337 skills found · Page 4 of 12
databrickslabs / Delta OmsDeltaOMS is a solution that help build a centralized repository of Delta Transaction logs and associated operational metrics/statistics for your Delta Lakehouse. Unity Catalog supported in the v0.7.0-rc1 release.Documentation here - https://databrickslabs.github.io/delta-oms/v0.7.0-rc1/
avivl / Cloud Sre AgentAn autonomous SRE agent that monitors cloud logs across multiple platforms, leveraging AI models from various providers to detect anomalies, perform root cause analysis, and automate remediation by creating GitHub Pull Requests.
vohidjon123 / Google(function(sttc){/* Copyright The Closure Library Authors. SPDX-License-Identifier: Apache-2.0 */ var n;function aa(a){var b=0;return function(){return b<a.length?{done:!1,value:a[b++]}:{done:!0}}}var ba="function"==typeof Object.defineProperties?Object.defineProperty:function(a,b,c){if(a==Array.prototype||a==Object.prototype)return a;a[b]=c.value;return a}; function ca(a){a=["object"==typeof globalThis&&globalThis,a,"object"==typeof window&&window,"object"==typeof self&&self,"object"==typeof global&&global];for(var b=0;b<a.length;++b){var c=a[b];if(c&&c.Math==Math)return c}throw Error("Cannot find global object");}var da=ca(this),ea="function"===typeof Symbol&&"symbol"===typeof Symbol("x"),p={},fa={};function r(a,b){var c=fa[b];if(null==c)return a[b];c=a[c];return void 0!==c?c:a[b]} function ha(a,b,c){if(b)a:{var d=a.split(".");a=1===d.length;var e=d[0],f;!a&&e in p?f=p:f=da;for(e=0;e<d.length-1;e++){var g=d[e];if(!(g in f))break a;f=f[g]}d=d[d.length-1];c=ea&&"es6"===c?f[d]:null;b=b(c);null!=b&&(a?ba(p,d,{configurable:!0,writable:!0,value:b}):b!==c&&(void 0===fa[d]&&(a=1E9*Math.random()>>>0,fa[d]=ea?da.Symbol(d):"$jscp$"+a+"$"+d),ba(f,fa[d],{configurable:!0,writable:!0,value:b})))}} ha("Symbol",function(a){function b(f){if(this instanceof b)throw new TypeError("Symbol is not a constructor");return new c(d+(f||"")+"_"+e++,f)}function c(f,g){this.h=f;ba(this,"description",{configurable:!0,writable:!0,value:g})}if(a)return a;c.prototype.toString=function(){return this.h};var d="jscomp_symbol_"+(1E9*Math.random()>>>0)+"_",e=0;return b},"es6"); ha("Symbol.iterator",function(a){if(a)return a;a=(0,p.Symbol)("Symbol.iterator");for(var b="Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array".split(" "),c=0;c<b.length;c++){var d=da[b[c]];"function"===typeof d&&"function"!=typeof d.prototype[a]&&ba(d.prototype,a,{configurable:!0,writable:!0,value:function(){return ia(aa(this))}})}return a},"es6"); function ia(a){a={next:a};a[r(p.Symbol,"iterator")]=function(){return this};return a}function ja(a){return a.raw=a}function u(a){var b="undefined"!=typeof p.Symbol&&r(p.Symbol,"iterator")&&a[r(p.Symbol,"iterator")];return b?b.call(a):{next:aa(a)}}function ka(a){if(!(a instanceof Array)){a=u(a);for(var b,c=[];!(b=a.next()).done;)c.push(b.value);a=c}return a}function la(a,b){return Object.prototype.hasOwnProperty.call(a,b)} var ma=ea&&"function"==typeof r(Object,"assign")?r(Object,"assign"):function(a,b){for(var c=1;c<arguments.length;c++){var d=arguments[c];if(d)for(var e in d)la(d,e)&&(a[e]=d[e])}return a};ha("Object.assign",function(a){return a||ma},"es6");var na="function"==typeof Object.create?Object.create:function(a){function b(){}b.prototype=a;return new b},oa; if(ea&&"function"==typeof Object.setPrototypeOf)oa=Object.setPrototypeOf;else{var pa;a:{var qa={a:!0},ra={};try{ra.__proto__=qa;pa=ra.a;break a}catch(a){}pa=!1}oa=pa?function(a,b){a.__proto__=b;if(a.__proto__!==b)throw new TypeError(a+" is not extensible");return a}:null}var sa=oa; function v(a,b){a.prototype=na(b.prototype);a.prototype.constructor=a;if(sa)sa(a,b);else for(var c in b)if("prototype"!=c)if(Object.defineProperties){var d=Object.getOwnPropertyDescriptor(b,c);d&&Object.defineProperty(a,c,d)}else a[c]=b[c];a.Ub=b.prototype}function ta(){for(var a=Number(this),b=[],c=a;c<arguments.length;c++)b[c-a]=arguments[c];return b} ha("Promise",function(a){function b(g){this.h=0;this.j=void 0;this.i=[];this.G=!1;var h=this.l();try{g(h.resolve,h.reject)}catch(k){h.reject(k)}}function c(){this.h=null}function d(g){return g instanceof b?g:new b(function(h){h(g)})}if(a)return a;c.prototype.i=function(g){if(null==this.h){this.h=[];var h=this;this.j(function(){h.m()})}this.h.push(g)};var e=da.setTimeout;c.prototype.j=function(g){e(g,0)};c.prototype.m=function(){for(;this.h&&this.h.length;){var g=this.h;this.h=[];for(var h=0;h<g.length;++h){var k= g[h];g[h]=null;try{k()}catch(l){this.l(l)}}}this.h=null};c.prototype.l=function(g){this.j(function(){throw g;})};b.prototype.l=function(){function g(l){return function(m){k||(k=!0,l.call(h,m))}}var h=this,k=!1;return{resolve:g(this.P),reject:g(this.m)}};b.prototype.P=function(g){if(g===this)this.m(new TypeError("A Promise cannot resolve to itself"));else if(g instanceof b)this.U(g);else{a:switch(typeof g){case "object":var h=null!=g;break a;case "function":h=!0;break a;default:h=!1}h?this.O(g):this.A(g)}}; b.prototype.O=function(g){var h=void 0;try{h=g.then}catch(k){this.m(k);return}"function"==typeof h?this.ga(h,g):this.A(g)};b.prototype.m=function(g){this.C(2,g)};b.prototype.A=function(g){this.C(1,g)};b.prototype.C=function(g,h){if(0!=this.h)throw Error("Cannot settle("+g+", "+h+"): Promise already settled in state"+this.h);this.h=g;this.j=h;2===this.h&&this.R();this.H()};b.prototype.R=function(){var g=this;e(function(){if(g.N()){var h=da.console;"undefined"!==typeof h&&h.error(g.j)}},1)};b.prototype.N= function(){if(this.G)return!1;var g=da.CustomEvent,h=da.Event,k=da.dispatchEvent;if("undefined"===typeof k)return!0;"function"===typeof g?g=new g("unhandledrejection",{cancelable:!0}):"function"===typeof h?g=new h("unhandledrejection",{cancelable:!0}):(g=da.document.createEvent("CustomEvent"),g.initCustomEvent("unhandledrejection",!1,!0,g));g.promise=this;g.reason=this.j;return k(g)};b.prototype.H=function(){if(null!=this.i){for(var g=0;g<this.i.length;++g)f.i(this.i[g]);this.i=null}};var f=new c; b.prototype.U=function(g){var h=this.l();g.ia(h.resolve,h.reject)};b.prototype.ga=function(g,h){var k=this.l();try{g.call(h,k.resolve,k.reject)}catch(l){k.reject(l)}};b.prototype.then=function(g,h){function k(t,y){return"function"==typeof t?function(F){try{l(t(F))}catch(z){m(z)}}:y}var l,m,q=new b(function(t,y){l=t;m=y});this.ia(k(g,l),k(h,m));return q};b.prototype.catch=function(g){return this.then(void 0,g)};b.prototype.ia=function(g,h){function k(){switch(l.h){case 1:g(l.j);break;case 2:h(l.j); break;default:throw Error("Unexpected state: "+l.h);}}var l=this;null==this.i?f.i(k):this.i.push(k);this.G=!0};b.resolve=d;b.reject=function(g){return new b(function(h,k){k(g)})};b.race=function(g){return new b(function(h,k){for(var l=u(g),m=l.next();!m.done;m=l.next())d(m.value).ia(h,k)})};b.all=function(g){var h=u(g),k=h.next();return k.done?d([]):new b(function(l,m){function q(F){return function(z){t[F]=z;y--;0==y&&l(t)}}var t=[],y=0;do t.push(void 0),y++,d(k.value).ia(q(t.length-1),m),k=h.next(); while(!k.done)})};return b},"es6");ha("Array.prototype.find",function(a){return a?a:function(b,c){a:{var d=this;d instanceof String&&(d=String(d));for(var e=d.length,f=0;f<e;f++){var g=d[f];if(b.call(c,g,f,d)){b=g;break a}}b=void 0}return b}},"es6"); ha("WeakMap",function(a){function b(g){this.h=(f+=Math.random()+1).toString();if(g){g=u(g);for(var h;!(h=g.next()).done;)h=h.value,this.set(h[0],h[1])}}function c(){}function d(g){var h=typeof g;return"object"===h&&null!==g||"function"===h}if(function(){if(!a||!Object.seal)return!1;try{var g=Object.seal({}),h=Object.seal({}),k=new a([[g,2],[h,3]]);if(2!=k.get(g)||3!=k.get(h))return!1;k.delete(g);k.set(h,4);return!k.has(g)&&4==k.get(h)}catch(l){return!1}}())return a;var e="$jscomp_hidden_"+Math.random(), f=0;b.prototype.set=function(g,h){if(!d(g))throw Error("Invalid WeakMap key");if(!la(g,e)){var k=new c;ba(g,e,{value:k})}if(!la(g,e))throw Error("WeakMap key fail: "+g);g[e][this.h]=h;return this};b.prototype.get=function(g){return d(g)&&la(g,e)?g[e][this.h]:void 0};b.prototype.has=function(g){return d(g)&&la(g,e)&&la(g[e],this.h)};b.prototype.delete=function(g){return d(g)&&la(g,e)&&la(g[e],this.h)?delete g[e][this.h]:!1};return b},"es6"); ha("Map",function(a){function b(){var h={};return h.L=h.next=h.head=h}function c(h,k){var l=h.h;return ia(function(){if(l){for(;l.head!=h.h;)l=l.L;for(;l.next!=l.head;)return l=l.next,{done:!1,value:k(l)};l=null}return{done:!0,value:void 0}})}function d(h,k){var l=k&&typeof k;"object"==l||"function"==l?f.has(k)?l=f.get(k):(l=""+ ++g,f.set(k,l)):l="p_"+k;var m=h.i[l];if(m&&la(h.i,l))for(h=0;h<m.length;h++){var q=m[h];if(k!==k&&q.key!==q.key||k===q.key)return{id:l,list:m,index:h,B:q}}return{id:l,list:m, index:-1,B:void 0}}function e(h){this.i={};this.h=b();this.size=0;if(h){h=u(h);for(var k;!(k=h.next()).done;)k=k.value,this.set(k[0],k[1])}}if(function(){if(!a||"function"!=typeof a||!a.prototype.entries||"function"!=typeof Object.seal)return!1;try{var h=Object.seal({x:4}),k=new a(u([[h,"s"]]));if("s"!=k.get(h)||1!=k.size||k.get({x:4})||k.set({x:4},"t")!=k||2!=k.size)return!1;var l=k.entries(),m=l.next();if(m.done||m.value[0]!=h||"s"!=m.value[1])return!1;m=l.next();return m.done||4!=m.value[0].x|| "t"!=m.value[1]||!l.next().done?!1:!0}catch(q){return!1}}())return a;var f=new p.WeakMap;e.prototype.set=function(h,k){h=0===h?0:h;var l=d(this,h);l.list||(l.list=this.i[l.id]=[]);l.B?l.B.value=k:(l.B={next:this.h,L:this.h.L,head:this.h,key:h,value:k},l.list.push(l.B),this.h.L.next=l.B,this.h.L=l.B,this.size++);return this};e.prototype.delete=function(h){h=d(this,h);return h.B&&h.list?(h.list.splice(h.index,1),h.list.length||delete this.i[h.id],h.B.L.next=h.B.next,h.B.next.L=h.B.L,h.B.head=null,this.size--, !0):!1};e.prototype.clear=function(){this.i={};this.h=this.h.L=b();this.size=0};e.prototype.has=function(h){return!!d(this,h).B};e.prototype.get=function(h){return(h=d(this,h).B)&&h.value};e.prototype.entries=function(){return c(this,function(h){return[h.key,h.value]})};e.prototype.keys=function(){return c(this,function(h){return h.key})};e.prototype.values=function(){return c(this,function(h){return h.value})};e.prototype.forEach=function(h,k){for(var l=this.entries(),m;!(m=l.next()).done;)m=m.value, h.call(k,m[1],m[0],this)};e.prototype[r(p.Symbol,"iterator")]=e.prototype.entries;var g=0;return e},"es6");function ua(a,b){a instanceof String&&(a+="");var c=0,d=!1,e={next:function(){if(!d&&c<a.length){var f=c++;return{value:b(f,a[f]),done:!1}}d=!0;return{done:!0,value:void 0}}};e[r(p.Symbol,"iterator")]=function(){return e};return e} ha("String.prototype.startsWith",function(a){return a?a:function(b,c){if(null==this)throw new TypeError("The 'this' value for String.prototype.startsWith must not be null or undefined");if(b instanceof RegExp)throw new TypeError("First argument to String.prototype.startsWith must not be a regular expression");var d=this.length,e=b.length;c=Math.max(0,Math.min(c|0,this.length));for(var f=0;f<e&&c<d;)if(this[c++]!=b[f++])return!1;return f>=e}},"es6");ha("globalThis",function(a){return a||da},"es_2020"); ha("Set",function(a){function b(c){this.h=new p.Map;if(c){c=u(c);for(var d;!(d=c.next()).done;)this.add(d.value)}this.size=this.h.size}if(function(){if(!a||"function"!=typeof a||!a.prototype.entries||"function"!=typeof Object.seal)return!1;try{var c=Object.seal({x:4}),d=new a(u([c]));if(!d.has(c)||1!=d.size||d.add(c)!=d||1!=d.size||d.add({x:4})!=d||2!=d.size)return!1;var e=d.entries(),f=e.next();if(f.done||f.value[0]!=c||f.value[1]!=c)return!1;f=e.next();return f.done||f.value[0]==c||4!=f.value[0].x|| f.value[1]!=f.value[0]?!1:e.next().done}catch(g){return!1}}())return a;b.prototype.add=function(c){c=0===c?0:c;this.h.set(c,c);this.size=this.h.size;return this};b.prototype.delete=function(c){c=this.h.delete(c);this.size=this.h.size;return c};b.prototype.clear=function(){this.h.clear();this.size=0};b.prototype.has=function(c){return this.h.has(c)};b.prototype.entries=function(){return this.h.entries()};b.prototype.values=function(){return r(this.h,"values").call(this.h)};b.prototype.keys=r(b.prototype, "values");b.prototype[r(p.Symbol,"iterator")]=r(b.prototype,"values");b.prototype.forEach=function(c,d){var e=this;this.h.forEach(function(f){return c.call(d,f,f,e)})};return b},"es6");ha("Array.prototype.keys",function(a){return a?a:function(){return ua(this,function(b){return b})}},"es6");ha("Array.prototype.values",function(a){return a?a:function(){return ua(this,function(b,c){return c})}},"es8");ha("Number.isNaN",function(a){return a?a:function(b){return"number"===typeof b&&isNaN(b)}},"es6"); ha("Promise.prototype.finally",function(a){return a?a:function(b){return this.then(function(c){return p.Promise.resolve(b()).then(function(){return c})},function(c){return p.Promise.resolve(b()).then(function(){throw c;})})}},"es9");var w=this||self;function va(a){a=a.split(".");for(var b=w,c=0;c<a.length;c++)if(b=b[a[c]],null==b)return null;return b}function wa(a){var b=typeof a;return"object"!=b?b:a?Array.isArray(a)?"array":b:"null"} function xa(a){var b=wa(a);return"array"==b||"object"==b&&"number"==typeof a.length}function ya(a){var b=typeof a;return"object"==b&&null!=a||"function"==b}function za(a){return Object.prototype.hasOwnProperty.call(a,Aa)&&a[Aa]||(a[Aa]=++Ba)}var Aa="closure_uid_"+(1E9*Math.random()>>>0),Ba=0;function Ca(a,b,c){return a.call.apply(a.bind,arguments)} function Da(a,b,c){if(!a)throw Error();if(2<arguments.length){var d=Array.prototype.slice.call(arguments,2);return function(){var e=Array.prototype.slice.call(arguments);Array.prototype.unshift.apply(e,d);return a.apply(b,e)}}return function(){return a.apply(b,arguments)}}function Ea(a,b,c){Function.prototype.bind&&-1!=Function.prototype.bind.toString().indexOf("native code")?Ea=Ca:Ea=Da;return Ea.apply(null,arguments)} function Fa(a,b){var c=Array.prototype.slice.call(arguments,1);return function(){var d=c.slice();d.push.apply(d,arguments);return a.apply(this,d)}}function Ga(a){var b=["__uspapi"],c=w;b[0]in c||"undefined"==typeof c.execScript||c.execScript("var "+b[0]);for(var d;b.length&&(d=b.shift());)b.length||void 0===a?c[d]&&c[d]!==Object.prototype[d]?c=c[d]:c=c[d]={}:c[d]=a}function Ha(a){return a};var Ia=(new Date).getTime();function Ja(a){return/^[\s\xa0]*([\s\S]*?)[\s\xa0]*$/.exec(a)[1]} function Ka(a,b){var c=0;a=Ja(String(a)).split(".");b=Ja(String(b)).split(".");for(var d=Math.max(a.length,b.length),e=0;0==c&&e<d;e++){var f=a[e]||"",g=b[e]||"";do{f=/(\d*)(\D*)(.*)/.exec(f)||["","","",""];g=/(\d*)(\D*)(.*)/.exec(g)||["","","",""];if(0==f[0].length&&0==g[0].length)break;c=La(0==f[1].length?0:parseInt(f[1],10),0==g[1].length?0:parseInt(g[1],10))||La(0==f[2].length,0==g[2].length)||La(f[2],g[2]);f=f[3];g=g[3]}while(0==c)}return c}function La(a,b){return a<b?-1:a>b?1:0};function Ma(){var a=w.navigator;return a&&(a=a.userAgent)?a:""}function x(a){return-1!=Ma().indexOf(a)};function Na(){return x("Trident")||x("MSIE")}function Oa(){return(x("Chrome")||x("CriOS"))&&!x("Edge")||x("Silk")}function Pa(a){var b={};a.forEach(function(c){b[c[0]]=c[1]});return function(c){return b[r(c,"find").call(c,function(d){return d in b})]||""}} function Qa(){var a=Ma();if(Na()){var b=/rv: *([\d\.]*)/.exec(a);if(b&&b[1])a=b[1];else{b="";var c=/MSIE +([\d\.]+)/.exec(a);if(c&&c[1])if(a=/Trident\/(\d.\d)/.exec(a),"7.0"==c[1])if(a&&a[1])switch(a[1]){case "4.0":b="8.0";break;case "5.0":b="9.0";break;case "6.0":b="10.0";break;case "7.0":b="11.0"}else b="7.0";else b=c[1];a=b}return a}c=RegExp("([A-Z][\\w ]+)/([^\\s]+)\\s*(?:\\((.*?)\\))?","g");b=[];for(var d;d=c.exec(a);)b.push([d[1],d[2],d[3]||void 0]);a=Pa(b);return x("Opera")?a(["Version","Opera"]): x("Edge")?a(["Edge"]):x("Edg/")?a(["Edg"]):x("Silk")?a(["Silk"]):Oa()?a(["Chrome","CriOS","HeadlessChrome"]):(a=b[2])&&a[1]||""};function Ra(a,b){for(var c=a.length,d="string"===typeof a?a.split(""):a,e=0;e<c;e++)e in d&&b.call(void 0,d[e],e,a)}function Sa(a,b){for(var c=a.length,d=[],e=0,f="string"===typeof a?a.split(""):a,g=0;g<c;g++)if(g in f){var h=f[g];b.call(void 0,h,g,a)&&(d[e++]=h)}return d}function Ta(a,b){for(var c=a.length,d=Array(c),e="string"===typeof a?a.split(""):a,f=0;f<c;f++)f in e&&(d[f]=b.call(void 0,e[f],f,a));return d} function Ua(a,b){for(var c=a.length,d="string"===typeof a?a.split(""):a,e=0;e<c;e++)if(e in d&&b.call(void 0,d[e],e,a))return!0;return!1}function Va(a,b){a:{for(var c=a.length,d="string"===typeof a?a.split(""):a,e=0;e<c;e++)if(e in d&&b.call(void 0,d[e],e,a)){b=e;break a}b=-1}return 0>b?null:"string"===typeof a?a.charAt(b):a[b]} function Wa(a,b){a:{for(var c="string"===typeof a?a.split(""):a,d=a.length-1;0<=d;d--)if(d in c&&b.call(void 0,c[d],d,a)){b=d;break a}b=-1}return 0>b?null:"string"===typeof a?a.charAt(b):a[b]}function Xa(a,b){a:if("string"===typeof a)a="string"!==typeof b||1!=b.length?-1:a.indexOf(b,0);else{for(var c=0;c<a.length;c++)if(c in a&&a[c]===b){a=c;break a}a=-1}return 0<=a}function Ya(a){var b=a.length;if(0<b){for(var c=Array(b),d=0;d<b;d++)c[d]=a[d];return c}return[]};function Za(a){Za[" "](a);return a}Za[" "]=function(){};var $a=Na();!x("Android")||Oa();Oa();!x("Safari")||Oa();var ab={},bb=null;var cb="undefined"!==typeof Uint8Array;var db="function"===typeof p.Symbol&&"symbol"===typeof(0,p.Symbol)()?(0,p.Symbol)(void 0):void 0;function eb(a,b){Object.isFrozen(a)||(db?a[db]|=b:void 0!==a.ma?a.ma|=b:Object.defineProperties(a,{ma:{value:b,configurable:!0,writable:!0,enumerable:!1}}))}function fb(a){var b;db?b=a[db]:b=a.ma;return null==b?0:b}function gb(a){eb(a,1);return a}function hb(a){return Array.isArray(a)?!!(fb(a)&2):!1}function ib(a){if(!Array.isArray(a))throw Error("cannot mark non-array as immutable");eb(a,2)};function jb(a){return null!==a&&"object"===typeof a&&!Array.isArray(a)&&a.constructor===Object}var kb,lb=Object.freeze(gb([]));function mb(a){if(hb(a.v))throw Error("Cannot mutate an immutable Message");}var nb="undefined"!=typeof p.Symbol&&"undefined"!=typeof p.Symbol.hasInstance;function ob(a){return{value:a,configurable:!1,writable:!1,enumerable:!1}};function pb(a){switch(typeof a){case "number":return isFinite(a)?a:String(a);case "object":if(a&&!Array.isArray(a)&&cb&&null!=a&&a instanceof Uint8Array){var b;void 0===b&&(b=0);if(!bb){bb={};for(var c="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".split(""),d=["+/=","+/","-_=","-_.","-_"],e=0;5>e;e++){var f=c.concat(d[e].split(""));ab[e]=f;for(var g=0;g<f.length;g++){var h=f[g];void 0===bb[h]&&(bb[h]=g)}}}b=ab[b];c=Array(Math.floor(a.length/3));d=b[64]||"";for(e=f=0;f<a.length- 2;f+=3){var k=a[f],l=a[f+1];h=a[f+2];g=b[k>>2];k=b[(k&3)<<4|l>>4];l=b[(l&15)<<2|h>>6];h=b[h&63];c[e++]=g+k+l+h}g=0;h=d;switch(a.length-f){case 2:g=a[f+1],h=b[(g&15)<<2]||d;case 1:a=a[f],c[e]=b[a>>2]+b[(a&3)<<4|g>>4]+h+d}return c.join("")}}return a};function qb(a){var b=sb;b=void 0===b?tb:b;return ub(a,b)}function vb(a,b){if(null!=a){if(Array.isArray(a))a=ub(a,b);else if(jb(a)){var c={},d;for(d in a)Object.prototype.hasOwnProperty.call(a,d)&&(c[d]=vb(a[d],b));a=c}else a=b(a);return a}}function ub(a,b){for(var c=a.slice(),d=0;d<c.length;d++)c[d]=vb(c[d],b);Array.isArray(a)&&fb(a)&1&&gb(c);return c}function sb(a){if(a&&"object"==typeof a&&a.toJSON)return a.toJSON();a=pb(a);return Array.isArray(a)?qb(a):a} function tb(a){return cb&&null!=a&&a instanceof Uint8Array?new Uint8Array(a):a};function A(a,b,c){return-1===b?null:b>=a.l?a.i?a.i[b]:void 0:(void 0===c?0:c)&&a.i&&(c=a.i[b],null!=c)?c:a.v[b+a.j]}function B(a,b,c,d,e){d=void 0===d?!1:d;(void 0===e?0:e)||mb(a);b<a.l&&!d?a.v[b+a.j]=c:(a.i||(a.i=a.v[a.l+a.j]={}))[b]=c;return a}function wb(a,b,c,d){c=void 0===c?!0:c;d=void 0===d?!1:d;var e=A(a,b,d);null==e&&(e=lb);if(hb(a.v))c&&(ib(e),Object.freeze(e));else if(e===lb||hb(e))e=gb(e.slice()),B(a,b,e,d);return e}function xb(a,b){a=A(a,b);return null==a?a:!!a} function C(a,b,c){a=A(a,b);return null==a?c:a}function D(a,b,c){a=xb(a,b);return null==a?void 0===c?!1:c:a}function yb(a,b){a=A(a,b);a=null==a?a:+a;return null==a?0:a}function zb(a,b,c){var d=void 0===d?!1:d;return B(a,b,null==c?gb([]):Array.isArray(c)?gb(c):c,d)}function Ab(a,b,c){mb(a);0!==c?B(a,b,c):B(a,b,void 0,!1,!1);return a}function Bb(a,b,c,d){mb(a);(c=Cb(a,c))&&c!==b&&null!=d&&(a.h&&c in a.h&&(a.h[c]=void 0),B(a,c));return B(a,b,d)}function Db(a,b,c){return Cb(a,b)===c?c:-1} function Cb(a,b){for(var c=0,d=0;d<b.length;d++){var e=b[d];null!=A(a,e)&&(0!==c&&B(a,c,void 0,!1,!0),c=e)}return c}function G(a,b,c){if(-1===c)return null;a.h||(a.h={});var d=a.h[c];if(d)return d;var e=A(a,c,!1);if(null==e)return d;b=new b(e);hb(a.v)&&ib(b.v);return a.h[c]=b}function H(a,b,c){a.h||(a.h={});var d=hb(a.v),e=a.h[c];if(!e){var f=wb(a,c,!0,!1);e=[];d=d||hb(f);for(var g=0;g<f.length;g++)e[g]=new b(f[g]),d&&ib(e[g].v);d&&(ib(e),Object.freeze(e));a.h[c]=e}return e} function Eb(a,b,c){var d=void 0===d?!1:d;mb(a);a.h||(a.h={});var e=c?c.v:c;a.h[b]=c;return B(a,b,e,d)}function Fb(a,b,c,d){mb(a);a.h||(a.h={});var e=d?d.v:d;a.h[b]=d;return Bb(a,b,c,e)}function Gb(a,b,c){var d=void 0===d?!1:d;mb(a);if(c){var e=gb([]);for(var f=0;f<c.length;f++)e[f]=c[f].v;a.h||(a.h={});a.h[b]=c}else a.h&&(a.h[b]=void 0),e=lb;return B(a,b,e,d)}function I(a,b){return C(a,b,"")}function Hb(a,b,c){return C(a,Db(a,c,b),0)}function Ib(a,b,c,d){return G(a,b,Db(a,d,c))};function Jb(a,b,c){a||(a=Kb);Kb=null;var d=this.constructor.messageId;a||(a=d?[d]:[]);this.j=(d?0:-1)-(this.constructor.h||0);this.h=void 0;this.v=a;a:{d=this.v.length;a=d-1;if(d&&(d=this.v[a],jb(d))){this.l=a-this.j;this.i=d;break a}void 0!==b&&-1<b?(this.l=Math.max(b,a+1-this.j),this.i=void 0):this.l=Number.MAX_VALUE}if(c)for(b=0;b<c.length;b++)if(a=c[b],a<this.l)a+=this.j,(d=this.v[a])?Array.isArray(d)&&gb(d):this.v[a]=lb;else{d=this.i||(this.i=this.v[this.l+this.j]={});var e=d[a];e?Array.isArray(e)&& gb(e):d[a]=lb}}Jb.prototype.toJSON=function(){var a=this.v;return kb?a:qb(a)};function Lb(a){kb=!0;try{return JSON.stringify(a.toJSON(),Mb)}finally{kb=!1}}function Nb(a,b){if(null==b||""==b)return new a;b=JSON.parse(b);if(!Array.isArray(b))throw Error("Expected to deserialize an Array but got "+wa(b)+": "+b);Kb=b;a=new a(b);Kb=null;return a}function Mb(a,b){return pb(b)}var Kb;function Ob(){Jb.apply(this,arguments)}v(Ob,Jb);if(nb){var Pb={};Object.defineProperties(Ob,(Pb[p.Symbol.hasInstance]=ob(function(){throw Error("Cannot perform instanceof checks for MutableMessage");}),Pb))};function J(){Ob.apply(this,arguments)}v(J,Ob);if(nb){var Qb={};Object.defineProperties(J,(Qb[p.Symbol.hasInstance]=ob(Object[p.Symbol.hasInstance]),Qb))};function Rb(a){J.call(this,a,-1,Sb)}v(Rb,J);function Tb(a){J.call(this,a)}v(Tb,J);var Sb=[2,3];function Ub(a,b){this.i=a===Vb&&b||"";this.h=Wb}var Wb={},Vb={};function Xb(a,b){var c={},d;for(d in a)b.call(void 0,a[d],d,a)&&(c[d]=a[d]);return c}function Yb(a,b){for(var c in a)if(b.call(void 0,a[c],c,a))return!0;return!1}function Zb(a){var b=[],c=0,d;for(d in a)b[c++]=a[d];return b}function $b(a){var b={},c;for(c in a)b[c]=a[c];return b};var ac;function bc(){if(void 0===ac){var a=null,b=w.trustedTypes;if(b&&b.createPolicy){try{a=b.createPolicy("goog#html",{createHTML:Ha,createScript:Ha,createScriptURL:Ha})}catch(c){w.console&&w.console.error(c.message)}ac=a}else ac=a}return ac};function cc(a,b){this.h=b===dc?a:""}function ec(a,b){a=fc.exec(gc(a).toString());var c=a[3]||"";return hc(a[1]+ic("?",a[2]||"",b)+ic("#",c))}cc.prototype.toString=function(){return this.h+""};function gc(a){return a instanceof cc&&a.constructor===cc?a.h:"type_error:TrustedResourceUrl"}var fc=/^([^?#]*)(\?[^#]*)?(#[\s\S]*)?/,dc={};function hc(a){var b=bc();a=b?b.createScriptURL(a):a;return new cc(a,dc)} function ic(a,b,c){if(null==c)return b;if("string"===typeof c)return c?a+encodeURIComponent(c):"";for(var d in c)if(Object.prototype.hasOwnProperty.call(c,d)){var e=c[d];e=Array.isArray(e)?e:[e];for(var f=0;f<e.length;f++){var g=e[f];null!=g&&(b||(b=a),b+=(b.length>a.length?"&":"")+encodeURIComponent(d)+"="+encodeURIComponent(String(g)))}}return b};function jc(a,b){this.h=b===kc?a:""}jc.prototype.toString=function(){return this.h.toString()};var kc={};/* SPDX-License-Identifier: Apache-2.0 */ var lc={};function mc(){}function nc(a){this.h=a}v(nc,mc);nc.prototype.toString=function(){return this.h.toString()};function oc(a){var b,c=null==(b=bc())?void 0:b.createScriptURL(a);return new nc(null!=c?c:a,lc)}function pc(a){if(a instanceof nc)return a.h;throw Error("");};function qc(a){return a instanceof mc?pc(a):gc(a)}function rc(a){return a instanceof jc&&a.constructor===jc?a.h:"type_error:SafeUrl"}function sc(a){return a instanceof mc?pc(a).toString():gc(a).toString()};var tc="alternate author bookmark canonical cite help icon license next prefetch dns-prefetch prerender preconnect preload prev search subresource".split(" ");function uc(a){return function(){return!a.apply(this,arguments)}}function vc(a){var b=!1,c;return function(){b||(c=a(),b=!0);return c}}function wc(a){var b=a;return function(){if(b){var c=b;b=null;c()}}};function xc(a,b,c){a.addEventListener&&a.addEventListener(b,c,!1)}function yc(a,b){a.removeEventListener&&a.removeEventListener("message",b,!1)};function zc(a){return String(a).replace(/\-([a-z])/g,function(b,c){return c.toUpperCase()})};function Ac(a,b,c){function d(h){h&&b.appendChild("string"===typeof h?a.createTextNode(h):h)}for(var e=1;e<c.length;e++){var f=c[e];if(!xa(f)||ya(f)&&0<f.nodeType)d(f);else{a:{if(f&&"number"==typeof f.length){if(ya(f)){var g="function"==typeof f.item||"string"==typeof f.item;break a}if("function"===typeof f){g="function"==typeof f.item;break a}}g=!1}Ra(g?Ya(f):f,d)}}}function Bc(a){this.h=a||w.document||document}n=Bc.prototype;n.getElementsByTagName=function(a,b){return(b||this.h).getElementsByTagName(String(a))}; n.createElement=function(a){var b=this.h;a=String(a);"application/xhtml+xml"===b.contentType&&(a=a.toLowerCase());return b.createElement(a)};n.createTextNode=function(a){return this.h.createTextNode(String(a))};n.append=function(a,b){Ac(9==a.nodeType?a:a.ownerDocument||a.document,a,arguments)}; n.contains=function(a,b){if(!a||!b)return!1;if(a.contains&&1==b.nodeType)return a==b||a.contains(b);if("undefined"!=typeof a.compareDocumentPosition)return a==b||!!(a.compareDocumentPosition(b)&16);for(;b&&a!=b;)b=b.parentNode;return b==a};function Cc(){return!Dc()&&(x("iPod")||x("iPhone")||x("Android")||x("IEMobile"))}function Dc(){return x("iPad")||x("Android")&&!x("Mobile")||x("Silk")};var Ec=RegExp("^(?:([^:/?#.]+):)?(?://(?:([^\\\\/?#]*)@)?([^\\\\/?#]*?)(?::([0-9]+))?(?=[\\\\/?#]|$))?([^?#]+)?(?:\\?([^#]*))?(?:#([\\s\\S]*))?$"),Fc=/#|$/;function Gc(a){var b=a.search(Fc),c;a:{for(c=0;0<=(c=a.indexOf("client",c))&&c<b;){var d=a.charCodeAt(c-1);if(38==d||63==d)if(d=a.charCodeAt(c+6),!d||61==d||38==d||35==d)break a;c+=7}c=-1}if(0>c)return null;d=a.indexOf("&",c);if(0>d||d>b)d=b;c+=7;return decodeURIComponent(a.substr(c,d-c).replace(/\+/g," "))};function Hc(a){try{var b;if(b=!!a&&null!=a.location.href)a:{try{Za(a.foo);b=!0;break a}catch(c){}b=!1}return b}catch(c){return!1}}function Ic(a){return Hc(a.top)?a.top:null} function Lc(a,b){var c=Mc("SCRIPT",a);c.src=qc(b);var d,e;(d=(b=null==(e=(d=(c.ownerDocument&&c.ownerDocument.defaultView||window).document).querySelector)?void 0:e.call(d,"script[nonce]"))?b.nonce||b.getAttribute("nonce")||"":"")&&c.setAttribute("nonce",d);return(a=a.getElementsByTagName("script")[0])&&a.parentNode?(a.parentNode.insertBefore(c,a),c):null}function Nc(a,b){return b.getComputedStyle?b.getComputedStyle(a,null):a.currentStyle} function Oc(a,b){if(!Pc()&&!Qc()){var c=Math.random();if(c<b)return c=Rc(),a[Math.floor(c*a.length)]}return null}function Rc(){if(!p.globalThis.crypto)return Math.random();try{var a=new Uint32Array(1);p.globalThis.crypto.getRandomValues(a);return a[0]/65536/65536}catch(b){return Math.random()}}function Sc(a,b){if(a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&b(a[c],c,a)} function Tc(a){var b=a.length;if(0==b)return 0;for(var c=305419896,d=0;d<b;d++)c^=(c<<5)+(c>>2)+a.charCodeAt(d)&4294967295;return 0<c?c:4294967296+c}var Qc=vc(function(){return Ua(["Google Web Preview","Mediapartners-Google","Google-Read-Aloud","Google-Adwords"],Uc)||1E-4>Math.random()});function Vc(a,b){var c=-1;try{a&&(c=parseInt(a.getItem(b),10))}catch(d){return null}return 0<=c&&1E3>c?c:null} function Wc(a,b){var c=Qc()?null:Math.floor(1E3*Rc());var d;if(d=null!=c&&a)a:{var e=String(c);try{if(a){a.setItem(b,e);d=e;break a}}catch(f){}d=null}return d?c:null}var Pc=vc(function(){return Uc("MSIE")});function Uc(a){return-1!=Ma().indexOf(a)}var Xc=/^([0-9.]+)px$/,Yc=/^(-?[0-9.]{1,30})$/;function Zc(a){var b=void 0===b?null:b;if(!Yc.test(a))return b;a=Number(a);return isNaN(a)?b:a}function K(a){return(a=Xc.exec(a))?+a[1]:null} function $c(a,b){for(var c=0;50>c;++c){try{var d=!(!a.frames||!a.frames[b])}catch(g){d=!1}if(d)return a;a:{try{var e=a.parent;if(e&&e!=a){var f=e;break a}}catch(g){}f=null}if(!(a=f))break}return null}var ad=vc(function(){return Cc()?2:Dc()?1:0});function bd(a){Sc({display:"none"},function(b,c){a.style.setProperty(c,b,"important")})}var cd=[];function dd(){var a=cd;cd=[];a=u(a);for(var b=a.next();!b.done;b=a.next()){b=b.value;try{b()}catch(c){}}} function ed(a,b){0!=a.length&&b.head&&a.forEach(function(c){if(c&&c&&b.head){var d=Mc("META");b.head.appendChild(d);d.httpEquiv="origin-trial";d.content=c}})}function fd(a){if("number"!==typeof a.goog_pvsid)try{Object.defineProperty(a,"goog_pvsid",{value:Math.floor(Math.random()*Math.pow(2,52)),configurable:!1})}catch(b){}return Number(a.goog_pvsid)||-1} function gd(a){var b=hd;"complete"===b.readyState||"interactive"===b.readyState?(cd.push(a),1==cd.length&&(p.Promise?p.Promise.resolve().then(dd):window.setImmediate?setImmediate(dd):setTimeout(dd,0))):b.addEventListener("DOMContentLoaded",a)}function Mc(a,b){b=void 0===b?document:b;return b.createElement(String(a).toLowerCase())};var id=null;var hd=document,L=window;var jd=null;function kd(a,b){b=void 0===b?[]:b;var c=!1;w.google_logging_queue||(c=!0,w.google_logging_queue=[]);w.google_logging_queue.push([a,b]);if(a=c){if(null==jd){jd=!1;try{var d=Ic(w);d&&-1!==d.location.hash.indexOf("google_logging")&&(jd=!0);w.localStorage.getItem("google_logging")&&(jd=!0)}catch(e){}}a=jd}a&&(d=w.document,a=new Ub(Vb,"https://pagead2.googlesyndication.com/pagead/js/logging_library.js"),a=hc(a instanceof Ub&&a.constructor===Ub&&a.h===Wb?a.i:"type_error:Const"),Lc(d,a))};function ld(a){a=void 0===a?w:a;var b=a.context||a.AMP_CONTEXT_DATA;if(!b)try{b=a.parent.context||a.parent.AMP_CONTEXT_DATA}catch(c){}try{if(b&&b.pageViewId&&b.canonicalUrl)return b}catch(c){}return null}function md(a){return(a=a||ld())?Hc(a.master)?a.master:null:null};function nd(a){var b=ta.apply(1,arguments);if(0===b.length)return oc(a[0]);for(var c=[a[0]],d=0;d<b.length;d++)c.push(encodeURIComponent(b[d])),c.push(a[d+1]);return oc(c.join(""))};function od(a){var b=void 0===b?1:b;a=md(ld(a))||a;a.google_unique_id=(a.google_unique_id||0)+b;return a.google_unique_id}function pd(a){a=a.google_unique_id;return"number"===typeof a?a:0}function qd(){var a=void 0===a?L:a;if(!a)return!1;try{return!(!a.navigator.standalone&&!a.top.navigator.standalone)}catch(b){return!1}}function rd(a){if(!a)return"";a=a.toLowerCase();"ca-"!=a.substring(0,3)&&(a="ca-"+a);return a};function sd(){this.i=new td(this);this.h=0}sd.prototype.resolve=function(a){ud(this);this.h=1;this.l=a;vd(this.i)};sd.prototype.reject=function(a){ud(this);this.h=2;this.j=a;vd(this.i)};function ud(a){if(0!=a.h)throw Error("Already resolved/rejected.");}function td(a){this.h=a}td.prototype.then=function(a,b){if(this.i)throw Error("Then functions already set.");this.i=a;this.j=b;vd(this)}; function vd(a){switch(a.h.h){case 0:break;case 1:a.i&&a.i(a.h.l);break;case 2:a.j&&a.j(a.h.j);break;default:throw Error("Unhandled deferred state.");}};function wd(a){this.h=a.slice(0)}n=wd.prototype;n.forEach=function(a){var b=this;this.h.forEach(function(c,d){return void a(c,d,b)})};n.filter=function(a){return new wd(Sa(this.h,a))};n.apply=function(a){return new wd(a(this.h.slice(0)))};n.sort=function(a){return new wd(this.h.slice(0).sort(a))};n.get=function(a){return this.h[a]};n.add=function(a){var b=this.h.slice(0);b.push(a);return new wd(b)};function xd(a,b){for(var c=[],d=a.length,e=0;e<d;e++)c.push(a[e]);c.forEach(b,void 0)};function yd(){this.h={};this.i={}}yd.prototype.set=function(a,b){var c=zd(a);this.h[c]=b;this.i[c]=a};yd.prototype.get=function(a,b){a=zd(a);return void 0!==this.h[a]?this.h[a]:b};yd.prototype.clear=function(){this.h={};this.i={}};function zd(a){return a instanceof Object?String(za(a)):a+""};function Ad(a,b){this.h=a;this.i=b}function Bd(a){return null!=a.h?a.h.value:null}function Cd(a,b){null!=a.h&&b(a.h.value);return a}Ad.prototype.map=function(a){return null!=this.h?(a=a(this.h.value),a instanceof Ad?a:Dd(a)):this};function Ed(a,b){null!=a.h||b(a.i);return a}function Dd(a){return new Ad({value:a},null)}function Fd(a){return new Ad(null,a)}function Gd(a){try{return Dd(a())}catch(b){return Fd(b)}};function Hd(a){this.h=new yd;if(a)for(var b=0;b<a.length;++b)this.add(a[b])}Hd.prototype.add=function(a){this.h.set(a,!0)};Hd.prototype.contains=function(a){return void 0!==this.h.h[zd(a)]};function Id(){this.h=new yd}Id.prototype.set=function(a,b){var c=this.h.get(a);c||(c=new Hd,this.h.set(a,c));c.add(b)};function Jd(a){J.call(this,a,-1,Kd)}v(Jd,J);Jd.prototype.getId=function(){return A(this,3)};var Kd=[4];function Ld(a){var b=void 0===a.Ga?void 0:a.Ga,c=void 0===a.gb?void 0:a.gb,d=void 0===a.Ra?void 0:a.Ra;this.h=void 0===a.bb?void 0:a.bb;this.l=new wd(b||[]);this.j=d;this.i=c};function Md(a){var b=[],c=a.l;c&&c.h.length&&b.push({X:"a",ca:Nd(c)});null!=a.h&&b.push({X:"as",ca:a.h});null!=a.i&&b.push({X:"i",ca:String(a.i)});null!=a.j&&b.push({X:"rp",ca:String(a.j)});b.sort(function(d,e){return d.X.localeCompare(e.X)});b.unshift({X:"t",ca:"aa"});return b}function Nd(a){a=a.h.slice(0).map(Od);a=JSON.stringify(a);return Tc(a)}function Od(a){var b={};null!=A(a,7)&&(b.q=A(a,7));null!=A(a,2)&&(b.o=A(a,2));null!=A(a,5)&&(b.p=A(a,5));return b};function Pd(a){J.call(this,a)}v(Pd,J);Pd.prototype.setLocation=function(a){return B(this,1,a)};function Qd(a,b){this.Ja=a;this.Qa=b}function Rd(a){var b=[].slice.call(arguments).filter(uc(function(e){return null===e}));if(!b.length)return null;var c=[],d={};b.forEach(function(e){c=c.concat(e.Ja||[]);d=r(Object,"assign").call(Object,d,e.Qa)});return new Qd(c,d)} function Sd(a){switch(a){case 1:return new Qd(null,{google_ad_semantic_area:"mc"});case 2:return new Qd(null,{google_ad_semantic_area:"h"});case 3:return new Qd(null,{google_ad_semantic_area:"f"});case 4:return new Qd(null,{google_ad_semantic_area:"s"});default:return null}} function Td(a){if(null==a)a=null;else{var b=Md(a);a=[];b=u(b);for(var c=b.next();!c.done;c=b.next()){c=c.value;var d=String(c.ca);a.push(c.X+"."+(20>=d.length?d:d.slice(0,19)+"_"))}a=new Qd(null,{google_placement_id:a.join("~")})}return a};var Ud={},Vd=new Qd(["google-auto-placed"],(Ud.google_reactive_ad_format=40,Ud.google_tag_origin="qs",Ud));function Wd(a){J.call(this,a)}v(Wd,J);function Xd(a){J.call(this,a)}v(Xd,J);Xd.prototype.getName=function(){return A(this,4)};function Yd(a){J.call(this,a)}v(Yd,J);function Zd(a){J.call(this,a)}v(Zd,J);function $d(a){J.call(this,a)}v($d,J);var ae=[1,2,3];function be(a){J.call(this,a)}v(be,J);function ce(a){J.call(this,a,-1,de)}v(ce,J);var de=[6,7,9,10,11];function ee(a){J.call(this,a,-1,fe)}v(ee,J);function ge(a){J.call(this,a)}v(ge,J);function he(a){J.call(this,a)}v(he,J);var fe=[1],ie=[1,2];function je(a){J.call(this,a,-1,ke)}v(je,J);function le(a){J.call(this,a)}v(le,J);function me(a){J.call(this,a,-1,ne)}v(me,J);function oe(a){J.call(this,a)}v(oe,J);function pe(a){J.call(this,a)}v(pe,J);function qe(a){J.call(this,a)}v(qe,J);function re(a){J.call(this,a)}v(re,J);var ke=[1,2,5,7],ne=[2,5,6,11];function se(a){J.call(this,a)}v(se,J);function te(a){if(1!=a.nodeType)var b=!1;else if(b="INS"==a.tagName)a:{b=["adsbygoogle-placeholder"];a=a.className?a.className.split(/\s+/):[];for(var c={},d=0;d<a.length;++d)c[a[d]]=!0;for(d=0;d<b.length;++d)if(!c[b[d]]){b=!1;break a}b=!0}return b};function ue(a,b,c){switch(c){case 0:b.parentNode&&b.parentNode.insertBefore(a,b);break;case 3:if(c=b.parentNode){var d=b.nextSibling;if(d&&d.parentNode!=c)for(;d&&8==d.nodeType;)d=d.nextSibling;c.insertBefore(a,d)}break;case 1:b.insertBefore(a,b.firstChild);break;case 2:b.appendChild(a)}te(b)&&(b.setAttribute("data-init-display",b.style.display),b.style.display="block")};function M(a,b){this.h=a;this.defaultValue=void 0===b?!1:b}function N(a,b){this.h=a;this.defaultValue=void 0===b?0:b}function ve(a,b){b=void 0===b?[]:b;this.h=a;this.defaultValue=b};var we=new M(1084),xe=new M(1082,!0),ye=new N(62,.001),ze=new N(1130,100),Ae=new function(a,b){this.h=a;this.defaultValue=void 0===b?"":b}(14),Be=new N(1114,1),Ce=new N(1110),De=new N(1111),Ee=new N(1112),Fe=new N(1113),Ge=new N(1104),He=new N(1108),Ie=new N(1106),Je=new N(1107),Ke=new N(1105),Le=new N(1115,1),Me=new M(1121),Ne=new M(1144),Oe=new M(1143),Pe=new M(316),Qe=new M(313),Re=new M(369),Se=new M(1093),Te=new N(1098),Ue=new M(1129),Ve=new M(1128),We=new M(1026),Xe=new M(1090),Ye=new M(1053, !0),Ze=new M(1162),$e=new M(1120),af=new M(1100,!0),bf=new N(1046),cf=new M(1102,!0),df=new M(218),ef=new M(217),ff=new M(227),gf=new M(208),hf=new M(282),jf=new M(1086),kf=new N(1079,5),lf=new M(1141),mf=new ve(1939),nf=new ve(1934,["A8FHS1NmdCwGqD9DwOicnHHY+y27kdWfxKa0YHSGDfv0CSpDKRHTQdQmZVPDUdaFWUsxdgVxlwAd6o+dhJykPA0AAACWeyJvcmlnaW4iOiJodHRwczovL2RvdWJsZWNsaWNrLm5ldDo0NDMiLCJmZWF0dXJlIjoiQ29udmVyc2lvbk1lYXN1cmVtZW50IiwiZXhwaXJ5IjoxNjQzMTU1MTk5LCJpc1N1YmRvbWFpbiI6dHJ1ZSwiaXNUaGlyZFBhcnR5Ijp0cnVlLCJ1c2FnZSI6InN1YnNldCJ9", "A8zdXi6dr1hwXEUjQrYiyYQGlU3557y5QWDnN0Lwgj9ePt66XMEvNkVWOEOWPd7TP9sBQ25X0Q15Lr1Nn4oGFQkAAACceyJvcmlnaW4iOiJodHRwczovL2dvb2dsZXN5bmRpY2F0aW9uLmNvbTo0NDMiLCJmZWF0dXJlIjoiQ29udmVyc2lvbk1lYXN1cmVtZW50IiwiZXhwaXJ5IjoxNjQzMTU1MTk5LCJpc1N1YmRvbWFpbiI6dHJ1ZSwiaXNUaGlyZFBhcnR5Ijp0cnVlLCJ1c2FnZSI6InN1YnNldCJ9","A4/Htern2udN9w3yJK9QgWQxQFruxOXsXL7cW60DyCl0EZFGCSme/J33Q/WzF7bBkVvhEWDlcBiUyZaim5CpFQwAAACceyJvcmlnaW4iOiJodHRwczovL2dvb2dsZXRhZ3NlcnZpY2VzLmNvbTo0NDMiLCJmZWF0dXJlIjoiQ29udmVyc2lvbk1lYXN1cmVtZW50IiwiZXhwaXJ5IjoxNjQzMTU1MTk5LCJpc1N1YmRvbWFpbiI6dHJ1ZSwiaXNUaGlyZFBhcnR5Ijp0cnVlLCJ1c2FnZSI6InN1YnNldCJ9"]), of=new M(203),pf=new M(434462125),qf=new M(84),rf=new M(1928),sf=new M(1941),tf=new M(370946349),uf=new M(392736476,!0),vf=new N(406149835),wf=new ve(1932,["AxujKG9INjsZ8/gUq8+dTruNvk7RjZQ1oFhhgQbcTJKDnZfbzSTE81wvC2Hzaf3TW4avA76LTZEMdiedF1vIbA4AAABueyJvcmlnaW4iOiJodHRwczovL2ltYXNkay5nb29nbGVhcGlzLmNvbTo0NDMiLCJmZWF0dXJlIjoiVHJ1c3RUb2tlbnMiLCJleHBpcnkiOjE2NTI3NzQ0MDAsImlzVGhpcmRQYXJ0eSI6dHJ1ZX0=","Azuce85ORtSnWe1MZDTv68qpaW3iHyfL9YbLRy0cwcCZwVnePnOmkUJlG8HGikmOwhZU22dElCcfrfX2HhrBPAkAAAB7eyJvcmlnaW4iOiJodHRwczovL2RvdWJsZWNsaWNrLm5ldDo0NDMiLCJmZWF0dXJlIjoiVHJ1c3RUb2tlbnMiLCJleHBpcnkiOjE2NTI3NzQ0MDAsImlzU3ViZG9tYWluIjp0cnVlLCJpc1RoaXJkUGFydHkiOnRydWV9", "A16nvcdeoOAqrJcmjLRpl1I6f3McDD8EfofAYTt/P/H4/AWwB99nxiPp6kA0fXoiZav908Z8etuL16laFPUdfQsAAACBeyJvcmlnaW4iOiJodHRwczovL2dvb2dsZXRhZ3NlcnZpY2VzLmNvbTo0NDMiLCJmZWF0dXJlIjoiVHJ1c3RUb2tlbnMiLCJleHBpcnkiOjE2NTI3NzQ0MDAsImlzU3ViZG9tYWluIjp0cnVlLCJpc1RoaXJkUGFydHkiOnRydWV9","AxBHdr0J44vFBQtZUqX9sjiqf5yWZ/OcHRcRMN3H9TH+t90V/j3ENW6C8+igBZFXMJ7G3Pr8Dd13632aLng42wgAAACBeyJvcmlnaW4iOiJodHRwczovL2dvb2dsZXN5bmRpY2F0aW9uLmNvbTo0NDMiLCJmZWF0dXJlIjoiVHJ1c3RUb2tlbnMiLCJleHBpcnkiOjE2NTI3NzQ0MDAsImlzU3ViZG9tYWluIjp0cnVlLCJpc1RoaXJkUGFydHkiOnRydWV9", "A88BWHFjcawUfKU3lIejLoryXoyjooBXLgWmGh+hNcqMK44cugvsI5YZbNarYvi3roc1fYbHA1AVbhAtuHZflgEAAAB2eyJvcmlnaW4iOiJodHRwczovL2dvb2dsZS5jb206NDQzIiwiZmVhdHVyZSI6IlRydXN0VG9rZW5zIiwiZXhwaXJ5IjoxNjUyNzc0NDAwLCJpc1N1YmRvbWFpbiI6dHJ1ZSwiaXNUaGlyZFBhcnR5Ijp0cnVlfQ=="]),xf=new N(1935);function O(a){var b="sa";if(a.sa&&a.hasOwnProperty(b))return a.sa;b=new a;return a.sa=b};function yf(){var a={};this.i=function(b,c){return null!=a[b]?a[b]:c};this.j=function(b,c){return null!=a[b]?a[b]:c};this.l=function(b,c){return null!=a[b]?a[b]:c};this.h=function(b,c){return null!=a[b]?a[b]:c};this.m=function(){}}function P(a){return O(yf).i(a.h,a.defaultValue)}function Q(a){return O(yf).j(a.h,a.defaultValue)}function zf(){return O(yf).l(Ae.h,Ae.defaultValue)};function Af(a,b,c){function d(f){f=Bf(f);return null==f?!1:c>f}function e(f){f=Bf(f);return null==f?!1:c<f}switch(b){case 0:return{init:Cf(a.previousSibling,e),ja:function(f){return Cf(f.previousSibling,e)},na:0};case 2:return{init:Cf(a.lastChild,e),ja:function(f){return Cf(f.previousSibling,e)},na:0};case 3:return{init:Cf(a.nextSibling,d),ja:function(f){return Cf(f.nextSibling,d)},na:3};case 1:return{init:Cf(a.firstChild,d),ja:function(f){return Cf(f.nextSibling,d)},na:3}}throw Error("Un-handled RelativePosition: "+ b);}function Bf(a){return a.hasOwnProperty("google-ama-order-assurance")?a["google-ama-order-assurance"]:null}function Cf(a,b){return a&&b(a)?a:null};var Df={rectangle:1,horizontal:2,vertical:4};function Ef(a,b){a.google_image_requests||(a.google_image_requests=[]);var c=Mc("IMG",a.document);c.src=b;a.google_image_requests.push(c)}function Ff(a){var b="https://pagead2.googlesyndication.com/pagead/gen_204?id=dtt_err";Sc(a,function(c,d){c&&(b+="&"+d+"="+encodeURIComponent(c))});Gf(b)}function Gf(a){var b=window;b.fetch?b.fetch(a,{keepalive:!0,credentials:"include",redirect:"follow",method:"get",mode:"no-cors"}):Ef(b,a)};function Hf(){this.j="&";this.i={};this.l=0;this.h=[]}function If(a,b){var c={};c[a]=b;return[c]}function Jf(a,b,c,d,e){var f=[];Sc(a,function(g,h){(g=Kf(g,b,c,d,e))&&f.push(h+"="+g)});return f.join(b)} function Kf(a,b,c,d,e){if(null==a)return"";b=b||"&";c=c||",$";"string"==typeof c&&(c=c.split(""));if(a instanceof Array){if(d=d||0,d<c.length){for(var f=[],g=0;g<a.length;g++)f.push(Kf(a[g],b,c,d+1,e));return f.join(c[d])}}else if("object"==typeof a)return e=e||0,2>e?encodeURIComponent(Jf(a,b,c,d,e+1)):"...";return encodeURIComponent(String(a))} function Lf(a,b){var c="https://pagead2.googlesyndication.com"+b,d=Mf(a)-b.length;if(0>d)return"";a.h.sort(function(m,q){return m-q});b=null;for(var e="",f=0;f<a.h.length;f++)for(var g=a.h[f],h=a.i[g],k=0;k<h.length;k++){if(!d){b=null==b?g:b;break}var l=Jf(h[k],a.j,",$");if(l){l=e+l;if(d>=l.length){d-=l.length;c+=l;e=a.j;break}b=null==b?g:b}}a="";null!=b&&(a=e+"trn="+b);return c+a}function Mf(a){var b=1,c;for(c in a.i)b=c.length>b?c.length:b;return 3997-b-a.j.length-1};function Nf(){this.h=Math.random()}function Of(){var a=Pf,b=w.google_srt;0<=b&&1>=b&&(a.h=b)}function Qf(a,b,c,d,e){if((d?a.h:Math.random())<(e||.01))try{if(c instanceof Hf)var f=c;else f=new Hf,Sc(c,function(h,k){var l=f,m=l.l++;h=If(k,h);l.h.push(m);l.i[m]=h});var g=Lf(f,"/pagead/gen_204?id="+b+"&");g&&Ef(w,g)}catch(h){}};var Rf={overlays:1,interstitials:2,vignettes:2,inserts:3,immersives:4,list_view:5};function Sf(){this.wasPlaTagProcessed=!1;this.wasReactiveAdConfigReceived={};this.adCount={};this.wasReactiveAdVisible={};this.stateForType={};this.reactiveTypeEnabledInAsfe={};this.wasReactiveTagRequestSent=!1;this.reactiveTypeDisabledByPublisher={};this.tagSpecificState={};this.messageValidationEnabled=!1;this.floatingAdsStacking=new Tf;this.sideRailProcessedFixedElements=new p.Set;this.sideRailAvailableSpace=new p.Map} function Uf(a){a.google_reactive_ads_global_state?(null==a.google_reactive_ads_global_state.sideRailProcessedFixedElements&&(a.google_reactive_ads_global_state.sideRailProcessedFixedElements=new p.Set),null==a.google_reactive_ads_global_state.sideRailAvailableSpace&&(a.google_reactive_ads_global_state.sideRailAvailableSpace=new p.Map)):a.google_reactive_ads_global_state=new Sf;return a.google_reactive_ads_global_state} function Tf(){this.maxZIndexRestrictions={};this.nextRestrictionId=0;this.maxZIndexListeners=[]};function Vf(a){a=a.document;var b={};a&&(b="CSS1Compat"==a.compatMode?a.documentElement:a.body);return b||{}}function Wf(a){return Vf(a).clientWidth};function Xf(a){return null!==a&&void 0!==a}function Yf(a,b){if(!b(a))throw Error(String(a));};function Zf(a){return"string"===typeof a}function $f(a){return void 0===a};function ag(a){J.call(this,a,-1,bg)}v(ag,J);var bg=[2,8],cg=[3,4,5],dg=[6,7];var eg;eg={Kb:0,Ya:3,Za:4,$a:5};var fg=eg.Ya,gg=eg.Za,hg=eg.$a;function ig(a){return null!=a?!a:a}function jg(a,b){for(var c=!1,d=0;d<a.length;d++){var e=a[d]();if(e===b)return e;null==e&&(c=!0)}if(!c)return!b}function kg(a,b){var c=H(a,ag,2);if(!c.length)return lg(a,b);a=C(a,1,0);if(1===a)return ig(kg(c[0],b));c=Ta(c,function(d){return function(){return kg(d,b)}});switch(a){case 2:return jg(c,!1);case 3:return jg(c,!0)}} function lg(a,b){var c=Cb(a,cg);a:{switch(c){case fg:var d=Hb(a,3,cg);break a;case gg:d=Hb(a,4,cg);break a;case hg:d=Hb(a,5,cg);break a}d=void 0}if(d&&(b=(b=b[c])&&b[d])){try{var e=b.apply(null,ka(wb(a,8)))}catch(f){return}b=C(a,1,0);if(4===b)return!!e;d=null!=e;if(5===b)return d;if(12===b)a=I(a,Db(a,dg,7));else a:{switch(c){case gg:a=yb(a,Db(a,dg,6));break a;case hg:a=I(a,Db(a,dg,7));break a}a=void 0}if(null!=a){if(6===b)return e===a;if(9===b)return null!=e&&0===Ka(String(e),a);if(d)switch(b){case 7:return e< a;case 8:return e>a;case 12:return Zf(a)&&Zf(e)&&(new RegExp(a)).test(e);case 10:return null!=e&&-1===Ka(String(e),a);case 11:return null!=e&&1===Ka(String(e),a)}}}}function mg(a,b){return!a||!(!b||!kg(a,b))};function ng(a){J.call(this,a,-1,og)}v(ng,J);var og=[4];function pg(a){J.call(this,a)}v(pg,J);function qg(a){J.call(this,a,-1,rg)}v(qg,J);var rg=[5],sg=[1,2,3,6,7];function tg(a){a.Sa.apply(a,ka(ta.apply(1,arguments).map(function(b){return{Xa:4,message:b}})))}function ug(a){a.Sa.apply(a,ka(ta.apply(1,arguments).map(function(b){return{Xa:7,message:b}})))};function vg(a){return function(){var b=ta.apply(0,arguments);try{return a.apply(this,b)}catch(c){}}}var wg=vg(function(a){var b=[],c={};a=u(a);for(var d=a.next();!d.done;c={ea:c.ea},d=a.next())c.ea=d.value,vg(function(e){return function(){b.push('[{"'+e.ea.Xa+'":'+Lb(e.ea.message)+"}]")}}(c))();return"[["+b.join(",")+"]]"});function xg(a,b){if(p.globalThis.fetch)p.globalThis.fetch(a,{method:"POST",body:b,keepalive:65536>b.length,credentials:"omit",mode:"no-cors",redirect:"follow"});else{var c=new XMLHttpRequest;c.open("POST",a,!0);c.send(b)}};function yg(a){var b=void 0===b?xg:b;this.l=void 0===a?1E3:a;this.j=b;this.i=[];this.h=null}yg.prototype.Sa=function(){var a=ta.apply(0,arguments),b=this;vg(function(){b.i.push.apply(b.i,ka(a));var c=vg(function(){var d=wg(b.i);b.j("https://pagead2.googlesyndication.com/pagead/ping?e=1",d);b.i=[];b.h=null});100<=b.i.length?(null!==b.h&&clearTimeout(b.h),b.h=setTimeout(c,0)):null===b.h&&(b.h=setTimeout(c,b.l))})()};function zg(a){J.call(this,a,-1,Ag)}v(zg,J);function Bg(a,b){return Eb(a,1,b)}function Cg(a,b){return Gb(a,2,b)}function Dg(a,b){return zb(a,4,b)}function Eg(a,b){return Gb(a,5,b)}function Fg(a,b){return Ab(a,6,b)}function Gg(a){J.call(this,a)}v(Gg,J);Gg.prototype.V=function(){return C(this,1,0)};function Hg(a,b){return Ab(a,1,b)}function Ig(a,b){return Ab(a,2,b)}function Jg(a){J.call(this,a)}v(Jg,J);var Ag=[2,4,5],Kg=[1,2];function Lg(a){J.call(this,a,-1,Mg)}v(Lg,J);function Ng(a){J.call(this,a,-1,Og)}v(Ng,J);var Mg=[2,3],Og=[5],Pg=[1,2,3,4];function Qg(a){J.call(this,a)}v(Qg,J);Qg.prototype.getTagSessionCorrelator=function(){return C(this,2,0)};function Rg(a){var b=new Qg;return Fb(b,4,Sg,a)}var Sg=[4,5,7];function Tg(a,b,c){var d=void 0===d?new yg(b):d;this.i=a;this.m=c;this.j=d;this.h=[];this.l=0<this.i&&Rc()<1/this.i}function Yg(a,b,c,d,e,f){var g=Ig(Hg(new Gg,b),c);b=Fg(Cg(Bg(Eg(Dg(new zg,d),e),g),a.h),f);b=Rg(b);a.l&&tg(a.j,Zg(a,b));if(1===f||3===f||4===f&&!a.h.some(function(h){return h.V()===g.V()&&C(h,2,0)===c}))a.h.push(g),100<a.h.length&&a.h.shift()}function $g(a,b,c,d){if(a.m){var e=new Lg;b=Gb(e,2,b);c=Gb(b,3,c);d&&Ab(c,1,d);d=new Qg;d=Fb(d,7,Sg,c);a.l&&tg(a.j,Zg(a,d))}} function Zg(a,b){b=Ab(b,1,Date.now());var c=fd(window);b=Ab(b,2,c);return Ab(b,6,a.i)};function ah(){var a={};this.h=(a[fg]={},a[gg]={},a[hg]={},a)};var bh=/^true$/.test("false");function ch(a,b){switch(b){case 1:return Hb(a,1,sg);case 2:return Hb(a,2,sg);case 3:return Hb(a,3,sg);case 6:return Hb(a,6,sg);default:return null}}function dh(a,b){if(!a)return null;switch(b){case 1:return D(a,1);case 7:return I(a,3);case 2:return yb(a,2);case 3:return I(a,3);case 6:return wb(a,4);default:return null}}var eh=vc(function(){if(!bh)return{};try{var a=window.sessionStorage&&window.sessionStorage.getItem("GGDFSSK");if(a)return JSON.parse(a)}catch(b){}return{}}); function fh(a,b,c,d){var e=d=void 0===d?0:d,f,g;O(gh).j[e]=null!=(g=null==(f=O(gh).j[e])?void 0:f.add(b))?g:(new p.Set).add(b);e=eh();if(null!=e[b])return e[b];b=hh(d)[b];if(!b)return c;b=new qg(b);b=ih(b);a=dh(b,a);return null!=a?a:c}function ih(a){var b=O(ah).h;if(b){var c=Wa(H(a,pg,5),function(d){return mg(G(d,ag,1),b)});if(c)return G(c,ng,2)}return G(a,ng,4)}function gh(){this.i={};this.l=[];this.j={};this.h=new p.Map}function jh(a,b,c){return!!fh(1,a,void 0===b?!1:b,c)} function kh(a,b,c){b=void 0===b?0:b;a=Number(fh(2,a,b,c));return isNaN(a)?b:a}function lh(a,b,c){return fh(3,a,void 0===b?"":b,c)}function mh(a,b,c){b=void 0===b?[]:b;return fh(6,a,b,c)}function hh(a){return O(gh).i[a]||(O(gh).i[a]={})}function nh(a,b){var c=hh(b);Sc(a,function(d,e){return c[e]=d})} function oh(a,b,c,d,e){e=void 0===e?!1:e;var f=[],g=[];Ra(b,function(h){var k=hh(h);Ra(a,function(l){var m=Cb(l,sg),q=ch(l,m);if(q){var t,y,F;var z=null!=(F=null==(t=O(gh).h.get(h))?void 0:null==(y=t.get(q))?void 0:y.slice(0))?F:[];a:{t=new Ng;switch(m){case 1:Bb(t,1,Pg,q);break;case 2:Bb(t,2,Pg,q);break;case 3:Bb(t,3,Pg,q);break;case 6:Bb(t,4,Pg,q);break;default:m=void 0;break a}zb(t,5,z);m=t}if(z=m){var E;z=!(null==(E=O(gh).j[h])||!E.has(q))}z&&f.push(m);if(E=m){var S;E=!(null==(S=O(gh).h.get(h))|| !S.has(q))}E&&g.push(m);e||(S=O(gh),S.h.has(h)||S.h.set(h,new p.Map),S.h.get(h).has(q)||S.h.get(h).set(q,[]),d&&S.h.get(h).get(q).push(d));k[q]=l.toJSON()}})});(f.length||g.length)&&$g(c,f,g,null!=d?d:void 0)}function ph(a,b){var c=hh(b);Ra(a,function(d){var e=new qg(d),f=Cb(e,sg);(e=ch(e,f))&&(c[e]||(c[e]=d))})}function qh(){return Ta(r(Object,"keys").call(Object,O(gh).i),function(a){return Number(a)})}function rh(a){Xa(O(gh).l,a)||nh(hh(4),a)};function sh(a){this.methodName=a}var th=new sh(1),uh=new sh(16),vh=new sh(15),wh=new sh(2),xh=new sh(3),yh=new sh(4),zh=new sh(5),Ah=new sh(6),Bh=new sh(7),Ch=new sh(8),Dh=new sh(9),Eh=new sh(10),Fh=new sh(11),Gh=new sh(12),Hh=new sh(13),Ih=new sh(14);function Jh(a,b,c){c.hasOwnProperty(a.methodName)||Object.defineProperty(c,String(a.methodName),{value:b})}function Kh(a,b,c){return b[a.methodName]||c||function(){}} function Lh(a){Jh(zh,jh,a);Jh(Ah,kh,a);Jh(Bh,lh,a);Jh(Ch,mh,a);Jh(Hh,ph,a);Jh(vh,rh,a)}function Mh(a){Jh(yh,function(b){O(ah).h=b},a);Jh(Dh,function(b,c){var d=O(ah);d.h[fg][b]||(d.h[fg][b]=c)},a);Jh(Eh,function(b,c){var d=O(ah);d.h[gg][b]||(d.h[gg][b]=c)},a);Jh(Fh,function(b,c){var d=O(ah);d.h[hg][b]||(d.h[hg][b]=c)},a);Jh(Ih,function(b){for(var c=O(ah),d=u([fg,gg,hg]),e=d.next();!e.done;e=d.next())e=e.value,r(Object,"assign").call(Object,c.h[e],b[e])},a)} function Nh(a){a.hasOwnProperty("init-done")||Object.defineProperty(a,"init-done",{value:!0})};function Oh(){this.l=function(){};this.i=function(){};this.j=function(){};this.h=function(){return[]}}function Ph(a,b,c){a.l=Kh(th,b,function(){});a.j=function(d){Kh(wh,b,function(){return[]})(d,c)};a.h=function(){return Kh(xh,b,function(){return[]})(c)};a.i=function(d){Kh(uh,b,function(){})(d,c)}};function Qh(a,b){var c=void 0===c?{}:c;this.error=a;this.context=b.context;this.msg=b.message||"";this.id=b.id||"jserror";this.meta=c}function Rh(a){return!!(a.error&&a.meta&&a.id)};var Sh=RegExp("^https?://(\\w|-)+\\.cdn\\.ampproject\\.(net|org)(\\?|/|$)");function Th(a,b){this.h=a;this.i=b}function Uh(a,b,c){this.url=a;this.u=b;this.La=!!c;this.depth=null};var Vh=null;function Wh(){if(null===Vh){Vh="";try{var a="";try{a=w.top.location.hash}catch(c){a=w.location.hash}if(a){var b=a.match(/\bdeid=([\d,]+)/);Vh=b?b[1]:""}}catch(c){}}return Vh};function Xh(){var a=void 0===a?w:a;return(a=a.performance)&&a.now&&a.timing?Math.floor(a.now()+a.timing.navigationStart):Date.now()}function Yh(){var a=void 0===a?w:a;return(a=a.performance)&&a.now?a.now():null};function Zh(a,b){var c=Yh()||Xh();this.label=a;this.type=b;this.value=c;this.duration=0;this.uniqueId=Math.random();this.slotId=void 0};var $h=w.performance,ai=!!($h&&$h.mark&&$h.measure&&$h.clearMarks),bi=vc(function(){var a;if(a=ai)a=Wh(),a=!!a.indexOf&&0<=a.indexOf("1337");return a});function ci(){this.i=[];this.j=w||w;var a=null;w&&(w.google_js_reporting_queue=w.google_js_reporting_queue||[],this.i=w.google_js_reporting_queue,a=w.google_measure_js_timing);this.h=bi()||(null!=a?a:1>Math.random())} function di(a){a&&$h&&bi()&&($h.clearMarks("goog_"+a.label+"_"+a.uniqueId+"_start"),$h.clearMarks("goog_"+a.label+"_"+a.uniqueId+"_end"))}ci.prototype.start=function(a,b){if(!this.h)return null;a=new Zh(a,b);b="goog_"+a.label+"_"+a.uniqueId+"_start";$h&&bi()&&$h.mark(b);return a};ci.prototype.end=function(a){if(this.h&&"number"===typeof a.value){a.duration=(Yh()||Xh())-a.value;var b="goog_"+a.label+"_"+a.uniqueId+"_end";$h&&bi()&&$h.mark(b);!this.h||2048<this.i.length||this.i.push(a)}};function ei(){var a=fi;this.m=Pf;this.i=null;this.l=this.I;this.h=void 0===a?null:a;this.j=!1}n=ei.prototype;n.Ua=function(a){this.l=a};n.Ta=function(a){this.i=a};n.Va=function(a){this.j=a};n.oa=function(a,b,c){try{if(this.h&&this.h.h){var d=this.h.start(a.toString(),3);var e=b();this.h.end(d)}else e=b()}catch(h){b=!0;try{di(d),b=this.l(a,new Qh(h,{message:gi(h)}),void 0,c)}catch(k){this.I(217,k)}if(b){var f,g;null==(f=window.console)||null==(g=f.error)||g.call(f,h)}else throw h;}return e}; n.Oa=function(a,b){var c=this;return function(){var d=ta.apply(0,arguments);return c.oa(a,function(){return b.apply(void 0,d)})}}; n.I=function(a,b,c,d,e){e=e||"jserror";try{var f=new Hf;f.h.push(1);f.i[1]=If("context",a);Rh(b)||(b=new Qh(b,{message:gi(b)}));if(b.msg){var g=b.msg.substring(0,512);f.h.push(2);f.i[2]=If("msg",g)}var h=b.meta||{};if(this.i)try{this.i(h)}catch(Jc){}if(d)try{d(h)}catch(Jc){}b=[h];f.h.push(3);f.i[3]=b;d=w;b=[];g=null;do{var k=d;if(Hc(k)){var l=k.location.href;g=k.document&&k.document.referrer||null}else l=g,g=null;b.push(new Uh(l||"",k));try{d=k.parent}catch(Jc){d=null}}while(d&&k!=d);l=0;for(var m= b.length-1;l<=m;++l)b[l].depth=m-l;k=w;if(k.location&&k.location.ancestorOrigins&&k.location.ancestorOrigins.length==b.length-1)for(m=1;m<b.length;++m){var q=b[m];q.url||(q.url=k.location.ancestorOrigins[m-1]||"",q.La=!0)}var t=new Uh(w.location.href,w,!1);k=null;var y=b.length-1;for(q=y;0<=q;--q){var F=b[q];!k&&Sh.test(F.url)&&(k=F);if(F.url&&!F.La){t=F;break}}F=null;var z=b.length&&b[y].url;0!=t.depth&&z&&(F=b[y]);var E=new Th(t,F);if(E.i){var S=E.i.url||"";f.h.push(4);f.i[4]=If("top",S)}var rb= {url:E.h.url||""};if(E.h.url){var Kc=E.h.url.match(Ec),Ug=Kc[1],Vg=Kc[3],Wg=Kc[4];t="";Ug&&(t+=Ug+":");Vg&&(t+="//",t+=Vg,Wg&&(t+=":"+Wg));var Xg=t}else Xg="";rb=[rb,{url:Xg}];f.h.push(5);f.i[5]=rb;Qf(this.m,e,f,this.j,c)}catch(Jc){try{Qf(this.m,e,{context:"ecmserr",rctx:a,msg:gi(Jc),url:E&&E.h.url},this.j,c)}catch(zp){}}return!0};n.Pa=function(a,b){var c=this;b.catch(function(d){d=d?d:"unknown rejection";c.I(a,d instanceof Error?d:Error(d))})}; function gi(a){var b=a.toString();a.name&&-1==b.indexOf(a.name)&&(b+=": "+a.name);a.message&&-1==b.indexOf(a.message)&&(b+=": "+a.message);if(a.stack){a=a.stack;try{-1==a.indexOf(b)&&(a=b+"\n"+a);for(var c;a!=c;)c=a,a=a.replace(/((https?:\/..*\/)[^\/:]*:\d+(?:.|\n)*)\2/,"$1");b=a.replace(/\n */g,"\n")}catch(d){}}return b};var hi=ja(["https://www.googletagservices.com/console/host/host.js"]),ii=ja(["https://www.googletagservices.com/console/panel/index.html"]),ji=ja(["https://www.googletagservices.com/console/overlay/index.html"]);nd(hi);nd(ii);nd(ji);function ki(a,b){do{var c=Nc(a,b);if(c&&"fixed"==c.position)return!1}while(a=a.parentElement);return!0};function li(a,b){for(var c=["width","height"],d=0;d<c.length;d++){var e="google_ad_"+c[d];if(!b.hasOwnProperty(e)){var f=K(a[c[d]]);f=null===f?null:Math.round(f);null!=f&&(b[e]=f)}}}function mi(a,b){return!((Yc.test(b.google_ad_width)||Xc.test(a.style.width))&&(Yc.test(b.google_ad_height)||Xc.test(a.style.height)))}function ni(a,b){return(a=oi(a,b))?a.y:0} function oi(a,b){try{var c=b.document.documentElement.getBoundingClientRect(),d=a.getBoundingClientRect();return{x:d.left-c.left,y:d.top-c.top}}catch(e){return null}}function pi(a){var b=0,c;for(c in Df)-1!=a.indexOf(c)&&(b|=Df[c]);return b} function qi(a,b,c,d,e){if(a!==a.top)return Ic(a)?3:16;if(!(488>Wf(a)))return 4;if(!(a.innerHeight>=a.innerWidth))return 5;var f=Wf(a);if(!f||(f-c)/f>d)a=6;else{if(c="true"!=e.google_full_width_responsive)a:{c=Wf(a);for(b=b.parentElement;b;b=b.parentElement)if((d=Nc(b,a))&&(e=K(d.width))&&!(e>=c)&&"visible"!=d.overflow){c=!0;break a}c=!1}a=c?7:!0}return a} function ri(a,b,c,d){var e=qi(b,c,a,.3,d);!0!==e?a=e:"true"==d.google_full_width_responsive||ki(c,b)?(b=Wf(b),a=b-a,a=b&&0<=a?!0:b?-10>a?11:0>a?14:12:10):a=9;return a}function si(a,b,c){a=a.style;"rtl"==b?a.marginRight=c:a.marginLeft=c} function ti(a,b){if(3==b.nodeType)return/\S/.test(b.data);if(1==b.nodeType){if(/^(script|style)$/i.test(b.nodeName))return!1;try{var c=Nc(b,a)}catch(d){}return!c||"none"!=c.display&&!("absolute"==c.position&&("hidden"==c.visibility||"collapse"==c.visibility))}return!1}function ui(a,b,c){a=oi(b,a);return"rtl"==c?-a.x:a.x} function vi(a,b){var c;c=(c=b.parentElement)?(c=Nc(c,a))?c.direction:"":"";if(c){b.style.border=b.style.borderStyle=b.style.outline=b.style.outlineStyle=b.style.transition="none";b.style.borderSpacing=b.style.padding="0";si(b,c,"0px");b.style.width=Wf(a)+"px";if(0!==ui(a,b,c)){si(b,c,"0px");var d=ui(a,b,c);si(b,c,-1*d+"px");a=ui(a,b,c);0!==a&&a!==d&&si(b,c,d/(a-d)*d+"px")}b.style.zIndex=30}};function wi(a,b){this.l=a;this.j=b}wi.prototype.minWidth=function(){return this.l};wi.prototype.height=function(){return this.j};wi.prototype.h=function(a){return 300<a&&300<this.j?this.l:Math.min(1200,Math.round(a))};wi.prototype.i=function(){};function xi(a,b,c,d){d=void 0===d?function(f){return f}:d;var e;return a.style&&a.style[c]&&d(a.style[c])||(e=Nc(a,b))&&e[c]&&d(e[c])||null}function yi(a){return function(b){return b.minWidth()<=a}}function zi(a,b,c,d){var e=a&&Ai(c,b),f=Bi(b,d);return function(g){return!(e&&g.height()>=f)}}function Ci(a){return function(b){return b.height()<=a}}function Ai(a,b){return ni(a,b)<Vf(b).clientHeight-100} function Di(a,b){var c=xi(b,a,"height",K);if(c)return c;var d=b.style.height;b.style.height="inherit";c=xi(b,a,"height",K);b.style.height=d;if(c)return c;c=Infinity;do(d=b.style&&K(b.style.height))&&(c=Math.min(c,d)),(d=xi(b,a,"maxHeight",K))&&(c=Math.min(c,d));while((b=b.parentElement)&&"HTML"!=b.tagName);return c}function Bi(a,b){var c=0==pd(a);return b&&c?Math.max(250,2*Vf(a).clientHeight/3):250};var R={},Ei=(R.google_ad_channel=!0,R.google_ad_client=!0,R.google_ad_host=!0,R.google_ad_host_channel=!0,R.google_adtest=!0,R.google_tag_for_child_directed_treatment=!0,R.google_tag_for_under_age_of_consent=!0,R.google_tag_partner=!0,R.google_restrict_data_processing=!0,R.google_page_url=!0,R.google_debug_params=!0,R.google_adbreak_test=!0,R.google_ad_frequency_hint=!0,R.google_admob_interstitial_slot=!0,R.google_admob_rewarded_slot=!0,R.google_max_ad_content_rating=!0,R.google_traffic_source=!0, R),Fi=RegExp("(^| )adsbygoogle($| )");function Gi(a,b){for(var c=0;c<b.length;c++){var d=b[c],e=zc(d.Rb);a[e]=d.value}};function Hi(a,b,c,d){this.l=a;this.i=b;this.j=c;this.h=d}function Ii(a,b){var c=[];try{c=b.querySelectorAll(a.l)}catch(g){}if(!c.length)return[];b=Ya(c);b=Ji(a,b);"number"===typeof a.i&&(c=a.i,0>c&&(c+=b.length),b=0<=c&&c<b.length?[b[c]]:[]);if("number"===typeof a.j){c=[];for(var d=0;d<b.length;d++){var e=Ki(b[d]),f=a.j;0>f&&(f+=e.length);0<=f&&f<e.length&&c.push(e[f])}b=c}return b} Hi.prototype.toString=function(){return JSON.stringify({nativeQuery:this.l,occurrenceIndex:this.i,paragraphIndex:this.j,ignoreMode:this.h})};function Ji(a,b){if(null==a.h)return b;switch(a.h){case 1:return b.slice(1);case 2:return b.slice(0,b.length-1);case 3:return b.slice(1,b.length-1);case 0:return b;default:throw Error("Unknown ignore mode: "+a.h);}}function Ki(a){var b=[];xd(a.getElementsByTagName("p"),function(c){100<=Li(c)&&b.push(c)});return b} function Li(a){if(3==a.nodeType)return a.length;if(1!=a.nodeType||"SCRIPT"==a.tagName)return 0;var b=0;xd(a.childNodes,function(c){b+=Li(c)});return b}function Mi(a){return 0==a.length||isNaN(a[0])?a:"\\"+(30+parseInt(a[0],10))+" "+a.substring(1)};function Ni(a){if(!a)return null;var b=A(a,7);if(A(a,1)||a.getId()||0<wb(a,4).length){var c=a.getId();b=wb(a,4);var d=A(a,1),e="";d&&(e+=d);c&&(e+="#"+Mi(c));if(b)for(c=0;c<b.length;c++)e+="."+Mi(b[c]);a=(b=e)?new Hi(b,A(a,2),A(a,5),Oi(A(a,6))):null}else a=b?new Hi(b,A(a,2),A(a,5),Oi(A(a,6))):null;return a}var Pi={1:1,2:2,3:3,0:0};function Oi(a){return null==a?a:Pi[a]}var Qi={1:0,2:1,3:2,4:3};function Ri(a){return a.google_ama_state=a.google_ama_state||{}} function Si(a){a=Ri(a);return a.optimization=a.optimization||{}};function Ti(a){switch(A(a,8)){case 1:case 2:if(null==a)var b=null;else b=G(a,Jd,1),null==b?b=null:(a=A(a,2),b=null==a?null:new Ld({Ga:[b],Ra:a}));return null!=b?Dd(b):Fd(Error("Missing dimension when creating placement id"));case 3:return Fd(Error("Missing dimension when creating placement id"));default:return Fd(Error("Invalid type: "+A(a,8)))}};function T(a){a=void 0===a?"":a;var b=Error.call(this);this.message=b.message;"stack"in b&&(this.stack=b.stack);this.name="TagError";this.message=a?"adsbygoogle.push() error: "+a:"";Error.captureStackTrace?Error.captureStackTrace(this,T):this.stack=Error().stack||""}v(T,Error);var Pf,Ui,fi=new ci;function Vi(a){null!=a&&(w.google_measure_js_timing=a);w.google_measure_js_timing||(a=fi,a.h=!1,a.i!=a.j.google_js_reporting_queue&&(bi()&&Ra(a.i,di),a.i.length=0))}(function(a){Pf=a||new Nf;"number"!==typeof w.google_srt&&(w.google_srt=Math.random());Of();Ui=new ei;Ui.Va(!0);"complete"==w.document.readyState?Vi():fi.h&&xc(w,"load",function(){Vi()})})();function Wi(a,b,c){return Ui.oa(a,b,c)}function Xi(a,b){return Ui.Oa(a,b)} function Yi(a,b,c){var d=O(Oh).h();!b.eid&&d.length&&(b.eid=d.toString());Qf(Pf,a,b,!0,c)}function Zi(a,b){Ui.Pa(a,b)}function $i(a,b,c,d){var e;Rh(b)?e=b.msg||gi(b.error):e=gi(b);return 0==e.indexOf("TagError")?(c=b instanceof Qh?b.error:b,c.pbr||(c.pbr=!0,Ui.I(a,b,.1,d,"puberror")),!1):Ui.I(a,b,c,d)};function aj(a){a=void 0===a?window:a;a=a.googletag;return(null==a?0:a.apiReady)?a:void 0};function bj(a){var b=aj(a);return b?Sa(Ta(b.pubads().getSlots(),function(c){return a.document.getElementById(c.getSlotElementId())}),function(c){return null!=c}):null}function cj(a,b){return Ya(a.document.querySelectorAll(b))}function dj(a){var b=[];a=u(a);for(var c=a.next();!c.done;c=a.next()){c=c.value;for(var d=!0,e=0;e<b.length;e++){var f=b[e];if(f.contains(c)){d=!1;break}if(c.contains(f)){d=!1;b[e]=c;break}}d&&b.push(c)}return b};function ej(a,b){function c(){d.push({anchor:e.anchor,position:e.position});return e.anchor==b.anchor&&e.position==b.position}for(var d=[],e=a;e;){switch(e.position){case 1:if(c())return d;e.position=2;case 2:if(c())return d;if(e.anchor.firstChild){e={anchor:e.anchor.firstChild,position:1};continue}else e.position=3;case 3:if(c())return d;e.position=4;case 4:if(c())return d}for(;e&&!e.anchor.nextSibling&&e.anchor.parentNode!=e.anchor.ownerDocument.body;){e={anchor:e.anchor.parentNode,position:3}; if(c())return d;e.position=4;if(c())return d}e&&e.anchor.nextSibling?e={anchor:e.anchor.nextSibling,position:1}:e=null}return d};function fj(a,b){this.i=a;this.h=b} function gj(a,b){var c=new Id,d=new Hd;b.forEach(function(e){if(Ib(e,Yd,1,ae)){e=Ib(e,Yd,1,ae);if(G(e,Wd,1)&&G(G(e,Wd,1),Jd,1)&&G(e,Wd,2)&&G(G(e,Wd,2),Jd,1)){var f=hj(a,G(G(e,Wd,1),Jd,1)),g=hj(a,G(G(e,Wd,2),Jd,1));if(f&&g)for(f=u(ej({anchor:f,position:A(G(e,Wd,1),2)},{anchor:g,position:A(G(e,Wd,2),2)})),g=f.next();!g.done;g=f.next())g=g.value,c.set(za(g.anchor),g.position)}G(e,Wd,3)&&G(G(e,Wd,3),Jd,1)&&(f=hj(a,G(G(e,Wd,3),Jd,1)))&&c.set(za(f),A(G(e,Wd,3),2))}else Ib(e,Zd,2,ae)?ij(a,Ib(e,Zd,2,ae), c):Ib(e,$d,3,ae)&&jj(a,Ib(e,$d,3,ae),d)});return new fj(c,d)}function ij(a,b,c){G(b,Jd,1)&&(a=kj(a,G(b,Jd,1)))&&a.forEach(function(d){d=za(d);c.set(d,1);c.set(d,4);c.set(d,2);c.set(d,3)})}function jj(a,b,c){G(b,Jd,1)&&(a=kj(a,G(b,Jd,1)))&&a.forEach(function(d){c.add(za(d))})}function hj(a,b){return(a=kj(a,b))&&0<a.length?a[0]:null}function kj(a,b){return(b=Ni(b))?Ii(b,a):null};function lj(){this.h=new p.Set}function mj(a){a=nj(a);return a.has("all")||a.has("after")}function oj(a){a=nj(a);return a.has("all")||a.has("before")}function pj(a,b,c){switch(c){case 2:case 3:break;case 1:case 4:b=b.parentElement;break;default:throw Error("Unknown RelativePosition: "+c);}for(c=[];b;){if(qj(b))return!0;if(a.h.has(b))break;c.push(b);b=b.parentElement}c.forEach(function(d){return a.h.add(d)});return!1} function qj(a){var b=nj(a);return a&&("AUTO-ADS-EXCLUSION-AREA"===a.tagName||b.has("inside")||b.has("all"))}function nj(a){return(a=a&&a.getAttribute("data-no-auto-ads"))?new p.Set(a.split("|")):new p.Set};function rj(a,b){if(!a)return!1;a=Nc(a,b);if(!a)return!1;a=a.cssFloat||a.styleFloat;return"left"==a||"right"==a}function sj(a){for(a=a.previousSibling;a&&1!=a.nodeType;)a=a.previousSibling;return a?a:null}function tj(a){return!!a.nextSibling||!!a.parentNode&&tj(a.parentNode)};function uj(a){var b={};a&&wb(a,6).forEach(function(c){b[c]=!0});return b}function vj(a,b,c,d,e){this.h=a;this.H=b;this.j=c;this.m=e||null;this.A=(this.C=d)?gj(a.document,H(d,Xd,5)):gj(a.document,[]);this.G=new lj;this.i=0;this.l=!1} function wj(a,b){if(a.l)return!0;a.l=!0;var c=H(a.j,ce,1);a.i=0;var d=uj(a.C);var e=a.h;try{var f=e.localStorage.getItem("google_ama_settings");var g=f?Nb(se,f):null}catch(S){g=null}var h=null!==g&&D(g,2,!1);g=Ri(e);h&&(g.eatf=!0,kd(7,[!0,0,!1]));var k=P(Ve)||P(Ue);f=P(Ue);if(k){b:{var l={fb:!1},m=cj(e,".google-auto-placed"),q=cj(e,'ins.adsbygoogle[data-anchor-shown="true"]'),t=cj(e,"ins.adsbygoogle[data-ad-format=autorelaxed]");var y=(bj(e)||cj(e,"div[id^=div-gpt-ad]")).concat(cj(e,"iframe[id^=google_ads_iframe]")); var F=cj(e,"div.trc_related_container,div.OUTBRAIN,div[id^=rcjsload],div[id^=ligatusframe],div[id^=crt-],iframe[id^=cto_iframe],div[id^=yandex_], div[id^=Ya_sync],iframe[src*=adnxs],div.advertisement--appnexus,div[id^=apn-ad],div[id^=amzn-native-ad],iframe[src*=amazon-adsystem],iframe[id^=ox_],iframe[src*=openx],img[src*=openx],div[class*=adtech],div[id^=adtech],iframe[src*=adtech],div[data-content-ad-placement=true],div.wpcnt div[id^=atatags-]"),z=cj(e,"ins.adsbygoogle-ablated-ad-slot"),E=cj(e,"div.googlepublisherpluginad"); k=[].concat(cj(e,"iframe[id^=aswift_],iframe[id^=google_ads_frame]"),cj(e,"ins.adsbygoogle"));h=[];l=u([[l.Mb,m],[l.fb,q],[l.Pb,t],[l.Nb,y],[l.Qb,F],[l.Lb,z],[l.Ob,E]]);for(m=l.next();!m.done;m=l.next())q=u(m.value),m=q.next().value,q=q.next().value,!1===m?h=h.concat(q):k=k.concat(q);k=dj(k);l=dj(h);h=k.slice(0);k=u(l);for(l=k.next();!l.done;l=k.next())for(l=l.value,m=0;m<h.length;m++)(l.contains(h[m])||h[m].contains(l))&&h.splice(m,1);e=Vf(e).clientHeight;for(k=0;k<h.length;k++)if(l=h[k].getBoundingClientRect(), !(0===l.height&&!f||l.top>e)){e=!0;break b}e=!1}g=e?g.eatfAbg=!0:!1}else g=h;if(g)return!0;g=new Hd([2]);for(e=0;e<c.length;e++){f=a;k=c[e];h=e;l=b;if(!G(k,Pd,4)||!g.contains(A(G(k,Pd,4),1))||1!==A(k,8)||k&&null!=A(k,4)&&d[A(G(k,Pd,4),2)])f=null;else{f.i++;if(k=xj(f,k,l,d))l=Ri(f.h),l.numAutoAdsPlaced||(l.numAutoAdsPlaced=0),null==l.placed&&(l.placed=[]),l.numAutoAdsPlaced++,l.placed.push({index:h,element:k.ha}),kd(7,[!1,f.i,!0]);f=k}if(f)return!0}kd(7,[!1,a.i,!1]);return!1} function xj(a,b,c,d){if(b&&null!=A(b,4)&&d[A(G(b,Pd,4),2)]||1!=A(b,8))return null;d=G(b,Jd,1);if(!d)return null;d=Ni(d);if(!d)return null;d=Ii(d,a.h.document);if(0==d.length)return null;d=d[0];var e=Qi[A(b,2)];e=void 0===e?null:e;var f;if(!(f=null==e)){a:{f=a.h;switch(e){case 0:f=rj(sj(d),f);break a;case 3:f=rj(d,f);break a;case 2:var g=d.lastChild;f=rj(g?1==g.nodeType?g:sj(g):null,f);break a}f=!1}if(c=!f&&!(!c&&2==e&&!tj(d)))c=1==e||2==e?d:d.parentNode,c=!(c&&!te(c)&&0>=c.offsetWidth);f=!c}if(!(c= f)){c=a.A;f=A(b,2);g=za(d);g=c.i.h.get(g);if(!(g=g?g.contains(f):!1))a:{if(c.h.contains(za(d)))switch(f){case 2:case 3:g=!0;break a;default:g=!1;break a}for(f=d.parentElement;f;){if(c.h.contains(za(f))){g=!0;break a}f=f.parentElement}g=!1}c=g}if(!c){c=a.G;f=A(b,2);a:switch(f){case 1:g=mj(d.previousElementSibling)||oj(d);break a;case 4:g=mj(d)||oj(d.nextElementSibling);break a;case 2:g=oj(d.firstElementChild);break a;case 3:g=mj(d.lastElementChild);break a;default:throw Error("Unknown RelativePosition: "+ f);}c=g||pj(c,d,f)}if(c)return null;c=G(b,be,3);f={};c&&(f.Wa=A(c,1),f.Ha=A(c,2),f.cb=!!xb(c,3));c=G(b,Pd,4)&&A(G(b,Pd,4),2)?A(G(b,Pd,4),2):null;c=Sd(c);g=null!=A(b,12)?A(b,12):null;g=null==g?null:new Qd(null,{google_ml_rank:g});b=yj(a,b);b=Rd(a.m,c,g,b);c=a.h;a=a.H;var h=c.document,k=f.cb||!1;g=(new Bc(h)).createElement("DIV");var l=g.style;l.width="100%";l.height="auto";l.clear=k?"both":"none";k=g.style;k.textAlign="center";f.lb&&Gi(k,f.lb);h=(new Bc(h)).createElement("INS");k=h.style;k.display= "block";k.margin="auto";k.backgroundColor="transparent";f.Wa&&(k.marginTop=f.Wa);f.Ha&&(k.marginBottom=f.Ha);f.ab&&Gi(k,f.ab);g.appendChild(h);f={ra:g,ha:h};f.ha.setAttribute("data-ad-format","auto");g=[];if(h=b&&b.Ja)f.ra.className=h.join(" ");h=f.ha;h.className="adsbygoogle";h.setAttribute("data-ad-client",a);g.length&&h.setAttribute("data-ad-channel",g.join("+"));a:{try{var m=f.ra;var q=void 0===q?0:q;if(P(Qe)){q=void 0===q?0:q;var t=Af(d,e,q);if(t.init){var y=t.init;for(d=y;d=t.ja(d);)y=d;var F= {anchor:y,position:t.na}}else F={anchor:d,position:e};m["google-ama-order-assurance"]=q;ue(m,F.anchor,F.position)}else ue(m,d,e);b:{var z=f.ha;z.dataset.adsbygoogleStatus="reserved";z.className+=" adsbygoogle-noablate";m={element:z};var E=b&&b.Qa;if(z.hasAttribute("data-pub-vars")){try{E=JSON.parse(z.getAttribute("data-pub-vars"))}catch(S){break b}z.removeAttribute("data-pub-vars")}E&&(m.params=E);(c.adsbygoogle=c.adsbygoogle||[]).push(m)}}catch(S){(z=f.ra)&&z.parentNode&&(E=z.parentNode,E.removeChild(z), te(E)&&(E.style.display=E.getAttribute("data-init-display")||"none"));z=!1;break a}z=!0}return z?f:null}function yj(a,b){return Bd(Ed(Ti(b).map(Td),function(c){Ri(a.h).exception=c}))};function zj(a){if(P(Pe))var b=null;else try{b=a.getItem("google_ama_config")}catch(d){b=null}try{var c=b?Nb(je,b):null}catch(d){c=null}return c};function Aj(a){J.call(this,a)}v(Aj,J);function Bj(a){try{var b=a.localStorage.getItem("google_auto_fc_cmp_setting")||null}catch(d){b=null}var c=b;return c?Gd(function(){return Nb(Aj,c)}):Dd(null)};function Cj(){this.S={}}function Dj(){if(Ej)return Ej;var a=md()||window,b=a.google_persistent_state_async;return null!=b&&"object"==typeof b&&null!=b.S&&"object"==typeof b.S?Ej=b:a.google_persistent_state_async=Ej=new Cj}function Fj(a){return Gj[a]||"google_ps_"+a}function Hj(a,b,c){b=Fj(b);a=a.S;var d=a[b];return void 0===d?a[b]=c:d}var Ej=null,Ij={},Gj=(Ij[8]="google_prev_ad_formats_by_region",Ij[9]="google_prev_ad_slotnames_by_region",Ij);function Jj(a){this.h=a||{cookie:""}} Jj.prototype.set=function(a,b,c){var d=!1;if("object"===typeof c){var e=c.Sb;d=c.Tb||!1;var f=c.domain||void 0;var g=c.path||void 0;var h=c.jb}if(/[;=\s]/.test(a))throw Error('Invalid cookie name "'+a+'"');if(/[;\r\n]/.test(b))throw Error('Invalid cookie value "'+b+'"');void 0===h&&(h=-1);this.h.cookie=a+"="+b+(f?";domain="+f:"")+(g?";path="+g:"")+(0>h?"":0==h?";expires="+(new Date(1970,1,1)).toUTCString():";expires="+(new Date(Date.now()+1E3*h)).toUTCString())+(d?";secure":"")+(null!=e?";samesite="+ e:"")};Jj.prototype.get=function(a,b){for(var c=a+"=",d=(this.h.cookie||"").split(";"),e=0,f;e<d.length;e++){f=Ja(d[e]);if(0==f.lastIndexOf(c,0))return f.substr(c.length);if(f==a)return""}return b};Jj.prototype.isEmpty=function(){return!this.h.cookie}; Jj.prototype.clear=function(){for(var a=(this.h.cookie||"").split(";"),b=[],c=[],d,e,f=0;f<a.length;f++)e=Ja(a[f]),d=e.indexOf("="),-1==d?(b.push(""),c.push(e)):(b.push(e.substring(0,d)),c.push(e.substring(d+1)));for(a=b.length-1;0<=a;a--)c=b[a],this.get(c),this.set(c,"",{jb:0,path:void 0,domain:void 0})};function Kj(a){J.call(this,a)}v(Kj,J);function Lj(a){var b=new Kj;return B(b,5,a)};function Mj(){this.A=this.A;this.G=this.G}Mj.prototype.A=!1;Mj.prototype.j=function(){if(this.G)for(;this.G.length;)this.G.shift()()};function Nj(a){void 0!==a.addtlConsent&&"string"!==typeof a.addtlConsent&&(a.addtlConsent=void 0);void 0!==a.gdprApplies&&"boolean"!==typeof a.gdprApplies&&(a.gdprApplies=void 0);return void 0!==a.tcString&&"string"!==typeof a.tcString||void 0!==a.listenerId&&"number"!==typeof a.listenerId?2:a.cmpStatus&&"error"!==a.cmpStatus?0:3}function Oj(a,b){b=void 0===b?500:b;Mj.call(this);this.h=a;this.i=null;this.m={};this.H=0;this.C=b;this.l=null}v(Oj,Mj); Oj.prototype.j=function(){this.m={};this.l&&(yc(this.h,this.l),delete this.l);delete this.m;delete this.h;delete this.i;Mj.prototype.j.call(this)};function Pj(a){return"function"===typeof a.h.__tcfapi||null!=Qj(a)} Oj.prototype.addEventListener=function(a){function b(f,g){clearTimeout(e);f?(c=f,c.internalErrorState=Nj(c),g&&0===c.internalErrorState||(c.tcString="tcunavailable",g||(c.internalErrorState=3))):(c.tcString="tcunavailable",c.internalErrorState=3);a(c)}var c={},d=wc(function(){return a(c)}),e=0;-1!==this.C&&(e=setTimeout(function(){c.tcString="tcunavailable";c.internalErrorState=1;d()},this.C));try{Rj(this,"addEventListener",b)}catch(f){c.tcString="tcunavailable",c.internalErrorState=3,e&&(clearTimeout(e), e=0),d()}};Oj.prototype.removeEventListener=function(a){a&&a.listenerId&&Rj(this,"removeEventListener",null,a.listenerId)};function Rj(a,b,c,d){c||(c=function(){});if("function"===typeof a.h.__tcfapi)a=a.h.__tcfapi,a(b,2,c,d);else if(Qj(a)){Sj(a);var e=++a.H;a.m[e]=c;a.i&&(c={},a.i.postMessage((c.__tcfapiCall={command:b,version:2,callId:e,parameter:d},c),"*"))}else c({},!1)}function Qj(a){if(a.i)return a.i;a.i=$c(a.h,"__tcfapiLocator");return a.i} function Sj(a){a.l||(a.l=function(b){try{var c=("string"===typeof b.data?JSON.parse(b.data):b.data).__tcfapiReturn;a.m[c.callId](c.returnValue,c.success)}catch(d){}},xc(a.h,"message",a.l))};function Tj(a){var b=a.u,c=a.ta,d=a.Ia;a=Uj({u:b,Z:a.Z,ka:void 0===a.ka?!1:a.ka,la:void 0===a.la?!1:a.la});null!=a.h||"tcunav"!=a.i.message?d(a):Vj(b,c).then(function(e){return e.map(Wj)}).then(function(e){return e.map(function(f){return Xj(b,f)})}).then(d)} function Uj(a){var b=a.u,c=a.Z,d=void 0===a.ka?!1:a.ka;if(!(a=!(void 0===a.la?0:a.la)&&Pj(new Oj(b)))){if(d=!d){if(c){c=Bj(b);if(null==c.h)Ui.I(806,c.i,void 0,void 0),c=!1;else if((c=c.h.value)&&null!=A(c,1))b:switch(c=A(c,1),c){case 1:c=!0;break b;default:throw Error("Unhandled AutoGdprFeatureStatus: "+c);}else c=!1;c=!c}d=c}a=d}if(!a)return Xj(b,Lj(!0));c=Dj();return(c=Hj(c,24))?Xj(b,Wj(c)):Fd(Error("tcunav"))}function Vj(a,b){return p.Promise.race([Yj(),Zj(a,b)])} function Yj(){return(new p.Promise(function(a){var b=Dj();a={resolve:a};var c=Hj(b,25,[]);c.push(a);b.S[Fj(25)]=c})).then(ak)}function Zj(a,b){return new p.Promise(function(c){a.setTimeout(c,b,Fd(Error("tcto")))})}function ak(a){return a?Dd(a):Fd(Error("tcnull"))} function Wj(a){var b=void 0===b?!1:b;if(!1===a.gdprApplies)var c=!0;else void 0===a.internalErrorState&&(a.internalErrorState=Nj(a)),c="error"===a.cmpStatus||0!==a.internalErrorState||"loaded"===a.cmpStatus&&("tcloaded"===a.eventStatus||"useractioncomplete"===a.eventStatus)?!0:!1;if(c)if(!1===a.gdprApplies||"tcunavailable"===a.tcString||void 0===a.gdprApplies&&!b||"string"!==typeof a.tcString||!a.tcString.length)a=!0;else{var d=void 0===d?"755":d;b:{if(a.publisher&&a.publisher.restrictions&&(b=a.publisher.restrictions["1"], void 0!==b)){b=b[void 0===d?"755":d];break b}b=void 0}0===b?a=!1:a.purpose&&a.vendor?(b=a.vendor.consents,(d=!(!b||!b[void 0===d?"755":d]))&&a.purposeOneTreatment&&"CH"===a.publisherCC?a=!0:(d&&(a=a.purpose.consents,d=!(!a||!a["1"])),a=d)):a=!0}else a=!1;return Lj(a)}function Xj(a,b){a:{a=void 0===a?window:a;if(xb(b,5))try{var c=a.localStorage;break a}catch(d){}c=null}return(b=c)?Dd(b):Fd(Error("unav"))};function bk(a){J.call(this,a)}v(bk,J);function ck(a){J.call(this,a,-1,dk)}v(ck,J);var dk=[1,2];function ek(a){this.exception=a}function fk(a,b,c){this.j=a;this.h=b;this.i=c}fk.prototype.start=function(){this.l()};fk.prototype.l=function(){try{switch(this.j.document.readyState){case "complete":case "interactive":wj(this.h,!0);gk(this);break;default:wj(this.h,!1)?gk(this):this.j.setTimeout(Ea(this.l,this),100)}}catch(a){gk(this,a)}};function gk(a,b){try{var c=a.i,d=c.resolve,e=a.h;Ri(e.h);H(e.j,ce,1);d.call(c,new ek(b))}catch(f){a.i.reject(f)}};function hk(a){J.call(this,a,-1,ik)}v(hk,J);function jk(a){J.call(this,a)}v(jk,J);function kk(a){J.call(this,a)}v(kk,J);var ik=[7];function lk(a){a=(a=(new Jj(a)).get("FCCDCF",""))?a:null;try{return a?Nb(hk,a):null}catch(b){return null}};Zb({Gb:0,Fb:1,Cb:2,xb:3,Db:4,yb:5,Eb:6,Ab:7,Bb:8,wb:9,zb:10}).map(function(a){return Number(a)});Zb({Ib:0,Jb:1,Hb:2}).map(function(a){return Number(a)});function mk(a){function b(){if(!a.frames.__uspapiLocator)if(c.body){var d=Mc("IFRAME",c);d.style.display="none";d.style.width="0px";d.style.height="0px";d.style.border="none";d.style.zIndex="-1000";d.style.left="-1000px";d.style.top="-1000px";d.name="__uspapiLocator";c.body.appendChild(d)}else a.setTimeout(b,5)}var c=a.document;b()};function nk(a){this.h=a;this.i=a.document;this.j=(a=(a=lk(this.i))?G(a,kk,5)||null:null)?A(a,2):null;(a=lk(this.i))&&G(a,jk,4);(a=lk(this.i))&&G(a,jk,4)}function ok(){var a=window;a.__uspapi||a.frames.__uspapiLocator||(a=new nk(a),pk(a))}function pk(a){!a.j||a.h.__uspapi||a.h.frames.__uspapiLocator||(a.h.__uspapiManager="fc",mk(a.h),Ga(function(){return a.l.apply(a,ka(ta.apply(0,arguments)))}))} nk.prototype.l=function(a,b,c){"function"===typeof c&&"getUSPData"===a&&c({version:1,uspString:this.j},!0)};function qk(a){J.call(this,a)}v(qk,J);qk.prototype.getWidth=function(){return C(this,1,0)};qk.prototype.getHeight=function(){return C(this,2,0)};function rk(a){J.call(this,a)}v(rk,J);function sk(a){J.call(this,a)}v(sk,J);var tk=[4,5];function uk(a){var b=/[a-zA-Z0-9._~-]/,c=/%[89a-zA-Z]./;return a.replace(/(%[a-zA-Z0-9]{2})/g,function(d){if(!d.match(c)){var e=decodeURIComponent(d);if(e.match(b))return e}return d.toUpperCase()})}function vk(a){for(var b="",c=/[/%?&=]/,d=0;d<a.length;++d){var e=a[d];b=e.match(c)?b+e:b+encodeURIComponent(e)}return b};function wk(a,b){a=vk(uk(a.location.pathname)).replace(/(^\/)|(\/$)/g,"");var c=Tc(a),d=xk(a);return r(b,"find").call(b,function(e){var f=null!=A(e,7)?A(G(e,oe,7),1):A(e,1);e=null!=A(e,7)?A(G(e,oe,7),2):2;if("number"!==typeof f)return!1;switch(e){case 1:return f==c;case 2:return d[f]||!1}return!1})||null}function xk(a){for(var b={};;){b[Tc(a)]=!0;if(!a)return b;a=a.substring(0,a.lastIndexOf("/"))}};var yk={},zk=(yk.google_ad_channel=!0,yk.google_ad_host=!0,yk);function Ak(a,b){a.location.href&&a.location.href.substring&&(b.url=a.location.href.substring(0,200));Yi("ama",b,.01)}function Bk(a){var b={};Sc(zk,function(c,d){d in a&&(b[d]=a[d])});return b};function Ck(a){a=G(a,le,3);return!a||A(a,1)<=Date.now()?!1:!0}function Dk(a){return(a=zj(a))?Ck(a)?a:null:null}function Ek(a,b){try{b.removeItem("google_ama_config")}catch(c){Ak(a,{lserr:1})}};function Fk(a){J.call(this,a)}v(Fk,J);function Gk(a){J.call(this,a,-1,Hk)}v(Gk,J);var Hk=[1];function Ik(a){J.call(this,a,-1,Jk)}v(Ik,J);Ik.prototype.getId=function(){return C(this,1,0)};Ik.prototype.V=function(){return C(this,7,0)};var Jk=[2];function Kk(a){J.call(this,a,-1,Lk)}v(Kk,J);Kk.prototype.V=function(){return C(this,5,0)};var Lk=[2];function Mk(a){J.call(this,a,-1,Nk)}v(Mk,J);function Ok(a){J.call(this,a,-1,Pk)}v(Ok,J);Ok.prototype.V=function(){return C(this,1,0)};function Qk(a){J.call(this,a)}v(Qk,J);var Nk=[1,4,2,3],Pk=[2];function Rk(a){J.call(this,a,-1,Sk)}v(Rk,J);function Tk(a){return Ib(a,Gk,14,Uk)}var Sk=[19],Uk=[13,14];var Vk=void 0;function Wk(){Yf(Vk,Xf);return Vk}function Xk(a){Yf(Vk,$f);Vk=a};function Yk(a,b,c,d){c=void 0===c?"":c;return 1===b&&Zk(c,void 0===d?null:d)?!0:$k(a,c,function(e){return Ua(H(e,Tb,2),function(f){return A(f,1)===b})})}function Zk(a,b){return b?13===Cb(b,Uk)?D(Ib(b,Fk,13,Uk),1):14===Cb(b,Uk)&&""!==a&&1===wb(Tk(b),1).length&&wb(Tk(b),1)[0]===a?D(G(Tk(b),Fk,2),1):!1:!1}function al(a,b){b=C(b,18,0);-1!==b&&(a.tmod=b)}function bl(a){var b=void 0===b?"":b;var c=Ic(L)||L;return cl(c,a)?!0:$k(L,b,function(d){return Ua(wb(d,3),function(e){return e===a})})} function dl(a){return $k(w,void 0===a?"":a,function(){return!0})}function cl(a,b){a=(a=(a=a.location&&a.location.hash)&&a.match(/forced_clientside_labs=([\d,]+)/))&&a[1];return!!a&&Xa(a.split(","),b.toString())}function $k(a,b,c){a=Ic(a)||a;var d=el(a);b&&(b=rd(String(b)));return Yb(d,function(e,f){return Object.prototype.hasOwnProperty.call(d,f)&&(!b||b===f)&&c(e)})}function el(a){a=fl(a);var b={};Sc(a,function(c,d){try{var e=new Rb(c);b[d]=e}catch(f){}});return b} function fl(a){return P(xe)?(a=Uj({u:a,Z:Wk()}),null!=a.h?(gl("ok"),a=hl(a.h.value)):(gl(a.i.message),a={}),a):hl(a.localStorage)}function hl(a){try{var b=a.getItem("google_adsense_settings");if(!b)return{};var c=JSON.parse(b);return c!==Object(c)?{}:Xb(c,function(d,e){return Object.prototype.hasOwnProperty.call(c,e)&&"string"===typeof e&&Array.isArray(d)})}catch(d){return{}}}function gl(a){P(we)&&Yi("abg_adsensesettings_lserr",{s:a,g:P(xe),c:Wk(),r:.01},.01)};function il(a,b,c,d){jl(new kl(a,b,c,d))}function kl(a,b,c,d){this.u=a;this.i=b;this.j=c;this.h=d}function jl(a){Ed(Cd(Uj({u:a.u,Z:D(a.i,6)}),function(b){ll(a,b,!0)}),function(){ml(a)})}function ll(a,b,c){Ed(Cd(nl(b),function(d){ol("ok");a.h(d)}),function(){Ek(a.u,b);c?ml(a):a.h(null)})}function ml(a){Ed(Cd(pl(a),a.h),function(){ql(a)})}function ql(a){Tj({u:a.u,Z:D(a.i,6),ta:50,Ia:function(b){rl(a,b)}})}function nl(a){return(a=Dk(a))?Dd(a):Fd(Error("invlocst"))} function pl(a){a:{var b=a.u;var c=a.j;a=a.i;if(13===Cb(a,Uk))b=(b=G(G(Ib(a,Fk,13,Uk),bk,2),ck,2))&&0<H(b,ce,1).length?b:null;else{if(14===Cb(a,Uk)){var d=wb(Tk(a),1),e=G(G(G(Tk(a),Fk,2),bk,2),ck,2);if(1===d.length&&d[0]===c&&e&&0<H(e,ce,1).length&&I(a,17)===b.location.host){b=e;break a}}b=null}}b?(c=new je,a=H(b,ce,1),c=Gb(c,1,a),b=H(b,me,2),b=Gb(c,7,b),b=Dd(b)):b=Fd(Error("invtag"));return b}function rl(a,b){Ed(Cd(b,function(c){ll(a,c,!1)}),function(c){ol(c.message);a.h(null)})} function ol(a){Yi("abg::amalserr",{status:a,guarding:"true",timeout:50,rate:.01},.01)};function sl(a){Ak(a,{atf:1})}function tl(a,b){(a.google_ama_state=a.google_ama_state||{}).exception=b;Ak(a,{atf:0})};function U(a){a.google_ad_modifications||(a.google_ad_modifications={});return a.google_ad_modifications}function ul(a){a=U(a);var b=a.space_collapsing||"none";return a.remove_ads_by_default?{Fa:!0,tb:b,qa:a.ablation_viewport_offset}:null}function vl(a,b){a=U(a);a.had_ads_ablation=!0;a.remove_ads_by_default=!0;a.space_collapsing="slot";a.ablation_viewport_offset=b}function wl(a){U(L).allow_second_reactive_tag=a} function xl(){var a=U(window);a.afg_slotcar_vars||(a.afg_slotcar_vars={});return a.afg_slotcar_vars};function yl(a,b){if(!a)return!1;a=a.hash;if(!a||!a.indexOf)return!1;if(-1!=a.indexOf(b))return!0;b=zl(b);return"go"!=b&&-1!=a.indexOf(b)?!0:!1}function zl(a){var b="";Sc(a.split("_"),function(c){b+=c.substr(0,2)});return b};$a||!x("Safari")||Oa();function Al(){var a=this;this.promise=new p.Promise(function(b,c){a.resolve=b;a.reject=c})};function Bl(){var a=new Al;return{promise:a.promise,resolve:a.resolve}};function Cl(a){a=void 0===a?function(){}:a;w.google_llp||(w.google_llp={});var b=w.google_llp,c=b[7];if(c)return c;c=Bl();b[7]=c;a();return c}function Dl(a){return Cl(function(){Lc(w.document,a)}).promise};function El(a){var b={};return{enable_page_level_ads:(b.pltais=!0,b),google_ad_client:a}};function Fl(a){if(w.google_apltlad||w!==w.top||!a.google_ad_client)return null;w.google_apltlad=!0;var b=El(a.google_ad_client),c=b.enable_page_level_ads;Sc(a,function(d,e){Ei[e]&&"google_ad_client"!==e&&(c[e]=d)});c.google_pgb_reactive=7;if("google_ad_section"in a||"google_ad_region"in a)c.google_ad_section=a.google_ad_section||a.google_ad_region;return b}function Gl(a){return ya(a.enable_page_level_ads)&&7===a.enable_page_level_ads.google_pgb_reactive};function Hl(a,b){this.h=w;this.i=a;this.j=b}function Il(a){P(lf)?il(a.h,a.j,a.i.google_ad_client||"",function(b){var c=a.h,d=a.i;U(L).ama_ran_on_page||b&&Jl(c,d,b)}):Tj({u:a.h,Z:D(a.j,6),ta:50,Ia:function(b){return Kl(a,b)}})}function Kl(a,b){Ed(Cd(b,function(c){Ll("ok");var d=a.h,e=a.i;if(!U(L).ama_ran_on_page){var f=Dk(c);f?Jl(d,e,f):Ek(d,c)}}),function(c){return Ll(c.message)})}function Ll(a){Yi("abg::amalserr",{status:a,guarding:!0,timeout:50,rate:.01},.01)} function Jl(a,b,c){if(null!=A(c,24)){var d=Si(a);d.availableAbg=!0;var e,f;d.ablationFromStorage=!!(null==(e=G(c,ee,24))?0:null==(f=G(e,ge,3))?0:Ib(f,he,2,ie))}if(Gl(b)&&(d=wk(a,H(c,me,7)),!d||!xb(d,8)))return;U(L).ama_ran_on_page=!0;var g;if(null==(g=G(c,re,15))?0:xb(g,23))U(a).enable_overlap_observer=!0;if((g=G(c,pe,13))&&1===A(g,1)){var h=0,k=G(g,qe,6);k&&A(k,3)&&(h=A(k,3)||0);vl(a,h)}else if(null==(h=G(c,ee,24))?0:null==(k=G(h,ge,3))?0:Ib(k,he,2,ie))Si(a).ablatingThisPageview=!0,vl(a,1);kd(3, [c.toJSON()]);var l=b.google_ad_client||"";b=Bk(ya(b.enable_page_level_ads)?b.enable_page_level_ads:{});var m=Rd(Vd,new Qd(null,b));Wi(782,function(){var q=m;try{var t=wk(a,H(c,me,7)),y;if(y=t)a:{var F=wb(t,2);if(F)for(var z=0;z<F.length;z++)if(1==F[z]){y=!0;break a}y=!1}if(y){if(A(t,4)){y={};var E=new Qd(null,(y.google_package=A(t,4),y));q=Rd(q,E)}var S=new vj(a,l,c,t,q),rb=new sd;(new fk(a,S,rb)).start();rb.i.then(Fa(sl,a),Fa(tl,a))}}catch(Kc){Ak(a,{atf:-1})}})};/* Copyright The Closure Library Authors. SPDX-License-Identifier: Apache-2.0 */ var Ml=ja(["https://fonts.googleapis.com/css2?family=Google+Material+Icons:wght@400;500;700"]);function Nl(a,b){return a instanceof HTMLScriptElement&&b.test(a.src)?0:1}function Ol(a){var b=L.document;if(b.currentScript)return Nl(b.currentScript,a);b=u(b.scripts);for(var c=b.next();!c.done;c=b.next())if(0===Nl(c.value,a))return 0;return 1};function Pl(a,b){var c={},d={},e={},f={};return f[fg]=(c[55]=function(){return 0===a},c[23]=function(g){return Yk(L,Number(g))},c[24]=function(g){return bl(Number(g))},c[61]=function(){return D(b,6)},c[63]=function(){return D(b,6)||".google.ch"===I(b,8)},c),f[gg]=(d[7]=function(g){try{var h=window.localStorage}catch(l){h=null}g=Number(g);g=void 0===g?0:g;g=0!==g?"google_experiment_mod"+g:"google_experiment_mod";var k=Vc(h,g);h=null===k?Wc(h,g):k;return null!=h?h:void 0},d),f[hg]=(e[6]=function(){return I(b, 15)},e),f};function Ql(a){a=void 0===a?w:a;return a.ggeac||(a.ggeac={})};function Rl(a,b){try{var c=a.split(".");a=w;for(var d=0,e;null!=a&&d<c.length;d++)e=a,a=a[c[d]],"function"===typeof a&&(a=e[c[d]]());var f=a;if(typeof f===b)return f}catch(g){}} function Sl(){var a={};this[fg]=(a[8]=function(b){try{return null!=va(b)}catch(c){}},a[9]=function(b){try{var c=va(b)}catch(d){return}if(b="function"===typeof c)c=c&&c.toString&&c.toString(),b="string"===typeof c&&-1!=c.indexOf("[native code]");return b},a[10]=function(){return window==window.top},a[6]=function(b){return Xa(O(Oh).h(),parseInt(b,10))},a[27]=function(b){b=Rl(b,"boolean");return void 0!==b?b:void 0},a[60]=function(b){try{return!!w.document.querySelector(b)}catch(c){}},a);a={};this[gg]= (a[3]=function(){return ad()},a[6]=function(b){b=Rl(b,"number");return void 0!==b?b:void 0},a[11]=function(b){b=void 0===b?"":b;var c=w;b=void 0===b?"":b;c=void 0===c?window:c;b=(c=(c=c.location.href.match(Ec)[3]||null)?decodeURI(c):c)?Tc(c+b):null;return null==b?void 0:b%1E3},a);a={};this[hg]=(a[2]=function(){return window.location.href},a[3]=function(){try{return window.top.location.hash}catch(b){return""}},a[4]=function(b){b=Rl(b,"string");return void 0!==b?b:void 0},a[10]=function(){try{var b= w.document;return b.visibilityState||b.webkitVisibilityState||b.mozVisibilityState||""}catch(c){return""}},a[11]=function(){try{var b,c,d,e,f;return null!=(f=null==(d=null==(b=va("google_tag_data"))?void 0:null==(c=b.uach)?void 0:c.fullVersionList)?void 0:null==(e=r(d,"find").call(d,function(g){return"Google Chrome"===g.brand}))?void 0:e.version)?f:""}catch(g){return""}},a)};var Tl=[12,13,20];function Ul(){}Ul.prototype.init=function(a,b,c,d){var e=this;d=void 0===d?{}:d;var f=void 0===d.Ka?!1:d.Ka,g=void 0===d.kb?{}:d.kb;d=void 0===d.mb?[]:d.mb;this.l=a;this.A={};this.G=f;this.m=g;a={};this.i=(a[b]=[],a[4]=[],a);this.j={};(b=Wh())&&Ra(b.split(",")||[],function(h){(h=parseInt(h,10))&&(e.j[h]=!0)});Ra(d,function(h){e.j[h]=!0});this.h=c;return this}; function Vl(a,b,c){var d=[],e=Wl(a.l,b),f;if(f=9!==b)a.A[b]?f=!0:(a.A[b]=!0,f=!1);if(f){var g;null==(g=a.h)||Yg(g,b,c,d,[],4);return d}if(!e.length){var h;null==(h=a.h)||Yg(h,b,c,d,[],3);return d}var k=Xa(Tl,b),l=[];Ra(e,function(q){var t=new Jg;if(q=Xl(a,q,c,t))0!==Cb(t,Kg)&&l.push(t),t=q.getId(),d.push(t),Yl(a,t,k?4:c),(q=H(q,qg,2))&&(k?oh(q,qh(),a.h,t):oh(q,[c],a.h,t))});var m;null==(m=a.h)||Yg(m,b,c,d,l,1);return d}function Yl(a,b,c){a.i[c]||(a.i[c]=[]);a=a.i[c];Xa(a,b)||a.push(b)} function Zl(a,b){a.l.push.apply(a.l,ka(Sa(Ta(b,function(c){return new Ok(c)}),function(c){return!Xa(Tl,c.V())})))} function Xl(a,b,c,d){var e=O(ah).h;if(!mg(G(b,ag,3),e))return null;var f=H(b,Ik,2),g=C(b,6,0);if(g){Bb(d,1,Kg,g);f=e[gg];switch(c){case 2:var h=f[8];break;case 1:h=f[7]}c=void 0;if(h)try{c=h(g),Ab(d,3,c)}catch(k){}return(b=$l(b,c))?am(a,[b],1):null}if(g=C(b,10,0)){Bb(d,2,Kg,g);h=null;switch(c){case 1:h=e[gg][9];break;case 2:h=e[gg][10];break;default:return null}c=h?h(String(g)):void 0;if(void 0===c&&1===C(b,11,0))return null;void 0!==c&&Ab(d,3,c);return(b=$l(b,c))?am(a,[b],1):null}d=e?Sa(f,function(k){return mg(G(k, ag,3),e)}):f;if(!d.length)return null;c=d.length*C(b,1,0);return(b=C(b,4,0))?bm(a,b,c,d):am(a,d,c/1E3)}function bm(a,b,c,d){var e=null!=a.m[b]?a.m[b]:1E3;if(0>=e)return null;d=am(a,d,c/e);a.m[b]=d?0:e-c;return d}function am(a,b,c){var d=a.j,e=Va(b,function(f){return!!d[f.getId()]});return e?e:a.G?null:Oc(b,c)} function cm(a,b){Jh(th,function(c){a.j[c]=!0},b);Jh(wh,function(c,d){return Vl(a,c,d)},b);Jh(xh,function(c){return(a.i[c]||[]).concat(a.i[4])},b);Jh(Gh,function(c){return Zl(a,c)},b);Jh(uh,function(c,d){return Yl(a,c,d)},b)}function Wl(a,b){return(a=Va(a,function(c){return c.V()==b}))&&H(a,Kk,2)||[]}function $l(a,b){var c=H(a,Ik,2),d=c.length,e=C(a,8,0);a=d*C(a,1,0)-1;b=void 0!==b?b:Math.floor(1E3*Rc());d=(b-e)%d;if(b<e||b-e-d>=a)return null;c=c[d];e=O(ah).h;return!c||e&&!mg(G(c,ag,3),e)?null:c};function dm(){this.h=function(){}}function em(a){O(dm).h(a)};var fm,gm,hm,im,jm,km; function lm(a,b,c,d){var e=1;d=void 0===d?Ql():d;e=void 0===e?0:e;var f=void 0===f?new Tg(null!=(im=null==(fm=G(a,Qk,5))?void 0:C(fm,2,0))?im:0,null!=(jm=null==(gm=G(a,Qk,5))?void 0:C(gm,4,0))?jm:0,null!=(km=null==(hm=G(a,Qk,5))?void 0:D(hm,3))?km:!1):f;d.hasOwnProperty("init-done")?(Kh(Gh,d)(Ta(H(a,Ok,2),function(g){return g.toJSON()})),Kh(Hh,d)(Ta(H(a,qg,1),function(g){return g.toJSON()}),e),b&&Kh(Ih,d)(b),mm(d,e)):(cm(O(Ul).init(H(a,Ok,2),e,f,c),d),Lh(d),Mh(d),Nh(d),mm(d,e),oh(H(a,qg,1),[e],f, void 0,!0),bh=bh||!(!c||!c.hb),em(O(Sl)),b&&em(b))}function mm(a,b){a=void 0===a?Ql():a;b=void 0===b?0:b;var c=a,d=b;d=void 0===d?0:d;Ph(O(Oh),c,d);nm(a,b);O(dm).h=Kh(Ih,a);O(yf).m()}function nm(a,b){var c=O(yf);c.i=function(d,e){return Kh(zh,a,function(){return!1})(d,e,b)};c.j=function(d,e){return Kh(Ah,a,function(){return 0})(d,e,b)};c.l=function(d,e){return Kh(Bh,a,function(){return""})(d,e,b)};c.h=function(d,e){return Kh(Ch,a,function(){return[]})(d,e,b)};c.m=function(){Kh(vh,a)(b)}};function om(a,b,c){var d=U(a);if(d.plle)mm(Ql(a),1);else{d.plle=!0;try{var e=a.localStorage}catch(f){e=null}d=e;null==Vc(d,"goog_pem_mod")&&Wc(d,"goog_pem_mod");d=G(b,Mk,12);e=D(b,9);lm(d,Pl(c,b),{Ka:e&&!!a.google_disable_experiments,hb:e},Ql(a));if(c=I(b,15))c=Number(c),O(Oh).l(c);if(c=I(b,10))c=Number(c),O(Oh).i(c);b=u(wb(b,19));for(c=b.next();!c.done;c=b.next())c=c.value,O(Oh).i(c);O(Oh).j(12);O(Oh).j(10);a=Ic(a)||a;yl(a.location,"google_mc_lab")&&O(Oh).i(44738307)}};function pm(a,b,c){a=a.style;a.border="none";a.height=c+"px";a.width=b+"px";a.margin=0;a.padding=0;a.position="relative";a.visibility="visible";a.backgroundColor="transparent"};var qm={"120x90":!0,"160x90":!0,"180x90":!0,"200x90":!0,"468x15":!0,"728x15":!0};function rm(a,b){if(15==b){if(728<=a)return 728;if(468<=a)return 468}else if(90==b){if(200<=a)return 200;if(180<=a)return 180;if(160<=a)return 160;if(120<=a)return 120}return null};function V(a,b,c,d){d=void 0===d?!1:d;wi.call(this,a,b);this.da=c;this.ib=d}v(V,wi);V.prototype.pa=function(){return this.da};V.prototype.i=function(a,b,c){b.google_ad_resize||(c.style.height=this.height()+"px",b.rpe=!0)};function sm(a){return function(b){return!!(b.da&a)}};var tm={},um=(tm.image_stacked=1/1.91,tm.image_sidebyside=1/3.82,tm.mobile_banner_image_sidebyside=1/3.82,tm.pub_control_image_stacked=1/1.91,tm.pub_control_image_sidebyside=1/3.82,tm.pub_control_image_card_stacked=1/1.91,tm.pub_control_image_card_sidebyside=1/3.74,tm.pub_control_text=0,tm.pub_control_text_card=0,tm),vm={},wm=(vm.image_stacked=80,vm.image_sidebyside=0,vm.mobile_banner_image_sidebyside=0,vm.pub_control_image_stacked=80,vm.pub_control_image_sidebyside=0,vm.pub_control_image_card_stacked= 85,vm.pub_control_image_card_sidebyside=0,vm.pub_control_text=80,vm.pub_control_text_card=80,vm),xm={},ym=(xm.pub_control_image_stacked=100,xm.pub_control_image_sidebyside=200,xm.pub_control_image_card_stacked=150,xm.pub_control_image_card_sidebyside=250,xm.pub_control_text=100,xm.pub_control_text_card=150,xm); function zm(a){var b=0;a.T&&b++;a.J&&b++;a.K&&b++;if(3>b)return{M:"Tags data-matched-content-ui-type, data-matched-content-columns-num and data-matched-content-rows-num should be set together."};b=a.T.split(",");var c=a.K.split(",");a=a.J.split(",");if(b.length!==c.length||b.length!==a.length)return{M:'Lengths of parameters data-matched-content-ui-type, data-matched-content-columns-num and data-matched-content-rows-num must match. Example: \n data-matched-content-rows-num="4,2"\ndata-matched-content-columns-num="1,6"\ndata-matched-content-ui-type="image_stacked,image_card_sidebyside"'}; if(2<b.length)return{M:"The parameter length of attribute data-matched-content-ui-type, data-matched-content-columns-num and data-matched-content-rows-num is too long. At most 2 parameters for each attribute are needed: one for mobile and one for desktop, while you are providing "+(b.length+' parameters. Example: \n data-matched-content-rows-num="4,2"\ndata-matched-content-columns-num="1,6"\ndata-matched-content-ui-type="image_stacked,image_card_sidebyside".')};for(var d=[],e=[],f=0;f<b.length;f++){var g= Number(c[f]);if(r(Number,"isNaN").call(Number,g)||0===g)return{M:"Wrong value '"+c[f]+"' for data-matched-content-rows-num."};d.push(g);g=Number(a[f]);if(r(Number,"isNaN").call(Number,g)||0===g)return{M:"Wrong value '"+a[f]+"' for data-matched-content-columns-num."};e.push(g)}return{K:d,J:e,Na:b}} function Am(a){return 1200<=a?{width:1200,height:600}:850<=a?{width:a,height:Math.floor(.5*a)}:550<=a?{width:a,height:Math.floor(.6*a)}:468<=a?{width:a,height:Math.floor(.7*a)}:{width:a,height:Math.floor(3.44*a)}};var Bm=Za("script");function Cm(a,b,c,d,e,f,g,h,k,l,m,q){this.A=a;this.U=b;this.da=void 0===c?null:c;this.h=void 0===d?null:d;this.P=void 0===e?null:e;this.i=void 0===f?null:f;this.j=void 0===g?null:g;this.H=void 0===h?null:h;this.N=void 0===k?null:k;this.l=void 0===l?null:l;this.m=void 0===m?null:m;this.O=void 0===q?null:q;this.R=this.C=this.G=null}Cm.prototype.size=function(){return this.U}; function Dm(a,b,c){null!=a.da&&(c.google_responsive_formats=a.da);null!=a.P&&(c.google_safe_for_responsive_override=a.P);null!=a.i&&(!0===a.i?c.google_full_width_responsive_allowed=!0:(c.google_full_width_responsive_allowed=!1,c.gfwrnwer=a.i));null!=a.j&&!0!==a.j&&(c.gfwrnher=a.j);var d=a.m||c.google_ad_width;null!=d&&(c.google_resizing_width=d);d=a.l||c.google_ad_height;null!=d&&(c.google_resizing_height=d);d=a.size().h(b);var e=a.size().height();if(!c.google_ad_resize){c.google_ad_width=d;c.google_ad_height= e;var f=a.size();b=f.h(b)+"x"+f.height();c.google_ad_format=b;c.google_responsive_auto_format=a.A;null!=a.h&&(c.armr=a.h);c.google_ad_resizable=!0;c.google_override_format=1;c.google_loader_features_used=128;!0===a.i&&(c.gfwrnh=a.size().height()+"px")}null!=a.H&&(c.gfwroml=a.H);null!=a.N&&(c.gfwromr=a.N);null!=a.l&&(c.gfwroh=a.l);null!=a.m&&(c.gfwrow=a.m);null!=a.O&&(c.gfwroz=a.O);null!=a.G&&(c.gml=a.G);null!=a.C&&(c.gmr=a.C);null!=a.R&&(c.gzi=a.R);b=Ic(window)||window;yl(b.location,"google_responsive_dummy_ad")&& (Xa([1,2,3,4,5,6,7,8],a.A)||1===a.h)&&2!==a.h&&(a=JSON.stringify({googMsgType:"adpnt",key_value:[{key:"qid",value:"DUMMY_AD"}]}),c.dash="<"+Bm+">window.top.postMessage('"+a+"', '*');\n </"+Bm+'>\n <div id="dummyAd" style="width:'+d+"px;height:"+e+'px;\n background:#ddd;border:3px solid #f00;box-sizing:border-box;\n color:#000;">\n <p>Requested size:'+d+"x"+e+"</p>\n <p>Rendered size:"+d+"x"+e+"</p>\n </div>")};var Em=["google_content_recommendation_ui_type","google_content_recommendation_columns_num","google_content_recommendation_rows_num"];function Fm(a,b){wi.call(this,a,b)}v(Fm,wi);Fm.prototype.h=function(a){return Math.min(1200,Math.max(this.minWidth(),Math.round(a)))}; function Gm(a,b){Hm(a,b);if("pedestal"==b.google_content_recommendation_ui_type)return new Cm(9,new Fm(a,Math.floor(a*b.google_phwr)));var c=Cc();468>a?c?(c=a-8-8,c=Math.floor(c/1.91+70)+Math.floor(11*(c*um.mobile_banner_image_sidebyside+wm.mobile_banner_image_sidebyside)+96),a={aa:a,$:c,J:1,K:12,T:"mobile_banner_image_sidebyside"}):(a=Am(a),a={aa:a.width,$:a.height,J:1,K:13,T:"image_sidebyside"}):(a=Am(a),a={aa:a.width,$:a.height,J:4,K:2,T:"image_stacked"});Im(b,a);return new Cm(9,new Fm(a.aa,a.$))} function Jm(a,b){Hm(a,b);var c=zm({K:b.google_content_recommendation_rows_num,J:b.google_content_recommendation_columns_num,T:b.google_content_recommendation_ui_type});if(c.M)a={aa:0,$:0,J:0,K:0,T:"image_stacked",M:c.M};else{var d=2===c.Na.length&&468<=a?1:0;var e=c.Na[d];e=0===e.indexOf("pub_control_")?e:"pub_control_"+e;var f=ym[e];for(var g=c.J[d];a/g<f&&1<g;)g--;f=g;c=c.K[d];d=Math.floor(((a-8*f-8)/f*um[e]+wm[e])*c+8*c+8);a=1500<a?{width:0,height:0,rb:"Calculated slot width is too large: "+a}: 1500<d?{width:0,height:0,rb:"Calculated slot height is too large: "+d}:{width:a,height:d};a={aa:a.width,$:a.height,J:f,K:c,T:e}}if(a.M)throw new T(a.M);Im(b,a);return new Cm(9,new Fm(a.aa,a.$))}function Hm(a,b){if(0>=a)throw new T("Invalid responsive width from Matched Content slot "+b.google_ad_slot+": "+a+". Please ensure to put this Matched Content slot into a non-zero width div container.");} function Im(a,b){a.google_content_recommendation_ui_type=b.T;a.google_content_recommendation_columns_num=b.J;a.google_content_recommendation_rows_num=b.K};function Km(a,b){wi.call(this,a,b)}v(Km,wi);Km.prototype.h=function(){return this.minWidth()};Km.prototype.i=function(a,b,c){vi(a,c);b.google_ad_resize||(c.style.height=this.height()+"px",b.rpe=!0)};var Lm={"image-top":function(a){return 600>=a?284+.414*(a-250):429},"image-middle":function(a){return 500>=a?196-.13*(a-250):164+.2*(a-500)},"image-side":function(a){return 500>=a?205-.28*(a-250):134+.21*(a-500)},"text-only":function(a){return 500>=a?187-.228*(a-250):130},"in-article":function(a){return 420>=a?a/1.2:460>=a?a/1.91+130:800>=a?a/4:200}};function Mm(a,b){wi.call(this,a,b)}v(Mm,wi);Mm.prototype.h=function(){return Math.min(1200,this.minWidth())}; function Nm(a,b,c,d,e){var f=e.google_ad_layout||"image-top";if("in-article"==f){var g=a;if("false"==e.google_full_width_responsive)a=g;else if(a=qi(b,c,g,.2,e),!0!==a)e.gfwrnwer=a,a=g;else if(a=Wf(b))if(e.google_full_width_responsive_allowed=!0,c.parentElement){b:{g=c;for(var h=0;100>h&&g.parentElement;++h){for(var k=g.parentElement.childNodes,l=0;l<k.length;++l){var m=k[l];if(m!=g&&ti(b,m))break b}g=g.parentElement;g.style.width="100%";g.style.height="auto"}}vi(b,c)}else a=g;else a=g}if(250>a)throw new T("Fluid responsive ads must be at least 250px wide: availableWidth="+ a);a=Math.min(1200,Math.floor(a));if(d&&"in-article"!=f){f=Math.ceil(d);if(50>f)throw new T("Fluid responsive ads must be at least 50px tall: height="+f);return new Cm(11,new wi(a,f))}if("in-article"!=f&&(d=e.google_ad_layout_key)){f=""+d;b=Math.pow(10,3);if(d=(c=f.match(/([+-][0-9a-z]+)/g))&&c.length){e=[];for(g=0;g<d;g++)e.push(parseInt(c[g],36)/b);b=e}else b=null;if(!b)throw new T("Invalid data-ad-layout-key value: "+f);f=(a+-725)/1E3;c=0;d=1;e=b.length;for(g=0;g<e;g++)c+=b[g]*d,d*=f;f=Math.ceil(1E3* c- -725+10);if(isNaN(f))throw new T("Invalid height: height="+f);if(50>f)throw new T("Fluid responsive ads must be at least 50px tall: height="+f);if(1200<f)throw new T("Fluid responsive ads must be at most 1200px tall: height="+f);return new Cm(11,new wi(a,f))}d=Lm[f];if(!d)throw new T("Invalid data-ad-layout value: "+f);c=Ai(c,b);b=Wf(b);b="in-article"!==f||c||a!==b?Math.ceil(d(a)):Math.ceil(1.25*d(a));return new Cm(11,"in-article"==f?new Mm(a,b):new wi(a,b))};function Om(a){return function(b){for(var c=a.length-1;0<=c;--c)if(!a[c](b))return!1;return!0}}function Pm(a,b){for(var c=Qm.slice(0),d=c.length,e=null,f=0;f<d;++f){var g=c[f];if(a(g)){if(!b||b(g))return g;null===e&&(e=g)}}return e};var W=[new V(970,90,2),new V(728,90,2),new V(468,60,2),new V(336,280,1),new V(320,100,2),new V(320,50,2),new V(300,600,4),new V(300,250,1),new V(250,250,1),new V(234,60,2),new V(200,200,1),new V(180,150,1),new V(160,600,4),new V(125,125,1),new V(120,600,4),new V(120,240,4),new V(120,120,1,!0)],Qm=[W[6],W[12],W[3],W[0],W[7],W[14],W[1],W[8],W[10],W[4],W[15],W[2],W[11],W[5],W[13],W[9],W[16]];function Rm(a,b,c,d,e){"false"==e.google_full_width_responsive?c={D:a,F:1}:"autorelaxed"==b&&e.google_full_width_responsive||Sm(b)||e.google_ad_resize?(b=ri(a,c,d,e),c=!0!==b?{D:a,F:b}:{D:Wf(c)||a,F:!0}):c={D:a,F:2};b=c.F;return!0!==b?{D:a,F:b}:d.parentElement?{D:c.D,F:b}:{D:a,F:b}} function Tm(a,b,c,d,e){var f=Wi(247,function(){return Rm(a,b,c,d,e)}),g=f.D;f=f.F;var h=!0===f,k=K(d.style.width),l=K(d.style.height),m=Um(g,b,c,d,e,h);g=m.Y;h=m.W;var q=m.pa;m=m.Ma;var t=Vm(b,q),y,F=(y=xi(d,c,"marginLeft",K))?y+"px":"",z=(y=xi(d,c,"marginRight",K))?y+"px":"";y=xi(d,c,"zIndex")||"";return new Cm(t,g,q,null,m,f,h,F,z,l,k,y)}function Sm(a){return"auto"==a||/^((^|,) *(horizontal|vertical|rectangle) *)+$/.test(a)} function Um(a,b,c,d,e,f){b="auto"==b?.25>=a/Math.min(1200,Wf(c))?4:3:pi(b);var g=!1,h=!1;if(488>Wf(c)){var k=ki(d,c);var l=Ai(d,c);g=!l&&k;h=l&&k}l=[yi(a),sm(b)];l.push(zi(488>Wf(c),c,d,h));null!=e.google_max_responsive_height&&l.push(Ci(e.google_max_responsive_height));var m=[function(t){return!t.ib}];if(g||h)g=Di(c,d),m.push(Ci(g));var q=Pm(Om(l),Om(m));if(!q)throw new T("No slot size for availableWidth="+a);l=Wi(248,function(){var t;a:if(f){if(e.gfwrnh&&(t=K(e.gfwrnh))){t={Y:new Km(a,t),W:!0}; break a}t=a/1.2;var y=Math;var F=y.min;if(e.google_resizing_allowed||"true"==e.google_full_width_responsive)var z=Infinity;else{z=d;var E=Infinity;do{var S=xi(z,c,"height",K);S&&(E=Math.min(E,S));(S=xi(z,c,"maxHeight",K))&&(E=Math.min(E,S))}while((z=z.parentElement)&&"HTML"!=z.tagName);z=E}y=F.call(y,t,z);if(y<.5*t||100>y)y=t;P(hf)&&!Ai(d,c)&&(y=Math.max(y,.5*Vf(c).clientHeight));t={Y:new Km(a,Math.floor(y)),W:y<t?102:!0}}else t={Y:q,W:100};return t});g=l.Y;l=l.W;return"in-article"===e.google_ad_layout&& Wm(c)?{Y:Xm(a,c,d,g,e),W:!1,pa:b,Ma:k}:{Y:g,W:l,pa:b,Ma:k}}function Vm(a,b){if("auto"==a)return 1;switch(b){case 2:return 2;case 1:return 3;case 4:return 4;case 3:return 5;case 6:return 6;case 5:return 7;case 7:return 8}throw Error("bad mask");}function Xm(a,b,c,d,e){var f=e.google_ad_height||xi(c,b,"height",K);b=Nm(a,b,c,f,e).size();return b.minWidth()*b.height()>a*d.height()?new V(b.minWidth(),b.height(),1):d}function Wm(a){return P(ff)||a.location&&"#hffwroe2etoq"==a.location.hash};function Ym(a,b,c,d,e){var f;(f=Wf(b))?488>Wf(b)?b.innerHeight>=b.innerWidth?(e.google_full_width_responsive_allowed=!0,vi(b,c),f={D:f,F:!0}):f={D:a,F:5}:f={D:a,F:4}:f={D:a,F:10};var g=f;f=g.D;g=g.F;if(!0!==g||a==f)return new Cm(12,new wi(a,d),null,null,!0,g,100);a=Um(f,"auto",b,c,e,!0);return new Cm(1,a.Y,a.pa,2,!0,g,a.W)};function Zm(a,b){var c=b.google_ad_format;if("autorelaxed"==c){a:{if("pedestal"!=b.google_content_recommendation_ui_type)for(a=u(Em),c=a.next();!c.done;c=a.next())if(null!=b[c.value]){b=!0;break a}b=!1}return b?9:5}if(Sm(c))return 1;if("link"===c)return 4;if("fluid"==c){if(c="in-article"===b.google_ad_layout)c=P(gf)||P(ff)||a.location&&("#hffwroe2etop"==a.location.hash||"#hffwroe2etoq"==a.location.hash);return c?($m(b),1):8}if(27===b.google_reactive_ad_format)return $m(b),1} function an(a,b,c,d,e){e=b.offsetWidth||(c.google_ad_resize||(void 0===e?!1:e))&&xi(b,d,"width",K)||c.google_ad_width||0;4===a&&(c.google_ad_format="auto",a=1);var f=(f=bn(a,e,b,c,d))?f:Tm(e,c.google_ad_format,d,b,c);f.size().i(d,c,b);Dm(f,e,c);1!=a&&(a=f.size().height(),b.style.height=a+"px")} function bn(a,b,c,d,e){var f=d.google_ad_height||xi(c,e,"height",K);switch(a){case 5:return f=Wi(247,function(){return Rm(b,d.google_ad_format,e,c,d)}),a=f.D,f=f.F,!0===f&&b!=a&&vi(e,c),!0===f?d.google_full_width_responsive_allowed=!0:(d.google_full_width_responsive_allowed=!1,d.gfwrnwer=f),Gm(a,d);case 9:return Jm(b,d);case 8:return Nm(b,e,c,f,d);case 10:return Ym(b,e,c,f,d)}}function $m(a){a.google_ad_format="auto";a.armr=3};function cn(a,b){var c=Ic(b);if(c){c=Wf(c);var d=Nc(a,b)||{},e=d.direction;if("0px"===d.width&&"none"!==d.cssFloat)return-1;if("ltr"===e&&c)return Math.floor(Math.min(1200,c-a.getBoundingClientRect().left));if("rtl"===e&&c)return a=b.document.body.getBoundingClientRect().right-a.getBoundingClientRect().right,Math.floor(Math.min(1200,c-a-Math.floor((c-b.document.body.clientWidth)/2)))}return-1};var dn=ja(["https://pagead2.googlesyndication.com/pagead/managed/js/adsense/","/slotcar_library",".js"]),en=ja(["https://googleads.g.doubleclick.net/pagead/html/","/","/zrt_lookup.html"]),fn=ja(["https://pagead2.googlesyndication.com/pagead/managed/js/adsense/","/show_ads_impl",".js"]),gn=ja(["https://pagead2.googlesyndication.com/pagead/managed/js/adsense/","/show_ads_impl_with_ama",".js"]),hn=ja(["https://pagead2.googlesyndication.com/pagead/managed/js/adsense/","/show_ads_impl_instrumented",".js"]);function jn(a){Ui.Ta(function(b){b.shv=String(a);b.mjsv="m202204040101";var c=O(Oh).h(),d=U(w);d.eids||(d.eids=[]);b.eid=c.concat(d.eids).join(",")})};function kn(a){var b=a.nb;return a.eb||("dev"===b?"dev":"")};var ln={},mn=(ln.google_ad_modifications=!0,ln.google_analytics_domain_name=!0,ln.google_analytics_uacct=!0,ln.google_pause_ad_requests=!0,ln.google_user_agent_client_hint=!0,ln);function nn(a){return(a=a.innerText||a.innerHTML)&&(a=a.replace(/^\s+/,"").split(/\r?\n/,1)[0].match(/^\x3c!--+(.*?)(?:--+>)?\s*$/))&&RegExp("google_ad_client").test(a[1])?a[1]:null} function on(a){if(a=a.innerText||a.innerHTML)if(a=a.replace(/^\s+|\s+$/g,"").replace(/\s*(\r?\n)+\s*/g,";"),(a=a.match(/^\x3c!--+(.*?)(?:--+>)?$/)||a.match(/^\/*\s*<!\[CDATA\[(.*?)(?:\/*\s*\]\]>)?$/i))&&RegExp("google_ad_client").test(a[1]))return a[1];return null} function pn(a){switch(a){case "true":return!0;case "false":return!1;case "null":return null;case "undefined":break;default:try{var b=a.match(/^(?:'(.*)'|"(.*)")$/);if(b)return b[1]||b[2]||"";if(/^[-+]?\d*(\.\d+)?$/.test(a)){var c=parseFloat(a);return c===c?c:void 0}}catch(d){}}};function qn(a){if(a.google_ad_client)return String(a.google_ad_client);var b,c,d,e,f;if(null!=(e=null!=(d=null==(b=U(a).head_tag_slot_vars)?void 0:b.google_ad_client)?d:null==(c=a.document.querySelector(".adsbygoogle[data-ad-client]"))?void 0:c.getAttribute("data-ad-client")))b=e;else{b:{b=a.document.getElementsByTagName("script");a=a.navigator&&a.navigator.userAgent||"";a=RegExp("appbankapppuzdradb|daumapps|fban|fbios|fbav|fb_iab|gsa/|messengerforios|naver|niftyappmobile|nonavigation|pinterest|twitter|ucbrowser|yjnewsapp|youtube", "i").test(a)||/i(phone|pad|pod)/i.test(a)&&/applewebkit/i.test(a)&&!/version|safari/i.test(a)&&!qd()?nn:on;for(c=b.length-1;0<=c;c--)if(d=b[c],!d.google_parsed_script_for_pub_code&&(d.google_parsed_script_for_pub_code=!0,d=a(d))){b=d;break b}b=null}if(b){a=/(google_\w+) *= *(['"]?[\w.-]+['"]?) *(?:;|$)/gm;for(c={};d=a.exec(b);)c[d[1]]=pn(d[2]);b=c.google_ad_client?c.google_ad_client:""}else b=""}return null!=(f=b)?f:""};var rn="undefined"===typeof sttc?void 0:sttc;function sn(a){var b=Ui;try{return Yf(a,Zf),new Rk(JSON.parse(a))}catch(c){b.I(838,c instanceof Error?c:Error(String(c)),void 0,function(d){d.jspb=String(a)})}return new Rk};var tn=O(yf).h(mf.h,mf.defaultValue);function un(){var a=L.document;a=void 0===a?window.document:a;ed(tn,a)};var vn=O(yf).h(nf.h,nf.defaultValue);function wn(){var a=L.document;a=void 0===a?window.document:a;ed(vn,a)};var xn=ja(["https://pagead2.googlesyndication.com/pagead/js/err_rep.js"]);function yn(){this.h=null;this.j=!1;this.l=Math.random();this.i=this.I;this.m=null}n=yn.prototype;n.Ta=function(a){this.h=a};n.Va=function(a){this.j=a};n.Ua=function(a){this.i=a}; n.I=function(a,b,c,d,e){if((this.j?this.l:Math.random())>(void 0===c?.01:c))return!1;Rh(b)||(b=new Qh(b,{context:a,id:void 0===e?"jserror":e}));if(d||this.h)b.meta={},this.h&&this.h(b.meta),d&&d(b.meta);w.google_js_errors=w.google_js_errors||[];w.google_js_errors.push(b);if(!w.error_rep_loaded){a=nd(xn);var f;Lc(w.document,null!=(f=this.m)?f:hc(qc(a).toString()));w.error_rep_loaded=!0}return!1};n.oa=function(a,b,c){try{return b()}catch(d){if(!this.i(a,d,.01,c,"jserror"))throw d;}}; n.Oa=function(a,b){var c=this;return function(){var d=ta.apply(0,arguments);return c.oa(a,function(){return b.apply(void 0,d)})}};n.Pa=function(a,b){var c=this;b.catch(function(d){d=d?d:"unknown rejection";c.I(a,d instanceof Error?d:Error(d))})};function zn(a,b,c){var d=window;return function(){var e=Yh(),f=3;try{var g=b.apply(this,arguments)}catch(h){f=13;if(c)return c(a,h),g;throw h;}finally{d.google_measure_js_timing&&e&&(e={label:a.toString(),value:e,duration:(Yh()||0)-e,type:f},f=d.google_js_reporting_queue=d.google_js_reporting_queue||[],2048>f.length&&f.push(e))}return g}}function An(a,b){return zn(a,b,function(c,d){(new yn).I(c,d)})};function Bn(a,b){return null==b?"&"+a+"=null":"&"+a+"="+Math.floor(b)}function Cn(a,b){return"&"+a+"="+b.toFixed(3)}function Dn(){var a=new p.Set,b=aj();try{if(!b)return a;for(var c=b.pubads(),d=u(c.getSlots()),e=d.next();!e.done;e=d.next())a.add(e.value.getSlotId().getDomId())}catch(f){}return a}function En(a){a=a.id;return null!=a&&(Dn().has(a)||r(a,"startsWith").call(a,"google_ads_iframe_")||r(a,"startsWith").call(a,"aswift"))} function Fn(a,b,c){if(!a.sources)return!1;switch(Gn(a)){case 2:var d=Hn(a);if(d)return c.some(function(f){return In(d,f)});case 1:var e=Jn(a);if(e)return b.some(function(f){return In(e,f)})}return!1}function Gn(a){if(!a.sources)return 0;a=a.sources.filter(function(b){return b.previousRect&&b.currentRect});if(1<=a.length){a=a[0];if(a.previousRect.top<a.currentRect.top)return 2;if(a.previousRect.top>a.currentRect.top)return 1}return 0}function Jn(a){return Kn(a,function(b){return b.currentRect})} function Hn(a){return Kn(a,function(b){return b.previousRect})}function Kn(a,b){return a.sources.reduce(function(c,d){d=b(d);return c?d&&0!==d.width*d.height?d.top<c.top?d:c:c:d},null)} function Ln(){Mj.call(this);this.i=this.h=this.P=this.O=this.H=0;this.Ba=this.ya=Number.NEGATIVE_INFINITY;this.ua=this.wa=this.xa=this.za=this.Ea=this.m=this.Da=this.U=0;this.va=!1;this.R=this.N=this.C=0;var a=document.querySelector("[data-google-query-id]");this.Ca=a?a.getAttribute("data-google-query-id"):null;this.l=null;this.Aa=!1;this.ga=function(){}}v(Ln,Mj); function Mn(){var a=new Ln;if(P(of)){var b=window;if(!b.google_plmetrics&&window.PerformanceObserver){b.google_plmetrics=!0;b=u(["layout-shift","largest-contentful-paint","first-input","longtask"]);for(var c=b.next();!c.done;c=b.next())c=c.value,Nn(a).observe({type:c,buffered:!0});On(a)}}} function Nn(a){a.l||(a.l=new PerformanceObserver(An(640,function(b){var c=Pn!==window.scrollX||Qn!==window.scrollY?[]:Rn,d=Sn();b=u(b.getEntries());for(var e=b.next();!e.done;e=b.next())switch(e=e.value,e.entryType){case "layout-shift":var f=a;if(!e.hadRecentInput){f.H+=Number(e.value);Number(e.value)>f.O&&(f.O=Number(e.value));f.P+=1;var g=Fn(e,c,d);g&&(f.m+=e.value,f.za++);if(5E3<e.startTime-f.ya||1E3<e.startTime-f.Ba)f.ya=e.startTime,f.h=0,f.i=0;f.Ba=e.startTime;f.h+=e.value;g&&(f.i+=e.value); f.h>f.U&&(f.U=f.h,f.Ea=f.i,f.Da=e.startTime+e.duration)}break;case "largest-contentful-paint":a.xa=Math.floor(e.renderTime||e.loadTime);a.wa=e.size;break;case "first-input":a.ua=Number((e.processingStart-e.startTime).toFixed(3));a.va=!0;break;case "longtask":e=Math.max(0,e.duration-50),a.C+=e,a.N=Math.max(a.N,e),a.R+=1}})));return a.l} function On(a){var b=An(641,function(){var d=document;2==(d.prerendering?3:{visible:1,hidden:2,prerender:3,preview:4,unloaded:5}[d.visibilityState||d.webkitVisibilityState||d.mozVisibilityState||""]||0)&&Tn(a)}),c=An(641,function(){return void Tn(a)});document.addEventListener("visibilitychange",b);document.addEventListener("unload",c);a.ga=function(){document.removeEventListener("visibilitychange",b);document.removeEventListener("unload",c);Nn(a).disconnect()}} Ln.prototype.j=function(){Mj.prototype.j.call(this);this.ga()}; function Tn(a){if(!a.Aa){a.Aa=!0;Nn(a).takeRecords();var b="https://pagead2.googlesyndication.com/pagead/gen_204?id=plmetrics";window.LayoutShift&&(b+=Cn("cls",a.H),b+=Cn("mls",a.O),b+=Bn("nls",a.P),window.LayoutShiftAttribution&&(b+=Cn("cas",a.m),b+=Bn("nas",a.za)),b+=Cn("wls",a.U),b+=Cn("tls",a.Da),window.LayoutShiftAttribution&&(b+=Cn("was",a.Ea)));window.LargestContentfulPaint&&(b+=Bn("lcp",a.xa),b+=Bn("lcps",a.wa));window.PerformanceEventTiming&&a.va&&(b+=Bn("fid",a.ua));window.PerformanceLongTaskTiming&& (b+=Bn("cbt",a.C),b+=Bn("mbt",a.N),b+=Bn("nlt",a.R));for(var c=0,d=u(document.getElementsByTagName("iframe")),e=d.next();!e.done;e=d.next())En(e.value)&&c++;b+=Bn("nif",c);b+=Bn("ifi",pd(window));c=O(Oh).h();b+="&eid="+encodeURIComponent(c.join());b+="&top="+(w===w.top?1:0);b+=a.Ca?"&qqid="+encodeURIComponent(a.Ca):Bn("pvsid",fd(w));window.googletag&&(b+="&gpt=1");window.fetch(b,{keepalive:!0,credentials:"include",redirect:"follow",method:"get",mode:"no-cors"});a.A||(a.A=!0,a.j())}} function In(a,b){var c=Math.min(a.right,b.right)-Math.max(a.left,b.left);a=Math.min(a.bottom,b.bottom)-Math.max(a.top,b.top);return 0>=c||0>=a?!1:50<=100*c*a/((b.right-b.left)*(b.bottom-b.top))} function Sn(){var a=[].concat(ka(document.getElementsByTagName("iframe"))).filter(En),b=[].concat(ka(Dn())).map(function(c){return document.getElementById(c)}).filter(function(c){return null!==c});Pn=window.scrollX;Qn=window.scrollY;return Rn=[].concat(ka(a),ka(b)).map(function(c){return c.getBoundingClientRect()})}var Pn=void 0,Qn=void 0,Rn=[];var X={issuerOrigin:"https://attestation.android.com",issuancePath:"/att/i",redemptionPath:"/att/r"},Y={issuerOrigin:"https://pagead2.googlesyndication.com",issuancePath:"/dtt/i",redemptionPath:"/dtt/r",getStatePath:"/dtt/s"};var Un=O(yf).h(wf.h,wf.defaultValue); function Vn(a,b,c){Mj.call(this);var d=this;this.i=a;this.h=[];b&&Wn()&&this.h.push(X);c&&this.h.push(Y);if(document.hasTrustToken&&!P(tf)){var e=new p.Map;this.h.forEach(function(f){e.set(f.issuerOrigin,{issuerOrigin:f.issuerOrigin,state:d.i?1:12,hasRedemptionRecord:!1})});window.goog_tt_state_map=window.goog_tt_state_map&&window.goog_tt_state_map instanceof p.Map?new p.Map([].concat(ka(e),ka(window.goog_tt_state_map))):e;window.goog_tt_promise_map&&window.goog_tt_promise_map instanceof p.Map||(window.goog_tt_promise_map= new p.Map)}}v(Vn,Mj);function Wn(){var a=void 0===a?window:a;a=a.navigator.userAgent;var b=/Chrome/.test(a);return/Android/.test(a)&&b}function Xn(){var a=void 0===a?window.document:a;ed(Un,a)}function Yn(a,b){return a||".google.ch"===b||"function"===typeof L.__tcfapi}function Z(a,b,c){var d,e=null==(d=window.goog_tt_state_map)?void 0:d.get(a);e&&(e.state=b,void 0!=c&&(e.hasRedemptionRecord=c))} function Zn(){var a=X.issuerOrigin+X.redemptionPath,b={keepalive:!0,trustToken:{type:"token-redemption",issuer:X.issuerOrigin,refreshPolicy:"none"}};Z(X.issuerOrigin,2);return window.fetch(a,b).then(function(c){if(!c.ok)throw Error(c.status+": Network response was not ok!");Z(X.issuerOrigin,6,!0)}).catch(function(c){c&&"NoModificationAllowedError"===c.name?Z(X.issuerOrigin,6,!0):Z(X.issuerOrigin,5)})} function $n(){var a=X.issuerOrigin+X.issuancePath;Z(X.issuerOrigin,8);return window.fetch(a,{keepalive:!0,trustToken:{type:"token-request"}}).then(function(b){if(!b.ok)throw Error(b.status+": Network response was not ok!");Z(X.issuerOrigin,10);return Zn()}).catch(function(b){if(b&&"NoModificationAllowedError"===b.name)return Z(X.issuerOrigin,10),Zn();Z(X.issuerOrigin,9)})}function ao(){Z(X.issuerOrigin,13);return document.hasTrustToken(X.issuerOrigin).then(function(a){return a?Zn():$n()})} function bo(){Z(Y.issuerOrigin,13);if(p.Promise){var a=document.hasTrustToken(Y.issuerOrigin).then(function(e){return e}).catch(function(e){return p.Promise.reject({state:19,error:e})}),b=Y.issuerOrigin+Y.redemptionPath,c={keepalive:!0,trustToken:{type:"token-redemption",refreshPolicy:"none"}};Z(Y.issuerOrigin,16);a=a.then(function(e){return window.fetch(b,c).then(function(f){if(!f.ok)throw Error(f.status+": Network response was not ok!");Z(Y.issuerOrigin,18,!0)}).catch(function(f){if(f&&"NoModificationAllowedError"=== f.name)Z(Y.issuerOrigin,18,!0);else{if(e)return p.Promise.reject({state:17,error:f});Z(Y.issuerOrigin,17)}})}).then(function(){return document.hasTrustToken(Y.issuerOrigin).then(function(e){return e}).catch(function(e){return p.Promise.reject({state:19,error:e})})}).then(function(e){var f=Y.issuerOrigin+Y.getStatePath;Z(Y.issuerOrigin,20);return window.fetch(f+"?ht="+e,{trustToken:{type:"send-redemption-record",issuers:[Y.issuerOrigin]}}).then(function(g){if(!g.ok)throw Error(g.status+": Network response was not ok!"); Z(Y.issuerOrigin,22);return g.text().then(function(h){return JSON.parse(h)})}).catch(function(g){return p.Promise.reject({state:21,error:g})})});var d=fd(window);return a.then(function(e){var f=Y.issuerOrigin+Y.issuancePath;return e&&e.srqt&&e.cs?(Z(Y.issuerOrigin,23),window.fetch(f+"?cs="+e.cs+"&correlator="+d,{keepalive:!0,trustToken:{type:"token-request"}}).then(function(g){if(!g.ok)throw Error(g.status+": Network response was not ok!");Z(Y.issuerOrigin,25);return e}).catch(function(g){return p.Promise.reject({state:24, error:g})})):e}).then(function(e){if(e&&e.srdt&&e.cs)return Z(Y.issuerOrigin,26),window.fetch(b+"?cs="+e.cs+"&correlator="+d,{keepalive:!0,trustToken:{type:"token-redemption",refreshPolicy:"refresh"}}).then(function(f){if(!f.ok)throw Error(f.status+": Network response was not ok!");Z(Y.issuerOrigin,28,!0)}).catch(function(f){return p.Promise.reject({state:27,error:f})})}).then(function(){Z(Y.issuerOrigin,29)}).catch(function(e){if(e instanceof Object&&e.hasOwnProperty("state")&&e.hasOwnProperty("error"))if("number"=== typeof e.state&&e.error instanceof Error){Z(Y.issuerOrigin,e.state);var f=Q(vf);Math.random()<=f&&Ff({state:e.state,err:e.error.toString()})}else throw Error(e);else throw e;})}} function co(a){if(document.hasTrustToken&&!P(tf)&&a.i){var b=window.goog_tt_promise_map;if(b&&b instanceof p.Map){var c=[];if(a.h.some(function(e){return e.issuerOrigin===X.issuerOrigin})){var d=b.get(X.issuerOrigin);d||(d=ao(),b.set(X.issuerOrigin,d));c.push(d)}a.h.some(function(e){return e.issuerOrigin===Y.issuerOrigin})&&(a=b.get(Y.issuerOrigin),a||(a=bo(),b.set(Y.issuerOrigin,a)),c.push(a));if(0<c.length&&p.Promise&&p.Promise.all)return p.Promise.all(c)}}};function eo(a){J.call(this,a,-1,fo)}v(eo,J);function go(a,b){return B(a,2,b)}function ho(a,b){return B(a,3,b)}function io(a,b){return B(a,4,b)}function jo(a,b){return B(a,5,b)}function ko(a,b){return B(a,9,b)}function lo(a,b){return Gb(a,10,b)}function mo(a,b){return B(a,11,b)}function no(a,b){return B(a,1,b)}function oo(a){J.call(this,a)}v(oo,J);oo.prototype.getVersion=function(){return I(this,2)};var fo=[10,6];var po="platform platformVersion architecture model uaFullVersion bitness fullVersionList wow64".split(" ");function qo(){var a;return null!=(a=L.google_tag_data)?a:L.google_tag_data={}} function ro(){var a,b;if("function"!==typeof(null==(a=L.navigator)?void 0:null==(b=a.userAgentData)?void 0:b.getHighEntropyValues))return null;var c=qo();if(c.uach_promise)return c.uach_promise;a=L.navigator.userAgentData.getHighEntropyValues(po).then(function(d){null!=c.uach||(c.uach=d);return d});return c.uach_promise=a} function so(a){var b;return mo(lo(ko(jo(io(ho(go(no(new eo,a.platform||""),a.platformVersion||""),a.architecture||""),a.model||""),a.uaFullVersion||""),a.bitness||""),(null==(b=a.fullVersionList)?void 0:b.map(function(c){var d=new oo;d=B(d,1,c.brand);return B(d,2,c.version)}))||[]),a.wow64||!1)} function to(){if(P(pf)){var a,b;return null!=(b=null==(a=ro())?void 0:a.then(function(f){return so(f)}))?b:null}var c,d;if("function"!==typeof(null==(c=L.navigator)?void 0:null==(d=c.userAgentData)?void 0:d.getHighEntropyValues))return null;var e;return null!=(e=L.navigator.userAgentData.getHighEntropyValues(po).then(function(f){return so(f)}))?e:null};function uo(a,b){b.google_ad_host||(a=vo(a))&&(b.google_ad_host=a)}function wo(a,b,c){c=void 0===c?"":c;L.google_sa_impl&&!L.document.getElementById("google_shimpl")&&(delete L.google_sa_queue,delete L.google_sa_impl);L.google_sa_queue||(L.google_sa_queue=[],L.google_process_slots=Xi(215,function(){return xo(L.google_sa_queue)}),a=yo(c,a,b),Lc(L.document,a).id="google_shimpl")} function xo(a){var b=a.shift();"function"===typeof b&&Wi(216,b);a.length&&w.setTimeout(Xi(215,function(){return xo(a)}),0)}function zo(a,b,c){a.google_sa_queue=a.google_sa_queue||[];a.google_sa_impl?c(b):a.google_sa_queue.push(b)} function yo(a,b,c){var d=Math.random()<Q(bf)?hc(qc(b.pb).toString()):null;b=D(c,4)?b.ob:b.qb;d=d?d:hc(qc(b).toString());b={};a:{if(D(c,4)){if(c=a||qn(L)){var e={};c=(e.client=c,e.plah=L.location.host,e);break a}throw Error("PublisherCodeNotFoundForAma");}c={}}Ao(c,b);a:{if(P($e)||P(Oe)){a=a||qn(L);var f;var g=(c=null==(g=U(L))?void 0:null==(f=g.head_tag_slot_vars)?void 0:f.google_ad_host)?c:vo(L);if(a){f={};g=(f.client=a,f.plah=L.location.host,f.ama_t="adsense",f.asntp=Q(Ge),f.asntpv=Q(Ke),f.asntpl= Q(Ie),f.asntpm=Q(Je),f.asntpc=Q(He),f.asna=Q(Ce),f.asnd=Q(De),f.asnp=Q(Ee),f.asns=Q(Fe),f.asmat=Q(Be),f.asptt=Q(Le),f.easpi=P($e),f.asro=P(Me),f.host=g,f.easai=P(Ze),f);break a}}g={}}Ao(g,b);Ao(zf()?{bust:zf()}:{},b);return ec(d,b)}function Ao(a,b){Sc(a,function(c,d){void 0===b[d]&&(b[d]=c)})}function vo(a){if(a=a.document.querySelector('meta[name="google-adsense-platform-account"]'))return a.getAttribute("content")} function Bo(a){a:{var b=void 0===b?!1:b;var c=void 0===c?1024:c;for(var d=[w.top],e=[],f=0,g;g=d[f++];){b&&!Hc(g)||e.push(g);try{if(g.frames)for(var h=0;h<g.frames.length&&d.length<c;++h)d.push(g.frames[h])}catch(l){}}for(b=0;b<e.length;b++)try{var k=e[b].frames.google_esf;if(k){id=k;break a}}catch(l){}id=null}if(id)return null;e=Mc("IFRAME");e.id="google_esf";e.name="google_esf";e.src=sc(a.vb);e.style.display="none";return e} function Co(a,b,c,d){Do(a,b,c,d,function(e,f){e=e.document;for(var g=void 0,h=0;!g||e.getElementById(g+"_anchor");)g="aswift_"+h++;e=g;g=Number(f.google_ad_width||0);f=Number(f.google_ad_height||0);h=Mc("INS");h.id=e+"_anchor";pm(h,g,f);h.style.display="block";var k=Mc("INS");k.id=e+"_expand";pm(k,g,f);k.style.display="inline-table";k.appendChild(h);c.appendChild(k);return e})} function Do(a,b,c,d,e){e=e(a,b);Eo(a,c,b);c=Ia;var f=(new Date).getTime();b.google_lrv=I(d,2);b.google_async_iframe_id=e;b.google_start_time=c;b.google_bpp=f>c?f-c:1;a.google_sv_map=a.google_sv_map||{};a.google_sv_map[e]=b;d=a.document.getElementById(e+"_anchor")?function(h){return h()}:function(h){return window.setTimeout(h,0)};var g={pubWin:a,vars:b};zo(a,function(){var h=a.google_sa_impl(g);h&&h.catch&&Zi(911,h)},d)} function Eo(a,b,c){var d=c.google_ad_output,e=c.google_ad_format,f=c.google_ad_width||0,g=c.google_ad_height||0;e||"html"!=d&&null!=d||(e=f+"x"+g);d=!c.google_ad_slot||c.google_override_format||!qm[c.google_ad_width+"x"+c.google_ad_height]&&"aa"==c.google_loader_used;e&&d?e=e.toLowerCase():e="";c.google_ad_format=e;if("number"!==typeof c.google_reactive_sra_index||!c.google_ad_unit_key){e=[c.google_ad_slot,c.google_orig_ad_format||c.google_ad_format,c.google_ad_type,c.google_orig_ad_width||c.google_ad_width, c.google_orig_ad_height||c.google_ad_height];d=[];f=0;for(g=b;g&&25>f;g=g.parentNode,++f)9===g.nodeType?d.push(""):d.push(g.id);(d=d.join())&&e.push(d);c.google_ad_unit_key=Tc(e.join(":")).toString();var h=void 0===h?!1:h;e=[];for(d=0;b&&25>d;++d){f="";void 0!==h&&h||(f=(f=9!==b.nodeType&&b.id)?"/"+f:"");a:{if(b&&b.nodeName&&b.parentElement){g=b.nodeName.toString().toLowerCase();for(var k=b.parentElement.childNodes,l=0,m=0;m<k.length;++m){var q=k[m];if(q.nodeName&&q.nodeName.toString().toLowerCase()=== g){if(b===q){g="."+l;break a}++l}}}g=""}e.push((b.nodeName&&b.nodeName.toString().toLowerCase())+f+g);b=b.parentElement}h=e.join()+":";b=[];if(a)try{var t=a.parent;for(e=0;t&&t!==a&&25>e;++e){var y=t.frames;for(d=0;d<y.length;++d)if(a===y[d]){b.push(d);break}a=t;t=a.parent}}catch(F){}c.google_ad_dom_fingerprint=Tc(h+b.join()).toString()}}function Fo(){var a=Ic(w);a&&(a=Uf(a),a.tagSpecificState[1]||(a.tagSpecificState[1]={debugCard:null,debugCardRequested:!1}))} function Go(a){Xn();Yn(Wk(),I(a,8))||Xi(779,function(){var b=window;b=void 0===b?window:b;b=P(b.PeriodicSyncManager?rf:sf);var c=P(uf);b=new Vn(!0,b,c);0<Q(xf)?L.google_trust_token_operation_promise=co(b):co(b)})();a=to();null!=a&&a.then(function(b){L.google_user_agent_client_hint=Lb(b)});wn();un()};function Ho(a,b){switch(a){case "google_reactive_ad_format":return a=parseInt(b,10),isNaN(a)?0:a;case "google_allow_expandable_ads":return/^true$/.test(b);default:return b}} function Io(a,b){if(a.getAttribute("src")){var c=a.getAttribute("src")||"";(c=Gc(c))&&(b.google_ad_client=Ho("google_ad_client",c))}a=a.attributes;c=a.length;for(var d=0;d<c;d++){var e=a[d];if(/data-/.test(e.name)){var f=Ja(e.name.replace("data-matched-content","google_content_recommendation").replace("data","google").replace(/-/g,"_"));b.hasOwnProperty(f)||(e=Ho(f,e.value),null!==e&&(b[f]=e))}}} function Jo(a){if(a=ld(a))switch(a.data&&a.data.autoFormat){case "rspv":return 13;case "mcrspv":return 15;default:return 14}else return 12} function Ko(a,b,c,d){Io(a,b);if(c.document&&c.document.body&&!Zm(c,b)&&!b.google_reactive_ad_format){var e=parseInt(a.style.width,10),f=cn(a,c);if(0<f&&e>f){var g=parseInt(a.style.height,10);e=!!qm[e+"x"+g];var h=f;if(e){var k=rm(f,g);if(k)h=k,b.google_ad_format=k+"x"+g+"_0ads_al";else throw new T("No slot size for availableWidth="+f);}b.google_ad_resize=!0;b.google_ad_width=h;e||(b.google_ad_format=null,b.google_override_format=!0);f=h;a.style.width=f+"px";g=Tm(f,"auto",c,a,b);h=f;g.size().i(c,b, a);Dm(g,h,b);g=g.size();b.google_responsive_formats=null;g.minWidth()>f&&!e&&(b.google_ad_width=g.minWidth(),a.style.width=g.minWidth()+"px")}}e=a.offsetWidth||xi(a,c,"width",K)||b.google_ad_width||0;f=Fa(Tm,e,"auto",c,a,b,!1,!0);if(!P(Xe)&&488>Wf(c)){g=Ic(c)||c;h=b.google_ad_client;d=g.location&&"#ftptohbh"===g.location.hash?2:yl(g.location,"google_responsive_slot_preview")||P(ef)?1:P(df)?2:Yk(g,1,h,d)?1:0;if(g=0!==d)b:if(b.google_reactive_ad_format||Zm(c,b)||mi(a,b))g=!1;else{for(g=a;g;g=g.parentElement){h= Nc(g,c);if(!h){b.gfwrnwer=18;g=!1;break b}if(!Xa(["static","relative"],h.position)){b.gfwrnwer=17;g=!1;break b}}g=qi(c,a,e,.3,b);!0!==g?(b.gfwrnwer=g,g=!1):g=c===c.top?!0:!1}g?(b.google_resizing_allowed=!0,b.ovlp=!0,2===d?(d={},Dm(f(),e,d),b.google_resizing_width=d.google_ad_width,b.google_resizing_height=d.google_ad_height,b.iaaso=!1):(b.google_ad_format="auto",b.iaaso=!0,b.armr=1),d=!0):d=!1}else d=!1;if(e=Zm(c,b))an(e,a,b,c,d);else{if(mi(a,b)){if(d=Nc(a,c))a.style.width=d.width,a.style.height= d.height,li(d,b);b.google_ad_width||(b.google_ad_width=a.offsetWidth);b.google_ad_height||(b.google_ad_height=a.offsetHeight);b.google_loader_features_used=256;b.google_responsive_auto_format=Jo(c)}else li(a.style,b);c.location&&"#gfwmrp"==c.location.hash||12==b.google_responsive_auto_format&&"true"==b.google_full_width_responsive?an(10,a,b,c,!1):.01>Math.random()&&12===b.google_responsive_auto_format&&(a=ri(a.offsetWidth||parseInt(a.style.width,10)||b.google_ad_width,c,a,b),!0!==a?(b.efwr=!1,b.gfwrnwer= a):b.efwr=!0)}};function Lo(a){this.j=new p.Set;this.u=md()||window;this.h=Q(ze);var b=0<this.h&&Rc()<1/this.h;this.A=(this.i=!!Hj(Dj(),30,b))?fd(this.u):0;this.m=this.i?qn(this.u):"";this.l=null!=a?a:new yg(100)}function Mo(){var a=O(Lo);var b=new qk;b=B(b,1,Vf(a.u).scrollWidth);b=B(b,2,Vf(a.u).scrollHeight);var c=new qk;c=B(c,1,Wf(a.u));c=B(c,2,Vf(a.u).clientHeight);var d=new sk;d=B(d,1,a.A);d=B(d,2,a.m);d=B(d,3,a.h);var e=new rk;b=Eb(e,2,b);b=Eb(b,1,c);b=Fb(d,4,tk,b);a.i&&!a.j.has(1)&&(a.j.add(1),ug(a.l,b))};function No(a){var b=window;var c=void 0===c?null:c;xc(b,"message",function(d){try{var e=JSON.parse(d.data)}catch(f){return}!e||"sc-cnf"!==e.googMsgType||c&&/[:|%3A]javascript\(/i.test(d.data)&&!c(e,d)||a(e,d)})};function Oo(a,b){b=void 0===b?500:b;Mj.call(this);this.i=a;this.ta=b;this.h=null;this.m={};this.l=null}v(Oo,Mj);Oo.prototype.j=function(){this.m={};this.l&&(yc(this.i,this.l),delete this.l);delete this.m;delete this.i;delete this.h;Mj.prototype.j.call(this)};function Po(a){Mj.call(this);this.h=a;this.i=null;this.l=!1}v(Po,Mj);var Qo=null,Ro=[],So=new p.Map,To=-1;function Uo(a){return Fi.test(a.className)&&"done"!=a.dataset.adsbygoogleStatus}function Vo(a,b,c){a.dataset.adsbygoogleStatus="done";Wo(a,b,c)} function Wo(a,b,c){var d=window;d.google_spfd||(d.google_spfd=Ko);var e=b.google_reactive_ads_config;e||Ko(a,b,d,c);uo(d,b);if(!Xo(a,b,d)){e||(d.google_lpabyc=ni(a,d)+xi(a,d,"height",K));if(e){e=e.page_level_pubvars||{};if(U(L).page_contains_reactive_tag&&!U(L).allow_second_reactive_tag){if(e.pltais){wl(!1);return}throw new T("Only one 'enable_page_level_ads' allowed per page.");}U(L).page_contains_reactive_tag=!0;wl(7===e.google_pgb_reactive)}b.google_unique_id=od(d);Sc(mn,function(f,g){b[g]=b[g]|| d[g]});b.google_loader_used="aa";b.google_reactive_tag_first=1===(U(L).first_tag_on_page||0);Wi(164,function(){Co(d,b,a,c)})}} function Xo(a,b,c){var d=b.google_reactive_ads_config,e="string"===typeof a.className&&RegExp("(\\W|^)adsbygoogle-noablate(\\W|$)").test(a.className),f=ul(c);if(f&&f.Fa&&"on"!=b.google_adtest&&!e){e=ni(a,c);var g=Vf(c).clientHeight;if(!f.qa||f.qa&&((0==g?null:e/g)||0)>=f.qa)return a.className+=" adsbygoogle-ablated-ad-slot",c=c.google_sv_map=c.google_sv_map||{},d=za(a),b.google_element_uid=d,c[b.google_element_uid]=b,a.setAttribute("google_element_uid",d),"slot"==f.tb&&(null!==Zc(a.getAttribute("width"))&& a.setAttribute("width",0),null!==Zc(a.getAttribute("height"))&&a.setAttribute("height",0),a.style.width="0px",a.style.height="0px"),!0}if((f=Nc(a,c))&&"none"==f.display&&!("on"==b.google_adtest||0<b.google_reactive_ad_format||d))return c.document.createComment&&a.appendChild(c.document.createComment("No ad requested because of display:none on the adsbygoogle tag")),!0;a=null==b.google_pgb_reactive||3===b.google_pgb_reactive;return 1!==b.google_reactive_ad_format&&8!==b.google_reactive_ad_format|| !a?!1:(w.console&&w.console.warn("Adsbygoogle tag with data-reactive-ad-format="+b.google_reactive_ad_format+" is deprecated. Check out page-level ads at https://www.google.com/adsense"),!0)}function Yo(a){var b=document.getElementsByTagName("INS");for(var c=0,d=b[c];c<b.length;d=b[++c]){var e=d;if(Uo(e)&&"reserved"!=e.dataset.adsbygoogleStatus&&(!a||d.id==a))return d}return null} function Zo(a,b,c){if(a&&a.shift)for(var d=20;0<a.length&&0<d;){try{$o(a.shift(),b,c)}catch(e){setTimeout(function(){throw e;})}--d}}function ap(){var a=Mc("INS");a.className="adsbygoogle";a.className+=" adsbygoogle-noablate";bd(a);return a} function bp(a,b){var c={};Sc(Rf,function(f,g){!1===a.enable_page_level_ads?c[g]=!1:a.hasOwnProperty(g)&&(c[g]=a[g])});ya(a.enable_page_level_ads)&&(c.page_level_pubvars=a.enable_page_level_ads);var d=ap();hd.body.appendChild(d);var e={};e=(e.google_reactive_ads_config=c,e.google_ad_client=a.google_ad_client,e);e.google_pause_ad_requests=!!U(L).pause_ad_requests;Vo(d,e,b)} function cp(a,b){function c(){return bp(a,b)}Uf(w).wasPlaTagProcessed=!0;var d=w.document;if(d.body||"complete"==d.readyState||"interactive"==d.readyState)c();else{var e=wc(Xi(191,c));xc(d,"DOMContentLoaded",e);(new w.MutationObserver(function(f,g){d.body&&(e(),g.disconnect())})).observe(d,{childList:!0,subtree:!0})}} function $o(a,b,c){var d={};Wi(165,function(){dp(a,d,b,c)},function(e){e.client=e.client||d.google_ad_client||a.google_ad_client;e.slotname=e.slotname||d.google_ad_slot;e.tag_origin=e.tag_origin||d.google_tag_origin})}function ep(a){delete a.google_checked_head;Sc(a,function(b,c){Ei[c]||(delete a[c],w.console.warn("AdSense head tag doesn't support "+c.replace("google","data").replace(/_/g,"-")+" attribute."))})} function fp(a,b){var c=L.document.querySelector('script[src*="/pagead/js/adsbygoogle.js?client="]:not([data-checked-head])')||L.document.querySelector('script[src*="/pagead/js/adsbygoogle.js"][data-ad-client]:not([data-checked-head])');if(c){c.setAttribute("data-checked-head","true");var d=U(window);if(d.head_tag_slot_vars)gp(c);else{var e={};Io(c,e);ep(e);var f=$b(e);d.head_tag_slot_vars=f;c={google_ad_client:e.google_ad_client,enable_page_level_ads:e};L.adsbygoogle||(L.adsbygoogle=[]);d=L.adsbygoogle; d.loaded?d.push(c):d.splice(0,0,c);var g;e.google_adbreak_test||(null==(g=Ib(b,Fk,13,Uk))?0:D(g,3))&&P(jf)?hp(f,a):No(function(){hp(f,a)})}}}function gp(a){var b=U(window).head_tag_slot_vars,c=a.getAttribute("src")||"";if((a=Gc(c)||a.getAttribute("data-ad-client")||"")&&a!==b.google_ad_client)throw new T("Warning: Do not add multiple property codes with AdSense tag to avoid seeing unexpected behavior. These codes were found on the page "+a+", "+b.google_ad_client);} function ip(a){if("object"===typeof a&&null!=a){if("string"===typeof a.type)return 2;if("string"===typeof a.sound||"string"===typeof a.preloadAdBreaks)return 3}return 0} function dp(a,b,c,d){if(null==a)throw new T("push() called with no parameters.");14===Cb(d,Uk)&&jp(a,wb(Tk(d),1),I(d,2));var e=ip(a);if(0!==e)P(af)&&(d=xl(),d.first_slotcar_request_processing_time||(d.first_slotcar_request_processing_time=Date.now(),d.adsbygoogle_execution_start_time=Ia)),null==Qo?(kp(a),Ro.push(a)):3===e?Wi(787,function(){Qo.handleAdConfig(a)}):Zi(730,Qo.handleAdBreak(a));else{Ia=(new Date).getTime();wo(c,d,lp(a));mp();a:{if(void 0!=a.enable_page_level_ads){if("string"===typeof a.google_ad_client){e= !0;break a}throw new T("'google_ad_client' is missing from the tag config.");}e=!1}if(e)np(a,d);else if((e=a.params)&&Sc(e,function(g,h){b[h]=g}),"js"===b.google_ad_output)console.warn("Ads with google_ad_output='js' have been deprecated and no longer work. Contact your AdSense account manager or switch to standard AdSense ads.");else{e=op(a.element);Io(e,b);c=U(w).head_tag_slot_vars||{};Sc(c,function(g,h){b.hasOwnProperty(h)||(b[h]=g)});if(e.hasAttribute("data-require-head")&&!U(w).head_tag_slot_vars)throw new T("AdSense head tag is missing. AdSense body tags don't work without the head tag. You can copy the head tag from your account on https://adsense.com."); if(!b.google_ad_client)throw new T("Ad client is missing from the slot.");b.google_apsail=dl(b.google_ad_client);var f=(c=0===(U(L).first_tag_on_page||0)&&Fl(b))&&Gl(c);c&&!f&&(np(c,d),U(L).skip_next_reactive_tag=!0);0===(U(L).first_tag_on_page||0)&&(U(L).first_tag_on_page=2);b.google_pause_ad_requests=!!U(L).pause_ad_requests;Vo(e,b,d);c&&f&&pp(c)}}}var qp=!1;function jp(a,b,c){P(Ye)&&!qp&&(qp=!0,a=lp(a)||qn(L),Yi("predictive_abg",{a_c:a,p_c:b,b_v:c},.01))} function lp(a){return a.google_ad_client?a.google_ad_client:(a=a.params)&&a.google_ad_client?a.google_ad_client:""}function mp(){if(P(Re)){var a=ul(L);if(!(a=a&&a.Fa)){try{var b=L.localStorage}catch(c){b=null}b=b?zj(b):null;a=!(b&&Ck(b)&&b)}a||vl(L,1)}}function pp(a){gd(function(){Uf(w).wasPlaTagProcessed||w.adsbygoogle&&w.adsbygoogle.push(a)})} function np(a,b){if(U(L).skip_next_reactive_tag)U(L).skip_next_reactive_tag=!1;else{0===(U(L).first_tag_on_page||0)&&(U(L).first_tag_on_page=1);if(a.tag_partner){var c=a.tag_partner,d=U(w);d.tag_partners=d.tag_partners||[];d.tag_partners.push(c)}U(L).ama_ran_on_page||Il(new Hl(a,b));cp(a,b)}} function op(a){if(a){if(!Uo(a)&&(a.id?a=Yo(a.id):a=null,!a))throw new T("'element' has already been filled.");if(!("innerHTML"in a))throw new T("'element' is not a good DOM element.");}else if(a=Yo(),!a)throw new T("All ins elements in the DOM with class=adsbygoogle already have ads in them.");return a} function rp(){var a=new Oj(L),b=new Oo(L),c=new Po(L),d=L.__cmp?1:0;a=Pj(a)?1:0;var e,f;(f="function"===typeof(null==(e=b.i)?void 0:e.__uspapi))||(b.h?b=b.h:(b.h=$c(b.i,"__uspapiLocator"),b=b.h),f=null!=b);c.l||(c.i||(c.i=c.h.googlefc?c.h:$c(c.h,"googlefcPresent")),c.l=!0);Yi("cmpMet",{tcfv1:d,tcfv2:a,usp:f?1:0,fc:c.i?1:0,ptt:9},Q(ye))}function sp(a){a={value:D(a,16)};var b=.01;Q(Te)&&(a.eid=Q(Te),b=1);a.frequency=b;Yi("new_abg_tag",a,b)}function tp(a){Dj().S[Fj(26)]=!!Number(a)} function up(a){Number(a)?U(L).pause_ad_requests=!0:(U(L).pause_ad_requests=!1,a=function(){if(!U(L).pause_ad_requests){var b=void 0===b?{}:b;if("function"===typeof window.CustomEvent)var c=new CustomEvent("adsbygoogle-pub-unpause-ad-requests-event",b);else c=document.createEvent("CustomEvent"),c.initCustomEvent("adsbygoogle-pub-unpause-ad-requests-event",!!b.bubbles,!!b.cancelable,b.detail);L.dispatchEvent(c)}},w.setTimeout(a,0),w.setTimeout(a,1E3))} function vp(a){Yi("adsenseGfpKnob",{value:a,ptt:9},.1);switch(a){case 0:case 2:a=!0;break;case 1:a=!1;break;default:throw Error("Illegal value of cookieOptions: "+a);}L._gfp_a_=a}function wp(a){a&&a.call&&"function"===typeof a&&window.setTimeout(a,0)} function hp(a,b){b=Dl(ec(hc(qc(b.sb).toString()),zf()?{bust:zf()}:{})).then(function(c){null==Qo&&(c.init(a),Qo=c,xp())});Zi(723,b);r(b,"finally").call(b,function(){Ro.length=0;Yi("slotcar",{event:"api_ld",time:Date.now()-Ia,time_pr:Date.now()-To})})} function xp(){for(var a=u(r(So,"keys").call(So)),b=a.next();!b.done;b=a.next()){b=b.value;var c=So.get(b);-1!==c&&(w.clearTimeout(c),So.delete(b))}a={};for(b=0;b<Ro.length;a={fa:a.fa,ba:a.ba},b++)So.has(b)||(a.ba=Ro[b],a.fa=ip(a.ba),Wi(723,function(d){return function(){3===d.fa?Qo.handleAdConfig(d.ba):2===d.fa&&Zi(730,Qo.handleAdBreakBeforeReady(d.ba))}}(a)))} function kp(a){var b=Ro.length;if(2===ip(a)&&"preroll"===a.type&&null!=a.adBreakDone){-1===To&&(To=Date.now());var c=w.setTimeout(function(){try{(0,a.adBreakDone)({breakType:"preroll",breakName:a.name,breakFormat:"preroll",breakStatus:"timeout"}),So.set(b,-1),Yi("slotcar",{event:"pr_to",source:"adsbygoogle"})}catch(d){console.error("[Ad Placement API] adBreakDone callback threw an error:",d instanceof Error?d:Error(String(d)))}},1E3*Q(kf));So.set(b,c)}} function yp(){if(P(Ne)&&!P(Me)){var a=L.document,b=a.createElement("LINK"),c=nd(Ml);if(c instanceof cc||c instanceof mc)b.href=sc(c);else{if(-1===tc.indexOf("stylesheet"))throw Error('TrustedResourceUrl href attribute required with rel="stylesheet"');b.href=rc(c)}b.rel="stylesheet";a.head.appendChild(b)}};(function(a,b,c,d){d=void 0===d?function(){}:d;Ui.Ua($i);Wi(166,function(){var e=sn(b);jn(I(e,2));Xk(D(e,6));d();kd(16,[1,e.toJSON()]);var f=md(ld(L))||L,g=c(kn({eb:a,nb:I(e,2)}),e);P(cf)&&al(f,e);om(f,e,null===L.document.currentScript?1:Ol(g.ub));Mo();if((!Na()||0<=Ka(Qa(),11))&&(null==(L.Prototype||{}).Version||!P(We))){Vi(P(qf));Go(e);ok();try{Mn()}catch(q){}Fo();fp(g,e);f=window;var h=f.adsbygoogle;if(!h||!h.loaded){if(P(Se)&&!D(e,16))try{if(L.document.querySelector('script[src*="/pagead/js/adsbygoogle.js?client="]'))return}catch(q){}yp(); sp(e);Q(ye)&&rp();var k={push:function(q){$o(q,g,e)},loaded:!0};try{Object.defineProperty(k,"requestNonPersonalizedAds",{set:tp}),Object.defineProperty(k,"pauseAdRequests",{set:up}),Object.defineProperty(k,"cookieOptions",{set:vp}),Object.defineProperty(k,"onload",{set:wp})}catch(q){}if(h)for(var l=u(["requestNonPersonalizedAds","pauseAdRequests","cookieOptions"]),m=l.next();!m.done;m=l.next())m=m.value,void 0!==h[m]&&(k[m]=h[m]);"_gfp_a_"in window||(window._gfp_a_=!0);Zo(h,g,e);f.adsbygoogle=k;h&& (k.onload=h.onload);(f=Bo(g))&&document.documentElement.appendChild(f)}}})})("m202204040101",rn,function(a,b){var c=2012<C(b,1,0)?"_fy"+C(b,1,0):"",d=I(b,3),e=I(b,2);b=nd(dn,a,c);d=nd(en,e,d);return{sb:b,qb:nd(fn,a,c),ob:nd(gn,a,c),pb:nd(hn,a,c),vb:d,ub:/^(?:https?:)?\/\/(?:pagead2\.googlesyndication\.com|securepubads\.g\.doubleclick\.net)\/pagead\/(?:js\/)?(?:show_ads|adsbygoogle)\.js(?:[?#].*)?$/}}); }).call(this,"[2019,\"r20220406\",\"r20190131\",null,null,null,null,\".google.co.uz\",null,null,null,[[[1082,null,null,[1]],[null,62,null,[null,0.001]],[383,null,null,[1]],[null,1130,null,[null,100]],[null,1126,null,[null,5000]],[1132,null,null,[1]],[1131,null,null,[1]],[null,1142,null,[null,2]],[null,1165,null,[null,1000]],[null,1114,null,[null,1]],[null,1116,null,[null,300]],[null,1117,null,[null,100]],[null,1115,null,[null,1]],[null,1159,null,[null,500]],[1145,null,null,[1]],[1021,null,null,[1]],[null,66,null,[null,-1]],[null,65,null,[null,-1]],[1087,null,null,[1]],[1053,null,null,[1]],[1100,null,null,[1]],[1102,null,null,[1]],[1149,null,null,[1]],[null,1072,null,[null,0.75]],[1101,null,null,[1]],[1036,null,null,[1]],[null,1085,null,[null,5]],[null,63,null,[null,30]],[null,1080,null,[null,5]],[1054,null,null,[1]],[null,1027,null,[null,10]],[null,57,null,[null,120]],[null,1079,null,[null,5]],[null,1050,null,[null,30]],[null,58,null,[null,120]],[381914117,null,null,[1]],[null,null,null,[null,null,null,[\"A8FHS1NmdCwGqD9DwOicnHHY+y27kdWfxKa0YHSGDfv0CSpDKRHTQdQmZVPDUdaFWUsxdgVxlwAd6o+dhJykPA0AAACWeyJvcmlnaW4iOiJodHRwczovL2RvdWJsZWNsaWNrLm5ldDo0NDMiLCJmZWF0dXJlIjoiQ29udmVyc2lvbk1lYXN1cmVtZW50IiwiZXhwaXJ5IjoxNjQzMTU1MTk5LCJpc1N1YmRvbWFpbiI6dHJ1ZSwiaXNUaGlyZFBhcnR5Ijp0cnVlLCJ1c2FnZSI6InN1YnNldCJ9\",\"A8zdXi6dr1hwXEUjQrYiyYQGlU3557y5QWDnN0Lwgj9ePt66XMEvNkVWOEOWPd7TP9sBQ25X0Q15Lr1Nn4oGFQkAAACceyJvcmlnaW4iOiJodHRwczovL2dvb2dsZXN5bmRpY2F0aW9uLmNvbTo0NDMiLCJmZWF0dXJlIjoiQ29udmVyc2lvbk1lYXN1cmVtZW50IiwiZXhwaXJ5IjoxNjQzMTU1MTk5LCJpc1N1YmRvbWFpbiI6dHJ1ZSwiaXNUaGlyZFBhcnR5Ijp0cnVlLCJ1c2FnZSI6InN1YnNldCJ9\",\"A4\/Htern2udN9w3yJK9QgWQxQFruxOXsXL7cW60DyCl0EZFGCSme\/J33Q\/WzF7bBkVvhEWDlcBiUyZaim5CpFQwAAACceyJvcmlnaW4iOiJodHRwczovL2dvb2dsZXRhZ3NlcnZpY2VzLmNvbTo0NDMiLCJmZWF0dXJlIjoiQ29udmVyc2lvbk1lYXN1cmVtZW50IiwiZXhwaXJ5IjoxNjQzMTU1MTk5LCJpc1N1YmRvbWFpbiI6dHJ1ZSwiaXNUaGlyZFBhcnR5Ijp0cnVlLCJ1c2FnZSI6InN1YnNldCJ9\"]],null,1934],[1953,null,null,[1]],[1947,null,null,[1]],[434462125,null,null,[1]],[1938,null,null,[1]],[1948,null,null,[1]],[392736476,null,null,[1]],[null,null,null,[null,null,null,[\"AxujKG9INjsZ8\/gUq8+dTruNvk7RjZQ1oFhhgQbcTJKDnZfbzSTE81wvC2Hzaf3TW4avA76LTZEMdiedF1vIbA4AAABueyJvcmlnaW4iOiJodHRwczovL2ltYXNkay5nb29nbGVhcGlzLmNvbTo0NDMiLCJmZWF0dXJlIjoiVHJ1c3RUb2tlbnMiLCJleHBpcnkiOjE2NTI3NzQ0MDAsImlzVGhpcmRQYXJ0eSI6dHJ1ZX0=\",\"Azuce85ORtSnWe1MZDTv68qpaW3iHyfL9YbLRy0cwcCZwVnePnOmkUJlG8HGikmOwhZU22dElCcfrfX2HhrBPAkAAAB7eyJvcmlnaW4iOiJodHRwczovL2RvdWJsZWNsaWNrLm5ldDo0NDMiLCJmZWF0dXJlIjoiVHJ1c3RUb2tlbnMiLCJleHBpcnkiOjE2NTI3NzQ0MDAsImlzU3ViZG9tYWluIjp0cnVlLCJpc1RoaXJkUGFydHkiOnRydWV9\",\"A16nvcdeoOAqrJcmjLRpl1I6f3McDD8EfofAYTt\/P\/H4\/AWwB99nxiPp6kA0fXoiZav908Z8etuL16laFPUdfQsAAACBeyJvcmlnaW4iOiJodHRwczovL2dvb2dsZXRhZ3NlcnZpY2VzLmNvbTo0NDMiLCJmZWF0dXJlIjoiVHJ1c3RUb2tlbnMiLCJleHBpcnkiOjE2NTI3NzQ0MDAsImlzU3ViZG9tYWluIjp0cnVlLCJpc1RoaXJkUGFydHkiOnRydWV9\",\"AxBHdr0J44vFBQtZUqX9sjiqf5yWZ\/OcHRcRMN3H9TH+t90V\/j3ENW6C8+igBZFXMJ7G3Pr8Dd13632aLng42wgAAACBeyJvcmlnaW4iOiJodHRwczovL2dvb2dsZXN5bmRpY2F0aW9uLmNvbTo0NDMiLCJmZWF0dXJlIjoiVHJ1c3RUb2tlbnMiLCJleHBpcnkiOjE2NTI3NzQ0MDAsImlzU3ViZG9tYWluIjp0cnVlLCJpc1RoaXJkUGFydHkiOnRydWV9\",\"A88BWHFjcawUfKU3lIejLoryXoyjooBXLgWmGh+hNcqMK44cugvsI5YZbNarYvi3roc1fYbHA1AVbhAtuHZflgEAAAB2eyJvcmlnaW4iOiJodHRwczovL2dvb2dsZS5jb206NDQzIiwiZmVhdHVyZSI6IlRydXN0VG9rZW5zIiwiZXhwaXJ5IjoxNjUyNzc0NDAwLCJpc1N1YmRvbWFpbiI6dHJ1ZSwiaXNUaGlyZFBhcnR5Ijp0cnVlfQ==\"]],null,1932],[null,397907552,null,[null,500]],[432938498,null,null,[1]]],[[10,[[1,[[21066108],[21066109,[[316,null,null,[1]]]]],null,null,null,34,18,1],[1,[[21066110],[21066111]],null,null,null,34,18,1],[1,[[42530528],[42530529,[[368,null,null,[1]]]],[42530530,[[369,null,null,[1]],[368,null,null,[1]]]]]],[1,[[42531496],[42531497,[[1161,null,null,[1]]]]]],[1,[[42531513],[42531514,[[316,null,null,[1]]]]]],[1,[[44719338],[44719339,[[334,null,null,[1]],[null,54,null,[null,100]],[null,66,null,[null,10]],[null,65,null,[null,1000]]]]]],[200,[[44760474],[44760475,[[1129,null,null,[1]]]]]],[10,[[44760911],[44760912,[[1160,null,null,[1]]]]]],[100,[[44761043],[44761044]]],[1,[[44752536,[[1122,null,null,[1]],[1033,null,null,[1]]]],[44753656]]],[null,[[44755592],[44755593,[[1122,null,null,[1]],[1033,null,null,[1]]]],[44755594,[[1122,null,null,[1]],[1033,null,null,[1]]]],[44755653,[[1122,null,null,[1]],[1033,null,null,[1]]]]]],[10,[[44762453],[44762454,[[1122,null,null,[1]],[1033,null,null,[1]]]]]],[20,[[182982000,[[218,null,null,[1]]],[1,[[12,null,null,null,2,null,\"\\\\.wiki(dogs|how)(-fun)?\\\\.\"]]]],[182982100,[[217,null,null,[1]]],[1,[[12,null,null,null,2,null,\"\\\\.wiki(dogs|how)(-fun)?\\\\.\"]]]]],null,null,null,36,8,1],[20,[[182982200,null,[1,[[12,null,null,null,2,null,\"\\\\.wiki(dogs|how)(-fun)?\\\\.\"]]]],[182982300,null,[1,[[12,null,null,null,2,null,\"\\\\.wiki(dogs|how)(-fun)?\\\\.\"]]]]],null,null,null,36,8,1],[10,[[182984000,null,[4,null,23,null,null,null,null,[\"1\"]]],[182984100,[[218,null,null,[1]]],[4,null,23,null,null,null,null,[\"1\"]]]],null,null,null,36,10,101],[10,[[182984200,null,[4,null,23,null,null,null,null,[\"1\"]]],[182984300,null,[4,null,23,null,null,null,null,[\"1\"]]]],null,null,null,36,10,101],[10,[[21066428],[21066429]]],[10,[[21066430],[21066431],[21066432],[21066433]],null,null,null,44,22],[10,[[21066434],[21066435]],null,null,null,44,null,500],[10,[[31065342],[31065343,[[1147,null,null,[1]]]]]],[50,[[31065544],[31065545,[[1154,null,null,[1]]]]]],[50,[[31065741],[31065742,[[1134,null,null,[1]]]]]],[1,[[31065944,[[null,1103,null,[null,31065944]],[1121,null,null,[1]],[null,1119,null,[null,300]]]],[31065945,[[null,1103,null,[null,31065945]],[1121,null,null,[1]],[1143,null,null,[1]],[null,1119,null,[null,300]]]],[31065946,[[null,1103,null,[null,31065946]],[1121,null,null,[1]],[null,1119,null,[null,300]],[1120,null,null,[1]]]],[31065950,[[null,1103,null,[null,31065950]],[null,1114,null,[null,0.9]],[null,1112,null,[null,5]],[null,1113,null,[null,5]],[null,1104,null,[null,100]],[null,1115,null,[null,0.8]],[1121,null,null,[1]],[null,1119,null,[null,300]],[1120,null,null,[1]]]],[31065951,[[null,1103,null,[null,31065951]],[null,1114,null,[null,0.9]],[null,1110,null,[null,1]],[null,1104,null,[null,100]],[null,1115,null,[null,0.8]],[1121,null,null,[1]],[null,1119,null,[null,300]],[1120,null,null,[1]]]],[31065952,[[null,1103,null,[null,31065952]],[null,1114,null,[null,0.9]],[null,1110,null,[null,5]],[null,1104,null,[null,100]],[null,1115,null,[null,0.8]],[1121,null,null,[1]],[null,1119,null,[null,300]],[1120,null,null,[1]]]],[31065953,[[null,1103,null,[null,31065953]],[null,1114,null,[null,0.9]],[null,1110,null,[null,5]],[null,1111,null,[null,5]],[null,1112,null,[null,5]],[null,1113,null,[null,5]],[null,1104,null,[null,100]],[null,1115,null,[null,0.8]],[1121,null,null,[1]],[null,1119,null,[null,300]],[1120,null,null,[1]]]],[44762492,[[null,1103,null,[null,44762492]],[null,1114,null,[null,0.9]],[null,1104,null,[null,100]],[null,1106,null,[null,10]],[null,1107,null,[null,10]],[null,1105,null,[null,10]],[null,1115,null,[null,-1]],[1121,null,null,[1]],[null,1119,null,[null,300]],[1120,null,null,[1]]]]],[6,null,null,3,null,2],49],[1,[[31066496,[[null,1103,null,[null,31066496]],[1121,null,null,[1]],[null,1119,null,[null,300]]]],[31066497,[[null,1158,null,[null,45]],[null,1157,null,[null,400]],[null,1103,null,[null,31066497]],[null,1114,null,[null,-1]],[null,1104,null,[null,100]],[null,1106,null,[null,10]],[null,1107,null,[null,10]],[null,1105,null,[null,10]],[null,1115,null,[null,-1]],[1121,null,null,[1]],[null,1119,null,[null,300]],[1162,null,null,[1]],[1155,null,null,[1]],[1120,null,null,[1]]]]],null,49],[1000,[[31067051,[[null,null,14,[null,null,\"31067051\"]]],[6,null,null,null,6,null,\"31067051\"]],[31067052,[[null,null,14,[null,null,\"31067052\"]]],[6,null,null,null,6,null,\"31067052\"]]],[4,null,55]],[1000,[[31067063,[[null,null,14,[null,null,\"31067063\"]]],[6,null,null,null,6,null,\"31067063\"]],[31067064,[[null,null,14,[null,null,\"31067064\"]]],[6,null,null,null,6,null,\"31067064\"]]],[4,null,55]],[10,[[31067067],[31067068,[[1148,null,null,[1]]]]]],[1000,[[31067083,[[null,null,14,[null,null,\"31067083\"]]],[6,null,null,null,6,null,\"31067083\"]],[31067084,[[null,null,14,[null,null,\"31067084\"]]],[6,null,null,null,6,null,\"31067084\"]]],[4,null,55]],[1,[[44736076],[44736077,[[null,1046,null,[null,0.1]]]]]],[1,[[44761631,[[null,1103,null,[null,44761631]]]],[44761632,[[null,1103,null,[null,44761632]],[1143,null,null,[1]]]],[44761633,[[null,1142,null,[null,2]],[null,1103,null,[null,44761633]],[null,1119,null,[null,300]],[1120,null,null,[1]]]],[44761634,[[null,1142,null,[null,2]],[null,1103,null,[null,44761634]],[null,1114,null,[null,0.9]],[null,1104,null,[null,100]],[null,1115,null,[null,0.8]],[null,1119,null,[null,300]],[1120,null,null,[1]]]],[44761635,[[null,1142,null,[null,2]],[null,1103,null,[null,44761635]],[null,1114,null,[null,0.9]],[null,1106,null,[null,10]],[null,1115,null,[null,0.8]],[null,1119,null,[null,300]],[1120,null,null,[1]]]],[44761636,[[null,1142,null,[null,2]],[null,1103,null,[null,44761636]],[null,1114,null,[null,0.9]],[null,1107,null,[null,10]],[null,1115,null,[null,0.8]],[null,1119,null,[null,300]],[1120,null,null,[1]]]],[44761637,[[null,1142,null,[null,2]],[null,1103,null,[null,44761637]],[null,1114,null,[null,0.9]],[null,1105,null,[null,10]],[null,1115,null,[null,0.8]],[null,1119,null,[null,300]],[1120,null,null,[1]]]],[44762110,[[null,1142,null,[null,2]],[null,1103,null,[null,44762110]],[null,1114,null,[null,0.9]],[null,1104,null,[null,100]],[null,1115,null,[null,-1]],[null,1119,null,[null,300]],[1120,null,null,[1]]]]],[6,null,null,3,null,2],49],[500,[[44761838,[[null,1142,null,[null,2]],[null,1103,null,[null,44761838]],[null,1114,null,[null,0.9]],[null,1104,null,[null,100]],[null,1115,null,[null,-1]],[null,1119,null,[null,300]],[1120,null,null,[1]]]]],[2,[[6,null,null,3,null,2],[12,null,null,null,2,null,\"smitmehta\\\\.com\/\"]]],49],[null,[[44762338],[44762339,[[380254521,null,null,[1]]]]],[1,[[4,null,63]]],null,null,56],[150,[[31061760],[31063913,[[null,1126,null,[null,5000],[[[12,null,null,null,4,null,\"Android\",[\"navigator.userAgent\"]],[null,5500]]]],[null,1032,null,[null,200],[[[12,null,null,null,4,null,\"Android\",[\"navigator.userAgent\"]],[null,500]]]]]],[31065341,[[1150,null,null,[1]],[null,1126,null,[null,5000],[[[12,null,null,null,4,null,\"Android\",[\"navigator.userAgent\"]],[null,5500]]]],[null,1032,null,[null,200],[[[12,null,null,null,4,null,\"Android\",[\"navigator.userAgent\"]],[null,500]]]]]]],[3,[[4,null,8,null,null,null,null,[\"gmaSdk.getQueryInfo\"]],[4,null,8,null,null,null,null,[\"webkit.messageHandlers.getGmaQueryInfo.postMessage\"]],[4,null,8,null,null,null,null,[\"webkit.messageHandlers.getGmaSig.postMessage\"]]]],15],[50,[[31061761,[[null,1126,null,[null,5000],[[[12,null,null,null,4,null,\"Android\",[\"navigator.userAgent\"]],[null,5500]]]],[null,1032,null,[null,200],[[[12,null,null,null,4,null,\"Android\",[\"navigator.userAgent\"]],[null,500]]]]]],[31062202,[[null,1126,null,[null,5000],[[[12,null,null,null,4,null,\"Android\",[\"navigator.userAgent\"]],[null,5500]]]],[null,1032,null,[null,200],[[[12,null,null,null,4,null,\"Android\",[\"navigator.userAgent\"]],[null,500]]]]]],[31063912],[44756455,[[null,1126,null,[null,5000],[[[12,null,null,null,4,null,\"Android\",[\"navigator.userAgent\"]],[null,5500]]]],[null,1032,null,[null,200],[[[12,null,null,null,4,null,\"Android\",[\"navigator.userAgent\"]],[null,500]]]]]]],[3,[[4,null,8,null,null,null,null,[\"gmaSdk.getQueryInfo\"]],[4,null,8,null,null,null,null,[\"webkit.messageHandlers.getGmaQueryInfo.postMessage\"]],[4,null,8,null,null,null,null,[\"webkit.messageHandlers.getGmaSig.postMessage\"]]]],15],[null,[[31063202,[[null,1126,null,[null,5000],[[[12,null,null,null,4,null,\"Android\",[\"navigator.userAgent\"]],[null,5500]]]],[null,1032,null,[null,200],[[[12,null,null,null,4,null,\"Android\",[\"navigator.userAgent\"]],[null,500]]]]]]],[3,[[4,null,8,null,null,null,null,[\"gmaSdk.getQueryInfo\"]],[4,null,8,null,null,null,null,[\"webkit.messageHandlers.getGmaQueryInfo.postMessage\"]],[4,null,8,null,null,null,null,[\"webkit.messageHandlers.getGmaSig.postMessage\"]]]],15],[null,[[44753753,[[null,1126,null,[null,5000],[[[12,null,null,null,4,null,\"Android\",[\"navigator.userAgent\"]],[null,5500]]]],[null,1032,null,[null,200],[[[12,null,null,null,4,null,\"Android\",[\"navigator.userAgent\"]],[null,500]]]]]]],[3,[[4,null,8,null,null,null,null,[\"gmaSdk.getQueryInfo\"]],[4,null,8,null,null,null,null,[\"webkit.messageHandlers.getGmaQueryInfo.postMessage\"]],[4,null,8,null,null,null,null,[\"webkit.messageHandlers.getGmaSig.postMessage\"]]]],15]]],[20,[[50,[[31062930],[31062931,[[380025941,null,null,[1]]]]],null,null,null,null,null,101,null,102]]],[13,[[10,[[44759847],[44759848,[[1947,null,null,[]]]]]],[10,[[44759849],[44759850]]],[1,[[31065824],[31065825,[[424117738,null,null,[1]]]]]],[10,[[31066184],[31066185,[[436251930,null,null,[1]]]]]],[1000,[[21067496]],[4,null,9,null,null,null,null,[\"document.hasTrustToken\"]]],[1000,[[31060475,null,[2,[[1,[[4,null,9,null,null,null,null,[\"window.PeriodicSyncManager\"]]]],[12,null,null,null,4,null,\"Android\",[\"navigator.userAgent\"]]]]]]],[500,[[31061692],[31061693,[[77,null,null,[1]],[78,null,null,[1]],[85,null,null,[1]],[80,null,null,[1]],[76,null,null,[1]]]]],[4,null,6,null,null,null,null,[\"31061691\"]]],[1,[[31062890],[31062891,[[397841828,null,null,[1]]]]]],[1,[[31062946]],[4,null,27,null,null,null,null,[\"document.prerendering\"]]],[1,[[31062947]],[1,[[4,null,27,null,null,null,null,[\"document.prerendering\"]]]]],[50,[[31064018],[31064019,[[1961,null,null,[1]]]]]],[1,[[31065981,null,[2,[[6,null,null,3,null,0],[12,null,null,null,4,null,\"Chrome\/(9[23456789]|\\\\d{3,})\",[\"navigator.userAgent\"]],[4,null,27,null,null,null,null,[\"crossOriginIsolated\"]]]]]]]]],[11,[[10,[[44760494],[44760495,[[1957,null,null,[1]]]]],null,48],[1,[[44760496],[44760497,[[1957,null,null,[1]]]],[44760498,[[1957,null,null,[1]]]]],null,48],[2,[[44761535],[44761536,[[1957,null,null,[1]],[1963,null,null,[1]]]],[44761537,[[1957,null,null,[1]],[1964,null,null,[1]]]],[44761538,[[1957,null,null,[1]],[1965,null,null,[1]]]],[44761539,[[1957,null,null,[1]]]]],null,48]]],[17,[[10,[[31060047]],null,null,null,44,null,900],[10,[[31060048],[31060049]],null,null,null,null,null,null,null,101],[10,[[31060566]]]]],[12,[[50,[[31061828],[31061829,[[null,1126,null,[null,5000],[[[12,null,null,null,4,null,\"Android\",[\"navigator.userAgent\"]],[null,5500]]]],[null,1032,null,[null,200],[[[12,null,null,null,4,null,\"Android\",[\"navigator.userAgent\"]],[null,500]]]],[360245597,null,null,[1]],[null,494,null,[null,5000],[[[12,null,null,null,4,null,\"Android\",[\"navigator.userAgent\"]],[null,5500]]]]]],[31065659,[[1150,null,null,[1]],[null,1126,null,[null,5000],[[[12,null,null,null,4,null,\"Android\",[\"navigator.userAgent\"]],[null,5500]]]],[null,1032,null,[null,10000]],[427841102,null,null,[1]],[360245597,null,null,[1]],[null,494,null,[null,5000],[[[12,null,null,null,4,null,\"Android\",[\"navigator.userAgent\"]],[null,5500]]]]]],[31065787]],null,15],[20,[[21065724],[21065725,[[203,null,null,[1]]]]],[4,null,9,null,null,null,null,[\"LayoutShift\"]]],[50,[[31060006,null,[2,[[12,null,null,null,4,null,\"Android\",[\"navigator.userAgent\"]],[12,null,null,null,4,null,\"Chrome\/(89|9\\\\d|\\\\d{3,})\",[\"navigator.userAgent\"]],[4,null,9,null,null,null,null,[\"window.PeriodicSyncManager\"]]]]],[31060007,[[1928,null,null,[1]]],[2,[[12,null,null,null,4,null,\"Android\",[\"navigator.userAgent\"]],[12,null,null,null,4,null,\"Chrome\/(89|9\\\\d|\\\\d{3,})\",[\"navigator.userAgent\"]],[4,null,9,null,null,null,null,[\"window.PeriodicSyncManager\"]]]]]],null,21],[10,[[31060032],[31060033,[[1928,null,null,[1]]]]],null,21],[10,[[31061690],[31061691,[[83,null,null,[1]],[84,null,null,[1]]]]]],[1,[[31065721],[31065722,[[432946749,null,null,[1]]]]]]]]],null,null,[0.001,\"1000\",1,\"1000\"]],[null,[]],null,null,1,\"github.com\",309779023,[44759876,44759927,44759842]]");
cortinico / Kscript Template📜 Get started with kscript in a few seconds... with colored logs, github actions and more!
arashstar1 / Bot LuaCode Issues 0 Pull requests 0 Pulse MaTaDoR/ 3233fdf V 5.7 MaTaDoR @MaTaDoRTeaMMaTaDoRTeaM committed on GitHub about 1 month ago 2 changed files 2,704 additions and 0 deletions cli/tg/tdcli.lua @@ -0,0 +1,2704 @@ +--[[ + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. + +]]-- + +-- Vector example form is like this: {[0] = v} or {v1, v2, v3, [0] = v} +-- If false or true crashed your telegram-cli, try to change true to 1 and false to 0 + +-- Main Bot Framework +local M = {} + +-- @chat_id = user, group, channel, and broadcast +-- @group_id = normal group +-- @channel_id = channel and broadcast +local function getChatId(chat_id) + local chat = {} + local chat_id = tostring(chat_id) + + if chat_id:match('^-100') then + local channel_id = chat_id:gsub('-100', '') + chat = {ID = channel_id, type = 'channel'} + else + local group_id = chat_id:gsub('-', '') + chat = {ID = group_id, type = 'group'} + end + + return chat +end + +local function getInputFile(file) + if file:match('/') then + infile = {ID = "InputFileLocal", path_ = file} + elseif file:match('^%d+$') then + infile = {ID = "InputFileId", id_ = file} + else + infile = {ID = "InputFilePersistentId", persistent_id_ = file} + end + + return infile +end + +-- User can send bold, italic, and monospace text uses HTML or Markdown format. +local function getParseMode(parse_mode) + if parse_mode then + local mode = parse_mode:lower() + + if mode == 'markdown' or mode == 'md' then + P = {ID = "TextParseModeMarkdown"} + elseif mode == 'html' then + P = {ID = "TextParseModeHTML"} + end + end + + return P +end + +-- Returns current authorization state, offline request +local function getAuthState(dl_cb, cmd) + tdcli_function ({ + ID = "GetAuthState", + }, dl_cb, cmd) +end + +M.getAuthState = getAuthState + +-- Sets user's phone number and sends authentication code to the user. +-- Works only when authGetState returns authStateWaitPhoneNumber. +-- If phone number is not recognized or another error has happened, returns an error. Otherwise returns authStateWaitCode +-- @phone_number User's phone number in any reasonable format +-- @allow_flash_call Pass True, if code can be sent via flash call to the specified phone number +-- @is_current_phone_number Pass true, if the phone number is used on the current device. Ignored if allow_flash_call is False +local function setAuthPhoneNumber(phone_number, allow_flash_call, is_current_phone_number, dl_cb, cmd) + tdcli_function ({ + ID = "SetAuthPhoneNumber", + phone_number_ = phone_number, + allow_flash_call_ = allow_flash_call, + is_current_phone_number_ = is_current_phone_number + }, dl_cb, cmd) +end + +M.setAuthPhoneNumber = setAuthPhoneNumber + +-- Resends authentication code to the user. +-- Works only when authGetState returns authStateWaitCode and next_code_type of result is not null. +-- Returns authStateWaitCode on success +local function resendAuthCode(dl_cb, cmd) + tdcli_function ({ + ID = "ResendAuthCode", + }, dl_cb, cmd) +end + +M.resendAuthCode = resendAuthCode + +-- Checks authentication code. +-- Works only when authGetState returns authStateWaitCode. +-- Returns authStateWaitPassword or authStateOk on success +-- @code Verification code from SMS, Telegram message, voice call or flash call +-- @first_name User first name, if user is yet not registered, 1-255 characters +-- @last_name Optional user last name, if user is yet not registered, 0-255 characters +local function checkAuthCode(code, first_name, last_name, dl_cb, cmd) + tdcli_function ({ + ID = "CheckAuthCode", + code_ = code, + first_name_ = first_name, + last_name_ = last_name + }, dl_cb, cmd) +end + +M.checkAuthCode = checkAuthCode + +-- Checks password for correctness. +-- Works only when authGetState returns authStateWaitPassword. +-- Returns authStateOk on success +-- @password Password to check +local function checkAuthPassword(password, dl_cb, cmd) + tdcli_function ({ + ID = "CheckAuthPassword", + password_ = password + }, dl_cb, cmd) +end + +M.checkAuthPassword = checkAuthPassword + +-- Requests to send password recovery code to email. +-- Works only when authGetState returns authStateWaitPassword. +-- Returns authStateWaitPassword on success +local function requestAuthPasswordRecovery(dl_cb, cmd) + tdcli_function ({ + ID = "RequestAuthPasswordRecovery", + }, dl_cb, cmd) +end + +M.requestAuthPasswordRecovery = requestAuthPasswordRecovery + +-- Recovers password with recovery code sent to email. +-- Works only when authGetState returns authStateWaitPassword. +-- Returns authStateOk on success +-- @recovery_code Recovery code to check +local function recoverAuthPassword(recovery_code, dl_cb, cmd) + tdcli_function ({ + ID = "RecoverAuthPassword", + recovery_code_ = recovery_code + }, dl_cb, cmd) +end + +M.recoverAuthPassword = recoverAuthPassword + +-- Logs out user. +-- If force == false, begins to perform soft log out, returns authStateLoggingOut after completion. +-- If force == true then succeeds almost immediately without cleaning anything at the server, but returns error with code 401 and description "Unauthorized" +-- @force If true, just delete all local data. Session will remain in list of active sessions +local function resetAuth(force, dl_cb, cmd) + tdcli_function ({ + ID = "ResetAuth", + force_ = force or nil + }, dl_cb, cmd) +end + +M.resetAuth = resetAuth + +-- Check bot's authentication token to log in as a bot. +-- Works only when authGetState returns authStateWaitPhoneNumber. +-- Can be used instead of setAuthPhoneNumber and checkAuthCode to log in. +-- Returns authStateOk on success +-- @token Bot token +local function checkAuthBotToken(token, dl_cb, cmd) + tdcli_function ({ + ID = "CheckAuthBotToken", + token_ = token + }, dl_cb, cmd) +end + +M.checkAuthBotToken = checkAuthBotToken + +-- Returns current state of two-step verification +local function getPasswordState(dl_cb, cmd) + tdcli_function ({ + ID = "GetPasswordState", + }, dl_cb, cmd) +end + +M.getPasswordState = getPasswordState + +-- Changes user password. +-- If new recovery email is specified, then error EMAIL_UNCONFIRMED is returned and password change will not be applied until email confirmation. +-- Application should call getPasswordState from time to time to check if email is already confirmed +-- @old_password Old user password +-- @new_password New user password, may be empty to remove the password +-- @new_hint New password hint, can be empty +-- @set_recovery_email Pass True, if recovery email should be changed +-- @new_recovery_email New recovery email, may be empty +local function setPassword(old_password, new_password, new_hint, set_recovery_email, new_recovery_email, dl_cb, cmd) + tdcli_function ({ + ID = "SetPassword", + old_password_ = old_password, + new_password_ = new_password, + new_hint_ = new_hint, + set_recovery_email_ = set_recovery_email, + new_recovery_email_ = new_recovery_email + }, dl_cb, cmd) +end + +M.setPassword = setPassword + +-- Returns set up recovery email. +-- This method can be used to verify a password provided by the user +-- @password Current user password +local function getRecoveryEmail(password, dl_cb, cmd) + tdcli_function ({ + ID = "GetRecoveryEmail", + password_ = password + }, dl_cb, cmd) +end + +M.getRecoveryEmail = getRecoveryEmail + +-- Changes user recovery email. +-- If new recovery email is specified, then error EMAIL_UNCONFIRMED is returned and email will not be changed until email confirmation. +-- Application should call getPasswordState from time to time to check if email is already confirmed. +-- If new_recovery_email coincides with the current set up email succeeds immediately and aborts all other requests waiting for email confirmation +-- @password Current user password +-- @new_recovery_email New recovery email +local function setRecoveryEmail(password, new_recovery_email, dl_cb, cmd) + tdcli_function ({ + ID = "SetRecoveryEmail", + password_ = password, + new_recovery_email_ = new_recovery_email + }, dl_cb, cmd) +end + +M.setRecoveryEmail = setRecoveryEmail + +-- Requests to send password recovery code to email +local function requestPasswordRecovery(dl_cb, cmd) + tdcli_function ({ + ID = "RequestPasswordRecovery", + }, dl_cb, cmd) +end + +M.requestPasswordRecovery = requestPasswordRecovery + +-- Recovers password with recovery code sent to email +-- @recovery_code Recovery code to check +local function recoverPassword(recovery_code, dl_cb, cmd) + tdcli_function ({ + ID = "RecoverPassword", + recovery_code_ = tostring(recovery_code) + }, dl_cb, cmd) +end + +M.recoverPassword = recoverPassword + +-- Returns current logged in user +local function getMe(dl_cb, cmd) + tdcli_function ({ + ID = "GetMe", + }, dl_cb, cmd) +end + +M.getMe = getMe + +-- Returns information about a user by its identifier, offline request if current user is not a bot +-- @user_id User identifier +local function getUser(user_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetUser", + user_id_ = user_id + }, dl_cb, cmd) +end + +M.getUser = getUser + +-- Returns full information about a user by its identifier +-- @user_id User identifier +local function getUserFull(user_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetUserFull", + user_id_ = user_id + }, dl_cb, cmd) +end + +M.getUserFull = getUserFull + +-- Returns information about a group by its identifier, offline request if current user is not a bot +-- @group_id Group identifier +local function getGroup(group_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetGroup", + group_id_ = getChatId(group_id).ID + }, dl_cb, cmd) +end + +M.getGroup = getGroup + +-- Returns full information about a group by its identifier +-- @group_id Group identifier +local function getGroupFull(group_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetGroupFull", + group_id_ = getChatId(group_id).ID + }, dl_cb, cmd) +end + +M.getGroupFull = getGroupFull + +-- Returns information about a channel by its identifier, offline request if current user is not a bot +-- @channel_id Channel identifier +local function getChannel(channel_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetChannel", + channel_id_ = getChatId(channel_id).ID + }, dl_cb, cmd) +end + +M.getChannel = getChannel + +-- Returns full information about a channel by its identifier, cached for at most 1 minute +-- @channel_id Channel identifier +local function getChannelFull(channel_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetChannelFull", + channel_id_ = getChatId(channel_id).ID + }, dl_cb, cmd) +end + +M.getChannelFull = getChannelFull + +-- Returns information about a secret chat by its identifier, offline request +-- @secret_chat_id Secret chat identifier +local function getSecretChat(secret_chat_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetSecretChat", + secret_chat_id_ = secret_chat_id + }, dl_cb, cmd) +end + +M.getSecretChat = getSecretChat + +-- Returns information about a chat by its identifier, offline request if current user is not a bot +-- @chat_id Chat identifier +local function getChat(chat_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetChat", + chat_id_ = chat_id + }, dl_cb, cmd) +end + +M.getChat = getChat + +-- Returns information about a message +-- @chat_id Identifier of the chat, message belongs to +-- @message_id Identifier of the message to get +local function getMessage(chat_id, message_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetMessage", + chat_id_ = chat_id, + message_id_ = message_id + }, dl_cb, cmd) +end + +M.getMessage = getMessage + +-- Returns information about messages. +-- If message is not found, returns null on the corresponding position of the result +-- @chat_id Identifier of the chat, messages belongs to +-- @message_ids Identifiers of the messages to get +local function getMessages(chat_id, message_ids, dl_cb, cmd) + tdcli_function ({ + ID = "GetMessages", + chat_id_ = chat_id, + message_ids_ = message_ids -- vector + }, dl_cb, cmd) +end + +M.getMessages = getMessages + +-- Returns information about a file, offline request +-- @file_id Identifier of the file to get +local function getFile(file_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetFile", + file_id_ = file_id + }, dl_cb, cmd) +end + +M.getFile = getFile + +-- Returns information about a file by its persistent id, offline request +-- @persistent_file_id Persistent identifier of the file to get +local function getFilePersistent(persistent_file_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetFilePersistent", + persistent_file_id_ = persistent_file_id + }, dl_cb, cmd) +end + +M.getFilePersistent = getFilePersistent + +-- Returns list of chats in the right order, chats are sorted by (order, chat_id) in decreasing order. +-- For example, to get list of chats from the beginning, the offset_order should be equal 2^63 - 1 +-- @offset_order Chat order to return chats from +-- @offset_chat_id Chat identifier to return chats from +-- @limit Maximum number of chats to be returned +local function getChats(offset_order, offset_chat_id, limit, dl_cb, cmd) + if not limit or limit > 20 then + limit = 20 + end + + tdcli_function ({ + ID = "GetChats", + offset_order_ = offset_order or 9223372036854775807, + offset_chat_id_ = offset_chat_id or 0, + limit_ = limit + }, dl_cb, cmd) +end + +M.getChats = getChats + +-- Searches public chat by its username. +-- Currently only private and channel chats can be public. +-- Returns chat if found, otherwise some error is returned +-- @username Username to be resolved +local function searchPublicChat(username, dl_cb, cmd) + tdcli_function ({ + ID = "SearchPublicChat", + username_ = username + }, dl_cb, cmd) +end + +M.searchPublicChat = searchPublicChat + +-- Searches public chats by prefix of their username. +-- Currently only private and channel (including supergroup) chats can be public. +-- Returns meaningful number of results. +-- Returns nothing if length of the searched username prefix is less than 5. +-- Excludes private chats with contacts from the results +-- @username_prefix Prefix of the username to search +local function searchPublicChats(username_prefix, dl_cb, cmd) + tdcli_function ({ + ID = "SearchPublicChats", + username_prefix_ = username_prefix + }, dl_cb, cmd) +end + +M.searchPublicChats = searchPublicChats + +-- Searches for specified query in the title and username of known chats, offline request. +-- Returns chats in the order of them in the chat list +-- @query Query to search for, if query is empty, returns up to 20 recently found chats +-- @limit Maximum number of chats to be returned +local function searchChats(query, limit, dl_cb, cmd) + if not limit or limit > 20 then + limit = 20 + end + + tdcli_function ({ + ID = "SearchChats", + query_ = query, + limit_ = limit + }, dl_cb, cmd) +end + +M.searchChats = searchChats + +-- Adds chat to the list of recently found chats. +-- The chat is added to the beginning of the list. +-- If the chat is already in the list, at first it is removed from the list +-- @chat_id Identifier of the chat to add +local function addRecentlyFoundChat(chat_id, dl_cb, cmd) + tdcli_function ({ + ID = "AddRecentlyFoundChat", + chat_id_ = chat_id + }, dl_cb, cmd) +end + +M.addRecentlyFoundChat = addRecentlyFoundChat + +-- Deletes chat from the list of recently found chats +-- @chat_id Identifier of the chat to delete +local function deleteRecentlyFoundChat(chat_id, dl_cb, cmd) + tdcli_function ({ + ID = "DeleteRecentlyFoundChat", + chat_id_ = chat_id + }, dl_cb, cmd) +end + +M.deleteRecentlyFoundChat = deleteRecentlyFoundChat + +-- Clears list of recently found chats +local function deleteRecentlyFoundChats(dl_cb, cmd) + tdcli_function ({ + ID = "DeleteRecentlyFoundChats", + }, dl_cb, cmd) +end + +M.deleteRecentlyFoundChats = deleteRecentlyFoundChats + +-- Returns list of common chats with an other given user. +-- Chats are sorted by their type and creation date +-- @user_id User identifier +-- @offset_chat_id Chat identifier to return chats from, use 0 for the first request +-- @limit Maximum number of chats to be returned, up to 100 +local function getCommonChats(user_id, offset_chat_id, limit, dl_cb, cmd) + if not limit or limit > 100 then + limit = 100 + end + + tdcli_function ({ + ID = "GetCommonChats", + user_id_ = user_id, + offset_chat_id_ = offset_chat_id, + limit_ = limit + }, dl_cb, cmd) +end + +M.getCommonChats = getCommonChats + +-- Returns messages in a chat. +-- Automatically calls openChat. +-- Returns result in reverse chronological order, i.e. in order of decreasing message.message_id +-- @chat_id Chat identifier +-- @from_message_id Identifier of the message near which we need a history, you can use 0 to get results from the beginning, i.e. from oldest to newest +-- @offset Specify 0 to get results exactly from from_message_id or negative offset to get specified message and some newer messages +-- @limit Maximum number of messages to be returned, should be positive and can't be greater than 100. +-- If offset is negative, limit must be greater than -offset. +-- There may be less than limit messages returned even the end of the history is not reached +local function getChatHistory(chat_id, from_message_id, offset, limit, dl_cb, cmd) + if not limit or limit > 100 then + limit = 100 + end + + tdcli_function ({ + ID = "GetChatHistory", + chat_id_ = chat_id, + from_message_id_ = from_message_id, + offset_ = offset or 0, + limit_ = limit + }, dl_cb, cmd) +end + +M.getChatHistory = getChatHistory + +-- Deletes all messages in the chat. +-- Can't be used for channel chats +-- @chat_id Chat identifier +-- @remove_from_chat_list Pass true, if chat should be removed from the chat list +local function deleteChatHistory(chat_id, remove_from_chat_list, dl_cb, cmd) + tdcli_function ({ + ID = "DeleteChatHistory", + chat_id_ = chat_id, + remove_from_chat_list_ = remove_from_chat_list + }, dl_cb, cmd) +end + +M.deleteChatHistory = deleteChatHistory + +-- Searches for messages with given words in the chat. +-- Returns result in reverse chronological order, i. e. in order of decreasimg message_id. +-- Doesn't work in secret chats +-- @chat_id Chat identifier to search in +-- @query Query to search for +-- @from_message_id Identifier of the message from which we need a history, you can use 0 to get results from beginning +-- @limit Maximum number of messages to be returned, can't be greater than 100 +-- @filter Filter for content of searched messages +-- filter = Empty|Animation|Audio|Document|Photo|Video|Voice|PhotoAndVideo|Url|ChatPhoto +local function searchChatMessages(chat_id, query, from_message_id, limit, filter, dl_cb, cmd) + if not limit or limit > 100 then + limit = 100 + end + + tdcli_function ({ + ID = "SearchChatMessages", + chat_id_ = chat_id, + query_ = query, + from_message_id_ = from_message_id, + limit_ = limit, + filter_ = { + ID = 'SearchMessagesFilter' .. filter + }, + }, dl_cb, cmd) +end + +M.searchChatMessages = searchChatMessages + +-- Searches for messages in all chats except secret chats. Returns result in reverse chronological order, i. e. in order of decreasing (date, chat_id, message_id) +-- @query Query to search for +-- @offset_date Date of the message to search from, you can use 0 or any date in the future to get results from the beginning +-- @offset_chat_id Chat identifier of the last found message or 0 for the first request +-- @offset_message_id Message identifier of the last found message or 0 for the first request +-- @limit Maximum number of messages to be returned, can't be greater than 100 +local function searchMessages(query, offset_date, offset_chat_id, offset_message_id, limit, dl_cb, cmd) + if not limit or limit > 100 then + limit = 100 + end + + tdcli_function ({ + ID = "SearchMessages", + query_ = query, + offset_date_ = offset_date, + offset_chat_id_ = offset_chat_id, + offset_message_id_ = offset_message_id, + limit_ = limit + }, dl_cb, cmd) +end + +M.searchMessages = searchMessages + +-- Invites bot to a chat (if it is not in the chat) and send /start to it. +-- Bot can't be invited to a private chat other than chat with the bot. +-- Bots can't be invited to broadcast channel chats and secret chats. +-- Returns sent message. +-- UpdateChatTopMessage will not be sent, so returned message should be used to update chat top message +-- @bot_user_id Identifier of the bot +-- @chat_id Identifier of the chat +-- @parameter Hidden parameter sent to bot for deep linking (https://api.telegram.org/bots#deep-linking) +-- parameter=start|startgroup or custom as defined by bot creator +local function sendBotStartMessage(bot_user_id, chat_id, parameter, dl_cb, cmd) + tdcli_function ({ + ID = "SendBotStartMessage", + bot_user_id_ = bot_user_id, + chat_id_ = chat_id, + parameter_ = parameter + }, dl_cb, cmd) +end + +M.sendBotStartMessage = sendBotStartMessage + +-- Sends result of the inline query as a message. +-- Returns sent message. +-- UpdateChatTopMessage will not be sent, so returned message should be used to update chat top message. +-- Always clears chat draft message +-- @chat_id Chat to send message +-- @reply_to_message_id Identifier of a message to reply to or 0 +-- @disable_notification Pass true, to disable notification about the message, doesn't works in secret chats +-- @from_background Pass true, if the message is sent from background +-- @query_id Identifier of the inline query +-- @result_id Identifier of the inline result +local function sendInlineQueryResultMessage(chat_id, reply_to_message_id, disable_notification, from_background, query_id, result_id, dl_cb, cmd) + tdcli_function ({ + ID = "SendInlineQueryResultMessage", + chat_id_ = chat_id, + reply_to_message_id_ = reply_to_message_id, + disable_notification_ = disable_notification, + from_background_ = from_background, + query_id_ = query_id, + result_id_ = result_id + }, dl_cb, cmd) +end + +M.sendInlineQueryResultMessage = sendInlineQueryResultMessage + +-- Forwards previously sent messages. +-- Returns forwarded messages in the same order as message identifiers passed in message_ids. +-- If message can't be forwarded, null will be returned instead of the message. +-- UpdateChatTopMessage will not be sent, so returned messages should be used to update chat top message +-- @chat_id Identifier of a chat to forward messages +-- @from_chat_id Identifier of a chat to forward from +-- @message_ids Identifiers of messages to forward +-- @disable_notification Pass true, to disable notification about the message, doesn't works if messages are forwarded to secret chat +-- @from_background Pass true, if the message is sent from background +local function forwardMessages(chat_id, from_chat_id, message_ids, disable_notification, dl_cb, cmd) + tdcli_function ({ + ID = "ForwardMessages", + chat_id_ = chat_id, + from_chat_id_ = from_chat_id, + message_ids_ = message_ids, -- vector + disable_notification_ = disable_notification, + from_background_ = 1 + }, dl_cb, cmd) +end + +M.forwardMessages = forwardMessages + +-- Changes current ttl setting in a secret chat and sends corresponding message +-- @chat_id Chat identifier +-- @ttl New value of ttl in seconds +local function sendChatSetTtlMessage(chat_id, ttl, dl_cb, cmd) + tdcli_function ({ + ID = "SendChatSetTtlMessage", + chat_id_ = chat_id, + ttl_ = ttl + }, dl_cb, cmd) +end + +M.sendChatSetTtlMessage = sendChatSetTtlMessage + +-- Deletes messages. +-- UpdateDeleteMessages will not be sent for messages deleted through that function +-- @chat_id Chat identifier +-- @message_ids Identifiers of messages to delete +local function deleteMessages(chat_id, message_ids, dl_cb, cmd) + tdcli_function ({ + ID = "DeleteMessages", + chat_id_ = chat_id, + message_ids_ = message_ids -- vector + }, dl_cb, cmd) +end + +M.deleteMessages = deleteMessages + +-- Deletes all messages in the chat sent by the specified user. +-- Works only in supergroup channel chats, needs appropriate privileges +-- @chat_id Chat identifier +-- @user_id User identifier +local function deleteMessagesFromUser(chat_id, user_id, dl_cb, cmd) + tdcli_function ({ + ID = "DeleteMessagesFromUser", + chat_id_ = chat_id, + user_id_ = user_id + }, dl_cb, cmd) +end + +M.deleteMessagesFromUser = deleteMessagesFromUser + +-- Edits text of text or game message. +-- Non-bots can edit message in a limited period of time. +-- Returns edited message after edit is complete server side +-- @chat_id Chat the message belongs to +-- @message_id Identifier of the message +-- @reply_markup Bots only. New message reply markup +-- @input_message_content New text content of the message. Should be of type InputMessageText +local function editMessageText(chat_id, message_id, reply_markup, text, disable_web_page_preview, parse_mode, dl_cb, cmd) + local TextParseMode = getParseMode(parse_mode) + + tdcli_function ({ + ID = "EditMessageText", + chat_id_ = chat_id, + message_id_ = message_id, + reply_markup_ = reply_markup, -- reply_markup:ReplyMarkup + input_message_content_ = { + ID = "InputMessageText", + text_ = text, + disable_web_page_preview_ = disable_web_page_preview, + clear_draft_ = 0, + entities_ = {}, + parse_mode_ = TextParseMode, + }, + }, dl_cb, cmd) +end + +M.editMessageText = editMessageText + +-- Edits message content caption. +-- Non-bots can edit message in a limited period of time. +-- Returns edited message after edit is complete server side +-- @chat_id Chat the message belongs to +-- @message_id Identifier of the message +-- @reply_markup Bots only. New message reply markup +-- @caption New message content caption, 0-200 characters +local function editMessageCaption(chat_id, message_id, reply_markup, caption, dl_cb, cmd) + tdcli_function ({ + ID = "EditMessageCaption", + chat_id_ = chat_id, + message_id_ = message_id, + reply_markup_ = reply_markup, -- reply_markup:ReplyMarkup + caption_ = caption + }, dl_cb, cmd) +end + +M.editMessageCaption = editMessageCaption + +-- Bots only. +-- Edits message reply markup. +-- Returns edited message after edit is complete server side +-- @chat_id Chat the message belongs to +-- @message_id Identifier of the message +-- @reply_markup New message reply markup +local function editMessageReplyMarkup(inline_message_id, reply_markup, caption, dl_cb, cmd) + tdcli_function ({ + ID = "EditInlineMessageCaption", + inline_message_id_ = inline_message_id, + reply_markup_ = reply_markup, -- reply_markup:ReplyMarkup + caption_ = caption + }, dl_cb, cmd) +end + +M.editMessageReplyMarkup = editMessageReplyMarkup + +-- Bots only. +-- Edits text of an inline text or game message sent via bot +-- @inline_message_id Inline message identifier +-- @reply_markup New message reply markup +-- @input_message_content New text content of the message. Should be of type InputMessageText +local function editInlineMessageText(inline_message_id, reply_markup, text, disable_web_page_preview, dl_cb, cmd) + tdcli_function ({ + ID = "EditInlineMessageText", + inline_message_id_ = inline_message_id, + reply_markup_ = reply_markup, -- reply_markup:ReplyMarkup + input_message_content_ = { + ID = "InputMessageText", + text_ = text, + disable_web_page_preview_ = disable_web_page_preview, + clear_draft_ = 0, + entities_ = {} + }, + }, dl_cb, cmd) +end + +M.editInlineMessageText = editInlineMessageText + +-- Bots only. +-- Edits caption of an inline message content sent via bot +-- @inline_message_id Inline message identifier +-- @reply_markup New message reply markup +-- @caption New message content caption, 0-200 characters +local function editInlineMessageCaption(inline_message_id, reply_markup, caption, dl_cb, cmd) + tdcli_function ({ + ID = "EditInlineMessageCaption", + inline_message_id_ = inline_message_id, + reply_markup_ = reply_markup, -- reply_markup:ReplyMarkup + caption_ = caption + }, dl_cb, cmd) +end + +M.editInlineMessageCaption = editInlineMessageCaption + +-- Bots only. +-- Edits reply markup of an inline message sent via bot +-- @inline_message_id Inline message identifier +-- @reply_markup New message reply markup +local function editInlineMessageReplyMarkup(inline_message_id, reply_markup, dl_cb, cmd) + tdcli_function ({ + ID = "EditInlineMessageReplyMarkup", + inline_message_id_ = inline_message_id, + reply_markup_ = reply_markup -- reply_markup:ReplyMarkup + }, dl_cb, cmd) +end + +M.editInlineMessageReplyMarkup = editInlineMessageReplyMarkup + + +-- Sends inline query to a bot and returns its results. +-- Unavailable for bots +-- @bot_user_id Identifier of the bot send query to +-- @chat_id Identifier of the chat, where the query is sent +-- @user_location User location, only if needed +-- @query Text of the query +-- @offset Offset of the first entry to return +local function getInlineQueryResults(bot_user_id, chat_id, latitude, longitude, query, offset, dl_cb, cmd) + tdcli_function ({ + ID = "GetInlineQueryResults", + bot_user_id_ = bot_user_id, + chat_id_ = chat_id, + user_location_ = { + ID = "Location", + latitude_ = latitude, + longitude_ = longitude + }, + query_ = query, + offset_ = offset + }, dl_cb, cmd) +end + +M.getInlineQueryResults = getInlineQueryResults + +-- Bots only. +-- Sets result of the inline query +-- @inline_query_id Identifier of the inline query +-- @is_personal Does result of the query can be cached only for specified user +-- @results Results of the query +-- @cache_time Allowed time to cache results of the query in seconds +-- @next_offset Offset for the next inline query, pass empty string if there is no more results +-- @switch_pm_text If non-empty, this text should be shown on the button, which opens private chat with the bot and sends bot start message with parameter switch_pm_parameter +-- @switch_pm_parameter Parameter for the bot start message +local function answerInlineQuery(inline_query_id, is_personal, cache_time, next_offset, switch_pm_text, switch_pm_parameter, dl_cb, cmd) + tdcli_function ({ + ID = "AnswerInlineQuery", + inline_query_id_ = inline_query_id, + is_personal_ = is_personal, + results_ = results, --vector<InputInlineQueryResult>, + cache_time_ = cache_time, + next_offset_ = next_offset, + switch_pm_text_ = switch_pm_text, + switch_pm_parameter_ = switch_pm_parameter + }, dl_cb, cmd) +end + +M.answerInlineQuery = answerInlineQuery + +-- Sends callback query to a bot and returns answer to it. +-- Unavailable for bots +-- @chat_id Identifier of the chat with a message +-- @message_id Identifier of the message, from which the query is originated +-- @payload Query payload +-- @text Text of the answer +-- @show_alert If true, an alert should be shown to the user instead of a toast +-- @url URL to be open +local function getCallbackQueryAnswer(chat_id, message_id, text, show_alert, url, dl_cb, cmd) + tdcli_function ({ + ID = "GetCallbackQueryAnswer", + chat_id_ = chat_id, + message_id_ = message_id, + payload_ = { + ID = "CallbackQueryAnswer", + text_ = text, + show_alert_ = show_alert, + url_ = url + }, + }, dl_cb, cmd) +end + +M.getCallbackQueryAnswer = getCallbackQueryAnswer + +-- Bots only. +-- Sets result of the callback query +-- @callback_query_id Identifier of the callback query +-- @text Text of the answer +-- @show_alert If true, an alert should be shown to the user instead of a toast +-- @url Url to be opened +-- @cache_time Allowed time to cache result of the query in seconds +local function answerCallbackQuery(callback_query_id, text, show_alert, url, cache_time, dl_cb, cmd) + tdcli_function ({ + ID = "AnswerCallbackQuery", + callback_query_id_ = callback_query_id, + text_ = text, + show_alert_ = show_alert, + url_ = url, + cache_time_ = cache_time + }, dl_cb, cmd) +end + +M.answerCallbackQuery = answerCallbackQuery + +-- Bots only. +-- Updates game score of the specified user in the game +-- @chat_id Chat a message with the game belongs to +-- @message_id Identifier of the message +-- @edit_message True, if message should be edited +-- @user_id User identifier +-- @score New score +-- @force Pass True to update the score even if it decreases. If score is 0, user will be deleted from the high scores table +local function setGameScore(chat_id, message_id, edit_message, user_id, score, force, dl_cb, cmd) + tdcli_function ({ + ID = "SetGameScore", + chat_id_ = chat_id, + message_id_ = message_id, + edit_message_ = edit_message, + user_id_ = user_id, + score_ = score, + force_ = force + }, dl_cb, cmd) +end + +M.setGameScore = setGameScore + +-- Bots only. +-- Updates game score of the specified user in the game +-- @inline_message_id Inline message identifier +-- @edit_message True, if message should be edited +-- @user_id User identifier +-- @score New score +-- @force Pass True to update the score even if it decreases. If score is 0, user will be deleted from the high scores table +local function setInlineGameScore(inline_message_id, edit_message, user_id, score, force, dl_cb, cmd) + tdcli_function ({ + ID = "SetInlineGameScore", + inline_message_id_ = inline_message_id, + edit_message_ = edit_message, + user_id_ = user_id, + score_ = score, + force_ = force + }, dl_cb, cmd) +end + +M.setInlineGameScore = setInlineGameScore + +-- Bots only. +-- Returns game high scores and some part of the score table around of the specified user in the game +-- @chat_id Chat a message with the game belongs to +-- @message_id Identifier of the message +-- @user_id User identifie +local function getGameHighScores(chat_id, message_id, user_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetGameHighScores", + chat_id_ = chat_id, + message_id_ = message_id, + user_id_ = user_id + }, dl_cb, cmd) +end + +M.getGameHighScores = getGameHighScores + +-- Bots only. +-- Returns game high scores and some part of the score table around of the specified user in the game +-- @inline_message_id Inline message identifier +-- @user_id User identifier +local function getInlineGameHighScores(inline_message_id, user_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetInlineGameHighScores", + inline_message_id_ = inline_message_id, + user_id_ = user_id + }, dl_cb, cmd) +end + +M.getInlineGameHighScores = getInlineGameHighScores + +-- Deletes default reply markup from chat. +-- This method needs to be called after one-time keyboard or ForceReply reply markup has been used. +-- UpdateChatReplyMarkup will be send if reply markup will be changed +-- @chat_id Chat identifier +-- @message_id Message identifier of used keyboard +local function deleteChatReplyMarkup(chat_id, message_id, dl_cb, cmd) + tdcli_function ({ + ID = "DeleteChatReplyMarkup", + chat_id_ = chat_id, + message_id_ = message_id + }, dl_cb, cmd) +end + +M.deleteChatReplyMarkup = deleteChatReplyMarkup + +-- Sends notification about user activity in a chat +-- @chat_id Chat identifier +-- @action Action description +-- action = Typing|Cancel|RecordVideo|UploadVideo|RecordVoice|UploadVoice|UploadPhoto|UploadDocument|GeoLocation|ChooseContact|StartPlayGame +local function sendChatAction(chat_id, action, progress, dl_cb, cmd) + tdcli_function ({ + ID = "SendChatAction", + chat_id_ = chat_id, + action_ = { + ID = "SendMessage" .. action .. "Action", + progress_ = progress or 100 + } + }, dl_cb, cmd) +end + +M.sendChatAction = sendChatAction + +-- Sends notification about screenshot taken in a chat. +-- Works only in secret chats +-- @chat_id Chat identifier +local function sendChatScreenshotTakenNotification(chat_id, dl_cb, cmd) + tdcli_function ({ + ID = "SendChatScreenshotTakenNotification", + chat_id_ = chat_id + }, dl_cb, cmd) +end + +M.sendChatScreenshotTakenNotification = sendChatScreenshotTakenNotification + +-- Chat is opened by the user. +-- Many useful activities depends on chat being opened or closed. For example, in channels all updates are received only for opened chats +-- @chat_id Chat identifier +local function openChat(chat_id, dl_cb, cmd) + tdcli_function ({ + ID = "OpenChat", + chat_id_ = chat_id + }, dl_cb, cmd) +end + +M.openChat = openChat + +-- Chat is closed by the user. +-- Many useful activities depends on chat being opened or closed. +-- @chat_id Chat identifier +local function closeChat(chat_id, dl_cb, cmd) + tdcli_function ({ + ID = "CloseChat", + chat_id_ = chat_id + }, dl_cb, cmd) +end + +M.closeChat = closeChat + +-- Messages are viewed by the user. +-- Many useful activities depends on message being viewed. For example, marking messages as read, incrementing of view counter, updating of view counter, removing of deleted messages in channels +-- @chat_id Chat identifier +-- @message_ids Identifiers of viewed messages +local function viewMessages(chat_id, message_ids, dl_cb, cmd) + tdcli_function ({ + ID = "ViewMessages", + chat_id_ = chat_id, + message_ids_ = message_ids -- vector + }, dl_cb, cmd) +end + +M.viewMessages = viewMessages + +-- Message content is opened, for example the user has opened a photo, a video, a document, a location or a venue or have listened to an audio or a voice message +-- @chat_id Chat identifier of the message +-- @message_id Identifier of the message with opened content +local function openMessageContent(chat_id, message_id, dl_cb, cmd) + tdcli_function ({ + ID = "OpenMessageContent", + chat_id_ = chat_id, + message_id_ = message_id + }, dl_cb, cmd) +end + +M.openMessageContent = openMessageContent + +-- Returns existing chat corresponding to the given user +-- @user_id User identifier +local function createPrivateChat(user_id, dl_cb, cmd) + tdcli_function ({ + ID = "CreatePrivateChat", + user_id_ = user_id + }, dl_cb, cmd) +end + +M.createPrivateChat = createPrivateChat + +-- Returns existing chat corresponding to the known group +-- @group_id Group identifier +local function createGroupChat(group_id, dl_cb, cmd) + tdcli_function ({ + ID = "CreateGroupChat", + group_id_ = getChatId(group_id).ID + }, dl_cb, cmd) +end + +M.createGroupChat = createGroupChat + +-- Returns existing chat corresponding to the known channel +-- @channel_id Channel identifier +local function createChannelChat(channel_id, dl_cb, cmd) + tdcli_function ({ + ID = "CreateChannelChat", + channel_id_ = getChatId(channel_id).ID + }, dl_cb, cmd) +end + +M.createChannelChat = createChannelChat + +-- Returns existing chat corresponding to the known secret chat +-- @secret_chat_id SecretChat identifier +local function createSecretChat(secret_chat_id, dl_cb, cmd) + tdcli_function ({ + ID = "CreateSecretChat", + secret_chat_id_ = secret_chat_id + }, dl_cb, cmd) +end + +M.createSecretChat = createSecretChat + +-- Creates new group chat and send corresponding messageGroupChatCreate, returns created chat +-- @user_ids Identifiers of users to add to the group +-- @title Title of new group chat, 0-255 characters +local function createNewGroupChat(user_ids, title, dl_cb, cmd) + tdcli_function ({ + ID = "CreateNewGroupChat", + user_ids_ = user_ids, -- vector + title_ = title + }, dl_cb, cmd) +end + +M.createNewGroupChat = createNewGroupChat + +-- Creates new channel chat and send corresponding messageChannelChatCreate, returns created chat +-- @title Title of new channel chat, 0-255 characters +-- @is_supergroup True, if supergroup chat should be created +-- @about Information about the channel, 0-255 characters +local function createNewChannelChat(title, is_supergroup, about, dl_cb, cmd) + tdcli_function ({ + ID = "CreateNewChannelChat", + title_ = title, + is_supergroup_ = is_supergroup, + about_ = about + }, dl_cb, cmd) +end + +M.createNewChannelChat = createNewChannelChat + +-- Creates new secret chat, returns created chat +-- @user_id Identifier of a user to create secret chat with +local function createNewSecretChat(user_id, dl_cb, cmd) + tdcli_function ({ + ID = "CreateNewSecretChat", + user_id_ = user_id + }, dl_cb, cmd) +end + +M.createNewSecretChat = createNewSecretChat + +-- Creates new channel supergroup chat from existing group chat and send corresponding messageChatMigrateTo and messageChatMigrateFrom. Deactivates group +-- @chat_id Group chat identifier +local function migrateGroupChatToChannelChat(chat_id, dl_cb, cmd) + tdcli_function ({ + ID = "MigrateGroupChatToChannelChat", + chat_id_ = chat_id + }, dl_cb, cmd) +end + +M.migrateGroupChatToChannelChat = migrateGroupChatToChannelChat + +-- Changes chat title. +-- Title can't be changed for private chats. +-- Title will not change until change will be synchronized with the server. +-- Title will not be changed if application is killed before it can send request to the server. +-- There will be update about change of the title on success. Otherwise error will be returned +-- @chat_id Chat identifier +-- @title New title of a chat, 0-255 characters +local function changeChatTitle(chat_id, title, dl_cb, cmd) + tdcli_function ({ + ID = "ChangeChatTitle", + chat_id_ = chat_id, + title_ = title + }, dl_cb, cmd) +end + +M.changeChatTitle = changeChatTitle + +-- Changes chat photo. +-- Photo can't be changed for private chats. +-- Photo will not change until change will be synchronized with the server. +-- Photo will not be changed if application is killed before it can send request to the server. +-- There will be update about change of the photo on success. Otherwise error will be returned +-- @chat_id Chat identifier +-- @photo New chat photo. You can use zero InputFileId to delete photo. Files accessible only by HTTP URL are not acceptable +local function changeChatPhoto(chat_id, photo, dl_cb, cmd) + tdcli_function ({ + ID = "ChangeChatPhoto", + chat_id_ = chat_id, + photo_ = getInputFile(photo) + }, dl_cb, cmd) +end + +M.changeChatPhoto = changeChatPhoto + +-- Changes chat draft message +-- @chat_id Chat identifier +-- @draft_message New draft message, nullable +local function changeChatDraftMessage(chat_id, reply_to_message_id, text, disable_web_page_preview, clear_draft, parse_mode, dl_cb, cmd) + local TextParseMode = getParseMode(parse_mode) + + tdcli_function ({ + ID = "ChangeChatDraftMessage", + chat_id_ = chat_id, + draft_message_ = { + ID = "DraftMessage", + reply_to_message_id_ = reply_to_message_id, + input_message_text_ = { + ID = "InputMessageText", + text_ = text, + disable_web_page_preview_ = disable_web_page_preview, + clear_draft_ = clear_draft, + entities_ = {}, + parse_mode_ = TextParseMode, + }, + }, + }, dl_cb, cmd) +end + +M.changeChatDraftMessage = changeChatDraftMessage + +-- Adds new member to chat. +-- Members can't be added to private or secret chats. +-- Member will not be added until chat state will be synchronized with the server. +-- Member will not be added if application is killed before it can send request to the server +-- @chat_id Chat identifier +-- @user_id Identifier of the user to add +-- @forward_limit Number of previous messages from chat to forward to new member, ignored for channel chats +local function addChatMember(chat_id, user_id, forward_limit, dl_cb, cmd) + tdcli_function ({ + ID = "AddChatMember", + chat_id_ = chat_id, + user_id_ = user_id, + forward_limit_ = forward_limit or 50 + }, dl_cb, cmd) +end + +M.addChatMember = addChatMember + +-- Adds many new members to the chat. +-- Currently, available only for channels. +-- Can't be used to join the channel. +-- Member will not be added until chat state will be synchronized with the server. +-- Member will not be added if application is killed before it can send request to the server +-- @chat_id Chat identifier +-- @user_ids Identifiers of the users to add +local function addChatMembers(chat_id, user_ids, dl_cb, cmd) + tdcli_function ({ + ID = "AddChatMembers", + chat_id_ = chat_id, + user_ids_ = user_ids -- vector + }, dl_cb, cmd) +end + +M.addChatMembers = addChatMembers + +-- Changes status of the chat member, need appropriate privileges. +-- In channel chats, user will be added to chat members if he is yet not a member and there is less than 200 members in the channel. +-- Status will not be changed until chat state will be synchronized with the server. +-- Status will not be changed if application is killed before it can send request to the server +-- @chat_id Chat identifier +-- @user_id Identifier of the user to edit status, bots can be editors in the channel chats +-- @status New status of the member in the chat +-- status = Creator|Editor|Moderator|Member|Left|Kicked +local function changeChatMemberStatus(chat_id, user_id, status, dl_cb, cmd) + tdcli_function ({ + ID = "ChangeChatMemberStatus", + chat_id_ = chat_id, + user_id_ = user_id, + status_ = { + ID = "ChatMemberStatus" .. status + }, + }, dl_cb, cmd) +end + +M.changeChatMemberStatus = changeChatMemberStatus + +-- Returns information about one participant of the chat +-- @chat_id Chat identifier +-- @user_id User identifier +local function getChatMember(chat_id, user_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetChatMember", + chat_id_ = chat_id, + user_id_ = user_id + }, dl_cb, cmd) +end + +M.getChatMember = getChatMember + +-- Asynchronously downloads file from cloud. +-- Updates updateFileProgress will notify about download progress. +-- Update updateFile will notify about successful download +-- @file_id Identifier of file to download +local function downloadFile(file_id, dl_cb, cmd) + tdcli_function ({ + ID = "DownloadFile", + file_id_ = file_id + }, dl_cb, cmd) +end + +M.downloadFile = downloadFile + +-- Stops file downloading. +-- If file already downloaded do nothing. +-- @file_id Identifier of file to cancel download +local function cancelDownloadFile(file_id, dl_cb, cmd) + tdcli_function ({ + ID = "CancelDownloadFile", + file_id_ = file_id + }, dl_cb, cmd) +end + +M.cancelDownloadFile = cancelDownloadFile + +-- Next part of a file was generated +-- @generation_id Identifier of the generation process +-- @ready Number of bytes already generated. Negative number means that generation has failed and should be terminated +local function setFileGenerationProgress(generation_id, ready, dl_cb, cmd) + tdcli_function ({ + ID = "SetFileGenerationProgress", + generation_id_ = generation_id, + ready_ = ready + }, dl_cb, cmd) +end + +M.setFileGenerationProgress = setFileGenerationProgress + +-- Finishes file generation +-- @generation_id Identifier of the generation process +local function finishFileGeneration(generation_id, dl_cb, cmd) + tdcli_function ({ + ID = "FinishFileGeneration", + generation_id_ = generation_id + }, dl_cb, cmd) +end + +M.finishFileGeneration = finishFileGeneration + +-- Generates new chat invite link, previously generated link is revoked. +-- Available for group and channel chats. +-- Only creator of the chat can export chat invite link +-- @chat_id Chat identifier +local function exportChatInviteLink(chat_id, dl_cb, cmd) + tdcli_function ({ + ID = "ExportChatInviteLink", + chat_id_ = chat_id + }, dl_cb, cmd) +end + +M.exportChatInviteLink = exportChatInviteLink + +-- Checks chat invite link for validness and returns information about the corresponding chat +-- @invite_link Invite link to check. Should begin with "https://telegram.me/joinchat/" +local function checkChatInviteLink(link, dl_cb, cmd) + tdcli_function ({ + ID = "CheckChatInviteLink", + invite_link_ = link + }, dl_cb, cmd) +end + +M.checkChatInviteLink = checkChatInviteLink + +-- Imports chat invite link, adds current user to a chat if possible. +-- Member will not be added until chat state will be synchronized with the server. +-- Member will not be added if application is killed before it can send request to the server +-- @invite_link Invite link to import. Should begin with "https://telegram.me/joinchat/" +local function importChatInviteLink(invite_link, dl_cb, cmd) + tdcli_function ({ + ID = "ImportChatInviteLink", + invite_link_ = invite_link + }, dl_cb, cmd) +end + +M.importChatInviteLink = importChatInviteLink + +-- Adds user to black list +-- @user_id User identifier +local function blockUser(user_id, dl_cb, cmd) + tdcli_function ({ + ID = "BlockUser", + user_id_ = user_id + }, dl_cb, cmd) +end + +M.blockUser = blockUser + +-- Removes user from black list +-- @user_id User identifier +local function unblockUser(user_id, dl_cb, cmd) + tdcli_function ({ + ID = "UnblockUser", + user_id_ = user_id + }, dl_cb, cmd) +end + +M.unblockUser = unblockUser + +-- Returns users blocked by the current user +-- @offset Number of users to skip in result, must be non-negative +-- @limit Maximum number of users to return, can't be greater than 100 +local function getBlockedUsers(offset, limit, dl_cb, cmd) + tdcli_function ({ + ID = "GetBlockedUsers", + offset_ = offset, + limit_ = limit + }, dl_cb, cmd) +end + +M.getBlockedUsers = getBlockedUsers + +-- Adds new contacts/edits existing contacts, contacts user identifiers are ignored. +-- Returns list of corresponding users in the same order as input contacts. +-- If contact doesn't registered in Telegram, user with id == 0 will be returned +-- @contacts List of contacts to import/edit +local function importContacts(phone_number, first_name, last_name, user_id, dl_cb, cmd) + tdcli_function ({ + ID = "ImportContacts", + contacts_ = {[0] = { + phone_number_ = tostring(phone_number), + first_name_ = tostring(first_name), + last_name_ = tostring(last_name), + user_id_ = user_id + }, + }, + }, dl_cb, cmd) +end + +M.importContacts = importContacts + +-- Searches for specified query in the first name, last name and username of the known user contacts +-- @query Query to search for, can be empty to return all contacts +-- @limit Maximum number of users to be returned +local function searchContacts(query, limit, dl_cb, cmd) + tdcli_function ({ + ID = "SearchContacts", + query_ = query, + limit_ = limit + }, dl_cb, cmd) +end + +M.searchContacts = searchContacts + +-- Deletes users from contacts list +-- @user_ids Identifiers of users to be deleted +local function deleteContacts(user_ids, dl_cb, cmd) + tdcli_function ({ + ID = "DeleteContacts", + user_ids_ = user_ids -- vector + }, dl_cb, cmd) +end + +M.deleteContacts = deleteContacts + +-- Returns profile photos of the user. +-- Result of this query can't be invalidated, so it must be used with care +-- @user_id User identifier +-- @offset Photos to skip, must be non-negative +-- @limit Maximum number of photos to be returned, can't be greater than 100 +local function getUserProfilePhotos(user_id, offset, limit, dl_cb, cmd) + tdcli_function ({ + ID = "GetUserProfilePhotos", + user_id_ = user_id, + offset_ = offset, + limit_ = limit + }, dl_cb, cmd) +end + +M.getUserProfilePhotos = getUserProfilePhotos + +-- Returns stickers corresponding to given emoji +-- @emoji String representation of emoji. If empty, returns all known stickers +local function getStickers(emoji, dl_cb, cmd) + tdcli_function ({ + ID = "GetStickers", + emoji_ = emoji + }, dl_cb, cmd) +end + +M.getStickers = getStickers + +-- Returns list of installed sticker sets without archived sticker sets +-- @is_masks Pass true to return masks, pass false to return stickers +local function getStickerSets(is_masks, dl_cb, cmd) + tdcli_function ({ + ID = "GetStickerSets", + is_masks_ = is_masks + }, dl_cb, cmd) +end + +M.getStickerSets = getStickerSets + +-- Returns list of archived sticker sets +-- @is_masks Pass true to return masks, pass false to return stickers +-- @offset_sticker_set_id Identifier of the sticker set from which return the result +-- @limit Maximum number of sticker sets to return +local function getArchivedStickerSets(is_masks, offset_sticker_set_id, limit, dl_cb, cmd) + tdcli_function ({ + ID = "GetArchivedStickerSets", + is_masks_ = is_masks, + offset_sticker_set_id_ = offset_sticker_set_id, + limit_ = limit + }, dl_cb, cmd) +end + +M.getArchivedStickerSets = getArchivedStickerSets + +-- Returns list of trending sticker sets +local function getTrendingStickerSets(dl_cb, cmd) + tdcli_function ({ + ID = "GetTrendingStickerSets" + }, dl_cb, cmd) +end + +M.getTrendingStickerSets = getTrendingStickerSets + +-- Returns list of sticker sets attached to a file, currently only photos and videos can have attached sticker sets +-- @file_id File identifier +local function getAttachedStickerSets(file_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetAttachedStickerSets", + file_id_ = file_id + }, dl_cb, cmd) +end + +M.getAttachedStickerSets = getAttachedStickerSets + +-- Returns information about sticker set by its identifier +-- @set_id Identifier of the sticker set +local function getStickerSet(set_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetStickerSet", + set_id_ = set_id + }, dl_cb, cmd) +end + +M.getStickerSet = getStickerSet + +-- Searches sticker set by its short name +-- @name Name of the sticker set +local function searchStickerSet(name, dl_cb, cmd) + tdcli_function ({ + ID = "SearchStickerSet", + name_ = name + }, dl_cb, cmd) +end + +M.searchStickerSet = searchStickerSet + +-- Installs/uninstalls or enables/archives sticker set. +-- Official sticker set can't be uninstalled, but it can be archived +-- @set_id Identifier of the sticker set +-- @is_installed New value of is_installed +-- @is_archived New value of is_archived +local function updateStickerSet(set_id, is_installed, is_archived, dl_cb, cmd) + tdcli_function ({ + ID = "UpdateStickerSet", + set_id_ = set_id, + is_installed_ = is_installed, + is_archived_ = is_archived + }, dl_cb, cmd) +end + +M.updateStickerSet = updateStickerSet + +-- Trending sticker sets are viewed by the user +-- @sticker_set_ids Identifiers of viewed trending sticker sets +local function viewTrendingStickerSets(sticker_set_ids, dl_cb, cmd) + tdcli_function ({ + ID = "ViewTrendingStickerSets", + sticker_set_ids_ = sticker_set_ids -- vector + }, dl_cb, cmd) +end + +M.viewTrendingStickerSets = viewTrendingStickerSets + +-- Changes the order of installed sticker sets +-- @is_masks Pass true to change masks order, pass false to change stickers order +-- @sticker_set_ids Identifiers of installed sticker sets in the new right order +local function reorderStickerSets(is_masks, sticker_set_ids, dl_cb, cmd) + tdcli_function ({ + ID = "ReorderStickerSets", + is_masks_ = is_masks, + sticker_set_ids_ = sticker_set_ids -- vector + }, dl_cb, cmd) +end + +M.reorderStickerSets = reorderStickerSets + +-- Returns list of recently used stickers +-- @is_attached Pass true to return stickers and masks recently attached to photo or video files, pass false to return recently sent stickers +local function getRecentStickers(is_attached, dl_cb, cmd) + tdcli_function ({ + ID = "GetRecentStickers", + is_attached_ = is_attached + }, dl_cb, cmd) +end + +M.getRecentStickers = getRecentStickers + +-- Manually adds new sticker to the list of recently used stickers. +-- New sticker is added to the beginning of the list. +-- If the sticker is already in the list, at first it is removed from the list +-- @is_attached Pass true to add the sticker to the list of stickers recently attached to photo or video files, pass false to add the sticker to the list of recently sent stickers +-- @sticker Sticker file to add +local function addRecentSticker(is_attached, sticker, dl_cb, cmd) + tdcli_function ({ + ID = "AddRecentSticker", + is_attached_ = is_attached, + sticker_ = getInputFile(sticker) + }, dl_cb, cmd) +end + +M.addRecentSticker = addRecentSticker + +-- Removes a sticker from the list of recently used stickers +-- @is_attached Pass true to remove the sticker from the list of stickers recently attached to photo or video files, pass false to remove the sticker from the list of recently sent stickers +-- @sticker Sticker file to delete +local function deleteRecentSticker(is_attached, sticker, dl_cb, cmd) + tdcli_function ({ + ID = "DeleteRecentSticker", + is_attached_ = is_attached, + sticker_ = getInputFile(sticker) + }, dl_cb, cmd) +end + +M.deleteRecentSticker = deleteRecentSticker + +-- Clears list of recently used stickers +-- @is_attached Pass true to clear list of stickers recently attached to photo or video files, pass false to clear the list of recently sent stickers +local function clearRecentStickers(is_attached, dl_cb, cmd) + tdcli_function ({ + ID = "ClearRecentStickers", + is_attached_ = is_attached + }, dl_cb, cmd) +end + +M.clearRecentStickers = clearRecentStickers + +-- Returns emojis corresponding to a sticker +-- @sticker Sticker file identifier +local function getStickerEmojis(sticker, dl_cb, cmd) + tdcli_function ({ + ID = "GetStickerEmojis", + sticker_ = getInputFile(sticker) + }, dl_cb, cmd) +end + +M.getStickerEmojis = getStickerEmojis + +-- Returns saved animations +local function getSavedAnimations(dl_cb, cmd) + tdcli_function ({ + ID = "GetSavedAnimations", + }, dl_cb, cmd) +end + +M.getSavedAnimations = getSavedAnimations + +-- Manually adds new animation to the list of saved animations. +-- New animation is added to the beginning of the list. +-- If the animation is already in the list, at first it is removed from the list. +-- Only non-secret video animations with MIME type "video/mp4" can be added to the list +-- @animation Animation file to add. Only known to server animations (i. e. successfully sent via message) can be added to the list +local function addSavedAnimation(animation, dl_cb, cmd) + tdcli_function ({ + ID = "AddSavedAnimation", + animation_ = getInputFile(animation) + }, dl_cb, cmd) +end + +M.addSavedAnimation = addSavedAnimation + +-- Removes animation from the list of saved animations +-- @animation Animation file to delete +local function deleteSavedAnimation(animation, dl_cb, cmd) + tdcli_function ({ + ID = "DeleteSavedAnimation", + animation_ = getInputFile(animation) + }, dl_cb, cmd) +end + +M.deleteSavedAnimation = deleteSavedAnimation + +-- Returns up to 20 recently used inline bots in the order of the last usage +local function getRecentInlineBots(dl_cb, cmd) + tdcli_function ({ + ID = "GetRecentInlineBots", + }, dl_cb, cmd) +end + +M.getRecentInlineBots = getRecentInlineBots + +-- Get web page preview by text of the message. +-- Do not call this function to often +-- @message_text Message text +local function getWebPagePreview(message_text, dl_cb, cmd) + tdcli_function ({ + ID = "GetWebPagePreview", + message_text_ = message_text + }, dl_cb, cmd) +end + +M.getWebPagePreview = getWebPagePreview + +-- Returns notification settings for a given scope +-- @scope Scope to return information about notification settings +-- scope = Chat(chat_id)|PrivateChats|GroupChats|AllChats| +local function getNotificationSettings(scope, chat_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetNotificationSettings", + scope_ = { + ID = 'NotificationSettingsFor' .. scope, + chat_id_ = chat_id or nil + }, + }, dl_cb, cmd) +end + +M.getNotificationSettings = getNotificationSettings + +-- Changes notification settings for a given scope +-- @scope Scope to change notification settings +-- @notification_settings New notification settings for given scope +-- scope = Chat(chat_id)|PrivateChats|GroupChats|AllChats| +local function setNotificationSettings(scope, chat_id, mute_for, show_preview, dl_cb, cmd) + tdcli_function ({ + ID = "SetNotificationSettings", + scope_ = { + ID = 'NotificationSettingsFor' .. scope, + chat_id_ = chat_id or nil + }, + notification_settings_ = { + ID = "NotificationSettings", + mute_for_ = mute_for, + sound_ = "default", + show_preview_ = show_preview + } + }, dl_cb, cmd) +end + +M.setNotificationSettings = setNotificationSettings + +-- Resets all notification settings to the default value. +-- By default the only muted chats are supergroups, sound is set to 'default' and message previews are showed +local function resetAllNotificationSettings(dl_cb, cmd) + tdcli_function ({ + ID = "ResetAllNotificationSettings" + }, dl_cb, cmd) +end + +M.resetAllNotificationSettings = resetAllNotificationSettings + +-- Uploads new profile photo for logged in user. +-- Photo will not change until change will be synchronized with the server. +-- Photo will not be changed if application is killed before it can send request to the server. +-- If something changes, updateUser will be sent +-- @photo_path Path to new profile photo +local function setProfilePhoto(photo_path, dl_cb, cmd) + tdcli_function ({ + ID = "SetProfilePhoto", + photo_path_ = photo_path + }, dl_cb, cmd) +end + +M.setProfilePhoto = setProfilePhoto + +-- Deletes profile photo. +-- If something changes, updateUser will be sent +-- @profile_photo_id Identifier of profile photo to delete +local function deleteProfilePhoto(profile_photo_id, dl_cb, cmd) + tdcli_function ({ + ID = "DeleteProfilePhoto", + profile_photo_id_ = profile_photo_id + }, dl_cb, cmd) +end + +M.deleteProfilePhoto = deleteProfilePhoto + +-- Changes first and last names of logged in user. +-- If something changes, updateUser will be sent +-- @first_name New value of user first name, 1-255 characters +-- @last_name New value of optional user last name, 0-255 characters +local function changeName(first_name, last_name, dl_cb, cmd) + tdcli_function ({ + ID = "ChangeName", + first_name_ = first_name, + last_name_ = last_name + }, dl_cb, cmd) +end + +M.changeName = changeName + +-- Changes about information of logged in user +-- @about New value of userFull.about, 0-255 characters +local function changeAbout(about, dl_cb, cmd) + tdcli_function ({ + ID = "ChangeAbout", + about_ = about + }, dl_cb, cmd) +end + +M.changeAbout = changeAbout + +-- Changes username of logged in user. +-- If something changes, updateUser will be sent +-- @username New value of username. Use empty string to remove username +local function changeUsername(username, dl_cb, cmd) + tdcli_function ({ + ID = "ChangeUsername", + username_ = username + }, dl_cb, cmd) +end + +M.changeUsername = changeUsername + +-- Changes user's phone number and sends authentication code to the new user's phone number. +-- Returns authStateWaitCode with information about sent code on success +-- @phone_number New user's phone number in any reasonable format +-- @allow_flash_call Pass True, if code can be sent via flash call to the specified phone number +-- @is_current_phone_number Pass true, if the phone number is used on the current device. Ignored if allow_flash_call is False +local function changePhoneNumber(phone_number, allow_flash_call, is_current_phone_number, dl_cb, cmd) + tdcli_function ({ + ID = "ChangePhoneNumber", + phone_number_ = phone_number, + allow_flash_call_ = allow_flash_call, + is_current_phone_number_ = is_current_phone_number + }, dl_cb, cmd) +end + +M.changePhoneNumber = changePhoneNumber + +-- Resends authentication code sent to change user's phone number. +-- Works only if in previously received authStateWaitCode next_code_type was not null. +-- Returns authStateWaitCode on success +local function resendChangePhoneNumberCode(dl_cb, cmd) + tdcli_function ({ + ID = "ResendChangePhoneNumberCode", + }, dl_cb, cmd) +end + +M.resendChangePhoneNumberCode = resendChangePhoneNumberCode + +-- Checks authentication code sent to change user's phone number. +-- Returns authStateOk on success +-- @code Verification code from SMS, voice call or flash call +local function checkChangePhoneNumberCode(code, dl_cb, cmd) + tdcli_function ({ + ID = "CheckChangePhoneNumberCode", + code_ = code + }, dl_cb, cmd) +end + +M.checkChangePhoneNumberCode = checkChangePhoneNumberCode + +-- Returns all active sessions of logged in user +local function getActiveSessions(dl_cb, cmd) + tdcli_function ({ + ID = "GetActiveSessions", + }, dl_cb, cmd) +end + +M.getActiveSessions = getActiveSessions + +-- Terminates another session of logged in user +-- @session_id Session identifier +local function terminateSession(session_id, dl_cb, cmd) + tdcli_function ({ + ID = "TerminateSession", + session_id_ = session_id + }, dl_cb, cmd) +end + +M.terminateSession = terminateSession + +-- Terminates all other sessions of logged in user +local function terminateAllOtherSessions(dl_cb, cmd) + tdcli_function ({ + ID = "TerminateAllOtherSessions", + }, dl_cb, cmd) +end + +M.terminateAllOtherSessions = terminateAllOtherSessions + +-- Gives or revokes all members of the group editor rights. +-- Needs creator privileges in the group +-- @group_id Identifier of the group +-- @anyone_can_edit New value of anyone_can_edit +local function toggleGroupEditors(group_id, anyone_can_edit, dl_cb, cmd) + tdcli_function ({ + ID = "ToggleGroupEditors", + group_id_ = getChatId(group_id).ID, + anyone_can_edit_ = anyone_can_edit + }, dl_cb, cmd) +end + +M.toggleGroupEditors = toggleGroupEditors + +-- Changes username of the channel. +-- Needs creator privileges in the channel +-- @channel_id Identifier of the channel +-- @username New value of username. Use empty string to remove username +local function changeChannelUsername(channel_id, username, dl_cb, cmd) + tdcli_function ({ + ID = "ChangeChannelUsername", + channel_id_ = getChatId(channel_id).ID, + username_ = username + }, dl_cb, cmd) +end + +M.changeChannelUsername = changeChannelUsername + +-- Gives or revokes right to invite new members to all current members of the channel. +-- Needs creator privileges in the channel. +-- Available only for supergroups +-- @channel_id Identifier of the channel +-- @anyone_can_invite New value of anyone_can_invite +local function toggleChannelInvites(channel_id, anyone_can_invite, dl_cb, cmd) + tdcli_function ({ + ID = "ToggleChannelInvites", + channel_id_ = getChatId(channel_id).ID, + anyone_can_invite_ = anyone_can_invite + }, dl_cb, cmd) +end + +M.toggleChannelInvites = toggleChannelInvites + +-- Enables or disables sender signature on sent messages in the channel. +-- Needs creator privileges in the channel. +-- Not available for supergroups +-- @channel_id Identifier of the channel +-- @sign_messages New value of sign_messages +local function toggleChannelSignMessages(channel_id, sign_messages, dl_cb, cmd) + tdcli_function ({ + ID = "ToggleChannelSignMessages", + channel_id_ = getChatId(channel_id).ID, + sign_messages_ = sign_messages + }, dl_cb, cmd) +end + +M.toggleChannelSignMessages = toggleChannelSignMessages + +-- Changes information about the channel. +-- Needs creator privileges in the broadcast channel or editor privileges in the supergroup channel +-- @channel_id Identifier of the channel +-- @about New value of about, 0-255 characters +local function changeChannelAbout(channel_id, about, dl_cb, cmd) + tdcli_function ({ + ID = "ChangeChannelAbout", + channel_id_ = getChatId(channel_id).ID, + about_ = about + }, dl_cb, cmd) +end + +M.changeChannelAbout = changeChannelAbout + +-- Pins a message in a supergroup channel chat. +-- Needs editor privileges in the channel +-- @channel_id Identifier of the channel +-- @message_id Identifier of the new pinned message +-- @disable_notification True, if there should be no notification about the pinned message +local function pinChannelMessage(channel_id, message_id, disable_notification, dl_cb, cmd) + tdcli_function ({ + ID = "PinChannelMessage", + channel_id_ = getChatId(channel_id).ID, + message_id_ = message_id, + disable_notification_ = disable_notification + }, dl_cb, cmd) +end + +M.pinChannelMessage = pinChannelMessage + +-- Removes pinned message in the supergroup channel. +-- Needs editor privileges in the channel +-- @channel_id Identifier of the channel +local function unpinChannelMessage(channel_id, dl_cb, cmd) + tdcli_function ({ + ID = "UnpinChannelMessage", + channel_id_ = getChatId(channel_id).ID + }, dl_cb, cmd) +end + +M.unpinChannelMessage = unpinChannelMessage + +-- Reports some supergroup channel messages from a user as spam messages +-- @channel_id Channel identifier +-- @user_id User identifier +-- @message_ids Identifiers of messages sent in the supergroup by the user, the list should be non-empty +local function reportChannelSpam(channel_id, user_id, message_ids, dl_cb, cmd) + tdcli_function ({ + ID = "ReportChannelSpam", + channel_id_ = getChatId(channel_id).ID, + user_id_ = user_id, + message_ids_ = message_ids -- vector + }, dl_cb, cmd) +end + +M.reportChannelSpam = reportChannelSpam + +-- Returns information about channel members or kicked from channel users. +-- Can be used only if channel_full->can_get_members == true +-- @channel_id Identifier of the channel +-- @filter Kind of channel users to return, defaults to channelMembersRecent +-- @offset Number of channel users to skip +-- @limit Maximum number of users be returned, can't be greater than 200 +-- filter = Recent|Administrators|Kicked|Bots +local function getChannelMembers(channel_id, offset, filter, limit, dl_cb, cmd) + if not limit or limit > 200 then + limit = 200 + end + + tdcli_function ({ + ID = "GetChannelMembers", + channel_id_ = getChatId(channel_id).ID, + filter_ = { + ID = "ChannelMembers" .. filter + }, + offset_ = offset, + limit_ = limit + }, dl_cb, cmd) +end + +M.getChannelMembers = getChannelMembers + +-- Deletes channel along with all messages in corresponding chat. +-- Releases channel username and removes all members. +-- Needs creator privileges in the channel. +-- Channels with more than 1000 members can't be deleted +-- @channel_id Identifier of the channel +local function deleteChannel(channel_id, dl_cb, cmd) + tdcli_function ({ + ID = "DeleteChannel", + channel_id_ = getChatId(channel_id).ID + }, dl_cb, cmd) +end + +M.deleteChannel = deleteChannel + +-- Returns list of created public channels +local function getCreatedPublicChannels(dl_cb, cmd) + tdcli_function ({ + ID = "GetCreatedPublicChannels" + }, dl_cb, cmd) +end + +M.getCreatedPublicChannels = getCreatedPublicChannels + +-- Closes secret chat +-- @secret_chat_id Secret chat identifier +local function closeSecretChat(secret_chat_id, dl_cb, cmd) + tdcli_function ({ + ID = "CloseSecretChat", + secret_chat_id_ = secret_chat_id + }, dl_cb, cmd) +end + +M.closeSecretChat = closeSecretChat + +-- Returns user that can be contacted to get support +local function getSupportUser(dl_cb, cmd) + tdcli_function ({ + ID = "GetSupportUser", + }, dl_cb, cmd) +end + +M.getSupportUser = getSupportUser + +-- Returns background wallpapers +local function getWallpapers(dl_cb, cmd) + tdcli_function ({ + ID = "GetWallpapers", + }, dl_cb, cmd) +end + +M.getWallpapers = getWallpapers + +-- Registers current used device for receiving push notifications +-- @device_token Device token +-- device_token = apns|gcm|mpns|simplePush|ubuntuPhone|blackberry +local function registerDevice(device_token, token, device_token_set, dl_cb, cmd) + local dToken = {ID = device_token .. 'DeviceToken', token_ = token} + + if device_token_set then + dToken = {ID = "DeviceTokenSet", token_ = device_token_set} -- tokens:vector<DeviceToken> + end + + tdcli_function ({ + ID = "RegisterDevice", + device_token_ = dToken + }, dl_cb, cmd) +end + +M.registerDevice = registerDevice + +-- Returns list of used device tokens +local function getDeviceTokens(dl_cb, cmd) + tdcli_function ({ + ID = "GetDeviceTokens", + }, dl_cb, cmd) +end + +M.getDeviceTokens = getDeviceTokens + +-- Changes privacy settings +-- @key Privacy key +-- @rules New privacy rules +-- @privacyKeyUserStatus Privacy key for managing visibility of the user status +-- @privacyKeyChatInvite Privacy key for managing ability of invitation of the user to chats +-- @privacyRuleAllowAll Rule to allow all users +-- @privacyRuleAllowContacts Rule to allow all user contacts +-- @privacyRuleAllowUsers Rule to allow specified users +-- @user_ids User identifiers +-- @privacyRuleDisallowAll Rule to disallow all users +-- @privacyRuleDisallowContacts Rule to disallow all user contacts +-- @privacyRuleDisallowUsers Rule to disallow all specified users +-- key = UserStatus|ChatInvite +-- rules = AllowAll|AllowContacts|AllowUsers(user_ids)|DisallowAll|DisallowContacts|DisallowUsers(user_ids) +local function setPrivacy(key, rule, allowed_user_ids, disallowed_user_ids, dl_cb, cmd) + local rules = {[0] = {ID = 'PrivacyRule' .. rule}} + + if allowed_user_ids then + rules = { + { + ID = 'PrivacyRule' .. rule + }, + [0] = { + ID = "PrivacyRuleAllowUsers", + user_ids_ = allowed_user_ids -- vector + }, + } + end + if disallowed_user_ids then + rules = { + { + ID = 'PrivacyRule' .. rule + }, + [0] = { + ID = "PrivacyRuleDisallowUsers", + user_ids_ = disallowed_user_ids -- vector + }, + } + end + if allowed_user_ids and disallowed_user_ids then + rules = { + { + ID = 'PrivacyRule' .. rule + }, + { + ID = "PrivacyRuleAllowUsers", + user_ids_ = allowed_user_ids + }, + [0] = { + ID = "PrivacyRuleDisallowUsers", + user_ids_ = disallowed_user_ids + }, + } + end + tdcli_function ({ + ID = "SetPrivacy", + key_ = { + ID = 'PrivacyKey' .. key + }, + rules_ = { + ID = "PrivacyRules", + rules_ = rules + }, + }, dl_cb, cmd) +end + +M.setPrivacy = setPrivacy + +-- Returns current privacy settings +-- @key Privacy key +-- key = UserStatus|ChatInvite +local function getPrivacy(key, dl_cb, cmd) + tdcli_function ({ + ID = "GetPrivacy", + key_ = { + ID = "PrivacyKey" .. key + }, + }, dl_cb, cmd) +end + +M.getPrivacy = getPrivacy + +-- Returns value of an option by its name. +-- See list of available options on https://core.telegram.org/tdlib/options +-- @name Name of the option +local function getOption(name, dl_cb, cmd) + tdcli_function ({ + ID = "GetOption", + name_ = name + }, dl_cb, cmd) +end + +M.getOption = getOption + +-- Sets value of an option. +-- See list of available options on https://core.telegram.org/tdlib/options. +-- Only writable options can be set +-- @name Name of the option +-- @value New value of the option +local function setOption(name, option, value, dl_cb, cmd) + tdcli_function ({ + ID = "SetOption", + name_ = name, + value_ = { + ID = 'Option' .. option, + value_ = value + }, + }, dl_cb, cmd) +end + +M.setOption = setOption + +-- Changes period of inactivity, after which the account of currently logged in user will be automatically deleted +-- @ttl New account TTL +local function changeAccountTtl(days, dl_cb, cmd) + tdcli_function ({ + ID = "ChangeAccountTtl", + ttl_ = { + ID = "AccountTtl", + days_ = days + }, + }, dl_cb, cmd) +end + +M.changeAccountTtl = changeAccountTtl + +-- Returns period of inactivity, after which the account of currently logged in user will be automatically deleted +local function getAccountTtl(dl_cb, cmd) + tdcli_function ({ + ID = "GetAccountTtl", + }, dl_cb, cmd) +end + +M.getAccountTtl = getAccountTtl + +-- Deletes the account of currently logged in user, deleting from the server all information associated with it. +-- Account's phone number can be used to create new account, but only once in two weeks +-- @reason Optional reason of account deletion +local function deleteAccount(reason, dl_cb, cmd) + tdcli_function ({ + ID = "DeleteAccount", + reason_ = reason + }, dl_cb, cmd) +end + +M.deleteAccount = deleteAccount + +-- Returns current chat report spam state +-- @chat_id Chat identifier +local function getChatReportSpamState(chat_id, dl_cb, cmd) + tdcli_function ({ + ID = "GetChatReportSpamState", + chat_id_ = chat_id + }, dl_cb, cmd) +end + +M.getChatReportSpamState = getChatReportSpamState + +-- Reports chat as a spam chat or as not a spam chat. +-- Can be used only if ChatReportSpamState.can_report_spam is true. +-- After this request ChatReportSpamState.can_report_spam became false forever +-- @chat_id Chat identifier +-- @is_spam_chat If true, chat will be reported as a spam chat, otherwise it will be marked as not a spam chat +local function changeChatReportSpamState(chat_id, is_spam_chat, dl_cb, cmd) + tdcli_function ({ + ID = "ChangeChatReportSpamState", + chat_id_ = chat_id, + is_spam_chat_ = is_spam_chat + }, dl_cb, cmd) +end + +M.changeChatReportSpamState = changeChatReportSpamState + +-- Bots only. +-- Informs server about number of pending bot updates if they aren't processed for a long time +-- @pending_update_count Number of pending updates +-- @error_message Last error's message +local function setBotUpdatesStatus(pending_update_count, error_message, dl_cb, cmd) + tdcli_function ({ + ID = "SetBotUpdatesStatus", + pending_update_count_ = pending_update_count, + error_message_ = error_message + }, dl_cb, cmd) +end + +M.setBotUpdatesStatus = setBotUpdatesStatus + +-- Returns Ok after specified amount of the time passed +-- @seconds Number of seconds before that function returns +local function setAlarm(seconds, dl_cb, cmd) + tdcli_function ({ + ID = "SetAlarm", + seconds_ = seconds + }, dl_cb, cmd) +end + +M.setAlarm = setAlarm + +-- Text message +-- @text Text to send +-- @disable_notification Pass true, to disable notification about the message, doesn't works in secret chats +-- @from_background Pass true, if the message is sent from background +-- @reply_markup Bots only. Markup for replying to message +-- @disable_web_page_preview Pass true to disable rich preview for link in the message text +-- @clear_draft Pass true if chat draft message should be deleted +-- @entities Bold, Italic, Code, Pre, PreCode and TextUrl entities contained in the text. Non-bot users can't use TextUrl entities. Can't be used with non-null parse_mode +-- @parse_mode Text parse mode, nullable. Can't be used along with enitities +local function sendMessage(chat_id, reply_to_message_id, disable_notification, text, disable_web_page_preview, parse_mode) + local TextParseMode = getParseMode(parse_mode) + + tdcli_function ({ + ID = "SendMessage", + chat_id_ = chat_id, + reply_to_message_id_ = reply_to_message_id, + disable_notification_ = disable_notification, + from_background_ = 1, + reply_markup_ = nil, + input_message_content_ = { + ID = "InputMessageText", + text_ = text, + disable_web_page_preview_ = disable_web_page_preview, + clear_draft_ = 0, + entities_ = {}, + parse_mode_ = TextParseMode, + }, + }, dl_cb, nil) +end + +M.sendMessage = sendMessage + +-- Animation message +-- @animation Animation file to send +-- @thumb Animation thumb, if available +-- @width Width of the animation, may be replaced by the server +-- @height Height of the animation, may be replaced by the server +-- @caption Animation caption, 0-200 characters +local function sendAnimation(chat_id, reply_to_message_id, disable_notification, from_background, reply_markup, animation, width, height, caption, dl_cb, cmd) + tdcli_function ({ + ID = "SendMessage", + chat_id_ = chat_id, + reply_to_message_id_ = reply_to_message_id, + disable_notification_ = disable_notification, + from_background_ = from_background, + reply_markup_ = reply_markup, + input_message_content_ = { + ID = "InputMessageAnimation", + animation_ = getInputFile(animation), + --thumb_ = { + --ID = "InputThumb", + --path_ = path, + --width_ = width, + --height_ = height + --}, + width_ = width or '', + height_ = height or '', + caption_ = caption or '' + }, + }, dl_cb, cmd) +end + +M.sendAnimation = sendAnimation + +-- Audio message +-- @audio Audio file to send +-- @album_cover_thumb Thumb of the album's cover, if available +-- @duration Duration of audio in seconds, may be replaced by the server +-- @title Title of the audio, 0-64 characters, may be replaced by the server +-- @performer Performer of the audio, 0-64 characters, may be replaced by the server +-- @caption Audio caption, 0-200 characters +local function sendAudio(chat_id, reply_to_message_id, disable_notification, from_background, reply_markup, audio, duration, title, performer, caption, dl_cb, cmd) + tdcli_function ({ + ID = "SendMessage", + chat_id_ = chat_id, + reply_to_message_id_ = reply_to_message_id, + disable_notification_ = disable_notification, + from_background_ = from_background, + reply_markup_ = reply_markup, + input_message_content_ = { + ID = "InputMessageAudio", + audio_ = getInputFile(audio), + --album_cover_thumb_ = { + --ID = "InputThumb", + --path_ = path, + --width_ = width, + --height_ = height + --}, + duration_ = duration or '', + title_ = title or '', + performer_ = performer or '', + caption_ = caption or '' + }, + }, dl_cb, cmd) +end + +M.sendAudio = sendAudio + +-- Document message +-- @document Document to send +-- @thumb Document thumb, if available +-- @caption Document caption, 0-200 characters +local function sendDocument(chat_id, reply_to_message_id, disable_notification, from_background, reply_markup, document, caption, dl_cb, cmd) + tdcli_function ({ + ID = "SendMessage", + chat_id_ = chat_id, + reply_to_message_id_ = reply_to_message_id, + disable_notification_ = disable_notification, + from_background_ = from_background, + reply_markup_ = reply_markup, + input_message_content_ = { + ID = "InputMessageDocument", + document_ = getInputFile(document), + --thumb_ = { + --ID = "InputThumb", + --path_ = path, + --width_ = width, + --height_ = height + --}, + caption_ = caption + }, + }, dl_cb, cmd) +end + +M.sendDocument = sendDocument + +-- Photo message +-- @photo Photo to send +-- @caption Photo caption, 0-200 characters +local function sendPhoto(chat_id, reply_to_message_id, disable_notification, from_background, reply_markup, photo, caption, dl_cb, cmd) + tdcli_function ({ + ID = "SendMessage", + chat_id_ = chat_id, + reply_to_message_id_ = reply_to_message_id, + disable_notification_ = disable_notification, + from_background_ = from_background, + reply_markup_ = reply_markup, + input_message_content_ = { + ID = "InputMessagePhoto", + photo_ = getInputFile(photo), + added_sticker_file_ids_ = {}, + width_ = 0, + height_ = 0, + caption_ = caption + }, + }, dl_cb, cmd) +end + +M.sendPhoto = sendPhoto + +-- Sticker message +-- @sticker Sticker to send +-- @thumb Sticker thumb, if available +local function sendSticker(chat_id, reply_to_message_id, disable_notification, from_background, reply_markup, sticker, dl_cb, cmd) + tdcli_function ({ + ID = "SendMessage", + chat_id_ = chat_id, + reply_to_message_id_ = reply_to_message_id, + disable_notification_ = disable_notification, + from_background_ = from_background, + reply_markup_ = reply_markup, + input_message_content_ = { + ID = "InputMessageSticker", + sticker_ = getInputFile(sticker), + --thumb_ = { + --ID = "InputThumb", + --path_ = path, + --width_ = width, + --height_ = height + --}, + }, + }, dl_cb, cmd) +end + +M.sendSticker = sendSticker + +-- Video message +-- @video Video to send +-- @thumb Video thumb, if available +-- @duration Duration of video in seconds +-- @width Video width +-- @height Video height +-- @caption Video caption, 0-200 characters +local function sendVideo(chat_id, reply_to_message_id, disable_notification, from_background, reply_markup, video, duration, width, height, caption, dl_cb, cmd) + tdcli_function ({ + ID = "SendMessage", + chat_id_ = chat_id, + reply_to_message_id_ = reply_to_message_id, + disable_notification_ = disable_notification, + from_background_ = from_background, + reply_markup_ = reply_markup, + input_message_content_ = { + ID = "InputMessageVideo", + video_ = getInputFile(video), + --thumb_ = { + --ID = "InputThumb", + --path_ = path, + --width_ = width, + --height_ = height + --}, + added_sticker_file_ids_ = {}, + duration_ = duration or '', + width_ = width or '', + height_ = height or '', + caption_ = caption or '' + }, + }, dl_cb, cmd) +end + +M.sendVideo = sendVideo + +-- Voice message +-- @voice Voice file to send +-- @duration Duration of voice in seconds +-- @waveform Waveform representation of the voice in 5-bit format +-- @caption Voice caption, 0-200 characters +local function sendVoice(chat_id, reply_to_message_id, disable_notification, from_background, reply_markup, voice, duration, waveform, caption, dl_cb, cmd) + tdcli_function ({ + ID = "SendMessage", + chat_id_ = chat_id, + reply_to_message_id_ = reply_to_message_id, + disable_notification_ = disable_notification, + from_background_ = from_background, + reply_markup_ = reply_markup, + input_message_content_ = { + ID = "InputMessageVoice", + voice_ = getInputFile(voice), + duration_ = duration or '', + waveform_ = waveform or '', + caption_ = caption or '' + }, + }, dl_cb, cmd) +end + +M.sendVoice = sendVoice + +-- Message with location +-- @latitude Latitude of location in degrees as defined by sender +-- @longitude Longitude of location in degrees as defined by sender +local function sendLocation(chat_id, reply_to_message_id, disable_notification, from_background, reply_markup, latitude, longitude, dl_cb, cmd) + tdcli_function ({ + ID = "SendMessage", + chat_id_ = chat_id, + reply_to_message_id_ = reply_to_message_id, + disable_notification_ = disable_notification, + from_background_ = from_background, + reply_markup_ = reply_markup, + input_message_content_ = { + ID = "InputMessageLocation", + location_ = { + ID = "Location", + latitude_ = latitude, + longitude_ = longitude + }, + }, + }, dl_cb, cmd) +end + +M.sendLocation = sendLocation + +-- Message with information about venue +-- @venue Venue to send +-- @latitude Latitude of location in degrees as defined by sender +-- @longitude Longitude of location in degrees as defined by sender +-- @title Venue name as defined by sender +-- @address Venue address as defined by sender +-- @provider Provider of venue database as defined by sender. Only "foursquare" need to be supported currently +-- @id Identifier of the venue in provider database as defined by sender +local function sendVenue(chat_id, reply_to_message_id, disable_notification, from_background, reply_markup, latitude, longitude, title, address, id, dl_cb, cmd) + tdcli_function ({ + ID = "SendMessage", + chat_id_ = chat_id, + reply_to_message_id_ = reply_to_message_id, + disable_notification_ = disable_notification, + from_background_ = from_background, + reply_markup_ = reply_markup, + input_message_content_ = { + ID = "InputMessageVenue", + venue_ = { + ID = "Venue", + location_ = { + ID = "Location", + latitude_ = latitude, + longitude_ = longitude + }, + title_ = title, + address_ = address, + provider_ = 'foursquare', + id_ = id + }, + }, + }, dl_cb, cmd) +end + +M.sendVenue = sendVenue + +-- User contact message +-- @contact Contact to send +-- @phone_number User's phone number +-- @first_name User first name, 1-255 characters +-- @last_name User last name +-- @user_id User identifier if known, 0 otherwise +local function sendContact(chat_id, reply_to_message_id, disable_notification, from_background, reply_markup, phone_number, first_name, last_name, user_id, dl_cb, cmd) + tdcli_function ({ + ID = "SendMessage", + chat_id_ = chat_id, + reply_to_message_id_ = reply_to_message_id, + disable_notification_ = disable_notification, + from_background_ = from_background, + reply_markup_ = reply_markup, + input_message_content_ = { + ID = "InputMessageContact", + contact_ = { + ID = "Contact", + phone_number_ = phone_number, + first_name_ = first_name, + last_name_ = last_name, + user_id_ = user_id + }, + }, + }, dl_cb, cmd) +end + +M.sendContact = sendContact + +-- Message with a game +-- @bot_user_id User identifier of a bot owned the game +-- @game_short_name Game short name +local function sendGame(chat_id, reply_to_message_id, disable_notification, from_background, reply_markup, bot_user_id, game_short_name, dl_cb, cmd) + tdcli_function ({ + ID = "SendMessage", + chat_id_ = chat_id, + reply_to_message_id_ = reply_to_message_id, + disable_notification_ = disable_notification, + from_background_ = from_background, + reply_markup_ = reply_markup, + input_message_content_ = { + ID = "InputMessageGame", + bot_user_id_ = bot_user_id, + game_short_name_ = game_short_name + }, + }, dl_cb, cmd) +end + +M.sendGame = sendGame + +-- Forwarded message +-- @from_chat_id Chat identifier of the message to forward +-- @message_id Identifier of the message to forward +local function sendForwarded(chat_id, reply_to_message_id, disable_notification, from_background, reply_markup, from_chat_id, message_id, dl_cb, cmd) + tdcli_function ({ + ID = "SendMessage", + chat_id_ = chat_id, + reply_to_message_id_ = reply_to_message_id, + disable_notification_ = disable_notification, + from_background_ = from_background, + reply_markup_ = reply_markup, + input_message_content_ = { + ID = "InputMessageForwarded", + from_chat_id_ = from_chat_id, + message_id_ = message_id + }, + }, dl_cb, cmd) +end + +M.sendForwarded = sendForwarded + +return M cli/tg/tgcli (Binary file not shown.) 0 comments on commit 3233fdf Comment on 3233fdf Leave a comment Comment Desktop version
avivsinai / Jenkins CliGitHub-style CLI for Jenkins — manage contexts, runs, logs, and admin tasks from your terminal.
wso2 / Wso2 Pax LoggingFork Repository of https://github.com/ops4j/org.ops4j.pax.logging
jwalton / Gh Docker LogsGitHub Action to collect logs from all docker containers.
abhioncbr / Docker AirflowRepo for building docker based airflow image. Containers support multiple features like writing logs to local or S3 folder and Initializing GCP while container booting. https://abhioncbr.github.io/docker-airflow/
johnreilly / Github FogbugzA sinatra app to log your GitHub commits with FogBugz
gh-tui-tools / Git Gloss✨Make your git logs show GitHub PR/issue/reviewer/author links
Marijn-Bergman / Copilot Chat Export Formatterthis python script takes the raw Visual Studio Code Github Copilot chat log and turns it into a more readable text file
suzuki-shunsuke / Ghaperfghaperf is a CLI to analyze the performance of GitHub Actions using GitHub API and raw job logs
mercerheather476 / Turbo Garbanzo [](https://search.maven.org/search?q=g:net.openid%20appauth) [](http://javadoc.io/doc/net.openid/appauth) [](https://github.com/openid/AppAuth-Android/actions/workflows/build.yml) [](https://codecov.io/github/openid/AppAuth-Android?branch=master) AppAuth for Android is a client SDK for communicating with [OAuth 2.0](https://tools.ietf.org/html/rfc6749) and [OpenID Connect](http://openid.net/specs/openid-connect-core-1_0.html) providers. It strives to directly map the requests and responses of those specifications, while following the idiomatic style of the implementation language. In addition to mapping the raw protocol flows, convenience methods are available to assist with common tasks like performing an action with fresh tokens. The library follows the best practices set out in [RFC 8252 - OAuth 2.0 for Native Apps](https://tools.ietf.org/html/rfc8252), including using [Custom Tabs](https://developer.chrome.com/multidevice/android/customtabs) for authorization requests. For this reason, `WebView` is explicitly *not* supported due to usability and security reasons. The library also supports the [PKCE](https://tools.ietf.org/html/rfc7636) extension to OAuth which was created to secure authorization codes in public clients when custom URI scheme redirects are used. The library is friendly to other extensions (standard or otherwise) with the ability to handle additional parameters in all protocol requests and responses. A talk providing an overview of using the library for enterprise single sign-on (produced by Google) can be found here: [Enterprise SSO with Chrome Custom Tabs](https://www.youtube.com/watch?v=DdQTXrk6YTk). ## Download AppAuth for Android is available on [MavenCentral](https://search.maven.org/search?q=g:net.openid%20appauth) ```groovy implementation 'net.openid:appauth:<version>' ``` ## Requirements AppAuth supports Android API 16 (Jellybean) and above. Browsers which provide a custom tabs implementation are preferred by the library, but not required. Both Custom URI Schemes (all supported versions of Android) and App Links (Android M / API 23+) can be used with the library. In general, AppAuth can work with any Authorization Server (AS) that supports native apps as documented in [RFC 8252](https://tools.ietf.org/html/rfc8252), either through custom URI scheme redirects, or App Links. AS's that assume all clients are web-based or require clients to maintain confidentiality of the client secrets may not work well. ## Demo app A demo app is contained within this repository. For instructions on how to build and configure this app, see the [demo app readme](https://github.com/openid/AppAuth-Android/blob/master/app/README.md). ## Conceptual overview AppAuth encapsulates the authorization state of the user in the [net.openid.appauth.AuthState](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/AuthState.java) class, and communicates with an authorization server through the use of the [net.openid.appauth.AuthorizationService](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/AuthorizationService.java) class. AuthState is designed to be easily persistable as a JSON string, using the storage mechanism of your choice (e.g. [SharedPreferences](https://developer.android.com/training/basics/data-storage/shared-preferences.html), [sqlite](https://developer.android.com/training/basics/data-storage/databases.html), or even just [in a file](https://developer.android.com/training/basics/data-storage/files.html)). AppAuth provides data classes which are intended to model the OAuth2 specification as closely as possible; this provides the greatest flexibility in interacting with a wide variety of OAuth2 and OpenID Connect implementations. Authorizing the user occurs via the user's web browser, and the request is described using instances of [AuthorizationRequest](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/AuthorizationRequest.java). The request is dispatched using [performAuthorizationRequest()](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/AuthorizationService.java#L159) on an AuthorizationService instance, and the response (an [AuthorizationResponse](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/AuthorizationResponse.java) instance) will be dispatched to the activity of your choice, expressed via an Intent. Token requests, such as obtaining a new access token using a refresh token, follow a similar pattern: [TokenRequest](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/TokenRequest.java) instances are dispatched using [performTokenRequest()](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/AuthorizationService.java#L252) on an AuthorizationService instance, and a [TokenResponse](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/TokenResponse.java) instance is returned via a callback. Responses can be provided to the [update()](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/AuthState.java#L367) methods on AuthState in order to track and persist changes to the authorization state. Once in an authorized state, the [performActionWithFreshTokens()](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/AuthState.java#L449) method on AuthState can be used to automatically refresh access tokens as necessary before performing actions that require valid tokens. ## Implementing the authorization code flow It is recommended that native apps use the [authorization code](https://tools.ietf.org/html/rfc6749#section-1.3.1) flow with a public client to gain authorization to access user data. This has the primary advantage for native clients that the authorization flow, which must occur in a browser, only needs to be performed once. This flow is effectively composed of four stages: 1. Discovering or specifying the endpoints to interact with the provider. 2. Authorizing the user, via a browser, in order to obtain an authorization code. 3. Exchanging the authorization code with the authorization server, to obtain a refresh token and/or ID token. 4. Using access tokens derived from the refresh token to interact with a resource server for further access to user data. At each step of the process, an AuthState instance can (optionally) be updated with the result to help with tracking the state of the flow. ### Authorization service configuration First, AppAuth must be instructed how to interact with the authorization service. This can be done either by directly creating an [AuthorizationServiceConfiguration](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/AuthorizationServiceConfiguration.java#L102) instance, or by retrieving an OpenID Connect discovery document. Directly specifying an AuthorizationServiceConfiguration involves providing the URIs of the authorization endpoint and token endpoint, and optionally a dynamic client registration endpoint (see "Dynamic client registration" for more info): ```java AuthorizationServiceConfiguration serviceConfig = new AuthorizationServiceConfiguration( Uri.parse("https://idp.example.com/auth"), // authorization endpoint Uri.parse("https://idp.example.com/token")); // token endpoint ``` Where available, using an OpenID Connect discovery document is preferable: ```java AuthorizationServiceConfiguration.fetchFromIssuer( Uri.parse("https://idp.example.com"), new AuthorizationServiceConfiguration.RetrieveConfigurationCallback() { public void onFetchConfigurationCompleted( @Nullable AuthorizationServiceConfiguration serviceConfiguration, @Nullable AuthorizationException ex) { if (ex != null) { Log.e(TAG, "failed to fetch configuration"); return; } // use serviceConfiguration as needed } }); ``` This will attempt to download a discovery document from the standard location under this base URI, `https://idp.example.com/.well-known/openid-configuration`. If the discovery document for your IDP is in some other non-standard location, you can instead provide the full URI as follows: ```java AuthorizationServiceConfiguration.fetchFromUrl( Uri.parse("https://idp.example.com/exampletenant/openid-config"), new AuthorizationServiceConfiguration.RetrieveConfigurationCallback() { ... } }); ``` If desired, this configuration can be used to seed an AuthState instance, to persist the configuration easily: ```java AuthState authState = new AuthState(serviceConfig); ``` ### Obtaining an authorization code An authorization code can now be acquired by constructing an AuthorizationRequest, using its Builder. In AppAuth, the builders for each data class accept the mandatory parameters via the builder constructor: ```java AuthorizationRequest.Builder authRequestBuilder = new AuthorizationRequest.Builder( serviceConfig, // the authorization service configuration MY_CLIENT_ID, // the client ID, typically pre-registered and static ResponseTypeValues.CODE, // the response_type value: we want a code MY_REDIRECT_URI); // the redirect URI to which the auth response is sent ``` Other optional parameters, such as the OAuth2 [scope string](https://tools.ietf.org/html/rfc6749#section-3.3) or OpenID Connect [login hint](http://openid.net/specs/openid-connect-core-1_0.html#rfc.section.3.1.2.1) are specified through set methods on the builder: ```java AuthorizationRequest authRequest = authRequestBuilder .setScope("openid email profile https://idp.example.com/custom-scope") .setLoginHint("jdoe@user.example.com") .build(); ``` This request can then be dispatched using one of two approaches. a `startActivityForResult` call using an Intent returned from the `AuthorizationService`, or by calling `performAuthorizationRequest` and providing pending intent for completion and cancelation handling activities. The `startActivityForResult` approach is simpler to use but may require more processing of the result: ```java private void doAuthorization() { AuthorizationService authService = new AuthorizationService(this); Intent authIntent = authService.getAuthorizationRequestIntent(authRequest); startActivityForResult(authIntent, RC_AUTH); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == RC_AUTH) { AuthorizationResponse resp = AuthorizationResponse.fromIntent(data); AuthorizationException ex = AuthorizationException.fromIntent(data); // ... process the response or exception ... } else { // ... } } ``` If instead you wish to directly transition to another activity on completion or cancelation, you can use `performAuthorizationRequest`: ```java AuthorizationService authService = new AuthorizationService(this); authService.performAuthorizationRequest( authRequest, PendingIntent.getActivity(this, 0, new Intent(this, MyAuthCompleteActivity.class), 0), PendingIntent.getActivity(this, 0, new Intent(this, MyAuthCanceledActivity.class), 0)); ``` The intents may be customized to carry any additional data or flags required for the correct handling of the authorization response. #### Capturing the authorization redirect Once the authorization flow is completed in the browser, the authorization service will redirect to a URI specified as part of the authorization request, providing the response via query parameters. In order for your app to capture this response, it must register with the Android OS as a handler for this redirect URI. We recommend using a custom scheme based redirect URI (i.e. those of form `my.scheme:/path`), as this is the most widely supported across all versions of Android. To avoid conflicts with other apps, it is recommended to configure a distinct scheme using "reverse domain name notation". This can either match your service web domain (in reverse) e.g. `com.example.service` or your package name `com.example.app` or be something completely new as long as it's distinct enough. Using the package name of your app is quite common but it's not always possible if it contains illegal characters for URI schemes (like underscores) or if you already have another handler for that scheme - so just use something else. When a custom scheme is used, AppAuth can be easily configured to capture all redirects using this custom scheme through a manifest placeholder: ```groovy android.defaultConfig.manifestPlaceholders = [ 'appAuthRedirectScheme': 'com.example.app' ] ``` Alternatively, the redirect URI can be directly configured by adding an intent-filter for AppAuth's RedirectUriReceiverActivity to your AndroidManifest.xml: ```xml <activity android:name="net.openid.appauth.RedirectUriReceiverActivity" tools:node="replace"> <intent-filter> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.BROWSABLE"/> <data android:scheme="com.example.app"/> </intent-filter> </activity> ``` If an HTTPS redirect URI is required instead of a custom scheme, the same approach (modifying your AndroidManifest.xml) is used: ```xml <activity android:name="net.openid.appauth.RedirectUriReceiverActivity" tools:node="replace"> <intent-filter> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.BROWSABLE"/> <data android:scheme="https" android:host="app.example.com" android:path="/oauth2redirect"/> </intent-filter> </activity> ``` HTTPS redirects can be secured by configuring the redirect URI as an [app link](https://developer.android.com/training/app-links/index.html) in Android M and above. We recommend that a fallback page be configured at the same address to forward authorization responses to your app via a custom scheme, for older Android devices. #### Handling the authorization response Upon completion of the authorization flow, the completion Intent provided to performAuthorizationRequest will be triggered. The authorization response is provided to this activity via Intent extra data, which can be extracted using the `fromIntent()` methods on AuthorizationResponse and AuthorizationException respectively: ```java public void onCreate(Bundle b) { AuthorizationResponse resp = AuthorizationResponse.fromIntent(getIntent()); AuthorizationException ex = AuthorizationException.fromIntent(getIntent()); if (resp != null) { // authorization completed } else { // authorization failed, check ex for more details } // ... } ``` The response can be provided to the AuthState instance for easy persistence and further processing: ``` authState.update(resp, ex); ``` If the full redirect URI is required in order to extract additional information that AppAuth does not provide, this is also provided to your activity: ```java public void onCreate(Bundle b) { // ... Uri redirectUri = getIntent().getData(); // ... } ``` ### Exchanging the authorization code Given a successful authorization response carrying an authorization code, a token request can be made to exchange the code for a refresh token: ```java authService.performTokenRequest( resp.createTokenExchangeRequest(), new AuthorizationService.TokenResponseCallback() { @Override public void onTokenRequestCompleted( TokenResponse resp, AuthorizationException ex) { if (resp != null) { // exchange succeeded } else { // authorization failed, check ex for more details } } }); ``` The token response can also be used to update an AuthState instance: ```java authState.update(resp, ex); ``` ### Using access tokens Finally, the retrieved access token can be used to interact with a resource server. This can be done directly, by extracting the access token from a token response. However, in most cases, it is simpler to use the `performActionWithFreshTokens` utility method provided by AuthState: ```java authState.performActionWithFreshTokens(service, new AuthStateAction() { @Override public void execute( String accessToken, String idToken, AuthorizationException ex) { if (ex != null) { // negotiation for fresh tokens failed, check ex for more details return; } // use the access token to do something ... } }); ``` This also updates the AuthState object with current access, id, and refresh tokens. If you are storing your AuthState in persistent storage, you should write the updated copy in the callback to this method. ### Ending current session Given you have a logged in session and you want to end it. In that case you need to get: - `AuthorizationServiceConfiguration` - valid Open Id Token that you should get after authentication - End of session URI that should be provided within you OpenId service config First you have to build EndSessionRequest ```java EndSessionRequest endSessionRequest = new EndSessionRequest.Builder(authorizationServiceConfiguration) .setIdTokenHint(idToken) .setPostLogoutRedirectUri(endSessionRedirectUri) .build(); ``` This request can then be dispatched using one of two approaches. a `startActivityForResult` call using an Intent returned from the `AuthorizationService`, or by calling `performEndSessionRequest` and providing pending intent for completion and cancelation handling activities. The startActivityForResult approach is simpler to use but may require more processing of the result: ```java private void endSession() { AuthorizationService authService = new AuthorizationService(this); Intent endSessionItent = authService.getEndSessionRequestIntent(endSessionRequest); startActivityForResult(endSessionItent, RC_END_SESSION); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == RC_END_SESSION) { EndSessionResonse resp = EndSessionResonse.fromIntent(data); AuthorizationException ex = AuthorizationException.fromIntent(data); // ... process the response or exception ... } else { // ... } } ``` If instead you wish to directly transition to another activity on completion or cancelation, you can use `performEndSessionRequest`: ```java AuthorizationService authService = new AuthorizationService(this); authService.performEndSessionRequest( endSessionRequest, PendingIntent.getActivity(this, 0, new Intent(this, MyAuthCompleteActivity.class), 0), PendingIntent.getActivity(this, 0, new Intent(this, MyAuthCanceledActivity.class), 0)); ``` End session flow will also work involving browser mechanism that is described in authorization mechanism session. Handling response mechanism with transition to another activity should be as follows: ```java public void onCreate(Bundle b) { EndSessionResponse resp = EndSessionResponse.fromIntent(getIntent()); AuthorizationException ex = AuthorizationException.fromIntent(getIntent()); if (resp != null) { // authorization completed } else { // authorization failed, check ex for more details } // ... } ``` ### AuthState persistence Instances of `AuthState` keep track of the authorization and token requests and responses. This is the only object that you need to persist to retain the authorization state of the session. Typically, one would do this by storing the authorization state in SharedPreferences or some other persistent store private to the app: ```java @NonNull public AuthState readAuthState() { SharedPreferences authPrefs = getSharedPreferences("auth", MODE_PRIVATE); String stateJson = authPrefs.getString("stateJson", null); if (stateJson != null) { return AuthState.jsonDeserialize(stateJson); } else { return new AuthState(); } } public void writeAuthState(@NonNull AuthState state) { SharedPreferences authPrefs = getSharedPreferences("auth", MODE_PRIVATE); authPrefs.edit() .putString("stateJson", state.jsonSerializeString()) .apply(); } ``` The demo app has an [AuthStateManager](https://github.com/openid/AppAuth-Android/blob/master/app/java/net/openid/appauthdemo/AuthStateManager.java) type which demonstrates this in more detail. ## Advanced configuration AppAuth provides some advanced configuration options via [AppAuthConfiguration](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/AppAuthConfiguration.java) instances, which can be provided to [AuthorizationService](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/AuthorizationService.java) during construction. ### Controlling which browser is used for authorization Some applications require explicit control over which browsers can be used for authorization - for example, to require that Chrome be used for second factor authentication to work, or require that some custom browser is used for authentication in an enterprise environment. Control over which browsers can be used can be achieved by defining a [BrowserMatcher](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/browser/BrowserMatcher.java), and supplying this to the builder of AppAuthConfiguration. A BrowserMatcher is suppled with a [BrowserDescriptor](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/browser/BrowserDescriptor.java) instance, and must decide whether this browser is permitted for the authorization flow. By default, [AnyBrowserMatcher](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/browser/AnyBrowserMatcher.java) is used. For your convenience, utility classes to help define a browser matcher are provided, such as: - [Browsers](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/browser/Browsers.java): contains a set of constants for the official package names and signatures of Chrome, Firefox and Samsung SBrowser. - [VersionedBrowserMatcher](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/browser/VersionedBrowserMatcher.java): will match a browser if it has a matching package name and signature, and a version number within a defined [VersionRange](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/browser/VersionRange.java). This class also provides some static instances for matching Chrome, Firefox and Samsung SBrowser. - [BrowserAllowList](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/browser/BrowserAllowList.java): takes a list of BrowserMatcher instances, and will match a browser if any of these child BrowserMatcher instances signals a match. - [BrowserDenyList](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/browser/BrowserDenyList.java): the inverse of BrowserAllowList - takes a list of browser matcher instances, and will match a browser if it _does not_ match any of these child BrowserMatcher instances. For instance, in order to restrict the authorization flow to using Chrome or SBrowser as a custom tab: ```java AppAuthConfiguration appAuthConfig = new AppAuthConfiguration.Builder() .setBrowserMatcher(new BrowserAllowList( VersionedBrowserMatcher.CHROME_CUSTOM_TAB, VersionedBrowserMatcher.SAMSUNG_CUSTOM_TAB)) .build(); AuthorizationService authService = new AuthorizationService(context, appAuthConfig); ``` Or, to prevent the use of a buggy version of the custom tabs in Samsung SBrowser: ```java AppAuthConfiguration appAuthConfig = new AppAuthConfiguration.Builder() .setBrowserMatcher(new BrowserDenyList( new VersionedBrowserMatcher( Browsers.SBrowser.PACKAGE_NAME, Browsers.SBrowser.SIGNATURE_SET, true, // when this browser is used via a custom tab VersionRange.atMost("5.3") ))) .build(); AuthorizationService authService = new AuthorizationService(context, appAuthConfig); ``` ### Customizing the connection builder for HTTP requests It can be desirable to customize how HTTP connections are made when performing token requests, for instance to use [certificate pinning](https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning) or to add additional trusted certificate authorities for an enterprise environment. This can be achieved in AppAuth by providing a custom [ConnectionBuilder](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/connectivity/ConnectionBuilder.java) instance. For example, to custom the SSL socket factory used, one could do the following: ```java AppAuthConfiguration appAuthConfig = new AppAuthConfiguration.Builder() .setConnectionBuilder(new ConnectionBuilder() { public HttpURLConnection openConnect(Uri uri) throws IOException { URL url = new URL(uri.toString()); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); if (connection instanceof HttpsUrlConnection) { HttpsURLConnection connection = (HttpsURLConnection) connection; connection.setSSLSocketFactory(MySocketFactory.getInstance()); } } }) .build(); ``` ### Issues with [ID Token](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/IdToken.java#L118) validation ID Token validation was introduced in `0.8.0` but not all authorization servers or configurations support it correctly. - For testing environments [setSkipIssuerHttpsCheck](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/AppAuthConfiguration.java#L129) can be used to bypass the fact the issuer needs to be HTTPS. ```java AppAuthConfiguration appAuthConfig = new AppAuthConfiguration.Builder() .setSkipIssuerHttpsCheck(true) .build() ``` - For services that don't support nonce[s] resulting in **IdTokenException** `Nonce mismatch` just set nonce to `null` on the `AuthorizationRequest`. Please consider **raising an issue** with your Identity Provider and removing this once it is fixed. ```java AuthorizationRequest authRequest = authRequestBuilder .setNonce(null) .build(); ``` ## Dynamic client registration AppAuth supports the [OAuth2 dynamic client registration protocol](https://tools.ietf.org/html/rfc7591). In order to dynamically register a client, create a [RegistrationRequest](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/RegistrationRequest.java) and dispatch it using [performRegistrationRequest](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/AuthorizationService.java#L278) on your AuthorizationService instance. The registration endpoint can either be defined directly as part of your [AuthorizationServiceConfiguration](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/AuthorizationServiceConfiguration.java), or discovered from an OpenID Connect discovery document. ```java RegistrationRequest registrationRequest = new RegistrationRequest.Builder( serviceConfig, Arrays.asList(redirectUri)) .build(); ``` Requests are dispatched with the help of `AuthorizationService`. As this request is asynchronous the response is passed to a callback: ```java service.performRegistrationRequest( registrationRequest, new AuthorizationService.RegistrationResponseCallback() { @Override public void onRegistrationRequestCompleted( @Nullable RegistrationResponse resp, @Nullable AuthorizationException ex) { if (resp != null) { // registration succeeded, store the registration response AuthState state = new AuthState(resp); //proceed to authorization... } else { // registration failed, check ex for more details } } }); ``` ## Utilizing client secrets (DANGEROUS) We _strongly recommend_ you avoid using static client secrets in your native applications whenever possible. Client secrets derived via a dynamic client registration are safe to use, but static client secrets can be easily extracted from your apps and allow others to impersonate your app and steal user data. If client secrets must be used by the OAuth2 provider you are integrating with, we strongly recommend performing the code exchange step on your backend, where the client secret can be kept hidden. Having said this, in some cases using client secrets is unavoidable. In these cases, a [ClientAuthentication](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/ClientAuthentication.java) instance can be provided to AppAuth when performing a token request. This allows additional parameters (both HTTP headers and request body parameters) to be added to token requests. Two standard implementations of ClientAuthentication are provided: - [ClientSecretBasic](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/ClientSecretBasic.java): includes a client ID and client secret as an HTTP Basic Authorization header. - [ClientSecretPost](https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/ClientSecretPost.java): includes a client ID and client secret as additional request parameters. So, in order to send a token request using HTTP basic authorization, one would write: ```java ClientAuthentication clientAuth = new ClientSecretBasic(MY_CLIENT_SECRET); TokenRequest req = ...; authService.performTokenRequest(req, clientAuth, callback); ``` This can also be done when using `performActionWithFreshTokens` on AuthState: ```java ClientAuthentication clientAuth = new ClientSecretPost(MY_CLIENT_SECRET); authState.performActionWithFreshTokens( authService, clientAuth, action); ``` ## Modifying or contributing to AppAuth This project requires the Android SDK for API level 25 (Nougat) to build, though the produced binaries only require API level 16 (Jellybean) to be used. We recommend that you fork and/or clone this repository to make modifications; downloading the source has been known to cause some developers problems. For contributors, see the additional instructions in [CONTRIBUTING.md](https://github.com/openid/AppAuth-Android/blob/master/CONTRIBUTING.md). ### Building from the Command line AppAuth for Android uses Gradle as its build system. In order to build the library and app binaries, run `./gradlew assemble`. The library AAR files are output to `library/build/outputs/aar`, while the demo app is output to `app/build/outputs/apk`. In order to run the tests and code analysis, run `./gradlew check`. ### Building from Android Studio In AndroidStudio, File -> New -> Import project. Select the root folder (the one with the `build.gradle` file).
debezium / Debezium Connector CassandraAn incubating Debezium CDC connector for Apache Cassandra. Please log issues at https://github.com/debezium/dbz/issues.
debezium / Debezium Connector Db2A Debezium connector for Db2 LUW and z/OS. Please log issues at https://github.com/debezium/dbz/issues.
laurent22 / Github Actions Logs ExtensionDisplay GitHub Action Raw log in color, converting the Ansi colors to HTML
sm-ll / Nord Modular G1 Patches720 Nord Modular G1 patches, used in the daily blog uploads now archived at https://github.com/sm-ll/mono-log.org/wiki
ariels7801 / Spring5webappThis is the most modern and comprehensive course available for Spring Framework 5 and Spring Boot 2. All source code examples used in this course have been developed using the latest version of the Spring Framework - Spring Framework 5 and Spring Boot 2. In this course, you will build multiple real world applications using Spring Framework 5. You will see how modern Spring Framework development is done by leveraging the features of Spring Boot 2. Jump In and Build a Spring MVC App with Spring Boot! We'll jump right into web development with the Spring Framework. I'll show you how kick off a Spring Boot project by using the Spring Initializr. We will then go step by step to build a simple Book / Author web application. You will see how easy it is to use Spring Boot, Spring MVC, and Spring Data JPA to create a functional web application running under Tomcat with a H2 in-memory database. Use Test Driven Development! In addition to teaching you Spring Framework 5, you will learn about modern best practices used in enterprise application development. As we build the applications, you'll see me using Test Driven Development (TDD) with JUnit and Mockito. Using Mockito mocks keeps your Spring Framework unit tests light and fast! You'll also see how the Spring context can be used for more complex integration tests. These techniques are best practices used by companies all over the world to build and manage large scale Spring Framework applications. GitHub Source Code You will have complete access to all source code examples used in the course. In each lesson where we write code, you will have a link to GitHub with two branches in the Github repository. The first branch is the starting state of the code. The second branch is the ending state of the code. You can see exactly what changed in each lesson. Each step of the way, you have a working example you can use for troubleshooting. In fact, you will get access to 15 (and growing!) different GitHub repositories - each packed with Spring Framework programming examples. And, you're encouraged to fork my GitHub repositories so you can share the Spring Framework applications, which you built, to future employers! Continuous Integration Builds Since we are using GitHub and have great test coverage, I also show you how easy it is to set up Continuous Integration builds with CircleCI. Continuous Integration builds are another best practice used by enterprise developers. Using CircleCI makes your CI builds a snap! Project Lombok We all know Java development can require a lot of boiler plate code. It's just the nature of Java. Would you like to see how to slash your boiler plate code using Project Lombok? Spring Data JPA and Hibernate Spring MVC and Hibernate have long been cornerstones of the Spring Framework. You will learn how to use Spring MVC, Spring Data JPA and Hibernate to build a real world web application. You'll learn about Hibernate configuration, and about the mapping of JPA entities. The Thymeleaf template engine is hugely popular with the Spring community. You will see how easy Spring Boot makes using Thymeleaf with Spring MVC. While Bootstrap CSS is not a focus of the course, we will leverage Bootstrap CSS to make our web pages look awesome! Spring MVC Spring MVC has a lot of robust capabilities. I start you off showing you how to build recipe application (using TDD, of course). Initially, it's all happy path development. We go back and add custom exception handling, form validation, and internationalization. Reactive Programming A big theme of Spring Framework 5 is Reactive Programming. Inside the course we build a web application using Thymeleaf, Spring MVC, Spring Data MongoDB, and MongoDB. We then take the MongoDB application we built and convert it to a Reactive application. You'll see how you can leverage the new Reactive types inside the Spring Framework from the data tier to the web tier. You will get to see step by step how to convert a traditional Spring MVC application to an end to end reactive application using the WebFlux framework - which is brand new to Spring Framework 5. Coming Soon to the Course I plan to add a lot more content to this course! I want this to be your go-to course for becoming a Spring Framework developer. Coming soon to the course in 2017: Building RESTFul APIs with Spring WebFlux (New in Spring Framework 5!) Spring Security Documenting your APIs with RestDoc and Swagger 2 Aspect Oriented Programming Using Spring Events Scheduling Tasks Using JAXB Caching with eHcache Spring JDBC (JDBC Template) Spring RestTemplate JMS Messaging AMQP with RabbitMQ Logging configuration for Logback and Log4J 2 And more real world Spring Framework apps! Message me if there is a topic you'd like to see! Spring Framework 5 GA Release This Spring Framework course is so new, it has been developed using Spring Framework 5 'Release Candidate' releases. Spring Framework 5 went GA (General Availability) in September of 2017. The Spring Boot 2.0 GA release is expected to be in late 2017. All source code examples will get updated as the GA releases of the Spring Framework and Spring Boot become available. Course Updates August 1, 2017 - All source code examples updated to latest release of Spring Framework 5 and Spring Boot 2. Now on Spring Framework 5.0 RC3 and Spring Boot 2.0.0.M3. August 8, 2017 - Added content for internationalization with Spring MVC. Added new section to course for using MySQL with Spring Boot / Spring MVC. Added CircleCI for CI builds. CodeCov (dot) io for test coverage reporting. August 9th, 2017 - Added whole new section course on Spring Data MongoDB. Learn to build a web application using the best of the Spring Framework! August 25th, 2017 - Reactive Programming with Spring Framework 5! Almost two hours of additional content has been added on Reactive Programming and Reactive MongoDB. October 10th, 2017 - 3 hours of new content added for consuming and building RESTFul web services using Spring MVC. This includes using RestTemplate to consume RESTFul services, Spring 5 WebClient to consume RESTFul services using Reactive data types, and new lessons on using MapStruct for data mapping. Course Extra - Spring Boot Cookbook! Inside this course, I'm including a Spring Boot Cookbook. You will have complete examples of using the Spring Framework with popular open source technologies. When you get hired as a Spring Framework developer, you'll have ready made Spring Framework examples! My Spring Boot Cookbook includes example Spring Boot projects for: MongoDB MySQL Postgres Maria DB DB2 Express Neo4J Redis Cassandra ActiveMQ RabbitMQ Course Extra - Learn Docker! Docker is an exciting technology that is on fire right now! As a course extra, I'm including the first 3 sections from my top rated Docker for Java Developers course. You will learn more about what Docker is and how you can deploy and run a Spring Boot application inside a Docker container. For Java developers, Docker really is a game changer! Course Extra - IntelliJ IDEA Ultimate Students enrolling in the course can receive a free 90 day trial license to IntelliJ IDEA Ultimate! Closed Captioning / Subtitles Closed captioning in english is available for all course videos! PDF Downloads All keynote presentations are available for you to download as PDFs. Lifetime Access When you purchase this course, you will receive lifetime access! You can login anytime from anywhere to access the course content. No Risk - Money Back Guarantee You can buy this course with no risk. If you are unhappy with the course, for any reason, you can get a complete refund. The course has a 30 day Money Back Guarantee. Future Proof Your Programming Career There is huge demand for Spring Framework developers. Downloads of Spring Boot are up 425% year over year, while Gartner Research is calling Java EE "Obsolete". The market trends are clear. Popularity for JEE is rapidly declining. The popularity for the Spring Framework is growing. Spring Framework 5 is packed with exciting and innovative new features making it a natural choice for enterprise application development. Future proof your programming career. Start learning how to building modern applications using the Spring Framework and enroll in this course today! ¿Cuáles son los requisitos? Basic Java knowledge is required HTML Knowledge is very helpful Knowledge of SQL and databases is helpful ¿Qué voy a aprender en este curso? Learn the Spring Framework from an instructor who has worked for Pivotal customers as a Spring Source consultant, and has spoken at Spring One Learn step by step how to build applications using Spring Framework 5 and Spring Boot 2 You will be taught using best practices such as SOLID OOP, GitHub, Test Driven Development, and Continuous Integration Testing You will understand how to access data using Hibernate 5 and Spring Data JPA Build an end to end Reactive application with Spring Framework 5 and MongoDB Learn About Reactive Programming with Spring Framework 5 Build web applications using Spring MVC See how to run a Spring Boot application inside a Docker container Get access to a Spring Boot Application Cookbook ¿A quién está dirigido? This course is ideal for Java developers who wish to use the Spring Framework for enterprise application development Ver más
Agentity-com / MCP Audit ExtensionAudit and log all GitHub Copilot MCP tool calls in VSCode with ease.