PageSourceSearch

https://www.crn.com/plugins/experimentation/src/ued.js

js crn.com collected 2026-09-24 06:49:11 UTC 7,238 bytes, 192 lines download raw bytes

1/*
2 * Copyright 2022 Adobe. All rights reserved.
3 * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License. You may obtain a copy
5 * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 *
7 * Unless required by applicable law or agreed to in writing, software distributed under
8 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 * OF ANY KIND, either express or implied. See the License for the specific language
10 * governing permissions and limitations under the License.
11 */
12
13var storage = window.sessionStorage;
14
15function murmurhash3_32_gc(key, seed) {
16  var remainder = key.length & 3;
17  var bytes = key.length - remainder;
18  var c1 = 0xcc9e2d51;
19  var c2 = 0x1b873593;
20  var h1 = seed;
21  var k1;
22  var h1b;
23  var i = 0;
24  while (i < bytes) {
25      k1 =
26          ((key.charCodeAt(i) & 0xff)) |
27              ((key.charCodeAt(++i) & 0xff) << 8) |
28              ((key.charCodeAt(++i) & 0xff) << 16) |
29              ((key.charCodeAt(++i) & 0xff) << 24);
30      ++i;
31      k1 = ((((k1 & 0xffff) * c1) + ((((k1 >>> 16) * c1) & 0xffff) << 16))) & 0xffffffff;
32      k1 = (k1 << 15) | (k1 >>> 17);
33      k1 = ((((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16))) & 0xffffffff;
34      h1 ^= k1;
35      h1 = (h1 << 13) | (h1 >>> 19);
36      h1b = ((((h1 & 0xffff) * 5) + ((((h1 >>> 16) * 5) & 0xffff) << 16))) & 0xffffffff;
37      h1 = (((h1b & 0xffff) + 0x6b64) + ((((h1b >>> 16) + 0xe654) & 0xffff) << 16));
38  }
39  k1 = 0;
40  switch (remainder) {
41      case 3: k1 ^= (key.charCodeAt(i + 2) & 0xff) << 16;
42      case 2: k1 ^= (key.charCodeAt(i + 1) & 0xff) << 8;
43      case 1:
44          k1 ^= (key.charCodeAt(i) & 0xff);
45          k1 = (((k1 & 0xffff) * c1) + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;
46          k1 = (k1 << 15) | (k1 >>> 17);
47          k1 = (((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;
48          h1 ^= k1;
49  }
50  h1 ^= key.length;
51  h1 ^= h1 >>> 16;
52  h1 = (((h1 & 0xffff) * 0x85ebca6b) + ((((h1 >>> 16) * 0x85ebca6b) & 0xffff) << 16)) & 0xffffffff;
53  h1 ^= h1 >>> 13;
54  h1 = ((((h1 & 0xffff) * 0xc2b2ae35) + ((((h1 >>> 16) * 0xc2b2ae35) & 0xffff) << 16))) & 0xffffffff;
55  h1 ^= h1 >>> 16;
56  return h1 >>> 0;
57}
58
59var TOTAL_BUCKETS = 10000;
60function getBucket(saltedId) {
61  var hash = murmurhash3_32_gc(saltedId, 0);
62  var hashFixedBucket = Math.abs(hash) % TOTAL_BUCKETS;
63  var bucket = hashFixedBucket / TOTAL_BUCKETS;
64  return bucket;
65}
66function pickWithWeightsBucket(allocationPercentages, treatments, bucket) {
67  var sum = allocationPercentages.reduce(function (partialSum, a) { return partialSum + a; }, 0);
68  var partialSum = 0.0;
69  for (var i = 0; i < treatments.length; i++) {
70      partialSum += Number(allocationPercentages[i].toFixed(2)) / sum;
71      if (bucket > partialSum) {
72          continue;
73      }
74      return treatments[i];
75  }
76}
77function assignTreatmentByVisitor(experimentid, identityId, allocationPercentages, treatments) {
78  var saltedId = experimentid + '.' + identityId;
79  var bucketId = getBucket(saltedId);
80  var treatmentId = pickWithWeightsBucket(allocationPercentages, treatments, bucketId);
81  return {
82      treatmentId: treatmentId,
83      bucketId: bucketId
84  };
85}
86
87var LOCAL_STORAGE_KEY = 'unified-decisioning-experiments';
88function assignTreatment(allocationPercentages, treatments) {
89  var random = Math.random() * 100;
90  var i = treatments.length;
91  while (random > 0 && i > 0) {
92      i -= 1;
93      random -= +allocationPercentages[i];
94  }
95  return treatments[i];
96}
97function getLastExperimentTreatment(experimentId) {
98  var experimentsStr = storage.getItem(LOCAL_STORAGE_KEY);
99  if (experimentsStr) {
100      var experiments = JSON.parse(experimentsStr);
101      if (experiments[experimentId]) {
102          return experiments[experimentId].treatment;
103      }
104  }
105  return null;
106}
107function setLastExperimentTreatment(experimentId, treatment) {
108  var experimentsStr = storage.getItem(LOCAL_STORAGE_KEY);
109  var experiments = experimentsStr ? JSON.parse(experimentsStr) : {};
110  var now = new Date();
111  var expKeys = Object.keys(experiments);
112  expKeys.forEach(function (key) {
113      var date = new Date(experiments[key].date);
114      if ((now.getTime() - date.getTime()) > (1000 * 86400 * 30)) {
115          delete experiments[key];
116      }
117  });
118  var date = now.toISOString().split('T')[0];
119  experiments[experimentId] = { treatment: treatment, date: date };
120  storage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(experiments));
121}
122function assignTreatmentByDevice(experimentId, allocationPercentages, treatments) {
123  var cachedTreatmentId = getLastExperimentTreatment(experimentId);
124  var treatmentIdResponse;
125  if (!cachedTreatmentId || !treatments.includes(cachedTreatmentId)) {
126      var assignedTreatmentId = assignTreatment(allocationPercentages, treatments);
127      setLastExperimentTreatment(experimentId, assignedTreatmentId);
128      treatmentIdResponse = assignedTreatmentId;
129  }
130  else {
131      treatmentIdResponse = cachedTreatmentId;
132  }
133  return {
134      treatmentId: treatmentIdResponse
135  };
136}
137
138var RandomizationUnit = {
139  VISITOR: 'VISITOR',
140  DEVICE: 'DEVICE'
141};
142function evaluateExperiment(context, experiment) {
143  var experimentId = experiment.id, identityNamespace = experiment.identityNamespace, _a = experiment.randomizationUnit, randomizationUnit = _a === void 0 ? RandomizationUnit.VISITOR : _a;
144  var identityMap = context.identityMap;
145  var treatments = experiment.treatments.map(function (item) { return item.id; });
146  var allocationPercentages = experiment.treatments.map(function (item) { return item.allocationPercentage; });
147  var treatmentAssignment = null;
148  switch (randomizationUnit) {
149      case RandomizationUnit.VISITOR: {
150          var identityId = identityMap[identityNamespace][0].id;
151          treatmentAssignment = assignTreatmentByVisitor(experimentId, identityId, allocationPercentages, treatments);
152          break;
153      }
154      case RandomizationUnit.DEVICE: {
155          treatmentAssignment = assignTreatmentByDevice(experimentId, allocationPercentages, treatments);
156          break;
157      }
158      default:
159          throw new Error("Unknow randomization unit");
160  }
161  var evaluationResponse = {
162      experimentId: experimentId,
163      hashedBucket: treatmentAssignment.bucketId,
164      treatment: {
165          id: treatmentAssignment.treatmentId
166      }
167  };
168  return evaluationResponse;
169}
170
171function traverseDecisionTree(decisionNodesMap, context, currentNodeId) {
172  var _a = decisionNodesMap[currentNodeId], experiment = _a.experiment, type = _a.type;
173  if (type === 'EXPERIMENTATION') {
174      var treatment = evaluateExperiment(context, experiment).treatment;
175      return [treatment];
176  }
177}
178function evaluateDecisionPolicy(decisionPolicy, context) {
179  if (context.storage && context.storage instanceof Storage) {
180    storage = context.storage;
181  }
182  var decisionNodesMap = {};
183  decisionPolicy.decisionNodes.forEach(function (item) {
184      decisionNodesMap[item['id']] = item;
185  });
186  var items = traverseDecisionTree(decisionNodesMap, context, decisionPolicy.rootDecisionNodeId);
187  return {
188      items: items
189  };
190}
191
192export const ued = { evaluateDecisionPolicy };

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.