AngularJS
AngularJS | ||||
---|---|---|---|---|
![]() | ||||
Ontwikkelaar(s) | Brat Tech LLC, Google en collectief. | |||
Uitgebracht | 20 oktober 2010 (13 jaar geleden) | |||
Recentste versie | 1.8.3 [1] (2022-04-07) | |||
Status | Gestopt (2022-04-07) | |||
Besturingssysteem | Multiplatform | |||
Geschreven in | JavaScript | |||
Categorie | JavaScript-framework | |||
Licentie(s) | MIT-licentie | |||
Versiebeheer | Officiële broncode | |||
Website | (en) Projectpagina | |||
|
AngularJS, nieuwste versie heet Angular, is een open source webapplicatieframework dat wordt onderhouden door Google en een collectief van individuele ontwikkelaars en bedrijven die bezig zijn de mogelijkheden voor het ontwikkelen van Single Page Applications (SPA) te verbeteren. Het doel is het vereenvoudigen van zowel de ontwikkeling als het testen van dergelijke applicaties door het aanbieden van een framework voor client-side model-view-controller (MVC)-architectuur, samen met componenten die gewoonlijk worden gebruikt in rich internet applications.
Het framework werkt door eerst de HTML-pagina te lezen, waarin aanvullende specifieke HTML-attributen zijn opgenomen. Die attributen worden geïnterpreteerd als directieven (Engels: directives)[2] die ervoor zorgen dat Angular invoer- of uitvoercomponenten van de pagina koppelt aan een model dat wordt weergegeven door middel van standaard JavaScript-variabelen. De waarden van die JavaScript-variabelen kunnen worden ingesteld binnen de code, of worden opgehaald uit statische of dynamische JSON-dataobjecten.
Architectuur
Uitgangspunten bij het ontwerp
Angular is gebouwd op basis van de zienswijze dat declaratief programmeren behoort te worden gebruikt voor het bouwen van gebruikersinterfaces en het koppelen van softwarecomponenten, terwijl imperatief programmeren beter geschikt is voor het definiëren van bedrijfslogica.[3] Het framework gebruikt traditionele HTML en geeft hier een uitbreiding aan om dynamische inhoud (Engels: content) te presenteren door middel van data-koppeling in twee richtingen (Engels: two-way data-binding), die zorgt voor automatische synchronisatie van modellen en views. Het resultaat hiervan is dat Angular de noodzaak om het Document Object Model (DOM) te manipuleren vermindert, met het doel om de testbaarheid en het prestatievermogen (de performance) te verbeteren.
De ontwerpdoelstellingen van Angular omvatten:
- Ontkoppel manipulatie van het DOM van de applicatielogica. Dit verbetert de testbaarheid van de programmacode.
- Ga ervan uit dat het testen van de applicatie net zo belangrijk is als het ontwikkelen. De testbaarheid wordt sterk beïnvloed door de manier waarop de code gestructureerd is.
- Ontkoppel het client-deel van een applicatie van het server-deel. Hierdoor kunnen de ontwikkelwerkzaamheden parallel worden uitgevoerd en wordt hergebruik van de software aan beide kanten mogelijk.
- Bied een structuur voor het gehele proces van het bouwen van een applicatie: het ontwerpen van de gebruikersinterface, het schrijven van de bedrijfslogica en het testen.
Angular implementeert het model-view-controller-model ontwerppatroon om datamodel (model), datapresentatie (view) en applicatielogica (controller) van elkaar te scheiden. Door gebruik te maken van dependency injection brengt Angular services die traditioneel aan de server-side werden uitgevoerd, zoals view-afhankelijke controllers, naar de client-side van de webapplicatie. Het gevolg hiervan is dat een deel van de belasting van de server wordt weggenomen.
Opstarten (Engels: bootstrapping)
De taken die door de Angular bootstrapper[4] worden uitgevoerd, gebeuren in drie fasen nadat het DOM geladen is:
- laden van de methode, die is gekoppeld aan het ng-app-directief
- creatie van een nieuwe injector
- compilatie van de directieven die het dynamische deel van het DOM opbouwen
Data-koppeling in twee richtingen
Data-koppeling in twee richtingen is een van de meest opmerkelijke eigenschappen van Angular.[5] Deze faciliteit vermindert de hoeveelheid code doordat de backend-server niet meer verantwoordelijk is voor het invullen van templates. In plaats hiervan worden templates in gewoon HTML opgebouwd met gegevens die worden bewaard in een scope[6] die in het model is gedefinieerd. Een scope in Angular is een object dat verwijst naar het applicatiemodel. Het is een omgeving (Engels: context) waarbinnen expressies kunnen worden uitgevoerd. Scopes zijn georganiseerd in een hiërarchische structuur die de DOM-structuur van de applicatie nabootsen. De $scope
-service in Angular ontdekt wijzigingen in het model-gedeelte en werkt HTML-expressies in de view bij via een controller. Bovendien worden alle wijzigingen in de view weergegeven in het model. Hierdoor is het niet meer nodig om het DOM actief te manipuleren en dit stimuleert een snelle ontwikkeling van prototypen van webapplicaties[7]. Angular ontdekt wijzigingen in modellen door het vergelijken van waarden met eerder opgeslagen waarden in een proces dat dirty-checking wordt genoemd[8]. Dit in tegenstelling tot Ember.js en Backbone.js, die bij het wijzigen van waarden in het model gebruikmaken van listeners, software die reageert op bepaalde gebeurtenissen (Engels: events), zoals acties van een gebruiker.
Belangrijke directives
Angular-directives zijn markeringen op een DOM-element (zoals een attribuut, elementnaam, commentaar of CSS-klasse), die ervoor zorgen dat de HTML-compiler van Angular een bepaald gedrag aan dat DOM-element koppelt. Angular bevat een aantal ingebouwde directives, maar ontwikkelaars kunnen ook zelf maatwerkdirectives maken. Enkele van de meest gebruikte standaarddirectives zijn:
- ng-app
- declareert het root-element (het hoogste element in de structuur) van een Angular-applicatie, waaronder directives gebruikt kunnen worden om data-koppelingen te declareren en gedrag te definiëren.
- ng-bind
- stelt de tekst van een DOM-element in op de waarde van een expressie.
<span ng-bind="naam"></span>
zal bijvoorbeeld de waarde van de variabele 'naam' binnen het span-element laten zien. Alle veranderingen in de variabele ‘naam’ in de scope van de applicatie worden onmiddellijk in het DOM weergegeven. - ng-model
- vergelijkbaar met ng-bind, maar deze directive ontwikkelt een data-koppeling in twee richtingen tussen de view en de scope.
- ng-model-options
- maakt het mogelijk in te stellen hoe wijzigingen in het model worden aangebracht.
- ng-class
- maakt het mogelijk CSS-klasse-attributen dynamisch te koppelen aan een HTML-element. Dit gebeurt door middel van een data-koppeling van een expressie, die de toe te voegen CSS-klassen vertegenwoordigt.
- ng-controller
- koppelt een JavaScript-controller-klasse aan de view. Dit is een cruciaal onderdeel van de manier waarop Angular het model-view-controller ontwerppatroon implementeert. Controller-klassen bevatten de bedrijfslogica achter de applicatie, zij voorzien de scope van functies en waarden.
- ng-repeat
- instantieert een element eenmaal per item uit een verzameling.
- ng-show & ng-hide
- toont of verbergt een element op basis van een conditie, afhankelijk van de waarde van een boolean-expressie. Het tonen en verbergen gebeurt door het instellen van de CSS-presentatiestijl.
- ng-switch
- instantieert een template uit een verzameling keuzemogelijkheden op basis van een conditie, afhankelijk van de waarde van een expressie.
- ng-view
- de directive die verantwoordelijk is voor het behandelen van routes die worden aangegeven door URL's. Het definiëren van routes zorgt ervoor dat templates worden weergegeven, die worden aangestuurd door gespecificeerde controllers.
- ng-if
- deze directive zorgt voor het verwijderen of opnieuw tonen van een deel van het DOM, gebaseerd op een expressie die de waarde waar ('true') of onwaar ('false') kan aannemen. Wanneer de expressie onwaar is, wordt het element uit het DOM verwijderd. Wanneer de expressie waar is, wordt een exemplaar van het element (opnieuw) ingevoegd.
Chrome-plug-in
In juli 2012 bouwde het Angular-team een plug-in voor de Google Chrome-browser genaamd Batarang[9], die helpt bij het opsporen van fouten (debuggen) in webapplicaties die met Angular zijn gebouwd. Deze plug-in helpt om performance-problemen snel te ontdekken en hij bevat een grafische gebruikersinterface voor het debuggen van applicaties.[10] Er zijn problemen gemeld met Batarang in combinatie met recente Angular-releases (na v1.2.x).[11]
Ondersteuning van oudere browserversies
Angular Release 1.2 en later bieden geen ondersteuning voor Internet Explorer versies 6 of 7.[12] Met ingang van Angular Release 1.3 is de ondersteuning voor Internet Explorer 8 vervallen.[13]
Geschiedenis
Angular is oorspronkelijk ontwikkeld in 2009 door Miško Hevery en Adam Abrons[14] vanuit het bedrijf Brat Tech LLC[15] als de software achter een online JSON-opslagapparaat waarvan de prijs per megabyte zou worden bepaald, om eenvoudig te maken applicaties voor het bedrijf te kunnen ontwikkelen. Deze onderneming was gevestigd op webdomein 'GetAngular.com' en had enkele abonnees, voordat de twee besloten het bedrijfsmodel op te geven en Angular vrij te geven als opensource framework.
Abrons verliet het project, maar Hevery, die werkt bij Google, ging verder met de ontwikkeling en het onderhoud van het framework, samen met Google-werknemers Igor Minár en Vojta Jína.[16]
Angularjs-releases
Releases 1.0.x, 1.2.x, 1.3.x, 1.4.x en 1.5.x zijn de stabiele versies, terwijl 1.1.x in enkele subversies wijzigingen bevatte die eerder gemaakte software liet falen (ze bevatten 'breaking changes').
De codenamen zijn gerelateerd aan superhelden, ze bestaan uit twee door een koppelteken gescheiden woorden, die 'leuk / gek / gaaf' moeten klinken en openbaar worden vrijgegeven waarna gebruikers erop kunnen stemmen.[17]
Releasedatum | Versie | Codenaam |
---|---|---|
20 oktober 2010 | 0.9.0 | dragon-breath (instabiel) |
26 oktober 2010 | 0.9.1 | repulsion-field (instabiel) |
3 november 2010 | 0.9.2 | faunal-mimicry (instabiel) |
10 november 2010 | 0.9.3 | cold-resistance (stabiel) |
18 november 2010 | 0.9.4 | total-recall (instabiel) |
25 november 2010 | 0.9.5 | turkey-blast (stabiel) |
6 december 2010 | 0.9.6 | night-vision (instabiel) |
10 december 2010 | 0.9.7 | sonic-scream (instabiel) |
23 december 2010 | 0.9.8 | astral-projection (stabiel) |
13 januari 2011 | 0.9.9 | time-shift (instabiel) |
26 januari 2011 | 0.9.10 | flea-whisperer (stabiel) |
8 februari 2011 | 0.9.11 | snow-maker (instabiel) |
3 maart 2011 | 0.9.12 | thought-implanter (instabiel) |
13 maart 2011 | 0.9.13 | curdling-stare (instabiel) |
1 april 2011 | 0.9.14 | key-maker (stabiel) |
11 april 2011 | 0.9.15 | lethal-stutter (stabiel) |
7 juni 2011 | 0.9.16 | weather-control (instabiel) |
30 juni 2011 | 0.9.17 | vegetable-reanimation (instabiel) |
29 juli 2011 | 0.9.18 | jiggling-armfat (instabiel) |
20 augustus 2011 | 0.9.19 | canine-psychokinesis (instabiel) |
2 september 2011 | 0.10.0 | chicken-hands (instabiel) |
9 september 2011 | 0.10.1 | inexorable-juggernaut (instabiel) |
8 oktober 2011 | 0.10.2 | sneaky-seagull (instabiel) |
13 oktober 2011 | 0.10.3 | shattering-heartbeat (instabiel) |
22 oktober 2011 | 0.10.4 | human-torch (instabiel) |
8 november 2011 | 0.10.5 | steel-fist (stabiel) |
17 januari 2012 | 0.10.6 | bubblewrap-cape (instabiel) |
13 juni 2012 | 1.0.0 | temporal-domination (stabiel) |
25 juni 2012 | 1.0.1 | thorium-shielding (stabiel) |
31 augustus 2012 | 1.0.2 | debilitating-awesomeness (stabiel) |
31 augustus 2012 | 1.1.0 | increase-gravatas (stabiel) |
26 november 2012 | 1.0.3 | bouncy-thunder (stabiel) |
26 november 2012 | 1.1.1 | pathological-kerning (instabiel) |
22 januari 2013 | 1.0.4 | bewildering-hair (stabiel) |
22 januari 2013 | 1.1.2 | tofu-animation (instabiel) |
20 februari 2013 | 1.0.5 | flatulent-propulsion (stabiel) |
22 februari 2013 | 1.1.3 | radioactive-gargle (stabiel) |
3 april 2013 | 1.1.4 | quantum-manipulation (instabiel) |
4 april 2013 | 1.0.6 | universal-irreversibility (stabiel) |
22 mei 2013 | 1.0.7 | monochromatic-rainbow (stabiel) |
22 mei 2013 | 1.1.5 | triangle-squarification (instabiel) |
22 augustus 2013 | 1.0.8 | bubble-burst (stabiel) |
8 november 2013 | 1.2.0 | timely-delivery (stabiel) |
14 november 2013 | 1.2.1 | underscore-empathy (stabiel) |
22 november 2013 | 1.2.2 | consciousness-inertia (stabiel) |
27 november 2013 | 1.2.3 | unicorn-zapper (stabiel) |
6 december 2013 | 1.2.4 | wormhole-blaster (stabiel) |
13 december 2013 | 1.2.5 | singularity-expansion (stabiel) |
19 december 2013 | 1.2.6 | taco-salsafication (stabiel) |
3 januari 2014 | 1.2.7 | emoji-clairvoyance (stabiel) |
10 januari 2014 | 1.2.8 | interdimensional-cartography (stabiel) |
15 januari 2014 | 1.2.9 | enchanted-articulacy (stabiel) |
24 januari 2014 | 1.2.10 | augmented-serendipity (stabiel) |
3 februari 2014 | 1.2.11 | cryptocurrency-hyperdeflation (stabiel) |
7 februari 2014 | 1.2.12 | cauliflower-eradication (stabiel) |
14 februari 2014 | 1.2.13 | romantic-transclusion (stabiel) |
1 maart 2014 | 1.2.14 | feisty-cryokinesis (stabiel) |
21 maart 2014 | 1.2.15 | beer-underestimating (stabiel) |
3 april 2014 | 1.2.16 | badger-enumeration (stabiel) |
6 juni 2014 | 1.2.17 | quantum disentanglement (stabiel) |
13 juni 2014 | 1.2.18 | ear-extendability (stabiel) |
1 juli 2014 | 1.2.19 | precognitive-flashbacks (stabiel) |
11 juli 2014 | 1.2.20 | accidental-beautification (stabiel) |
25 juli 2014 | 1.2.21 | wizard-props (stabiel) |
12 augustus 2014 | 1.2.22 | finicky-pleasure (stabiel) |
22 augustus 2014 | 1.2.23 | superficial-malady (stabiel) |
9 september 2014 | 1.2.24 | static-levitation (stabiel) |
16 september 2014 | 1.2.25 | hypnotic-gesticulation (stabiel) |
1 oktober 2014 | 1.2.26 | captivating-disinterest (stabiel) |
13 oktober 2014 | 1.3.0 | superluminal-nudge (stabiel) |
31 oktober 2014 | 1.3.1 | spectral-lobster (stabiel) |
7 november 2014 | 1.3.2 | cardiovasculatory-magnification (stabiel) |
17 november 2014 | 1.3.3 | undersea-arithmetic (stabiel) |
20 november 2014 | 1.2.27 | prime-factorization (stabiel) |
24 november 2014 | 1.3.4 | highfalutin-petroglyph (stabiel) |
1 december 2014 | 1.3.5 | cybernetic-mercantilism (stabiel) |
8 december 2014 | 1.3.6 | robofunky-danceblaster (stabiel) |
15 december 2014 | 1.2.28 | finnish-disembarkation (stabiel) |
15 december 2014 | 1.3.7 | leaky-obstruction (stabiel) |
19 december 2014 | 1.3.8 | prophetic-narwhal (stabiel) |
29 september 2015 | 1.2.29 | ultimate-deprecation (stabiel) |
19 november 2015 | 1.4.8 | ice-manipulation (stabiel) |
21 januari 2016 | 1.4.9 | implicit-superannuation (stabiel) |
5 februari 2016 | 1.5.0 | ennoblement-facilitation (stabiel) |
15 juni 2016 | 1.5.7 | hexagonal-circumvolution (stabiel) |
22 juli 2016 | 1.5.8 | arbitrary-fallbacks (stabiel) |
24 november 2017 | 1.6.7 | imperial-backstroke (stabiel) |
18 december 2018 | 1.6.8 | beneficial-tincture (stabiel) |
2 februari 2018 | 1.6.9 | fiery-basilisk (stabiel) |
17 april 2018 | 1.6.10 | crystalline-persuasion (stabiel) |
11 mei 2018 | 1.7.0 | nonexistent-physiology (stabiel) |
8 juni 2018 | 1.7.1 | momentum-defiance (stabiel) |
12 juni 2018 | 1.7.2 | extreme-compatiplication (stabiel) |
3 augustus 2018 | 1.7.3 | eventful-proposal (stabiel) |
7 september 2018 | 1.7.4 | interstellar-exploration (stabiel) |
4 oktober 2018 | 1.7.5 | anti-prettification (stabiel) |
17 januari 2019 | 1.7.6 | gravity-manipulation (stabiel) |
4 februari 2019 | 1.7.7 | kingly-exiting (stabiel) |
11 maart 2019 | 1.7.8 | enthusiastic-oblation (stabiel) |
19 november 2019 | 1.7.9 | pollution-eradication(stabiel) |
1 juni 2020 | 1.8.0 | nested-vaccination (stabiel) |
30 september 2020 | 1.8.1 | mutually-supporting(stabiel) |
21 oktober | 1.8.2 | meteoric-mining (stabiel) |
Toekomstige ontwikkelingen
Parallel wordt gewerkt aan drie nieuwe releases van Angular:
- Release 1.x.x die verder bouwt op de huidige versie. Deze tak wordt AngularJS genoemd.
- Release 2.0 is bedoeld om een groot aantal verbeterpunten te realiseren en tevens om Angular aanzienlijk sneller en eenvoudiger te maken met een aanpak die niet haalbaar is middels incrementele stappen op basis van de 1.x-releases.[18]
- Angular 4 werd op 13 december 2016 aangekondigd, versie 3 wordt overgeslagen om verwarring te vermijden met een NPM-package verspreid onder de naam v3.3.0.[19] Versie 4 is backwards compatible met Angular 2.
Vergelijking met Backbone.js
- Data-koppeling
- De meest opvallende eigenschap die de frameworks Angular en Backbone.js onderscheidt, is de manier waarop modellen en views gesynchroniseerd worden. Terwijl Angular data-koppeling in twee richtingen ondersteunt, is Backbone.js sterk afhankelijk van gedupliceerde code (Engels: boilerplate code) om zijn modellen en views op een lijn te brengen.[20]
- REST
- Backbone.js communiceert goed met RESTful services in de backend. Ook met Angular is toepassing van REST-API's eenvoudig mogelijk door gebruik te maken van de $resource-service. Angular beschikt bovendien over een $http-service die flexibeler is en koppelingen met servers op afstand mogelijk maakt, door middel van een XMLHttpRequest-object van de browser of via JSONP-code.
- Templates
- Angulars mogelijkheden om templates toe te passen maken gebruik van een combinatie van aanpasbare HTML-tags en expressies. Backbone.js wordt geleverd met de template()-functie van Underscore.js en integreert ook met andere templating-software, zoals Mustache.
Literatuur
- (en) Green, Brad, Shyam Seshadri (april 2013). AngularJS. O'Reilly Media, blz. 196,. ISBN 978-1-4493-4485-6.
- (en) Kozlowski, Pawel, Peter Darwin (april 2013). Mastering Web Application Development with AngularJS. Packt Publishing Limited, blz. 372,. ISBN 978-1-7821-6182-0.
- (en) Ford, Brian, Lukas Ruebbelke (april 2015 (geplande datum)). AngularJS in Action. Manning Publications, blz. 325,. ISBN 978-1-6172-9133-3.
Zie ook
- Client-servermodel
- HTML-scripting
- JavaScript
- Rich internet application
- Server-side scripting
- Webdevelopment
Externe links
- (en) AngularJS-projectpagina
- (en) ng-conf - Angular-conferentie in VS
- (en) ng-europe - Angular-conferentie in Europa (gearchiveerd)
- (en) Bibliotheek met AngularJS-modules (gearchiveerd)
- (en) Applicaties die zijn gebouwd met AngularJS (gearchiveerd)
- (en) AngularJS op Google Groups
- (en) AngularJS op Google+ (gearchiveerd)
- (en) Batarang Chrome-plug-in op Github
- (en) NG-CONF 2014 Video's en slides (gearchiveerd)
- (en) NG-EUROPE 2014 Video's en slides (gearchiveerd)
- (en) AngularSpot, collectief van AngularJS-ontwikkelaars (gearchiveerd)
- (en) Vergelijking van applicatie-frameworks die m.b.v. AngularJS zijn gebouwd (gearchiveerd)
- (en) Videotrainingen voor AngularJS
- (en) Blog van AngularJS-ontwikkelaars
Dit artikel of een eerdere versie ervan is een (gedeeltelijke) vertaling van het artikel AngularJS op de Engelstalige Wikipedia, dat onder de licentie Creative Commons Naamsvermelding/Gelijk delen valt. Zie de bewerkingsgeschiedenis aldaar.
- ↑ jelbourn, 1.8.3 ultimate-farewell (2022-04-07). Angular (7 april 2022). Geraadpleegd op 14 maart 2023.
- ↑ Angular directives. Gearchiveerd op 29 december 2014. Geraadpleegd op 27 december 2014.
- ↑ What Is Angular?. Gearchiveerd op 2 september 2014. Geraadpleegd op 27 december 2014.
- ↑ Angular Bootstrap. Gearchiveerd op 3 januari 2015. Geraadpleegd op 27 december 2014.
- ↑ AngularJS Developer Guide - Data Binding. Gearchiveerd op 3 januari 2015. Geraadpleegd op 1 januari 2015.
- ↑ AngularJS Developer Guide - Scopes. Gearchiveerd op 15 oktober 2021. Geraadpleegd op 2015.
- ↑ 5 Awesome AngularJS Features. Gearchiveerd op 8 januari 2014. Geraadpleegd op 27 december 2014.
- ↑ Miško Hevery, Databinding in angularjs. Geraadpleegd op 27 december 2014.
- ↑ Brian Ford, angular/angularjs-batarang (GitHub). Gearchiveerd op 10 februari 2015. Geraadpleegd op 27 december 2014.
- ↑ Introducing the AngularJS Batarang. Gearchiveerd op 8 december 2014. Geraadpleegd op 27 december 2014.
- ↑ Batarang Chrome extension for AngularJS appears broken. Gearchiveerd op 2 januari 2015. Geraadpleegd op 27 december 2014.
- ↑ AngularJS: Developer Guide: Internet Explorer Compatibility. Gearchiveerd op 17 december 2014. Geraadpleegd op 27 december 2014.
- ↑ AngularJS 1.3: a new release approaches. Gearchiveerd op 8 december 2014. Geraadpleegd op 27 december 2014.
- ↑ 'Hello World, <angular/> is here'. Gearchiveerd op 20 februari 2015. Geraadpleegd op 27 december 2014.
- ↑ GetAngular. Gearchiveerd op 13 april 2010. Geraadpleegd op 27 december 2014.
- ↑ Contributors to angular/angular.js (GitHub). Gearchiveerd op 11 januari 2015. Geraadpleegd op 27 december 2014.
- ↑ AngularJS Code Names - Google Moderator. Gearchiveerd op 24 augustus 2015. Geraadpleegd op 27 december 2014.
- ↑ From 1.3 to 2.0: Angular's Next Step. Gearchiveerd op 3 januari 2015. Geraadpleegd op 1 januari 2015.
- ↑ Ok... let me explain: it's going to be Angular 4.0. angularjs.blogspot.kr. Gearchiveerd op 22 december 2016. Geraadpleegd op 14 december 2016.
- ↑ Backbonejs vs Angularjs: Demystifying the myths. Gearchiveerd op 30 december 2012. Geraadpleegd op 27 december 2014.
![](http://upload.wikimedia.org/wikipedia/commons/thumb/4/4a/Commons-logo.svg/25px-Commons-logo.svg.png)