From 7cd5c1921aaf15bc730c6a4c3ae3f887ec2235f9 Mon Sep 17 00:00:00 2001 From: Alexey-Verkhovsky Date: Thu, 16 Sep 2021 11:00:12 +0300 Subject: [PATCH 01/10] Add @JvmOverloads to the factory method --- build.gradle | 1 - .../java/com/fingerprintjs/android/fpjs_pro/FPJSProClient.kt | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index f4ca252..1fbde18 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,6 @@ buildscript { } } - task clean(type: Delete) { delete rootProject.buildDir } \ No newline at end of file diff --git a/fpjs-pro/src/main/java/com/fingerprintjs/android/fpjs_pro/FPJSProClient.kt b/fpjs-pro/src/main/java/com/fingerprintjs/android/fpjs_pro/FPJSProClient.kt index 11374fd..f19b4a8 100644 --- a/fpjs-pro/src/main/java/com/fingerprintjs/android/fpjs_pro/FPJSProClient.kt +++ b/fpjs-pro/src/main/java/com/fingerprintjs/android/fpjs_pro/FPJSProClient.kt @@ -9,7 +9,7 @@ interface FPJSProClient { fun getVisitorId(listener: (String) -> Unit) } -class Configuration( +class Configuration @JvmOverloads constructor( val apiToken: String, val region: Region = Region.US, val endpointUrl: String = region.endpointUrl From e07d614d2f6e1e53edfd62a0d2f75d0bce59d7fe Mon Sep 17 00:00:00 2001 From: Alexey-Verkhovsky Date: Thu, 16 Sep 2021 12:00:30 +0300 Subject: [PATCH 02/10] Update the agent, fix UI thread freeze, remove transitive dependency --- app/build.gradle | 1 - fpjs-pro/build.gradle | 5 +- fpjs-pro/src/main/AndroidManifest.xml | 2 +- fpjs-pro/src/main/assets/index.html | 11 ++--- .../android/fpjs_pro/FPJSProClient.kt | 19 ++++--- .../android/fpjs_pro/FPJSProClientImpl.kt | 20 +++++--- .../android/fpjs_pro/FPJSProInterface.kt | 29 ++++++----- .../device_id_providers/AndroidIdProvider.kt | 22 +++++++++ .../device_id_providers/GsfIdProvider.kt | 49 +++++++++++++++++++ .../device_id_providers/MediaDrmIdProvider.kt | 45 +++++++++++++++++ .../fpjs_pro/tools/ExceptionSafeExecutor.kt | 13 +++++ settings.gradle | 3 -- 12 files changed, 180 insertions(+), 39 deletions(-) create mode 100644 fpjs-pro/src/main/java/com/fingerprintjs/android/fpjs_pro/device_id_providers/AndroidIdProvider.kt create mode 100644 fpjs-pro/src/main/java/com/fingerprintjs/android/fpjs_pro/device_id_providers/GsfIdProvider.kt create mode 100644 fpjs-pro/src/main/java/com/fingerprintjs/android/fpjs_pro/device_id_providers/MediaDrmIdProvider.kt create mode 100644 fpjs-pro/src/main/java/com/fingerprintjs/android/fpjs_pro/tools/ExceptionSafeExecutor.kt diff --git a/app/build.gradle b/app/build.gradle index a9cc9df..99aa345 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -36,7 +36,6 @@ dependencies { implementation project(":fpjs-pro") implementation 'androidx.core:core-ktx:1.6.0' implementation 'androidx.appcompat:appcompat:1.3.1' - implementation "com.github.fingerprintjs:fingerprint-android:1.2" implementation 'com.google.android.material:material:1.4.0' testImplementation 'junit:junit:4.+' androidTestImplementation 'androidx.test.ext:junit:1.1.3' diff --git a/fpjs-pro/build.gradle b/fpjs-pro/build.gradle index 792ea6c..92a426e 100644 --- a/fpjs-pro/build.gradle +++ b/fpjs-pro/build.gradle @@ -7,12 +7,12 @@ plugins { group='com.github.fingerprintjs' android { - compileSdkVersion 30 + compileSdkVersion 31 buildToolsVersion "30.0.3" defaultConfig { minSdkVersion 21 - targetSdkVersion 30 + targetSdkVersion 31 versionCode 1 versionName "1.0" } @@ -35,5 +35,4 @@ android { dependencies { implementation 'androidx.core:core-ktx:1.6.0' implementation 'androidx.appcompat:appcompat:1.3.1' - implementation "com.github.fingerprintjs:fingerprint-android:1.2" } \ No newline at end of file diff --git a/fpjs-pro/src/main/AndroidManifest.xml b/fpjs-pro/src/main/AndroidManifest.xml index 2b39c5a..ee5f6cd 100644 --- a/fpjs-pro/src/main/AndroidManifest.xml +++ b/fpjs-pro/src/main/AndroidManifest.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/fpjs-pro/src/main/assets/index.html b/fpjs-pro/src/main/assets/index.html index a577805..4ece647 100644 --- a/fpjs-pro/src/main/assets/index.html +++ b/fpjs-pro/src/main/assets/index.html @@ -8,7 +8,7 @@ * MurmurHash3 by Karan Lyons (https://github.com/karanlyons/murmurHash3.js) */ - var FingerprintJS=function(e){"use strict";var t=function(){return(t=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]=r+n?(r=u,[4,a(0)]):[3,3]):[3,4];case 2:i.sent(),i.label=3;case 3:return++o,[3,1];case 4:return[2]}}))}))}function c(e,t){e=[e[0]>>>16,65535&e[0],e[1]>>>16,65535&e[1]],t=[t[0]>>>16,65535&t[0],t[1]>>>16,65535&t[1]];var n=[0,0,0,0];return n[3]+=e[3]+t[3],n[2]+=n[3]>>>16,n[3]&=65535,n[2]+=e[2]+t[2],n[1]+=n[2]>>>16,n[2]&=65535,n[1]+=e[1]+t[1],n[0]+=n[1]>>>16,n[1]&=65535,n[0]+=e[0]+t[0],n[0]&=65535,[n[0]<<16|n[1],n[2]<<16|n[3]]}function l(e,t){e=[e[0]>>>16,65535&e[0],e[1]>>>16,65535&e[1]],t=[t[0]>>>16,65535&t[0],t[1]>>>16,65535&t[1]];var n=[0,0,0,0];return n[3]+=e[3]*t[3],n[2]+=n[3]>>>16,n[3]&=65535,n[2]+=e[2]*t[3],n[1]+=n[2]>>>16,n[2]&=65535,n[2]+=e[3]*t[2],n[1]+=n[2]>>>16,n[2]&=65535,n[1]+=e[1]*t[3],n[0]+=n[1]>>>16,n[1]&=65535,n[1]+=e[2]*t[2],n[0]+=n[1]>>>16,n[1]&=65535,n[1]+=e[3]*t[1],n[0]+=n[1]>>>16,n[1]&=65535,n[0]+=e[0]*t[3]+e[1]*t[2]+e[2]*t[1]+e[3]*t[0],n[0]&=65535,[n[0]<<16|n[1],n[2]<<16|n[3]]}function f(e,t){return 32===(t%=64)?[e[1],e[0]]:t<32?[e[0]<>>32-t,e[1]<>>32-t]:(t-=32,[e[1]<>>32-t,e[0]<>>32-t])}function d(e,t){return 0===(t%=64)?e:t<32?[e[0]<>>32-t,e[1]<>>1]),e=v(e=l(e,[4283543511,3981806797]),[0,e[0]>>>1]),e=v(e=l(e,[3301882366,444984403]),[0,e[0]>>>1])}function m(e){return parseInt(e)}function p(e){return parseFloat(e)}function g(e,t){return"number"==typeof e&&isNaN(e)?t:e}function b(e){return e.reduce((function(e,t){return e+(t?1:0)}),0)}function w(e,t){if(void 0===t&&(t=1),Math.abs(t)>=1)return Math.round(e/t)*t;var n=1/t;return Math.round(e*n)/n}function y(e){return e&&"object"==typeof e&&"message"in e?e:{message:e}}function k(e,t,n){var o=Object.keys(e).filter((function(e){return!function(e,t){for(var n=0,r=e.length;n=4}function R(){var e=window,t=navigator;return b(["msWriteProfilerMark"in e,"MSStream"in e,"msLaunchUri"in t,"msSaveBlob"in t])>=3&&!E()}function S(){var e=window,t=navigator;return b(["webkitPersistentStorage"in t,"webkitTemporaryStorage"in t,0===t.vendor.indexOf("Google"),"webkitResolveLocalFileSystemURL"in e,"BatteryManager"in e,"webkitMediaStream"in e,"webkitSpeechGrammar"in e])>=5}function T(){var e=window,t=navigator;return b(["ApplePayError"in e,"CSSPrimitiveValue"in e,"Counter"in e,0===t.vendor.indexOf("Apple"),"getStorageUpdates"in t,"WebKitMediaKeys"in e])>=4}function _(){var e=window;return b(["safari"in e,!("DeviceMotionEvent"in e),!("ongestureend"in e),!("standalone"in navigator)])>=3}function A(){var e,t,n=window;return b(["buildID"in navigator,"MozAppearance"in(null!==(t=null===(e=document.documentElement)||void 0===e?void 0:e.style)&&void 0!==t?t:{}),"MediaRecorderErrorEvent"in n,"mozInnerScreenX"in n,"CSSMozDocumentRule"in n,"CanvasCaptureMediaStream"in n])>=4}function C(){var e=document;return e.fullscreenElement||e.msFullscreenElement||e.mozFullScreenElement||e.webkitFullscreenElement||null}function I(){var e=S(),t=A();if(!e&&!t)return!1;var n=window;return b(["onorientationchange"in n,"orientation"in n,e&&"SharedWorker"in n,t&&/android/i.test(navigator.appVersion)])>=2}function O(e){var t=new Error(e);return t.name=e,t}function x(e,t,n){var o,u,s;return void 0===n&&(n=50),r(this,void 0,void 0,(function(){var r,c;return i(this,(function(i){switch(i.label){case 0:r=document,i.label=1;case 1:return r.body?[3,3]:[4,a(n)];case 2:return i.sent(),[3,1];case 3:c=r.createElement("iframe"),i.label=4;case 4:return i.trys.push([4,,10,11]),[4,new Promise((function(e,n){c.onload=e,c.onerror=n;var i=c.style;i.setProperty("display","block","important"),i.position="absolute",i.top="0",i.left="0",i.visibility="hidden",t&&"srcdoc"in c?c.srcdoc=t:c.src="about:blank",r.body.appendChild(c);var o=function(){var t,n;"complete"===(null===(n=null===(t=c.contentWindow)||void 0===t?void 0:t.document)||void 0===n?void 0:n.readyState)?e():setTimeout(o,10)};o()}))];case 5:i.sent(),i.label=6;case 6:return(null===(u=null===(o=c.contentWindow)||void 0===o?void 0:o.document)||void 0===u?void 0:u.body)?[3,8]:[4,a(n)];case 7:return i.sent(),[3,6];case 8:return[4,e(c,c.contentWindow)];case 9:return[2,i.sent()];case 10:return null===(s=c.parentNode)||void 0===s||s.removeChild(c),[7];case 11:return[2]}}))}))}function P(e){for(var t=function(e){for(var t,n,r="Unexpected syntax '"+e+"'",i=/^\s*([a-z-]*)(.*)$/i.exec(e),o=i[1]||void 0,a={},u=/([.:#][\w-]+|\[.+?\])/gi,s=function(e,t){a[e]=a[e]||[],a[e].push(t)};;){var c=u.exec(i[2]);if(!c)break;var l=c[0];switch(l[0]){case".":s("class",l.slice(1));break;case"#":s("id",l.slice(1));break;case"[":var f=/^\[([\w-]+)([~|^$*]?=("(.*?)"|([\w-]+)))?(\s+[is])?\]$/.exec(l);if(!f)throw new Error(r);s(f[1],null!==(n=null!==(t=f[4])&&void 0!==t?t:f[5])&&void 0!==n?n:"");break;default:throw new Error(r)}}return[o,a]}(e),n=t[0],r=t[1],i=document.createElement(null!=n?n:"div"),o=0,a=Object.keys(r);o.6*n.length}))).sort(),[2,n]}}))}))},fontPreferences:function(){return function(e,t){void 0===t&&(t=4e3);return x((function(n,r){var i=r.document,a=i.body,u=a.style;u.width=t+"px",u.webkitTextSizeAdjust=u.textSizeAdjust="none",S()?a.style.zoom=""+1/r.devicePixelRatio:T()&&(a.style.zoom="reset");var s=i.createElement("div");return s.textContent=o(Array(t/20<<0)).map((function(){return"word"})).join(" "),a.appendChild(s),e(i,a)}),'')}((function(e,t){for(var n={},r={},i=0,o=Object.keys(Se);i=3}())return-1;var n=new t(1,5e3,44100),r=n.createOscillator();r.type="triangle",r.frequency.value=1e4;var i=n.createDynamicsCompressor();i.threshold.value=-50,i.knee.value=40,i.ratio.value=12,i.attack.value=0,i.release.value=.25,r.connect(i),i.connect(n.destination),r.start(0);var o=function(e){var t=3,n=500,r=500,i=5e3,o=function(){};return[new Promise((function(a,u){var s=!1,c=0,l=0;e.oncomplete=function(e){return a(e.renderedBuffer)};var f=function(){setTimeout((function(){return u(O("timeout"))}),Math.min(r,l+i-Date.now()))},d=function(){try{switch(e.startRendering(),e.state){case"running":l=Date.now(),s&&f();break;case"suspended":document.hidden||c++,s&&c>=t?u(O("suspended")):setTimeout(d,n)}}catch(r){u(r)}};d(),o=function(){s||(s=!0,l>0&&f())}})),o]}(n),a=o[0],u=o[1],s=a.then((function(e){return function(e){for(var t=0,n=0;n=3||n.push(t.languages);else if("string"==typeof t.languages){var i=t.languages;i&&n.push(i.split(","))}return n},colorDepth:function(){return window.screen.colorDepth},deviceMemory:function(){return g(p(navigator.deviceMemory),void 0)},screenResolution:function(){var e=screen,t=function(e){return g(m(e),null)},n=[t(e.width),t(e.height)];return n.sort().reverse(),n},hardwareConcurrency:function(){return g(m(navigator.hardwareConcurrency),void 0)},timezone:function(){var e,t=null===(e=window.Intl)||void 0===e?void 0:e.DateTimeFormat;if(t){var n=(new t).resolvedOptions().timeZone;if(n)return n}var r,i=(r=(new Date).getFullYear(),-Math.max(p(new Date(r,0,1).getTimezoneOffset()),p(new Date(r,6,1).getTimezoneOffset())));return"UTC"+(i>=0?"+":"")+Math.abs(i)},sessionStorage:function(){try{return!!window.sessionStorage}catch(e){return!0}},localStorage:function(){try{return!!window.localStorage}catch(e){return!0}},indexedDB:function(){if(!E()&&!R())try{return!!window.indexedDB}catch(e){return!0}},openDatabase:function(){return!!window.openDatabase},cpuClass:function(){return navigator.cpuClass},platform:function(){var e=navigator.platform;return"MacIntel"===e&&T()&&!_()?function(){if("iPad"===navigator.platform)return!0;var e=screen,t=e.width/e.height;return b(["MediaSource"in window,!!Element.prototype.webkitRequestFullscreen,t>2/3&&t<1.5])>=2}()?"iPad":"iPhone":e},plugins:function(){var e=navigator.plugins;if(e){for(var t=[],n=0;n>>0).toString(16)).slice(-8)+("00000000"+(o[1]>>>0).toString(16)).slice(-8)+("00000000"+(a[0]>>>0).toString(16)).slice(-8)+("00000000"+(a[1]>>>0).toString(16)).slice(-8)},Oe="3.5.0";function xe(e,t){return new Promise((function(n){return Pe(n,e,t)}))}function Pe(e,t){for(var n=[],r=2;re.length)return-1;for(var n=0;n>2]+Ve[(3&t[i])<<4|t[i+1]>>4]+Ve[(15&t[i+1])<<2|t[i+2]>>6]+Ve[63&t[i+2]];return n%3==2?r.slice(0,-1)+"=":n%3==1?r.slice(0,-2)+"==":r}function Ye(e){for(var t="",n=0;n0){var r=e[n].toLowerCase();r!==e[n]?t+=" "+r:t+=e[n]}else t+=e[n].toUpperCase();return t}function Ze(e,t){for(var n="",r=0;r=4}function ft(){var e=window;return $e(["AnonymousContent"in e,!("AudioBuffer"in e),!("RTCPeerConnection"in e),!("geolocation"in navigator),!("ServiceWorker"in e)])>=3}var dt=function(e){return new vt(e).addEvent},vt=function(){function e(e){var t=this;this.onReportReady=e,this.isStopped=!1,this.pageStartTimestamp=function(){var e,t,n=performance;if(n.timeOrigin){var r=null===(t=null===(e=n.getEntriesByType)||void 0===e?void 0:e.call(n,"navigation"))||void 0===t?void 0:t[0];if(r)return n.timeOrigin+(r.responseStart||r.unloadEventEnd)}return n.timing.domLoading||n.timing.responseStart||n.timing.unloadEventEnd}(),this.events={},this.addEvent=function(e){if(!t.isStopped){var n={time:new Date,type:"agentEvent",event:e};switch(0===e.e&&(n.documentReadyState=document.readyState,n.isPageVisible=kt(),n.isFullscreen=Et(),n.network=Rt()),t.storeAgentEvent(n),e.e){case 2:t.submitReport(e.agentId,void 0);break;case 4:case 5:t.submitReport(e.agentId,e.getCallId)}}};for(var n=window,r=document,i=[[r,"readystatechange",function(){return t.handleDocumentReadyStateChange()}],[r,"visibilitychange",function(){return t.handleVisibilityChange()}],[r,"pageshow",function(){return t.handlePageTransition(!0)}],[r,"pagehide",function(){return t.handlePageTransition(!1)}],[n,"unload",function(){return t.handlePageUnload()}]],o=0,a=i;o=o)break;var v=d&&d.time.getTime()<=o,h=((null==d?void 0:d.time)||i).getTime()-f.time.getTime();u.triesCount++,u.triesTotalDuration+=h,v&&(u.completeTriesCount++,u.completeTriesTotalDuration+=h)}}return u}function bt(e,n){return e?t(t({},e),n()):void 0}function wt(e){for(var t={},n=0,r=Object.keys(e);n1800?Xe(new Uint8Array(a,0,1800))+"...":Xe(a))}return o(t(t({},i),{body:a}))}}function Ct(e){if(!e||"incomplete"===e.state||"fail"===e.state)return e;e.componentDurations;var r=n(e,["componentDurations"]),i=Object.keys(e.failedComponents),o=i.length?","+i.join(",")+",":void 0;return t(t({},r),{failedComponents:o})}function It(e,n){void 0===n&&(n="_");for(var r=t({},e),i=0,o=Object.keys(e);i=500)return t;throw t}function cn(e,t,n,r,i){void 0===i&&(i=et);var o=i()%(n+1),a=function(e){if("function"==typeof TextEncoder)return(new TextEncoder).encode(e);for(var t=unescape(encodeURI(e)),n=new Uint8Array(t.length),r=0;r=2?function(){return r(this,void 0,void 0,(function(){var e,t,n,r,o;return i(this,(function(i){switch(i.label){case 0:return e=gn(),t=navigator,n=t[e[3]],(r=t[e[4]])?[4,new Promise((function(t){r[e[5]]((function(e,n){return t(n)}))}))]:[3,2];case 1:return o=i.sent(),[3,4];case 2:return(null==n?void 0:n[e[6]])?[4,n[e[6]]().then((function(e){return e.quota}))]:[3,4];case 3:o=i.sent(),i.label=4;case 4:return o?[2,o=6)return u();1===a.length&&Me(u,10)}},n.onicegatheringstatechange=function(){"complete"===n.iceGatheringState&&u()},n.onicecandidateerror=t;try{null===(r=n.createDataChannel)||void 0===r||r.call(n,"test")}catch(i){return void(i.name===Sn?e(-7):t(i))}var s=function(e,t){try{return e.createOffer(t)}catch(i){if(/\bcreateOffer\b.*(\bcallback\b.*\bnot a function\b|\barguments required\b.*\bpresent\b)/i.test(i.message))return new Promise((function(n,r){e.createOffer(n,r,t)}));throw i}}(n,R()?{offerToReceiveAudio:!0}:void 0);void 0===s?e(-8):s.then((function(e){return n.setLocalDescription(e)}),t)}))];case 2:return[2,r.sent()];case 3:try{n.close()}catch(i){}return[7];case 4:return[2]}}))}))}function _n(e){if("InvalidAccessError"===e.name){if(/\bfrom\b.*\binsecure\b/i.test(e.message))return{s:-2,v:null};if(/\bdifferent\b.*\borigin\b.*top.level\b.*\bframe\b/i.test(e.message))return{s:-3,v:null}}throw e}function An(e){return matchMedia("(prefers-color-scheme: "+e+")").matches}function Cn(e){var t=Number(e);return isNaN(t)?-1:t}var In=["MAX_TEXTURE_MAX_ANISOTROPY_EXT","FRAGMENT_SHADER_DERIVATIVE_HINT_OES","MAX_COLOR_ATTACHMENTS_WEBGL","MAX_DRAW_BUFFERS_WEBGL","DRAW_BUFFER0_WEBGL","DRAW_BUFFER1_WEBGL","VERTEX_ARRAY_BINDING_OES","TIMESTAMP_EXT","GPU_DISJOINT_EXT","MAX_VIEWS_OVR"],On=[10752,2849,2884,2885,2886,2928,2929,2930,2931,2932,2960,2961,2962,2963,2964,2965,2966,2967,2968,2978,3024,3042,3088,3089,3106,3107,32773,32777,32777,32823,32824,32926,32928,32936,32937,32938,32939,32968,32969,32970,32971,3317,33170,3333,3379,3386,33901,33902,34016,34024,34076,3408,3410,3411,3412,3413,3414,3415,34467,34816,34817,34818,34819,34877,34921,34930,35660,35661,35724,35738,35739,36003,36004,36005,36347,36348,36349,37440,37441,37443,7936,7937,7938],xn=[32926,32928],Pn=["FRAGMENT_SHADER","VERTEX_SHADER"],Dn=["LOW_FLOAT","MEDIUM_FLOAT","HIGH_FLOAT","LOW_INT","MEDIUM_INT","HIGH_INT"];function Mn(e,t,n){var r=e.getShaderPrecisionFormat(e[t],e[n]);return r?[r.rangeMin,r.rangeMax,r.precision]:[]}function Nn(e){return"string"==typeof e&&!e.match(/[^A-Z0-9_x]/)}function Ln(e){return Object.keys(e.__proto__).filter(Nn)}function jn(e){var t=function(e){return e.replace(/([,\\])/g,"\\$1")};return e.map((function(e){return[t(e.voiceURI),t(e.name),t(e.lang),e.localService?"1":"0",e.default?"1":"0"].join(",")})).sort()}var Bn={m:["$$s-macbook-pro","$$s-macbook-air","$$s-mac-mini"],i:["$$s-iphone"]},Fn={m:["macbook-pro-$$","macbook-air-$$","mac-mini-$$"],i:["iphone-$$"]},Un={"en-us":t(t({},Bn),{n:["james","mary","john","patricia","robert","jennifer","michael","linda","william","elizabeth","david","barbara","richard","susan","joseph","jessica","thomas","sarah","charles","karen","christopher","nancy","daniel","lisa","matthew","margaret","anthony","betty","donald","sandra"]}),"en-gb":t(t({},Bn),{n:["oliver","george","noah","arthur","harry","leo","muhammad","jack","charlie","oscar","jacob","henry","thomas","joshua","william","olivia","amelia","isla","ava","mia","isabella","sophia","grace","lily","freya","emily","ivy","ella","rosie","charlotte"]}),"ru-ru":t(t({},Fn),{n:["aleksandr","sergej","vladimir","elena","tatana","andrej","aleksej","olga","nikolaj","natala","anna","ivan","dmitrij","irina","maria","mihail","svetlana","ekaterina","evgenij","viktor","anastasia","urij","ulia","valentin","roman","igor","anatolij","oleg","pavel","maksim"]})};Un.default=Un["en-us"],Un.en=Un["en-us"],Un.ru=Un["ru-ru"];var Gn={m:["macbook-pro","macbook-air","mac-mini","mac-pro"],i:["iphone","iphone-2"]};function qn(e){return r(this,void 0,void 0,(function(){var t,n,o,a,u,s,c,l,f=this;return i(this,(function(d){switch(d.label){case 0:if(!(t=window.RTCPeerConnection))return[2,-5];n=Math.random().toString(),o=new Map,u="candidate:0 1 udp 2113937151 ${addr} ${port} typ host generation 0 ufrag "+(a="ABCD")+" network-cost 999",s=new t({iceTransportPolicy:"all"}),c=s.createDataChannel(n),l=0,d.label=1;case 1:return d.trys.push([1,,3,4]),[4,new Promise((function(t,n){Me((function(){return t(-4)}),1e3),s.oniceconnectionstatechange=function(){"checking"===s.iceConnectionState&&(l=setInterval((function(){return r(f,void 0,void 0,(function(){var e,n;return i(this,(function(r){switch(r.label){case 0:return"checking"!==s.iceConnectionState?[2,t([])]:[4,s.getStats()];case 1:return e=r.sent(),n=[],e.forEach((function(e){if("remote-candidate"===e.type){var t=o.get(e.port);n.push(t)}})),n.length>0&&t(n),[2]}}))}))}),30))},s.createOffer().then((function(n){var r=n.sdp;if(!r)return t(-5);for(var i=[],c=0;c1?[2,Vn(n)]:1===n.length?[2,n[0]]:[2,-1]}}))}))}var zn,Hn,$n=["brands","mobile","platform","platformVersion","architecture","bitness","model","uaFullVersion"];var Kn=((zn={})[0]=function(){return Be(Ne(510,-4),Tn)},zn[1]=function(){var e,t,n,r=((n=new Promise((function(n,r){e=n,t=r}))).resolve=e,n.reject=t,n),i=Ne(_()?310:410);return Be(Promise.race([r,i]).then((function(e){if(void 0!==e)return Ne(e+100-Date.now())})).then((function(){return-4})),(function(){return Wn((function(){return r.resolve(Date.now())}))}))},zn[2]=function(){var e=window.speechSynthesis;if("function"!=typeof(null==e?void 0:e.getVoices))return-1;var t=function(){return e.getVoices()};return!e.addEventListener||A()&&ft()?jn(t()):function(e){return r(this,void 0,void 0,(function(){var t;return i(this,(function(n){switch(n.label){case 0:return n.trys.push([0,,2,3]),[4,new Promise((function(n,r){var i,o=function(){e.getVoices().length?(null==i||i(),i=Pe(n,50)):i||(i=Me(n,600))};t=function(){try{o()}catch(e){r(e)}},o(),e.addEventListener("voiceschanged",t)}))];case 1:return[2,n.sent()];case 2:return t&&e.removeEventListener("voiceschanged",t),[7];case 3:return[2]}}))}))}(e).then((function(){return function(){var e=t();return e.length?jn(e):-2}}))},zn[3]=function(){return r(this,void 0,void 0,(function(){var e;return i(this,(function(t){switch(t.label){case 0:if("function"!=typeof(e=window.ApplePaySession))return[2,{s:-1,v:null}];t.label=1;case 1:return t.trys.push([1,3,,4]),e.canMakePayments()?T()&&!lt()?[2,{s:0,v:1}]:[4,Promise.race([e.canMakePaymentsWithActiveCard(""),Ne(250,!1)])]:[2,{s:0,v:0}];case 2:return[2,{s:0,v:t.sent()?3:2}];case 3:return[2,_n(t.sent())];case 4:return[2]}}))}))},zn[4]=function(e){var t=e.storageKeyPrefix;return r(this,void 0,void 0,(function(){var e,n,r;return i(this,(function(i){switch(i.label){case 0:return void 0!==(n=function(e){try{var t=localStorage.getItem(e);if(!t)return;return"1"===t}catch(n){return}}(e=t+"_i"))?[2,n]:[4,Rn()];case 1:return r=i.sent(),function(e,t){try{localStorage.setItem(e,t?"1":"0")}catch(n){}}(e,r),[2,r]}}))}))},zn[5]=G,zn[8]=function(){var e=this;return Be(xe(250,-2),(function(){return r(e,void 0,void 0,(function(){var e,t,n;return i(this,(function(r){switch(r.label){case 0:return(null==(e=navigator.mediaDevices)?void 0:e.enumerateDevices)?(t=function(e){return e.slice(0,32).replace(/([,\\])/g,"\\$1")},n=function(e){return[t(e.deviceId),t(e.groupId),{audioinput:"ai",audiooutput:"ao",videoinput:"vi"}[e.kind],t(e.label)].join(",")},[4,e.enumerateDevices()]):[2,-1];case 1:return[2,r.sent().map(n)]}}))}))}))},zn[7]=function(){var e;return r(this,void 0,void 0,(function(){var t,n,o,a,u,s,c=this;return i(this,(function(l){switch(l.label){case 0:if(!(t=null===(e=window.crypto)||void 0===e?void 0:e.subtle)||!t.generateKey||!t.exportKey)return[2,-1];n=function(){return r(c,void 0,void 0,(function(){var e,n;return i(this,(function(r){switch(r.label){case 0:return[4,t.generateKey({name:"AES-GCM",length:128},!0,["encrypt"])];case 1:return e=r.sent(),[4,t.exportKey("raw",e)];case 2:return n=r.sent(),[2,new Uint8Array(n)]}}))}))},l.label=1;case 1:return l.trys.push([1,3,,4]),[4,Promise.all([n(),n()])];case 2:for(o=l.sent(),a=new Uint8Array(o[0].length),u=0;u=0;--n)if(n%4096==0){var r=Math.random();e.push((t-r)*Math.pow(2,31)|0),t=r}return e},zn[29]=function(){var e=window.performance;if(null==e?void 0:e.now){for(var t=1,n=1,r=e.now(),i=r,o=0;o<5e4;o++)if((r=i)<(i=e.now())){var a=i-r;a>t?a0?d.push(C+"("+w+")="+e.getParameter(w)):d.push(C+"="+w)}}for(var I=0,O=Pn;I0?e.lastIndexOf(".",n-1):-1,!1===t(e.slice(n+1)))return!1}while(n>=0);return!0}function er(e){return[Xn(e),nr(e)]}function tr(e,t){Zn(t,e,365),function(e,t){var n;try{null===(n=null===localStorage||void 0===localStorage?void 0:localStorage.setItem)||void 0===n||n.call(localStorage,e,t)}catch(r){}}(t,e)}function nr(e){var t,n;try{return null!==(n=null===(t=null===localStorage||void 0===localStorage?void 0:localStorage.getItem)||void 0===t?void 0:t.call(localStorage,e))&&void 0!==n?n:void 0}catch(r){}}function rr(e,t){return{score:e[0]||e[1]?.999:t[25].value?.99:A()&&ft()?.9:function(){for(var e=[],t=0;t0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]e.length)return-1;for(var n=0;n>2]+y[(3&t[i])<<4|t[i+1]>>4]+y[(15&t[i+1])<<2|t[i+2]>>6]+y[63&t[i+2]];return n%3==2?r.slice(0,-1)+"=":n%3==1?r.slice(0,-2)+"==":r}function C(e){for(var t="",n=0;n0){var r=e[n].toLowerCase();r!==e[n]?t+=" "+r:t+=e[n]}else t+=e[n].toUpperCase();return t}function A(e){return void 0===e?void 0:""+e}function I(e,t){for(var n="",r=0;r=r+n?(r=a,[4,z(0)]):[3,3]):[3,4];case 2:i.sent(),i.label=3;case 3:return++o,[3,1];case 4:return[2]}}))}))}function K(e,t){e=[e[0]>>>16,65535&e[0],e[1]>>>16,65535&e[1]],t=[t[0]>>>16,65535&t[0],t[1]>>>16,65535&t[1]];var n=[0,0,0,0];return n[3]+=e[3]+t[3],n[2]+=n[3]>>>16,n[3]&=65535,n[2]+=e[2]+t[2],n[1]+=n[2]>>>16,n[2]&=65535,n[1]+=e[1]+t[1],n[0]+=n[1]>>>16,n[1]&=65535,n[0]+=e[0]+t[0],n[0]&=65535,[n[0]<<16|n[1],n[2]<<16|n[3]]}function J(e,t){e=[e[0]>>>16,65535&e[0],e[1]>>>16,65535&e[1]],t=[t[0]>>>16,65535&t[0],t[1]>>>16,65535&t[1]];var n=[0,0,0,0];return n[3]+=e[3]*t[3],n[2]+=n[3]>>>16,n[3]&=65535,n[2]+=e[2]*t[3],n[1]+=n[2]>>>16,n[2]&=65535,n[2]+=e[3]*t[2],n[1]+=n[2]>>>16,n[2]&=65535,n[1]+=e[1]*t[3],n[0]+=n[1]>>>16,n[1]&=65535,n[1]+=e[2]*t[2],n[0]+=n[1]>>>16,n[1]&=65535,n[1]+=e[3]*t[1],n[0]+=n[1]>>>16,n[1]&=65535,n[0]+=e[0]*t[3]+e[1]*t[2]+e[2]*t[1]+e[3]*t[0],n[0]&=65535,[n[0]<<16|n[1],n[2]<<16|n[3]]}function X(e,t){return 32===(t%=64)?[e[1],e[0]]:t<32?[e[0]<>>32-t,e[1]<>>32-t]:(t-=32,[e[1]<>>32-t,e[0]<>>32-t])}function Y(e,t){return 0===(t%=64)?e:t<32?[e[0]<>>32-t,e[1]<>>1]),e=Z(e=J(e,[4283543511,3981806797]),[0,e[0]>>>1]),e=Z(e=J(e,[3301882366,444984403]),[0,e[0]>>>1])}function ee(e){return parseInt(e)}function te(e){return parseFloat(e)}function ne(e,t){return"number"==typeof e&&isNaN(e)?t:e}function re(e){return e.reduce((function(e,t){return e+(t?1:0)}),0)}function ie(e,t){if(void 0===t&&(t=1),Math.abs(t)>=1)return Math.round(e/t)*t;var n=1/t;return Math.round(e*n)/n}function oe(e){return e&&"object"==typeof e&&"message"in e?e:{message:e}}function ae(e,t,n){var o=Object.keys(e).filter((function(e){return!function(e,t){for(var n=0,r=e.length;n=4}function se(){var e=window,t=navigator;return re(["msWriteProfilerMark"in e,"MSStream"in e,"msLaunchUri"in t,"msSaveBlob"in t])>=3&&!ue()}function ce(){var e=window,t=navigator;return re(["webkitPersistentStorage"in t,"webkitTemporaryStorage"in t,0===t.vendor.indexOf("Google"),"webkitResolveLocalFileSystemURL"in e,"BatteryManager"in e,"webkitMediaStream"in e,"webkitSpeechGrammar"in e])>=5}function le(){var e=window,t=navigator;return re(["ApplePayError"in e,"CSSPrimitiveValue"in e,"Counter"in e,0===t.vendor.indexOf("Apple"),"getStorageUpdates"in t,"WebKitMediaKeys"in e])>=4}function fe(){var e=window;return re(["safari"in e,!("DeviceMotionEvent"in e),!("ongestureend"in e),!("standalone"in navigator)])>=3}function de(){var e,t,n=window;return re(["buildID"in navigator,"MozAppearance"in(null!==(t=null===(e=document.documentElement)||void 0===e?void 0:e.style)&&void 0!==t?t:{}),"MediaRecorderErrorEvent"in n,"mozInnerScreenX"in n,"CSSMozDocumentRule"in n,"CanvasCaptureMediaStream"in n])>=4}function ve(){var e=document;return e.fullscreenElement||e.msFullscreenElement||e.mozFullScreenElement||e.webkitFullscreenElement||null}function he(){var e=ce(),t=de();if(!e&&!t)return!1;var n=window;return re(["onorientationchange"in n,"orientation"in n,e&&"SharedWorker"in n,t&&/android/i.test(navigator.appVersion)])>=2}function me(e){var t=new Error(e);return t.name=e,t}function pe(e,t,n){var o,a,u;return void 0===n&&(n=50),r(this,void 0,void 0,(function(){var r,s;return i(this,(function(i){switch(i.label){case 0:r=document,i.label=1;case 1:return r.body?[3,3]:[4,z(n)];case 2:return i.sent(),[3,1];case 3:s=r.createElement("iframe"),i.label=4;case 4:return i.trys.push([4,,10,11]),[4,new Promise((function(e,n){s.onload=e,s.onerror=n;var i=s.style;i.setProperty("display","block","important"),i.position="absolute",i.top="0",i.left="0",i.visibility="hidden",t&&"srcdoc"in s?s.srcdoc=t:s.src="about:blank",r.body.appendChild(s);var o=function(){var t,n;"complete"===(null===(n=null===(t=s.contentWindow)||void 0===t?void 0:t.document)||void 0===n?void 0:n.readyState)?e():setTimeout(o,10)};o()}))];case 5:i.sent(),i.label=6;case 6:return(null===(a=null===(o=s.contentWindow)||void 0===o?void 0:o.document)||void 0===a?void 0:a.body)?[3,8]:[4,z(n)];case 7:return i.sent(),[3,6];case 8:return[4,e(s,s.contentWindow)];case 9:return[2,i.sent()];case 10:return null===(u=s.parentNode)||void 0===u||u.removeChild(s),[7];case 11:return[2]}}))}))}function ge(e){for(var t=function(e){for(var t,n,r="Unexpected syntax '"+e+"'",i=/^\s*([a-z-]*)(.*)$/i.exec(e),o=i[1]||void 0,a={},u=/([.:#][\w-]+|\[.+?\])/gi,s=function(e,t){a[e]=a[e]||[],a[e].push(t)};;){var c=u.exec(i[2]);if(!c)break;var l=c[0];switch(l[0]){case".":s("class",l.slice(1));break;case"#":s("id",l.slice(1));break;case"[":var f=/^\[([\w-]+)([~|^$*]?=("(.*?)"|([\w-]+)))?(\s+[is])?\]$/.exec(l);if(!f)throw new Error(r);s(f[1],null!==(n=null!==(t=f[4])&&void 0!==t?t:f[5])&&void 0!==n?n:"");break;default:throw new Error(r)}}return[o,a]}(e),n=t[0],r=t[1],i=document.createElement(null!=n?n:"div"),o=0,a=Object.keys(r);o.6*n.length}))).sort(),[2,n]}}))}))},fontPreferences:function(){return function(e,t){void 0===t&&(t=4e3);return pe((function(n,r){var i=r.document,a=i.body,u=a.style;u.width=t+"px",u.webkitTextSizeAdjust=u.textSizeAdjust="none",ce()?a.style.zoom=""+1/r.devicePixelRatio:le()&&(a.style.zoom="reset");var s=i.createElement("div");return s.textContent=o(Array(t/20<<0)).map((function(){return"word"})).join(" "),a.appendChild(s),e(i,a)}),'')}((function(e,t){for(var n={},r={},i=0,o=Object.keys(ct);i=3}())return-1;var n=new t(1,5e3,44100),r=n.createOscillator();r.type="triangle",r.frequency.value=1e4;var i=n.createDynamicsCompressor();i.threshold.value=-50,i.knee.value=40,i.ratio.value=12,i.attack.value=0,i.release.value=.25,r.connect(i),i.connect(n.destination),r.start(0);var o=function(e){var t=3,n=500,r=500,i=5e3,o=function(){};return[new Promise((function(a,u){var s=!1,c=0,l=0;e.oncomplete=function(e){return a(e.renderedBuffer)};var f=function(){setTimeout((function(){return u(me("timeout"))}),Math.min(r,l+i-Date.now()))},d=function(){try{switch(e.startRendering(),e.state){case"running":l=Date.now(),s&&f();break;case"suspended":document.hidden||c++,s&&c>=t?u(me("suspended")):setTimeout(d,n)}}catch(r){u(r)}};d(),o=function(){s||(s=!0,l>0&&f())}})),o]}(n),a=o[0],u=o[1],s=a.then((function(e){return function(e){for(var t=0,n=0;n=3||n.push(t.languages);else if("string"==typeof t.languages){var i=t.languages;i&&n.push(i.split(","))}return n},colorDepth:function(){return window.screen.colorDepth},deviceMemory:function(){return ne(te(navigator.deviceMemory),void 0)},screenResolution:function(){var e=screen,t=function(e){return ne(ee(e),null)},n=[t(e.width),t(e.height)];return n.sort().reverse(),n},hardwareConcurrency:function(){return ne(ee(navigator.hardwareConcurrency),void 0)},timezone:function(){var e,t=null===(e=window.Intl)||void 0===e?void 0:e.DateTimeFormat;if(t){var n=(new t).resolvedOptions().timeZone;if(n)return n}var r,i=(r=(new Date).getFullYear(),-Math.max(te(new Date(r,0,1).getTimezoneOffset()),te(new Date(r,6,1).getTimezoneOffset())));return"UTC"+(i>=0?"+":"")+Math.abs(i)},sessionStorage:function(){try{return!!window.sessionStorage}catch(e){return!0}},localStorage:function(){try{return!!window.localStorage}catch(e){return!0}},indexedDB:function(){if(!ue()&&!se())try{return!!window.indexedDB}catch(e){return!0}},openDatabase:function(){return!!window.openDatabase},cpuClass:function(){return navigator.cpuClass},platform:function(){var e=navigator.platform;return"MacIntel"===e&&le()&&!fe()?function(){if("iPad"===navigator.platform)return!0;var e=screen,t=e.width/e.height;return re(["MediaSource"in window,!!Element.prototype.webkitRequestFullscreen,t>2/3&&t<1.5])>=2}()?"iPad":"iPhone":e},plugins:function(){var e=navigator.plugins;if(e){for(var t=[],n=0;n>>0).toString(16)).slice(-8)+("00000000"+(o[1]>>>0).toString(16)).slice(-8)+("00000000"+(a[0]>>>0).toString(16)).slice(-8)+("00000000"+(a[1]>>>0).toString(16)).slice(-8)};function mt(){var e=window,t=navigator;return R(["maxTouchPoints"in t,"mediaCapabilities"in t,"PointerEvent"in e,"visualViewport"in e,"onafterprint"in e])>=4}function pt(){var e=window;return R(["AnonymousContent"in e,!("AudioBuffer"in e),!("RTCPeerConnection"in e),!("geolocation"in navigator),!("ServiceWorker"in e)])>=3}var gt=function(e){return new bt(e).addEvent},bt=function(){function e(e){var t=this;this.onReportReady=e,this.isStopped=!1,this.pageStartTimestamp=function(){var e,t,n=performance;if(n.timeOrigin){var r=null===(t=null===(e=n.getEntriesByType)||void 0===e?void 0:e.call(n,"navigation"))||void 0===t?void 0:t[0];if(r)return n.timeOrigin+(r.responseStart||r.unloadEventEnd)}return n.timing.domLoading||n.timing.responseStart||n.timing.unloadEventEnd}(),this.events={},this.addEvent=function(e){if(!t.isStopped){var n={time:new Date,type:"agentEvent",event:e};switch(0===e.e&&(n.documentReadyState=document.readyState,n.isPageVisible=_t(),n.isFullscreen=Ct(),n.network=At()),t.storeAgentEvent(n),e.e){case 2:t.submitReport(e.agentId,void 0);break;case 4:case 5:t.submitReport(e.agentId,e.getCallId)}}};for(var n=window,r=document,i=[[r,"readystatechange",function(){return t.handleDocumentReadyStateChange()}],[r,"visibilitychange",function(){return t.handleVisibilityChange()}],[r,"pageshow",function(){return t.handlePageTransition(!0)}],[r,"pagehide",function(){return t.handlePageTransition(!1)}],[n,"unload",function(){return t.handlePageUnload()}]],o=0,a=i;o=o)break;var v=d&&d.time.getTime()<=o,h=((null==d?void 0:d.time)||i).getTime()-f.time.getTime();u.triesCount++,u.triesTotalDuration+=h,v&&(u.completeTriesCount++,u.completeTriesTotalDuration+=h)}}return u}function Rt(e,n){return e?t(t({},e),n()):void 0}function St(e){for(var t={},n=0,r=Object.keys(e);n1800?_(new Uint8Array(c,0,1800))+"...":_(c))}return s(t(t({},u),{body:c}))}}function Dt(e){if(!e||"incomplete"===e.state||"fail"===e.state)return e;e.componentDurations;var r=n(e,["componentDurations"]),i=Object.keys(e.failedComponents),o=i.length?","+i.join(",")+",":void 0;return t(t({},r),{failedComponents:o})}function Mt(e,n){void 0===n&&(n="_");for(var r=t({},e),i=0,o=Object.keys(e);i=500)return t;throw t}function fn(e,t,n,r,i){void 0===i&&(i=x);var o=i()%(n+1),a=function(e){if("function"==typeof TextEncoder)return(new TextEncoder).encode(e);for(var t=unescape(encodeURI(e)),n=new Uint8Array(t.length),r=0;r=2?function(){return r(this,void 0,void 0,(function(){var e,t,n,r,o;return i(this,(function(i){switch(i.label){case 0:return e=Pn(),t=navigator,n=t[e[3]],(r=t[e[4]])?[4,new Promise((function(t){r[e[5]]((function(e,n){return t(n)}))}))]:[3,2];case 1:return o=i.sent(),[3,4];case 2:return(null==n?void 0:n[e[6]])?[4,n[e[6]]().then((function(e){return e.quota}))]:[3,4];case 3:o=i.sent(),i.label=4;case 4:return o?[2,ot?a0?d.push(C+"("+w+")="+e.getParameter(w)):d.push(C+"="+w)}}for(var A=0,I=tr;A0&&t(n),[2]}}))}))}),30))},s.createOffer().then((function(n){var r=n.sdp;if(!r)return t(-5);for(var i=[],c=0;c=4)?[2,-2]:[4,hr(t=pr())];case 1:return n=r.sent(),null==e||e(),"number"==typeof n?[2,n]:n.length===t.length?[2,-3]:n.length>1?[2,mr(n)]:1===n.length?[2,n[0]]:[2,-1]}var i}))}))}function br(){var e,t,n,r=((n=new Promise((function(n,r){e=n,t=r}))).resolve=e,n.reject=t,n),i=f(fe()?310:410);return h(Promise.race([r,i]).then((function(e){if(void 0!==e)return f(e+100-Date.now())})).then((function(){return-4})),(function(){return gr((function(){return r.resolve(Date.now())}))}))}var wr=["brands","mobile","platform","platformVersion","architecture","bitness","model","uaFullVersion"];function yr(){var e;return r(this,void 0,void 0,(function(){var t,n,o,a=this;return i(this,(function(u){switch(u.label){case 0:return(t=navigator.userAgentData)&&"object"==typeof t?(n={},o=[],"function"!=typeof t.getHighEntropyValues?[3,2]:[4,Promise.all(wr.map((function(e){return r(a,void 0,void 0,(function(){var r,a;return i(this,(function(i){switch(i.label){case 0:return i.trys.push([0,2,,3]),[4,t.getHighEntropyValues([e])];case 1:return void 0!==(r=i.sent()[e])&&(n[e]="string"==typeof r?r:JSON.stringify(r)),[3,3];case 2:if("NotAllowedError"!==(a=i.sent()).name)throw a;return o.push(e),[3,3];case 3:return[2]}}))}))})))]):[2,void 0];case 1:u.sent(),u.label=2;case 2:return[2,{b:t.brands.map((function(e){return{b:e.brand,v:e.version}})),m:t.mobile,p:null!==(e=t.platform)&&void 0!==e?e:null,h:n,nah:o}]}}))}))}function kr(){var e=document.createElement("a").attributionsourceid;return void 0===e?void 0:String(e)}function Er(){var e=this;return h(u(250,-2),(function(){return r(e,void 0,void 0,(function(){var e,t,n;return i(this,(function(r){switch(r.label){case 0:return(null==(e=navigator.mediaDevices)?void 0:e.enumerateDevices)?(t=function(e){return e.slice(0,32).replace(/([,\\])/g,"\\$1")},n=function(e){return[t(e.deviceId),t(e.groupId),{audioinput:"ai",audiooutput:"ao",videoinput:"vi"}[e.kind],t(e.label)].join(",")},[4,e.enumerateDevices()]):[2,-1];case 1:return[2,r.sent().map(n)]}}))}))}))}function Rr(){var e;return null!==(e=navigator.doNotTrack)&&void 0!==e?e:void 0}function Sr(){var e;return null!==(e=window.devicePixelRatio)&&void 0!==e?e:void 0}function Tr(){var e=this;return h(u(75,-3),(function(){return r(e,void 0,void 0,(function(){var e,t,n,r;return i(this,(function(i){switch(i.label){case 0:if(!(e=navigator).requestMediaKeySystemAccess)return[2,-1];i.label=1;case 1:return i.trys.push([1,6,,7]),[4,e.requestMediaKeySystemAccess("org.w3.clearkey",[{initDataTypes:["keyids","webm"],audioCapabilities:["opus","vorbis"].map((function(e){return{contentType:'audio/webm; codecs="'+e+'"'}})),videoCapabilities:["vp9","vp8"].map((function(e){return{contentType:'video/webm; codecs="'+e+'"'}}))}])];case 2:return[4,i.sent().createMediaKeys()];case 3:return t=i.sent(),(n=t.createSession()).sessionId?[3,5]:[4,new Promise((function(e){n.onmessage=e,n.generateRequest("webm",new Uint8Array([1,1,1,1]))}))];case 4:i.sent(),i.label=5;case 5:return[2,n.sessionId];case 6:if("NotSupportedError"===(r=i.sent()).name)return[2,-2];throw r;case 7:return[2]}}))}))}))}function _r(){var e=window.WebAssembly;if(null==e?void 0:e.validate){for(var t=[0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,10],n=0,r=0,i=[[9,1,7,0,65,0,253,15,26,11,0,10,4,110,97,109,101,2,3,1,0,0],[240,67,0,0,0,12,1,10,0,252,2,3,1,1,0,0,110,26,11,161,10],[6,1,4,0,18,0,11,0,10,4,110,97,109,101,2,3,1,0,0],[8,1,6,0,65,0,192,26,11,0,10,4,110,97,109,101,2,3,1,0,0],[7,1,5,0,208,112,26,11,0,10,4,110,97,109,101,2,3,1,0,0]];r=0;--n)if(n%4096==0){var r=Math.random();e.push((t-r)*Math.pow(2,31)|0),t=r}return e}function Ar(){var e;return r(this,void 0,void 0,(function(){var t,n,o,a,u,s,c=this;return i(this,(function(l){switch(l.label){case 0:if(!(t=null===(e=window.crypto)||void 0===e?void 0:e.subtle)||!t.generateKey||!t.exportKey)return[2,-1];n=function(){return r(c,void 0,void 0,(function(){var e,n;return i(this,(function(r){switch(r.label){case 0:return[4,t.generateKey({name:"AES-GCM",length:128},!0,["encrypt"])];case 1:return e=r.sent(),[4,t.exportKey("raw",e)];case 2:return n=r.sent(),[2,new Uint8Array(n)]}}))}))},l.label=1;case 1:return l.trys.push([1,3,,4]),[4,Promise.all([n(),n()])];case 2:for(o=l.sent(),a=new Uint8Array(o[0].length),u=0;u0?e.lastIndexOf(".",n-1):-1,!1===t(e.slice(n+1)))return!1}while(n>=0);return!0}function Mr(e){return[Or(e),Lr(e)]}function Nr(e,t){Pr(t,e,365),function(e,t){var n;try{null===(n=null===localStorage||void 0===localStorage?void 0:localStorage.setItem)||void 0===n||n.call(localStorage,e,t)}catch(r){}}(t,e)}function Lr(e){var t,n;try{return null!==(n=null===(t=null===localStorage||void 0===localStorage?void 0:localStorage.getItem)||void 0===t?void 0:t.call(localStorage,e))&&void 0!==n?n:void 0}catch(r){}}function Br(e,t){return{score:e[0]||e[1]?.999:t[25].value?.99:de()&&pt()?.9:function(){for(var e=[],t=0;t fp.get({ - tag: { - deviceId: androidDeviceId, - deviceType: 'android', - } + environment: { + type: 'android', + deviceId: androidDeviceId, + } })) .then(result => { document.write(result.visitorId); @@ -33,7 +33,6 @@ document.write(e); } ) - diff --git a/fpjs-pro/src/main/java/com/fingerprintjs/android/fpjs_pro/FPJSProClient.kt b/fpjs-pro/src/main/java/com/fingerprintjs/android/fpjs_pro/FPJSProClient.kt index f19b4a8..5ffacca 100644 --- a/fpjs-pro/src/main/java/com/fingerprintjs/android/fpjs_pro/FPJSProClient.kt +++ b/fpjs-pro/src/main/java/com/fingerprintjs/android/fpjs_pro/FPJSProClient.kt @@ -2,7 +2,9 @@ package com.fingerprintjs.android.fpjs_pro import android.content.Context -import com.fingerprintjs.android.fingerprint.FingerprinterFactory +import com.fingerprintjs.android.fpjs_pro.device_id_providers.AndroidIdProvider +import com.fingerprintjs.android.fpjs_pro.device_id_providers.GsfIdProvider +import com.fingerprintjs.android.fpjs_pro.device_id_providers.MediaDrmIdProvider interface FPJSProClient { @@ -34,11 +36,16 @@ class FPJSProFactory( } fun createInterface(configuration: Configuration = Configuration("")): FPJSProInterface { - val fingerprinter = FingerprinterFactory.getInstance( - applicationContext, - com.fingerprintjs.android.fingerprint.Configuration(3) + val contentResolver = applicationContext.contentResolver!! + val androidIdProvider = AndroidIdProvider(contentResolver) + val gsfIdProvider = GsfIdProvider(contentResolver) + val mediaDrmIdProvider = MediaDrmIdProvider() + return FPJSProInterface( + configuration.apiToken, + configuration.endpointUrl, + androidIdProvider, + gsfIdProvider, + mediaDrmIdProvider ) - - return FPJSProInterface(fingerprinter, configuration.apiToken, configuration.endpointUrl) } } diff --git a/fpjs-pro/src/main/java/com/fingerprintjs/android/fpjs_pro/FPJSProClientImpl.kt b/fpjs-pro/src/main/java/com/fingerprintjs/android/fpjs_pro/FPJSProClientImpl.kt index 144ac62..573b4a1 100644 --- a/fpjs-pro/src/main/java/com/fingerprintjs/android/fpjs_pro/FPJSProClientImpl.kt +++ b/fpjs-pro/src/main/java/com/fingerprintjs/android/fpjs_pro/FPJSProClientImpl.kt @@ -10,9 +10,10 @@ import android.webkit.ConsoleMessage import android.webkit.JsResult import android.webkit.WebChromeClient import android.webkit.WebView -import com.fingerprintjs.android.fingerprint.Configuration -import com.fingerprintjs.android.fingerprint.FingerprinterFactory -import com.fingerprintjs.android.fingerprint.tools.executeSafe +import com.fingerprintjs.android.fpjs_pro.device_id_providers.AndroidIdProvider +import com.fingerprintjs.android.fpjs_pro.device_id_providers.GsfIdProvider +import com.fingerprintjs.android.fpjs_pro.device_id_providers.MediaDrmIdProvider +import com.fingerprintjs.android.fpjs_pro.tools.executeSafe import java.lang.ref.WeakReference import java.util.concurrent.Executors @@ -36,8 +37,10 @@ class FPJSProClientImpl( } private fun init(listener: (String) -> (Unit)) { - val fingerprinter = - FingerprinterFactory.getInstance(applicationContext, Configuration(3)) + val contentResolver = applicationContext.contentResolver!! + val androidIdProvider = AndroidIdProvider(contentResolver) + val gsfIdProvider = GsfIdProvider(contentResolver) + val mediaDrmIdProvider = MediaDrmIdProvider() webViewWeakRef.get()?.webChromeClient = object : WebChromeClient() { @@ -66,7 +69,12 @@ class FPJSProClientImpl( webViewWeakRef.get()?.settings?.defaultTextEncodingName = "utf-8" webViewWeakRef.get() ?.addJavascriptInterface( - FPJSProInterface(fingerprinter, apiToken, endpointUrl), + FPJSProInterface( + apiToken, endpointUrl, + androidIdProvider, + gsfIdProvider, + mediaDrmIdProvider + ), JS_INTERFACE_NAME ) } diff --git a/fpjs-pro/src/main/java/com/fingerprintjs/android/fpjs_pro/FPJSProInterface.kt b/fpjs-pro/src/main/java/com/fingerprintjs/android/fpjs_pro/FPJSProInterface.kt index b474c12..db9c396 100644 --- a/fpjs-pro/src/main/java/com/fingerprintjs/android/fpjs_pro/FPJSProInterface.kt +++ b/fpjs-pro/src/main/java/com/fingerprintjs/android/fpjs_pro/FPJSProInterface.kt @@ -2,30 +2,33 @@ package com.fingerprintjs.android.fpjs_pro import android.webkit.JavascriptInterface -import com.fingerprintjs.android.fingerprint.Fingerprinter -import java.util.concurrent.CountDownLatch +import com.fingerprintjs.android.fpjs_pro.device_id_providers.AndroidIdProvider +import com.fingerprintjs.android.fpjs_pro.device_id_providers.GsfIdProvider +import com.fingerprintjs.android.fpjs_pro.device_id_providers.MediaDrmIdProvider +import com.fingerprintjs.android.fpjs_pro.tools.executeSafe class FPJSProInterface internal constructor( - private val fingerprinter: Fingerprinter, private val apiToken: String, private val endpointUrl: String, + private val androidIdProvider: AndroidIdProvider, + private val gsfIdProvider: GsfIdProvider, + private val mediaDrmIdProvider: MediaDrmIdProvider ) { @JavascriptInterface - fun getDeviceId(): String { - val countDownLatch = CountDownLatch(1) - var result = "" - fingerprinter.getDeviceId { - result = it.deviceId - countDownLatch.countDown() - } - countDownLatch.await() - return result - } + fun getDeviceId(): String = nativeDeviceId() @JavascriptInterface fun getEndpoint(): String = endpointUrl @JavascriptInterface fun getApiToken(): String = apiToken + + private fun nativeDeviceId(): String { + val mediaDrmId = mediaDrmIdProvider.getMediaDrmId() + val gsfId = gsfIdProvider.getGsfAndroidId() + val androidId = androidIdProvider.getAndroidId() + + return gsfId ?: mediaDrmId ?: androidId + } } \ No newline at end of file diff --git a/fpjs-pro/src/main/java/com/fingerprintjs/android/fpjs_pro/device_id_providers/AndroidIdProvider.kt b/fpjs-pro/src/main/java/com/fingerprintjs/android/fpjs_pro/device_id_providers/AndroidIdProvider.kt new file mode 100644 index 0000000..924f24b --- /dev/null +++ b/fpjs-pro/src/main/java/com/fingerprintjs/android/fpjs_pro/device_id_providers/AndroidIdProvider.kt @@ -0,0 +1,22 @@ +package com.fingerprintjs.android.fpjs_pro.device_id_providers + + +import android.annotation.SuppressLint +import android.content.ContentResolver +import android.provider.Settings +import com.fingerprintjs.android.fpjs_pro.tools.executeSafe + + +class AndroidIdProvider( + private val contentResolver: ContentResolver +) { + @SuppressLint("HardwareIds") + fun getAndroidId(): String { + return executeSafe({ + Settings.Secure.getString( + contentResolver, + Settings.Secure.ANDROID_ID + ) + }, "") + } +} \ No newline at end of file diff --git a/fpjs-pro/src/main/java/com/fingerprintjs/android/fpjs_pro/device_id_providers/GsfIdProvider.kt b/fpjs-pro/src/main/java/com/fingerprintjs/android/fpjs_pro/device_id_providers/GsfIdProvider.kt new file mode 100644 index 0000000..f3b5c9a --- /dev/null +++ b/fpjs-pro/src/main/java/com/fingerprintjs/android/fpjs_pro/device_id_providers/GsfIdProvider.kt @@ -0,0 +1,49 @@ +package com.fingerprintjs.android.fpjs_pro.device_id_providers + + +import android.content.ContentResolver +import android.net.Uri +import com.fingerprintjs.android.fpjs_pro.tools.executeSafe + + +class GsfIdProvider( + private val contentResolver: ContentResolver +) { + + fun getGsfAndroidId(): String? { + return executeSafe( + { getGsfId() }, null + ) + } + + private fun getGsfId(): String? { + val URI = Uri.parse(URI_GSF_CONTENT_PROVIDER) + val params = arrayOf(ID_KEY) + return try { + val cursor = contentResolver + .query(URI, null, null, params, null) + + if (cursor == null) { + return null + } + + if (!cursor.moveToFirst() || cursor.columnCount < 2) { + cursor.close() + return null + } + try { + val result = java.lang.Long.toHexString(cursor.getString(1).toLong()) + cursor.close() + result + } catch (e: NumberFormatException) { + cursor.close() + null + } + } catch (e: Exception) { + null + } + } +} + +private const val URI_GSF_CONTENT_PROVIDER = "content://com.google.android.gsf.gservices" +private const val ID_KEY = "android_id" \ No newline at end of file diff --git a/fpjs-pro/src/main/java/com/fingerprintjs/android/fpjs_pro/device_id_providers/MediaDrmIdProvider.kt b/fpjs-pro/src/main/java/com/fingerprintjs/android/fpjs_pro/device_id_providers/MediaDrmIdProvider.kt new file mode 100644 index 0000000..c5a4e96 --- /dev/null +++ b/fpjs-pro/src/main/java/com/fingerprintjs/android/fpjs_pro/device_id_providers/MediaDrmIdProvider.kt @@ -0,0 +1,45 @@ +package com.fingerprintjs.android.fpjs_pro.device_id_providers + + +import android.media.MediaDrm +import android.os.Build +import com.fingerprintjs.android.fpjs_pro.tools.executeSafe +import java.security.MessageDigest +import java.util.UUID + + +class MediaDrmIdProvider { + fun getMediaDrmId() = executeSafe({ + mediaDrmId() + }, null) + + private fun mediaDrmId(): String { + val widevineUUID = UUID(WIDEWINE_UUID_MOST_SIG_BITS, WIDEWINE_UUID_LEAST_SIG_BITS) + val wvDrm: MediaDrm? + + wvDrm = MediaDrm(widevineUUID) + val mivevineId = wvDrm.getPropertyByteArray(MediaDrm.PROPERTY_DEVICE_UNIQUE_ID) + releaseMediaDRM(wvDrm) + val md: MessageDigest = MessageDigest.getInstance("SHA-256") + md.update(mivevineId) + + return md.digest().toHexString() + } + + private fun releaseMediaDRM(drmObject: MediaDrm) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + drmObject.close() + } else { + drmObject.release() + } + } +} + +private fun ByteArray.toHexString(): String { + return this.joinToString("") { + java.lang.String.format("%02x", it) + } +} + +private const val WIDEWINE_UUID_MOST_SIG_BITS = -0x121074568629b532L +private const val WIDEWINE_UUID_LEAST_SIG_BITS = -0x5c37d8232ae2de13L \ No newline at end of file diff --git a/fpjs-pro/src/main/java/com/fingerprintjs/android/fpjs_pro/tools/ExceptionSafeExecutor.kt b/fpjs-pro/src/main/java/com/fingerprintjs/android/fpjs_pro/tools/ExceptionSafeExecutor.kt new file mode 100644 index 0000000..e2cb4f9 --- /dev/null +++ b/fpjs-pro/src/main/java/com/fingerprintjs/android/fpjs_pro/tools/ExceptionSafeExecutor.kt @@ -0,0 +1,13 @@ +package com.fingerprintjs.android.fpjs_pro.tools + + +import java.lang.Exception + + +fun executeSafe(code: () -> T, defaultValue: T): T { + return try { + code() + } catch (exception: Exception) { + defaultValue + } +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index b259e1a..c6e404b 100644 --- a/settings.gradle +++ b/settings.gradle @@ -3,9 +3,6 @@ dependencyResolutionManagement { repositories { google() mavenCentral() - maven { - url "https://jitpack.io" - } } } rootProject.name = "fingerprintjs-pro-android-webview" From b716cbee38cb03eeb728825185a2a9bd040e70dc Mon Sep 17 00:00:00 2001 From: Alexey-Verkhovsky Date: Thu, 16 Sep 2021 15:03:01 +0300 Subject: [PATCH 03/10] Correct versioning --- app/build.gradle | 19 +++++++++---------- fpjs-pro/build.gradle | 17 +++++++++-------- gradle.properties | 25 +++++-------------------- 3 files changed, 23 insertions(+), 38 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 99aa345..40f1d56 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -4,15 +4,15 @@ plugins { } android { - compileSdk 30 + compileSdk 31 buildToolsVersion "30.0.3" defaultConfig { applicationId "com.fingerprintjs.android.fpjs_pro_demo" minSdk 21 - targetSdk 30 - versionCode 1 - versionName "1.0" + targetSdk 31 + versionCode Integer.parseInt(project.VERSION_CODE) + versionName project.VERSION_NAME testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } @@ -23,12 +23,11 @@ android { proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - kotlinOptions { - jvmTarget = '1.8' + + applicationVariants.all { variant -> + variant.outputs.all { + outputFileName = "FPJS-Pro-Playground-${variant.name}-${variant.versionName}.apk" + } } } diff --git a/fpjs-pro/build.gradle b/fpjs-pro/build.gradle index 92a426e..5a950c6 100644 --- a/fpjs-pro/build.gradle +++ b/fpjs-pro/build.gradle @@ -13,8 +13,8 @@ android { defaultConfig { minSdkVersion 21 targetSdkVersion 31 - versionCode 1 - versionName "1.0" + versionCode Integer.parseInt(project.VERSION_CODE) + versionName project.VERSION_NAME } buildTypes { @@ -23,12 +23,13 @@ android { proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - kotlinOptions { - jvmTarget = '1.8' + + libraryVariants.all { variant -> + variant.outputs.all { output -> + if (outputFile != null && outputFileName.endsWith('.aar')) { + outputFileName = "fpjs-pro-${defaultConfig.versionName}-${variant.name}.aar" + } + } } } diff --git a/gradle.properties b/gradle.properties index 98bed16..c7e2267 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,21 +1,6 @@ -# Project-wide Gradle settings. -# IDE (e.g. Android Studio) users: -# Gradle settings configured through the IDE *will override* -# any settings specified in this file. -# For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 -# When configured, Gradle will run in incubating parallel mode. -# This option should only be used with decoupled projects. More details, visit -# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true -# AndroidX package structure to make it clearer which packages are bundled with the -# Android operating system, and which are packaged with your app"s APK -# https://developer.android.com/topic/libraries/support-library/androidx-rn -android.useAndroidX=true -# Automatically convert third-party libraries to use AndroidX android.enableJetifier=true -# Kotlin code style for this project: "official" or "obsolete": -kotlin.code.style=official \ No newline at end of file +kotlin.code.style=official +android.useAndroidX=true +org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8 +VERSION_NAME=1.0.0 +VERSION_CODE=3 \ No newline at end of file From 98eb7996dea0c3a124e799b79c5cb2dc68597463 Mon Sep 17 00:00:00 2001 From: Alexey-Verkhovsky Date: Thu, 16 Sep 2021 15:14:00 +0300 Subject: [PATCH 04/10] Add github actions workflow --- .github/workflows/blank.yml | 46 ++++++++++++++++++++++++++++++++++++ app/build.gradle | 12 ++++++++++ app/release.jks | Bin 0 -> 2289 bytes 3 files changed, 58 insertions(+) create mode 100644 .github/workflows/blank.yml create mode 100644 app/release.jks diff --git a/.github/workflows/blank.yml b/.github/workflows/blank.yml new file mode 100644 index 0000000..2b712d0 --- /dev/null +++ b/.github/workflows/blank.yml @@ -0,0 +1,46 @@ +name: Test + +on: + push: + branches: [ main, develop ] + pull_request: + paths-ignore: + - '**.md' + - app/** + +env: + KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }} + RELEASE_SIGN_KEY_ALIAS: ${{ secrets.RELEASE_SIGN_KEY_ALIAS }} + RELEASE_SIGN_KEY_PASSWORD: ${{ secrets.RELEASE_SIGN_KEY_PASSWORD }} + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Make gradlew executable + run: chmod +x ./gradlew + + - name: Lint + run: ./gradlew fpjs-pro:lint + + - name: Test + run: ./gradlew fpjs-pro:test + + - name: Build library + run: ./gradlew fpjs-pro:assembleRelease + + - name: Save library to artifacts + uses: actions/upload-artifact@v2 + with: + path: fpjs-pro/build/outputs/aar/* + + - name: Build App + run: ./gradlew app:assembleRelease + + - name: Save application to artifacts + uses: actions/upload-artifact@v2 + with: + path: app/build/outputs/apk/release/* \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 40f1d56..ee283db 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -17,6 +17,15 @@ android { testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } + signingConfigs { + release { + storeFile file("release.jks") + storePassword System.getenv('KEYSTORE_PASSWORD') + keyAlias System.getenv('RELEASE_SIGN_KEY_ALIAS') + keyPassword System.getenv('RELEASE_SIGN_KEY_PASSWORD') + } + } + buildTypes { release { minifyEnabled false @@ -32,6 +41,9 @@ android { } dependencies { + debugImplementation fileTree(dir: "../fpjs-pro/build/outputs/aar/", include: ["*$project.VERSION_NAME-debug.aar"]) + releaseImplementation fileTree(dir: "../fpjs-pro/build/outputs/aar/", include: ["*$project.VERSION_NAME-release.aar"]) + implementation project(":fpjs-pro") implementation 'androidx.core:core-ktx:1.6.0' implementation 'androidx.appcompat:appcompat:1.3.1' diff --git a/app/release.jks b/app/release.jks new file mode 100644 index 0000000000000000000000000000000000000000..bd521e94a495f248e9d7eaef5e664184451bf77c GIT binary patch literal 2289 zcmc&#`8U)J7oYFU*hUP7Y>jP1sbR*xq(T^m$_y-aJ z)Zhp-jT}lo6G29YkYjfebmz3ZMi58cS<&bT}Qf>LF@9U)Y`hvpIu9_eQ*Wj^?|7UIMkp%83j~?;u@Ed1!F^syl3u>LQ zG0@DlH|6-om@ke(_`;>szn)j>2RVJqIG2`|(DYstNrc2aX9$6lfE?z$Gv+c7CUuEMNx5^05 zqO!_t&&#Bd`XxT_1au1Iy1^e(?hV$-wp_DczMzs5>Q4Di4SO+5SCb6_4?AS)j*R_S znRcq}+PkN6+1_RP96w_N733(}U3f%Svc5dUJPC>_^C3JvYSr|jM%Y;Igv5{;sdLis zJ<4ZWT0nyphz-w>oS`cH7>mUXJ^pGpjW+mm-dfNWwt^EmK124LmFr2q-93ofr5PaI z+u9Uh$hvs^YW1GD%HT|J3Di4$ZhNxu@5Zr9Uno3!HT~#M;@XuOcJ|4PLjz{_IXdnt z4%NgZ_X@2U(p*aYvLJ~Wvp0}3qieF>vnyF&$2N)k&Cnpo1pX_Q;D3;K)Uky;_j!Vt zO*NXSoO`<0=GFqMKmLs9DXrdD&T8%DiwnxckGc(s6BBs~Z%-P;+i72XG(?K<@9`;m zYJR!3bTfNX2WanEN=fPfH=b4m5XhhKQ735|+c7Gwt$Opn%(4%~dN zbhbIa!7GnA zvCDa`_2hU15xhakfU~G|kKevk=ue1BuF4pGpSs@gy&{Gsn@UdQAjSwSeU}4wrbkllqpY(=q76e^fte3bKuY)HpMi zaLKzklt`G*?dFN{?Kwc#5>%UGZEGxBenAM zOJGY*_IHVnPk&}*vMWT@S3@(U%_(f-`)O4fJ;L2e^`>rnn2bu9yWw|zKb;rL-D2NU zwV|&`J6^ADhmFe|M}vgl@@akc5yHdBUX^8iXP^47PMueW4G11j{7mM>D2e#mH`q{{ zi6n8It0m%S$%k!`F=}625<2znls^c^&OoRHWv?YQv%uq-@q5ZC{0hJY}04pqaw* zh%0N#IurA;<-E=$XIyC0BeCvl8%uq&h2b{uJMKbC>P;w?aZO>kc7x`TgI0EsF>QQQ z&LPHkax>fMM2=i?0Qr58hVvI{t}5YI;EO8!R+YqDamFF;qYdWMU}^@EhmZ5K5>#aP z`^7Rc?cvS1D5nJ#fmwPeEei4YyI`-ItJ27-*zpNC}1sPAP|g0WcUEk`PVAhzW{lv2d(4F#r%10AUiaq8JfD z2oWlX025uYk{I~!Ko}ux7aAHAMhS|*O6*+J9ZCoxWEB|XcjhbwtB8^R&A<>+HbG%$ z$uuf0C@j+6RmCpMPy2u6q6i_2Fn<~)$RDeKk^5Z^K}cGJl4HoRDsE(2NFaqC5fY10 zkrmU$V0E!Ow&V0X<>0y)gB=2+|6k(&-5?WC`?q8}4+X*m;2;bWfPt9+0P1g^7$~^~ z%ZJsLb< zlC~wHgI7ajm8eGsS!P5e{~}c&Jyo7BCph9)-Iz%0tF=p5(DMC&d&ew1wd?rJIUz67 z%_y0^dBj0uROO`3Mm4wq&=TNj^wPBC96HWbN!g_F3V~rzPZ%4 zYO6VF&l9ij3^4`g$#42r;=z~VHKXO7+;4ZM?bDZvN)CL15m7m*p#%p*01!~6ic!WO zcZQ4%dzbt|drsc-n-ws#9<$2g{#(SIz1tBH0L6sC(uwllz$cBLRB(B9 zrensUe_V)X4R<|2!3MIof^V?N$F7FqUwT5QxYnFNAv9;@SZ1F(-^>$|?fOWI72Nf6 z%6ppFnRbi=dspJ-cpzy%+sh)lVk=Mj`BfK^yvw<&!o4Kr%F61Qxe;KaW!}#VheK>G z4#4i4!wttHg;1+&7Lk7A#kTg!d~t4Fp#KS$W?cGEaoF%_eEC!lfPh|><#+J~jU56w zauJI31`w@LgS~!Q54ztJxM$qqX4IXNZ_CE@+-;X%wvJrxzooyw&#mM!KoI6y79~H+ zO*f8PF)c#4j{out#O?mIk}rNL0u)qs Date: Thu, 16 Sep 2021 15:20:40 +0300 Subject: [PATCH 05/10] Update workflow --- .github/workflows/blank.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/blank.yml b/.github/workflows/blank.yml index 2b712d0..50e5944 100644 --- a/.github/workflows/blank.yml +++ b/.github/workflows/blank.yml @@ -25,10 +25,7 @@ jobs: - name: Lint run: ./gradlew fpjs-pro:lint - - - name: Test - run: ./gradlew fpjs-pro:test - + - name: Build library run: ./gradlew fpjs-pro:assembleRelease From 53e5b72e3fdff8d73defa9f3f2856e1caff81584 Mon Sep 17 00:00:00 2001 From: Alexey-Verkhovsky Date: Thu, 16 Sep 2021 15:32:33 +0300 Subject: [PATCH 06/10] Remove reduntant line from build.gradle --- app/build.gradle | 1 - build.gradle | 2 +- fpjs-pro/build.gradle | 1 + 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index ee283db..722ab3e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -44,7 +44,6 @@ dependencies { debugImplementation fileTree(dir: "../fpjs-pro/build/outputs/aar/", include: ["*$project.VERSION_NAME-debug.aar"]) releaseImplementation fileTree(dir: "../fpjs-pro/build/outputs/aar/", include: ["*$project.VERSION_NAME-release.aar"]) - implementation project(":fpjs-pro") implementation 'androidx.core:core-ktx:1.6.0' implementation 'androidx.appcompat:appcompat:1.3.1' implementation 'com.google.android.material:material:1.4.0' diff --git a/build.gradle b/build.gradle index 1fbde18..37c6849 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = '1.4.30' + ext.kotlin_version = '1.5.10' repositories { google() mavenCentral() diff --git a/fpjs-pro/build.gradle b/fpjs-pro/build.gradle index 5a950c6..536f2ee 100644 --- a/fpjs-pro/build.gradle +++ b/fpjs-pro/build.gradle @@ -34,6 +34,7 @@ android { } dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation 'androidx.core:core-ktx:1.6.0' implementation 'androidx.appcompat:appcompat:1.3.1' } \ No newline at end of file From 5872dc81d1141f27ab6235299ae8ee1e463518b6 Mon Sep 17 00:00:00 2001 From: Alexey-Verkhovsky Date: Thu, 16 Sep 2021 18:11:04 +0300 Subject: [PATCH 07/10] Change publishing properties --- fpjs-pro/build.gradle | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/fpjs-pro/build.gradle b/fpjs-pro/build.gradle index 536f2ee..fa735fb 100644 --- a/fpjs-pro/build.gradle +++ b/fpjs-pro/build.gradle @@ -4,7 +4,15 @@ plugins { id 'maven-publish' } -group='com.github.fingerprintjs' +publishing { + publications { + mavenJava(MavenPublication) { + groupId = 'com.github.fingerprintjs' + artifactId = "fpjs-pro" + version = '1.0.0' + } + } +} android { compileSdkVersion 31 @@ -31,6 +39,7 @@ android { } } } + } dependencies { From 83e5ea267705d9271c1edbbd5a432b23f92ebd4a Mon Sep 17 00:00:00 2001 From: Alexey-Verkhovsky Date: Fri, 17 Sep 2021 10:25:03 +0300 Subject: [PATCH 08/10] Import library as project --- app/build.gradle | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 722ab3e..1a3505d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -41,9 +41,7 @@ android { } dependencies { - debugImplementation fileTree(dir: "../fpjs-pro/build/outputs/aar/", include: ["*$project.VERSION_NAME-debug.aar"]) - releaseImplementation fileTree(dir: "../fpjs-pro/build/outputs/aar/", include: ["*$project.VERSION_NAME-release.aar"]) - + implementation project(":fpjs-pro") implementation 'androidx.core:core-ktx:1.6.0' implementation 'androidx.appcompat:appcompat:1.3.1' implementation 'com.google.android.material:material:1.4.0' From e263764ac0b75279ec53e4f8c0fd2e08b8216000 Mon Sep 17 00:00:00 2001 From: Alexey-Verkhovsky Date: Fri, 17 Sep 2021 11:06:01 +0300 Subject: [PATCH 09/10] Set artifact name explicitly --- fpjs-pro/build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/fpjs-pro/build.gradle b/fpjs-pro/build.gradle index fa735fb..25f572e 100644 --- a/fpjs-pro/build.gradle +++ b/fpjs-pro/build.gradle @@ -10,6 +10,7 @@ publishing { groupId = 'com.github.fingerprintjs' artifactId = "fpjs-pro" version = '1.0.0' + artifact("$buildDir/outputs/aar/fpjs-pro-1.0.0-release.aar") } } } From fc806c3ff1c8d16b2493378b410aa8f3117d6d1f Mon Sep 17 00:00:00 2001 From: Alexey Verkhovsky <72796626+Alexey-Verkhovsky@users.noreply.github.com> Date: Fri, 17 Sep 2021 11:23:22 +0300 Subject: [PATCH 10/10] Update README.md --- README.md | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 0c67a5b..61e1f91 100644 --- a/README.md +++ b/README.md @@ -37,15 +37,11 @@ allprojects { }} ``` -### 2. Download the latest [release](https://github.com/fingerprintjs/fingerprintjs-pro-android-integrations/releases) to the `libs` folder of your application. - - -### 3. Add a dependency to your `build.gradle` file +### 2. Add a dependency to your `build.gradle` file ```gradle dependencies { - implementation "com.github.fingerprintjs:fingerprint-android:1.2" - implementation files("libs/fpjs-pro-0.1.0-release.aar") + implementation 'com.github.fingerprintjs:fingerprintjs-pro-android-integrations:v1.0.0-rc5' // If you use Java for you project, add also this line implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"} @@ -59,10 +55,11 @@ buildscript { ``` *Note: You can find your Kotlin version in Android Studio > File > Settings > Languages & Frameworks > Kotlin.* -### 4. Get the visitor identifier +### 3. Get the visitor identifier Retrieve the visitor identifier using browser token. You can find your [browser token](https://dev.fingerprintjs.com/docs) in your [dashboard](https://dashboard.fingerprintjs.com/subscriptions/). +#### 3.1 Kotlin example ```kotlin // Initialization @@ -83,6 +80,26 @@ fpjsClient.getVisitorId { visitorId -> } ``` +#### 3.2 Java example + +```java + +FPJSProFactory factory = new FPJSProFactory(this.getApplicationContext()); +Configuration configuration = new Configuration("BROWSER_TOKEN", Configuration.Region.US, Configuration.Region.US.getEndpointUrl()); +// Or you can choose Region.EU + +FPJSProClient fpjsClient = factory.createInstance( + configuration +); + +fpjsClient.getVisitorId(new Function1() { + @Override + public Unit invoke(String visitorId) { + // Use visitorId + return null; + } +}); +``` *❗ Important: Due to WebView limitations the initialization of the client is performed on the UI-thread, consider call `getVisitorId()` while the screen is static.*