diff --git a/.circleci/config.yml b/.circleci/config.yml index a5b953b01..181e091bf 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -7,15 +7,18 @@ version: 2.1 # Orbs are reusable packages of CircleCI configuration that you may share across projects, enabling you to create encapsulated, parameterized commands, jobs, and executors that can be used across multiple projects. # See: https://circleci.com/docs/2.0/orb-intro/ orbs: - android: circleci/android@1.0.3 + android: circleci/android@2.5.0 # Define a job to be invoked later in a workflow. # See: https://circleci.com/docs/2.0/configuration-reference/#jobs jobs: android-test: executor: name: android/android-machine + tag: default steps: - checkout + - android/change-java-version: + java-version: 17 - android/start-emulator-and-run-tests: post-emulator-launch-assemble-command: ./gradlew PrebidDemoKotlin:assembleAndroidTest test-command: ./gradlew PrebidDemoKotlin:connectedDebugAndroidTest @@ -29,12 +32,14 @@ jobs: type: string executor: name: android/android-machine - + tag: default # Add steps to the job # See: https://circleci.com/docs/2.0/configuration-reference/#steps steps: # Checkout the code as the first step. - checkout + - android/change-java-version: + java-version: 17 - run: command: << parameters.buildCommand >> @@ -44,11 +49,14 @@ jobs: # See: https://circleci.com/docs/2.0/executor-types/ executor: name: android/android-machine + tag: default # Add steps to the job # See: https://circleci.com/docs/2.0/configuration-reference/#steps steps: # Checkout the code as the first step. - checkout + - android/change-java-version: + java-version: 17 # And finally run the release build - run: name: Test Frameworks diff --git a/Example/PrebidDemoJava/build.gradle b/Example/PrebidDemoJava/build.gradle index 39f11d41b..6fb89e537 100644 --- a/Example/PrebidDemoJava/build.gradle +++ b/Example/PrebidDemoJava/build.gradle @@ -1,11 +1,12 @@ apply plugin: 'com.android.application' android { - setCompileSdkVersion(33) + namespace "org.prebid.mobile.javademo" + setCompileSdkVersion(34) setBuildToolsVersion("30.0.3") defaultConfig { - minSdkVersion 19 - targetSdkVersion 33 + minSdkVersion 21 + targetSdkVersion 34 versionCode 1 versionName "1.0.0" applicationId "org.prebid.mobile.javademo" @@ -14,8 +15,8 @@ android { } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 } buildFeatures { dataBinding true diff --git a/Example/PrebidDemoJava/src/main/AndroidManifest.xml b/Example/PrebidDemoJava/src/main/AndroidManifest.xml index e28083b3a..5df78da6a 100644 --- a/Example/PrebidDemoJava/src/main/AndroidManifest.xml +++ b/Example/PrebidDemoJava/src/main/AndroidManifest.xml @@ -1,6 +1,5 @@ - + diff --git a/Example/PrebidDemoKotlin/build.gradle b/Example/PrebidDemoKotlin/build.gradle index cc6b31cc1..fc4c45af0 100644 --- a/Example/PrebidDemoKotlin/build.gradle +++ b/Example/PrebidDemoKotlin/build.gradle @@ -2,11 +2,12 @@ apply plugin: 'com.android.application' apply plugin: 'kotlin-android' android { - setCompileSdkVersion(33) + namespace "org.prebid.mobile.prebidkotlindemo" + setCompileSdkVersion(34) setBuildToolsVersion("30.0.3") defaultConfig { - minSdkVersion 19 - targetSdkVersion 33 + minSdkVersion 21 + targetSdkVersion 34 versionCode 1 versionName "1.0.0" applicationId "org.prebid.mobile.prebidkotlindemo" @@ -14,8 +15,8 @@ android { multiDexEnabled true } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 } buildFeatures { dataBinding true diff --git a/Example/PrebidDemoKotlin/src/main/AndroidManifest.xml b/Example/PrebidDemoKotlin/src/main/AndroidManifest.xml index 0e1f74257..1b861ea37 100644 --- a/Example/PrebidDemoKotlin/src/main/AndroidManifest.xml +++ b/Example/PrebidDemoKotlin/src/main/AndroidManifest.xml @@ -1,6 +1,5 @@ - + diff --git a/Example/PrebidInternalTestApp/build.gradle b/Example/PrebidInternalTestApp/build.gradle index e59fcb314..fb8077b55 100644 --- a/Example/PrebidInternalTestApp/build.gradle +++ b/Example/PrebidInternalTestApp/build.gradle @@ -19,11 +19,12 @@ apply plugin: 'kotlin-android' apply plugin: 'kotlin-kapt' android { - setCompileSdkVersion(33) + namespace "org.prebid.mobile.renderingtestapp" + setCompileSdkVersion(34) setBuildToolsVersion("30.0.3") defaultConfig { - minSdkVersion 19 - targetSdkVersion 33 + minSdkVersion 21 + targetSdkVersion 34 versionCode 1 versionName "1.0.0" applicationId "org.prebid.mobile.renderingtestapp" @@ -40,11 +41,11 @@ android { exclude 'LICENSE.txt' } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = JavaVersion.VERSION_1_8.toString() + jvmTarget = JavaVersion.VERSION_17.toString() } adbOptions { timeOutInMs 5 * 60 * 1000 // 5 minutes diff --git a/Example/PrebidInternalTestApp/src/main/AndroidManifest.xml b/Example/PrebidInternalTestApp/src/main/AndroidManifest.xml index 655c95953..a39d0fa4f 100755 --- a/Example/PrebidInternalTestApp/src/main/AndroidManifest.xml +++ b/Example/PrebidInternalTestApp/src/main/AndroidManifest.xml @@ -16,8 +16,7 @@ --> + xmlns:tools="http://schemas.android.com/tools"> diff --git a/Example/PrebidInternalTestApp/src/main/java/org/prebid/mobile/renderingtestapp/plugplay/utilities/consent/ConsentSettingsFragment.kt b/Example/PrebidInternalTestApp/src/main/java/org/prebid/mobile/renderingtestapp/plugplay/utilities/consent/ConsentSettingsFragment.kt index 2fa68cefb..430a94fa9 100644 --- a/Example/PrebidInternalTestApp/src/main/java/org/prebid/mobile/renderingtestapp/plugplay/utilities/consent/ConsentSettingsFragment.kt +++ b/Example/PrebidInternalTestApp/src/main/java/org/prebid/mobile/renderingtestapp/plugplay/utilities/consent/ConsentSettingsFragment.kt @@ -32,9 +32,9 @@ class ConsentSettingsFragment : PreferenceFragmentCompat(), SharedPreferences.On getDefaultSharedPreference()?.registerOnSharedPreferenceChangeListener(this) } - override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String) { + override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) { - when (val preference = findPreference(key)) { + when (val preference = key?.let { findPreference(it) }) { is IntegerEditTextPreferenceWithValue -> preference.summary = sharedPreferences?.getInt(key, -1).toString() is EditTextPreferenceWithValue -> diff --git a/PrebidMobile/PrebidMobile-admobAdapters/build.gradle b/PrebidMobile/PrebidMobile-admobAdapters/build.gradle index 0b9286692..dfe54eabc 100644 --- a/PrebidMobile/PrebidMobile-admobAdapters/build.gradle +++ b/PrebidMobile/PrebidMobile-admobAdapters/build.gradle @@ -3,8 +3,15 @@ apply from: '../publisher.gradle' apply from: '../tests.gradle' android { + namespace "org.prebid.mobile.admob.adapters" defaultConfig { - minSdkVersion 19 + minSdkVersion 21 + } + testOptions { + unitTests.all { + jvmArgs '--add-opens=java.base/java.lang=ALL-UNNAMED' + systemProperty 'robolectric.invokedynamic.enable', 'false' + } } } diff --git a/PrebidMobile/PrebidMobile-admobAdapters/src/main/AndroidManifest.xml b/PrebidMobile/PrebidMobile-admobAdapters/src/main/AndroidManifest.xml index 1b8d102bc..9b65eb06c 100644 --- a/PrebidMobile/PrebidMobile-admobAdapters/src/main/AndroidManifest.xml +++ b/PrebidMobile/PrebidMobile-admobAdapters/src/main/AndroidManifest.xml @@ -1 +1 @@ - + diff --git a/PrebidMobile/PrebidMobile-core/PBMJSLibraries/mraid.js b/PrebidMobile/PrebidMobile-core/PBMJSLibraries/mraid.js new file mode 100644 index 000000000..9dd1b7624 --- /dev/null +++ b/PrebidMobile/PrebidMobile-core/PBMJSLibraries/mraid.js @@ -0,0 +1,545 @@ +var printDebug = function(messageBuilder) {}; + +(function() { + + const LOG_TO_CONSOLE_ENABLE = false; + const TAG = "PREBID_MRAID_JS"; + + var mraid = window.mraid = {}; + mraid.eventListeners = {}; + mraid.state = "loading"; + mraid.viewable = false; + mraid.resizePropertiesInitialized = false; + mraid.volumePercentage = null; + + var nativeCallQueue = []; + var nativeCallInFlight = false; + + mraid.currentPosition = { + x: 0, + y: 0, + width: 0, + height: 0 + }; + + mraid.maxSize = { + width: 0, + height: 0 + }; + + mraid.defaultPosition = { + x: 0, + y: 0, + width: 0, + height: 0 + }; + + mraid.screenSize = { + width: 0, + height: 0 + }; + + mraid.allSupports = { + sms: false, + tel: false, + calendar: false, + storePicture: false, + inlineVideo: false, + vpaid: false + }; + + if (LOG_TO_CONSOLE_ENABLE) { + printDebug = function(messageBuilder) { + var message = messageBuilder(); + console.log(TAG + ': ' + message); + } + } + + mraid.setCurrentPosition = function(x, y, width, height) { + + printDebug(() => 'setCurrentPosition'); + + mraid.currentPosition.x = x; + mraid.currentPosition.y = y; + mraid.currentPosition.width = width; + mraid.currentPosition.height = height; + + }; + + mraid.setMaxSize = function(width, height) { + + printDebug(() => 'setMaxSize'); + + mraid.maxSize.width = width; + mraid.maxSize.height = height; + + }; + + mraid.setDefaultPosition = function(x, y, width, height) { + + printDebug(() => 'setDefaultPosition'); + + mraid.defaultPosition.x = x; + mraid.defaultPosition.y = y; + mraid.defaultPosition.width = width; + mraid.defaultPosition.height = height; + + }; + + mraid.setScreenSize = function(width, height) { + + printDebug(() => 'setScreenSize'); + + mraid.screenSize.width = width; + mraid.screenSize.height = height; + + }; + + mraid.orientationProperties = { + allowOrientationChange: true, + forceOrientation: "none" + }; + + mraid.expandProperties = { + width: 0, + height: 0, + useCustomClose: false + }; + + mraid.resizeProperties = { + width: 0, + height: 0, + customClosePosition: "top-right", + offsetX: 0, + offsetY: 0, + allowOffscreen: true + }; + + mraid.lastExposure = { + exposedPercentage: 100.0, + visibleRectangle: { + x: 0.0, + y: 0.0, + width: 0.0, + height: 0.0 + }, + occlusionRectangles: null + }; + + var safeString = function(str) { + + printDebug(() => 'safeString' + str); + return str ? str : ''; + }; + + + var callContainer = function(command) { + printDebug(() => 'callContainer ' + command); + var args = Array.prototype.slice.call(arguments); + args.shift(); + + if (nativeCallInFlight) { + var nextCommand = { + "command" : command, + "args" : args + }; + printDebug(() => 'callContainer nextCommand in queue ' + nextCommand); + nativeCallQueue.push(nextCommand); + } else { + nativeCallInFlight = true; + printDebug(() => 'callContainer executing immediately.'); + jsBridge[command].apply(jsBridge, args); + } + }; + + mraid.open = function(url) { + printDebug(() => 'open(' + url + ')'); + + callContainer('open', url); + }; + + + mraid.resize = function() { + printDebug(() => 'resize'); + if(mraid.resizePropertiesInitialized) { + + callContainer('resize'); + + } else { + + mraid.onError("[width] and [height] parameters must be at least 1px. Set them using setResizeProperties() MRAID method.", "resize"); + } + }; + + mraid.expand = function(url) { + printDebug(() => 'mraid.expand(' + url + ')'); + + if(url) { + callContainer('expand', url); + } else { + callContainer('expand'); + } + }; + + + mraid.close = function() { + printDebug(() => 'close'); + callContainer('close'); + }; + + + mraid.getPlacementType = function() { + printDebug(() => 'getPlacementType'); + return jsBridge.getPlacementType(); + }; + + + mraid.getState = function() { + printDebug(() => 'getState ' + mraid.state); + return mraid.state; + }; + + + mraid.getVersion = function() { + printDebug(() => 'getVersion'); + return '3.0'; + }; + + + mraid.isViewable = function() { + + printDebug(() => 'isViewable ' + mraid.viewable); + return mraid.viewable; + }; + + + mraid.getScreenSize = function() { + printDebug(() => 'getScreenSize'); + return JSON.parse(jsBridge.getScreenSize()); + }; + + + mraid.getDefaultPosition = function() { + printDebug(() => 'getDefaultPosition'); + return JSON.parse(jsBridge.getDefaultPosition()); + }; + + + mraid.getCurrentPosition = function() { + printDebug(() => 'getCurrentPosition'); + return JSON.parse(jsBridge.getCurrentPosition()); + }; + + + mraid.getMaxSize = function() { + printDebug(() => 'getMaxSize'); + return JSON.parse(jsBridge.getMaxSize()); + }; + + + mraid.supports = function(feature) { + printDebug(() => 'supports: ' + feature); + printDebug(() => 'supports:regular call: ' + mraid.allSupports[feature]); + return mraid.allSupports[feature]; + }; + + + mraid.playVideo = function(url) { + printDebug(() => 'playVideo'); + callContainer('playVideo', url); + }; + + + mraid.addEventListener = function(event, listener) { + printDebug(() => 'addEventListener: ' + event); + var handlers = mraid.eventListeners[event]; + if(handlers == null) { + handlers = mraid.eventListeners[event] = []; + } + + + for(var handler = 0; handler < handlers.length; handler++) { + if(listener == handlers[handler]) { + return; + } + } + + + handlers.push(listener); + }; + + + mraid.removeEventListener = function(event, listener) { + printDebug(() => 'removeEventListener: ' + event); + var handlers = mraid.eventListeners[event]; + if(handlers != null) { + for(var handler = 0; handler < handlers.length; handler++) { + if(handlers[handler] == listener) { + handlers.splice(handler, 1); + break; + } + } + } + }; + + + mraid.setOrientationProperties = function(properties) { + printDebug(() => 'setOrientationProperties'); + if(!properties) + return; + var aoc = properties.allowOrientationChange; + if(aoc === true || aoc === false) { + mraid.orientationProperties.allowOrientationChange = aoc; + } + + var fo = properties.forceOrientation; + if(fo == 'landscape' || fo == 'portrait' || fo == 'none') { + mraid.orientationProperties.forceOrientation = fo; + } + + callContainer('onOrientationPropertiesChanged', JSON.stringify(mraid.getOrientationProperties())); + }; + + + mraid.getOrientationProperties = function() { + printDebug(() => 'getOrientationProperties'); + return mraid.orientationProperties; + }; + + + mraid.getResizeProperties = function() { + printDebug(() => 'getResizeProperties'); + return mraid.resizeProperties; + }; + + + mraid.getExpandProperties = function() { + printDebug(() => 'getExpandProperties'); + mraid.expandProperties.isModal = true; + return mraid.expandProperties; + }; + + + mraid.setResizeProperties = function(properties) { + printDebug(() => 'setResizeProperties '); + mraid.resizePropertiesInitialized = false; + + if (!properties) { + mraid.onError("properties is null", "setResizeProperties"); + return; + } + + //Allow Offscreen + if (typeof(properties.allowOffscreen) !== "boolean") { + mraid.onError("allowOffscreen param of [" + properties.allowOffscreen + "] is unusable.", "setResizeProperties"); + return; + } + + var allowOffscreen = properties.allowOffscreen + + //Get max size + var maxSize = mraid.getMaxSize(); + if (!maxSize || !maxSize.width || !maxSize.height) { + mraid.onError("Unable to use maxSize of [" + JSON.stringify(maxSize) + "]", "setResizeProperties"); + return; + } + + //Width + if (properties.width == null || typeof properties.width === 'undefined' || isNaN(properties.width)) { + mraid.onError("width param of [" + properties.width + "] is unusable.", "setResizeProperties"); + return; + } + + if (properties.width < 50 || (properties.width > maxSize.width && !allowOffscreen)) { + mraid.onError("width param of [" + properties.width + "] outside of acceptable range of 50 to " + maxSize.width, "setResizeProperties"); + return; + } + + //Height + if (properties.height == null || typeof properties.height === 'undefined' || isNaN(properties.height)) { + mraid.onError("height param of [" + properties.height + "] is unusable.", "setResizeProperties"); + return; + } + + if (properties.height < 50 || (properties.height > maxSize.height && !allowOffscreen)) { + mraid.onError("height param of [" + properties.height + "] outside of acceptable range of 50 to " + maxSize.height, "setResizeProperties"); + return; + } + + //Offset + if (properties.offsetX == null || typeof properties.offsetX === 'undefined' || isNaN(properties.offsetX)) { + mraid.onError("offsetX param of [" + properties.offsetX + "] is unusable.", "setResizeProperties"); + return; + } + + if (properties.offsetY == null || typeof properties.offsetY === 'undefined' || isNaN(properties.offsetY)) { + mraid.onError("offsetY param of [" + properties.offsetY + "] is unusable.", "setResizeProperties"); + return; + } + + + mraid.resizeProperties.width = properties.width; + mraid.resizeProperties.height = properties.height; + mraid.resizeProperties.customClosePosition = properties.customClosePosition; + mraid.resizeProperties.offsetX = properties.offsetX; + mraid.resizeProperties.offsetY = properties.offsetY; + mraid.resizeProperties.allowOffscreen = properties.allowOffscreen; + + mraid.resizePropertiesInitialized = true; + }; + + + mraid.setExpandProperties = function(properties) { + + printDebug(() => 'setExpandProperties'); + + if(properties && properties.width != null && typeof properties.width !== 'undefined' && !isNaN(properties.width)) { + mraid.expandProperties.width = properties.width; + } + + if(properties && properties.height != null && typeof properties.height !== 'undefined' && !isNaN(properties.height)) { + mraid.expandProperties.height = properties.height; + } + }; + + mraid.useCustomClose = function(useCustomClose) { + printDebug(() => 'DEPRECATED useCustomClose' + useCustomClose); + if(useCustomClose == true || useCustomClose == false) { + mraid.expandProperties.useCustomClose = useCustomClose; + //also call container's + callContainer('shouldUseCustomClose', useCustomClose); + } + }; + + + mraid.fireEvent = function(event, args) { + printDebug(() => 'fireEvent ' + event); + var handlers = mraid.eventListeners[event]; + if(handlers == null) { + return; + } + + + for(var handler = 0; handler < handlers.length; handler++) { + if(event == 'ready') { + handlers[handler](); + } else if(event == 'error') { + handlers[handler](args[0], args[1]); + } else if(event == 'stateChange') { + handlers[handler](args); + } else if(event == 'viewableChange') { + handlers[handler](args); + } else if(event == 'sizeChange') { + handlers[handler](args[0], args[1]); + } else if(event == 'audioVolumeChange') { + handlers[handler](args); + } else if(event == 'exposureChange') { + handlers[handler](mraid.lastExposure.exposedPercentage, + mraid.lastExposure.visibleRectangle, + mraid.lastExposure.occlusionRectangles); + } + } + }; + + + mraid.createCalendarEvent = function(parameters) { + printDebug(() => 'createCalendarEvent'); + callContainer('createCalendarEvent', JSON.stringify(parameters)); + }; + + + mraid.storePicture = function(url) { + printDebug(() => 'storePicture'); + callContainer('storePicture', url); + }; + + mraid.onError = function(message, action) { + printDebug(() => 'onError' + message); + mraid.fireEvent("error", [message, action]); + }; + + + mraid.onReady = function() { + printDebug(() => 'ready'); + + mraid.fireEvent("ready"); + }; + + mraid.onReadyExpanded = function() { + printDebug(() => 'onReadyExpanded'); + mraid.fireEvent("ready"); + }; + + mraid.onSizeChange = function(width, height) { + printDebug(() => 'onSizeChange: width ' + width + 'height: ' + height); + mraid.fireEvent("sizeChange", [width, height]); + }; + + + mraid.onStateChange = function(state) { + printDebug(() => 'onStateChange' + state); + mraid.state = state; + mraid.fireEvent("stateChange", mraid.getState()); + }; + + + /** + * @deprecated Since MRAID 3. Use onExposureChange instead. + */ + mraid.onViewableChange = function(isViewable) { + printDebug(() => 'onViewableChange'); + + mraid.viewable = isViewable; + mraid.fireEvent("viewableChange", mraid.isViewable()); + }; + + mraid.getLocation = function() { + printDebug(() => 'getLocation'); + return JSON.parse(jsBridge.getLocation()); + }; + + mraid.getCurrentAppOrientation = function() { + printDebug(() => 'getCurrentAppOrientation'); + return JSON.parse(jsBridge.getCurrentAppOrientation()); + }; + + mraid.unload = function() { + printDebug(() => 'unload'); + callContainer('unload'); + }; + + mraid.onExposureChange = function(viewExposureString) { + printDebug(() => 'onExposureChange ' + viewExposureString); + var viewExposure = JSON.parse(viewExposureString); + mraid.lastExposure = viewExposure; + mraid.fireEvent("exposureChange"); + }; + + /* + This event fires on changing of the audio volume. + See https://www.iab.com/wp-content/uploads/2017/07/MRAID_3.0_FINAL.pdf , par. 7.6 + + @volumePercentage - percentage of maximum audio playback + volume, a floating-point number between 0.0 and 100.0, or 0.0 + if playback is not allowed, or null if volume can’t be + determined + */ + mraid.onAudioVolumeChange = function(newVolumePercentage) { + printDebug(() => 'onAudioVolumeChange(' + newVolumePercentage + ')'); + mraid.volumePercentage = newVolumePercentage; + mraid.fireEvent("audioVolumeChange", newVolumePercentage); + }; + + mraid.nativeCallComplete = function() { + if (nativeCallQueue.length === 0) { + nativeCallInFlight = false; + return; + } + + var nextCall = nativeCallQueue.shift(); + printDebug(() => 'nativeCallComplete nextCall: ' + nextCall.command + " arg " + nextCall.args); + + jsBridge[nextCall.command].apply(jsBridge, nextCall.args); + }; + +}()); \ No newline at end of file diff --git a/PrebidMobile/PrebidMobile-core/PBMJSLibraries/omsdk.js b/PrebidMobile/PrebidMobile-core/PBMJSLibraries/omsdk.js new file mode 100644 index 000000000..c0f6ac9a1 --- /dev/null +++ b/PrebidMobile/PrebidMobile-core/PBMJSLibraries/omsdk.js @@ -0,0 +1,74 @@ +;(function(omidGlobal) { + 'use strict';var n;function aa(a){var b=0;return function(){return bc&&(c=Math.max(c+e,0));ch&&F.yz){P=!0;break}}P&&(e+=Math.round(k)*Math.round(xa))}}c-=e;b=Math.round(c/b*100);a.u=Math.max(b,0);a.v=Math.max(c,0)}} +function Ja(a,b){if(0!==b.width&&0!==b.height&&a.b){a=va(a.b);var c=a.y,d=a.endX,e=a.endY;b=!(b.endX<=a.x||b.x>=d||b.endY<=c||b.y>=e)}else b=!1;return b}function D(a,b){for(var c=!1,d=0;dd.time&&(d=b[e]);c=d;a.g=Hb(c.rootBounds);a.a=Hb(c.boundingClientRect);a.v=Hb(c.intersectionRect);sb(a)}}catch(g){a.m(),db(a.F,'generic','Problem handling IntersectionObserver callback: '+g.message)}},{root:null,rootMargin:'0px',threshold:[0,.1,.2,.3,.4,.5,.6,.7,.8,.9,1]})} +function Gb(a){a.f.ResizeObserver?a.l||(a.l=Ib(a,function(){return Kb(a)}),a.l.observe(a.b)):(a.s||(a.s=function(){return Kb(a)},(0,a.f.addEventListener)('resize',a.s)),a.j||(a.j=new MutationObserver(function(){return Kb(a)}),a.j.observe(a.b,{childList:!1,attributes:!0,subtree:!1})))}function Kb(a){a.b&&!Fb(a.b)&&(Eb(a),Cb(a))}function Ib(a,b){return new a.f.ResizeObserver(b)}function Hb(a){if(a&&null!==a.x&&null!==a.y&&null!==a.width&&null!==a.height)return new A(a,!1)};function R(a){return'object'===typeof a}function Lb(a){return'number'===typeof a&&!isNaN(a)&&0<=a}function S(a){return'string'===typeof a}function T(a,b){return S(a)&&-1!==Object.values(b).indexOf(a)};function Mb(a){return a&&R(a)?Object.entries(a).reduce(function(b,c){var d=p(c);c=d.next().value;d=d.next().value;return b&&S(c)&&null!=d&&R(d)&&S(d.resourceUrl)},!0):!1};function U(a,b,c,d){this.b=a;this.method=b;this.version=c;this.a=d}function Nb(a){return!!a&&void 0!==a.omid_message_guid&&void 0!==a.omid_message_method&&void 0!==a.omid_message_version&&'string'===typeof a.omid_message_guid&&'string'===typeof a.omid_message_method&&'string'===typeof a.omid_message_version&&(void 0===a.omid_message_args||void 0!==a.omid_message_args)}function Ob(a){return new U(a.omid_message_guid,a.omid_message_method,a.omid_message_version,a.omid_message_args)} +function Pb(a){var b={};b=(b.omid_message_guid=a.b,b.omid_message_method=a.method,b.omid_message_version=a.version,b);void 0!==a.a&&(b.omid_message_args=a.a);return b};function Qb(a){this.c=a};function V(a){this.c=a;this.handleExportedMessage=V.prototype.f.bind(this)}r(V,Qb);V.prototype.b=function(a,b){b=void 0===b?this.c:b;if(!b)throw Error('Message destination must be defined at construction time or when sending the message.');b.handleExportedMessage(Pb(a),this)};V.prototype.f=function(a,b){Nb(a)&&this.a&&this.a(Ob(a),b)};function Rb(a,b){this.c=b=void 0===b?H:b;var c=this;a.addEventListener('message',function(d){if('object'===typeof d.data){var e=d.data;Nb(e)&&d.source&&c.a&&c.a(Ob(e),d.source)}})}r(Rb,Qb);Rb.prototype.b=function(a,b){b=void 0===b?this.c:b;if(!b)throw Error('Message destination must be defined at construction time or when sending the message.');b.postMessage(Pb(a),'*')};function Sb(){return'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,function(a){var b=16*Math.random()|0;return'y'===a?(b&3|8).toString(16):b.toString(16)})};function Tb(a){if(!a.b||!a.b.document)throw Error('OMID Service Script is not running within a window.');var b=a.a;a.a=[];b.forEach(function(c){var d=a.c.C?'limited':'full';var e=T(c.accessMode,ra)?c.accessMode:null;d=e?'full'==e&&'limited'==d?d:e:d;c.accessMode=d;e='full'!=d;d=Sb();var g=c.resourceUrl,l=a.b.document,f=l.createElement('iframe');e&&(f.sandbox='allow-scripts');f.id='omid-verification-script-frame-'+d;f.style.display='none';f.srcdoc="\n