Linguaggio per la modellazione e presentazione web di eventi turistici a tappe. Attività...
-
Upload
simone-costantino -
Category
Documents
-
view
213 -
download
0
Transcript of Linguaggio per la modellazione e presentazione web di eventi turistici a tappe. Attività...
Linguaggio per la modellazione e presentazione web di eventi turistici a tappe.
Attività progettuale per il corso diLinguaggi e Modelli Computazionali M
Professore: Studente:Enrico Denti Thomas Ricci
Scopo del Progetto1. Sviluppo di un linguaggio semplice e intuitivo ma allo
stesso flessibile e completo per la modellazione di un itinerario turistico riguardante un “evento a tappe”, al fine di automatizzare la generazione di una presentazione dell’itinerario con tecnologie Web 2.0:
2. Migliorare l’esperienza di navigazione degli utenti web fornendo contenuti interattivi di qualità per la presentazione di un evento (piuttosto che semplici contenuti testuali).
Caratteristiche del linguaggio• 3 tipologie di “evento a tappe”:
1. RACE: Manifestazioni sportive su strada senza punti di sosta (gare ciclistiche, rally automobilistici,…).
2. TOUR: Itinerari culturali/enogastronomici che prevedono punti di sosta con eventuale visita.
3. SAIL-RACE: Regate.
• Il linguaggio consente di definire le informazioni generali sull’evento:
▫ Periodo evento▫ Descrizione evento▫ Elenco delle tappe previste
• … e quelle specifiche in base alla tipologia, come ad esempio: ▫ Statistiche di gara nel caso di eventi sportive.▫ Informazioni culturali e contatti nel caso di itinerari per eventi culturali.
La Grammatica• TOKEN:
A_GR : '{' ;C_GR : '}' ;
fragment DIGIT : ( '0'..'9');
INT : DIGIT+;FLOAT : DIGIT+ '.' DIGIT+;
DATE : DIGIT DIGIT '/' DIGIT DIGIT '/' (DIGIT DIGIT | DIGIT DIGIT DIGIT DIGIT);
ORARIO : DIGIT DIGIT ':' DIGIT DIGIT;
STRING: '"' ( ESC_SEQ | ~('\\'|'"') )* '"';
fragment HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ;fragment ESC_SEQ : '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\') | UNICODE_ESC | OCTAL_ESC;fragment OCTAL_ESC: '\\' ('0'..'3') ('0'..'7') ('0'..'7‘)| '\\' ('0'..'7') ('0'..'7')| '\\' ('0'..'7');fragment UNICODE_ESC : '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT;
WS : ( ‘ ‘ | ‘\t’ | ‘\r‘ | ‘\n‘ ) {$channel=HIDDEN;};
La Grammatica• TOKEN:
EVENT='event'; TOUR='tour'; RACE='race'; SAIL='sail'; BOA='boa'; DEST='dest'; STAGE='stage'; LAP='lap'; DEP='departure'; ARR='arrival'; DISLIV='disliv'; KM='km'; KM_TOT='km_tot'; MI='mi'; PEND_PRC='pend_%'; PEND_MAX='pend_max'; ALT='alt';
TEL='tel'; EMAIL='email'; WEB='website'; RIST='restaurant';MED='firstAid'; MEC='mechanic';GAS='gas'; INFO='info'; DATA='data'; TIME='h'; BIKE='bike'; CAR='car'; IMG='img'; COORD='coordinates'; LNG='lng'; LAT='lat';ADDR='addr';
La GrammaticaG = <VT, VN, P, S>• PRODUZIONI:
s ::= <EVENT> <STRING> <A_GR> description period ( race| tour | sail_race ) <C_GR>
Lo scopo della grammatica è il simbolo non terminale s e la relativa produzione prevede che un evento inizi con la keyword “event” seguita da:
• Nome evento• Descrizione dell’evento
description ::= <INFO> <STRING>• Periodo evento
period ::= <DATA> (<DATE> | “da” <DATE> “a” <DATE>)
• Tipologia di evento…
Esempio:event “Giro d’Italia 2011”{
info “…descrizione dell’evento…”
data da 20/05/11 a 22/05/11
[…tipo evento: tour|race|sail_race…]}
La Grammatica: Race race ::= <RACE> <A_GR> ( stage| poi )+ <C_GR>
Una race rappresenta una manifestazione sportiva a tappe che non prevede punti di sosta lungo il percorso ma solo:
• Tratti di gara
stage ::= <STAGE> (“by” (<BIKE> | <CAR>))? <STRING> <A_GR> partenza (indirizzo)* arrivo (period)? (km_tot)?
( pend_prc )? ( pend_max )? ( disliv )? description <C_GR>
• Points of Interests (non necessariamente sul percorso)
poi ::= (<RIST>|<MED>|<MEC>|<GAS>) <STRING><A_GR> <Indirizzo> (contatti )? <C_GR>
La Grammatica: Race• Esempio:
race { stage by bike "Cesenatico - Polenta“
{ departure "Portocanale di Cesenatico“ {
addr "via Cesenatico 10, Cesenatico" h 05:00
img “http://www.cesenaticoholidays.com/images/eventi/noveColli/partenza_noveColli.jpg“
} addr "Via San Pellegrino 5, Cesenatico“ addr "Via Collinello, Bertinoro" arrival "Polenta“ {
addr "via Polenta 477, Polenta, Bertinoro“ km 37 alt 287
} data 20/05/10 km_tot 34 pend_% 3.06 pend_max 13 disliv 284 info "Dopo essersi lasciati alle spalle il mare di Cesenatico,...“
} firstAid "Ospedale Bufalini" { addr "viale Ghirotti 286, Cesena" tel 0547352111 website "www.ausl-
cesena.emr.it"}}
stage ::= <STAGE> (“by” (<BIKE> | <CAR>))? <STRING> <A_GR> partenza (indirizzo)* arrivo (period)? (km_tot)? ( pend_prc )? ( pend_max )? ( disliv )? description <C_GR>km_tot ::= <KM_TOT> (<INT>|<FLOAT>)alt ::= <ALT> (<FLOAT>|<INT>) disliv ::= <DISLIV> (<FLOAT>|<INT>)pend_prc ::= <PEND_PRC> <FLOAT>pend_max ::= <PEND_MAX> <INT>
partenza ::= <DEP> <STRING> <A_GR> (indirizzo | coordinates) (km)? (alt)? (time)? ( img )? <C_GR>
arrivo ::= <ARR> <STRING> <A_GR> (indirizzo | coordinates) (km)? (alt)? (time)? ( img )? <C_GR>
poi ::= (<RIST>|<MED>|<MEC>|<GAS>) <STRING> <A_GR> indirizzo ( contatti )? <C_GR>contatti ::= (tel | email| web)+tel ::= <TEL> <INT>email ::= <EMAIL> <STRING>web ::= <WEB> <STRING>indirizzo ::= <ADDR> <STRING>
La Grammatica: Tour tour ::= <TOUR> <A_GR> ( destination | stage | poi )+ <C_GR>
Un tour rappresenta un evento con eventuali mete da visitare lungo il percorso (esempi: tour culturali/enogastronomici, raduni d’auto d’epoca, …).
Un tour prevede la possibilità di definire:
• Punti di sosta di rilevanza turistica.destination ::= <DEST> <STRING> <A_GR> indirizzo (km)? (contatti)? (period)?
description> (<img>)? <C_GR>
• Percorsi per raggiungere le destinazioni / eventuali tratti di gara (es. raduni auto d’epoca).stage ::= <STAGE> (“by” (<BIKE> | <CAR>))? <STRING> <A_GR> partenza
(indirizzo)* arrivo (period)? (km_tot)? ( pend_prc )? ( pend_max )? ( disliv )? description <C_GR>
• Points of Interests (non necessariamente sul percorso)poi ::= (<RIST>|<MED>|<MEC>|<GAS>) <STRING> <A_GR> <Indirizzo>
(contatti )? <C_GR>
• Esempio:
tour {dest “Museo della Marineria di Cesenatico”
{ addr "via Cesenatico 10, Cesenatico"
km 10tel 0547 80375date 31/10/10info “museo allestito sul portocanale di Cesenatico…“img “http://www.cesenatico.it/img/museo.jpg”
}gas “Distributore ESSO“ { addr “Statale Adriatica, Tagliata di Cervia"
tel 054433390}…
}
poi ::= (<RIST>|<MED>|<MEC>|<GAS>) <STRING> <A_GR> indirizzo ( contatti )? <C_GR>
destination ::= <DEST> <STRING> <A_GR> indirizzo (km)? (contatti)? (period)? description (<img>)? <C_GR>
La Grammatica: Tour
description ::= <INFO> <STRING>img ::= <IMG> <STRING>contatti ::= (tel | email| web)+tel ::= <TEL> <INT>email ::= <EMAIL><STRING>web ::= <WEB> <STRING>km ::= <KM> (<FLOAT>|<INT>)
La Grammatica: Sail Race sail_race ::= <SAIL> <A_GR> ( lap | poi )+ <C_GR>
Una sail race rappresenta una regata ed è costituita da una serie di:
• Rotte della regata:
lap ::= <LAP> <STRING> <A_GR> partenza ( coordinates | boa )+ arrivo ( description )? <C_GR>
• Points of Interests (non necessariamente sul percorso)
poi ::= (<RIST>|<MED>|<MEC>|<GAS>) <STRING> <A_GR> <Indirizzo> (contatti )? <C_GR>
La Grammatica: Sail Race
sail{ lap "Tappa Cesenatico-Cervia“ { departure "Congrega Velisti Cesenatico" { coordinates { lat 44.210821 lng
12.395849 } } coordinates { lat 44.226707 lng 12.424579 } boa { coordinates { lat 44.229414 lng 12.431617 } } coordinates { lat 44.266745 lng 12.378703 } coordinates { lat 44.269745 lng 12.368703 } arrival "Portocanale di Cervia“ { coordinates { lat 44.267533 lng 12.356687 } } info "La prima tappa della regata prevede il raggiungimento del portocanale di Cervia." } restaurant “Ristorante da Urbano" { addr "via Lungomare Ponente 1, Cesenatico" tel 0547352111 } }
lap ::= <LAP> <STRING> <A_GR> partenza ( coordinates | boa )+ arrivo ( description )? <C_GR>partenza ::= <DEP> <STRING> <A_GR> (indirizzo | coordinates) (km)? (alt)? (time)? ( img )? <C_GR>arrivo ::= <ARR> <STRING> <A_GR> (indirizzo | coordinates) (km)? (alt)? (time)? ( img )? <C_GR>
boa ::= <BOA> <A_GR> coordinates ( miles )? <C_GR>coordinates ::= <COORD> <A_GR> lat lng <C_GR>lat ::= <LAT> <FLOAT>lng ::= <LNG> <FLOAT>miles ::= <MI> (<FLOAT>|<INT>)
coordinates ::= <COORD> <A_GR> lat lng <C_GR>lat ::= <LAT> <FLOAT>lng ::= <LNG> <FLOAT>
Per la costruzione del percorso della regata tramite coordinate (semplici punti intermedi) e boe.
• Esempio:
La GrammaticaG = <VT, VN, P, S>
• PRODUZIONI:
s ::= <EVENT> <STRING> <A_GR> description period ( tour | race | sail_race ) <C_GR>
tour ::= <TOUR> <A_GR> ( destination | stage | poi )+ <C_GR>race ::= <RACE> <A_GR> ( stage| poi )+ <C_GR>sail_race ::= <SAIL> <A_GR> ( lap | poi )+ <C_GR>destination ::= <DEST> <STRING> <A_GR> indirizzo (km)? (contatti)? (period)?
description> (<Img>)? <C_GR>stage ::= <STAGE> (“by” (<BIKE> | <CAR>))? <STRING> <A_GR> partenza
(indirizzo)* arrivo (period)? (km_tot)? ( pend_prc )? ( pend_max )? ( disliv )? description <C_GR>
lap ::= <LAP> <STRING> <A_GR> partenza ( coordinates | boa )+ arrivo (description)? <C_GR>
partenza ::= <DEP> <STRING> <A_GR> (indirizzo | coordinates) (km)? (alt)? (time)? (img )? <C_GR>
arrivo ::= <ARR> <STRING> <A_GR> (indirizzo | coordinates) (km)? (alt)? (time)? (img )? <C_GR>
poi ::= (<RIST>|<MED>|<MEC>|<GAS>) <STRING> <A_GR> <Indirizzo> (contatti)? <C_GR>
boa ::= <BOA> <A_GR> coordinates ( miles )? <C_GR>
La Grammaticadescription ::= <INFO> <STRING>indirizzo ::= <ADDR> <STRING>period ::= <DATA> (<DATE> | “da” <DATE> “a” <DATE>)time ::= <TIME> <ORARIO>coordinates ::= <COORD> <A_GR> lat lng <C_GR>lat ::= <LAT> <FLOAT>lng ::= <LNG> <FLOAT>miles ::= <MI> (<FLOAT>|<INT>)km ::= <KM> (<FLOAT>|<INT>)km_tot ::= <KM_TOT> (<INT>|<FLOAT>)alt ::= <ALT> (<FLOAT>|<INT>) disliv ::= <DISLIV> (<FLOAT>|<INT>)pend_prc ::= <PEND_PRC> <FLOAT>pend_max ::= <PEND_MAX> <INT>img ::= <IMG> <STRING>contatti ::= (tel | email| web)+tel ::= <TEL> <INT>email ::= <EMAIL> <STRING>web ::= <WEB> <STRING>
Analisi della Grammatica• La grammatica è di tipo 2 (context free) secondo la
classificazione di Chomsky in quanto le produzioni sono vincolate alla forma:
• … tuttavia non sono presenti produzioni con self-embedding
• … pertanto il linguaggio è regolare (tipo 3)
A → α con α є (VT U VN)* ed A є VN
A → α1 A α2con A є VN e α1, α2 є (VN U VT)+
Analisi della Grammatica• La grammatica è LL(1)?
• Una grammatica context-free è LL(1) se per ogni metasimbolo che compare nella parte sinistra di più produzioni alternative, i DIRECTOR SYMBOLS relativi a tali produzioni sono disgiunti.
Grammatica è LL(1)
grammatica LL(1) è caratterizzata dalla possibilità di analizzare la frasi Left to right applicando la Left-most derivation utilizzando al più 1 simbolo della frase per scegliere con certezza la produzione opportuna per la riscrittura.
SS(α) se α non genera mai ε-rules DS(A → α) SS(α) U FOLLOW(A) se α può generare ε-rules
Strumenti Utilizzati Linguaggio di programmazione:
C# IDE di sviluppo:
Visual Studio 2010 Piattaforma web:
ASP .Net 4.0
Strumento per generazione automatica di Lexer e Parser: ANTLR 3.0
Strumenti di supporto per la valutazione del linguaggio: Web Services:
Google Geocoding API Google Directions API
Architettura: Package• Il progetto è stato implementato con una Class Library,
EventiATappeLib.dll, che verrà poi utilizzata all’interno di una applicazione web ASP.Net per generare contenuti.
Architettura: Nodi AST• Package AST: alcuni nodi…
class Domain Mo...
AST::Arriv alNode
+ Accept(Visitors.IEventoVisitor) : void+ ArrivalNode(IToken)
«property»+ Altitudine() : string+ Coordinate() : string+ ImageUrl() : string+ Indirizzo() : string+ Km() : string+ Nome() : string+ Orario() : string
CommonTree
AST::ASTNode
+ Accept(EventiATappeLib.Visitors.IEventoVisitor) : void+ ASTNode(IToken)
AST::DepartureNode
+ Accept(Visitors.IEventoVisitor) : void+ DepartureNode(IToken)
«property»+ Altitudine() : string+ Coordinate() : string+ ImageUrl() : string+ Indirizzo() : string+ Km() : string+ Nome() : string+ Orario() : string
AST::Ev entoNode
+ Accept(IEventoVisitor) : void+ EventoNode(IToken)
«property»+ Descrizione() : string+ Nome() : string+ Periodo() : string
AST::FirstAidNode
+ Accept(Visitors.IEventoVisitor) : void+ FirstAidNode(IToken)
AST::GasNode
+ Accept(Visitors.IEventoVisitor) : void+ GasNode(IToken)
AST::LapNode
+ Accept(Visitors.IEventoVisitor) : void+ LapNode(IToken)
«property»+ CoordinateArrivo() : string+ CoordinatePartenza() : string+ Descrizione() : string+ Nome() : string+ PuntiIntermedi() : IList<string>
AST::MechanicNode
+ Accept(Visitors.IEventoVisitor) : void+ MechanicNode(IToken)
AST::PoiNode
+ Accept(Visitors.IEventoVisitor) : void+ PoiNode(IToken)
«property»+ Contatti() : string+ Indirizzo() : string+ Nome() : string
AST::RestaurantNode
+ Accept(Visitors.IEventoVisitor) : void+ RestaurantNode(IToken)
AST::StageNode
+ Accept(Visitors.IEventoVisitor) : void+ StageNode(IToken)
«property»+ ByBike() : bool+ Descrizione() : string+ Dislivello() : string+ IndirizzoArrivo() : string+ IndirizzoPartenza() : string+ KmTappa() : string+ Nome() : string+ PendenzaMax() : string+ PendenzaPercentuale() : string+ Periodo() : string+ PuntiIntermedi() : IList<string>
• Antlr 3.0 non implementa più Pattern Visitor per la valutazione dell’AST…• Estensione della classe CommonTree che rappresenta il generico nodo dell’AST
Architettura del Sistema class C...
System.Web.UI.Page
cms_Ev entiATappe_Default
- _htmlVisitor: HtmlVisitor- _jsonVisitor: JsonVisitor- _kmlVisitor: KmlVisitor- _lex: EventiATappeLexer- _parser: EventiATappeParser
+ EvalHtml(string, string, string) : string+ EvalJson(string, string, string) : string+ EvalKml(string, string, string) : string+ GetEventiFiles() : string+ GetFileContent(string) : string# Page_Load(object, EventArgs) : void+ Parse(string) : string+ Parse(string, string*) : EventiATappeLib.AST.EventoNode+ SaveFile(string, string) : string
Visitors::HtmlVisitor
- _fineEvento: DateTime- _htmlWriter: TextWriter- _inizioEvento: DateTime- count: int
+ HtmlVisitor(string, string)
«property»+ AltitudiniLocalità() : Dictionary<string, float>+ DateEvento() : IList<DateTime>+ IsRace() : bool+ MenuTappeHtml() : List<string>+ PendenzeMax() : Dictionary<string, int>+ PendenzePrc() : Dictionary<string, float>
«interface»Visitors::IEv entoVisitor
+ Visit(AST.EventoNode) : void+ Visit(AST.DescriptionNode) : void+ Visit(AST.AddressNode) : void+ Visit(AST.TourNode) : void+ Visit(AST.RaceNode) : void+ Visit(AST.DestinationNode) : void+ Visit(AST.StageNode) : void+ Visit(AST.DepartureNode) : void+ Visit(AST.ArrivalNode) : void+ Visit(AST.DateNode) : void+ Visit(AST.TimeNode) : void+ Visit(AST.KmNode) : void+ Visit(AST.DislivelloNode) : void+ Visit(AST.AltitudeNode) : void+ Visit(AST.PendPrcNode) : void+ Visit(AST.PendMaxNode) : void+ Visit(AST.LngNode) : void+ Visit(AST.LatNode) : void+ Visit(AST.WebSiteNode) : void+ Visit(AST.EmailNode) : void+ Visit(AST.PhoneNode) : void+ Visit(AST.TextNode) : void+ Visit(AST.KmTotNode) : void+ Visit(AST.PeriodNode) : void+ Visit(AST.RestaurantNode) : void+ Visit(AST.FirstAidNode) : void+ Visit(AST.MechanicNode) : void+ Visit(AST.GasNode) : void+ Visit(AST.ByBikeNode) : void+ Visit(AST.PoiNode) : void+ Visit(AST.ImageNode) : void+ Visit(AST.MilesNode) : void+ Visit(AST.BoaNode) : void+ Visit(AST.LapNode) : void+ Visit(AST.SailNode) : void+ Visit(AST.CoordinatesNode) : void
Visitors::JsonVisitor
- _fineEvento: DateTime- _jsonWriter: JsonTextWriter
+ JsonVisitor(string, string)
«property»- DateEvento() : IList<DateTime>+ FileName() : string
Visitors::KmlVisitor
- _fineEvento: DateTime- _kmlWriter: XmlTextWriter
+ KmlVisitor(string, string)
«property»- DateEvento() : IList<DateTime>- FileName() : string
Lexer
Grammar::Ev entiATappeLexer
+ EventiATappeLexer()+ EventiATappeLexer(ICharStream)+ EventiATappeLexer(ICharStream, RecognizerSharedState)
Parser
Grammar::Ev entiATappeParser
+ alt() : EventiATappeParser.alt_return+ arrivo() : EventiATappeParser.arrivo_return+ boa() : EventiATappeParser.boa_return+ contatti() : EventiATappeParser.contatti_return+ coordinates() : EventiATappeParser.coordinates_return+ description() : EventiATappeParser.description_return+ destination() : EventiATappeParser.destination_return+ disliv() : EventiATappeParser.disliv_return+ email() : EventiATappeParser.email_return+ EventiATappeParser(ITokenStream)+ EventiATappeParser(ITokenStream, RecognizerSharedState)+ img() : EventiATappeParser.img_return+ indirizzo() : EventiATappeParser.indirizzo_return+ km() : EventiATappeParser.km_return+ km_tot() : EventiATappeParser.km_tot_return+ lap() : EventiATappeParser.lap_return+ lat() : EventiATappeParser.lat_return+ lng() : EventiATappeParser.lng_return+ miles() : EventiATappeParser.miles_return+ partenza() : EventiATappeParser.partenza_return+ pend_max() : EventiATappeParser.pend_max_return+ pend_prc() : EventiATappeParser.pend_prc_return+ period() : EventiATappeParser.period_return+ poi() : EventiATappeParser.poi_return+ race() : EventiATappeParser.race_return+ s() : EventiATappeParser.s_return+ sail_race() : EventiATappeParser.sail_race_return+ stage() : EventiATappeParser.stage_return+ tel() : EventiATappeParser.tel_return+ time() : EventiATappeParser.time_return+ tour() : EventiATappeParser.tour_return+ type() : EventiATappeParser.type_return+ web() : EventiATappeParser.web_return
«property»+ GrammarFileName() : string
+_htmlVisitor
+_jsonVisitor
+_kmlVisitor
+_lex
+_parser
Editor Web del linguaggio
Funzionamento del Sistema
LEXER
PARSER
AST
Tokens
Valutazioni
AST
KmlVisitor
JsonVisitor
HtmlVisitor
Keyhole Markup Language XML based e condivide parte della grammatica di GML dell’Open Geospatial Consortium (standard ISO). Linguaggio proprietario di Google per la definizione di mappe interattive utilizzate in Google Maps e Google Earth.
JavaScript Object NotationLinguaggio standard IETF per la definizione di oggetti JavaScript. l'interprete JavaScript è in grado di eseguire il parsing di una stringa Json tramite una semplice chiamata alla funzione eval() che restituisce l’oggetto JavaScript rappresentato.Molto utilizzato in ambito Web con teconologia Ajax per lo scambio di dati al posto di XML perché più leggero.
Verifica Semantica delle frasi• Errori lessicali e sintattici vengono rilevati
direttamente da Lexer e Parser tramite le eccezionipredefinite di Antlr.
• Errori semantici gestiti:▫ Verifica correttezza date e orari.
▫ Verifica esistenza indirizzo richiesto a Google Geocoding
▫ Verifica correttezza sintattica URL immagine
▫ Verifica correttezza sintattica indirizzi email
Collaudo• Per il collaudo sono stati realizzati alcuni esempi delle tre
tipologie di evento… tra cui un evento ciclistico reale!
• I contenuti web della Nove Colli 2011 ad un mese dalla pubblicazione, hanno avuto un notevole successo:
▫ Apprezzamento degli utenti web che hanno manifestato un grande interesse per l’evento in termini di visite alla pagina e richieste di prenotazione nel periodo dell’evento.
Sviluppi futuri• Limiti:
▫ Contenuti attualmente presentati prevalentemente testuali… manca la possibilità di introdurre video e photogallery dell’evento.
• Sviluppi Futuri:
▫ Estensioni del linguaggio per integrare informazioni sull’evento:
Mash-up con Wikipedia per integrare informazioni turistiche. Aggiunta contenuti multimediali da Youtube e Flickr
▫ Potenziamento sezione gestionale nel CMS al fine di affiancare all’attuale editor del linguaggio un wizard per l’inserzione nuovi eventi che generi in modo trasparente all’utente le frasi del linguaggio.