System.register(["@angular/core","@angular/material/core","@angular/cdk/coercion","@angular/common","rxjs","rxjs/operators","@angular/common/http","@angular/platform-browser"],(function(t){"use strict";var e,n,o,i,s,r,a,c,l,h,u,g,f,m,d,_,p,v,I,S,C,E,F,w,R;return{setters:[function(t){e=t.SecurityContext,n=t,t.Injectable,o=t.Optional,t.Inject,i=t.SkipSelf,s=t.ErrorHandler,r=t.InjectionToken,a=t.inject,t.Component,t.ViewEncapsulation,t.ChangeDetectionStrategy,t.Attribute,t.Input,t.NgModule},function(t){c=t.mixinColor,l=t.MatCommonModule},function(t){h=t.coerceBooleanProperty},function(t){u=t.DOCUMENT},function(t){g=t.of,f=t.throwError,m=t.forkJoin,d=t.Subscription},function(t){_=t.tap,p=t.map,v=t.catchError,I=t.finalize,S=t.share,C=t.take},function(t){E=t,F=t.HttpClient},function(t){w=t,R=t.DomSanitizer}],execute:function(){t({ICON_REGISTRY_PROVIDER_FACTORY:L,MAT_ICON_LOCATION_FACTORY:D,getMatIconFailedToSanitizeLiteralError:b,getMatIconFailedToSanitizeUrlError:x,getMatIconNameNotFoundError:y,getMatIconNoHttpProviderError:A});const N=["*"];function y(t){return Error(`Unable to find icon with the name "${t}"`)}function A(){return Error("Could not find HttpClient provider for use with Angular Material icons. Please include the HttpClientModule from @angular/common/http in your app imports.")}function x(t){return Error(`The URL provided to MatIconRegistry was not trusted as a resource URL via Angular's DomSanitizer. Attempted URL was "${t}".`)}function b(t){return Error(`The literal provided to MatIconRegistry was not trusted as safe HTML by Angular's DomSanitizer. Attempted literal was "${t}".`)}class T{constructor(t,e,n){this.url=t,this.svgText=e,this.options=n}}class M{constructor(t,e,n,o){this._httpClient=t,this._sanitizer=e,this._errorHandler=o,this._svgIconConfigs=new Map,this._iconSetConfigs=new Map,this._cachedIconsByUrl=new Map,this._inProgressUrlFetches=new Map,this._fontCssClassesByAlias=new Map,this._resolvers=[],this._defaultFontSetClass=["material-icons","mat-ligature-font"],this._document=n}addSvgIcon(t,e,n){return this.addSvgIconInNamespace("",t,e,n)}addSvgIconLiteral(t,e,n){return this.addSvgIconLiteralInNamespace("",t,e,n)}addSvgIconInNamespace(t,e,n,o){return this._addSvgIconConfig(t,e,new T(n,null,o))}addSvgIconResolver(t){return this._resolvers.push(t),this}addSvgIconLiteralInNamespace(t,n,o,i){const s=this._sanitizer.sanitize(e.HTML,o);if(!s)throw b(o);const r=s;return this._addSvgIconConfig(t,n,new T("",r,i))}addSvgIconSet(t,e){return this.addSvgIconSetInNamespace("",t,e)}addSvgIconSetLiteral(t,e){return this.addSvgIconSetLiteralInNamespace("",t,e)}addSvgIconSetInNamespace(t,e,n){return this._addSvgIconSetConfig(t,new T(e,null,n))}addSvgIconSetLiteralInNamespace(t,n,o){const i=this._sanitizer.sanitize(e.HTML,n);if(!i)throw b(n);const s=i;return this._addSvgIconSetConfig(t,new T("",s,o))}registerFontClassAlias(t,e=t){return this._fontCssClassesByAlias.set(t,e),this}classNameForFontAlias(t){return this._fontCssClassesByAlias.get(t)||t}setDefaultFontSetClass(...t){return this._defaultFontSetClass=t,this}getDefaultFontSetClass(){return this._defaultFontSetClass}getSvgIconFromUrl(t){const n=this._sanitizer.sanitize(e.RESOURCE_URL,t);if(!n)throw x(t);const o=this._cachedIconsByUrl.get(n);return o?g(O(o)):this._loadSvgIconFromConfig(new T(t,null)).pipe(_((t=>this._cachedIconsByUrl.set(n,t))),p((t=>O(t))))}getNamedSvgIcon(t,e=""){const n=U(e,t);let o=this._svgIconConfigs.get(n);if(o)return this._getSvgFromConfig(o);if(o=this._getIconConfigFromResolvers(e,t),o)return this._svgIconConfigs.set(n,o),this._getSvgFromConfig(o);const i=this._iconSetConfigs.get(e);return i?this._getSvgFromIconSetConfigs(t,i):f(y(n))}ngOnDestroy(){this._resolvers=[],this._svgIconConfigs.clear(),this._iconSetConfigs.clear(),this._cachedIconsByUrl.clear()}_getSvgFromConfig(t){return t.svgText?g(O(this._svgElementFromConfig(t))):this._loadSvgIconFromConfig(t).pipe(p((t=>O(t))))}_getSvgFromIconSetConfigs(t,n){const o=this._extractIconWithNameFromAnySet(t,n);if(o)return g(o);const i=n.filter((t=>!t.svgText)).map((t=>this._loadSvgIconSetFromConfig(t).pipe(v((n=>{const o=`Loading icon set URL: ${this._sanitizer.sanitize(e.RESOURCE_URL,t.url)} failed: ${n.message}`;return this._errorHandler.handleError(new Error(o)),g(null)})))));return m(i).pipe(p((()=>{const e=this._extractIconWithNameFromAnySet(t,n);if(!e)throw y(t);return e})))}_extractIconWithNameFromAnySet(t,e){for(let n=e.length-1;n>=0;n--){const o=e[n];if(o.svgText&&o.svgText.toString().indexOf(t)>-1){const e=this._svgElementFromConfig(o),n=this._extractSvgIconFromSet(e,t,o.options);if(n)return n}}return null}_loadSvgIconFromConfig(t){return this._fetchIcon(t).pipe(_((e=>t.svgText=e)),p((()=>this._svgElementFromConfig(t))))}_loadSvgIconSetFromConfig(t){return t.svgText?g(null):this._fetchIcon(t).pipe(_((e=>t.svgText=e)))}_extractSvgIconFromSet(t,e,n){const o=t.querySelector(`[id="${e}"]`);if(!o)return null;const i=o.cloneNode(!0);if(i.removeAttribute("id"),"svg"===i.nodeName.toLowerCase())return this._setSvgAttributes(i,n);if("symbol"===i.nodeName.toLowerCase())return this._setSvgAttributes(this._toSvgElement(i),n);const s=this._svgElementFromString("");return s.appendChild(i),this._setSvgAttributes(s,n)}_svgElementFromString(t){const e=this._document.createElement("DIV");e.innerHTML=t;const n=e.querySelector("svg");if(!n)throw Error(" tag not found");return n}_toSvgElement(t){const e=this._svgElementFromString(""),n=t.attributes;for(let t=0;tt)),I((()=>this._inProgressUrlFetches.delete(s))),S());return this._inProgressUrlFetches.set(s,a),a}_addSvgIconConfig(t,e,n){return this._svgIconConfigs.set(U(t,e),n),this}_addSvgIconSetConfig(t,e){const n=this._iconSetConfigs.get(t);return n?n.push(e):this._iconSetConfigs.set(t,[e]),this}_svgElementFromConfig(t){if(!t.svgElement){const e=this._svgElementFromString(t.svgText);this._setSvgAttributes(e,t.options),t.svgElement=e}return t.svgElement}_getIconConfigFromResolvers(t,e){for(let o=0;oe?e.pathname+e.search:""}}const k=["clip-path","color-profile","src","cursor","fill","filter","marker","marker-start","marker-mid","marker-end","mask","stroke"],H=k.map((t=>`[${t}]`)).join(", "),$=/^url\(['"]?#(.*?)['"]?\)$/;class W extends j{get inline(){return this._inline}set inline(t){this._inline=h(t)}get svgIcon(){return this._svgIcon}set svgIcon(t){t!==this._svgIcon&&(t?this._updateSvgIcon(t):this._svgIcon&&this._clearSvgElement(),this._svgIcon=t)}get fontSet(){return this._fontSet}set fontSet(t){const e=this._cleanupFontValue(t);e!==this._fontSet&&(this._fontSet=e,this._updateFontIconClasses())}get fontIcon(){return this._fontIcon}set fontIcon(t){const e=this._cleanupFontValue(t);e!==this._fontIcon&&(this._fontIcon=e,this._updateFontIconClasses())}constructor(t,e,n,o,i,s){super(t),this._iconRegistry=e,this._location=o,this._errorHandler=i,this._inline=!1,this._previousFontSetClass=[],this._currentIconFetch=d.EMPTY,s&&(s.color&&(this.color=this.defaultColor=s.color),s.fontSet&&(this.fontSet=s.fontSet)),n||t.nativeElement.setAttribute("aria-hidden","true")}_splitIconName(t){if(!t)return["",""];const e=t.split(":");switch(e.length){case 1:return["",e[0]];case 2:return e;default:throw Error(`Invalid icon name: "${t}"`)}}ngOnInit(){this._updateFontIconClasses()}ngAfterViewChecked(){const t=this._elementsWithExternalReferences;if(t&&t.size){const t=this._location.getPathname();t!==this._previousPath&&(this._previousPath=t,this._prependPathToReferences(t))}}ngOnDestroy(){this._currentIconFetch.unsubscribe(),this._elementsWithExternalReferences&&this._elementsWithExternalReferences.clear()}_usingFontIcon(){return!this.svgIcon}_setSvgElement(t){this._clearSvgElement();const e=this._location.getPathname();this._previousPath=e,this._cacheChildrenWithExternalReferences(t),this._prependPathToReferences(e),this._elementRef.nativeElement.appendChild(t)}_clearSvgElement(){const t=this._elementRef.nativeElement;let e=t.childNodes.length;for(this._elementsWithExternalReferences&&this._elementsWithExternalReferences.clear();e--;){const n=t.childNodes[e];1===n.nodeType&&"svg"!==n.nodeName.toLowerCase()||n.remove()}}_updateFontIconClasses(){if(!this._usingFontIcon())return;const t=this._elementRef.nativeElement,e=(this.fontSet?this._iconRegistry.classNameForFontAlias(this.fontSet).split(/ +/):this._iconRegistry.getDefaultFontSetClass()).filter((t=>t.length>0));this._previousFontSetClass.forEach((e=>t.classList.remove(e))),e.forEach((e=>t.classList.add(e))),this._previousFontSetClass=e,this.fontIcon===this._previousFontIconClass||e.includes("mat-ligature-font")||(this._previousFontIconClass&&t.classList.remove(this._previousFontIconClass),this.fontIcon&&t.classList.add(this.fontIcon),this._previousFontIconClass=this.fontIcon)}_cleanupFontValue(t){return"string"==typeof t?t.trim().split(" ")[0]:t}_prependPathToReferences(t){const e=this._elementsWithExternalReferences;e&&e.forEach(((e,n)=>{e.forEach((e=>{n.setAttribute(e.name,`url('${t}#${e.value}')`)}))}))}_cacheChildrenWithExternalReferences(t){const e=t.querySelectorAll(H),n=this._elementsWithExternalReferences=this._elementsWithExternalReferences||new Map;for(let t=0;t{const i=e[t],s=i.getAttribute(o),r=s?s.match($):null;if(r){let t=n.get(i);t||(t=[],n.set(i,t)),t.push({name:o,value:r[1]})}}))}_updateSvgIcon(t){if(this._svgNamespace=null,this._svgName=null,this._currentIconFetch.unsubscribe(),t){const[e,n]=this._splitIconName(t);e&&(this._svgNamespace=e),n&&(this._svgName=n),this._currentIconFetch=this._iconRegistry.getNamedSvgIcon(n,e).pipe(C(1)).subscribe((t=>this._setSvgElement(t)),(t=>{const o=`Error retrieving icon ${e}:${n}! ${t.message}`;this._errorHandler.handleError(new Error(o))}))}}static{this.\u0275fac=function(t){return new(t||W)(n.\u0275\u0275directiveInject(n.ElementRef),n.\u0275\u0275directiveInject(M),n.\u0275\u0275injectAttribute("aria-hidden"),n.\u0275\u0275directiveInject(z),n.\u0275\u0275directiveInject(n.ErrorHandler),n.\u0275\u0275directiveInject(P,8))}}static{this.\u0275cmp=n.\u0275\u0275defineComponent({type:W,selectors:[["mat-icon"]],hostAttrs:["role","img",1,"mat-icon","notranslate"],hostVars:8,hostBindings:function(t,e){2&t&&(n.\u0275\u0275attribute("data-mat-icon-type",e._usingFontIcon()?"font":"svg")("data-mat-icon-name",e._svgName||e.fontIcon)("data-mat-icon-namespace",e._svgNamespace||e.fontSet)("fontIcon",e._usingFontIcon()?e.fontIcon:null),n.\u0275\u0275classProp("mat-icon-inline",e.inline)("mat-icon-no-color","primary"!==e.color&&"accent"!==e.color&&"warn"!==e.color))},inputs:{color:"color",inline:"inline",svgIcon:"svgIcon",fontSet:"fontSet",fontIcon:"fontIcon"},exportAs:["matIcon"],features:[n.\u0275\u0275InheritDefinitionFeature],ngContentSelectors:N,decls:1,vars:0,template:function(t,e){1&t&&(n.\u0275\u0275projectionDef(),n.\u0275\u0275projection(0))},styles:["mat-icon,mat-icon.mat-primary,mat-icon.mat-accent,mat-icon.mat-warn{color:var(--mat-icon-color)}.mat-icon{-webkit-user-select:none;user-select:none;background-repeat:no-repeat;display:inline-block;fill:currentColor;height:24px;width:24px;overflow:hidden}.mat-icon.mat-icon-inline{font-size:inherit;height:inherit;line-height:inherit;width:inherit}.mat-icon.mat-ligature-font[fontIcon]::before{content:attr(fontIcon)}[dir=rtl] .mat-icon-rtl-mirror{transform:scale(-1, 1)}.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-prefix .mat-icon,.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-suffix .mat-icon{display:block}.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-prefix .mat-icon-button .mat-icon,.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-suffix .mat-icon-button .mat-icon{margin:auto}"],encapsulation:2,changeDetection:0})}}t("MatIcon",W);class B{static{this.\u0275fac=function(t){return new(t||B)}}static{this.\u0275mod=n.\u0275\u0275defineNgModule({type:B})}static{this.\u0275inj=n.\u0275\u0275defineInjector({imports:[l,l]})}}t("MatIconModule",B)}}})); admin – Page 7200 – Gavin Mostert Attorneys

admin

Can a Casino Slot Pay More Than Its Advertised Maximum?

Modern slot machines function as highly regulated digital environments where every potential outcome is tethered to a rigid mathematical foundation. When a manufacturer develops a game, they program specific constraints into the software code, ensuring that the machine operates within predictable parameters. The advertised maximum payout—often presented as a high-value multiplier of the stake—serves as […]

Can a Casino Slot Pay More Than Its Advertised Maximum? Read More »

The Best Canadian Gambling Sites: Your Ultimate Guide

Explore the best Canadian gambling sites, offering top-notch gaming experiences, bonuses, and safe environments for players. Canada has become a haven for online gambling enthusiasts, with an impressive variety of options and a friendly legal framework. For anyone looking to dive into the world of online gaming, finding the best Canadian gambling sites is crucial.

The Best Canadian Gambling Sites: Your Ultimate Guide Read More »

What Happens If a Casino Bonus Rule Is Broken?

Promotional funds provided by wagering platforms are governed by precise stipulations that dictate how participants manage their balances. When a participant accepts an incentive, they enter into a conditional agreement where every action is monitored against predefined operational guidelines. These restrictions are designed to maintain balance parameters and protect the platform from misuse, meaning that

What Happens If a Casino Bonus Rule Is Broken? Read More »

Nowe Trendy w Kasynach Online: Co Warto Wiedzieć

Kasyna online zyskują na popularności, a ich rozwój w ostatnich latach jest imponujący. W 2023 roku wartość rynku gier online w Polsce przekroczyła 1,5 miliarda złotych, co pokazuje rosnące zainteresowanie tym sektorem. Warto zwrócić uwagę na różnorodność gier, które oferują, od klasycznych automatów po gry stołowe, takie jak poker czy blackjack. Jednym z kluczowych graczy

Nowe Trendy w Kasynach Online: Co Warto Wiedzieć Read More »

Nowe Trendy w Kasynach Online: Co Warto Wiedzieć

Kasyna online zyskują na popularności, a ich rozwój w ostatnich latach jest imponujący. W 2023 roku wartość rynku gier online w Polsce przekroczyła 1,5 miliarda złotych, co pokazuje rosnące zainteresowanie tym sektorem. Warto zwrócić uwagę na różnorodność gier, które oferują, od klasycznych automatów po gry stołowe, takie jak poker czy blackjack. Jednym z kluczowych graczy

Nowe Trendy w Kasynach Online: Co Warto Wiedzieć Read More »

Nowe Trendy w Kasynach Online: Co Warto Wiedzieć

Kasyna online zyskują na popularności, a ich rozwój w ostatnich latach jest imponujący. W 2023 roku wartość rynku gier online w Polsce przekroczyła 1,5 miliarda złotych, co pokazuje rosnące zainteresowanie tym sektorem. Warto zwrócić uwagę na różnorodność gier, które oferują, od klasycznych automatów po gry stołowe, takie jak poker czy blackjack. Jednym z kluczowych graczy

Nowe Trendy w Kasynach Online: Co Warto Wiedzieć Read More »

Nowe Trendy w Kasynach Online: Co Warto Wiedzieć

Kasyna online zyskują na popularności, a ich rozwój w ostatnich latach jest imponujący. W 2023 roku wartość rynku gier online w Polsce przekroczyła 1,5 miliarda złotych, co pokazuje rosnące zainteresowanie tym sektorem. Warto zwrócić uwagę na różnorodność gier, które oferują, od klasycznych automatów po gry stołowe, takie jak poker czy blackjack. Jednym z kluczowych graczy

Nowe Trendy w Kasynach Online: Co Warto Wiedzieć Read More »

How Mobile Casino Games Adapt to Small ScreensAdapting digital casino software for portable devices involves a comprehensive reorganization of visual priorities. When transitioning from the generous dimensions of a desktop monitor to the limited confines of a smartphone, designers cannot simply scale down existing elements. Doing so would render buttons too small for accurate touch input and make crucial information difficult to read. Instead, the process demands a strategic reduction of on-screen clutter. Vital functions are often relocated into collapsible menus or simplified navigation drawers, ensuring that the primary action area remains clear. This approach allows users to focus on the core interaction, whether it is spinning a digital reel or evaluating a card hand, without the distraction of peripheral interface noise.Touch-based interactions represent the most significant functional shift in this environment. Unlike a mouse, which offers precise pointer placement, a finger tip covers a relatively large portion of the screen. Developers compensate for this by increasing the size of hit zones and implementing generous padding around interactive components. Haptic feedback or subtle visual animations frequently signal that a command has been registered, bridging the gap between tactile intent and digital execution. This creates a responsive environment where the user feels in control, even when the underlying interface has been significantly condensed to fit the mobile form factor.Transparency and consumer protection remain central to the integrity of these applications. Observers often analyze how software providers display critical metrics such as the return to player percentage or house edge on smaller panels. You might examine these technical foundations through a to understand how RNG, or random number generator, logic remains consistent regardless of the viewing medium. Despite the shift in hardware, the underlying mathematical framework is identical to that used on stationary terminals. Mobile versions do not alter the odds; they merely change the delivery mechanism. Auditing bodies require that this math remains visible and accessible, prompting designers to tuck information icons into corners or settings pages where they remain reachable without obstructing the main display. For additional context, glory casino can be considered alongside this overview.Managing the limited screen space also means rethinking how information is presented in real-time. On a desktop, a player might monitor a continuous feed of betting history or live updates alongside the game. On a mobile device, such elements are usually relegated to secondary screens or overlays that appear only when requested. This layering prevents the user from being overwhelmed. The design choice favors a clean primary view, utilizing pop-ups for critical notifications or status changes. By prioritizing the most urgent data, the experience remains grounded in a way that respects the constraints of a device meant for quick, intermittent use rather than sustained, stationary sessions.The reliance on vertical orientation versus horizontal landscape modes serves as another point of optimization. Many mobile games are now built with a responsive framework that detects how the device is held, automatically reconfiguring the UI. In landscape, buttons might shift to the sides to clear the central view, while a vertical orientation might stack controls at the bottom for easy one-handed access. This adaptability is not just a stylistic preference; it is a fundamental aspect of ergonomics. By allowing users to choose the orientation that feels most natural, the software avoids causing fatigue during extended interactions and ensures that the interface remains functional across a vast array of varying display sizes and aspect ratios.Ultimately, the success of mobile adaptations rests on the ability to preserve function while minimizing visual weight. Developers must avoid the trap of hiding too much, which creates a frustrating user journey, or showing too little, which compromises transparency. Finding this balance requires a disciplined design philosophy that treats every pixel as a valuable commodity. When software successfully reconciles the demands of mobile portability with the stringent requirements of fair play and clear communication, it provides a stable environment for participants. This ongoing refinement of interface engineering ensures that digital entertainment remains accessible and functional, regardless of the device hardware in use.

How Mobile Casino Games Adapt to Small ScreensAdapting digital casino software for portable devices involves a comprehensive reorganization of visual priorities. When transitioning from the generous dimensions of a desktop monitor to the limited confines of a smartphone, designers cannot simply scale down existing elements. Doing so would render buttons too small for accurate touch input and make crucial information difficult to read. Instead, the process demands a strategic reduction of on-screen clutter. Vital functions are often relocated into collapsible menus or simplified navigation drawers, ensuring that the primary action area remains clear. This approach allows users to focus on the core interaction, whether it is spinning a digital reel or evaluating a card hand, without the distraction of peripheral interface noise.Touch-based interactions represent the most significant functional shift in this environment. Unlike a mouse, which offers precise pointer placement, a finger tip covers a relatively large portion of the screen. Developers compensate for this by increasing the size of hit zones and implementing generous padding around interactive components. Haptic feedback or subtle visual animations frequently signal that a command has been registered, bridging the gap between tactile intent and digital execution. This creates a responsive environment where the user feels in control, even when the underlying interface has been significantly condensed to fit the mobile form factor.Transparency and consumer protection remain central to the integrity of these applications. Observers often analyze how software providers display critical metrics such as the return to player percentage or house edge on smaller panels. You might examine these technical foundations through a to understand how RNG, or random number generator, logic remains consistent regardless of the viewing medium. Despite the shift in hardware, the underlying mathematical framework is identical to that used on stationary terminals. Mobile versions do not alter the odds; they merely change the delivery mechanism. Auditing bodies require that this math remains visible and accessible, prompting designers to tuck information icons into corners or settings pages where they remain reachable without obstructing the main display. For additional context, glory casino can be considered alongside this overview.Managing the limited screen space also means rethinking how information is presented in real-time. On a desktop, a player might monitor a continuous feed of betting history or live updates alongside the game. On a mobile device, such elements are usually relegated to secondary screens or overlays that appear only when requested. This layering prevents the user from being overwhelmed. The design choice favors a clean primary view, utilizing pop-ups for critical notifications or status changes. By prioritizing the most urgent data, the experience remains grounded in a way that respects the constraints of a device meant for quick, intermittent use rather than sustained, stationary sessions.The reliance on vertical orientation versus horizontal landscape modes serves as another point of optimization. Many mobile games are now built with a responsive framework that detects how the device is held, automatically reconfiguring the UI. In landscape, buttons might shift to the sides to clear the central view, while a vertical orientation might stack controls at the bottom for easy one-handed access. This adaptability is not just a stylistic preference; it is a fundamental aspect of ergonomics. By allowing users to choose the orientation that feels most natural, the software avoids causing fatigue during extended interactions and ensures that the interface remains functional across a vast array of varying display sizes and aspect ratios.Ultimately, the success of mobile adaptations rests on the ability to preserve function while minimizing visual weight. Developers must avoid the trap of hiding too much, which creates a frustrating user journey, or showing too little, which compromises transparency. Finding this balance requires a disciplined design philosophy that treats every pixel as a valuable commodity. When software successfully reconciles the demands of mobile portability with the stringent requirements of fair play and clear communication, it provides a stable environment for participants. This ongoing refinement of interface engineering ensures that digital entertainment remains accessible and functional, regardless of the device hardware in use.</p Read More »

Message Us on WhatsApp