{
    "exportFormatVersion": 2,
    "exportTime": "2026-07-12 17:20:10",
    "containerVersion": {
        "path": "accounts/6365534927/containers/258048563/versions/0",
        "accountId": "6365534927",
        "containerId": "258048563",
        "containerVersionId": "0",
        "container": {
            "path": "accounts/6365534927/containers/258048563",
            "accountId": "6365534927",
            "containerId": "258048563",
            "name": "Contenedor Servidor",
            "publicId": "GTM-MBJFMCRF",
            "usageContext": [
                "SERVER"
            ],
            "fingerprint": "1783780297919",
            "tagManagerUrl": "https://tagmanager.google.com/#/container/accounts/6365534927/containers/258048563/workspaces?apiLink=container",
            "features": {
                "supportUserPermissions": true,
                "supportEnvironments": true,
                "supportWorkspaces": true,
                "supportGtagConfigs": false,
                "supportBuiltInVariables": true,
                "supportClients": true,
                "supportFolders": true,
                "supportTags": true,
                "supportTemplates": true,
                "supportTriggers": true,
                "supportVariables": true,
                "supportVersions": true,
                "supportZones": true,
                "supportTransformations": true
            },
            "tagIds": [
                "GTM-MBJFMCRF"
            ],
            "taggingServerUrls": [
                "https://jiknffqc.sav.stape.io"
            ]
        },
        "tag": [
            {
                "accountId": "6365534927",
                "containerId": "258048563",
                "tagId": "23",
                "name": "FB - API de conversiones",
                "type": "cvt_5TP8W",
                "parameter": [
                    {
                        "type": "TEMPLATE",
                        "key": "logType",
                        "value": "debug"
                    },
                    {
                        "type": "BOOLEAN",
                        "key": "autoMapCustomData",
                        "value": "true"
                    },
                    {
                        "type": "TEMPLATE",
                        "key": "adStorageConsent",
                        "value": "optional"
                    },
                    {
                        "type": "BOOLEAN",
                        "key": "autoMapServerEventData",
                        "value": "true"
                    },
                    {
                        "type": "BOOLEAN",
                        "key": "generateFbp",
                        "value": "true"
                    },
                    {
                        "type": "BOOLEAN",
                        "key": "autoMapUserData",
                        "value": "true"
                    },
                    {
                        "type": "BOOLEAN",
                        "key": "overrideCookieDomain",
                        "value": "false"
                    },
                    {
                        "type": "LIST",
                        "key": "userDataList",
                        "list": [
                            {
                                "type": "MAP",
                                "map": [
                                    {
                                        "type": "TEMPLATE",
                                        "key": "name",
                                        "value": "ct"
                                    },
                                    {
                                        "type": "TEMPLATE",
                                        "key": "value",
                                        "value": "{{User - City city_meta - X-GEO-City}}"
                                    }
                                ]
                            },
                            {
                                "type": "MAP",
                                "map": [
                                    {
                                        "type": "TEMPLATE",
                                        "key": "name",
                                        "value": "st"
                                    },
                                    {
                                        "type": "TEMPLATE",
                                        "key": "value",
                                        "value": "{{User - State x-geo-region}}"
                                    }
                                ]
                            },
                            {
                                "type": "MAP",
                                "map": [
                                    {
                                        "type": "TEMPLATE",
                                        "key": "name",
                                        "value": "zp"
                                    },
                                    {
                                        "type": "TEMPLATE",
                                        "key": "value",
                                        "value": "{{User - ZIP x-geo-postalcode}}"
                                    }
                                ]
                            },
                            {
                                "type": "MAP",
                                "map": [
                                    {
                                        "type": "TEMPLATE",
                                        "key": "name",
                                        "value": "country"
                                    },
                                    {
                                        "type": "TEMPLATE",
                                        "key": "value",
                                        "value": "{{User - Country x-geo-country}}"
                                    }
                                ]
                            },
                            {
                                "type": "MAP",
                                "map": [
                                    {
                                        "type": "TEMPLATE",
                                        "key": "name",
                                        "value": "external_id"
                                    },
                                    {
                                        "type": "TEMPLATE",
                                        "key": "value",
                                        "value": "{{User - ID x-stape-user-id}}"
                                    }
                                ]
                            },
                            {
                                "type": "MAP",
                                "map": [
                                    {
                                        "type": "TEMPLATE",
                                        "key": "name",
                                        "value": "client_ip_address"
                                    },
                                    {
                                        "type": "TEMPLATE",
                                        "key": "value",
                                        "value": "{{User - IP address x-real-ip}}"
                                    }
                                ]
                            },
                            {
                                "type": "MAP",
                                "map": [
                                    {
                                        "type": "TEMPLATE",
                                        "key": "name",
                                        "value": "client_user_agent"
                                    },
                                    {
                                        "type": "TEMPLATE",
                                        "key": "value",
                                        "value": "{{User - Agent user-agent}}"
                                    }
                                ]
                            }
                        ]
                    },
                    {
                        "type": "TEMPLATE",
                        "key": "accessToken",
                        "value": "{{Const - FB Access Token}}"
                    },
                    {
                        "type": "BOOLEAN",
                        "key": "useAppSecretProof",
                        "value": "false"
                    },
                    {
                        "type": "TEMPLATE",
                        "key": "inheritEventName",
                        "value": "inherit"
                    },
                    {
                        "type": "TEMPLATE",
                        "key": "actionSource",
                        "value": "website"
                    },
                    {
                        "type": "TEMPLATE",
                        "key": "pixelId",
                        "value": "{{Const - FB Pixel ID}}"
                    },
                    {
                        "type": "BOOLEAN",
                        "key": "useHttpOnlyCookie",
                        "value": "false"
                    },
                    {
                        "type": "TEMPLATE",
                        "key": "itemIdKey"
                    },
                    {
                        "type": "BOOLEAN",
                        "key": "mapViewItemListToViewContent",
                        "value": "false"
                    },
                    {
                        "type": "BOOLEAN",
                        "key": "useOptimisticScenario",
                        "value": "false"
                    },
                    {
                        "type": "TEMPLATE",
                        "key": "bigQueryLogType",
                        "value": "no"
                    },
                    {
                        "type": "LIST",
                        "key": "serverEventDataList",
                        "list": [
                            {
                                "type": "MAP",
                                "map": [
                                    {
                                        "type": "TEMPLATE",
                                        "key": "name",
                                        "value": "event_id"
                                    },
                                    {
                                        "type": "TEMPLATE",
                                        "key": "value",
                                        "value": "{{Event ID}}"
                                    }
                                ]
                            }
                        ]
                    },
                    {
                        "type": "BOOLEAN",
                        "key": "enableMultipixelSetup",
                        "value": "false"
                    },
                    {
                        "type": "BOOLEAN",
                        "key": "enableEventEnhancement",
                        "value": "true"
                    }
                ],
                "fingerprint": "1783781091282",
                "firingTriggerId": [
                    "11",
                    "14",
                    "19"
                ],
                "tagFiringOption": "ONCE_PER_EVENT",
                "monitoringMetadata": {
                    "type": "MAP"
                },
                "consentSettings": {
                    "consentStatus": "NOT_SET"
                }
            }
        ],
        "trigger": [
            {
                "accountId": "6365534927",
                "containerId": "258048563",
                "triggerId": "11",
                "name": "page_view",
                "type": "CUSTOM_EVENT",
                "customEventFilter": [
                    {
                        "type": "EQUALS",
                        "parameter": [
                            {
                                "type": "TEMPLATE",
                                "key": "arg0",
                                "value": "{{_event}}"
                            },
                            {
                                "type": "TEMPLATE",
                                "key": "arg1",
                                "value": "page_view"
                            }
                        ]
                    }
                ],
                "filter": [
                    {
                        "type": "EQUALS",
                        "parameter": [
                            {
                                "type": "TEMPLATE",
                                "key": "arg0",
                                "value": "{{Client Name}}"
                            },
                            {
                                "type": "TEMPLATE",
                                "key": "arg1",
                                "value": "Data Client"
                            }
                        ]
                    }
                ],
                "fingerprint": "1783780016187"
            },
            {
                "accountId": "6365534927",
                "containerId": "258048563",
                "triggerId": "14",
                "name": "generate_lead",
                "type": "CUSTOM_EVENT",
                "customEventFilter": [
                    {
                        "type": "EQUALS",
                        "parameter": [
                            {
                                "type": "TEMPLATE",
                                "key": "arg0",
                                "value": "{{_event}}"
                            },
                            {
                                "type": "TEMPLATE",
                                "key": "arg1",
                                "value": "generate_lead"
                            }
                        ]
                    }
                ],
                "filter": [
                    {
                        "type": "EQUALS",
                        "parameter": [
                            {
                                "type": "TEMPLATE",
                                "key": "arg0",
                                "value": "{{Client Name}}"
                            },
                            {
                                "type": "TEMPLATE",
                                "key": "arg1",
                                "value": "Data Client"
                            }
                        ]
                    }
                ],
                "fingerprint": "1783780016236"
            },
            {
                "accountId": "6365534927",
                "containerId": "258048563",
                "triggerId": "19",
                "name": "Eventos ecommerce",
                "type": "CUSTOM_EVENT",
                "customEventFilter": [
                    {
                        "type": "MATCH_REGEX",
                        "parameter": [
                            {
                                "type": "TEMPLATE",
                                "key": "arg0",
                                "value": "{{_event}}"
                            },
                            {
                                "type": "TEMPLATE",
                                "key": "arg1",
                                "value": "view_item|add_to_cart|begin_checkout|purchase"
                            }
                        ]
                    }
                ],
                "fingerprint": "1783780016237"
            }
        ],
        "variable": [
            {
                "accountId": "6365534927",
                "containerId": "258048563",
                "variableId": "4",
                "name": "Const - FB Access Token",
                "type": "c",
                "parameter": [
                    {
                        "type": "TEMPLATE",
                        "key": "value",
                        "value": "TU_ACCESS_TOKEN"
                    }
                ],
                "fingerprint": "1783876482470",
                "formatValue": {}
            },
            {
                "accountId": "6365534927",
                "containerId": "258048563",
                "variableId": "5",
                "name": "User - IP address x-real-ip",
                "type": "rh",
                "parameter": [
                    {
                        "type": "TEMPLATE",
                        "key": "headerName",
                        "value": "x-real-ip"
                    }
                ],
                "fingerprint": "1783780016096",
                "formatValue": {}
            },
            {
                "accountId": "6365534927",
                "containerId": "258048563",
                "variableId": "6",
                "name": "User - State x-geo-region",
                "type": "rh",
                "parameter": [
                    {
                        "type": "TEMPLATE",
                        "key": "headerName",
                        "value": "x-geo-region"
                    }
                ],
                "fingerprint": "1783780016096",
                "formatValue": {
                    "caseConversionType": "LOWERCASE"
                }
            },
            {
                "accountId": "6365534927",
                "containerId": "258048563",
                "variableId": "7",
                "name": "User - Country x-geo-country",
                "type": "rh",
                "parameter": [
                    {
                        "type": "TEMPLATE",
                        "key": "headerName",
                        "value": "x-geo-country"
                    }
                ],
                "fingerprint": "1783780016096",
                "formatValue": {
                    "caseConversionType": "LOWERCASE"
                }
            },
            {
                "accountId": "6365534927",
                "containerId": "258048563",
                "variableId": "8",
                "name": "Const - FB Pixel ID",
                "type": "c",
                "parameter": [
                    {
                        "type": "TEMPLATE",
                        "key": "value",
                        "value": "TU_PIXEL_ID"
                    }
                ],
                "fingerprint": "1783876491820",
                "formatValue": {}
            },
            {
                "accountId": "6365534927",
                "containerId": "258048563",
                "variableId": "9",
                "name": "User - City x-geo-city",
                "type": "rh",
                "parameter": [
                    {
                        "type": "TEMPLATE",
                        "key": "headerName",
                        "value": "x-geo-city"
                    }
                ],
                "fingerprint": "1783780016096",
                "formatValue": {
                    "caseConversionType": "LOWERCASE"
                }
            },
            {
                "accountId": "6365534927",
                "containerId": "258048563",
                "variableId": "12",
                "name": "User - ZIP x-geo-postalcode",
                "type": "rh",
                "parameter": [
                    {
                        "type": "TEMPLATE",
                        "key": "headerName",
                        "value": "x-geo-postalcode"
                    }
                ],
                "fingerprint": "1783780016187",
                "formatValue": {}
            },
            {
                "accountId": "6365534927",
                "containerId": "258048563",
                "variableId": "18",
                "name": "User - City city_meta - X-GEO-City",
                "type": "cvt_258048563_17",
                "fingerprint": "1783780016237",
                "formatValue": {
                    "caseConversionType": "LOWERCASE"
                }
            },
            {
                "accountId": "6365534927",
                "containerId": "258048563",
                "variableId": "20",
                "name": "User - ID x-stape-user-id",
                "type": "rh",
                "parameter": [
                    {
                        "type": "TEMPLATE",
                        "key": "headerName",
                        "value": "x-stape-user-id"
                    }
                ],
                "fingerprint": "1783780016237",
                "formatValue": {}
            },
            {
                "accountId": "6365534927",
                "containerId": "258048563",
                "variableId": "21",
                "name": "User - Agent user-agent",
                "type": "rh",
                "parameter": [
                    {
                        "type": "TEMPLATE",
                        "key": "headerName",
                        "value": "user-agent"
                    }
                ],
                "fingerprint": "1783780016237",
                "formatValue": {}
            },
            {
                "accountId": "6365534927",
                "containerId": "258048563",
                "variableId": "22",
                "name": "Event ID",
                "type": "ed",
                "parameter": [
                    {
                        "type": "BOOLEAN",
                        "key": "setDefaultValue",
                        "value": "false"
                    },
                    {
                        "type": "TEMPLATE",
                        "key": "keyPath",
                        "value": "event_id"
                    }
                ],
                "fingerprint": "1783780016238",
                "formatValue": {}
            }
        ],
        "builtInVariable": [
            {
                "accountId": "6365534927",
                "containerId": "258048563",
                "type": "EVENT_NAME",
                "name": "Event Name"
            },
            {
                "accountId": "6365534927",
                "containerId": "258048563",
                "type": "CLIENT_NAME",
                "name": "Client Name"
            }
        ],
        "fingerprint": "1783876810148",
        "tagManagerUrl": "https://tagmanager.google.com/#/versions/accounts/6365534927/containers/258048563/versions/0?apiLink=version",
        "customTemplate": [
            {
                "accountId": "6365534927",
                "containerId": "258048563",
                "templateId": "10",
                "name": "Facebook Conversion API",
                "fingerprint": "1783780016096",
                "templateData": "___TERMS_OF_SERVICE___\n\nBy creating or modifying this file you agree to Google Tag Manager's Community\nTemplate Gallery Developer Terms of Service available at\nhttps://developers.google.com/tag-manager/gallery-tos (or such other URL as\nGoogle may provide), as modified from time to time.\n\n\n___INFO___\n\n{\n  \"type\": \"TAG\",\n  \"id\": \"cvt_5TP8W\",\n  \"version\": 1,\n  \"displayName\": \"Facebook Conversion API\",\n  \"categories\": [\n    \"ADVERTISING\",\n    \"ANALYTICS\",\n    \"CONVERSIONS\",\n    \"MARKETING\",\n    \"REMARKETING\"\n  ],\n  \"brand\": {\n    \"id\": \"github.com_stape-io\",\n    \"displayName\": \"stape-io\",\n    \"thumbnail\": \"data:image/png;base64,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\\u003d\"\n  },\n  \"description\": \"Tag that send the event data from the GA4/Data clients to Facebook Conversion API.\",\n  \"containerContexts\": [\n    \"SERVER\"\n  ]\n}\n\n\n___TEMPLATE_PARAMETERS___\n\n[\n  {\n    \"type\": \"GROUP\",\n    \"name\": \"configGroup\",\n    \"subParams\": [\n      {\n        \"type\": \"SELECT\",\n        \"name\": \"inheritEventName\",\n        \"displayName\": \"Event Name Setup Method\",\n        \"selectItems\": [\n          {\n            \"value\": \"inherit\",\n            \"displayValue\": \"Inherit from client\"\n          },\n          {\n            \"value\": \"override\",\n            \"displayValue\": \"Override\"\n          }\n        ],\n        \"simpleValueType\": true,\n        \"subParams\": [\n          {\n            \"type\": \"RADIO\",\n            \"name\": \"eventName\",\n            \"radioItems\": [\n              {\n                \"value\": \"standard\",\n                \"displayValue\": \"Standard\",\n                \"subParams\": [\n                  {\n                    \"type\": \"SELECT\",\n                    \"name\": \"eventNameStandard\",\n                    \"macrosInSelect\": false,\n                    \"selectItems\": [\n                      {\n                        \"value\": \"PageView\",\n                        \"displayValue\": \"PageView\"\n                      },\n                      {\n                        \"value\": \"AddPaymentInfo\",\n                        \"displayValue\": \"AddPaymentInfo\"\n                      },\n                      {\n                        \"value\": \"AddToCart\",\n                        \"displayValue\": \"AddToCart\"\n                      },\n                      {\n                        \"value\": \"AddToWishlist\",\n                        \"displayValue\": \"AddToWishlist\"\n                      },\n                      {\n                        \"value\": \"AppendValue\",\n                        \"displayValue\": \"AppendValue\"\n                      },\n                      {\n                        \"value\": \"CompleteRegistration\",\n                        \"displayValue\": \"CompleteRegistration\"\n                      },\n                      {\n                        \"value\": \"Contact\",\n                        \"displayValue\": \"Contact\"\n                      },\n                      {\n                        \"value\": \"CustomizeProduct\",\n                        \"displayValue\": \"CustomizeProduct\"\n                      },\n                      {\n                        \"value\": \"Donate\",\n                        \"displayValue\": \"Donate\"\n                      },\n                      {\n                        \"value\": \"FindLocation\",\n                        \"displayValue\": \"FindLocation\"\n                      },\n                      {\n                        \"value\": \"InitiateCheckout\",\n                        \"displayValue\": \"InitiateCheckout\"\n                      },\n                      {\n                        \"value\": \"Lead\",\n                        \"displayValue\": \"Lead\"\n                      },\n                      {\n                        \"value\": \"Purchase\",\n                        \"displayValue\": \"Purchase\"\n                      },\n                      {\n                        \"value\": \"Schedule\",\n                        \"displayValue\": \"Schedule\"\n                      },\n                      {\n                        \"value\": \"Search\",\n                        \"displayValue\": \"Search\"\n                      },\n                      {\n                        \"value\": \"StartTrial\",\n                        \"displayValue\": \"StartTrial\"\n                      },\n                      {\n                        \"value\": \"SubmitApplication\",\n                        \"displayValue\": \"SubmitApplication\"\n                      },\n                      {\n                        \"value\": \"Subscribe\",\n                        \"displayValue\": \"Subscribe\"\n                      },\n                      {\n                        \"value\": \"ViewContent\",\n                        \"displayValue\": \"ViewContent\"\n                      }\n                    ],\n                    \"simpleValueType\": true\n                  }\n                ]\n              },\n              {\n                \"value\": \"custom\",\n                \"displayValue\": \"Custom\",\n                \"subParams\": [\n                  {\n                    \"type\": \"TEXT\",\n                    \"name\": \"eventNameCustom\",\n                    \"simpleValueType\": true\n                  }\n                ]\n              }\n            ],\n            \"simpleValueType\": true,\n            \"enablingConditions\": [\n              {\n                \"paramName\": \"inheritEventName\",\n                \"paramValue\": \"override\",\n                \"type\": \"EQUALS\"\n              }\n            ],\n            \"displayName\": \"Event Type\"\n          }\n        ],\n        \"help\": \"\\u003cb\\u003eInherit from client\\u003c/b\\u003e\\n\\u003cbr/\\u003e\\nIf the incoming request follows the \\u003cb\\u003eGoogle Analytics 4 (GA4)\\u003c/b\\u003e schema, the following mappings will be applied to convert GA4 \\u003ci\\u003eEvent Names\\u003c/i\\u003e into the Conversion API \\u003ci\\u003eEvent Name\\u003c/i\\u003e equivalent:\\n\\u003cbr/\\u003e\\n\\u003cul\\u003e\\n\\u003cli\\u003e\\u003ci\\u003epage_view\\u003c/i\\u003e → \\u003ci\\u003ePageView\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003ci\\u003egtm.dom\\u003c/i\\u003e → \\u003ci\\u003ePageView\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003ci\\u003eadd_payment_info\\u003c/i\\u003e → \\u003ci\\u003eAddPaymentInfo\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003ci\\u003eadd_to_cart\\u003c/i\\u003e → \\u003ci\\u003eAddToCart\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003ci\\u003eadd_to_wishlist\\u003c/i\\u003e → \\u003ci\\u003eAddToWishlist\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003ci\\u003esign_up\\u003c/i\\u003e → \\u003ci\\u003eCompleteRegistration\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003ci\\u003ebegin_checkout\\u003c/i\\u003e → \\u003ci\\u003eInitiateCheckout\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003ci\\u003egenerate_lead\\u003c/i\\u003e → \\u003ci\\u003eLead\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003ci\\u003epurchase\\u003c/i\\u003e → \\u003ci\\u003ePurchase\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003ci\\u003esearch\\u003c/i\\u003e → \\u003ci\\u003eSearch\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003ci\\u003eview_item\\u003c/i\\u003e → \\u003ci\\u003eViewContent\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003ci\\u003eview_item_list\\u003c/i\\u003e → \\u003ci\\u003eViewContent\\u003c/i\\u003e (conditional)\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003ci\\u003econtact\\u003c/i\\u003e → \\u003ci\\u003eContact\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003ci\\u003ecustomize_product\\u003c/i\\u003e → \\u003ci\\u003eCustomizeProduct\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003ci\\u003edonate\\u003c/i\\u003e → \\u003ci\\u003eDonate\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003ci\\u003efind_location\\u003c/i\\u003e → \\u003ci\\u003eFindLocation\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003ci\\u003eschedule\\u003c/i\\u003e → \\u003ci\\u003eSchedule\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003ci\\u003estart_trial\\u003c/i\\u003e → \\u003ci\\u003eStartTrial\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003ci\\u003esubmit_application\\u003c/i\\u003e → \\u003ci\\u003eSubmitApplication\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003ci\\u003esubscribe\\u003c/i\\u003e → \\u003ci\\u003eSubscribe\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003ci\\u003egtm4wp.addProductToCartEEC\\u003c/i\\u003e → \\u003ci\\u003eAddToCart\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003ci\\u003egtm4wp.productClickEEC\\u003c/i\\u003e → \\u003ci\\u003eViewContent\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003ci\\u003egtm4wp.checkoutOptionEEC\\u003c/i\\u003e → \\u003ci\\u003eInitiateCheckout\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003ci\\u003egtm4wp.checkoutStepEEC\\u003c/i\\u003e → \\u003ci\\u003eAddPaymentInfo\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003ci\\u003egtm4wp.orderCompletedEEC\\u003c/i\\u003e → \\u003ci\\u003ePurchase\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003c/ul\\u003e\\n\\u003cbr/\\u003e\\nPlease note that it provides partial event mapping. Not all GA4 events can be mapped to Conversion API Event Name.\"\n      },\n      {\n        \"type\": \"SELECT\",\n        \"name\": \"actionSource\",\n        \"displayName\": \"Action Source\",\n        \"selectItems\": [\n          {\n            \"value\": \"website\",\n            \"displayValue\": \"Website\"\n          },\n          {\n            \"value\": \"email\",\n            \"displayValue\": \"Email\"\n          },\n          {\n            \"value\": \"app\",\n            \"displayValue\": \"App\"\n          },\n          {\n            \"value\": \"phone_call\",\n            \"displayValue\": \"Phone Call\"\n          },\n          {\n            \"value\": \"chat\",\n            \"displayValue\": \"Chat\"\n          },\n          {\n            \"value\": \"physical_store\",\n            \"displayValue\": \"Physical Store\"\n          },\n          {\n            \"value\": \"system_generated\",\n            \"displayValue\": \"System Generated\"\n          },\n          {\n            \"value\": \"business_messaging\",\n            \"displayValue\": \"Business Messaging\"\n          },\n          {\n            \"value\": \"other\",\n            \"displayValue\": \"Other\"\n          }\n        ],\n        \"simpleValueType\": true,\n        \"valueValidators\": [\n          {\n            \"type\": \"NON_EMPTY\"\n          }\n        ],\n        \"defaultValue\": \"website\",\n        \"help\": \"\\u003cb\\u003eEmail\\u003c/b\\u003e — Conversion happened over email.\\n\\u003cbr/\\u003e\\n\\u003cb\\u003eWebsite\\u003c/b\\u003e — Conversion was made on your website.\\n\\u003cbr/\\u003e\\n\\u003cb\\u003eApp\\u003c/b\\u003e — Conversion was made on your mobile app.\\n\\u003cbr/\\u003e\\n\\u003cb\\u003ePhone Call\\u003c/b\\u003e — Conversion was made over the phone.\\n\\u003cbr/\\u003e\\n\\u003cb\\u003eChat\\u003c/b\\u003e — Conversion was made via a messaging app, SMS, or online messaging feature.\\n\\u003cbr/\\u003e\\n\\u003cb\\u003ePhysical Store\\u003c/b\\u003e — Conversion was made in person at your physical store, helping to optimize your omni-channel marketing strategy.\\n\\u003cbr/\\u003e\\n\\u003cb\\u003eSystem Generated\\u003c/b\\u003e — Conversion happened automatically, such as a subscription renewal set to auto-pay, often linked with CRM CAPI for Meta Lead Ads.\\n\\u003cbr/\\u003e\\n\\u003cb\\u003eBusiness Messaging\\u003c/b\\u003e — Conversion was made from ads that click to Messenger, Instagram or WhatsApp.\\n\\u003cbr/\\u003e \\n\\u003cb\\u003eOther\\u003c/b\\u003e — Conversion happened in a way that is not listed.\",\n        \"alwaysInSummary\": true\n      },\n      {\n        \"type\": \"SELECT\",\n        \"name\": \"messaging_channel\",\n        \"displayName\": \"Messaging Channel\",\n        \"macrosInSelect\": false,\n        \"selectItems\": [\n          {\n            \"value\": \"messenger\",\n            \"displayValue\": \"Messenger\"\n          },\n          {\n            \"value\": \"whatsapp\",\n            \"displayValue\": \"WhatsApp\"\n          },\n          {\n            \"value\": \"instagram\",\n            \"displayValue\": \"Instagram\"\n          }\n        ],\n        \"simpleValueType\": true,\n        \"defaultValue\": \"messenger\",\n        \"enablingConditions\": [\n          {\n            \"paramName\": \"actionSource\",\n            \"paramValue\": \"business_messaging\",\n            \"type\": \"EQUALS\"\n          }\n        ],\n        \"valueValidators\": [\n          {\n            \"type\": \"NON_EMPTY\"\n          }\n        ],\n        \"alwaysInSummary\": true\n      },\n      {\n        \"type\": \"TEXT\",\n        \"name\": \"pixelId\",\n        \"displayName\": \"Facebook Pixel ID\",\n        \"simpleValueType\": true,\n        \"valueValidators\": [\n          {\n            \"type\": \"NON_EMPTY\"\n          }\n        ],\n        \"help\": \"Set to a valid Facebook Pixel ID.\"\n      },\n      {\n        \"type\": \"TEXT\",\n        \"name\": \"accessToken\",\n        \"displayName\": \"API Access Token\",\n        \"simpleValueType\": true,\n        \"help\": \"Set to your Facebook API Access Token. See \\u003ca href\\u003d\\\"https://developers.facebook.com/docs/marketing-api/server-side-api/get-started#access-token\\\" target\\u003d\\\"_blank\\\"\\u003ehere\\u003c/a\\u003e for more information.\",\n        \"valueValidators\": [\n          {\n            \"type\": \"NON_EMPTY\"\n          }\n        ]\n      },\n      {\n        \"type\": \"CHECKBOX\",\n        \"name\": \"enableMultipixelSetup\",\n        \"checkboxText\": \"Add Multiple Facebook Pixel IDs\",\n        \"simpleValueType\": true,\n        \"help\": \"Add one \\u003ci\\u003eFacebook Pixel ID\\u003c/i\\u003e and one \\u003ci\\u003eAccess Token\\u003c/i\\u003e per line.\",\n        \"subParams\": [\n          {\n            \"type\": \"SIMPLE_TABLE\",\n            \"name\": \"pixelIdAndAccessTokenTable\",\n            \"simpleTableColumns\": [\n              {\n                \"defaultValue\": \"\",\n                \"displayName\": \"Facebook Pixel ID\",\n                \"name\": \"pixelId\",\n                \"type\": \"TEXT\",\n                \"valueValidators\": [\n                  {\n                    \"type\": \"NON_EMPTY\"\n                  }\n                ]\n              },\n              {\n                \"defaultValue\": \"\",\n                \"displayName\": \"API Access Token\",\n                \"name\": \"accessToken\",\n                \"type\": \"TEXT\",\n                \"valueValidators\": [\n                  {\n                    \"type\": \"NON_EMPTY\"\n                  }\n                ]\n              }\n            ],\n            \"enablingConditions\": [\n              {\n                \"paramName\": \"enableMultipixelSetup\",\n                \"paramValue\": true,\n                \"type\": \"EQUALS\"\n              }\n            ],\n            \"newRowButtonText\": \"Add Pixel ID\"\n          }\n        ],\n        \"enablingConditions\": [\n          {\n            \"paramName\": \"useAppSecretProof\",\n            \"paramValue\": true,\n            \"type\": \"NOT_EQUALS\"\n          }\n        ]\n      },\n      {\n        \"type\": \"TEXT\",\n        \"name\": \"testId\",\n        \"displayName\": \"Test ID\",\n        \"simpleValueType\": true,\n        \"help\": \"Provide a Test ID if you want to test server-side events in the Test Events feature of Events Manager.\\n\\u003cbr/\\u003e\\nIt automatically uses the value in \\u003ci\\u003eeventData.test_event_code\\u003c/i\\u003e, if present.\",\n        \"valueHint\": \"TEST123\"\n      },\n      {\n        \"type\": \"SELECT\",\n        \"name\": \"overrideCookieDomain\",\n        \"displayName\": \"Override the cookie domain\",\n        \"macrosInSelect\": true,\n        \"selectItems\": [\n          {\n            \"value\": false,\n            \"displayValue\": \"False\"\n          },\n          {\n            \"value\": true,\n            \"displayValue\": \"True\"\n          }\n        ],\n        \"simpleValueType\": true,\n        \"subParams\": [\n          {\n            \"type\": \"TEXT\",\n            \"name\": \"overridenCookieDomain\",\n            \"displayName\": \"Cookie Domain\",\n            \"simpleValueType\": true,\n            \"enablingConditions\": [\n              {\n                \"paramName\": \"overrideCookieDomain\",\n                \"paramValue\": false,\n                \"type\": \"NOT_EQUALS\"\n              }\n            ],\n            \"help\": \"Enable this option to override the cookie domain.\\u003cbr\\u003eEnter your website\\u0027s top-level domain as a fixed value (e.g., example.com). \\u003cbr\\u003e If left as \\\"auto\\\", the top-level domain will be automatically determined using the following priority: \\u003cul\\u003e \\u003cli\\u003eTop-level domain of the \\u003ci\\u003eForwarded\\u003c/i\\u003e header (if present).\\u003c/li\\u003e \\u003cli\\u003eTop-level domain of the \\u003ci\\u003eX-Forwarded-Host\\u003c/i\\u003e header (if present).\\u003c/li\\u003e \\u003cli\\u003eTop-level domain of the \\u003ci\\u003eHost\\u003c/i\\u003e header.\\u003c/li\\u003e \\u003c/ul\\u003e\",\n            \"defaultValue\": \"auto\",\n            \"valueHint\": \"example.com\",\n            \"alwaysInSummary\": true\n          }\n        ],\n        \"defaultValue\": false\n      },\n      {\n        \"type\": \"CHECKBOX\",\n        \"name\": \"generateFbp\",\n        \"checkboxText\": \"Generate _fbp cookie if it not exist\",\n        \"simpleValueType\": true,\n        \"defaultValue\": true,\n        \"alwaysInSummary\": true\n      },\n      {\n        \"type\": \"CHECKBOX\",\n        \"name\": \"useHttpOnlyCookie\",\n        \"checkboxText\": \"Use HttpOnly cookies for _fbc and _fbp\",\n        \"simpleValueType\": true,\n        \"help\": \"If enabled, Forbids JavaScript from accessing the \\u003ci\\u003e_fbc\\u003c/i\\u003e and \\u003ci\\u003e_fbp\\u003c/i\\u003e cookies.\"\n      },\n      {\n        \"type\": \"CHECKBOX\",\n        \"name\": \"enableEventEnhancement\",\n        \"checkboxText\": \"Enable Event Enhancement\",\n        \"simpleValueType\": true,\n        \"help\": \"Enable Use of HTTP Only Secure Cookie (gtmeec) to Enhance Event Data.\",\n        \"defaultValue\": true,\n        \"alwaysInSummary\": true\n      },\n      {\n        \"type\": \"CHECKBOX\",\n        \"name\": \"useOptimisticScenario\",\n        \"checkboxText\": \"Use Optimistic Scenario\",\n        \"simpleValueType\": true,\n        \"help\": \"The tag will call gtmOnSuccess() without waiting for a response from the API. This will speed up sGTM response time however your tag will always return the status fired successfully even in case it is not.\"\n      }\n    ]\n  },\n  {\n    \"displayName\": \"Server Event Data Override\",\n    \"name\": \"serverEventDataListGroup\",\n    \"groupStyle\": \"ZIPPY_OPEN_ON_PARAM\",\n    \"type\": \"GROUP\",\n    \"subParams\": [\n      {\n        \"type\": \"LABEL\",\n        \"name\": \"serverEventDataLabel\",\n        \"displayName\": \"Check \\u003ca href\\u003d\\\"https://developers.facebook.com/docs/marketing-api/conversions-api/parameters/server-event\\\"\\u003ethis documentation\\u003c/a\\u003e for more details on which parameters you can override.\\u003cbr/\\u003e\\u003cbr/\\u003e\"\n      },\n      {\n        \"type\": \"CHECKBOX\",\n        \"name\": \"autoMapServerEventData\",\n        \"checkboxText\": \"Automap Server Event Data\",\n        \"simpleValueType\": true,\n        \"help\": \"If enabled, the tag will attempt to automatically map parameters from your event data.\\n\\u003cbr/\\u003e\\u003cbr/\\u003e\\nAny value you manually enter in a field below will always override the auto-mapped value.\\n\\u003cbr/\\u003e\\u003cbr/\\u003e\\nDefault mappings:\\n\\u003cul\\u003e\\n\\u003cli\\u003eSource URL:\\n\\u003cul\\u003e\\n\\u003cli\\u003e\\u003ci\\u003eeventData.page_location\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003c/ul\\u003e\\n\\u003c/li\\u003e\\n\\u003cli\\u003eReferrer URL:\\n\\u003cul\\u003e\\n\\u003cli\\u003e\\u003ci\\u003eeventData.page_referrer\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003c/ul\\u003e\\n\\u003c/li\\u003e\\n\\u003cli\\u003eEvent ID:\\n\\u003cul\\u003e\\n\\u003cli\\u003e\\u003ci\\u003eeventData.event_id\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003ci\\u003eeventData.transaction_id\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003c/ul\\u003e\\n\\u003c/li\\u003e\\n\\u003c/ul\\u003e\",\n        \"defaultValue\": true\n      },\n      {\n        \"name\": \"serverEventDataList\",\n        \"simpleTableColumns\": [\n          {\n            \"valueValidators\": [\n              {\n                \"type\": \"NON_EMPTY\"\n              }\n            ],\n            \"defaultValue\": \"event_id\",\n            \"displayName\": \"Property Name\",\n            \"name\": \"name\",\n            \"isUnique\": true,\n            \"type\": \"SELECT\",\n            \"selectItems\": [\n              {\n                \"value\": \"event_time\",\n                \"displayValue\": \"Event Time\"\n              },\n              {\n                \"value\": \"event_source_url\",\n                \"displayValue\": \"Source URL\"\n              },\n              {\n                \"value\": \"opt_out\",\n                \"displayValue\": \"Opt Out\"\n              },\n              {\n                \"value\": \"event_id\",\n                \"displayValue\": \"Event ID\"\n              },\n              {\n                \"value\": \"data_processing_options\",\n                \"displayValue\": \"Data Processing Options\"\n              },\n              {\n                \"value\": \"data_processing_options_country\",\n                \"displayValue\": \"Data Processing Options Country\"\n              },\n              {\n                \"value\": \"data_processing_options_state\",\n                \"displayValue\": \"Data Processing Options State\"\n              },\n              {\n                \"value\": \"referrer_url\",\n                \"displayValue\": \"Referrer URL\"\n              }\n            ]\n          },\n          {\n            \"defaultValue\": \"\",\n            \"displayName\": \"Property Value\",\n            \"name\": \"value\",\n            \"type\": \"TEXT\"\n          }\n        ],\n        \"type\": \"SIMPLE_TABLE\",\n        \"newRowButtonText\": \"Add property\"\n      }\n    ]\n  },\n  {\n    \"type\": \"GROUP\",\n    \"name\": \"originalEventDataListGroup\",\n    \"displayName\": \"Original Event Data\",\n    \"groupStyle\": \"ZIPPY_OPEN_ON_PARAM\",\n    \"subParams\": [\n      {\n        \"type\": \"LABEL\",\n        \"name\": \"originalEventDataLabel\",\n        \"displayName\": \"Check \\u003ca href\\u003d\\\"https://developers.facebook.com/docs/marketing-api/conversions-api/parameters/original-event\\\"\\u003ethis documentation\\u003c/a\\u003e for more details on which parameters you can override.\\n\\u003cbr/\\u003e\\nUse these parameters to identify the Original Event that happened at an earlier time. Then, use the \\u003ci\\u003eAppendValue\\u003c/i\\u003e event and the other sections to supplement information the Original Event. This is useful for Value Optimization for Profit (using the \\u003ci\\u003enet_revenue\\u003c/i\\u003e parameter), allowing you to report the final profit margin after the initial sale has occurred.\\n\\u003cbr/\\u003e\\u003cbr/\\u003e\"\n      },\n      {\n        \"type\": \"SIMPLE_TABLE\",\n        \"name\": \"originalEventDataList\",\n        \"displayName\": \"\",\n        \"simpleTableColumns\": [\n          {\n            \"defaultValue\": \"\",\n            \"displayName\": \"Property Name\",\n            \"name\": \"name\",\n            \"type\": \"SELECT\",\n            \"isUnique\": true,\n            \"valueValidators\": [\n              {\n                \"type\": \"NON_EMPTY\"\n              }\n            ],\n            \"selectItems\": [\n              {\n                \"value\": \"event_name\",\n                \"displayValue\": \"Original Event Name\"\n              },\n              {\n                \"value\": \"event_time\",\n                \"displayValue\": \"Original Event Time\"\n              },\n              {\n                \"value\": \"order_id\",\n                \"displayValue\": \"Original Order ID\"\n              },\n              {\n                \"value\": \"event_id\",\n                \"displayValue\": \"Original Event ID\"\n              }\n            ]\n          },\n          {\n            \"defaultValue\": \"\",\n            \"displayName\": \"Property Value\",\n            \"name\": \"value\",\n            \"type\": \"TEXT\",\n            \"valueValidators\": [\n              {\n                \"type\": \"NON_EMPTY\"\n              }\n            ]\n          }\n        ],\n        \"valueValidators\": [\n          {\n            \"type\": \"NON_EMPTY\"\n          }\n        ],\n        \"newRowButtonText\": \"Add property\"\n      }\n    ],\n    \"enablingConditions\": [\n      {\n        \"paramName\": \"eventNameStandard\",\n        \"paramValue\": \"AppendValue\",\n        \"type\": \"EQUALS\"\n      },\n      {\n        \"paramName\": \"eventNameCustom\",\n        \"paramValue\": \"AppendValue\",\n        \"type\": \"EQUALS\"\n      }\n    ]\n  },\n  {\n    \"displayName\": \"User Data\",\n    \"name\": \"userDataListGroup\",\n    \"groupStyle\": \"ZIPPY_OPEN_ON_PARAM\",\n    \"type\": \"GROUP\",\n    \"subParams\": [\n      {\n        \"type\": \"LABEL\",\n        \"name\": \"userDataLabel\",\n        \"displayName\": \"User Data is your main \\u003ca href\\u003d\\\"https://www.facebook.com/business/help/765081237991954?id\\u003d818859032317965\\\"\\u003eEvent Match Quality (EMQ) contributor\\u003c/a\\u003e. Matched events improve ad targeting by connecting actions to Meta accounts. Events with better match quality can lead to lower costs per action.\\n\\u003cbr/\\u003e\\nCheck \\u003ca href\\u003d\\\"https://developers.facebook.com/docs/marketing-api/server-side-api/parameters/user-data\\\"\\u003ethis documentation\\u003c/a\\u003e for more details on accepted User Data parameters.\\n\\u003cbr/\\u003e\\nThe tag will automatically hash parameters that need it, pre-hashed data is also accepted.\\n\\u003cbr/\\u003e\\u003cbr/\\u003e\"\n      },\n      {\n        \"type\": \"CHECKBOX\",\n        \"name\": \"autoMapUserData\",\n        \"checkboxText\": \"Automap User Data\",\n        \"simpleValueType\": true,\n        \"help\": \"If enabled, the tag will attempt to automatically map parameters from your event data.\\n\\u003cbr/\\u003e\\u003cbr/\\u003e\\nAny value you manually enter in a field below will always override the auto-mapped value.\\n\\u003cbr/\\u003e\\u003cbr/\\u003e\\nDefault mappings:\\n\\u003cul\\u003e\\n\\u003cli\\u003e\\u003cb\\u003eClick ID:\\u003c/b\\u003e \\u003ci\\u003efbclid URL parameter\\u003c/i\\u003e, \\u003ci\\u003e_fbc cookie\\u003c/i\\u003e, \\u003ci\\u003eeventData.common_cookie._fbc\\u003c/i\\u003e, \\u003ci\\u003eeventData._fbc\\u003c/i\\u003e, \\u003ci\\u003eeventData.fbc\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003cb\\u003eBrowser ID:\\u003c/b\\u003e \\u003ci\\u003e_fbp cookie\\u003c/i\\u003e, \\u003ci\\u003eeventData.common_cookie._fbp\\u003c/i\\u003e, \\u003ci\\u003eeventData._fbp\\u003c/i\\u003e, \\u003ci\\u003eeventData.fbp\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003cb\\u003eEmail:\\u003c/b\\u003e \\u003ci\\u003eeventData.email\\u003c/i\\u003e, \\u003ci\\u003eeventData.user_data.email_address\\u003c/i\\u003e, \\u003ci\\u003eeventData.user_data.email\\u003c/i\\u003e, \\u003ci\\u003eeventData.user_data.sha256_email_address\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003cb\\u003ePhone:\\u003c/b\\u003e \\u003ci\\u003eeventData.phone\\u003c/i\\u003e, \\u003ci\\u003eeventData.user_data.phone_number\\u003c/i\\u003e, \\u003ci\\u003eeventData.user_data.phone\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003cb\\u003eFirst Name:\\u003c/b\\u003e \\u003ci\\u003eeventData.firstName\\u003c/i\\u003e, \\u003ci\\u003eeventData.FirstName\\u003c/i\\u003e, \\u003ci\\u003eeventData.nameFirst\\u003c/i\\u003e, \\u003ci\\u003eeventData.first_name\\u003c/i\\u003e, \\u003ci\\u003eeventData.user_data.first_name\\u003c/i\\u003e, \\u003ci\\u003eeventData.user_data.address[].first_name\\u003c/i\\u003e, \\u003ci\\u003eeventData.user_data.address[].sha256_first_name\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003cb\\u003eLast Name:\\u003c/b\\u003e \\u003ci\\u003eeventData.lastName\\u003c/i\\u003e, \\u003ci\\u003eeventData.LastName\\u003c/i\\u003e, \\u003ci\\u003eeventData.nameLast\\u003c/i\\u003e, \\u003ci\\u003eeventData.last_name\\u003c/i\\u003e, \\u003ci\\u003eeventData.user_data.last_name\\u003c/i\\u003e, \\u003ci\\u003eeventData.user_data.address[].last_name\\u003c/i\\u003e, \\u003ci\\u003eeventData.user_data.address[].sha256_last_name\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003cb\\u003eCity:\\u003c/b\\u003e \\u003ci\\u003eeventData.city\\u003c/i\\u003e, \\u003ci\\u003eeventData.user_data.address[].city\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003cb\\u003eState:\\u003c/b\\u003e \\u003ci\\u003eeventData.state\\u003c/i\\u003e, \\u003ci\\u003eeventData.region\\u003c/i\\u003e, \\u003ci\\u003eeventData.user_data.region\\u003c/i\\u003e, \\u003ci\\u003eeventData.user_data.address[].region\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003cb\\u003eZip:\\u003c/b\\u003e \\u003ci\\u003eeventData.zip\\u003c/i\\u003e, \\u003ci\\u003eeventData.postal_code\\u003c/i\\u003e, \\u003ci\\u003eeventData.user_data.postal_code\\u003c/i\\u003e, \\u003ci\\u003eeventData.user_data.address[].postal_code\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003cb\\u003eCountry:\\u003c/b\\u003e \\u003ci\\u003eeventData.countryCode\\u003c/i\\u003e, \\u003ci\\u003eeventData.country\\u003c/i\\u003e, \\u003ci\\u003eeventData.user_data.country\\u003c/i\\u003e, \\u003ci\\u003eeventData.user_data.address[].country\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003cb\\u003eGender:\\u003c/b\\u003e \\u003ci\\u003eeventData.gender\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003cb\\u003eDate of Birth:\\u003c/b\\u003e \\u003ci\\u003eeventData.db\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003cb\\u003eExternal ID:\\u003c/b\\u003e \\u003ci\\u003eeventData.external_id\\u003c/i\\u003e, \\u003ci\\u003eeventData.user_id\\u003c/i\\u003e, \\u003ci\\u003eeventData.userId\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003cb\\u003eFB Login ID:\\u003c/b\\u003e \\u003ci\\u003eeventData.fb_login_id\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003cb\\u003eInstall ID:\\u003c/b\\u003e \\u003ci\\u003eeventData.anon_id\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003cb\\u003eMobile Advertising ID:\\u003c/b\\u003e \\u003ci\\u003eeventData.madid\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003cb\\u003eLead ID:\\u003c/b\\u003e \\u003ci\\u003eeventData.lead_id\\u003c/i\\u003e, \\u003ci\\u003eeventData.leadId\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003cb\\u003eSubscription ID:\\u003c/b\\u003e \\u003ci\\u003eeventData.subscription_id\\u003c/i\\u003e, \\u003ci\\u003eeventData.subscriptionId\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003cb\\u003ePlaintext IP Address:\\u003c/b\\u003e \\u003ci\\u003eeventData.ip_override\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003cb\\u003eClient User Agent:\\u003c/b\\u003e \\u003ci\\u003eeventData.user_agent\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003c/ul\\u003e\",\n        \"defaultValue\": true\n      },\n      {\n        \"type\": \"SELECT\",\n        \"name\": \"userDataObject\",\n        \"displayName\": \"User Data Properties Object\",\n        \"macrosInSelect\": true,\n        \"selectItems\": [],\n        \"simpleValueType\": true,\n        \"help\": \"Provide an object with User Data Properties to merge with the fields below. Any conflicting properties will be overwritten.\",\n        \"notSetText\": \"(not set)\"\n      },\n      {\n        \"name\": \"userDataList\",\n        \"simpleTableColumns\": [\n          {\n            \"valueValidators\": [\n              {\n                \"type\": \"NON_EMPTY\"\n              }\n            ],\n            \"defaultValue\": \"em\",\n            \"displayName\": \"Property Name\",\n            \"name\": \"name\",\n            \"isUnique\": true,\n            \"type\": \"SELECT\",\n            \"selectItems\": [\n              {\n                \"value\": \"em\",\n                \"displayValue\": \"Email\"\n              },\n              {\n                \"value\": \"ph\",\n                \"displayValue\": \"Phone\"\n              },\n              {\n                \"value\": \"ge\",\n                \"displayValue\": \"Gender\"\n              },\n              {\n                \"value\": \"db\",\n                \"displayValue\": \"Date of Birth\"\n              },\n              {\n                \"value\": \"ln\",\n                \"displayValue\": \"Last Name\"\n              },\n              {\n                \"value\": \"fn\",\n                \"displayValue\": \"First Name\"\n              },\n              {\n                \"value\": \"ct\",\n                \"displayValue\": \"City\"\n              },\n              {\n                \"value\": \"st\",\n                \"displayValue\": \"State\"\n              },\n              {\n                \"value\": \"zp\",\n                \"displayValue\": \"Zip\"\n              },\n              {\n                \"value\": \"country\",\n                \"displayValue\": \"Country\"\n              },\n              {\n                \"value\": \"external_id\",\n                \"displayValue\": \"External ID\"\n              },\n              {\n                \"value\": \"client_ip_address\",\n                \"displayValue\": \"Client IP Address\"\n              },\n              {\n                \"value\": \"client_user_agent\",\n                \"displayValue\": \"Client User Agent\"\n              },\n              {\n                \"value\": \"fbc\",\n                \"displayValue\": \"Click ID\"\n              },\n              {\n                \"value\": \"fbp\",\n                \"displayValue\": \"Browser ID\"\n              },\n              {\n                \"value\": \"subscription_id\",\n                \"displayValue\": \"Subscription ID\"\n              },\n              {\n                \"value\": \"lead_id\",\n                \"displayValue\": \"Lead ID\"\n              },\n              {\n                \"value\": \"fb_login_id\",\n                \"displayValue\": \"FB Login ID\"\n              },\n              {\n                \"value\": \"anon_id\",\n                \"displayValue\": \"Install ID\"\n              },\n              {\n                \"value\": \"madid\",\n                \"displayValue\": \"Mobile Advertiser ID\"\n              },\n              {\n                \"value\": \"page_id\",\n                \"displayValue\": \"Page ID\"\n              },\n              {\n                \"value\": \"page_scoped_user_id\",\n                \"displayValue\": \"Page Scoped User ID\"\n              },\n              {\n                \"value\": \"ctwa_clid\",\n                \"displayValue\": \"Click to WhatsApp ID\"\n              },\n              {\n                \"value\": \"ig_account_id\",\n                \"displayValue\": \"IG Account ID\"\n              },\n              {\n                \"value\": \"ig_sid\",\n                \"displayValue\": \"Click to Instagram ID\"\n              }\n            ]\n          },\n          {\n            \"defaultValue\": \"\",\n            \"displayName\": \"Property Value\",\n            \"name\": \"value\",\n            \"type\": \"TEXT\"\n          }\n        ],\n        \"type\": \"SIMPLE_TABLE\",\n        \"newRowButtonText\": \"Add property\"\n      }\n    ]\n  },\n  {\n    \"displayName\": \"App Data\",\n    \"name\": \"appDataListGroup\",\n    \"type\": \"GROUP\",\n    \"subParams\": [\n      {\n        \"type\": \"LABEL\",\n        \"name\": \"appDataLabel\",\n        \"displayName\": \"Check \\u003ca href\\u003d\\\"https://developers.facebook.com/docs/marketing-api/conversions-api/parameters/app-data\\\"\\u003ethis documentation\\u003c/a\\u003e for more details on which parameters you can override.\\n\\u003cbr/\\u003e\\u003cbr/\\u003e\"\n      },\n      {\n        \"type\": \"CHECKBOX\",\n        \"name\": \"autoMapAppData\",\n        \"checkboxText\": \"Automap App Data\",\n        \"simpleValueType\": true,\n        \"help\": \"If enabled, the tag will attempt to automatically map parameters from your event data.\\n\\u003cbr/\\u003e\\u003cbr/\\u003e\\nAny value you manually enter in a field below will always override the auto-mapped value.\\n\\u003cbr/\\u003e\\u003cbr/\\u003e\\nDefault mappings:\\n\\u003cul\\u003e\\n\\u003cli\\u003eIf \\u003ci\\u003eeventData.app_data\\u003c/i\\u003e is an object, it is used directly.\\u003c/li\\u003e\\n\\u003cli\\u003eOtherwise:\\n\\u003cul\\u003e\\n\\u003cli\\u003eAdvertiser Tracking Enabled: \\u003ci\\u003eeventData.advertiser_tracking_enabled\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003eApplication Tracking Enabled: \\u003ci\\u003eeventData.application_tracking_enabled\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003eExt Info: \\u003ci\\u003eeventData.extinfo\\u003c/i\\u003e, or built from \\u003ci\\u003eeventData[x-ga-platform]\\u003c/i\\u003e, \\u003ci\\u003eeventData.app_id\\u003c/i\\u003e, \\u003ci\\u003eeventData.app_version\\u003c/i\\u003e, \\u003ci\\u003eeventData[x-ga-os_version]\\u003c/i\\u003e, \\u003ci\\u003eeventData[x-ga-device_model]\\u003c/i\\u003e, \\u003ci\\u003eeventData.language\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003eCampaign IDs: \\u003ci\\u003eeventData.campaign_ids\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003eInstall Referrer: \\u003ci\\u003eeventData.install_referrer\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003eInstaller Package: \\u003ci\\u003eeventData.installer_package\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003eURL Schemes: \\u003ci\\u003eeventData.url_schemes\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003eVendor ID: \\u003ci\\u003eeventData.vendor_id\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003eWindows Attribution ID: \\u003ci\\u003eeventData.windows_attribution_id\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003c/ul\\u003e\\n\\u003c/li\\u003e\\n\\u003c/ul\\u003e\",\n        \"defaultValue\": true\n      },\n      {\n        \"type\": \"SELECT\",\n        \"name\": \"appDataObject\",\n        \"displayName\": \"App Data Properties Object\",\n        \"macrosInSelect\": true,\n        \"selectItems\": [],\n        \"simpleValueType\": true,\n        \"help\": \"Provide an object with App Data Properties to merge with the fields below. Any conflicting properties will be overwritten.\",\n        \"notSetText\": \"(not set)\"\n      },\n      {\n        \"name\": \"appDataList\",\n        \"simpleTableColumns\": [\n          {\n            \"valueValidators\": [\n              {\n                \"type\": \"NON_EMPTY\"\n              }\n            ],\n            \"defaultValue\": \"\",\n            \"displayName\": \"Property Name\",\n            \"name\": \"name\",\n            \"isUnique\": true,\n            \"type\": \"SELECT\",\n            \"selectItems\": [\n              {\n                \"value\": \"advertiser_tracking_enabled\",\n                \"displayValue\": \"Advertiser Tracking Enabled\"\n              },\n              {\n                \"value\": \"application_tracking_enabled\",\n                \"displayValue\": \"Application Tracking Enabled\"\n              },\n              {\n                \"value\": \"extinfo\",\n                \"displayValue\": \"Ext Info\"\n              },\n              {\n                \"value\": \"campaign_ids\",\n                \"displayValue\": \"Campaign IDs\"\n              },\n              {\n                \"value\": \"install_referrer\",\n                \"displayValue\": \"Install Referrer\"\n              },\n              {\n                \"value\": \"installer_package\",\n                \"displayValue\": \"Installer Package\"\n              },\n              {\n                \"value\": \"url_schemes\",\n                \"displayValue\": \"URL Schemes\"\n              },\n              {\n                \"value\": \"vendor_id\",\n                \"displayValue\": \"Vendor ID\"\n              },\n              {\n                \"value\": \"windows_attribution_id\",\n                \"displayValue\": \"Windows Attribution ID\"\n              }\n            ]\n          },\n          {\n            \"defaultValue\": \"\",\n            \"displayName\": \"Property Value\",\n            \"name\": \"value\",\n            \"type\": \"TEXT\"\n          }\n        ],\n        \"type\": \"SIMPLE_TABLE\",\n        \"newRowButtonText\": \"Add property\"\n      }\n    ],\n    \"enablingConditions\": [\n      {\n        \"paramName\": \"actionSource\",\n        \"paramValue\": \"app\",\n        \"type\": \"EQUALS\"\n      }\n    ],\n    \"groupStyle\": \"ZIPPY_OPEN_ON_PARAM\"\n  },\n  {\n    \"displayName\": \"Custom Data\",\n    \"name\": \"customDataListGroup\",\n    \"groupStyle\": \"ZIPPY_OPEN_ON_PARAM\",\n    \"type\": \"GROUP\",\n    \"subParams\": [\n      {\n        \"type\": \"LABEL\",\n        \"name\": \"customDataLabel\",\n        \"displayName\": \"Check \\u003ca href\\u003d\\\"https://developers.facebook.com/docs/marketing-api/conversions-api/parameters/custom-data\\\"\\u003ethis documentation\\u003c/a\\u003e for more details on which parameters you can override.\\n\\u003cbr/\\u003e\\u003cbr/\\u003e\"\n      },\n      {\n        \"type\": \"CHECKBOX\",\n        \"name\": \"autoMapCustomData\",\n        \"checkboxText\": \"Automap Custom Data\",\n        \"simpleValueType\": true,\n        \"help\": \"If enabled, the tag will attempt to automatically map parameters from your event data.\\n\\u003cbr/\\u003e\\u003cbr/\\u003e\\nAny value you manually enter in a field below will always override the auto-mapped value.\\n\\u003cbr/\\u003e\\u003cbr/\\u003e\\nDefault mappings:\\n\\u003cul\\u003e\\n\\u003cli\\u003eValue:\\n\\u003cul\\u003e\\n\\u003cli\\u003e\\u003ci\\u003eeventData[\\u0027x-ga-mp1-ev\\u0027]\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003ci\\u003eeventData[\\u0027x-ga-mp1-tr\\u0027]\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003ci\\u003eeventData.value\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003ci\\u003eSum of Price * Quantity from eventData.items[] or eventData.ecommerce.items[]\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003ci\\u003e0\\u003c/i\\u003e, if event is \\\"Purchase\\\" and no value is defined\\u003c/li\\u003e\\n\\u003c/ul\\u003e\\n\\u003c/li\\u003e\\n\\u003cli\\u003eCurrency:\\n\\u003cul\\u003e\\n\\u003cli\\u003e\\u003ci\\u003eeventData.currency\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003ci\\u003eCurrency from eventData.items[] or eventData.ecommerce.items[]\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003ci\\u003eUSD\\u003c/i\\u003e, if event is \\\"Purchase\\\" and no currency is defined\\u003c/li\\u003e\\n\\u003c/ul\\u003e\\n\\u003c/li\\u003e\\n\\u003cli\\u003eContents:\\n\\u003cul\\u003e\\n\\u003cli\\u003e\\u003ci\\u003eeventData.items[]\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003ci\\u003eeventData.ecommerce.items[]\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003c/ul\\u003e\\n\\u003c/li\\u003e\\n\\u003cli\\u003eContent Type:\\n\\u003cul\\u003e\\n\\u003cli\\u003e\\u003ci\\u003eeventData[x-fb-cd-content_type]\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003e\\u003ci\\u003eeventData.content_type\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003eDefault: \\u003ci\\u003eproduct\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003c/ul\\u003e\\n\\u003c/li\\u003e\\n\\u003cli\\u003eOrder ID:\\n\\u003cul\\u003e\\n\\u003cli\\u003e\\u003ci\\u003eeventData.transaction_id\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003c/ul\\u003e\\n\\u003c/li\\u003e\\n\\u003cli\\u003eSearch String:\\n\\u003cul\\u003e\\n\\u003cli\\u003e\\u003ci\\u003eeventData.search_term\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003c/ul\\u003e\\n\\u003c/li\\u003e\\n\\u003c/ul\\u003e\",\n        \"defaultValue\": true\n      },\n      {\n        \"type\": \"TEXT\",\n        \"name\": \"itemIdKey\",\n        \"displayName\": \"Custom Item ID Key\",\n        \"simpleValueType\": true,\n        \"help\": \"Optional.\\n\\u003cbr/\\u003e\\u003cbr/\\u003e\\nYou can specify a custom key, which will be used to set the content Item ID, by default \\u003ci\\u003eitem_id\\u003c/i\\u003e will be used. This may be useful if you are using WooCommerce extensions.\",\n        \"canBeEmptyString\": true,\n        \"enablingConditions\": [\n          {\n            \"paramName\": \"autoMapCustomData\",\n            \"paramValue\": false,\n            \"type\": \"NOT_EQUALS\"\n          }\n        ]\n      },\n      {\n        \"type\": \"SELECT\",\n        \"name\": \"customDataObject\",\n        \"displayName\": \"Custom Data Properties Object\",\n        \"macrosInSelect\": true,\n        \"selectItems\": [],\n        \"simpleValueType\": true,\n        \"help\": \"Provide an object with Custom Data Properties to merge with the fields below. Any conflicting properties will be overwritten.\",\n        \"notSetText\": \"(not set)\"\n      },\n      {\n        \"name\": \"customDataList\",\n        \"simpleTableColumns\": [\n          {\n            \"valueValidators\": [\n              {\n                \"type\": \"NON_EMPTY\"\n              }\n            ],\n            \"defaultValue\": \"\",\n            \"displayName\": \"Property Name\",\n            \"name\": \"name\",\n            \"isUnique\": true,\n            \"type\": \"TEXT\"\n          },\n          {\n            \"defaultValue\": \"\",\n            \"displayName\": \"Property Value\",\n            \"name\": \"value\",\n            \"type\": \"TEXT\"\n          }\n        ],\n        \"type\": \"SIMPLE_TABLE\",\n        \"newRowButtonText\": \"Add property\"\n      }\n    ]\n  },\n  {\n    \"type\": \"GROUP\",\n    \"name\": \"tagExecutionConsentSettingsGroup\",\n    \"displayName\": \"Tag Execution Consent Settings\",\n    \"groupStyle\": \"ZIPPY_CLOSED\",\n    \"subParams\": [\n      {\n        \"type\": \"RADIO\",\n        \"name\": \"adStorageConsent\",\n        \"radioItems\": [\n          {\n            \"value\": \"optional\",\n            \"displayValue\": \"Send data always\"\n          },\n          {\n            \"value\": \"required\",\n            \"displayValue\": \"Send data in case marketing consent given\",\n            \"help\": \"Aborts the tag execution if marketing consent (\\u003ci\\u003ead_storage\\u003c/i\\u003e Google Consent Mode or Stape\\u0027s Data Tag parameter) is not given.\"\n          }\n        ],\n        \"simpleValueType\": true,\n        \"defaultValue\": \"optional\"\n      }\n    ]\n  },\n  {\n    \"displayName\": \"Logs Settings\",\n    \"name\": \"logsGroup\",\n    \"groupStyle\": \"ZIPPY_CLOSED\",\n    \"type\": \"GROUP\",\n    \"subParams\": [\n      {\n        \"type\": \"RADIO\",\n        \"name\": \"logType\",\n        \"radioItems\": [\n          {\n            \"value\": \"no\",\n            \"displayValue\": \"Do not log\"\n          },\n          {\n            \"value\": \"debug\",\n            \"displayValue\": \"Log to console during debug and preview\"\n          },\n          {\n            \"value\": \"always\",\n            \"displayValue\": \"Always log to console\"\n          }\n        ],\n        \"simpleValueType\": true,\n        \"defaultValue\": \"debug\"\n      }\n    ]\n  },\n  {\n    \"displayName\": \"BigQuery Logs Settings\",\n    \"name\": \"bigQueryLogsGroup\",\n    \"groupStyle\": \"ZIPPY_CLOSED\",\n    \"type\": \"GROUP\",\n    \"subParams\": [\n      {\n        \"type\": \"RADIO\",\n        \"name\": \"bigQueryLogType\",\n        \"radioItems\": [\n          {\n            \"value\": \"no\",\n            \"displayValue\": \"Do not log to BigQuery\"\n          },\n          {\n            \"value\": \"always\",\n            \"displayValue\": \"Log to BigQuery\"\n          }\n        ],\n        \"simpleValueType\": true,\n        \"defaultValue\": \"no\"\n      },\n      {\n        \"type\": \"GROUP\",\n        \"name\": \"logsBigQueryConfigGroup\",\n        \"groupStyle\": \"NO_ZIPPY\",\n        \"subParams\": [\n          {\n            \"type\": \"TEXT\",\n            \"name\": \"logBigQueryProjectId\",\n            \"displayName\": \"BigQuery Project ID\",\n            \"simpleValueType\": true,\n            \"help\": \"Optional.  \\u003cbr\\u003e\\u003cbr\\u003e  If omitted, it will be retrieved from the environment variable \\u003cI\\u003eGOOGLE_CLOUD_PROJECT\\u003c/i\\u003e where the server container is running. If the server container is running on Google Cloud, \\u003cI\\u003eGOOGLE_CLOUD_PROJECT\\u003c/i\\u003e will already be set to the Google Cloud project\\u0027s ID.\"\n          },\n          {\n            \"type\": \"TEXT\",\n            \"name\": \"logBigQueryDatasetId\",\n            \"displayName\": \"BigQuery Dataset ID\",\n            \"simpleValueType\": true,\n            \"valueValidators\": [\n              {\n                \"type\": \"NON_EMPTY\"\n              }\n            ]\n          },\n          {\n            \"type\": \"TEXT\",\n            \"name\": \"logBigQueryTableId\",\n            \"displayName\": \"BigQuery Table ID\",\n            \"simpleValueType\": true,\n            \"valueValidators\": [\n              {\n                \"type\": \"NON_EMPTY\"\n              }\n            ]\n          }\n        ],\n        \"enablingConditions\": [\n          {\n            \"paramName\": \"bigQueryLogType\",\n            \"paramValue\": \"always\",\n            \"type\": \"EQUALS\"\n          }\n        ]\n      }\n    ]\n  },\n  {\n    \"type\": \"GROUP\",\n    \"name\": \"moreSettingsGroup\",\n    \"displayName\": \"More Settings\",\n    \"groupStyle\": \"ZIPPY_OPEN_ON_PARAM\",\n    \"subParams\": [\n      {\n        \"type\": \"CHECKBOX\",\n        \"name\": \"useAppSecretProof\",\n        \"checkboxText\": \"Use App Secret Proof\",\n        \"simpleValueType\": true,\n        \"help\": \"Optional. \\u003cbr/\\u003e\\u003cbr/\\u003e Use this field only if your Business Manager’s Conversions API Application requires API calls to include the \\u003ci\\u003eapp secret proof\\u003c/i\\u003e.   \\u003cbr/\\u003e\\u003cbr/\\u003e You’ll encounter this requirement if event requests fail with the error:  \\u003ci\\u003e\\\"API calls from the server require an appsecret_proof argument\\\"\\u003c/i\\u003e. \\u003cbr/\\u003e\\u003cbr/\\u003e \\u003ca href\\u003d\\\"https://developers.facebook.com/docs/graph-api/guides/secure-requests#appsecret_proof\\\"\\u003eLearn more\\u003c/a\\u003e about how to generate this value.\",\n        \"subParams\": [\n          {\n            \"type\": \"TEXT\",\n            \"name\": \"appSecretProof\",\n            \"displayName\": \"App Secret Proof\",\n            \"simpleValueType\": true,\n            \"enablingConditions\": [\n              {\n                \"paramName\": \"useAppSecretProof\",\n                \"paramValue\": true,\n                \"type\": \"EQUALS\"\n              }\n            ],\n            \"valueValidators\": [\n              {\n                \"type\": \"NON_EMPTY\"\n              }\n            ]\n          }\n        ]\n      },\n      {\n        \"type\": \"CHECKBOX\",\n        \"name\": \"mapViewItemListToViewContent\",\n        \"checkboxText\": \"Automap GA4 \\\"view_item_list\\\" event to \\\"ViewContent\\\"\",\n        \"simpleValueType\": true,\n        \"defaultValue\": false,\n        \"help\": \"When enabled with \\\"Inherit from client\\\" \\u003ci\\u003eEvent Name Setup Method\\u003c/i\\u003e:\\n\\u003cul\\u003e\\n\\u003cli\\u003eMaps the GA4 \\\"view_item_list\\\" event to \\\"ViewContent\\\".\\u003c/li\\u003e\\n\\u003cli\\u003eSets \\\"content_type\\\" to \\\"product_group\\\" if an items array is present.\\u003c/li\\u003e\\n\\u003c/ul\\u003e\",\n        \"enablingConditions\": [\n          {\n            \"paramName\": \"inheritEventName\",\n            \"paramValue\": \"inherit\",\n            \"type\": \"EQUALS\"\n          }\n        ]\n      }\n    ]\n  }\n]\n\n\n___SANDBOXED_JS_FOR_SERVER___\n\nconst BigQuery = require('BigQuery');\nconst computeEffectiveTldPlusOne = require('computeEffectiveTldPlusOne');\nconst createRegex = require('createRegex');\nconst decodeUriComponent = require('decodeUriComponent');\nconst encodeUriComponent = require('encodeUriComponent');\nconst fromBase64 = require('fromBase64');\nconst generateRandom = require('generateRandom');\nconst getAllEventData = require('getAllEventData');\nconst getContainerVersion = require('getContainerVersion');\nconst getCookieValues = require('getCookieValues');\nconst getRequestHeader = require('getRequestHeader');\nconst getTimestampMillis = require('getTimestampMillis');\nconst getType = require('getType');\nconst JSON = require('JSON');\nconst logToConsole = require('logToConsole');\nconst makeNumber = require('makeNumber');\nconst makeString = require('makeString');\nconst Math = require('Math');\nconst parseUrl = require('parseUrl');\nconst Promise = require('Promise');\nconst sendHttpRequest = require('sendHttpRequest');\nconst setCookie = require('setCookie');\nconst sha256Sync = require('sha256Sync');\nconst testRegex = require('testRegex');\nconst toBase64 = require('toBase64');\n\n/*==============================================================================\n==============================================================================*/\n\nconst eventData = getAllEventData();\nconst API_VERSION = '25.0';\nconst PARTNER_AGENT_STRING = 'stape-gtmss-2.1.4' + (data.enableEventEnhancement ? '-ee' : '');\n\nif (shouldExitEarly(data, eventData)) {\n  return data.gtmOnSuccess();\n}\n\nconst ids = getClickAndBrowserId(data, eventData);\nconst fbc = ids.fbc;\nconst fbp = ids.fbp;\nsetCookies(data, fbc, fbp);\n\nconst mappedPostBody = mapEvent(data, eventData, fbc, fbp);\n\nlet pixelsConfig = [\n  {\n    pixelId: data.pixelId,\n    accessToken: data.accessToken,\n    appSecretProof: data.useAppSecretProof ? data.appSecretProof : undefined\n  }\n];\nif (data.enableMultipixelSetup) {\n  pixelsConfig = pixelsConfig.concat(data.pixelIdAndAccessTokenTable);\n}\n\nconst requests = pixelsConfig.map((pixelConfig) => {\n  const pixelId = pixelConfig.pixelId;\n  const accessToken = pixelConfig.accessToken;\n  const appSecretProof = pixelConfig.appSecretProof;\n  const postUrl =\n    'https://graph.facebook.com/v' +\n    API_VERSION +\n    '/' +\n    enc(pixelId) +\n    '/events?access_token=' +\n    enc(accessToken) +\n    (appSecretProof ? '&appsecret_proof=' + enc(appSecretProof) : '');\n\n  log({\n    Name: 'Facebook',\n    Type: 'Request',\n    EventName: mappedPostBody.data[0].event_name,\n    RequestMethod: 'POST',\n    RequestUrl: postUrl,\n    RequestBody: mappedPostBody\n  });\n\n  return sendHttpRequest(\n    postUrl,\n    { headers: { 'content-type': 'application/json' }, method: 'POST' },\n    JSON.stringify(mappedPostBody)\n  )\n    .then((result) => {\n      log({\n        Name: 'Facebook',\n        Type: 'Response',\n        EventName: mappedPostBody.data[0].event_name,\n        ResponseStatusCode: result.statusCode,\n        ResponseHeaders: result.headers,\n        ResponseBody: result.body,\n        Message: 'Pixel ID: ' + pixelId\n      });\n\n      if (result.statusCode < 200 || result.statusCode >= 300) return false;\n      return true;\n    })\n    .catch((result) => {\n      log({\n        Name: 'Facebook',\n        Type: 'Response',\n        EventName: mappedPostBody.data[0].event_name,\n        Message: 'Request failed or timed out. Pixel ID: ' + pixelId,\n        Reason: JSON.stringify(result)\n      });\n\n      return false;\n    });\n});\n\nPromise.all(requests)\n  .then((results) => {\n    if (!data.useOptimisticScenario) {\n      const someRequestFailed = results.some((success) => !success);\n      if (someRequestFailed) return data.gtmOnFailure();\n      return data.gtmOnSuccess();\n    }\n  })\n  .catch((result) => {\n    log({\n      Name: 'Facebook',\n      Type: 'Message',\n      EventName: mappedPostBody.data[0].event_name,\n      Message: 'Something went wrong.',\n      Reason: JSON.stringify(result)\n    });\n\n    if (!data.useOptimisticScenario) return data.gtmOnFailure();\n  });\n\nif (data.useOptimisticScenario) {\n  return data.gtmOnSuccess();\n}\n\n/*==============================================================================\n  Vendor related functions\n==============================================================================*/\n\nfunction setCookies(data, fbc, fbp) {\n  const cookieOptions = {\n    domain: isUIFieldTrue(data.overrideCookieDomain)\n      ? data.overridenCookieDomain || 'auto'\n      : 'auto',\n    path: '/',\n    samesite: 'Lax',\n    secure: true,\n    'max-age': 7776000, // 90 days\n    HttpOnly: !!data.useHttpOnlyCookie\n  };\n\n  if (fbc) {\n    setCookie('_fbc', fbc, cookieOptions);\n  }\n\n  if (fbp) {\n    setCookie('_fbp', fbp, cookieOptions);\n  }\n}\n\nfunction getClickAndBrowserId(data, eventData) {\n  const ids = {\n    fbc:\n      getCookieValues('_fbc')[0] ||\n      (eventData.common_cookie || {})._fbc ||\n      eventData._fbc ||\n      eventData.fbc,\n    fbp:\n      getCookieValues('_fbp')[0] ||\n      (eventData.common_cookie || {})._fbp ||\n      eventData._fbp ||\n      eventData.fbp\n  };\n\n  const url = getUrl(eventData);\n  const subDomainIndex = url ? computeEffectiveTldPlusOne(url).split('.').length - 1 : 1;\n\n  if (url) {\n    const urlParsed = parseUrl(url);\n    if (urlParsed && urlParsed.searchParams.fbclid) {\n      if (\n        !ids.fbc ||\n        (ids.fbc &&\n          ids.fbc.split('.')[ids.fbc.split('.').length - 1] !==\n            decodeUriComponent(urlParsed.searchParams.fbclid))\n      ) {\n        ids.fbc =\n          'fb.' +\n          subDomainIndex +\n          '.' +\n          getTimestampMillis() +\n          '.' +\n          decodeUriComponent(urlParsed.searchParams.fbclid);\n      }\n    }\n  }\n\n  if (!ids.fbp && data.generateFbp) {\n    ids.fbp =\n      'fb.' +\n      subDomainIndex +\n      '.' +\n      getTimestampMillis() +\n      '.' +\n      generateRandom(1000000000, 2147483647);\n  }\n\n  return ids;\n}\n\nfunction getEventName(data) {\n  if (data.inheritEventName === 'inherit') {\n    const eventName = eventData.event_name;\n\n    const gaToFacebookEventName = {\n      page_view: 'PageView',\n      'gtm.dom': 'PageView',\n      add_payment_info: 'AddPaymentInfo',\n      add_to_cart: 'AddToCart',\n      add_to_wishlist: 'AddToWishlist',\n      sign_up: 'CompleteRegistration',\n      begin_checkout: 'InitiateCheckout',\n      generate_lead: 'Lead',\n      purchase: 'Purchase',\n      search: 'Search',\n      view_item: 'ViewContent',\n\n      contact: 'Contact',\n      customize_product: 'CustomizeProduct',\n      donate: 'Donate',\n      find_location: 'FindLocation',\n      schedule: 'Schedule',\n      start_trial: 'StartTrial',\n      submit_application: 'SubmitApplication',\n      subscribe: 'Subscribe',\n\n      'gtm4wp.addProductToCartEEC': 'AddToCart',\n      'gtm4wp.productClickEEC': 'ViewContent',\n      'gtm4wp.checkoutOptionEEC': 'InitiateCheckout',\n      'gtm4wp.checkoutStepEEC': 'AddPaymentInfo',\n      'gtm4wp.orderCompletedEEC': 'Purchase'\n    };\n\n    if (data.mapViewItemListToViewContent) {\n      gaToFacebookEventName.view_item_list = 'ViewContent';\n    }\n\n    return gaToFacebookEventName[eventName] || eventName;\n  }\n\n  return data.eventName === 'standard' ? data.eventNameStandard : data.eventNameCustom;\n}\n\nfunction mapEvent(data, eventData, fbc, fbp) {\n  let mappedData = {\n    event_name: getEventName(data),\n    action_source: data.actionSource || 'website',\n    event_time: Math.round(getTimestampMillis() / 1000),\n    custom_data: {},\n    user_data: {}\n  };\n  const mappedPostBody = {\n    data: [mappedData],\n    partner_agent: PARTNER_AGENT_STRING\n  };\n\n  if (eventData.test_event_code || data.testId) {\n    mappedPostBody.test_event_code = eventData.test_event_code\n      ? eventData.test_event_code\n      : data.testId;\n  }\n\n  if (mappedData.action_source === 'app') {\n    mappedData.app_data = {};\n  }\n\n  if (mappedData.action_source === 'business_messaging') {\n    mappedData.messaging_channel = data.messaging_channel;\n  }\n\n  mappedData = addServerEventData(data, eventData, mappedData);\n  mappedData = addUserData(data, eventData, mappedData, fbc, fbp);\n  mappedData = addAppData(data, eventData, mappedData);\n  mappedData = addEcommerceData(data, eventData, mappedData);\n  mappedData = addOriginalEventData(mappedData);\n  mappedData = overrideDataIfNeeded(mappedData);\n  mappedData = cleanupData(mappedData);\n  mappedData = hashDataIfNeeded(mappedData);\n\n  if (data.enableEventEnhancement) {\n    mappedData.user_data = enhanceEventData(eventData, mappedData.user_data);\n    setGtmEecCookie(mappedData.user_data);\n  }\n\n  return mappedPostBody;\n}\n\nfunction hashData(key, value) {\n  if (!value) {\n    return value;\n  }\n\n  const type = getType(value);\n\n  if (type === 'undefined' || value === 'undefined') {\n    return undefined;\n  }\n\n  if (type === 'array') {\n    return value.map((val) => {\n      return hashData(key, val);\n    });\n  }\n\n  if (isHashed(value)) {\n    return value;\n  }\n\n  value = makeString(value).trim().toLowerCase();\n\n  if (key === 'ph') {\n    value = normalizePhoneNumber(value);\n  } else if (key === 'ct') {\n    value = value.split(' ').join('');\n  }\n\n  return sha256Sync(value, { outputEncoding: 'hex' });\n}\n\nfunction hashDataIfNeeded(mappedData) {\n  if (mappedData.user_data) {\n    const keysToHash = [\n      'em',\n      'ph',\n      'ge',\n      'db',\n      'ln',\n      'fn',\n      'ct',\n      'st',\n      'zp',\n      'country',\n      'external_id'\n    ];\n    for (let key in mappedData.user_data) {\n      if (keysToHash.indexOf(key) !== -1) {\n        mappedData.user_data[key] = hashData(key, mappedData.user_data[key]);\n      }\n    }\n  }\n\n  return mappedData;\n}\n\nfunction overrideDataIfNeeded(mappedData) {\n  if (getType(data.userDataObject) === 'object') {\n    mergeObj(mappedData.user_data, data.userDataObject);\n  }\n  if (data.userDataList) {\n    data.userDataList.forEach((d) => {\n      mappedData.user_data[d.name] = d.value;\n    });\n  }\n\n  if (getType(data.customDataObject) === 'object') {\n    mergeObj(mappedData.custom_data, data.customDataObject);\n  }\n  if (data.customDataList) {\n    data.customDataList.forEach((d) => {\n      mappedData.custom_data[d.name] = d.value;\n    });\n  }\n\n  if (mappedData.action_source === 'app') {\n    if (getType(data.appDataObject) === 'object') {\n      mergeObj(mappedData.app_data, data.appDataObject);\n    }\n    if (data.appDataList) {\n      data.appDataList.forEach((d) => {\n        mappedData.app_data[d.name] = d.value;\n      });\n    }\n  }\n\n  return mappedData;\n}\n\nfunction cleanupData(mappedData) {\n  if (mappedData.action_source === 'business_messaging') {\n    mappedData.event_source_url = undefined;\n    ['client_ip_address', 'client_user_agent', 'fbc', 'fbp'].forEach(\n      (key) => (mappedData.user_data[key] = undefined)\n    );\n  }\n\n  if (mappedData.user_data) {\n    const userData = {};\n\n    for (let userDataKey in mappedData.user_data) {\n      if (isValidValue(mappedData.user_data[userDataKey])) {\n        userData[userDataKey] = mappedData.user_data[userDataKey];\n      }\n    }\n\n    mappedData.user_data = userData;\n  }\n\n  if (mappedData.custom_data) {\n    const customData = {};\n\n    for (let customDataKey in mappedData.custom_data) {\n      if (isValidValue(mappedData.custom_data[customDataKey])) {\n        customData[customDataKey] = mappedData.custom_data[customDataKey];\n      }\n    }\n\n    if (customData.value === 0 || customData.value === '0') customData.value = '0.00';\n\n    mappedData.custom_data = customData;\n  }\n\n  if (mappedData.app_data) {\n    const appData = {};\n\n    for (let appDataKey in mappedData.app_data) {\n      if (isValidValue(mappedData.app_data[appDataKey])) {\n        appData[appDataKey] = mappedData.app_data[appDataKey];\n      }\n    }\n\n    mappedData.app_data = appData;\n  }\n\n  if (mappedData.original_event_data) {\n    const originalEventData = {};\n\n    for (let originalEventDataKey in mappedData.original_event_data) {\n      if (isValidValue(mappedData.original_event_data[originalEventDataKey])) {\n        originalEventData[originalEventDataKey] =\n          mappedData.original_event_data[originalEventDataKey];\n      }\n    }\n\n    mappedData.original_event_data = originalEventData;\n  }\n\n  return mappedData;\n}\n\nfunction addEcommerceData(data, eventData, mappedData) {\n  const autoMapEnabled = data.hasOwnProperty('autoMapCustomData') ? data.autoMapCustomData : true; // To avoid a breaking change.\n  if (autoMapEnabled) {\n    let currencyFromItems = '';\n    let valueFromItems = 0;\n\n    let items;\n    if (getType(eventData.items) === 'array' && eventData.items.length) items = eventData.items;\n    else if (\n      getType(eventData.ecommerce) === 'object' &&\n      getType(eventData.ecommerce.items) === 'array' &&\n      eventData.ecommerce.items.length\n    ) {\n      items = eventData.ecommerce.items;\n    }\n\n    if (items) {\n      currencyFromItems = items[0].currency;\n\n      mappedData.custom_data.contents = [];\n      mappedData.custom_data.content_type =\n        eventData['x-fb-cd-content_type'] || eventData.content_type || 'product';\n\n      if (\n        data.mapViewItemListToViewContent &&\n        data.inheritEventName === 'inherit' &&\n        eventData.event_name === 'view_item_list'\n      ) {\n        mappedData.custom_data.content_type = 'product_group';\n      }\n\n      if (!items[1]) {\n        if (items[0].item_name) mappedData.custom_data.content_name = items[0].item_name;\n        if (items[0].item_category)\n          mappedData.custom_data.content_category = items[0].item_category;\n\n        if (items[0].price) {\n          mappedData.custom_data.value = items[0].quantity\n            ? items[0].quantity * items[0].price\n            : items[0].price;\n        }\n      }\n\n      const itemIdKey = data.itemIdKey ? data.itemIdKey : 'item_id';\n      items.forEach((d) => {\n        const content = {};\n        if (d[itemIdKey]) content.id = d[itemIdKey];\n        if (d.item_name) content.title = d.item_name;\n        if (d.item_brand) content.brand = d.item_brand;\n        if (d.quantity) content.quantity = d.quantity;\n        if (d.item_category) content.category = d.item_category;\n\n        if (d.price) {\n          content.item_price = makeNumber(d.price);\n          valueFromItems += d.quantity ? d.quantity * content.item_price : content.item_price;\n        }\n\n        mappedData.custom_data.contents.push(content);\n      });\n    }\n\n    const value = eventData['x-ga-mp1-ev'] || eventData['x-ga-mp1-tr'] || eventData.value;\n    if (value) mappedData.custom_data.value = value;\n\n    const currency = eventData.currency || currencyFromItems;\n    if (currency) mappedData.custom_data.currency = currency;\n\n    if (eventData.search_term) mappedData.custom_data.search_string = eventData.search_term;\n\n    if (eventData.transaction_id) mappedData.custom_data.order_id = eventData.transaction_id;\n\n    if (mappedData.event_name === 'Purchase') {\n      if (!mappedData.custom_data.currency) mappedData.custom_data.currency = 'USD';\n      if (!mappedData.custom_data.value)\n        mappedData.custom_data.value = valueFromItems ? valueFromItems : 0;\n    }\n  }\n\n  return mappedData;\n}\n\nfunction addUserData(data, eventData, mappedData, fbc, fbp) {\n  const autoMapEnabled = data.hasOwnProperty('autoMapUserData') ? data.autoMapUserData : true; // To avoid a breaking change.\n  if (autoMapEnabled) {\n    let address = {};\n    let user_data = {};\n    if (getType(eventData.user_data) === 'object') {\n      user_data = eventData.user_data;\n      const addressType = getType(user_data.address);\n      if (addressType === 'object' || addressType === 'array') {\n        address = user_data.address[0] || user_data.address;\n      }\n    }\n\n    if (fbc) mappedData.user_data.fbc = fbc;\n    if (fbp) mappedData.user_data.fbp = fbp;\n\n    if (eventData.user_agent) mappedData.user_data.client_user_agent = eventData.user_agent;\n\n    if (eventData.ip_override) {\n      mappedData.user_data.client_ip_address = eventData.ip_override\n        .split(' ')\n        .join('')\n        .split(',')[0];\n    }\n\n    if (eventData.fb_login_id) mappedData.user_data.fb_login_id = eventData.fb_login_id;\n\n    if (eventData.anon_id) mappedData.user_data.anon_id = eventData.anon_id;\n\n    if (eventData.madid) mappedData.user_data.madid = eventData.madid;\n\n    const externalId = eventData.external_id || eventData.user_id || eventData.userId;\n    if (externalId) mappedData.user_data.external_id = externalId;\n\n    const subscriptionId = eventData.subscription_id || eventData.subscriptionId;\n    if (subscriptionId) mappedData.user_data.subscription_id = subscriptionId;\n\n    const leadId = eventData.lead_id || eventData.leadId;\n    if (leadId) mappedData.user_data.lead_id = leadId;\n\n    const ln =\n      eventData.lastName ||\n      eventData.LastName ||\n      eventData.nameLast ||\n      eventData.last_name ||\n      user_data.last_name ||\n      address.last_name ||\n      address.sha256_last_name;\n    if (ln) mappedData.user_data.ln = ln;\n\n    const fn =\n      eventData.firstName ||\n      eventData.FirstName ||\n      eventData.nameFirst ||\n      eventData.first_name ||\n      user_data.first_name ||\n      address.first_name ||\n      address.sha256_first_name;\n    if (fn) mappedData.user_data.fn = fn;\n\n    const em =\n      eventData.email ||\n      user_data.email_address ||\n      user_data.email ||\n      user_data.sha256_email_address;\n    if (em) mappedData.user_data.em = em;\n\n    const ph = eventData.phone || user_data.phone_number || user_data.phone;\n    if (ph) mappedData.user_data.ph = ph;\n\n    const ct = eventData.city || address.city;\n    if (ct) mappedData.user_data.ct = ct;\n\n    const st = eventData.state || eventData.region || user_data.region || address.region;\n    if (st) mappedData.user_data.st = st;\n\n    const zp =\n      eventData.zip || eventData.postal_code || user_data.postal_code || address.postal_code;\n    if (zp) mappedData.user_data.zp = zp;\n\n    const country =\n      eventData.countryCode || eventData.country || user_data.country || address.country;\n    if (country) mappedData.user_data.country = country;\n\n    if (eventData.gender) mappedData.user_data.ge = eventData.gender;\n    if (eventData.db) mappedData.user_data.db = eventData.db;\n  }\n  return mappedData;\n}\n\nfunction addServerEventData(data, eventData, mappedData) {\n  const autoMapEnabled = data.hasOwnProperty('autoMapServerEventData')\n    ? data.autoMapServerEventData\n    : true; // To avoid a breaking change.\n  if (autoMapEnabled) {\n    if (eventData.page_location) mappedData.event_source_url = eventData.page_location;\n    if (eventData.page_referrer) mappedData.referrer_url = eventData.page_referrer;\n\n    const eventId = eventData.event_id || eventData.transaction_id;\n    if (eventId) mappedData.event_id = eventId;\n  }\n\n  if (data.serverEventDataList) {\n    data.serverEventDataList.forEach((d) => {\n      mappedData[d.name] = d.value;\n    });\n\n    if (\n      !mappedData.data_processing_options &&\n      (mappedData.data_processing_options_country || mappedData.data_processing_options_state)\n    ) {\n      mappedData.data_processing_options_country = undefined;\n      mappedData.data_processing_options_state = undefined;\n    }\n  }\n\n  return mappedData;\n}\n\nfunction addAppData(data, eventData, mappedData) {\n  if (mappedData.action_source !== 'app') {\n    return mappedData;\n  }\n\n  const autoMapEnabled = data.hasOwnProperty('autoMapAppData') ? data.autoMapAppData : true; // To avoid a breaking change.\n  if (autoMapEnabled) {\n    if (getType(eventData.app_data) === 'object') {\n      mappedData.app_data = eventData.app_data;\n      return mappedData;\n    }\n\n    mappedData.app_data.advertiser_tracking_enabled = eventData.advertiser_tracking_enabled ? 1 : 0; // Required\n    mappedData.app_data.application_tracking_enabled = eventData.application_tracking_enabled\n      ? 1\n      : 0; // Required\n    if (eventData.extinfo) {\n      mappedData.app_data.extinfo = eventData.extinfo;\n    } else {\n      const platform = makeString(eventData['x-ga-platform'] || '').toLowerCase();\n      const extinfoArray = [\n        platform === 'android' ? 'a2' : platform === 'ios' ? 'i2' : '', // Required\n        eventData.app_id || '',\n        eventData.app_version || '',\n        eventData.app_version ? 'Version ' + eventData.app_version : '',\n        makeString(eventData['x-ga-os_version'] || ''), // Required\n        eventData['x-ga-device_model'] || '',\n        eventData.language || '',\n        '',\n        '',\n        '',\n        '',\n        '',\n        '',\n        '',\n        '',\n        ''\n      ];\n      mappedData.app_data.extinfo = extinfoArray;\n    }\n    if (eventData.campaign_ids) mappedData.app_data.campaign_ids = eventData.campaign_ids;\n    if (eventData.install_referrer)\n      mappedData.app_data.install_referrer = eventData.install_referrer;\n    if (eventData.installer_package)\n      mappedData.app_data.installer_package = eventData.installer_package;\n    if (eventData.url_schemes) mappedData.app_data.url_schemes = eventData.url_schemes;\n    if (eventData.vendor_id) mappedData.app_data.vendor_id = eventData.vendor_id;\n    if (eventData.windows_attribution_id)\n      mappedData.app_data.windows_attribution_id = eventData.windows_attribution_id;\n  }\n\n  return mappedData;\n}\n\nfunction addOriginalEventData(mappedData) {\n  if (mappedData.event_name !== 'AppendValue') {\n    return mappedData;\n  }\n\n  if (data.originalEventDataList) {\n    mappedData.action_source = undefined;\n\n    mappedData.original_event_data = {};\n    data.originalEventDataList.forEach((d) => {\n      mappedData.original_event_data[d.name] = d.value;\n    });\n  }\n\n  return mappedData;\n}\n\nfunction setGtmEecCookie(userData) {\n  const gtmeecCookie = {};\n\n  if (userData.em) gtmeecCookie.em = userData.em;\n  if (userData.ph) gtmeecCookie.ph = userData.ph;\n  if (userData.ln) gtmeecCookie.ln = userData.ln;\n  if (userData.fn) gtmeecCookie.fn = userData.fn;\n  if (userData.ct) gtmeecCookie.ct = userData.ct;\n  if (userData.st) gtmeecCookie.st = userData.st;\n  if (userData.zp) gtmeecCookie.zp = userData.zp;\n  if (userData.ge) gtmeecCookie.ge = userData.ge;\n  if (userData.db) gtmeecCookie.db = userData.db;\n  if (userData.country) gtmeecCookie.country = userData.country;\n  if (userData.external_id) gtmeecCookie.external_id = userData.external_id;\n  if (userData.fb_login_id) gtmeecCookie.fb_login_id = userData.fb_login_id;\n\n  setCookie('_gtmeec', toBase64(JSON.stringify(gtmeecCookie)), {\n    domain: isUIFieldTrue(data.overrideCookieDomain)\n      ? data.overridenCookieDomain || 'auto'\n      : 'auto',\n    path: '/',\n    samesite: 'strict',\n    secure: true,\n    'max-age': 7776000, // 90 days\n    HttpOnly: true\n  });\n}\n\nfunction enhanceEventData(eventData, userData) {\n  const commonCookie = eventData.common_cookie || {};\n\n  const cookieValues = getCookieValues('_gtmeec');\n  if ((!cookieValues || cookieValues.length === 0) && !commonCookie._gtmeec) {\n    return userData;\n  }\n\n  const encodedValue = cookieValues[0] || commonCookie._gtmeec;\n  if (!encodedValue) {\n    return userData;\n  }\n\n  const jsonStr = fromBase64(encodedValue);\n  if (!jsonStr) {\n    return userData;\n  }\n\n  const gtmeecData = JSON.parse(jsonStr);\n\n  if (gtmeecData) {\n    if (!userData.em && gtmeecData.em) userData.em = gtmeecData.em;\n    if (!userData.ph && gtmeecData.ph) userData.ph = gtmeecData.ph;\n    if (!userData.ln && gtmeecData.ln) userData.ln = gtmeecData.ln;\n    if (!userData.fn && gtmeecData.fn) userData.fn = gtmeecData.fn;\n    if (!userData.ct && gtmeecData.ct) userData.ct = gtmeecData.ct;\n    if (!userData.st && gtmeecData.st) userData.st = gtmeecData.st;\n    if (!userData.zp && gtmeecData.zp) userData.zp = gtmeecData.zp;\n    if (!userData.ge && gtmeecData.ge) userData.ge = gtmeecData.ge;\n    if (!userData.db && gtmeecData.db) userData.db = gtmeecData.db;\n    if (!userData.country && gtmeecData.country) userData.country = gtmeecData.country;\n    if (!userData.external_id && gtmeecData.external_id)\n      userData.external_id = gtmeecData.external_id;\n    if (!userData.fb_login_id && gtmeecData.fb_login_id)\n      userData.fb_login_id = gtmeecData.fb_login_id;\n  }\n\n  return userData;\n}\n\n/*==============================================================================\n  Helpers\n==============================================================================*/\n\nfunction getUrl(eventData) {\n  return eventData.page_location || getRequestHeader('referer') || eventData.page_referrer;\n}\n\nfunction shouldExitEarly(data, eventData) {\n  if (!isConsentGivenOrNotRequired(data, eventData)) return true;\n\n  const url = getUrl(eventData);\n  if (url && url.lastIndexOf('https://gtm-msr.appspot.com/', 0) === 0) return true;\n\n  return false;\n}\n\nfunction enc(data) {\n  if (['null', 'undefined'].indexOf(getType(data)) !== -1) data = '';\n  return encodeUriComponent(makeString(data));\n}\n\nfunction isHashed(value) {\n  if (!value) return false;\n  return makeString(value).match('^[A-Fa-f0-9]{64}$') !== null;\n}\n\nfunction isValidValue(value) {\n  const valueType = getType(value);\n  return valueType !== 'null' && valueType !== 'undefined' && value !== '';\n}\n\nfunction normalizePhoneNumber(phoneNumber) {\n  if (!phoneNumber) return phoneNumber;\n  const itemRegex = createRegex('^[0-9]$');\n  return phoneNumber\n    .split('')\n    .filter((item) => testRegex(itemRegex, item))\n    .join('');\n}\n\nfunction isUIFieldTrue(field) {\n  return [true, 'true'].indexOf(field) !== -1;\n}\n\nfunction mergeObj(target, source) {\n  for (const key in source) {\n    if (source.hasOwnProperty(key)) target[key] = source[key];\n  }\n  return target;\n}\n\nfunction isConsentGivenOrNotRequired(data, eventData) {\n  if (data.adStorageConsent !== 'required') return true;\n  if (eventData.consent_state) return !!eventData.consent_state.ad_storage;\n  const xGaGcs = eventData['x-ga-gcs'] || ''; // x-ga-gcs is a string like \"G110\"\n  return xGaGcs[2] === '1';\n}\n\nfunction log(rawDataToLog) {\n  const logDestinationsHandlers = {};\n  if (determinateIsLoggingEnabled()) logDestinationsHandlers.console = logConsole;\n  if (determinateIsLoggingEnabledForBigQuery()) logDestinationsHandlers.bigQuery = logToBigQuery;\n\n  rawDataToLog.TraceId = getRequestHeader('trace-id');\n\n  const keyMappings = {\n    // No transformation for Console is needed.\n    bigQuery: {\n      Name: 'tag_name',\n      Type: 'type',\n      TraceId: 'trace_id',\n      EventName: 'event_name',\n      RequestMethod: 'request_method',\n      RequestUrl: 'request_url',\n      RequestBody: 'request_body',\n      ResponseStatusCode: 'response_status_code',\n      ResponseHeaders: 'response_headers',\n      ResponseBody: 'response_body'\n    }\n  };\n\n  for (const logDestination in logDestinationsHandlers) {\n    const handler = logDestinationsHandlers[logDestination];\n    if (!handler) continue;\n\n    const mapping = keyMappings[logDestination];\n    const dataToLog = mapping ? {} : rawDataToLog;\n\n    if (mapping) {\n      for (const key in rawDataToLog) {\n        const mappedKey = mapping[key] || key;\n        dataToLog[mappedKey] = rawDataToLog[key];\n      }\n    }\n\n    handler(dataToLog);\n  }\n}\n\nfunction logConsole(dataToLog) {\n  logToConsole(JSON.stringify(dataToLog));\n}\n\nfunction logToBigQuery(dataToLog) {\n  const connectionInfo = {\n    projectId: data.logBigQueryProjectId,\n    datasetId: data.logBigQueryDatasetId,\n    tableId: data.logBigQueryTableId\n  };\n\n  dataToLog.timestamp = getTimestampMillis();\n\n  ['request_body', 'response_headers', 'response_body'].forEach((p) => {\n    dataToLog[p] = JSON.stringify(dataToLog[p]);\n  });\n\n  BigQuery.insert(connectionInfo, [dataToLog], { ignoreUnknownValues: true });\n}\n\nfunction determinateIsLoggingEnabled() {\n  const containerVersion = getContainerVersion();\n  const isDebug = !!(\n    containerVersion &&\n    (containerVersion.debugMode || containerVersion.previewMode)\n  );\n\n  if (!data.logType) {\n    return isDebug;\n  }\n\n  if (data.logType === 'no') {\n    return false;\n  }\n\n  if (data.logType === 'debug') {\n    return isDebug;\n  }\n\n  return data.logType === 'always';\n}\n\nfunction determinateIsLoggingEnabledForBigQuery() {\n  if (data.bigQueryLogType === 'no') return false;\n  return data.bigQueryLogType === 'always';\n}\n\n\n___SERVER_PERMISSIONS___\n\n[\n  {\n    \"instance\": {\n      \"key\": {\n        \"publicId\": \"read_event_data\",\n        \"versionId\": \"1\"\n      },\n      \"param\": [\n        {\n          \"key\": \"eventDataAccess\",\n          \"value\": {\n            \"type\": 1,\n            \"string\": \"any\"\n          }\n        }\n      ]\n    },\n    \"clientAnnotations\": {\n      \"isEditedByUser\": true\n    },\n    \"isRequired\": true\n  },\n  {\n    \"instance\": {\n      \"key\": {\n        \"publicId\": \"set_cookies\",\n        \"versionId\": \"1\"\n      },\n      \"param\": [\n        {\n          \"key\": \"allowedCookies\",\n          \"value\": {\n            \"type\": 2,\n            \"listItem\": [\n              {\n                \"type\": 3,\n                \"mapKey\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"name\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"domain\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"path\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"secure\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"session\"\n                  }\n                ],\n                \"mapValue\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"_fbc\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"*\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"*\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"any\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"any\"\n                  }\n                ]\n              },\n              {\n                \"type\": 3,\n                \"mapKey\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"name\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"domain\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"path\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"secure\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"session\"\n                  }\n                ],\n                \"mapValue\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"_fbp\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"*\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"*\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"any\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"any\"\n                  }\n                ]\n              },\n              {\n                \"type\": 3,\n                \"mapKey\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"name\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"domain\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"path\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"secure\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"session\"\n                  }\n                ],\n                \"mapValue\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"_gtmeec\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"*\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"*\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"any\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"any\"\n                  }\n                ]\n              }\n            ]\n          }\n        }\n      ]\n    },\n    \"clientAnnotations\": {\n      \"isEditedByUser\": true\n    },\n    \"isRequired\": true\n  },\n  {\n    \"instance\": {\n      \"key\": {\n        \"publicId\": \"send_http\",\n        \"versionId\": \"1\"\n      },\n      \"param\": [\n        {\n          \"key\": \"allowedUrls\",\n          \"value\": {\n            \"type\": 1,\n            \"string\": \"specific\"\n          }\n        },\n        {\n          \"key\": \"urls\",\n          \"value\": {\n            \"type\": 2,\n            \"listItem\": [\n              {\n                \"type\": 1,\n                \"string\": \"https://graph.facebook.com/\"\n              }\n            ]\n          }\n        }\n      ]\n    },\n    \"clientAnnotations\": {\n      \"isEditedByUser\": true\n    },\n    \"isRequired\": true\n  },\n  {\n    \"instance\": {\n      \"key\": {\n        \"publicId\": \"get_cookies\",\n        \"versionId\": \"1\"\n      },\n      \"param\": [\n        {\n          \"key\": \"cookieAccess\",\n          \"value\": {\n            \"type\": 1,\n            \"string\": \"specific\"\n          }\n        },\n        {\n          \"key\": \"cookieNames\",\n          \"value\": {\n            \"type\": 2,\n            \"listItem\": [\n              {\n                \"type\": 1,\n                \"string\": \"_fbc\"\n              },\n              {\n                \"type\": 1,\n                \"string\": \"_fbp\"\n              },\n              {\n                \"type\": 1,\n                \"string\": \"_gtmeec\"\n              }\n            ]\n          }\n        }\n      ]\n    },\n    \"clientAnnotations\": {\n      \"isEditedByUser\": true\n    },\n    \"isRequired\": true\n  },\n  {\n    \"instance\": {\n      \"key\": {\n        \"publicId\": \"logging\",\n        \"versionId\": \"1\"\n      },\n      \"param\": [\n        {\n          \"key\": \"environments\",\n          \"value\": {\n            \"type\": 1,\n            \"string\": \"all\"\n          }\n        }\n      ]\n    },\n    \"clientAnnotations\": {\n      \"isEditedByUser\": true\n    },\n    \"isRequired\": true\n  },\n  {\n    \"instance\": {\n      \"key\": {\n        \"publicId\": \"read_container_data\",\n        \"versionId\": \"1\"\n      },\n      \"param\": []\n    },\n    \"isRequired\": true\n  },\n  {\n    \"instance\": {\n      \"key\": {\n        \"publicId\": \"read_request\",\n        \"versionId\": \"1\"\n      },\n      \"param\": [\n        {\n          \"key\": \"headerWhitelist\",\n          \"value\": {\n            \"type\": 2,\n            \"listItem\": [\n              {\n                \"type\": 3,\n                \"mapKey\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"headerName\"\n                  }\n                ],\n                \"mapValue\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"trace-id\"\n                  }\n                ]\n              },\n              {\n                \"type\": 3,\n                \"mapKey\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"headerName\"\n                  }\n                ],\n                \"mapValue\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"referer\"\n                  }\n                ]\n              }\n            ]\n          }\n        },\n        {\n          \"key\": \"headersAllowed\",\n          \"value\": {\n            \"type\": 8,\n            \"boolean\": true\n          }\n        },\n        {\n          \"key\": \"requestAccess\",\n          \"value\": {\n            \"type\": 1,\n            \"string\": \"specific\"\n          }\n        },\n        {\n          \"key\": \"headerAccess\",\n          \"value\": {\n            \"type\": 1,\n            \"string\": \"specific\"\n          }\n        },\n        {\n          \"key\": \"queryParameterAccess\",\n          \"value\": {\n            \"type\": 1,\n            \"string\": \"any\"\n          }\n        }\n      ]\n    },\n    \"clientAnnotations\": {\n      \"isEditedByUser\": true\n    },\n    \"isRequired\": true\n  },\n  {\n    \"instance\": {\n      \"key\": {\n        \"publicId\": \"access_bigquery\",\n        \"versionId\": \"1\"\n      },\n      \"param\": [\n        {\n          \"key\": \"allowedTables\",\n          \"value\": {\n            \"type\": 2,\n            \"listItem\": [\n              {\n                \"type\": 3,\n                \"mapKey\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"projectId\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"datasetId\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"tableId\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"operation\"\n                  }\n                ],\n                \"mapValue\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"*\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"*\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"*\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"write\"\n                  }\n                ]\n              }\n            ]\n          }\n        }\n      ]\n    },\n    \"clientAnnotations\": {\n      \"isEditedByUser\": true\n    },\n    \"isRequired\": true\n  }\n]\n\n\n___TESTS___\n\nscenarios:\n- name: Check semantical errors\n  code: \"mock('sendHttpRequest', (requestUrl, requestOptions, requestBody) => {\\n\\\n    \\  return {\\n    then: (callback) => { \\n      callback({ statusCode: 200 });\\n\\\n    \\      return {\\n        then: () => {},\\n        catch: () => {}\\n      };\\n\\\n    \\    },\\n    catch: (callback) => callback()\\n  };\\n});\\n\\nrunCode(mockData);\"\n- name: '[Cookie] Cookie domain is NOT overriden when option is NOT selected'\n  code: |-\n    mockData.overrideCookieDomain = false;\n    mockData.enableEventEnhancement = true;\n\n    const expectedFbp = 'expectedFbp';\n    const expectedFbc = 'expectedFbc';\n    mock('getAllEventData', {\n      _fbp: expectedFbp,\n      _fbc: expectedFbc\n    });\n\n    mock('setCookie', (cookieName, cookieValue, cookieOptions, noEncode) => {\n      switch (cookieName) {\n        case '_fbp':\n        case '_fbc':\n        case '_gtmeec':\n          if (cookieOptions.domain !== 'auto') fail('cookieDomain shouldn\\'t have been overriden');\n          break;\n      }\n    });\n\n    runCode(mockData);\n\n    callLater(() => {\n      assertApi('gtmOnSuccess').wasCalled();\n      assertApi('gtmOnFailure').wasNotCalled();\n    });\n- name: '[Cookie] Cookie domain is overriden when option is selected'\n  code: |-\n    mockData.overrideCookieDomain = true;\n    mockData.overridenCookieDomain = 'example.com';\n    mockData.enableEventEnhancement = true;\n\n    const expectedFbp = 'expectedFbp';\n    const expectedFbc = 'expectedFbc';\n    mock('getAllEventData', {\n      _fbp: expectedFbp,\n      _fbc: expectedFbc\n    });\n\n    mock('setCookie', (cookieName, cookieValue, cookieOptions, noEncode) => {\n      switch (cookieName) {\n        case '_fbp':\n        case '_fbc':\n        case '_gtmeec':\n          assertThat(cookieOptions.domain).isEqualTo(mockData.overridenCookieDomain);\n          break;\n      }\n    });\n\n    runCode(mockData);\n\n    callLater(() => {\n      assertApi('gtmOnSuccess').wasCalled();\n      assertApi('gtmOnFailure').wasNotCalled();\n    });\n- name: '[Action Source = App] Request is sent successfully when using Event Data\n    as source'\n  code: \"mockData.generateFbp = false;\\nmockData.actionSource = 'app';\\nmockData.appDataList\\\n    \\ = undefined;\\n\\nmock('getAllEventData', {\\n  app_data: {\\n    advertiser_tracking_enabled:\\\n    \\ 1,\\n    application_tracking_enabled: 0,\\n    extinfo: [\\n      'a2',\\n    \\\n    \\  'app_id',\\n      'app_version',\\n      'Version app_version',\\n      'os_version',\\n\\\n    \\      'device_model',\\n      'language',\\n      '',\\n      '',\\n      '',\\n \\\n    \\     '',\\n      '',\\n      '',\\n      '',\\n      '',\\n      ''\\n    ],\\n    campaign_ids:\\\n    \\ 'expected-campaign_ids',\\n    install_referrer: 'expected-install_referrer',\\n\\\n    \\    installer_package: 'expected-installer_package', \\n    url_schemes: ['foobar',\\\n    \\ 'abcdef'],\\n    vendor_id: 'expected-vendor_id',\\n    windows_attribution_id:\\\n    \\ 'expected-windows_attribution_id'\\n  }\\n});\\n\\nconst expectedRequestBody = {\\n\\\n    \\  data: [\\n    {\\n      event_name: 'test',\\n      action_source: 'app',\\n  \\\n    \\    event_time: 1747945830,\\n      custom_data: {},\\n      user_data: {},\\n \\\n    \\     app_data: {\\n        advertiser_tracking_enabled: 1,\\n        application_tracking_enabled:\\\n    \\ 0,\\n        extinfo: [\\n          'a2',\\n          'app_id',\\n          'app_version',\\n\\\n    \\          'Version app_version',\\n          'os_version',\\n          'device_model',\\n\\\n    \\          'language',\\n          '',\\n          '',\\n          '',\\n        \\\n    \\  '',\\n          '',\\n          '',\\n          '',\\n          '',\\n         \\\n    \\ ''\\n        ],\\n        campaign_ids: 'expected-campaign_ids',\\n        install_referrer:\\\n    \\ 'expected-install_referrer',\\n        installer_package: 'expected-installer_package',\\n\\\n    \\        url_schemes: ['foobar', 'abcdef'],\\n        vendor_id: 'expected-vendor_id',\\n\\\n    \\        windows_attribution_id: 'expected-windows_attribution_id'\\n      }\\n\\\n    \\    }\\n  ],\\n  partner_agent: expectedPartnerAgent\\n};\\n\\nmock('sendHttpRequest',\\\n    \\ (requestUrl, requestOptions, requestBody) => {\\n  const parsedBody = JSON.parse(requestBody);\\n\\\n    \\  assertThat(parsedBody).isEqualTo(expectedRequestBody);\\n  return Promise.create((resolve,\\\n    \\ reject) => {\\n    resolve({ statusCode: 200 });\\n  });    \\n});\\n\\nrunCode(mockData);\\n\\\n    \\ncallLater(() => {\\n  assertApi('gtmOnSuccess').wasCalled();\\n  assertApi('gtmOnFailure').wasNotCalled();\\n\\\n    });\"\n- name: '[Action Source = App] Request is sent successfully when using UI data as\n    source'\n  code: \"mockData.generateFbp = false;\\nmockData.actionSource = 'app';\\nmockData.appDataList\\\n    \\ = [\\n  { name: 'advertiser_tracking_enabled', value: '1' },\\n  { name: 'application_tracking_enabled',\\\n    \\ value: '0' },\\n  { \\n   name: 'extinfo',\\n   value: \\n     [\\n      'a2',\\n\\\n    \\      'app_id',\\n      'app_version',\\n      'Version app_version',\\n      'os_version',\\n\\\n    \\      'device_model',\\n      'language',\\n      '',\\n      '',\\n      '',\\n \\\n    \\     '',\\n      '',\\n      '',\\n      '',\\n      '',\\n      ''\\n    ]\\n  },\\n\\\n    \\  { name: 'campaign_ids', value: 'expected-campaign_ids' },\\n  { name: 'install_referrer',\\\n    \\ value: 'expected-install_referrer' },\\n  { name: 'installer_package', value:\\\n    \\ 'expected-installer_package' }, \\n  { name: 'url_schemes', value: ['foobar',\\\n    \\ 'abcdef'] },\\n  { name: 'vendor_id', value: 'expected-vendor_id' },\\n  { name:\\\n    \\ 'windows_attribution_id', value: 'expected-windows_attribution_id' }\\n];\\n\\n\\\n    mock('getAllEventData', {});\\n\\nconst expectedRequestBody = {\\n  data: [\\n   \\\n    \\ {\\n      event_name: 'test',\\n      action_source: 'app',\\n      event_time:\\\n    \\ 1747945830,\\n      custom_data: {},\\n      user_data: {},\\n      app_data: {\\n\\\n    \\        advertiser_tracking_enabled: '1',\\n        application_tracking_enabled:\\\n    \\ '0',\\n        extinfo: [\\n          'a2',\\n          'app_id',\\n          'app_version',\\n\\\n    \\          'Version app_version',\\n          'os_version',\\n          'device_model',\\n\\\n    \\          'language',\\n          '',\\n          '',\\n          '',\\n        \\\n    \\  '',\\n          '',\\n          '',\\n          '',\\n          '',\\n         \\\n    \\ ''\\n        ],\\n        campaign_ids: 'expected-campaign_ids',\\n        install_referrer:\\\n    \\ 'expected-install_referrer',\\n        installer_package: 'expected-installer_package',\\n\\\n    \\        url_schemes: ['foobar', 'abcdef'],\\n        vendor_id: 'expected-vendor_id',\\n\\\n    \\        windows_attribution_id: 'expected-windows_attribution_id'\\n      }\\n\\\n    \\    }\\n  ],\\n  partner_agent: expectedPartnerAgent\\n};\\n\\nmock('sendHttpRequest',\\\n    \\ (requestUrl, requestOptions, requestBody) => {\\n  const parsedBody = JSON.parse(requestBody);\\n\\\n    \\  assertThat(parsedBody).isEqualTo(expectedRequestBody);\\n  return Promise.create((resolve,\\\n    \\ reject) => {\\n    resolve({ statusCode: 200 });\\n  });    \\n});\\n\\nrunCode(mockData);\\n\\\n    \\ncallLater(() => {\\n  assertApi('gtmOnSuccess').wasCalled();\\n  assertApi('gtmOnFailure').wasNotCalled();\\n\\\n    });\"\n- name: '[Event = AppendValue] Request is sent successfully'\n  code: \"mockData.inheritEventName = 'override';\\nmockData.eventNameCustom = 'AppendValue';\\n\\\n    mockData.generateFbp = false;\\nmockData.actionSource = 'website';\\nmockData.userDataList\\\n    \\ = [\\n  { name: 'em', value: 'test' },\\n  { name: 'ph', value: 'test' }\\n];\\n\\\n    mockData.customDataList = [\\n  { name: 'currency', value: 'BRL' },\\n  { name:\\\n    \\ 'net_revenue', value: 123 }\\n];\\nmockData.originalEventDataList = [\\n  { name:\\\n    \\ 'event_name', value: 'Purchase' },\\n  { name: 'event_time', value: 17555555\\\n    \\ },\\n  { name: 'order_id', value: 'foobar123' },\\n  { name: 'event_id', value:\\\n    \\ '1747945830' }\\n];\\n\\nmock('getAllEventData', {});\\n\\nconst expectedRequestBody\\\n    \\ = {\\n  data: [\\n    {\\n      event_name: 'AppendValue',\\n      event_time: 1747945830,\\n\\\n    \\      custom_data: { currency: 'BRL', net_revenue: 123 },\\n      user_data: {\\n\\\n    \\        em: '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08',\\n\\\n    \\        ph: 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'\\n\\\n    \\      },\\n      original_event_data: {\\n        event_name: 'Purchase',\\n   \\\n    \\     event_time: 17555555,\\n        order_id: 'foobar123',\\n        event_id:\\\n    \\ '1747945830'\\n      }\\n    }\\n  ],\\n  partner_agent: expectedPartnerAgent\\n\\\n    };\\n\\nmock('sendHttpRequest', (requestUrl, requestOptions, requestBody) => {\\n\\\n    \\  const parsedBody = JSON.parse(requestBody);\\n  assertThat(parsedBody).isEqualTo(expectedRequestBody);\\n\\\n    \\  return Promise.create((resolve, reject) => {\\n    resolve({ statusCode: 200\\\n    \\ });\\n  });    \\n});\\n\\nrunCode(mockData);\\n\\ncallLater(() => {\\n  assertApi('gtmOnSuccess').wasCalled();\\n\\\n    \\  assertApi('gtmOnFailure').wasNotCalled();\\n});\"\n- name: '[Parameters from Object or List] Parameters are read and sent succesfullly'\n  code: \"mockData.actionSource = 'app'; // Using 'app' just to have access to the\\\n    \\ App Data section.\\n\\n[\\n  // Object empty, list empty\\n  {\\n    mockDataObj:\\\n    \\ {\\n      appDataObject: undefined,\\n      appDataList: undefined,\\n      userDataObject:\\\n    \\ undefined,\\n      userDataList: undefined,\\n      customDataObject: undefined,\\n\\\n    \\      customDataList: undefined\\n    },\\n    expectedRequestBody: {\\n      appData:\\\n    \\ {\\n        advertiser_tracking_enabled: 0,\\n        application_tracking_enabled:\\\n    \\ 0,\\n        extinfo: ['', '', '', '', '', '', '', '', '', '', '', '', '', '',\\\n    \\ '', '']\\n      },\\n      userData: {},\\n      customData: {}\\n    }\\n  },\\n\\\n    \\  \\n  // Object empty, list not-empty\\n  {\\n    mockDataObj: {\\n      appDataObject:\\\n    \\ undefined,\\n      appDataList: [\\n        { name: 'vendor_id', value: 'vendor_id'\\\n    \\ },\\n        { name: 'campaign_ids', value: 'campaign_ids' }\\n      ],\\n    \\\n    \\  userDataObject: undefined,\\n      userDataList: [{ name: 'fn', value: 'test'\\\n    \\ }],\\n      customDataObject: undefined,\\n      customDataList: [\\n        {\\\n    \\ name: 'currency', value: 'BRL' },\\n        { name: 'net_revenue', value: 123\\\n    \\ },\\n        { name: 'test', value: 'test' }\\n      ]\\n    },\\n    expectedRequestBody:\\\n    \\ {\\n      appData: {\\n        advertiser_tracking_enabled: 0,\\n        application_tracking_enabled:\\\n    \\ 0,\\n        extinfo: ['', '', '', '', '', '', '', '', '', '', '', '', '', '',\\\n    \\ '', ''],\\n        vendor_id: 'vendor_id',\\n        campaign_ids: 'campaign_ids'\\n\\\n    \\      },\\n      userData: { fn: '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08'\\\n    \\ },\\n      customData: { currency: 'BRL', net_revenue: 123, test: 'test' }\\n\\\n    \\    }\\n  },\\n  \\n  // Object not-empty, list empty\\n  {\\n    mockDataObj: {\\n\\\n    \\      appDataObject: { vendor_id: 'vendor_id_obj' },\\n      appDataList: undefined,\\n\\\n    \\      userDataObject: { em: 'test@example.com_obj' },\\n      userDataList: undefined,\\n\\\n    \\      customDataObject: { test: 'test_obj' },\\n      customDataList: undefined\\n\\\n    \\    },\\n    expectedRequestBody: {\\n      appData: {\\n        advertiser_tracking_enabled:\\\n    \\ 0,\\n        application_tracking_enabled: 0,\\n        extinfo: ['', '', '',\\\n    \\ '', '', '', '', '', '', '', '', '', '', '', '', ''],\\n        vendor_id: 'vendor_id_obj'\\n\\\n    \\      },\\n      userData: { em: '0217a86a7b92e2511273b0081bfc67f939b7f9a897d960849690056732795b3d'\\\n    \\ },\\n      customData: { test: 'test_obj' }\\n    }\\n  },\\n  \\n  // Object not-empty\\\n    \\ and list not-empty, with different values each.\\n  {\\n    mockDataObj: {\\n \\\n    \\     appDataObject: { vendor_id: 'vendor_id_obj' },\\n      appDataList: [\\n \\\n    \\       { name: 'campaign_ids', value: 'campaign_ids' }\\n      ],\\n      userDataObject:\\\n    \\ { em: 'test@example.com_obj' },\\n      userDataList: [{ name: 'fn', value: 'test'\\\n    \\ }],\\n      customDataObject: { test: 'test_obj' },\\n      customDataList: [\\n\\\n    \\        { name: 'currency', value: 'BRL' },\\n        { name: 'net_revenue', value:\\\n    \\ 123 }\\n      ],\\n    },\\n    expectedRequestBody: {\\n      appData: {\\n    \\\n    \\    advertiser_tracking_enabled: 0,\\n        application_tracking_enabled: 0,\\n\\\n    \\        extinfo: ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '',\\\n    \\ ''],\\n        vendor_id: 'vendor_id_obj',\\n        campaign_ids: 'campaign_ids'\\n\\\n    \\      },\\n      userData: { em: '0217a86a7b92e2511273b0081bfc67f939b7f9a897d960849690056732795b3d',\\\n    \\ fn: '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08' },\\n\\\n    \\      customData: { test: 'test_obj', currency: 'BRL', net_revenue: 123 }\\n \\\n    \\   }\\n  },\\n  \\n  // Object not-empty and list not-empty, with overlapping values.\\\n    \\ Should favor list.\\n  {\\n    mockDataObj: {\\n      appDataObject: { vendor_id:\\\n    \\ 'vendor_id_obj' },\\n      appDataList: [\\n        { name: 'vendor_id', value:\\\n    \\ 'vendor_id' },\\n        { name: 'campaign_ids', value: 'campaign_ids' }\\n  \\\n    \\    ],\\n      userDataObject: { em: 'test@example.com_obj' },\\n      userDataList:\\\n    \\ [{ name: 'fn', value: 'test' }, { name: 'em', value: 'test' }],\\n      customDataObject:\\\n    \\ { test: 'test_obj' },\\n      customDataList: [\\n        { name: 'currency',\\\n    \\ value: 'BRL' },\\n        { name: 'net_revenue', value: 123 },\\n        { name:\\\n    \\ 'test', value: 'test' }\\n      ],\\n    },\\n    expectedRequestBody: {\\n    \\\n    \\  appData: {\\n        advertiser_tracking_enabled: 0,\\n        application_tracking_enabled:\\\n    \\ 0,\\n        extinfo: ['', '', '', '', '', '', '', '', '', '', '', '', '', '',\\\n    \\ '', ''],\\n        vendor_id: 'vendor_id',\\n        campaign_ids: 'campaign_ids'\\n\\\n    \\      },\\n      userData: { em: '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08',\\\n    \\ fn: '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08' },\\n\\\n    \\      customData: { test: 'test', currency: 'BRL', net_revenue: 123 }\\n    }\\n\\\n    \\  }\\n].forEach((scenario, index) => {\\n  const copyMockData = JSON.parse(JSON.stringify(mockData));\\n\\\n    \\  mergeObj(copyMockData, scenario.mockDataObj);\\n  \\n  mock('sendHttpRequest',\\\n    \\ (requestUrl, requestOptions, requestBody) => {\\n    const parsedBody = JSON.parse(requestBody);\\n\\\n    \\    assertThat(parsedBody.data[0].app_data).isEqualTo(scenario.expectedRequestBody.appData);\\n\\\n    \\    assertThat(parsedBody.data[0].user_data).isEqualTo(scenario.expectedRequestBody.userData);\\n\\\n    \\    assertThat(parsedBody.data[0].custom_data).isEqualTo(scenario.expectedRequestBody.customData);\\n\\\n    \\    return Promise.create((resolve, reject) => {\\n      resolve({ statusCode:\\\n    \\ 200 });\\n    });\\n  });\\n  \\n  runCode(copyMockData);\\n  \\n  callLater(() =>\\\n    \\ {\\n    assertApi('gtmOnSuccess').wasCalled();\\n    assertApi('gtmOnFailure').wasNotCalled();\\n\\\n    \\  });\\n});\"\n- name: '[App Secret Proof] App Secret Proof is handled and sent succesfully'\n  code: \"mockData.useAppSecretProof = true;\\nmockData.appSecretProof = 'appSecretProof1';\\n\\\n    \\nmock('sendHttpRequest', (requestUrl, requestOptions, requestBody) => {\\n  const\\\n    \\ pixelId = mockData.pixelId;\\n  const accessToken = mockData.accessToken;\\n \\\n    \\ const appSecretProof = mockData.appSecretProof;\\n  \\n  assertThat(requestUrl).isEqualTo(\\n\\\n    \\    'https://graph.facebook.com/v' + expectedApiVersion + '/' + pixelId + \\n\\\n    \\    '/events?access_token=' + accessToken +\\n    '&appsecret_proof=' + appSecretProof\\n\\\n    \\  );\\n\\n  return Promise.create((resolve, reject) => {\\n    resolve({ statusCode:\\\n    \\ 200 });\\n  });  \\n});\\n\\nrunCode(mockData);\\n\\ncallLater(() => {\\n  assertApi('gtmOnSuccess').wasCalled();\\n\\\n    \\  assertApi('gtmOnFailure').wasNotCalled();\\n});\"\n- name: gtmOnFailure handler is called if some request fails with status code\n  code: |-\n    mockData.enableMultipixelSetup = true;\n    mockData.pixelIdAndAccessTokenTable = [\n      {\n        pixelId: 'pixelId2',\n        accessToken: 'accessToken2',\n        appSecretProof: 'appSecretProof2'\n      }\n    ];\n\n    const lastRequestIndex = mockData.pixelIdAndAccessTokenTable.length + 1;\n\n    let requestCount = 0;\n    mock('sendHttpRequest', (requestUrl, requestOptions, requestBody) => {\n      requestCount++;\n      const statusCode = (requestCount === 1) ? 500 : 200;\n      return Promise.create((resolve, reject) => {\n        resolve({ statusCode: statusCode });\n      });\n    });\n\n    runCode(mockData);\n\n    callLater(() => {\n      assertApi('gtmOnSuccess').wasNotCalled();\n      assertApi('gtmOnFailure').wasCalled();\n    });\n- name: gtmOnFailure handler is called if some request rejects\n  code: \"mockData.enableMultipixelSetup = true;\\nmockData.pixelIdAndAccessTokenTable\\\n    \\ = [\\n  {\\n    pixelId: 'pixelId2',\\n    accessToken: 'accessToken2',\\n    appSecretProof:\\\n    \\ 'appSecretProof2'\\n  }\\n];\\n\\nlet requestCount = 0;\\nmock('sendHttpRequest',\\\n    \\ (requestUrl, requestOptions, requestBody) => { \\n  requestCount++;\\n  return\\\n    \\ Promise.create((resolve, reject) => {\\n    if (requestCount === 1) reject({\\\n    \\ reason: 'failed' });\\n    else resolve({ statusCode: 200 });\\n  });\\n});\\n\\n\\\n    runCode(mockData);\\n\\ncallLater(() => {\\n  assertApi('gtmOnSuccess').wasNotCalled();\\n\\\n    \\  assertApi('gtmOnFailure').wasCalled();\\n});\"\n- name: gtmOnFailure handler is called if Promise dot all rejects\n  code: \"mockData.enableMultipixelSetup = true;\\nmockData.pixelIdAndAccessTokenTable\\\n    \\ = [\\n  {\\n    pixelId: 'pixelId2',\\n    accessToken: 'accessToken2',\\n    appSecretProof:\\\n    \\ 'appSecretProof2'\\n  }\\n];\\n\\nmock('sendHttpRequest', (requestUrl, requestOptions,\\\n    \\ requestBody) => { \\n  return Promise.create((resolve, reject) => {\\n    resolve({\\\n    \\ statusCode: 200 });\\n  });\\n});\\n\\nmockObject('Promise', {\\n  all: () => Promise.create((resolve,\\\n    \\ reject) => reject({ reason: 'failed' }))\\n});\\n\\nrunCode(mockData);\\n\\ncallLater(()\\\n    \\ => {\\n  assertApi('gtmOnSuccess').wasNotCalled();\\n  assertApi('gtmOnFailure').wasCalled();\\n\\\n    });\"\nsetup: \"const JSON = require('JSON');\\nconst Promise = require('Promise');\\nconst\\\n  \\ callLater = require('callLater');\\n\\nconst mergeObj = (target, source) => {\\n\\\n  \\  for (const key in source) {\\n    if (source.hasOwnProperty(key)) target[key]\\\n  \\ = source[key];\\n  }\\n  return target;\\n};\\n\\nconst expectedBigQuerySettings =\\\n  \\ {\\n  logBigQueryProjectId: 'logBigQueryProjectId',\\n  logBigQueryDatasetId: 'logBigQueryDatasetId',\\n\\\n  \\  logBigQueryTableId: 'logBigQueryTableId'\\n};\\n\\nconst requiredConsoleKeys = ['Type',\\\n  \\ 'TraceId', 'Name'];\\nconst requiredBqKeys = ['timestamp', 'type', 'trace_id',\\\n  \\ 'tag_name'];\\nconst expectedBqOptions = { ignoreUnknownValues: true };\\n\\nconst\\\n  \\ expectedValue = 'test';\\nconst expectedPixelId = '1111111111111';\\nconst expectedPartnerAgent\\\n  \\ = 'stape-gtmss-2.1.4';\\nconst expectedApiVersion = '25.0';\\n\\n\\nconst mockData\\\n  \\ = {\\n  pixelId: expectedPixelId,\\n  accessToken: expectedValue,\\n  inheritEventName:\\\n  \\ 'override',\\n  eventNameCustom: expectedValue,\\n  logBigQueryProjectId: expectedBigQuerySettings.logBigQueryProjectId,\\n\\\n  \\  logBigQueryDatasetId: expectedBigQuerySettings.logBigQueryDatasetId,\\n  logBigQueryTableId:\\\n  \\ expectedBigQuerySettings.logBigQueryTableId,\\n};\\n\\nmock('sendHttpRequest', (requestUrl,\\\n  \\ callback, requestOptions, requestBody) => {\\n  if (typeof callback === 'function')\\\n  \\ {\\n    callback(200);\\n  } else {\\n    requestBody = requestOptions;\\n    requestOptions\\\n  \\ = callback;\\n    return Promise.create((resolve, reject) => {\\n      resolve({\\\n  \\ statusCode: 200 });\\n    });  \\n  }\\n});\\n\\nmock('getRequestHeader', (header)\\\n  \\ => {\\n  if (header === 'trace-id') return 'expectedTraceId';\\n});\\n\\nmock('getTimestampMillis',\\\n  \\ 1747945830456);\"\n\n\n___NOTES___\n\n2026-05-20 - Change Notes:\n  - Add four automap toggle checkboxes (Server Event Data, User Data, App Data, Custom Data), each defaulting to true, allowing individual auto-mapping groups to be disabled without affecting manual overrides; existing configurations are unaffected via a hasOwnProperty fallback\n  - Add optional GA4 \"view_item_list\" → \"ViewContent\" mapping (sets content_type to \"product_group\") and move \"Use App Secret Proof\" into a new \"More Settings\" group\n  - Move \"Custom Item ID Key\" into the Custom Data section gated on automap being enabled; improve help texts for \"Inherit from client\" event name, HttpOnly cookies, and Test ID fields\n  - Refactor fbc/fbp resolution, cookie writing, and exit checks into dedicated functions; add page_referrer as a third URL fallback for subdomain index calculation\n  - Bump API version to 25.0 and partner agent to stape-gtmss-2.1.4\n\nCreated on 10/11/2020, 18:14:02\n\n\n",
                "galleryReference": {
                    "host": "github.com",
                    "owner": "stape-io",
                    "repository": "facebook-tag",
                    "version": "7d1a6ee57624225bc0e8540101ae6aff3505e090",
                    "signature": "503d71d7cf914e97b360cec17bccbd44f6806455a346b1e91e164d6d114ef295",
                    "galleryTemplateId": "5TP8W"
                }
            },
            {
                "accountId": "6365534927",
                "containerId": "258048563",
                "templateId": "13",
                "name": "TikTok Events API",
                "fingerprint": "1783780016188",
                "templateData": "___TERMS_OF_SERVICE___\n\nBy creating or modifying this file you agree to Google Tag Manager's Community\nTemplate Gallery Developer Terms of Service available at\nhttps://developers.google.com/tag-manager/gallery-tos (or such other URL as\nGoogle may provide), as modified from time to time.\n\n\n___INFO___\n\n{\n  \"type\": \"TAG\",\n  \"id\": \"cvt_K8M24\",\n  \"version\": 1,\n  \"displayName\": \"TikTok Events API\",\n  \"categories\": [\n    \"ADVERTISING\",\n    \"ANALYTICS\",\n    \"CONVERSIONS\",\n    \"MARKETING\",\n    \"REMARKETING\"\n  ],\n  \"brand\": {\n    \"id\": \"github.com_stape-io\",\n    \"displayName\": \"stape-io\",\n    \"thumbnail\": \"data:image/png;base64,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HABASjIOACAlGQcAkJKMAwBIScYBAKQk4wAAUpJxAAApyTgAgJRkHABASjIOACAlGQcAkJKMAwBIScYBAKQk4wAAUpJxAAApyTgAgJRkHABASjIOACAlGQcAkJKMAwBIScYBAKQk4wAAUpJxAAApyTgAgJRkHABASjIOACAlGQcAkJKMAwBIScYBAKQk4wAAUpJxAAApyTgAgJRkHABASjIOACAlGQcAkJKMAwBIScYBAKQk4wAAUpJxAAApyTgAgJRkHABASjIOACAlGQcAkJKMAwBIScYBAKQk4wAAUpJxAAApyTgAgJRkHABASjIOACAlGQcAkJKMAwBIScYBAKQk4wAAUpJxAAApyTgAgJRkHABASjIOACAlGQcAkJKMAwBIScYBAKQk4wAAUpJxAAApyTgAgJRkHABASjIOACAlGQcAkJKMAwBIScYBAKQk4wAAUpJxAAApyTgAgJRkHABASjIOACAlGQcAkJKMAwBIScYBAKQk4wAAUpJxAAApyTgAgJRkHABASjIOACAlGQcAkJKMAwBIScYBAKQk4wAAUpJxAAApyTgAgJRkHABASjIOACAlGQcAkJKMAwBIScYBAKQk4wAAUpJxAAApyTgAgJRkHABASjIOACClV86fP181AwDA7lIUxf8A/d26PBdp9woAAAAASUVORK5CYII\\u003d\"\n  },\n  \"description\": \"Tag that send the event data from the Universal Analytics/GA4/Data client to TikTok Events API.\",\n  \"containerContexts\": [\n    \"SERVER\"\n  ]\n}\n\n\n___TEMPLATE_PARAMETERS___\n\n[\n  {\n    \"type\": \"GROUP\",\n    \"name\": \"baseConfigGroup\",\n    \"subParams\": [\n      {\n        \"type\": \"RADIO\",\n        \"name\": \"eventType\",\n        \"displayName\": \"Event Name Setup Method\",\n        \"radioItems\": [\n          {\n            \"value\": \"standard\",\n            \"displayValue\": \"Standard\",\n            \"subParams\": [\n              {\n                \"type\": \"SELECT\",\n                \"name\": \"eventName\",\n                \"macrosInSelect\": false,\n                \"selectItems\": [\n                  {\n                    \"value\": \"AddPaymentInfo\",\n                    \"displayValue\": \"Add Payment Info\"\n                  },\n                  {\n                    \"value\": \"AddToCart\",\n                    \"displayValue\": \"Add to Cart\"\n                  },\n                  {\n                    \"value\": \"AddToWishlist\",\n                    \"displayValue\": \"Add to Wishlist\"\n                  },\n                  {\n                    \"value\": \"ApplicationApproval\",\n                    \"displayValue\": \"Application Approval\"\n                  },\n                  {\n                    \"value\": \"CompleteRegistration\",\n                    \"displayValue\": \"Complete Registration\"\n                  },\n                  {\n                    \"value\": \"Contact\",\n                    \"displayValue\": \"Contact\"\n                  },\n                  {\n                    \"value\": \"CustomizeProduct\",\n                    \"displayValue\": \"Customize Product\"\n                  },\n                  {\n                    \"value\": \"Download\",\n                    \"displayValue\": \"Download\"\n                  },\n                  {\n                    \"value\": \"FindLocation\",\n                    \"displayValue\": \"Find Location\"\n                  },\n                  {\n                    \"value\": \"InitiateCheckout\",\n                    \"displayValue\": \"Initiate Checkout\"\n                  },\n                  {\n                    \"value\": \"Lead\",\n                    \"displayValue\": \"Lead\"\n                  },\n                  {\n                    \"value\": \"Pageview\",\n                    \"displayValue\": \"Page View\"\n                  },\n                  {\n                    \"value\": \"Purchase\",\n                    \"displayValue\": \"Purchase\"\n                  },\n                  {\n                    \"value\": \"Schedule\",\n                    \"displayValue\": \"Schedule\"\n                  },\n                  {\n                    \"value\": \"Search\",\n                    \"displayValue\": \"Search\"\n                  },\n                  {\n                    \"value\": \"StartTrial\",\n                    \"displayValue\": \"Start Trial\"\n                  },\n                  {\n                    \"value\": \"SubmitApplication\",\n                    \"displayValue\": \"Submit Application\"\n                  },\n                  {\n                    \"value\": \"Subscribe\",\n                    \"displayValue\": \"Subscribe\"\n                  },\n                  {\n                    \"value\": \"ViewContent\",\n                    \"displayValue\": \"View Content\"\n                  },\n                  {\n                    \"value\": \"CompletePayment\",\n                    \"displayValue\": \"Complete Payment (legacy - Use Purchase instead)\"\n                  },\n                  {\n                    \"value\": \"SubmitForm\",\n                    \"displayValue\": \"Submit Form (legacy - Use Lead instead)\"\n                  },\n                  {\n                    \"value\": \"ClickButton\",\n                    \"displayValue\": \"Click Button (deprecated)\"\n                  },\n                  {\n                    \"value\": \"PlaceAnOrder\",\n                    \"displayValue\": \"Place an Order (deprecated)\"\n                  }\n                ],\n                \"simpleValueType\": true,\n                \"alwaysInSummary\": true,\n                \"valueValidators\": [\n                  {\n                    \"type\": \"NON_EMPTY\"\n                  }\n                ],\n                \"displayName\": \"Event Name\",\n                \"defaultValue\": \"Pageview\"\n              }\n            ]\n          },\n          {\n            \"value\": \"inherit\",\n            \"subParams\": [],\n            \"displayValue\": \"Inherit from client\"\n          },\n          {\n            \"value\": \"custom\",\n            \"subParams\": [\n              {\n                \"type\": \"TEXT\",\n                \"name\": \"eventNameCustom\",\n                \"displayName\": \"\",\n                \"simpleValueType\": true\n              }\n            ],\n            \"displayValue\": \"Custom\"\n          }\n        ],\n        \"simpleValueType\": true,\n        \"defaultValue\": \"standard\"\n      },\n      {\n        \"type\": \"SELECT\",\n        \"name\": \"eventSource\",\n        \"displayName\": \"Event Source\",\n        \"selectItems\": [\n          {\n            \"value\": \"web\",\n            \"displayValue\": \"Web\"\n          },\n          {\n            \"value\": \"app\",\n            \"displayValue\": \"App\"\n          },\n          {\n            \"value\": \"offline\",\n            \"displayValue\": \"Offline\"\n          },\n          {\n            \"value\": \"crm\",\n            \"displayValue\": \"CRM\"\n          }\n        ],\n        \"simpleValueType\": true,\n        \"defaultValue\": \"web\"\n      },\n      {\n        \"type\": \"TEXT\",\n        \"name\": \"accessToken\",\n        \"displayName\": \"Access Token\",\n        \"simpleValueType\": true,\n        \"help\": \"Set to your TikTok API Access Token. More info on how to get it can be found \\u003ca href\\u003d\\\"https://ads.tiktok.com/marketing_api/docs?rid\\u003d959icq5stjr\\u0026id\\u003d1701890979375106\\\" target\\u003d\\\"_blank\\\"\\u003ehere\\u003c/a\\u003e.\",\n        \"valueValidators\": [\n          {\n            \"type\": \"NON_EMPTY\"\n          }\n        ]\n      },\n      {\n        \"type\": \"TEXT\",\n        \"name\": \"pixelId\",\n        \"displayName\": \"TikTok Pixel ID / Offline Event Set ID / TikTok App ID / CRM Event Set ID\",\n        \"simpleValueType\": true,\n        \"valueValidators\": [\n          {\n            \"type\": \"NON_EMPTY\"\n          }\n        ],\n        \"help\": \"For \\u003cb\\u003eWeb events\\u003c/b\\u003e, enter a valid \\u003cb\\u003eTikTok Pixel ID\\u003c/b\\u003e. Only one TikTok Pixel ID can be used per tag.\\n\\u003cbr\\u003e\\nFor \\u003cb\\u003eOffline events\\u003c/b\\u003e, provide the \\u003cb\\u003eOffline Event Set ID\\u003c/b\\u003e. Only one Offline Event Set ID can be used per tag.\\n\\u003cbr\\u003e\\nFor \\u003cb\\u003eApp events\\u003c/b\\u003e, enter the \\u003cb\\u003eTikTok App ID\\u003c/b\\u003e. Only one TikTok App ID can be used per tag.\\n\\u003cbr\\u003e\\nFor \\u003cb\\u003eCRM events\\u003c/b\\u003e, enter the \\u003cb\\u003eCRM Event Set ID\\u003c/b\\u003e. Only one CRM Event Set ID can be used per tag.\"\n      },\n      {\n        \"type\": \"TEXT\",\n        \"name\": \"appId\",\n        \"displayName\": \"Mobile App ID\",\n        \"simpleValueType\": true,\n        \"enablingConditions\": [\n          {\n            \"paramName\": \"eventSource\",\n            \"paramValue\": \"app\",\n            \"type\": \"EQUALS\"\n          }\n        ],\n        \"valueValidators\": [\n          {\n            \"type\": \"NON_EMPTY\"\n          }\n        ],\n        \"help\": \"\\u003ca href\\u003d\\\"https://business-api.tiktok.com/portal/docs?id\\u003d1771101151059969#item-link-app%20parameters\\\"\\u003eLearn more\\u003c/a\\u003e.\"\n      },\n      {\n        \"type\": \"TEXT\",\n        \"name\": \"leadId\",\n        \"displayName\": \"Lead ID\",\n        \"simpleValueType\": true,\n        \"help\": \"\\u003ca href\\u003d\\\"https://business-api.tiktok.com/portal/docs?id\\u003d1835052338764993#item-link-lead%20parameters\\\"\\u003eLearn more\\u003c/a\\u003e.\",\n        \"enablingConditions\": [\n          {\n            \"paramName\": \"eventSource\",\n            \"paramValue\": \"crm\",\n            \"type\": \"EQUALS\"\n          }\n        ],\n        \"valueValidators\": [\n          {\n            \"type\": \"NON_EMPTY\"\n          }\n        ]\n      },\n      {\n        \"type\": \"TEXT\",\n        \"name\": \"testEventCode\",\n        \"displayName\": \"Test Event Code\",\n        \"simpleValueType\": true,\n        \"help\": \"If you want to test event tracking, you can use this field to specify a test code. If the event is received on TikTok side, this test code will display in the Test Events tab of the Pixel in TikTok Ads Manager.\"\n      },\n      {\n        \"type\": \"CHECKBOX\",\n        \"name\": \"generateTtp\",\n        \"checkboxText\": \"Generate _ttp cookie if not exist\",\n        \"simpleValueType\": true\n      },\n      {\n        \"type\": \"CHECKBOX\",\n        \"name\": \"enableEventEnhancement\",\n        \"checkboxText\": \"Enable Event Enhancement\",\n        \"simpleValueType\": true,\n        \"help\": \"Enable Use of HTTP Only Secure Cookie (\\u003ci\\u003egtmeec-tt\\u003c/i\\u003e) to Enhance Event Data.\",\n        \"defaultValue\": true\n      },\n      {\n        \"type\": \"CHECKBOX\",\n        \"name\": \"overrideCookiesSettings\",\n        \"checkboxText\": \"Override Cookies Settings\",\n        \"simpleValueType\": true,\n        \"help\": \"If enabled, it will override the listed settings for the \\u003ci\\u003e_gtmeec-tt\\u003c/i\\u003e, \\u003ci\\u003ettclid\\u003c/i\\u003e and \\u003ci\\u003e_ttp\\u003c/i\\u003e cookies.\",\n        \"subParams\": [\n          {\n            \"type\": \"GROUP\",\n            \"name\": \"cookieSettingsGroup\",\n            \"displayName\": \"Cookies Settings\",\n            \"groupStyle\": \"ZIPPY_OPEN_ON_PARAM\",\n            \"subParams\": [\n              {\n                \"type\": \"TEXT\",\n                \"name\": \"cookieDomain\",\n                \"displayName\": \"Cookie Domain\",\n                \"simpleValueType\": true,\n                \"help\": \"Use this option to override the cookie domain. \\u003cbr\\u003e Enter your website\\u0027s top-level domain as a fixed value (e.g., example.com). \\u003cbr\\u003e If left empty or using the \\\"auto\\\" value, the domain will be automatically determined using the following priority: \\u003cul\\u003e \\u003cli\\u003eDomain of the \\u003ci\\u003epage_location\\u003c/i\\u003e Event Data parameter (if present).\\u003c/li\\u003e \\u003cli\\u003eDomain of the \\u003ci\\u003eReferer\\u003c/i\\u003e header (if present).\\u003c/li\\u003e \\u003cli\\u003eDomain of the \\u003ci\\u003eForwarded\\u003c/i\\u003e header (if present).\\u003c/li\\u003e \\u003cli\\u003eDomain of the \\u003ci\\u003eX-Forwarded-Host\\u003c/i\\u003e header (if present).\\u003c/li\\u003e \\u003cli\\u003eDomain of the \\u003ci\\u003eHost\\u003c/i\\u003e header.\\u003c/li\\u003e \\u003c/ul\\u003e\",\n                \"valueHint\": \"example.com\",\n                \"defaultValue\": \"auto\"\n              },\n              {\n                \"type\": \"SELECT\",\n                \"name\": \"cookieSameSite\",\n                \"displayName\": \"Cookie SameSite\",\n                \"macrosInSelect\": true,\n                \"selectItems\": [\n                  {\n                    \"value\": \"none\",\n                    \"displayValue\": \"None\"\n                  },\n                  {\n                    \"value\": \"lax\",\n                    \"displayValue\": \"Lax\"\n                  },\n                  {\n                    \"value\": \"strict\",\n                    \"displayValue\": \"Strict\"\n                  }\n                ],\n                \"simpleValueType\": true,\n                \"defaultValue\": \"none\",\n                \"help\": \"\\u003ca href\\u003d\\\"https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Set-Cookie#samesitesamesite-value\\\"\\u003eLearn more\\u003c/a\\u003e.\"\n              }\n            ],\n            \"enablingConditions\": [\n              {\n                \"paramName\": \"overrideCookiesSettings\",\n                \"paramValue\": true,\n                \"type\": \"EQUALS\"\n              }\n            ]\n          }\n        ]\n      },\n      {\n        \"type\": \"CHECKBOX\",\n        \"name\": \"useOptimisticScenario\",\n        \"checkboxText\": \"Use Optimistic Scenario\",\n        \"simpleValueType\": true,\n        \"help\": \"The tag will call gtmOnSuccess() without waiting for a response from the API\"\n      }\n    ]\n  },\n  {\n    \"displayName\": \"Common Event Data Override\",\n    \"name\": \"commonEventDataListGroup\",\n    \"groupStyle\": \"ZIPPY_CLOSED\",\n    \"type\": \"GROUP\",\n    \"subParams\": [\n      {\n        \"type\": \"TEXT\",\n        \"name\": \"eventId\",\n        \"displayName\": \"Event ID\",\n        \"simpleValueType\": true,\n        \"help\": \"\\u003ca href\\u003d\\\"https://business-api.tiktok.com/portal/docs?id\\u003d1771101151059969#item-link-Top-level%20Parameters\\\"\\u003eLearn more\\u003c/a\\u003e.\"\n      },\n      {\n        \"type\": \"TEXT\",\n        \"name\": \"eventTime\",\n        \"displayName\": \"Event Time\",\n        \"simpleValueType\": true,\n        \"help\": \"The time when the event occurred, indicated as a Unix timestamp measured in seconds, and in UTC+0 time zone.\"\n      },\n      {\n        \"type\": \"CHECKBOX\",\n        \"name\": \"limitedDataUse\",\n        \"checkboxText\": \"Limited Data Use\",\n        \"simpleValueType\": true,\n        \"help\": \"To learn more about the Limited Data Use feature, refer to \\u003ca href\\u003d\\\"https://ads.tiktok.com/marketing_api/docs?id\\u003d1771101204435970\\\" target\\u003d\\\"_blank\\\"\\u003eEvents API 2.0 - Limited Data Use\\u003c/a\\u003e.\",\n        \"defaultValue\": false\n      }\n    ]\n  },\n  {\n    \"type\": \"GROUP\",\n    \"name\": \"pageDataGroup\",\n    \"displayName\": \"Page Data\",\n    \"groupStyle\": \"ZIPPY_CLOSED\",\n    \"subParams\": [\n      {\n        \"type\": \"TEXT\",\n        \"name\": \"pageLocation\",\n        \"displayName\": \"Page Location\",\n        \"simpleValueType\": true\n      },\n      {\n        \"type\": \"TEXT\",\n        \"name\": \"pageReferrer\",\n        \"displayName\": \"Page Referrer\",\n        \"simpleValueType\": true\n      }\n    ],\n    \"enablingConditions\": [\n      {\n        \"paramName\": \"eventSource\",\n        \"paramValue\": \"web\",\n        \"type\": \"EQUALS\"\n      }\n    ]\n  },\n  {\n    \"type\": \"GROUP\",\n    \"name\": \"appDataGroup\",\n    \"displayName\": \"App Data\",\n    \"groupStyle\": \"ZIPPY_CLOSED\",\n    \"subParams\": [\n      {\n        \"type\": \"TEXT\",\n        \"name\": \"appName\",\n        \"displayName\": \"Application name\",\n        \"simpleValueType\": true,\n        \"help\": \"\\u003ca href\\u003d\\\"https://business-api.tiktok.com/portal/docs?id\\u003d1771101151059969#item-link-app%20parameters\\\"\\u003eLearn more\\u003c/a\\u003e.\"\n      },\n      {\n        \"type\": \"TEXT\",\n        \"name\": \"appVersion\",\n        \"displayName\": \"App version number\",\n        \"simpleValueType\": true,\n        \"help\": \"\\u003ca href\\u003d\\\"https://business-api.tiktok.com/portal/docs?id\\u003d1771101151059969#item-link-app%20parameters\\\"\\u003eLearn more\\u003c/a\\u003e.\"\n      }\n    ],\n    \"enablingConditions\": [\n      {\n        \"paramName\": \"eventSource\",\n        \"paramValue\": \"app\",\n        \"type\": \"EQUALS\"\n      }\n    ]\n  },\n  {\n    \"displayName\": \"Ad Data\",\n    \"name\": \"adDataGroup\",\n    \"groupStyle\": \"ZIPPY_CLOSED\",\n    \"type\": \"GROUP\",\n    \"subParams\": [\n      {\n        \"type\": \"LABEL\",\n        \"name\": \"adDataGroupLabel\",\n        \"displayName\": \"See \\u003ca href\\u003d\\\"https://business-api.tiktok.com/portal/docs?id\\u003d1771101151059969\\\"\\u003ethis documentation\\u003c/a\\u003e for more details on Ad Data properties.\\u003cbr/\\u003e\\u003cbr/\\u003e\"\n      },\n      {\n        \"name\": \"adDataList\",\n        \"simpleTableColumns\": [\n          {\n            \"valueValidators\": [\n              {\n                \"type\": \"NON_EMPTY\"\n              }\n            ],\n            \"defaultValue\": \"ad_id\",\n            \"displayName\": \"Property Name\",\n            \"name\": \"name\",\n            \"isUnique\": true,\n            \"type\": \"SELECT\",\n            \"selectItems\": [\n              {\n                \"value\": \"callback\",\n                \"displayValue\": \"Callback\"\n              },\n              {\n                \"value\": \"campaign_id\",\n                \"displayValue\": \"Campaign ID\"\n              },\n              {\n                \"value\": \"ad_id\",\n                \"displayValue\": \"Ad ID\"\n              },\n              {\n                \"value\": \"creative_id\",\n                \"displayValue\": \"Creative ID\"\n              },\n              {\n                \"value\": \"is_retargeting\",\n                \"displayValue\": \"Is Retargeting\"\n              },\n              {\n                \"value\": \"attributed\",\n                \"displayValue\": \"Attributed\"\n              },\n              {\n                \"value\": \"attribution_type\",\n                \"displayValue\": \"Attribution Type\"\n              },\n              {\n                \"value\": \"attribution_provider\",\n                \"displayValue\": \"Attribution Provider\"\n              }\n            ]\n          },\n          {\n            \"defaultValue\": \"\",\n            \"displayName\": \"Property Value\",\n            \"name\": \"value\",\n            \"type\": \"TEXT\"\n          }\n        ],\n        \"type\": \"SIMPLE_TABLE\",\n        \"newRowButtonText\": \"Add property\"\n      }\n    ],\n    \"enablingConditions\": [\n      {\n        \"paramName\": \"eventSource\",\n        \"paramValue\": \"app\",\n        \"type\": \"EQUALS\"\n      }\n    ]\n  },\n  {\n    \"type\": \"GROUP\",\n    \"name\": \"leadDataGroup\",\n    \"displayName\": \"Lead Data\",\n    \"groupStyle\": \"ZIPPY_CLOSED\",\n    \"subParams\": [\n      {\n        \"type\": \"TEXT\",\n        \"name\": \"leadEventSource\",\n        \"displayName\": \"Lead Event Source\",\n        \"simpleValueType\": true,\n        \"help\": \"\\u003ca href\\u003d\\\"https://business-api.tiktok.com/portal/docs?id\\u003d1835052338764993#item-link-lead%20parameters\\\"\\u003eLearn more\\u003c/a\\u003e.\"\n      }\n    ],\n    \"enablingConditions\": [\n      {\n        \"paramName\": \"eventSource\",\n        \"paramValue\": \"crm\",\n        \"type\": \"EQUALS\"\n      }\n    ]\n  },\n  {\n    \"displayName\": \"User Data\",\n    \"name\": \"userDataGroup\",\n    \"groupStyle\": \"ZIPPY_CLOSED\",\n    \"type\": \"GROUP\",\n    \"subParams\": [\n      {\n        \"type\": \"LABEL\",\n        \"name\": \"userDataGroupLabel\",\n        \"displayName\": \"See \\u003ca href\\u003d\\\"https://business-api.tiktok.com/portal/docs?id\\u003d1771101151059969\\\"\\u003ethis documentation\\u003c/a\\u003e for more details on User Data properties. If the documentation requires the parameter to be hashed, you \\u003cb\\u003emust\\u003c/b\\u003e hash it with SHA256, or the tag will do this automatically before sending the event to TikTok.\\u003cbr/\\u003e\\u003cbr/\\u003e\"\n      },\n      {\n        \"name\": \"userDataList\",\n        \"simpleTableColumns\": [\n          {\n            \"valueValidators\": [\n              {\n                \"type\": \"NON_EMPTY\"\n              }\n            ],\n            \"defaultValue\": \"email\",\n            \"displayName\": \"Property Name\",\n            \"name\": \"name\",\n            \"isUnique\": true,\n            \"type\": \"SELECT\",\n            \"selectItems\": [\n              {\n                \"value\": \"email\",\n                \"displayValue\": \"Email\"\n              },\n              {\n                \"value\": \"phone\",\n                \"displayValue\": \"Phone\"\n              },\n              {\n                \"value\": \"external_id\",\n                \"displayValue\": \"External ID\"\n              },\n              {\n                \"value\": \"ip\",\n                \"displayValue\": \"Client IP address\"\n              },\n              {\n                \"value\": \"user_agent\",\n                \"displayValue\": \"Client user agent\"\n              },\n              {\n                \"value\": \"ttclid\",\n                \"displayValue\": \"ttclid\"\n              },\n              {\n                \"value\": \"ttp\",\n                \"displayValue\": \"ttp\"\n              },\n              {\n                \"value\": \"locale\",\n                \"displayValue\": \"Locale\"\n              },\n              {\n                \"value\": \"idfa\",\n                \"displayValue\": \"iOS IDFA\"\n              },\n              {\n                \"value\": \"idfv\",\n                \"displayValue\": \"iOS IDFV\"\n              },\n              {\n                \"value\": \"gaid\",\n                \"displayValue\": \"GAID (Google Advertising ID)\"\n              },\n              {\n                \"value\": \"att_status\",\n                \"displayValue\": \"ATT Status\"\n              },\n              {\n                \"value\": \"first_name\",\n                \"displayValue\": \"First Name\"\n              },\n              {\n                \"value\": \"last_name\",\n                \"displayValue\": \"Last Name\"\n              },\n              {\n                \"value\": \"city\",\n                \"displayValue\": \"City\"\n              },\n              {\n                \"value\": \"state\",\n                \"displayValue\": \"State\"\n              },\n              {\n                \"value\": \"country\",\n                \"displayValue\": \"Country\"\n              },\n              {\n                \"value\": \"zip_code\",\n                \"displayValue\": \"Zip\"\n              }\n            ]\n          },\n          {\n            \"defaultValue\": \"\",\n            \"displayName\": \"Property Value\",\n            \"name\": \"value\",\n            \"type\": \"TEXT\"\n          }\n        ],\n        \"type\": \"SIMPLE_TABLE\",\n        \"newRowButtonText\": \"Add property\"\n      }\n    ]\n  },\n  {\n    \"displayName\": \"Event Properties\",\n    \"name\": \"eventPropertiesGroup\",\n    \"groupStyle\": \"ZIPPY_CLOSED\",\n    \"type\": \"GROUP\",\n    \"subParams\": [\n      {\n        \"type\": \"LABEL\",\n        \"name\": \"eventPropertiesGroupLabel\",\n        \"displayName\": \"See \\u003ca href\\u003d\\\"https://business-api.tiktok.com/portal/docs?id\\u003d1771101151059969\\\"\\u003ethis documentation\\u003c/a\\u003e for more details on Event Properties.\\u003cbr/\\u003e\\u003cbr/\\u003e\"\n      },\n      {\n        \"name\": \"customDataList\",\n        \"simpleTableColumns\": [\n          {\n            \"valueValidators\": [\n              {\n                \"type\": \"NON_EMPTY\"\n              }\n            ],\n            \"defaultValue\": \"currency\",\n            \"displayName\": \"Property Name\",\n            \"name\": \"name\",\n            \"isUnique\": true,\n            \"type\": \"SELECT\",\n            \"selectItems\": [\n              {\n                \"value\": \"contents\",\n                \"displayValue\": \"Contents\"\n              },\n              {\n                \"value\": \"content_ids\",\n                \"displayValue\": \"Content IDs\"\n              },\n              {\n                \"value\": \"content_type\",\n                \"displayValue\": \"Content Type\"\n              },\n              {\n                \"value\": \"num_items\",\n                \"displayValue\": \"Number of Items\"\n              },\n              {\n                \"value\": \"currency\",\n                \"displayValue\": \"Currency\"\n              },\n              {\n                \"value\": \"value\",\n                \"displayValue\": \"Value\"\n              },\n              {\n                \"value\": \"description\",\n                \"displayValue\": \"Description\"\n              },\n              {\n                \"value\": \"search_string\",\n                \"displayValue\": \"Search String\"\n              },\n              {\n                \"value\": \"query\",\n                \"displayValue\": \"Query (legacy - use Search String instead)\"\n              },\n              {\n                \"value\": \"order_id\",\n                \"displayValue\": \"Order ID\"\n              },\n              {\n                \"value\": \"shop_id\",\n                \"displayValue\": \"Shop ID\"\n              }\n            ]\n          },\n          {\n            \"defaultValue\": \"\",\n            \"displayName\": \"Property Value\",\n            \"name\": \"value\",\n            \"type\": \"TEXT\"\n          }\n        ],\n        \"type\": \"SIMPLE_TABLE\",\n        \"newRowButtonText\": \"Add property\"\n      }\n    ]\n  },\n  {\n    \"displayName\": \"Additional Event Properties\",\n    \"name\": \"additionalEventPropertiesGroup\",\n    \"groupStyle\": \"ZIPPY_CLOSED\",\n    \"type\": \"GROUP\",\n    \"subParams\": [\n      {\n        \"type\": \"LABEL\",\n        \"name\": \"additionalEventPropertiesGroupLabel\",\n        \"displayName\": \"Use Additional Event Properties to send any custom property or properties specific to a vertical (Travel, Automotive etc.). \\u003cbr/\\u003e Check these documentations for more details on Additional Event Properties for \\u003ca href\\u003d\\\"https://ads.tiktok.com/help/article/available-events-and-parameters-for-travel-ads?lang\\u003den \\\"\\u003eTravel Ads\\u003c/a\\u003e, \\u003ca href\\u003d\\\"https://ads.tiktok.com/help/article/available-parameters-for-automotive-ads?lang\\u003den\\\"\\u003eAutomotive Ads\\u003c/a\\u003e and \\u003ca href\\u003d\\\"https://business-api.tiktok.com/portal/docs?id\\u003d1771101151059969\\\"\\u003eothers\\u003c/a\\u003e. \\u003cbr/\\u003e\\u003cbr/\\u003e\"\n      },\n      {\n        \"name\": \"additionalEventPropertiesList\",\n        \"simpleTableColumns\": [\n          {\n            \"valueValidators\": [\n              {\n                \"type\": \"NON_EMPTY\"\n              }\n            ],\n            \"defaultValue\": \"\",\n            \"displayName\": \"Property Name\",\n            \"name\": \"name\",\n            \"isUnique\": true,\n            \"type\": \"TEXT\"\n          },\n          {\n            \"defaultValue\": \"\",\n            \"displayName\": \"Property Value\",\n            \"name\": \"value\",\n            \"type\": \"TEXT\"\n          }\n        ],\n        \"type\": \"SIMPLE_TABLE\",\n        \"newRowButtonText\": \"Add property\"\n      }\n    ]\n  },\n  {\n    \"type\": \"GROUP\",\n    \"name\": \"tagExecutionConsentSettingsGroup\",\n    \"displayName\": \"Tag Execution Consent Settings\",\n    \"groupStyle\": \"ZIPPY_CLOSED\",\n    \"subParams\": [\n      {\n        \"type\": \"RADIO\",\n        \"name\": \"adStorageConsent\",\n        \"displayName\": \"\",\n        \"radioItems\": [\n          {\n            \"value\": \"optional\",\n            \"displayValue\": \"Send data always\"\n          },\n          {\n            \"value\": \"required\",\n            \"displayValue\": \"Send data in case marketing consent given\",\n            \"help\": \"Aborts the tag execution if marketing consent (\\u003ci\\u003ead_storage\\u003c/i\\u003e Google Consent Mode or Stape\\u0027s Data Tag parameter) is not given.\"\n          }\n        ],\n        \"simpleValueType\": true,\n        \"defaultValue\": \"optional\"\n      }\n    ]\n  },\n  {\n    \"type\": \"GROUP\",\n    \"name\": \"logsGroup\",\n    \"displayName\": \"Logs Settings\",\n    \"groupStyle\": \"ZIPPY_CLOSED\",\n    \"subParams\": [\n      {\n        \"type\": \"RADIO\",\n        \"name\": \"logType\",\n        \"radioItems\": [\n          {\n            \"value\": \"no\",\n            \"displayValue\": \"Do not log\"\n          },\n          {\n            \"value\": \"debug\",\n            \"displayValue\": \"Log to console during debug and preview\"\n          },\n          {\n            \"value\": \"always\",\n            \"displayValue\": \"Always log to console\"\n          }\n        ],\n        \"simpleValueType\": true,\n        \"defaultValue\": \"debug\"\n      }\n    ]\n  },\n  {\n    \"displayName\": \"BigQuery Logs Settings\",\n    \"name\": \"bigQueryLogsGroup\",\n    \"groupStyle\": \"ZIPPY_CLOSED\",\n    \"type\": \"GROUP\",\n    \"subParams\": [\n      {\n        \"type\": \"RADIO\",\n        \"name\": \"bigQueryLogType\",\n        \"radioItems\": [\n          {\n            \"value\": \"no\",\n            \"displayValue\": \"Do not log to BigQuery\"\n          },\n          {\n            \"value\": \"always\",\n            \"displayValue\": \"Log to BigQuery\"\n          }\n        ],\n        \"simpleValueType\": true,\n        \"defaultValue\": \"no\"\n      },\n      {\n        \"type\": \"GROUP\",\n        \"name\": \"logsBigQueryConfigGroup\",\n        \"groupStyle\": \"NO_ZIPPY\",\n        \"subParams\": [\n          {\n            \"type\": \"TEXT\",\n            \"name\": \"logBigQueryProjectId\",\n            \"displayName\": \"BigQuery Project ID\",\n            \"simpleValueType\": true,\n            \"help\": \"Optional.  \\u003cbr\\u003e\\u003cbr\\u003e  If omitted, it will be retrieved from the environment variable \\u003cI\\u003eGOOGLE_CLOUD_PROJECT\\u003c/i\\u003e where the server container is running. If the server container is running on Google Cloud, \\u003cI\\u003eGOOGLE_CLOUD_PROJECT\\u003c/i\\u003e will already be set to the Google Cloud project\\u0027s ID.\"\n          },\n          {\n            \"type\": \"TEXT\",\n            \"name\": \"logBigQueryDatasetId\",\n            \"displayName\": \"BigQuery Dataset ID\",\n            \"simpleValueType\": true,\n            \"valueValidators\": [\n              {\n                \"type\": \"NON_EMPTY\"\n              }\n            ]\n          },\n          {\n            \"type\": \"TEXT\",\n            \"name\": \"logBigQueryTableId\",\n            \"displayName\": \"BigQuery Table ID\",\n            \"simpleValueType\": true,\n            \"valueValidators\": [\n              {\n                \"type\": \"NON_EMPTY\"\n              }\n            ]\n          }\n        ],\n        \"enablingConditions\": [\n          {\n            \"paramName\": \"bigQueryLogType\",\n            \"paramValue\": \"always\",\n            \"type\": \"EQUALS\"\n          }\n        ]\n      }\n    ]\n  }\n]\n\n\n___SANDBOXED_JS_FOR_SERVER___\n\nconst BigQuery = require('BigQuery');\nconst computeEffectiveTldPlusOne = require('computeEffectiveTldPlusOne');\nconst decodeUriComponent = require('decodeUriComponent');\nconst fromBase64 = require('fromBase64');\nconst generateRandom = require('generateRandom');\nconst getAllEventData = require('getAllEventData');\nconst getContainerVersion = require('getContainerVersion');\nconst getCookieValues = require('getCookieValues');\nconst getEventData = require('getEventData');\nconst getRequestHeader = require('getRequestHeader');\nconst getTimestampMillis = require('getTimestampMillis');\nconst getType = require('getType');\nconst JSON = require('JSON');\nconst logToConsole = require('logToConsole');\nconst makeInteger = require('makeInteger');\nconst makeNumber = require('makeNumber');\nconst makeString = require('makeString');\nconst Math = require('Math');\nconst parseUrl = require('parseUrl');\nconst sendHttpRequest = require('sendHttpRequest');\nconst setCookie = require('setCookie');\nconst sha256Sync = require('sha256Sync');\nconst toBase64 = require('toBase64');\n\n/*==============================================================================\n==============================================================================*/\n\nconst gtmVersion = 'stape_2_1_3' + (data.enableEventEnhancement ? '_ee' : '');\n\nconst eventData = getAllEventData();\n\nif (shouldExitEarly(data, eventData)) return;\n\nconst url = getUrl(eventData);\nconst commonCookie = eventData.common_cookie || {};\n\nlet ttclid = getCookieValues('ttclid')[0] || commonCookie.ttclid || eventData.ttclid;\nif (url) {\n  const urlParsed = parseUrl(url);\n  if (urlParsed && urlParsed.searchParams.ttclid) {\n    ttclid = decodeUriComponent(urlParsed.searchParams.ttclid);\n  }\n}\n\nlet ttp = getCookieValues('_ttp')[0] || commonCookie._ttp || eventData._ttp || eventData.ttp;\nif (!ttp && data.generateTtp) {\n  ttp = generateTtp();\n}\n\nif (ttclid) {\n  setCookie('ttclid', ttclid, {\n    domain: getCookieDomain(data),\n    path: '/',\n    samesite: data.cookieSameSite || 'Lax',\n    secure: true,\n    'max-age': 2592000, // 30 days\n    httpOnly: false\n  });\n}\n\nif (ttp) {\n  setCookie('_ttp', ttp, {\n    domain: getCookieDomain(data),\n    path: '/',\n    samesite: data.cookieSameSite || 'Lax',\n    secure: true,\n    'max-age': 34190000, // 13 months\n    httpOnly: false\n  });\n}\n\nconst apiVersion = '1.3';\nconst postUrl = 'https://business-api.tiktok.com/open_api/v' + apiVersion + '/event/track/';\nconst eventName = getEventName(eventData, data);\nconst postBody = mapEvent(eventData, data);\n\nlog({\n  Name: 'TikTok',\n  Type: 'Request',\n  EventName: eventName,\n  RequestMethod: 'POST',\n  RequestUrl: postUrl,\n  RequestBody: postBody\n});\n\nsendHttpRequest(\n  postUrl,\n  (statusCode, headers, body) => {\n    log({\n      Name: 'TikTok',\n      Type: 'Response',\n      EventName: eventName,\n      ResponseStatusCode: statusCode,\n      ResponseHeaders: headers,\n      ResponseBody: body\n    });\n\n    if (!data.useOptimisticScenario) {\n      if (statusCode >= 200 && statusCode < 400) return data.gtmOnSuccess();\n      return data.gtmOnFailure();\n    }\n  },\n  {\n    headers: {\n      'Content-Type': 'application/json',\n      'Access-Token': data.accessToken\n    },\n    method: 'POST'\n  },\n  JSON.stringify(postBody)\n);\n\nif (data.useOptimisticScenario) {\n  return data.gtmOnSuccess();\n}\n\n/*==============================================================================\n  Vendor related functions\n==============================================================================*/\n\nfunction mapEvent(eventData, data) {\n  const eventSource = data.eventSource || 'web';\n  let mappedData = {\n    event: eventName,\n    event_time: getEventTime(eventData)\n  };\n\n  mappedData = addEventId(mappedData, eventData);\n\n  if (eventSource === 'web') {\n    addPageData(mappedData, eventData);\n  }\n\n  if (eventSource === 'app') {\n    addAppData(mappedData, eventData);\n  }\n\n  if (eventSource === 'web' || eventSource === 'app') {\n    mappedData.limited_data_use = data.limitedDataUse || false;\n  }\n\n  if (eventSource === 'crm') {\n    addLeadData(mappedData);\n  }\n\n  mappedData = addUserData(eventData, mappedData, eventSource);\n  mappedData = addPropertiesData(eventData, mappedData);\n  mappedData = hashDataIfNeeded(mappedData);\n\n  if (data.enableEventEnhancement) {\n    mappedData.user = enhanceEventData(mappedData.user);\n    setGtmEecCookie(mappedData.user);\n  }\n\n  const requestData = {\n    event_source: eventSource,\n    event_source_id: data.pixelId,\n    data: [mappedData]\n  };\n  const testEventCode = eventData.test_event_code || data.testEventCode;\n  if (testEventCode) requestData.test_event_code = testEventCode;\n\n  return requestData;\n}\n\nfunction hashData(value) {\n  if (!value) {\n    return value;\n  }\n\n  const type = getType(value);\n\n  if (type === 'undefined' || value === 'undefined') {\n    return undefined;\n  }\n\n  if (type === 'array') {\n    return value.map((val) => {\n      return hashData(val);\n    });\n  }\n\n  if (isHashed(value)) {\n    return value;\n  }\n\n  return sha256Sync(makeString(value).trim().toLowerCase(), {\n    outputEncoding: 'hex'\n  });\n}\n\nfunction hashDataIfNeeded(mappedData) {\n  if (mappedData.user) {\n    const userDataKeysToHash = [\n      'external_id',\n      'phone',\n      'email',\n      'first_name',\n      'last_name',\n      'zip_code'\n    ];\n    for (let key in mappedData.user) {\n      if (userDataKeysToHash.indexOf(key) !== -1) {\n        mappedData.user[key] = hashData(mappedData.user[key]);\n      }\n    }\n  }\n\n  return mappedData;\n}\n\nfunction addPropertiesData(eventData, mappedData) {\n  mappedData.properties = {};\n\n  let items;\n  if (getType(eventData.items) === 'array' && eventData.items.length) items = eventData.items;\n  else if (\n    getType(eventData.ecommerce) === 'object' &&\n    getType(eventData.ecommerce.items) === 'array' &&\n    eventData.ecommerce.items.length\n  ) {\n    items = eventData.ecommerce.items;\n  }\n\n  if (eventData.content_type) mappedData.properties.content_type = eventData.content_type;\n  else if (items) mappedData.properties.content_type = 'product';\n\n  if (eventData.query) mappedData.properties.query = eventData.query;\n  if (eventData.search_term || eventData.search_string)\n    mappedData.properties.search_string = eventData.search_term || eventData.search_string;\n  if (eventData.description) mappedData.properties.description = eventData.description;\n  if (eventData.order_id) mappedData.properties.order_id = eventData.order_id;\n  if (eventData.shop_id) mappedData.properties.shop_id = eventData.shop_id;\n\n  let currencyFromItems;\n  let valueFromItems = 0;\n\n  if (eventData.contents) mappedData.properties.contents = eventData.contents;\n  else if (items) {\n    currencyFromItems = items[0].currency;\n    mappedData.properties.contents = [];\n\n    items.forEach((d) => {\n      const item = {};\n\n      if (d.quantity) item.quantity = makeInteger(d.quantity);\n      if (isValidValue(d.price)) {\n        item.price = makeNumber(d.price);\n        valueFromItems += (item.quantity || 1) * item.price;\n      }\n\n      if (d.item_id) item.content_id = makeString(d.item_id);\n      else if (d.id) item.content_id = makeString(d.id);\n\n      if (d.content_category) item.content_category = d.content_category;\n      else if (d.item_category) item.content_category = d.item_category;\n\n      if (d.content_name) item.content_name = d.content_name;\n      else if (d.item_name) item.content_name = d.item_name;\n\n      if (d.brand) item.brand = d.brand;\n      else if (d.item_brand) item.brand = d.item_brand;\n\n      mappedData.properties.contents.push(item);\n    });\n  }\n\n  const currency = eventData.currency || currencyFromItems;\n  if (currency) mappedData.properties.currency = currency;\n\n  const value =\n    makeNumber(eventData.value) ||\n    makeNumber(eventData['x-ga-mp1-ev']) ||\n    makeNumber(eventData['x-ga-mp1-tr']) ||\n    roundValue(valueFromItems);\n  if (value) mappedData.properties.value = value;\n\n  if (data.customDataList) {\n    data.customDataList.forEach((d) => {\n      if (isValidValue(d.value)) {\n        mappedData.properties[d.name] = d.value;\n      }\n    });\n  }\n\n  if (data.additionalEventPropertiesList) {\n    data.additionalEventPropertiesList.forEach((d) => {\n      if (isValidValue(d.value)) {\n        mappedData.properties[d.name] = d.value;\n      }\n    });\n  }\n\n  mappedData.properties.gtm_version = gtmVersion;\n\n  return mappedData;\n}\n\nfunction addUserData(eventData, mappedData, eventSource) {\n  mappedData.user = {};\n  let userEventData = {};\n  let address = {};\n  if (getType(eventData.user_data) === 'object') {\n    userEventData = eventData.user_data;\n    const addressType = getType(userEventData.address);\n    if (addressType === 'object' || addressType === 'array') {\n      address = userEventData.address[0] || userEventData.address;\n    }\n  }\n\n  const email =\n    eventData.email ||\n    eventData.email_address ||\n    userEventData.email ||\n    userEventData.email_address ||\n    userEventData.sha256_email_address;\n  if (email) mappedData.user.email = email;\n\n  const phone =\n    eventData.phone ||\n    eventData.phone_number ||\n    userEventData.phone ||\n    userEventData.phone_number ||\n    userEventData.sha256_phone_number;\n  if (phone) mappedData.user.phone = phone;\n\n  const lastName =\n    eventData.lastName ||\n    eventData.LastName ||\n    eventData.nameLast ||\n    eventData.last_name ||\n    userEventData.last_name ||\n    address.last_name ||\n    address.sha256_last_name;\n  if (lastName) mappedData.user.last_name = lastName;\n\n  const firstName =\n    eventData.firstName ||\n    eventData.FirstName ||\n    eventData.nameFirst ||\n    eventData.first_name ||\n    userEventData.first_name ||\n    address.first_name ||\n    address.sha256_first_name;\n  if (firstName) mappedData.user.first_name = firstName;\n\n  const city = eventData.city || address.city;\n  if (city) mappedData.user.city = city;\n\n  const state = eventData.state || eventData.region || userEventData.region || address.region;\n  if (state) mappedData.user.state = state;\n\n  const zipCode =\n    eventData.zip || eventData.postal_code || userEventData.postal_code || address.postal_code;\n  if (zipCode) mappedData.user.zip_code = zipCode;\n\n  const country =\n    eventData.countryCode || eventData.country || userEventData.country || address.country;\n  if (country) mappedData.user.country = country;\n\n  if (eventSource === 'web') {\n    if (ttclid) mappedData.user.ttclid = ttclid;\n    else if (eventData.ttclid) mappedData.user.ttclid = eventData.ttclid;\n    else if (userEventData.ttclid) mappedData.user.ttclid = userEventData.ttclid;\n\n    if (ttp) mappedData.user.ttp = ttp;\n    else if (eventData.ttp) mappedData.user.ttp = eventData.ttp;\n    else if (userEventData.ttp) mappedData.user.ttp = userEventData.ttp;\n\n    const externalId =\n      eventData.external_id || eventData.user_id || eventData.userId || userEventData.external_id;\n    if (externalId) mappedData.user.external_id = externalId;\n\n    const ip = eventData.ip_override || eventData.ip_address || eventData.ip;\n    if (ip) mappedData.user.ip = ip;\n\n    if (eventData.user_agent) mappedData.user.user_agent = eventData.user_agent;\n  }\n\n  if (eventSource === 'app') {\n    const idfa = eventData.idfa || userEventData.idfa;\n    if (idfa) mappedData.user.idfa = idfa;\n\n    const idfv = eventData.idfv || userEventData.idfv;\n    if (idfv) mappedData.user.idfv = idfv;\n\n    const gaid = eventData.gaid || userEventData.gaid;\n    if (gaid) mappedData.user.gaid = gaid;\n\n    const attStatus = eventData.att_status || userEventData.att_status;\n    if (attStatus) mappedData.user.att_status = attStatus;\n  }\n\n  if (eventSource === 'web' || eventSource === 'app') {\n    const locale = eventData.locale || userEventData.locale;\n    if (locale) mappedData.user.locale = locale;\n  }\n\n  if (data.userDataList) {\n    data.userDataList.forEach((d) => {\n      if (isValidValue(d.value)) {\n        mappedData.user[d.name] = d.value;\n      }\n    });\n  }\n\n  return mappedData;\n}\n\nfunction getEventName(eventData, data) {\n  if (data.eventType === 'inherit') {\n    const eventName = eventData.event_name;\n\n    const gaToEventName = {\n      page_view: 'Pageview',\n      click: 'ClickButton',\n      download: 'Download',\n      file_download: 'Download',\n      complete_registration: 'CompleteRegistration',\n      'gtm.dom': 'Pageview',\n      add_payment_info: 'AddPaymentInfo',\n      add_to_cart: 'AddToCart',\n      add_to_wishlist: 'AddToWishlist',\n      sign_up: 'CompleteRegistration',\n      begin_checkout: 'InitiateCheckout',\n      generate_lead: 'Lead',\n      purchase: 'Purchase',\n      search: 'Search',\n      view_item: 'ViewContent',\n\n      contact: 'Contact',\n      find_location: 'Search',\n      submit_application: 'Subscribe',\n      subscribe: 'Subscribe',\n\n      'gtm4wp.addProductToCartEEC': 'AddToCart',\n      'gtm4wp.productClickEEC': 'ViewContent',\n      'gtm4wp.checkoutOptionEEC': 'InitiateCheckout',\n      'gtm4wp.checkoutStepEEC': 'AddPaymentInfo',\n      'gtm4wp.orderCompletedEEC': 'Purchase'\n    };\n\n    if (!gaToEventName[eventName]) {\n      return eventName;\n    }\n\n    return gaToEventName[eventName];\n  }\n\n  return data.eventType === 'custom' ? data.eventNameCustom : data.eventName;\n}\n\nfunction addEventId(mappedData, eventData) {\n  if (data.eventId) mappedData.event_id = data.eventId;\n  else if (eventData.event_id) mappedData.event_id = eventData.event_id;\n  else if (eventData.transaction_id) mappedData.event_id = eventData.transaction_id;\n\n  return mappedData;\n}\n\nfunction getEventTime(eventData) {\n  if (data.eventTime) return makeInteger(data.eventTime);\n  else if (eventData.event_time) return makeInteger(eventData.event_time);\n\n  return Math.round(getTimestampMillis() / 1000);\n}\n\nfunction addPageData(mappedData, eventData) {\n  mappedData.page = {\n    url: data.pageLocation || eventData.page_location\n  };\n\n  if (data.pageReferrer) mappedData.page.referrer = data.pageReferrer;\n  else if (eventData.page_referrer) mappedData.page.referrer = eventData.page_referrer;\n  else if (eventData.referrer) mappedData.page.referrer = eventData.referrer;\n\n  return mappedData;\n}\n\nfunction addAppData(mappedData, eventData) {\n  mappedData.app = {\n    app_id: data.appId\n  };\n\n  if (data.appName) mappedData.app.app_name = data.appName;\n  else if (eventData.app_name) mappedData.app.app_name = eventData.app_name;\n\n  if (data.appVersion) mappedData.app.app_version = data.appVersion;\n  else if (eventData.app_version) mappedData.app.app_version = eventData.app_version;\n\n  let adEventData = {};\n  mappedData.ad = {};\n\n  if (getType(eventData.ad) === 'object') {\n    adEventData = eventData.ad;\n  }\n\n  if (adEventData.callback) mappedData.ad.callback = adEventData.callback;\n  else if (eventData.callback) mappedData.ad.callback = eventData.callback;\n\n  if (adEventData.campaign_id) mappedData.ad.campaign_id = adEventData.campaign_id;\n  else if (eventData.campaign_id) mappedData.ad.campaign_id = eventData.campaign_id;\n\n  if (adEventData.ad_id) mappedData.ad.ad_id = adEventData.ad_id;\n  else if (eventData.ad_id) mappedData.ad.ad_id = eventData.ad_id;\n\n  if (adEventData.creative_id) mappedData.ad.creative_id = adEventData.creative_id;\n  else if (eventData.creative_id) mappedData.ad.creative_id = eventData.creative_id;\n\n  if (adEventData.is_retargeting) mappedData.ad.is_retargeting = adEventData.is_retargeting;\n  else if (eventData.is_retargeting) mappedData.ad.is_retargeting = eventData.is_retargeting;\n\n  if (adEventData.attributed) mappedData.ad.attributed = adEventData.attributed;\n  else if (eventData.attributed) mappedData.ad.attributed = eventData.attributed;\n\n  if (adEventData.attribution_type) mappedData.ad.attribution_type = adEventData.attribution_type;\n  else if (eventData.attribution_type) mappedData.ad.attribution_type = eventData.attribution_type;\n\n  if (adEventData.attribution_provider)\n    mappedData.ad.attribution_provider = adEventData.attribution_provider;\n  else if (eventData.attribution_provider)\n    mappedData.ad.attribution_provider = eventData.attribution_provider;\n\n  if (data.adDataList) {\n    data.adDataList.forEach((d) => {\n      if (isValidValue(d.value)) {\n        mappedData.ad[d.name] = d.value;\n      }\n    });\n  }\n\n  return mappedData;\n}\n\nfunction addLeadData(mappedData) {\n  mappedData.lead = {\n    lead_id: makeString(data.leadId)\n  };\n\n  if (data.leadEventSource) mappedData.lead.lead_event_source = data.leadEventSource;\n\n  return mappedData;\n}\n\nfunction generateTtp() {\n  const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n  let result = '';\n\n  for (let i = 0; i < 27; i++) {\n    const randomIndex = generateRandom(0, characters.length - 1);\n    result += characters.charAt(randomIndex);\n  }\n\n  return result;\n}\n\nfunction setGtmEecCookie(userData) {\n  const gtmeecCookie = {};\n\n  if (userData.email) gtmeecCookie.email = userData.email;\n  if (userData.phone) gtmeecCookie.phone = userData.phone;\n  if (userData.last_name) gtmeecCookie.last_name = userData.last_name;\n  if (userData.first_name) gtmeecCookie.first_name = userData.first_name;\n  if (userData.city) gtmeecCookie.city = userData.city;\n  if (userData.state) gtmeecCookie.state = userData.state;\n  if (userData.zip_code) gtmeecCookie.zip_code = userData.zip_code;\n  if (userData.country) gtmeecCookie.country = userData.country;\n  if (userData.external_id) gtmeecCookie.external_id = userData.external_id;\n\n  setCookie('_gtmeec-tt', toBase64(JSON.stringify(gtmeecCookie)), {\n    domain: getCookieDomain(data),\n    path: '/',\n    samesite: data.cookieSameSite || 'strict',\n    secure: true,\n    'max-age': 7776000, // 90 days\n    HttpOnly: true\n  });\n}\n\nfunction enhanceEventData(userData) {\n  const cookieValue = getCookieValues('_gtmeec-tt')[0] || commonCookie['_gtmeec-tt'];\n  if (!cookieValue) return userData;\n\n  const jsonStr = fromBase64(cookieValue);\n  if (!jsonStr) return userData;\n\n  const gtmeecData = JSON.parse(jsonStr);\n\n  if (getType(gtmeecData) === 'object') {\n    if (!userData.email && gtmeecData.email) userData.email = gtmeecData.email;\n    if (!userData.phone && gtmeecData.phone) userData.phone = gtmeecData.phone;\n    if (!userData.last_name && gtmeecData.last_name) userData.last_name = gtmeecData.last_name;\n    if (!userData.first_name && gtmeecData.first_name) userData.first_name = gtmeecData.first_name;\n    if (!userData.city && gtmeecData.city) userData.city = gtmeecData.city;\n    if (!userData.state && gtmeecData.state) userData.state = gtmeecData.state;\n    if (!userData.zip_code && gtmeecData.zip_code) userData.zip_code = gtmeecData.zip_code;\n    if (!userData.country && gtmeecData.country) userData.country = gtmeecData.country;\n    if (!userData.external_id && gtmeecData.external_id)\n      userData.external_id = gtmeecData.external_id;\n  }\n\n  return userData;\n}\n\n/*==============================================================================\n  Helpers\n==============================================================================*/\n\nfunction shouldExitEarly(data, eventData) {\n  if (!isConsentGivenOrNotRequired(data, eventData)) {\n    data.gtmOnSuccess();\n    return true;\n  }\n\n  const url = getUrl(eventData);\n  if (url && url.lastIndexOf('https://gtm-msr.appspot.com/', 0) === 0) {\n    data.gtmOnSuccess();\n    return true;\n  }\n}\n\nfunction getUrl(eventData) {\n  return eventData.page_location || getRequestHeader('referer') || eventData.page_referrer;\n}\n\nfunction getCookieDomain(data) {\n  return !data.cookieDomain || data.cookieDomain === 'auto'\n    ? computeEffectiveTldPlusOne(getEventData('page_location') || getRequestHeader('referer')) ||\n        'auto'\n    : data.cookieDomain;\n}\n\nfunction roundValue(value) {\n  if (!value) return value;\n  return Math.round(makeNumber(value) * 100) / 100;\n}\n\nfunction isHashed(value) {\n  if (!value) return false;\n  return makeString(value).match('^[A-Fa-f0-9]{64}$') !== null;\n}\n\nfunction isValidValue(value) {\n  const valueType = getType(value);\n  return valueType !== 'null' && valueType !== 'undefined' && value !== '' && value === value;\n}\n\nfunction isConsentGivenOrNotRequired(data, eventData) {\n  if (data.adStorageConsent !== 'required') return true;\n  if (eventData.consent_state) return !!eventData.consent_state.ad_storage;\n  const xGaGcs = eventData['x-ga-gcs'] || ''; // x-ga-gcs is a string like \"G110\"\n  return xGaGcs[2] === '1';\n}\n\nfunction log(rawDataToLog) {\n  const logDestinationsHandlers = {};\n  if (determinateIsLoggingEnabled()) logDestinationsHandlers.console = logConsole;\n  if (determinateIsLoggingEnabledForBigQuery()) logDestinationsHandlers.bigQuery = logToBigQuery;\n\n  rawDataToLog.TraceId = getRequestHeader('trace-id');\n\n  const keyMappings = {\n    // No transformation for Console is needed.\n    bigQuery: {\n      Name: 'tag_name',\n      Type: 'type',\n      TraceId: 'trace_id',\n      EventName: 'event_name',\n      RequestMethod: 'request_method',\n      RequestUrl: 'request_url',\n      RequestBody: 'request_body',\n      ResponseStatusCode: 'response_status_code',\n      ResponseHeaders: 'response_headers',\n      ResponseBody: 'response_body'\n    }\n  };\n\n  for (const logDestination in logDestinationsHandlers) {\n    const handler = logDestinationsHandlers[logDestination];\n    if (!handler) continue;\n\n    const mapping = keyMappings[logDestination];\n    const dataToLog = mapping ? {} : rawDataToLog;\n\n    if (mapping) {\n      for (const key in rawDataToLog) {\n        const mappedKey = mapping[key] || key;\n        dataToLog[mappedKey] = rawDataToLog[key];\n      }\n    }\n\n    handler(dataToLog);\n  }\n}\n\nfunction logConsole(dataToLog) {\n  logToConsole(JSON.stringify(dataToLog));\n}\n\nfunction logToBigQuery(dataToLog) {\n  const connectionInfo = {\n    projectId: data.logBigQueryProjectId,\n    datasetId: data.logBigQueryDatasetId,\n    tableId: data.logBigQueryTableId\n  };\n\n  dataToLog.timestamp = getTimestampMillis();\n\n  ['request_body', 'response_headers', 'response_body'].forEach((p) => {\n    dataToLog[p] = JSON.stringify(dataToLog[p]);\n  });\n\n  BigQuery.insert(connectionInfo, [dataToLog], { ignoreUnknownValues: true });\n}\n\nfunction determinateIsLoggingEnabled() {\n  const containerVersion = getContainerVersion();\n  const isDebug = !!(\n    containerVersion &&\n    (containerVersion.debugMode || containerVersion.previewMode)\n  );\n\n  if (!data.logType) {\n    return isDebug;\n  }\n\n  if (data.logType === 'no') {\n    return false;\n  }\n\n  if (data.logType === 'debug') {\n    return isDebug;\n  }\n\n  return data.logType === 'always';\n}\n\nfunction determinateIsLoggingEnabledForBigQuery() {\n  if (data.bigQueryLogType === 'no') return false;\n  return data.bigQueryLogType === 'always';\n}\n\n\n___SERVER_PERMISSIONS___\n\n[\n  {\n    \"instance\": {\n      \"key\": {\n        \"publicId\": \"read_event_data\",\n        \"versionId\": \"1\"\n      },\n      \"param\": [\n        {\n          \"key\": \"eventDataAccess\",\n          \"value\": {\n            \"type\": 1,\n            \"string\": \"any\"\n          }\n        }\n      ]\n    },\n    \"clientAnnotations\": {\n      \"isEditedByUser\": true\n    },\n    \"isRequired\": true\n  },\n  {\n    \"instance\": {\n      \"key\": {\n        \"publicId\": \"set_cookies\",\n        \"versionId\": \"1\"\n      },\n      \"param\": [\n        {\n          \"key\": \"allowedCookies\",\n          \"value\": {\n            \"type\": 2,\n            \"listItem\": [\n              {\n                \"type\": 3,\n                \"mapKey\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"name\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"domain\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"path\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"secure\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"session\"\n                  }\n                ],\n                \"mapValue\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"ttclid\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"*\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"*\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"any\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"any\"\n                  }\n                ]\n              },\n              {\n                \"type\": 3,\n                \"mapKey\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"name\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"domain\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"path\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"secure\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"session\"\n                  }\n                ],\n                \"mapValue\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"_ttp\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"*\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"*\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"any\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"any\"\n                  }\n                ]\n              },\n              {\n                \"type\": 3,\n                \"mapKey\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"name\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"domain\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"path\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"secure\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"session\"\n                  }\n                ],\n                \"mapValue\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"_gtmeec-tt\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"*\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"*\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"any\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"any\"\n                  }\n                ]\n              }\n            ]\n          }\n        }\n      ]\n    },\n    \"clientAnnotations\": {\n      \"isEditedByUser\": true\n    },\n    \"isRequired\": true\n  },\n  {\n    \"instance\": {\n      \"key\": {\n        \"publicId\": \"send_http\",\n        \"versionId\": \"1\"\n      },\n      \"param\": [\n        {\n          \"key\": \"allowedUrls\",\n          \"value\": {\n            \"type\": 1,\n            \"string\": \"specific\"\n          }\n        },\n        {\n          \"key\": \"urls\",\n          \"value\": {\n            \"type\": 2,\n            \"listItem\": [\n              {\n                \"type\": 1,\n                \"string\": \"https://business-api.tiktok.com/\"\n              }\n            ]\n          }\n        }\n      ]\n    },\n    \"clientAnnotations\": {\n      \"isEditedByUser\": true\n    },\n    \"isRequired\": true\n  },\n  {\n    \"instance\": {\n      \"key\": {\n        \"publicId\": \"get_cookies\",\n        \"versionId\": \"1\"\n      },\n      \"param\": [\n        {\n          \"key\": \"cookieAccess\",\n          \"value\": {\n            \"type\": 1,\n            \"string\": \"specific\"\n          }\n        },\n        {\n          \"key\": \"cookieNames\",\n          \"value\": {\n            \"type\": 2,\n            \"listItem\": [\n              {\n                \"type\": 1,\n                \"string\": \"ttclid\"\n              },\n              {\n                \"type\": 1,\n                \"string\": \"_ttp\"\n              },\n              {\n                \"type\": 1,\n                \"string\": \"_gtmeec-tt\"\n              }\n            ]\n          }\n        }\n      ]\n    },\n    \"clientAnnotations\": {\n      \"isEditedByUser\": true\n    },\n    \"isRequired\": true\n  },\n  {\n    \"instance\": {\n      \"key\": {\n        \"publicId\": \"logging\",\n        \"versionId\": \"1\"\n      },\n      \"param\": [\n        {\n          \"key\": \"environments\",\n          \"value\": {\n            \"type\": 1,\n            \"string\": \"all\"\n          }\n        }\n      ]\n    },\n    \"clientAnnotations\": {\n      \"isEditedByUser\": true\n    },\n    \"isRequired\": true\n  },\n  {\n    \"instance\": {\n      \"key\": {\n        \"publicId\": \"read_container_data\",\n        \"versionId\": \"1\"\n      },\n      \"param\": []\n    },\n    \"isRequired\": true\n  },\n  {\n    \"instance\": {\n      \"key\": {\n        \"publicId\": \"read_request\",\n        \"versionId\": \"1\"\n      },\n      \"param\": [\n        {\n          \"key\": \"headerWhitelist\",\n          \"value\": {\n            \"type\": 2,\n            \"listItem\": [\n              {\n                \"type\": 3,\n                \"mapKey\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"headerName\"\n                  }\n                ],\n                \"mapValue\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"trace-id\"\n                  }\n                ]\n              },\n              {\n                \"type\": 3,\n                \"mapKey\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"headerName\"\n                  }\n                ],\n                \"mapValue\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"referer\"\n                  }\n                ]\n              }\n            ]\n          }\n        },\n        {\n          \"key\": \"headersAllowed\",\n          \"value\": {\n            \"type\": 8,\n            \"boolean\": true\n          }\n        },\n        {\n          \"key\": \"requestAccess\",\n          \"value\": {\n            \"type\": 1,\n            \"string\": \"specific\"\n          }\n        },\n        {\n          \"key\": \"headerAccess\",\n          \"value\": {\n            \"type\": 1,\n            \"string\": \"specific\"\n          }\n        },\n        {\n          \"key\": \"queryParameterAccess\",\n          \"value\": {\n            \"type\": 1,\n            \"string\": \"any\"\n          }\n        }\n      ]\n    },\n    \"clientAnnotations\": {\n      \"isEditedByUser\": true\n    },\n    \"isRequired\": true\n  },\n  {\n    \"instance\": {\n      \"key\": {\n        \"publicId\": \"access_bigquery\",\n        \"versionId\": \"1\"\n      },\n      \"param\": [\n        {\n          \"key\": \"allowedTables\",\n          \"value\": {\n            \"type\": 2,\n            \"listItem\": [\n              {\n                \"type\": 3,\n                \"mapKey\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"projectId\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"datasetId\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"tableId\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"operation\"\n                  }\n                ],\n                \"mapValue\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"*\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"*\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"*\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"write\"\n                  }\n                ]\n              }\n            ]\n          }\n        }\n      ]\n    },\n    \"clientAnnotations\": {\n      \"isEditedByUser\": true\n    },\n    \"isRequired\": true\n  }\n]\n\n\n___TESTS___\n\nscenarios:\n- name: Should log to console, if the 'Always log to console' option is selected\n  code: \"mockData.logType = 'always';\\n\\nconst expectedDebugMode = true;\\nmock('getContainerVersion',\\\n    \\ () => {\\n  return {\\n    debugMode: expectedDebugMode\\n  };\\n}); \\n\\nmock('logToConsole',\\\n    \\ (logData) => {\\n  const parsedLogData = JSON.parse(logData);\\n  requiredConsoleKeys.forEach(p\\\n    \\ => assertThat(parsedLogData[p]).isDefined());\\n});\\n\\nrunCode(mockData);\\n\\n\\\n    assertApi('logToConsole').wasCalled();\\nassertApi('gtmOnSuccess').wasCalled();\\n\\\n    assertApi('gtmOnFailure').wasNotCalled();\\n\"\n- name: Should log to console, if the 'Log during debug and preview' option is selected\n    AND is on preview mode\n  code: |-\n    mockData.logType = 'debug';\n\n    const expectedDebugMode = true;\n    mock('getContainerVersion', () => {\n      return {\n        debugMode: expectedDebugMode\n      };\n    });\n\n    mock('logToConsole', (logData) => {\n      const parsedLogData = JSON.parse(logData);\n      requiredConsoleKeys.forEach(p => assertThat(parsedLogData[p]).isDefined());\n    });\n\n    runCode(mockData);\n\n    assertApi('logToConsole').wasCalled();\n    assertApi('gtmOnSuccess').wasCalled();\n    assertApi('gtmOnFailure').wasNotCalled();\n- name: Should NOT log to console, if the 'Log during debug and preview' option is\n    selected AND is NOT on preview mode\n  code: |-\n    mockData.logType = 'debug';\n\n    const expectedDebugMode = false;\n    mock('getContainerVersion', () => {\n      return {\n        debugMode: expectedDebugMode\n      };\n    });\n\n    runCode(mockData);\n\n    assertApi('logToConsole').wasNotCalled();\n    assertApi('gtmOnSuccess').wasCalled();\n    assertApi('gtmOnFailure').wasNotCalled();\n- name: Should NOT log to console, if the 'Do not log' option is selected\n  code: |-\n    mockData.logType = 'no';\n\n    runCode(mockData);\n\n    assertApi('logToConsole').wasNotCalled();\n    assertApi('gtmOnSuccess').wasCalled();\n    assertApi('gtmOnFailure').wasNotCalled();\n- name: Should log to BQ, if the 'Log to BigQuery' option is selected\n  code: \"mockData.bigQueryLogType = 'always';\\n\\n// assertApi doesn't work for 'BigQuery.insert()'.\\n\\\n    // Ref: https://gtm-gear.com/posts/gtm-templates-testing/\\nmockObject('BigQuery',\\\n    \\ {\\n  insert: (connectionInfo, rows, options) => { \\n    assertThat(connectionInfo).isDefined();\\n\\\n    \\    assertThat(rows).isArray();\\n    assertThat(rows).hasLength(1);\\n    requiredBqKeys.forEach(p\\\n    \\ => assertThat(rows[0][p]).isDefined());\\n    assertThat(options).isEqualTo(expectedBqOptions);\\n\\\n    \\    return Promise.create((resolve, reject) => {\\n      resolve();\\n    });\\n\\\n    \\  }\\n});\\n\\nrunCode(mockData);\\n\\nassertApi('gtmOnSuccess').wasCalled();\\nassertApi('gtmOnFailure').wasNotCalled();\"\n- name: Should NOT log to BQ, if the 'Do not log to BigQuery' option is selected\n  code: \"mockData.bigQueryLogType = 'no';\\n\\n// assertApi doesn't work for 'BigQuery.insert()'.\\n\\\n    // Ref: https://gtm-gear.com/posts/gtm-templates-testing/\\nmockObject('BigQuery',\\\n    \\ {\\n  insert: (connectionInfo, rows, options) => { \\n    fail('BigQuery.insert\\\n    \\ should not have been called.');\\n    return Promise.create((resolve, reject)\\\n    \\ => {\\n      resolve();\\n    });\\n  }\\n});\\n\\nrunCode(mockData);\\n\\nassertApi('gtmOnSuccess').wasCalled();\\n\\\n    assertApi('gtmOnFailure').wasNotCalled();\"\nsetup: \"const JSON = require('JSON');\\nconst Promise = require('Promise');\\n\\nconst\\\n  \\ expectedBigQuerySettings = {\\n  logBigQueryProjectId: 'logBigQueryProjectId',\\n\\\n  \\  logBigQueryDatasetId: 'logBigQueryDatasetId',\\n  logBigQueryTableId: 'logBigQueryTableId'\\n\\\n  };\\nconst requiredConsoleKeys = ['Type', 'TraceId', 'Name'];\\nconst requiredBqKeys\\\n  \\ = ['timestamp', 'type', 'trace_id', 'tag_name'];\\nconst expectedBqOptions = {\\\n  \\ ignoreUnknownValues: true };\\n\\nconst expectedValue = 'test';\\nconst expectedPixelId\\\n  \\ = '1111111111111';\\n\\nconst mockData = {\\n  logBigQueryProjectId: expectedBigQuerySettings.logBigQueryProjectId,\\n\\\n  \\  logBigQueryDatasetId: expectedBigQuerySettings.logBigQueryDatasetId,\\n  logBigQueryTableId:\\\n  \\ expectedBigQuerySettings.logBigQueryTableId,\\n  eventType: 'custom',\\n  accessToken:\\\n  \\ expectedValue,\\n  pixelId: expectedPixelId,\\n  eventName: expectedValue\\n};\\n\\n\\\n  mock('sendHttpRequest', (requestUrl, callback, requestOptions, requestBody) => {\\n\\\n  \\  if (typeof callback === 'function') {\\n    callback(200);\\n  } else {\\n    requestBody\\\n  \\ = requestOptions;\\n    requestOptions = callback;\\n    return Promise.create((resolve,\\\n  \\ reject) => {\\n      resolve({ statusCode: 200 });\\n    });  \\n  }\\n});\\n\\nmock('getRequestHeader',\\\n  \\ (header) => {\\n  if (header === 'trace-id') return 'expectedTraceId';\\n});\\n\\n\\\n  mock('getTimestampMillis', 1747945830456);\"\n\n\n___NOTES___\n\nCreated on 10/11/2020, 18:14:02\n\n\n",
                "galleryReference": {
                    "host": "github.com",
                    "owner": "stape-io",
                    "repository": "tiktok-tag",
                    "version": "1e962b8a71ed26f73b2dae43bdf0c67c8bf30231",
                    "signature": "92e2a3488d8f339644cb788d57bbef114b18965b9614e43c75f5cdca5760e886",
                    "galleryTemplateId": "K8M24"
                }
            },
            {
                "accountId": "6365534927",
                "containerId": "258048563",
                "templateId": "15",
                "name": "Data Client",
                "fingerprint": "1783780016236",
                "templateData": "___INFO___\n\n{\n  \"type\": \"CLIENT\",\n  \"id\": \"cvt_temp_public_id\",\n  \"version\": 1,\n  \"securityGroups\": [],\n  \"displayName\": \"Data Client\",\n  \"brand\": {\n    \"id\": \"brand_dummy\",\n    \"displayName\": \"Stape\",\n    \"thumbnail\": \"data:image/png;base64,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\"\n  },\n  \"description\": \"Use this Client as a mapper from Request Data to Event Data.\",\n  \"containerContexts\": [\n    \"SERVER\"\n  ]\n}\n\n\n___TEMPLATE_PARAMETERS___\n\n[\n  {\n    \"type\": \"CHECKBOX\",\n    \"name\": \"exposeFPIDCookie\",\n    \"checkboxText\": \"Expose GA4 FPID Cookie\",\n    \"simpleValueType\": true,\n    \"help\": \"If enabled, the \\u003ci\\u003eFPID\\u003c/i\\u003e cookie only accessible by the server and generated by the GA4 Client, will be duplicated to \\u003ci\\u003eFPIDP\\u003c/i\\u003e cookie, which will be accessible in the browser by JavaScript. \\n\\u003cbr/\\u003e\\nIt\\u0027s highly recommend using this option only in case it is necessary.\\n\\u003cbr/\\u003e\\u003cbr/\\u003e\\nThe cookie won\\u0027t be stored if the \\u003ci\\u003eCookie Storage Mode\\u003c/i\\u003e under the \\u003ci\\u003eCookie Consent Settings\\u003c/i\\u003e section receives \\u003ci\\u003edenied\\u003c/i\\u003e.\"\n  },\n  {\n    \"type\": \"CHECKBOX\",\n    \"name\": \"generateClientId\",\n    \"checkboxText\": \"Generate the \\\"client_id\\\" parameter and store it as the \\\"_dcid\\\" cookie\",\n    \"simpleValueType\": true,\n    \"help\": \"If enabled, even if the \\u003ci\\u003eclient_id\\u003c/i\\u003e parameter is not determined from the request, it will still be generated and stored in the \\u003ci\\u003e_dcid\\u003c/i\\u003e cookie.\\n\\u003cbr/\\u003e\\nThe \\u003ci\\u003eclient_id\\u003c/i\\u003e parameter is required by GA4 tags.\\n\\u003cbr/\\u003e\\u003cbr/\\u003e\\nThe cookie won\\u0027t be stored if the \\u003ci\\u003eCookie Storage Mode\\u003c/i\\u003e under the \\u003ci\\u003eCookie Consent Settings\\u003c/i\\u003e section receives \\u003ci\\u003edenied\\u003c/i\\u003e.\",\n    \"defaultValue\": true,\n    \"subParams\": [\n      {\n        \"type\": \"CHECKBOX\",\n        \"name\": \"httpOnlyCookie\",\n        \"checkboxText\": \"Write the \\\"_dcid\\\" cookie as HttpOnly\",\n        \"simpleValueType\": true,\n        \"help\": \"If enabled, the \\u003ci\\u003e_dcid\\u003c/i\\u003e cookie will be written with the HttpOnly flag, making it non-accessible in the browser by JavaScript.\",\n        \"defaultValue\": false,\n        \"enablingConditions\": [\n          {\n            \"paramName\": \"generateClientId\",\n            \"paramValue\": true,\n            \"type\": \"EQUALS\"\n          }\n        ]\n      }\n    ]\n  },\n  {\n    \"type\": \"CHECKBOX\",\n    \"name\": \"prolongCookies\",\n    \"checkboxText\": \"Prolong Data Tag \\\"stape\\\" cookie\",\n    \"simpleValueType\": true,\n    \"help\": \"If enabled, the \\u003ci\\u003estape\\u003c/i\\u003e cookie generated by Data Tag will be reset from the server with an expiration time of 2 years. It\\u0027s useful if you use the store functionality of Data Tag.\\n\\u003cbr/\\u003e\\u003cbr/\\u003e\\nThe cookie won\\u0027t be stored if the \\u003ci\\u003eCookie Storage Mode\\u003c/i\\u003e under the \\u003ci\\u003eCookie Consent Settings\\u003c/i\\u003e section receives \\u003ci\\u003edenied\\u003c/i\\u003e.\",\n    \"defaultValue\": true\n  },\n  {\n    \"type\": \"CHECKBOX\",\n    \"name\": \"acceptMultipleEvents\",\n    \"checkboxText\": \"Accept Multiple Events\",\n    \"simpleValueType\": true,\n    \"help\": \"When the Accept Multiple Events is set to true, the Data Client will parse an array of objects, in the request body, as separate events.\\n\\u003cbr/\\u003e\\nExample:\\n\\u003cbr/\\u003e\\n[\\n  {\\\"event\\\":\\\"page_view\\\"},\\n  {\\\"event\\\":\\\"view_item\\\"}\\n]\",\n    \"defaultValue\": false\n  },\n  {\n    \"type\": \"GROUP\",\n    \"name\": \"responseSettings\",\n    \"displayName\": \"Response Settings\",\n    \"groupStyle\": \"ZIPPY_CLOSED\",\n    \"subParams\": [\n      {\n        \"type\": \"SELECT\",\n        \"name\": \"responseStatusCode\",\n        \"displayName\": \"Response Status Code\",\n        \"selectItems\": [\n          {\n            \"value\": 200,\n            \"displayValue\": \"200\"\n          },\n          {\n            \"value\": 201,\n            \"displayValue\": \"201\"\n          },\n          {\n            \"value\": 301,\n            \"displayValue\": \"301\"\n          },\n          {\n            \"value\": 302,\n            \"displayValue\": \"302\"\n          },\n          {\n            \"value\": 403,\n            \"displayValue\": \"403\"\n          },\n          {\n            \"value\": 404,\n            \"displayValue\": \"404\"\n          }\n        ],\n        \"simpleValueType\": true,\n        \"defaultValue\": 200\n      },\n      {\n        \"type\": \"GROUP\",\n        \"name\": \"regularResponseSettings\",\n        \"groupStyle\": \"NO_ZIPPY\",\n        \"subParams\": [\n          {\n            \"type\": \"SELECT\",\n            \"name\": \"responseBody\",\n            \"displayName\": \"Response Body\",\n            \"macrosInSelect\": false,\n            \"selectItems\": [\n              {\n                \"value\": \"timestamp\",\n                \"displayValue\": \"JSON Object with timestamp (recommended)\"\n              },\n              {\n                \"value\": \"eventData\",\n                \"displayValue\": \"JSON Object with Event Data\"\n              },\n              {\n                \"value\": \"empty\",\n                \"displayValue\": \"Empty\"\n              }\n            ],\n            \"simpleValueType\": true,\n            \"defaultValue\": \"timestamp\"\n          },\n          {\n            \"type\": \"CHECKBOX\",\n            \"name\": \"responseBodyGet\",\n            \"checkboxText\": \"Send Response Body for GET request\",\n            \"simpleValueType\": true,\n            \"help\": \"By default, for the GET request type, the answer is image pixel.  \\u003ca target\\u003d\\\"_blank\\\" href\\u003d\\\"https://developers.google.com/tag-manager/serverside/api#setpixelresponse\\\"\\u003eMore Info\\u003c/a\\u003e.\"\n          }\n        ],\n        \"enablingConditions\": [\n          {\n            \"paramName\": \"responseStatusCode\",\n            \"paramValue\": 200,\n            \"type\": \"EQUALS\"\n          },\n          {\n            \"paramName\": \"responseStatusCode\",\n            \"paramValue\": 201,\n            \"type\": \"EQUALS\"\n          }\n        ]\n      },\n      {\n        \"type\": \"GROUP\",\n        \"name\": \"redirectResponseSettings\",\n        \"groupStyle\": \"NO_ZIPPY\",\n        \"subParams\": [\n          {\n            \"type\": \"TEXT\",\n            \"name\": \"redirectTo\",\n            \"displayName\": \"Redirect To\",\n            \"simpleValueType\": true,\n            \"valueValidators\": [\n              {\n                \"type\": \"NON_EMPTY\"\n              },\n              {\n                \"type\": \"REGEX\",\n                \"args\": [\n                  \"^https?:\\\\/\\\\/.*\"\n                ]\n              }\n            ]\n          },\n          {\n            \"type\": \"CHECKBOX\",\n            \"name\": \"lookupForRedirectToParam\",\n            \"checkboxText\": \"Try to find redirect destination in query params\",\n            \"simpleValueType\": true,\n            \"help\": \"Override destination URL with query param from request url\"\n          },\n          {\n            \"type\": \"TEXT\",\n            \"name\": \"redirectToQueryParamName\",\n            \"displayName\": \"Query Param Name\",\n            \"simpleValueType\": true,\n            \"enablingConditions\": [\n              {\n                \"paramName\": \"lookupForRedirectToParam\",\n                \"paramValue\": true,\n                \"type\": \"EQUALS\"\n              }\n            ],\n            \"valueValidators\": [\n              {\n                \"type\": \"NON_EMPTY\"\n              }\n            ]\n          }\n        ],\n        \"enablingConditions\": [\n          {\n            \"paramName\": \"responseStatusCode\",\n            \"paramValue\": 301,\n            \"type\": \"EQUALS\"\n          },\n          {\n            \"paramName\": \"responseStatusCode\",\n            \"paramValue\": 302,\n            \"type\": \"EQUALS\"\n          }\n        ]\n      },\n      {\n        \"type\": \"GROUP\",\n        \"name\": \"clientErrorResponseSettings\",\n        \"groupStyle\": \"NO_ZIPPY\",\n        \"subParams\": [\n          {\n            \"type\": \"TEXT\",\n            \"name\": \"clientErrorResponseMessage\",\n            \"displayName\": \"Client Error Response Message\",\n            \"simpleValueType\": true,\n            \"valueValidators\": [\n              {\n                \"type\": \"NON_EMPTY\"\n              }\n            ]\n          }\n        ],\n        \"enablingConditions\": [\n          {\n            \"paramName\": \"responseStatusCode\",\n            \"paramValue\": 403,\n            \"type\": \"EQUALS\"\n          },\n          {\n            \"paramName\": \"responseStatusCode\",\n            \"paramValue\": 404,\n            \"type\": \"EQUALS\"\n          }\n        ]\n      }\n    ]\n  },\n  {\n    \"type\": \"GROUP\",\n    \"name\": \"pathSettings\",\n    \"displayName\": \"Accepted Path Settings\",\n    \"groupStyle\": \"ZIPPY_CLOSED\",\n    \"subParams\": [\n      {\n        \"type\": \"SIMPLE_TABLE\",\n        \"name\": \"path\",\n        \"displayName\": \"Type additional paths that will be claimed by this client\",\n        \"simpleTableColumns\": [\n          {\n            \"defaultValue\": \"\",\n            \"displayName\": \"For example: /callback\",\n            \"name\": \"path\",\n            \"type\": \"TEXT\",\n            \"isUnique\": true,\n            \"valueValidators\": [\n              {\n                \"type\": \"NON_EMPTY\"\n              }\n            ]\n          }\n        ],\n        \"newRowButtonText\": \"Add path\",\n        \"help\": \"By default path \\u003cb\\u003e/data\\u003c/b\\u003e will be claimed. But you can add more paths that will be claimed by this client.\"\n      }\n    ]\n  },\n  {\n    \"type\": \"GROUP\",\n    \"name\": \"cookieConsentSettingsGroup\",\n    \"displayName\": \"Cookie Consent Settings\",\n    \"groupStyle\": \"ZIPPY_CLOSED\",\n    \"subParams\": [\n      {\n        \"type\": \"SELECT\",\n        \"name\": \"cookieStorageMode\",\n        \"macrosInSelect\": false,\n        \"selectItems\": [\n          {\n            \"value\": \"auto\",\n            \"displayValue\": \"Store cookies based on Consent Status from Stape\\u0027s Data Tag\"\n          },\n          {\n            \"value\": \"manual\",\n            \"displayValue\": \"Store cookies based on manual Consent Status\"\n          }\n        ],\n        \"simpleValueType\": true,\n        \"subParams\": [\n          {\n            \"type\": \"SELECT\",\n            \"name\": \"cookieConsentAutoParameter\",\n            \"displayName\": \"Consent Status Parameter\",\n            \"selectItems\": [\n              {\n                \"value\": \"analytics_storage\",\n                \"displayValue\": \"analytics_storage\"\n              },\n              {\n                \"value\": \"ad_storage\",\n                \"displayValue\": \"ad_storage\"\n              }\n            ],\n            \"simpleValueType\": true,\n            \"help\": \"If you are using Stape\\u0027s Data Tag to transmit consent to the server, choose parameter corresponding to the consent category to which the cookies set by Data Client were allocated in your Consent Management Platform.\\n\\u003cbr/\\u003e\\nBe sure to enable the \\u003ci\\u003eAdd consent state\\u003c/i\\u003e option in the Data Tag.\",\n            \"enablingConditions\": [\n              {\n                \"paramName\": \"cookieStorageMode\",\n                \"paramValue\": \"auto\",\n                \"type\": \"EQUALS\"\n              }\n            ],\n            \"valueValidators\": [\n              {\n                \"type\": \"NON_EMPTY\"\n              }\n            ]\n          },\n          {\n            \"type\": \"TEXT\",\n            \"name\": \"cookieConsentManualValue\",\n            \"displayName\": \"Consent Status Manual\",\n            \"simpleValueType\": true,\n            \"help\": \"Use this field if you are not using Google Consent Mode.\\n\\u003cbr/\\u003e\\nThis field allows you to specify the user consent status using a custom variable.\\n\\u003cbr/\\u003e\\u003cbr/\\u003e\\nAccepted values:\\n\\u003cul\\u003e\\n\\u003cli\\u003efor Denied: \\u003ci\\u003e0\\u003c/i\\u003e, \\u003ci\\u003efalse\\u003c/i\\u003e and \\u003ci\\u003edenied\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003cli\\u003efor Granted: \\u003ci\\u003e1\\u003c/i\\u003e, \\u003ci\\u003etrue\\u003c/i\\u003e and \\u003ci\\u003egranted\\u003c/i\\u003e\\u003c/li\\u003e\\n\\u003c/ul\\u003e\\n\\u003cbr/\\u003e\\nIf any other values are passed, or the field is left blank, the tag will assume \\u003ci\\u003egranted\\u003c/i\\u003e was specified.\",\n            \"enablingConditions\": [\n              {\n                \"paramName\": \"cookieStorageMode\",\n                \"paramValue\": \"manual\",\n                \"type\": \"EQUALS\"\n              }\n            ]\n          }\n        ],\n        \"notSetText\": \"Always store cookies\",\n        \"displayName\": \"Cookie Storage Mode\",\n        \"help\": \"Use this option to conditionally control whether the Data Client will store cookies based on consent signals that are present in the incoming request or based on manual input.\\n\\u003cbr/\\u003e\\nBy default, it always store cookies.\"\n      }\n    ]\n  }\n]\n\n\n___SANDBOXED_JS_FOR_SERVER___\n\nconst computeEffectiveTldPlusOne = require('computeEffectiveTldPlusOne');\nconst createRegex = require('createRegex');\nconst decodeUriComponent = require('decodeUriComponent');\nconst fromBase64 = require('fromBase64');\nconst generateRandom = require('generateRandom');\nconst getCookieValues = require('getCookieValues');\nconst getRemoteAddress = require('getRemoteAddress');\nconst getRequestBody = require('getRequestBody');\nconst getRequestHeader = require('getRequestHeader');\nconst getRequestMethod = require('getRequestMethod');\nconst getRequestPath = require('getRequestPath');\nconst getRequestQueryParameter = require('getRequestQueryParameter');\nconst getRequestQueryParameters = require('getRequestQueryParameters');\nconst getTimestampMillis = require('getTimestampMillis');\nconst getType = require('getType');\nconst JSON = require('JSON');\nconst makeInteger = require('makeInteger');\nconst makeString = require('makeString');\nconst Object = require('Object');\nconst returnResponse = require('returnResponse');\nconst runContainer = require('runContainer');\nconst setCookie = require('setCookie');\nconst setPixelResponse = require('setPixelResponse');\nconst setResponseBody = require('setResponseBody');\nconst setResponseHeader = require('setResponseHeader');\nconst setResponseStatus = require('setResponseStatus');\n\n/*==============================================================================\n==============================================================================*/\n\nconst requestMethod = getRequestMethod();\nconst path = getRequestPath();\nlet isClientUsed = false;\nlet isEventModelsWrappedInArray = false;\n\nif (path === '/data') {\n  runClient();\n}\n\nif (data.path && !isClientUsed) {\n  for (let key in data.path) {\n    if (!isClientUsed && data.path[key].path === path) {\n      runClient();\n    }\n  }\n}\n\n/*==============================================================================\n  Vendor related functions\n==============================================================================*/\n\nfunction runClient() {\n  isClientUsed = true;\n  require('claimRequest')();\n\n  if (requestMethod === 'OPTIONS') {\n    setCommonResponseHeaders(200);\n    returnResponse();\n    return;\n  }\n  const baseEventModel = getBaseEventModelWithQueryParameters();\n  let eventModels = getEventModels(baseEventModel);\n  const clientId = getClientId(eventModels);\n  eventModels = eventModels.map((eventModel) => {\n    eventModel = addRequiredParametersToEventModel(eventModel);\n    eventModel = addCommonParametersToEventModel(eventModel);\n    eventModel = addClientIdToEventModel(eventModel, clientId);\n    if (eventModel._dcid_temp) Object.delete(eventModel, '_dcid_temp');\n    return eventModel;\n  });\n\n  const consentDeclined = isConsentDeclined(data, eventModels[0]);\n  storeClientId(eventModels[0], consentDeclined);\n  exposeFPIDCookie(eventModels[0], consentDeclined);\n  prolongDataTagCookies(eventModels[0], consentDeclined);\n\n  const responseStatusCode = makeInteger(data.responseStatusCode || 200);\n  setCommonResponseHeaders(responseStatusCode);\n\n  let counter = 0;\n  eventModels.forEach((event) => {\n    runContainer(event, () => {\n      if (++counter === eventModels.length) {\n        switch (responseStatusCode) {\n          case 200:\n          case 201:\n            if (requestMethod === 'POST' || data.responseBodyGet) {\n              prepareResponseBody(eventModels);\n            } else {\n              setPixelResponse();\n            }\n            break;\n          case 301:\n          case 302:\n            setRedirectLocation();\n            break;\n          case 403:\n          case 404:\n            setClientErrorResponseMessage();\n            break;\n        }\n\n        returnResponse();\n      }\n    });\n  });\n}\n\nfunction addCommonParametersToEventModel(eventModel) {\n  if (!eventModel.ip_override) {\n    const ipOverride = eventModel.ip || eventModel.ipOverride || getRemoteAddress();\n    eventModel.ip_override = ipOverride;\n  }\n\n  if (!eventModel.user_agent) {\n    const userAgent = eventModel.userAgent || getRequestHeader('User-Agent');\n    if (userAgent) eventModel.user_agent = userAgent;\n  }\n\n  if (!eventModel.language) {\n    const acceptLanguageHeader = getRequestHeader('Accept-Language');\n    if (acceptLanguageHeader) {\n      eventModel.language = acceptLanguageHeader.split(';')[0].substring(0, 2).toLowerCase();\n    }\n  }\n\n  if (!eventModel.page_hostname) {\n    const pageHostname = eventModel.pageHostname || eventModel.hostname;\n    if (pageHostname) eventModel.page_hostname = pageHostname;\n  }\n\n  if (!eventModel.page_location) {\n    const pageLocation = eventModel.pageLocation || eventModel.url || eventModel.href;\n    if (pageLocation) eventModel.page_location = pageLocation;\n  }\n\n  if (!eventModel.page_referrer) {\n    const pageReferrer = eventModel.pageReferrer || eventModel.referrer || eventModel.urlref;\n    if (pageReferrer) eventModel.page_referrer = pageReferrer;\n  }\n\n  if (!eventModel.value && eventModel.e_v) eventModel.value = eventModel.e_v;\n\n  if (getType(eventModel.items) === 'array' && eventModel.items.length) {\n    const firstItem = eventModel.items[0];\n    if (!eventModel.currency && firstItem.currency) eventModel.currency = firstItem.currency;\n    if (eventModel.items.length === 1) {\n      if (!eventModel.item_id && firstItem.item_id) eventModel.item_id = firstItem.item_id;\n      if (!eventModel.item_name && firstItem.item_name) eventModel.item_name = firstItem.item_name;\n      if (!eventModel.item_brand && firstItem.item_brand)\n        eventModel.item_brand = firstItem.item_brand;\n      if (!eventModel.item_quantity && firstItem.quantity)\n        eventModel.item_quantity = firstItem.quantity;\n      if (!eventModel.item_category && firstItem.item_category)\n        eventModel.item_category = firstItem.item_category;\n      if (!eventModel.item_price && firstItem.price) eventModel.item_price = firstItem.price;\n    }\n    if (!eventModel.value) {\n      const valueFromItems = eventModel.items.reduce((acc, item) => {\n        if (!item.price) return acc;\n        const quantity = item.quantity ? item.quantity : 1;\n        return acc + quantity * item.price;\n      }, 0);\n      if (valueFromItems) eventModel.value = valueFromItems;\n    }\n  }\n\n  const ecommerceAction = getEcommerceAction(eventModel);\n\n  if (ecommerceAction) {\n    if (!eventModel['x-ga-mp1-pa']) eventModel['x-ga-mp1-pa'] = ecommerceAction;\n\n    if (ecommerceAction === 'purchase' && eventModel.ecommerce.purchase.actionField) {\n      if (!eventModel['x-ga-mp1-tr'])\n        eventModel['x-ga-mp1-tr'] = eventModel.ecommerce.purchase.actionField.revenue;\n      if (!eventModel.revenue)\n        eventModel.revenue = eventModel.ecommerce.purchase.actionField.revenue;\n      if (!eventModel.affiliation)\n        eventModel.affiliation = eventModel.ecommerce.purchase.actionField.affiliation;\n      if (!eventModel.tax) eventModel.tax = eventModel.ecommerce.purchase.actionField.tax;\n      if (!eventModel.shipping)\n        eventModel.shipping = eventModel.ecommerce.purchase.actionField.shipping;\n      if (!eventModel.coupon) eventModel.coupon = eventModel.ecommerce.purchase.actionField.coupon;\n      if (!eventModel.transaction_id)\n        eventModel.transaction_id = eventModel.ecommerce.purchase.actionField.id;\n    }\n  }\n\n  if (!eventModel.page_encoding && eventModel.pageEncoding)\n    eventModel.page_encoding = eventModel.pageEncoding;\n  if (!eventModel.page_path && eventModel.pagePath) eventModel.page_path = eventModel.pagePath;\n  if (!eventModel.page_title && eventModel.pageTitle) eventModel.page_title = eventModel.pageTitle;\n  if (!eventModel.screen_resolution && eventModel.screenResolution)\n    eventModel.screen_resolution = eventModel.screenResolution;\n  if (!eventModel.viewport_size && eventModel.viewportSize)\n    eventModel.viewport_size = eventModel.viewportSize;\n  if (!eventModel.user_id && eventModel.userId) eventModel.user_id = eventModel.userId;\n\n  if (!eventModel.user_data) {\n    let userData = {};\n    let userAddressData = {};\n\n    if (!userData.email_address) {\n      const emailAddress =\n        eventModel.userEmail || eventModel.email_address || eventModel.email || eventModel.mail;\n      if (emailAddress) userData.email_address = emailAddress;\n    }\n\n    if (!userData.phone_number) {\n      const phoneNumber =\n        eventModel.userPhoneNumber ||\n        eventModel.phone_number ||\n        eventModel.phoneNumber ||\n        eventModel.phone;\n      if (phoneNumber) userData.phone_number = phoneNumber;\n    }\n\n    if (!userAddressData.street && eventModel.street) userAddressData.street = eventModel.street;\n    if (!userAddressData.city && eventModel.city) userAddressData.city = eventModel.city;\n    if (!userAddressData.region && eventModel.region) userAddressData.region = eventModel.region;\n    if (!userAddressData.country && eventModel.country)\n      userAddressData.country = eventModel.country;\n\n    if (!userAddressData.first_name) {\n      const firstName =\n        eventModel.userFirstName ||\n        eventModel.first_name ||\n        eventModel.firstName ||\n        eventModel.name;\n      if (firstName) userAddressData.first_name = firstName;\n    }\n\n    if (!userAddressData.last_name) {\n      const lastName =\n        eventModel.userLastName ||\n        eventModel.last_name ||\n        eventModel.lastName ||\n        eventModel.surname ||\n        eventModel.family_name ||\n        eventModel.familyName;\n      if (lastName) userAddressData.last_name = lastName;\n    }\n\n    if (!userAddressData.region) {\n      if (eventModel.region) userAddressData.region = eventModel.region;\n      else if (eventModel.state) userAddressData.region = eventModel.state;\n    }\n\n    if (!userAddressData.postal_code) {\n      const postalCode = eventModel.postal_code || eventModel.postalCode || eventModel.zip;\n      if (postalCode) userAddressData.postal_code = postalCode;\n    }\n\n    if (getObjectLength(userAddressData) !== 0) {\n      userData.address = userAddressData;\n    }\n\n    if (!eventModel.user_data && getObjectLength(userData) !== 0) {\n      eventModel.user_data = userData;\n    }\n  }\n\n  return eventModel;\n}\n\nfunction getBaseEventModelWithQueryParameters() {\n  const requestQueryParameters = getRequestQueryParameters();\n  const eventModel = {};\n\n  if (requestQueryParameters) {\n    for (let queryParameterKey in requestQueryParameters) {\n      if (\n        (queryParameterKey === 'dtcd' || queryParameterKey === 'dtdc') &&\n        requestMethod === 'GET'\n      ) {\n        let dt =\n          queryParameterKey === 'dtcd'\n            ? JSON.parse(requestQueryParameters[queryParameterKey])\n            : JSON.parse(fromBase64(requestQueryParameters[queryParameterKey]));\n\n        for (let dtKey in dt) {\n          eventModel[dtKey] = dt[dtKey];\n        }\n      } else {\n        eventModel[queryParameterKey] = requestQueryParameters[queryParameterKey];\n      }\n    }\n  }\n\n  return eventModel;\n}\n\nfunction addClientIdToEventModel(eventModel, clientId) {\n  eventModel.client_id = clientId;\n  return eventModel;\n}\n\nfunction prolongDataTagCookies(eventModel, consentDeclined) {\n  if (consentDeclined || !data.prolongCookies) return;\n\n  const stapeData = getCookieValues('stape');\n  if (stapeData.length) {\n    setCookie('stape', stapeData[0], {\n      domain: 'auto',\n      path: '/',\n      samesite: getCookieType(eventModel),\n      secure: true,\n      'max-age': 63072000, // 2 years\n      httpOnly: false\n    });\n  }\n}\n\nfunction addRequiredParametersToEventModel(eventModel) {\n  if (!eventModel.event_name) {\n    const eventName = eventModel.eventName || eventModel.event || eventModel.e_n || 'Data';\n    eventModel.event_name = eventName;\n  }\n\n  return eventModel;\n}\n\nfunction exposeFPIDCookie(eventModel, consentDeclined) {\n  if (consentDeclined || !data.exposeFPIDCookie) return;\n\n  const fpid = getCookieValues('FPID');\n  if (fpid.length) {\n    setCookie('FPIDP', fpid[0], {\n      domain: 'auto',\n      path: '/',\n      samesite: getCookieType(eventModel),\n      secure: true,\n      'max-age': 63072000, // 2 years\n      httpOnly: false\n    });\n  }\n}\n\nfunction storeClientId(eventModel, consentDeclined) {\n  if (consentDeclined || !data.generateClientId) return;\n\n  setCookie('_dcid', eventModel.client_id, {\n    domain: 'auto',\n    path: '/',\n    samesite: getCookieType(eventModel),\n    secure: true,\n    'max-age': 63072000, // 2 years\n    httpOnly: data.httpOnlyCookie || false\n  });\n}\n\nfunction setCommonResponseHeaders(statusCode) {\n  setResponseHeader('Access-Control-Max-Age', '600');\n  setResponseHeader('Access-Control-Allow-Origin', getRequestHeader('origin'));\n  setResponseHeader('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,OPTIONS');\n  setResponseHeader(\n    'Access-Control-Allow-Headers',\n    'content-type,set-cookie,x-robots-tag,x-gtm-server-preview,x-stape-preview,x-stape-app-version'\n  );\n  setResponseHeader('Access-Control-Allow-Credentials', 'true');\n  setResponseStatus(statusCode);\n}\n\nfunction getCookieType(eventModel) {\n  if (!eventModel.page_location) {\n    return 'Lax';\n  }\n\n  const host = getRequestHeader('host');\n  const effectiveTldPlusOne = computeEffectiveTldPlusOne(eventModel.page_location);\n\n  if (!host || !effectiveTldPlusOne) {\n    return 'Lax';\n  }\n\n  if (host && host.indexOf(effectiveTldPlusOne) !== -1) {\n    return 'Lax';\n  }\n\n  return 'None';\n}\n\nfunction prepareResponseBody(eventModels) {\n  if (data.responseBody === 'empty') {\n    return;\n  }\n\n  const responseModel = isEventModelsWrappedInArray ? eventModels[0] : eventModels;\n\n  setResponseHeader('Content-Type', 'application/json');\n\n  if (data.responseBody === 'eventData') {\n    setResponseBody(JSON.stringify(responseModel));\n\n    return;\n  }\n\n  if (isEventModelsWrappedInArray) {\n    setResponseBody(\n      JSON.stringify({\n        timestamp: responseModel.timestamp,\n        unique_event_id: responseModel.unique_event_id\n      })\n    );\n    return;\n  }\n\n  setResponseBody(\n    JSON.stringify(\n      eventModels.map((eventModel) => {\n        return {\n          timestamp: eventModel.timestamp,\n          unique_event_id: eventModel.unique_event_id\n        };\n      })\n    )\n  );\n}\n\nfunction getEcommerceAction(eventModel) {\n  if (eventModel.ecommerce) {\n    const actions = [\n      'detail',\n      'click',\n      'add',\n      'remove',\n      'checkout',\n      'checkout_option',\n      'purchase',\n      'refund'\n    ];\n\n    for (let index = 0; index < actions.length; ++index) {\n      const action = actions[index];\n\n      if (eventModel.ecommerce[action]) {\n        return action;\n      }\n    }\n  }\n\n  return null;\n}\n\nfunction setRedirectLocation() {\n  let location = data.redirectTo;\n  if (data.lookupForRedirectToParam && data.redirectToQueryParamName) {\n    const param = getRequestQueryParameter(data.redirectToQueryParamName);\n    if (param && param.startsWith('http')) {\n      location = param;\n    }\n  }\n  setResponseHeader('location', location);\n}\n\nfunction setClientErrorResponseMessage() {\n  if (data.clientErrorResponseMessage) {\n    setResponseBody(data.clientErrorResponseMessage);\n  }\n}\n\nfunction getEventModels(baseEventModel) {\n  const body = getRequestBody();\n\n  if (body) {\n    const contentType = getRequestHeader('content-type');\n    const isFormUrlEncoded =\n      !!contentType && contentType.indexOf('application/x-www-form-urlencoded') !== -1;\n    let bodyJson = isFormUrlEncoded ? parseUrlEncoded(body) : JSON.parse(body);\n    if (bodyJson) {\n      const bodyType = getType(bodyJson);\n      const shouldUseOriginalBody = data.acceptMultipleEvents && bodyType === 'array';\n      if (!shouldUseOriginalBody) {\n        bodyJson = [bodyJson];\n        isEventModelsWrappedInArray = true;\n      }\n\n      return bodyJson.map((bodyItem) => {\n        const eventModel = assign(\n          {\n            timestamp: makeInteger(getTimestampMillis() / 1000),\n            unique_event_id: getTimestampMillis() + '_' + generateRandom(100000000, 999999999)\n          },\n          baseEventModel\n        );\n        for (let bodyItemKey in bodyItem) {\n          eventModel[bodyItemKey] = bodyItem[bodyItemKey];\n        }\n        return eventModel;\n      });\n    }\n  }\n\n  return [\n    assign(\n      {\n        timestamp: makeInteger(getTimestampMillis() / 1000),\n        unique_event_id: getTimestampMillis() + '_' + generateRandom(100000000, 999999999)\n      },\n      baseEventModel\n    )\n  ];\n}\n\nfunction getClientId(eventModels) {\n  for (let i = 0; i < eventModels.length; i++) {\n    const eventModel = eventModels[i];\n    const clientId = eventModel.client_id || eventModel.data_client_id || eventModel._dcid;\n    if (clientId) return clientId;\n  }\n\n  const dcid = getCookieValues('_dcid');\n  if (dcid && dcid[0]) return dcid[0];\n\n  if (data.generateClientId) {\n    for (let i = 0; i < eventModels.length; i++) {\n      const eventModel = eventModels[i];\n      const tempClientId = eventModel._dcid_temp;\n      if (tempClientId) return tempClientId;\n    }\n\n    return 'dcid.1.' + getTimestampMillis() + '.' + generateRandom(100000000, 999999999);\n  }\n\n  return '';\n}\n\nfunction isConsentDeclined(data, eventData) {\n  const cookieStorageMode = data.cookieStorageMode;\n  if (!cookieStorageMode) return false;\n\n  if (cookieStorageMode === 'auto' && getType(eventData.consent_state) === 'object') {\n    // Check consent state from Stape's Data Tag\n    return eventData.consent_state[data.cookieConsentAutoParameter] === false;\n  } else if (cookieStorageMode === 'manual') {\n    // Check template field specific consent signal\n    return ['0', 0, 'false', false, 'denied'].indexOf(data.cookieConsentManualValue) !== -1;\n  }\n\n  return false;\n}\n\n/*==============================================================================\n  Helpers\n==============================================================================*/\n\nfunction getObjectLength(object) {\n  let length = 0;\n\n  for (let key in object) {\n    if (object.hasOwnProperty(key)) {\n      ++length;\n    }\n  }\n  return length;\n}\n\nfunction assign() {\n  const target = arguments[0];\n  for (let i = 1; i < arguments.length; i++) {\n    for (let key in arguments[i]) {\n      target[key] = arguments[i][key];\n    }\n  }\n  return target;\n}\n\nfunction parseUrlEncoded(data) {\n  const pairs = data.split('&');\n  const parsedData = {};\n  const regex = createRegex('\\\\+', 'g');\n  for (const pair of pairs) {\n    const pairValue = pair.split('=');\n    const key = pairValue[0];\n    const value = pairValue[1];\n    const keys = key.split('.').map((k) => decodeUriComponent(k.replace(regex, ' ')));\n\n    let currentObject = parsedData;\n\n    for (let i = 0; i < keys.length - 1; i++) {\n      const currentKey = keys[i];\n\n      if (!currentObject[currentKey]) {\n        const nextKey = keys[i + 1];\n        const nextKeyIsNumber = makeString(makeInteger(nextKey)) === nextKey;\n        currentObject[currentKey] = nextKeyIsNumber ? [] : {};\n      }\n\n      currentObject = currentObject[currentKey];\n    }\n\n    const lastKey = keys[keys.length - 1];\n    const decodedValue = decodeUriComponent(value.replace(regex, ' '));\n    const parsedValue = JSON.parse(decodedValue) || decodedValue;\n\n    if (getType(currentObject) === 'array') {\n      currentObject.push(parsedValue);\n    } else {\n      currentObject[lastKey] = parsedValue;\n    }\n  }\n\n  return parsedData;\n}\n\n\n___SERVER_PERMISSIONS___\n\n[\n  {\n    \"instance\": {\n      \"key\": {\n        \"publicId\": \"return_response\",\n        \"versionId\": \"1\"\n      },\n      \"param\": []\n    },\n    \"isRequired\": true\n  },\n  {\n    \"instance\": {\n      \"key\": {\n        \"publicId\": \"access_response\",\n        \"versionId\": \"1\"\n      },\n      \"param\": [\n        {\n          \"key\": \"writeResponseAccess\",\n          \"value\": {\n            \"type\": 1,\n            \"string\": \"any\"\n          }\n        },\n        {\n          \"key\": \"writeHeaderAccess\",\n          \"value\": {\n            \"type\": 1,\n            \"string\": \"specific\"\n          }\n        }\n      ]\n    },\n    \"clientAnnotations\": {\n      \"isEditedByUser\": true\n    },\n    \"isRequired\": true\n  },\n  {\n    \"instance\": {\n      \"key\": {\n        \"publicId\": \"run_container\",\n        \"versionId\": \"1\"\n      },\n      \"param\": []\n    },\n    \"isRequired\": true\n  },\n  {\n    \"instance\": {\n      \"key\": {\n        \"publicId\": \"get_cookies\",\n        \"versionId\": \"1\"\n      },\n      \"param\": [\n        {\n          \"key\": \"cookieAccess\",\n          \"value\": {\n            \"type\": 1,\n            \"string\": \"specific\"\n          }\n        },\n        {\n          \"key\": \"cookieNames\",\n          \"value\": {\n            \"type\": 2,\n            \"listItem\": [\n              {\n                \"type\": 1,\n                \"string\": \"stape\"\n              },\n              {\n                \"type\": 1,\n                \"string\": \"_dcid\"\n              },\n              {\n                \"type\": 1,\n                \"string\": \"FPIDP\"\n              },\n              {\n                \"type\": 1,\n                \"string\": \"FPID\"\n              }\n            ]\n          }\n        }\n      ]\n    },\n    \"clientAnnotations\": {\n      \"isEditedByUser\": true\n    },\n    \"isRequired\": true\n  },\n  {\n    \"instance\": {\n      \"key\": {\n        \"publicId\": \"read_request\",\n        \"versionId\": \"1\"\n      },\n      \"param\": [\n        {\n          \"key\": \"requestAccess\",\n          \"value\": {\n            \"type\": 1,\n            \"string\": \"any\"\n          }\n        },\n        {\n          \"key\": \"headerAccess\",\n          \"value\": {\n            \"type\": 1,\n            \"string\": \"any\"\n          }\n        },\n        {\n          \"key\": \"queryParameterAccess\",\n          \"value\": {\n            \"type\": 1,\n            \"string\": \"any\"\n          }\n        }\n      ]\n    },\n    \"clientAnnotations\": {\n      \"isEditedByUser\": true\n    },\n    \"isRequired\": true\n  },\n  {\n    \"instance\": {\n      \"key\": {\n        \"publicId\": \"set_cookies\",\n        \"versionId\": \"1\"\n      },\n      \"param\": [\n        {\n          \"key\": \"allowedCookies\",\n          \"value\": {\n            \"type\": 2,\n            \"listItem\": [\n              {\n                \"type\": 3,\n                \"mapKey\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"name\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"domain\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"path\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"secure\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"session\"\n                  }\n                ],\n                \"mapValue\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"stape\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"*\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"*\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"any\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"any\"\n                  }\n                ]\n              },\n              {\n                \"type\": 3,\n                \"mapKey\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"name\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"domain\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"path\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"secure\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"session\"\n                  }\n                ],\n                \"mapValue\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"_dcid\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"*\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"*\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"any\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"any\"\n                  }\n                ]\n              },\n              {\n                \"type\": 3,\n                \"mapKey\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"name\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"domain\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"path\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"secure\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"session\"\n                  }\n                ],\n                \"mapValue\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"FPIDP\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"*\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"*\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"any\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"any\"\n                  }\n                ]\n              }\n            ]\n          }\n        }\n      ]\n    },\n    \"clientAnnotations\": {\n      \"isEditedByUser\": true\n    },\n    \"isRequired\": true\n  }\n]\n\n\n___TESTS___\n\nscenarios:\n- name: runContainer is called succesfully for a single event and response is sent\n    back once\n  code: \"mock('getRequestPath', '/data');\\nmock('getRequestMethod', 'POST');\\nmock('getRequestBody',\\\n    \\ '{\\\"event\\\":\\\"page_view\\\",\\\"client_id\\\":\\\"client_id\\\"}');\\n\\n/* \\n  For some\\\n    \\ reason when we use \\\"assertApi('claimRequest').wasCalled()\\\" AND we run all\\\n    \\ the tests,\\n  it produces the following error \\\"Tried to claim a request after\\\n    \\ a Client had returned. Calling claimRequest from a callback is not supported.\\\"\\\n    \\n  If we run only this single test, the error does not occur.\\n  A workaround\\\n    \\ is to mock 'claimRequest' API and make a dummy assertion in the mocked function.\\\n    \\ This way we make sure it's been called.\\n*/\\nlet claimRequestWasCalled;\\nmock('claimRequest',\\\n    \\ () => {\\n  claimRequestWasCalled = true;\\n});\\n\\nlet runContainerExecutions\\\n    \\ = 0;\\nconst runContainerExpectedExecutions = 1;\\nmock('runContainer', (eventData,\\\n    \\ onCompleteCallback, onStartCallback) => {\\n  assertThat(eventData).isObject();\\n\\\n    \\  runContainerExecutions++;\\n  assertThat(onCompleteCallback).isFunction();\\n\\\n    \\  onCompleteCallback();\\n});\\n\\nmock('returnResponse', () => {\\n  if (runContainerExecutions\\\n    \\ !== runContainerExpectedExecutions) {\\n    fail('returnResponse should be called\\\n    \\ by the last runContainer onComplete callback execution only.');\\n    return;\\n\\\n    \\  }\\n  assertThat(true).isTrue(); // Dummy to cover the case when runContainerExecutions\\\n    \\ === runContainerExpectedExecutions.\\n});\\n\\nrunCode(mockData);\\n\\ncallLater(()\\\n    \\ => {\\n  assertThat(claimRequestWasCalled).isTrue();\\n  assertApi('setResponseStatus').wasCalledWith(200);\\n\\\n    \\  assertThat(runContainerExecutions).isEqualTo(runContainerExpectedExecutions);\\n\\\n    });\"\n- name: runContainer is called succesfully for multiple events and response is sent\n    back once\n  code: \"mockData.acceptMultipleEvents = true;\\n\\nmock('getRequestPath', '/data');\\n\\\n    mock('getRequestMethod', 'POST');\\nmock('getRequestBody', '[{\\\"event\\\":\\\"page_view\\\"\\\n    ,\\\"client_id\\\":\\\"client_id\\\"},{\\\"event\\\":\\\"view_item\\\",\\\"client_id\\\":\\\"client_id\\\"\\\n    }]');\\n\\n/* \\n  For some reason when we use \\\"assertApi('claimRequest').wasCalled()\\\"\\\n    \\ AND we run all the tests,\\n  it produces the following error \\\"Tried to claim\\\n    \\ a request after a Client had returned. Calling claimRequest from a callback\\\n    \\ is not supported.\\\"\\n  If we run only this single test, the error does not occur.\\n\\\n    \\  A workaround is to mock 'claimRequest' API and make a dummy assertion in the\\\n    \\ mocked function. This way we make sure it's been called.\\n*/\\nlet claimRequestWasCalled;\\n\\\n    mock('claimRequest', () => {\\n  claimRequestWasCalled = true;\\n});\\n\\nlet runContainerExecutions\\\n    \\ = 0;\\nconst runContainerExpectedExecutions = 2;\\nmock('runContainer', (eventData,\\\n    \\ onCompleteCallback, onStartCallback) => {\\n  assertThat(eventData).isObject();\\n\\\n    \\  runContainerExecutions++;\\n  assertThat(onCompleteCallback).isFunction();\\n\\\n    \\  onCompleteCallback();\\n});\\n\\nmock('returnResponse', () => {\\n  if (runContainerExecutions\\\n    \\ !== runContainerExpectedExecutions) {\\n    fail('returnResponse should be called\\\n    \\ by the last runContainer onComplete callback execution only.');\\n    return;\\n\\\n    \\  }\\n  assertThat(true).isTrue(); // Dummy to cover the case when runContainerExecutions\\\n    \\ === runContainerExpectedExecutions.\\n});\\n\\nrunCode(mockData);\\n\\ncallLater(()\\\n    \\ => {\\n  assertThat(claimRequestWasCalled).isTrue();\\n  assertApi('setResponseStatus').wasCalledWith(200);\\n\\\n    \\  assertThat(runContainerExecutions).isEqualTo(runContainerExpectedExecutions);\\n\\\n    });\"\n- name: Should fallback to 200 if Response Status Code is absent from the data object\n  code: \"mockData.acceptMultipleEvents = true;\\n\\nObject.delete(mockData, 'responseStatusCode');\\n\\\n    \\nmock('getRequestPath', '/data');\\nmock('getRequestMethod', 'POST');\\nmock('getRequestBody',\\\n    \\ '[{\\\"event\\\":\\\"page_view\\\",\\\"client_id\\\":\\\"client_id\\\"},{\\\"event\\\":\\\"view_item\\\"\\\n    ,\\\"client_id\\\":\\\"client_id\\\"}]');\\n\\n/* \\n  For some reason when we use \\\"assertApi('claimRequest').wasCalled()\\\"\\\n    \\ AND we run all the tests,\\n  it produces the following error \\\"Tried to claim\\\n    \\ a request after a Client had returned. Calling claimRequest from a callback\\\n    \\ is not supported.\\\"\\n  If we run only this single test, the error does not occur.\\n\\\n    \\  A workaround is to mock 'claimRequest' API and make a dummy assertion in the\\\n    \\ mocked function. This way we make sure it's been called.\\n*/\\nlet claimRequestWasCalled;\\n\\\n    mock('claimRequest', () => {\\n  claimRequestWasCalled = true;\\n});\\n\\nmock('setResponseStatus',\\\n    \\ (responseStatus) => {\\n  assertThat(responseStatus).isEqualTo(200);\\n});\\n\\n\\\n    /*\\n  For some reason when we mock 'claimRequest', the following error is shown\\\n    \\ when the test is run: 'Request must be claimed before calling runContainer.'\\n\\\n    \\  A workaround is to mock 'runContainer' and simply call its callbacks.\\n*/\\n\\\n    mock('runContainer', (eventData, onCompleteCallback, onStartCallback) => {\\n \\\n    \\ onCompleteCallback();\\n});\\n\\nrunCode(mockData);\\n\\ncallLater(() => {\\n  assertThat(claimRequestWasCalled).isTrue();\\n\\\n    \\  assertApi('returnResponse').wasCalled();\\n});\"\n- name: Client ID retrieval and generation (from _dcid cookie, from Event Data pre-defined\n    keys and from Temporary Client ID)\n  code: \"const originalMockData = mockData;\\n\\nmock('getRequestPath', '/data');\\n\\\n    mock('getRequestMethod', 'POST');\\n\\n[\\n  {\\n    description: 'Should use Client\\\n    \\ ID from Event Model if one is present',\\n    mockData: {\\n      generateClientId:\\\n    \\ true,\\n      acceptMultipleEvents: true\\n    },\\n    mock: () => {\\n      mock('getRequestBody',\\\n    \\ '[{\\\"event\\\":\\\"page_view\\\",\\\"client_id\\\":\\\"client_id\\\",\\\"_dcid_temp\\\":\\\"_dcid_temp\\\"\\\n    },{\\\"event\\\":\\\"view_item\\\",\\\"_dcid\\\":\\\"_dcid\\\",\\\"_dcid_temp\\\":\\\"_dcid_temp\\\"}]');\\n\\\n    \\      mock('getCookieValues', []);\\n    },\\n    assert: (eventData) => {\\n  \\\n    \\    assertThat(eventData.client_id).isEqualTo('client_id'); // The first found\\\n    \\ Client ID is used for all events in the payload.\\n    }\\n  },\\n  {\\n    description:\\\n    \\ 'Should use Client ID from _dcid cookie if present and no Client ID is present\\\n    \\ in Event Model',\\n    mockData: {\\n      generateClientId: true,\\n      acceptMultipleEvents:\\\n    \\ true\\n    }, \\n    mock: () => {\\n      mock('getRequestBody', '[{\\\"event\\\"\\\n    :\\\"page_view\\\",\\\"_dcid_temp\\\":\\\"_dcid_temp\\\"},{\\\"event\\\":\\\"view_item\\\",\\\"_dcid_temp\\\"\\\n    :\\\"_dcid_temp\\\"}]');\\n      mock('getCookieValues', ['_dcid_from_cookie']);\\n\\\n    \\    },\\n    assert: (eventData) => {\\n      assertThat(eventData.client_id).isEqualTo('_dcid_from_cookie');\\n\\\n    \\    }\\n  },\\n  { \\n    description: 'Should use Client ID from temporary Client\\\n    \\ ID if option is enabled, and it is present in Event Model and, _dcid cookie\\\n    \\ or Client ID in Event Data do not exist',\\n    mockData: {\\n      generateClientId:\\\n    \\ true,\\n      acceptMultipleEvents: true\\n    },\\n    mock: () => {\\n      mock('getRequestBody',\\\n    \\ '[{\\\"event\\\":\\\"page_view\\\",\\\"_dcid_temp\\\":\\\"_dcid_temp\\\"},{\\\"event\\\":\\\"view_item\\\"\\\n    ,\\\"_dcid_temp\\\":\\\"_dcid_temp\\\"}]');\\n      mock('getCookieValues', []);\\n    },\\n\\\n    \\    assert: (eventData) => {\\n      assertThat(eventData.client_id).isEqualTo('_dcid_temp');\\n\\\n    \\    }\\n  },\\n  { \\n    description: 'Should generate a random Client ID if option\\\n    \\ is enabled, and _dcid cookie or Client ID in Event Data or temporary Client\\\n    \\ ID do not exist',\\n    mockData: {\\n      generateClientId: true,\\n      acceptMultipleEvents:\\\n    \\ true\\n    },\\n    mock: () => {\\n      mock('getRequestBody', '[{\\\"event\\\":\\\"\\\n    page_view\\\"},{\\\"event\\\":\\\"view_item\\\"}]');\\n      mock('getCookieValues', []);\\n\\\n    \\    },\\n    assert: (eventData) => {\\n      assertThat(eventData.client_id).isEqualTo('dcid.1.1747945830456.123456789');\\n\\\n    \\    }\\n  },\\n  { \\n    description: 'Should NOT generate a random Client ID or\\\n    \\ use temporary Client ID if option is disabled',\\n    mockData: {\\n      generateClientId:\\\n    \\ false,\\n      acceptMultipleEvents: true\\n    },\\n    mock: () => {\\n      mock('getRequestBody',\\\n    \\ '[{\\\"event\\\":\\\"page_view\\\"},{\\\"event\\\":\\\"view_item\\\"}]');\\n      mock('getCookieValues',\\\n    \\ []);\\n    },\\n    assert: (eventData) => {\\n      assertThat(eventData.client_id).isFalsy();\\n\\\n    \\    }\\n  }\\n].forEach(scenario => {\\n  const copyMockData = JSON.parse(JSON.stringify(originalMockData));\\n\\\n    \\  mergeObj(copyMockData, scenario.mockData);\\n  \\n  scenario.mock();\\n  \\n  /*\\\n    \\ \\n    For some reason when we use \\\"assertApi('claimRequest').wasCalled()\\\"\\\n    \\ AND we run all the tests,\\n    it produces the following error \\\"Tried to claim\\\n    \\ a request after a Client had returned. Calling claimRequest from a callback\\\n    \\ is not supported.\\\"\\n    If we run only this single test, the error does not\\\n    \\ occur.\\n    A workaround is to mock 'claimRequest' API and make a dummy assertion\\\n    \\ in the mocked function. This way we make sure it's been called.\\n  */\\n  let\\\n    \\ claimRequestWasCalled;\\n  mock('claimRequest', () => {\\n    claimRequestWasCalled\\\n    \\ = true;\\n  });\\n  \\n  mock('setResponseStatus', (responseStatus) => {\\n    assertThat(responseStatus).isEqualTo(200);\\n\\\n    \\  });\\n  \\n  /*\\n    For some reason when we mock 'claimRequest', the following\\\n    \\ error is shown when the test is run: 'Request must be claimed before calling\\\n    \\ runContainer.'\\n    A workaround is to mock 'runContainer' and simply call its\\\n    \\ callbacks.\\n  */\\n  mock('runContainer', (eventData, onCompleteCallback, onStartCallback)\\\n    \\ => {\\n    assertThat(eventData.hasOwnProperty('_temp_dcid')).isFalse();\\n  \\\n    \\  scenario.assert(eventData);\\n    onCompleteCallback();  \\n  });\\n  \\n  runCode(copyMockData);\\n\\\n    \\  \\n  callLater(() => {\\n    assertThat(claimRequestWasCalled).isTrue();\\n  \\\n    \\  assertApi('returnResponse').wasCalled();\\n  });\\n});\"\n- name: '[Cookie Consent] Consent declined scenarios - setCookie is not called'\n  code: \"mockData.prolongCookies = true;\\nmockData.generateClientId = true;\\nmockData.exposeFPIDCookie\\\n    \\ = true;\\n\\nmock('getRequestPath', '/data');\\nmock('getRequestMethod', 'POST');\\n\\\n    \\nconst cleanup = () => {\\n  mock('getCookieValues', () => []);\\n};\\n\\n[\\n  {\\n\\\n    \\    description: 'auto mode - consent_state analytics_storage declined',\\n  \\\n    \\  dataOverrides: { cookieStorageMode: 'auto', cookieConsentAutoParameter: 'analytics_storage'\\\n    \\ },\\n    body: '{\\\"event\\\":\\\"page_view\\\",\\\"client_id\\\":\\\"cid_123\\\",\\\"consent_state\\\"\\\n    :{\\\"analytics_storage\\\":false}}'\\n  },\\n  {\\n    description: 'manual mode - denied\\\n    \\ value 0 (string)',\\n    dataOverrides: { cookieStorageMode: 'manual', cookieConsentManualValue:\\\n    \\ '0' },\\n    body: '{\\\"event\\\":\\\"page_view\\\",\\\"client_id\\\":\\\"cid_123\\\"}'\\n  },\\n\\\n    \\  {\\n    description: 'manual mode - denied value false (string)',\\n    dataOverrides:\\\n    \\ { cookieStorageMode: 'manual', cookieConsentManualValue: 'false' },\\n    body:\\\n    \\ '{\\\"event\\\":\\\"page_view\\\",\\\"client_id\\\":\\\"cid_123\\\"}'\\n  },\\n  {\\n    description:\\\n    \\ 'manual mode - denied value denied',\\n    dataOverrides: { cookieStorageMode:\\\n    \\ 'manual', cookieConsentManualValue: 'denied' },\\n    body: '{\\\"event\\\":\\\"page_view\\\"\\\n    ,\\\"client_id\\\":\\\"cid_123\\\"}'\\n  }\\n].forEach(scenario => {\\n  cleanup();\\n\\n \\\n    \\ const copyMockData = JSON.parse(JSON.stringify(mockData));\\n  mergeObj(copyMockData,\\\n    \\ scenario.dataOverrides);\\n\\n  mock('getRequestBody', scenario.body);\\n\\n  let\\\n    \\ claimRequestWasCalled;\\n  mock('claimRequest', () => { claimRequestWasCalled\\\n    \\ = true; });\\n  mock('runContainer', (eventData, onCompleteCallback) => { onCompleteCallback();\\\n    \\ });\\n  \\n  runCode(copyMockData);\\n\\n  callLater(() => {\\n    assertThat(claimRequestWasCalled).isTrue();\\n\\\n    \\    assertApi('setCookie').wasNotCalled();\\n    assertApi('returnResponse').wasCalled();\\n\\\n    \\  });\\n});\"\n- name: '[Cookie Consent] Consent granted scenarios - setCookie is called'\n  code: |-\n    mockData.prolongCookies = true;\n    mockData.generateClientId = true;\n    mockData.exposeFPIDCookie = true;\n\n    mock('getRequestPath', '/data');\n    mock('getRequestMethod', 'POST');\n\n    const cleanup = () => {\n      mock('getCookieValues', () => []);\n    };\n\n    [\n      {\n        description: 'no cookieStorageMode - consent not declined',\n        dataOverrides: {},\n        body: '{\"event\":\"page_view\",\"client_id\":\"cid_123\"}'\n      },\n      {\n        description: 'auto mode - consent_state analytics_storage granted',\n        dataOverrides: { cookieStorageMode: 'auto', cookieConsentAutoParameter: 'analytics_storage' },\n        body: '{\"event\":\"page_view\",\"client_id\":\"cid_123\",\"consent_state\":{\"analytics_storage\":true}}'\n      },\n      {\n        description: 'auto mode - no autoConsentParameter - consent not declined',\n        dataOverrides: { cookieStorageMode: 'auto' },\n        body: '{\"event\":\"page_view\",\"client_id\":\"cid_123\",\"consent_state\":{\"analytics_storage\":false}}'\n      },\n      {\n        description: 'manual mode - granted value',\n        dataOverrides: { cookieStorageMode: 'manual', cookieConsentManualValue: 'granted' },\n        body: '{\"event\":\"page_view\",\"client_id\":\"cid_123\"}'\n      }\n    ].forEach(scenario => {\n      cleanup();\n\n      const copyMockData = JSON.parse(JSON.stringify(mockData));\n      mergeObj(copyMockData, scenario.dataOverrides);\n\n      mock('getRequestBody', scenario.body);\n\n      let claimRequestWasCalled;\n      mock('claimRequest', () => { claimRequestWasCalled = true; });\n      mock('runContainer', (eventData, onCompleteCallback) => { onCompleteCallback(); });\n\n      runCode(copyMockData);\n\n      callLater(() => {\n        assertThat(claimRequestWasCalled).isTrue();\n        assertApi('setCookie').wasCalled();\n        assertApi('returnResponse').wasCalled();\n      });\n    });\nsetup: |-\n  const JSON = require('JSON');\n  const Object = require('Object');\n  const callLater = require('callLater');\n\n  function mergeObj(target, source) {\n    for (const key in source) {\n      if (source.hasOwnProperty(key)) target[key] = source[key];\n    }\n    return target;\n  }\n\n  const mockData = {\n    responseStatusCode: 200,\n    generateClientId: true,\n    responseBody: 'timestamp',\n    prolongCookies: true,\n    httpOnlyCookie: false,\n    responseBodyGet: false,\n    acceptMultipleEvents: false,\n    exposeFPIDCookie: false\n  };\n\n  mock('getRequestHeader', (header) => {\n    if (header === 'trace-id') return 'expectedTraceId';\n  });\n\n  mock('getTimestampMillis', 1747945830456);\n\n  mock('generateRandom', 123456789);\n\n\n___NOTES___\n\n2026-05-22 - Change Notes:\n  - Add cookie consent gating: new \"Cookie Consent Settings\" parameter group lets users skip all setCookie calls when consent is denied, using either auto-detection (via Data Tag's consent_state) or a manual GTM variable\n  - Refactor property fallback chains from if/else to || short-circuit for cleaner code; behavior is unchanged\n  - Fix broken test mock: mock('requestMethod') corrected to mock('getRequestMethod') across existing test scenarios\n\nCreated on 21/03/2021, 11:24:30\n\n\n"
            },
            {
                "accountId": "6365534927",
                "containerId": "258048563",
                "templateId": "17",
                "name": "city_meta - X-GEO-City",
                "fingerprint": "1783780016237",
                "templateData": "___INFO___\n\n{\n  \"type\": \"MACRO\",\n  \"id\": \"cvt_temp_public_id\",\n  \"version\": 1,\n  \"securityGroups\": [],\n  \"displayName\": \"city_meta - X-GEO-City\",\n  \"description\": \"Transforma o valor do X-GEO-City no padrão exigido pela Meta.\\n\\nCódigo desenvolvido por um aluno do Treinamento Traqueamento Avançado - @gustavobork.\",\n  \"containerContexts\": [\n    \"SERVER\"\n  ]\n}\n\n\n___TEMPLATE_PARAMETERS___\n\n[]\n\n\n___SANDBOXED_JS_FOR_SERVER___\n\nconst getRequestHeader = require('getRequestHeader');\nconst logToConsole = require('logToConsole');\n\nlet cityName = getRequestHeader('X-Geo-City');\nlogToConsole(\"Original cityName: \" + cityName); // Log before replacement\n\nif (cityName) {\n    let result = '';\n    for (let i = 0; i < cityName.length; i++) {\n        const current = cityName.charAt(i);\n        const next = i + 1 < cityName.length ? cityName.charAt(i + 1) : '';\n        const pair = current + next;\n\n        if (pair === 'Ã£' || pair === 'Ã¡' || pair === 'Ã ' || pair === 'Ã¢') {\n            result += 'a';\n            i++; // Skip next character\n        } else if (pair === 'Ã©' || pair === 'Ãª') {\n            result += 'e';\n            i++; // Skip next character\n        } else if (pair === 'Ã­') {\n            result += 'i';\n            i++; // Skip next character\n        } else if (pair === 'Ã³' || pair === 'Ã´' || pair === 'Ãµ') {\n            result += 'o';\n            i++; // Skip next character\n        } else if (pair === 'Ãº' || pair === 'Ã¼') {\n            result += 'u';\n            i++; // Skip next character\n        } else if (pair === 'Ã§') {\n            result += 'c';\n            i++; // Skip next character\n        } else if (current !== ' ') { // Check if the current character is not a space\n            result += current;\n        }\n        // If it is a space, do nothing (effectively removing it)\n    }\n\n    cityName = result.toLowerCase(); // Lowercase result\n    logToConsole(\"Processed cityName: \" + cityName); // Log after replacement\n    return cityName;\n}\n\ndata.gtmOnSuccess(); // In GTM, end with this call\n\n//Código desenvolvido por um aluno do Treinamento Traqueamento Avançado - @gustavobork.\n\n\n___SERVER_PERMISSIONS___\n\n[\n  {\n    \"instance\": {\n      \"key\": {\n        \"publicId\": \"read_request\",\n        \"versionId\": \"1\"\n      },\n      \"param\": [\n        {\n          \"key\": \"requestAccess\",\n          \"value\": {\n            \"type\": 1,\n            \"string\": \"any\"\n          }\n        },\n        {\n          \"key\": \"headerAccess\",\n          \"value\": {\n            \"type\": 1,\n            \"string\": \"any\"\n          }\n        },\n        {\n          \"key\": \"queryParameterAccess\",\n          \"value\": {\n            \"type\": 1,\n            \"string\": \"any\"\n          }\n        }\n      ]\n    },\n    \"clientAnnotations\": {\n      \"isEditedByUser\": true\n    },\n    \"isRequired\": true\n  },\n  {\n    \"instance\": {\n      \"key\": {\n        \"publicId\": \"logging\",\n        \"versionId\": \"1\"\n      },\n      \"param\": [\n        {\n          \"key\": \"environments\",\n          \"value\": {\n            \"type\": 1,\n            \"string\": \"all\"\n          }\n        }\n      ]\n    },\n    \"clientAnnotations\": {\n      \"isEditedByUser\": true\n    },\n    \"isRequired\": true\n  }\n]\n\n\n___TESTS___\n\nscenarios: []\n\n\n___NOTES___\n\nCreated on 6/29/2024, 3:17:49 PM\n\n\n"
            }
        ],
        "client": [
            {
                "accountId": "6365534927",
                "containerId": "258048563",
                "clientId": "16",
                "name": "Data Client",
                "type": "cvt_258048563_15",
                "parameter": [
                    {
                        "type": "INTEGER",
                        "key": "responseStatusCode",
                        "value": "200"
                    },
                    {
                        "type": "BOOLEAN",
                        "key": "generateClientId",
                        "value": "true"
                    },
                    {
                        "type": "TEMPLATE",
                        "key": "responseBody",
                        "value": "timestamp"
                    },
                    {
                        "type": "BOOLEAN",
                        "key": "prolongCookies",
                        "value": "true"
                    },
                    {
                        "type": "BOOLEAN",
                        "key": "httpOnlyCookie",
                        "value": "false"
                    },
                    {
                        "type": "BOOLEAN",
                        "key": "responseBodyGet",
                        "value": "false"
                    },
                    {
                        "type": "BOOLEAN",
                        "key": "acceptMultipleEvents",
                        "value": "false"
                    },
                    {
                        "type": "BOOLEAN",
                        "key": "exposeFPIDCookie",
                        "value": "false"
                    }
                ],
                "fingerprint": "1783780016237"
            }
        ]
    }
}