interoperable ajax tools and mashups - techtarget, where serious

62
Interoperable Ajax Tools and Mashups Jon Ferraiolo IBM and OpenAjax Alliance September 30, 2008

Upload: others

Post on 03-Feb-2022

5 views

Category:

Documents


0 download

TRANSCRIPT

Interoperable Ajax Tools and Mashups

Jon FerraioloIBM and OpenAjax AllianceSeptember 30, 2008

Interoperable Ajax Tools and Mashups 2

Agenda

Introducing OpenAjax Alliance

Ajax IDEs

OpenAjax Metadata (for Ajax Libraries)

Mashups

OpenAjax Hub 1.1

OpenAjax Metadata (for Widgets)

Summary

Introducing OpenAjax Alliance

Ajax IDEs

OpenAjax Metadata (for Ajax Libraries)

Mashups

OpenAjax Hub 1.1

OpenAjax Metadata (for Widgets)

Summary

Interoperable Ajax Tools and Mashups 33

The Ajax explosion (2005-2007)

Huge amount of hype

~200 Ajax toolkits appear almost instantlyMicrosoft Atlas (now called ASP.NET AJAX)

• Helps contribute to legitimacy

Several other major “proprietary” Ajax frameworks• Adobe/Spry, Backbase, ICEsoft, Nexaweb, Sun/jMaki, TIBCO, …

Several major open source projects• Prototype/Scriptaculous, Dojo, Yahoo, DWR, Google GWT, jQuery,…

Why so many so quickly? Simply rebrand DHTML to Ajax

Huge amount of hype

~200 Ajax toolkits appear almost instantlyMicrosoft Atlas (now called ASP.NET AJAX)

• Helps contribute to legitimacy

Several other major “proprietary” Ajax frameworks• Adobe/Spry, Backbase, ICEsoft, Nexaweb, Sun/jMaki, TIBCO, …

Several major open source projects• Prototype/Scriptaculous, Dojo, Yahoo, DWR, Google GWT, jQuery,…

Why so many so quickly? Simply rebrand DHTML to Ajax

Interoperable Ajax Tools and Mashups 44

Why OpenAjax Alliance?

A rich but fragile ecosystemInteroperability shortcomingsEducational/marketing shortcomingsDependence on browsers companies for technical advances

Ajax vendors motivated to work together (united we stand, divided we fall)

Ajax technology layer not addressed by other industry groups

A rich but fragile ecosystemInteroperability shortcomingsEducational/marketing shortcomingsDependence on browsers companies for technical advances

Ajax vendors motivated to work together (united we stand, divided we fall)

Ajax technology layer not addressed by other industry groups

Browser

Ajax toolkit(s)

Ajax appHTML app

Interoperable Ajax Tools and Mashups 5

OpenAjax Alliance Formation

Kick-off meeting May 200630 companies Objectives, process, scope, and initial tasks

Scope of activitiesInteroperabilityEducationalHelp shape the future of the Ajax ecosystem

What we produceDocuments (e.g., specs)Open source (mostly JavaScript)

Kick-off meeting May 200630 companies Objectives, process, scope, and initial tasks

Scope of activitiesInteroperabilityEducationalHelp shape the future of the Ajax ecosystem

What we produceDocuments (e.g., specs)Open source (mostly JavaScript)

Interoperable Ajax Tools and Mashups 6

OpenAjax Alliance Areas of Focus

InteroperabilityAjax runtime librariesAjax IDEsMashups and widgetsMobile Ajax

Marketing, education and evangelism

Future browsers

InteroperabilityAjax runtime librariesAjax IDEsMashups and widgetsMobile Ajax

Marketing, education and evangelism

Future browsers

Interoperable Ajax Tools and Mashups 7

Runtime Interoperability

Runtime = JavaScript running in the browser

ProblemsName collisionsIntegration difficulties

• Critical for mashups, where you assemble pre-built components onto the canvas, often using different Ajax toolkits

OpenAjax RegistryAn industry-wide registry of JavaScript globals, CSS classnames, and HTML markup extensions

OpenAjax Hub

OpenAjax Metadata

Runtime = JavaScript running in the browser

ProblemsName collisionsIntegration difficulties

• Critical for mashups, where you assemble pre-built components onto the canvas, often using different Ajax toolkits

OpenAjax RegistryAn industry-wide registry of JavaScript globals, CSS classnames, and HTML markup extensions

OpenAjax Hub

OpenAjax Metadata

Interoperable Ajax Tools and Mashups 8

IDE Interoperability

IDEs = Developer tools (code assist, debug, visual layout)

ProblemNxM permutation problem (~200 Ajax toolkits, ~15 Ajax IDEs)Each Ajax toolkit documents their APIs and widgets in their own way

OpenAjax Metadata for Ajax LibrariesIndustry standard XML for:

• JavaScript APIs• UI controls

JSDoc to OpenAjax Metadata converter (open source)

Some of the leading OpenAjax Alliance’s IDE WG membersAdobe DreamweaverEclipse (Aptana, JSDT, ATF)Microsoft Visual Studio

IDEs = Developer tools (code assist, debug, visual layout)

ProblemNxM permutation problem (~200 Ajax toolkits, ~15 Ajax IDEs)Each Ajax toolkit documents their APIs and widgets in their own way

OpenAjax Metadata for Ajax LibrariesIndustry standard XML for:

• JavaScript APIs• UI controls

JSDoc to OpenAjax Metadata converter (open source)

Some of the leading OpenAjax Alliance’s IDE WG membersAdobe DreamweaverEclipse (Aptana, JSDT, ATF)Microsoft Visual Studio

Interoperable Ajax Tools and Mashups 9

Mashup and Widget Interoperability

Mashups = Ability to assemble pre-built components into a composite application

ProblemsSecurityWidget interoperability

OpenAjax Hub 1.1

OpenAjax Metadata for Widgets

Open source Google Gadgets support

Open source mini-mashup tool

Mashups = Ability to assemble pre-built components into a composite application

ProblemsSecurityWidget interoperability

OpenAjax Hub 1.1

OpenAjax Metadata for Widgets

Open source Google Gadgets support

Open source mini-mashup tool

Interoperable Ajax Tools and Mashups 10

Mobile Ajax

Mobile Ajax = Full Ajax running on mobile phones

ProblemsSpecial challenges (screen size, latency, keypad, battery, …)Special opportunities (portability, GPS, camera, voice, …)

White paper: Introduction to Mobile Ajax for Developers

Mobile Device APIsOpen source JavaScript to access CPS, camera, address book, SMS, …Targets both existing proprietary, system-dependent APIs (via plugins) and emerging industry standardsCollaborating with OMTP, tracking W3C (e.g., geolocation)

Mobile Ajax = Full Ajax running on mobile phones

ProblemsSpecial challenges (screen size, latency, keypad, battery, …)Special opportunities (portability, GPS, camera, voice, …)

White paper: Introduction to Mobile Ajax for Developers

Mobile Device APIsOpen source JavaScript to access CPS, camera, address book, SMS, …Targets both existing proprietary, system-dependent APIs (via plugins) and emerging industry standardsCollaborating with OMTP, tracking W3C (e.g., geolocation)

Interoperable Ajax Tools and Mashups 11

Marketing, Education and Evangelism

Problems:Industry: needs a central place for industry-wide initiativesCustomers: With so many choices: Ajax can be confusing to newcomers

OpenAjax ConformanceA small set of conformance requirements that products must meet in order to interoperate well with other Ajax productsAn Ajax industry interoperability trust brand

White papersIntroduction to Ajax and OpenAjaxWhen Does Ajax Make Business SenseNext Generation Applications Using Ajax and OpenAjaxSuccessful Deployment of Ajax and OpenAjaxAjax and Mashup SecurityIntroduction to Mobile Ajax for DevelopersGood News for Ajax – the Browser Wars are Back

Problems:Industry: needs a central place for industry-wide initiativesCustomers: With so many choices: Ajax can be confusing to newcomers

OpenAjax ConformanceA small set of conformance requirements that products must meet in order to interoperate well with other Ajax productsAn Ajax industry interoperability trust brand

White papersIntroduction to Ajax and OpenAjaxWhen Does Ajax Make Business SenseNext Generation Applications Using Ajax and OpenAjaxSuccessful Deployment of Ajax and OpenAjaxAjax and Mashup SecurityIntroduction to Mobile Ajax for DevelopersGood News for Ajax – the Browser Wars are Back

Interoperable Ajax Tools and Mashups 12

Shaping the Future of Ajax Ecosystem

Ajax industry browser wishlist initiative April – July, 2008222 participants, including many industry leaders55 separate feature requests described and discussed on wiki

Top feature requests2D GraphicsSecurity (better prevention of XSS and CSRF)Improved low-level DOM hooks for visual layoutDOM performanceRich text editingServer push (Comet)Video and audio

Ajax industry browser wishlist initiative April – July, 2008222 participants, including many industry leaders55 separate feature requests described and discussed on wiki

Top feature requests2D GraphicsSecurity (better prevention of XSS and CSRF)Improved low-level DOM hooks for visual layoutDOM performanceRich text editingServer push (Comet)Video and audio

Interoperable Ajax Tools and Mashups 13

Agenda

Introducing OpenAjax Alliance

Ajax IDEs

OpenAjax Metadata (for Ajax Libraries)

Mashups

OpenAjax Hub 1.1

OpenAjax Metadata (for Widgets)

Summary

Introducing OpenAjax Alliance

Ajax IDEs

OpenAjax Metadata (for Ajax Libraries)

Mashups

OpenAjax Hub 1.1

OpenAjax Metadata (for Widgets)

Summary

Interoperable Ajax Tools and Mashups 14

Ajax IDEs: Limited support for Ajax libraries

Adobe Dreamweaver CS3: Spry widgets

Visual Studio: ASP.NET AJAX APIs and widgets

TIBCO, Backbase, Nexaweb, …: their own libraries

JSEclipse: no special support for Ajax libraries

Eclipse JSDT and ATF: works in progress

Netbeans/jMaki: widgets from various libs (dojo, GWT, YUI)

Aptana: supports JavaScript APIs in many popular toolkitsAflax, ASP.NET AJAX, Dojo, Ext JS, jQuery, Mochikit, Mootools, Prototype, Scriptaculous, Spry, YUI

Adobe Dreamweaver CS3: Spry widgets

Visual Studio: ASP.NET AJAX APIs and widgets

TIBCO, Backbase, Nexaweb, …: their own libraries

JSEclipse: no special support for Ajax libraries

Eclipse JSDT and ATF: works in progress

Netbeans/jMaki: widgets from various libs (dojo, GWT, YUI)

Aptana: supports JavaScript APIs in many popular toolkitsAflax, ASP.NET AJAX, Dojo, Ext JS, jQuery, Mochikit, Mootools, Prototype, Scriptaculous, Spry, YUI

Interoperable Ajax Tools and Mashups 15

What should be possible?

Intelligent code assist for APIs in Ajax librariesWhat Aptana does with APIs

Visual design using widgets from Ajax librariesWhat jMaki/Netbeans does with widgets

So what’s the problem?NxM problem (~200 Ajax toolkits, ~15 Ajax IDEs)Each toolkit documents APIs and widgets their own way

Intelligent code assist for APIs in Ajax librariesWhat Aptana does with APIs

Visual design using widgets from Ajax librariesWhat jMaki/Netbeans does with widgets

So what’s the problem?NxM problem (~200 Ajax toolkits, ~15 Ajax IDEs)Each toolkit documents APIs and widgets their own way

Interoperable Ajax Tools and Mashups 16

Agenda

Introducing OpenAjax Alliance

Ajax IDEs

OpenAjax Metadata (for Ajax Libraries)

Mashups

OpenAjax Hub 1.1

OpenAjax Metadata (for Widgets)

Summary

Introducing OpenAjax Alliance

Ajax IDEs

OpenAjax Metadata (for Ajax Libraries)

Mashups

OpenAjax Hub 1.1

OpenAjax Metadata (for Widgets)

Summary

Interoperable Ajax Tools and Mashups 17

Solution: OpenAjax Metadata

OpenAjax Metadata for JavaScript APIsEmbraced an industry leader (Aptana ScriptDoc XML)Standard stuff: <class>, <namespace>, <method>, <parameter>, etc.Open source

• JSDoc to OpenAjax Metadata (extension to JSDoc Toolkit)• Aptana ScriptDoc XML to OpenAjax Metadata (and probably vice versa)

OpenAjax Metadata for WidgetsEmbraced an industry leader (Adobe Dreamweaver submission)Standard stuff: <widget>, <content>, <require>, <author>, <icon>, etc.Markup designed for strong alignment with Google GadgetsOpen source

• Sample widgets• Reference implementation of a simple mashup editor

OpenAjax Metadata for JavaScript APIsEmbraced an industry leader (Aptana ScriptDoc XML)Standard stuff: <class>, <namespace>, <method>, <parameter>, etc.Open source

• JSDoc to OpenAjax Metadata (extension to JSDoc Toolkit)• Aptana ScriptDoc XML to OpenAjax Metadata (and probably vice versa)

OpenAjax Metadata for WidgetsEmbraced an industry leader (Adobe Dreamweaver submission)Standard stuff: <widget>, <content>, <require>, <author>, <icon>, etc.Markup designed for strong alignment with Google GadgetsOpen source

• Sample widgets• Reference implementation of a simple mashup editor

Interoperable Ajax Tools and Mashups 18

OpenAjax Metadata for JavaScript APIsSample JavaScript with JSDoc

/*** Processes a method found in the JSDoc data structure.* Produces an OpenAjax 'method' element.* @param {object} method JSDoc object that holds info on this method* @param {number} indent Current indent level for pretty printing*/this.method_element = function(method, indent) { … }

Corresponding OpenAjax Metadata

<method name="method_element"><description>

Processes a method found in the JSDoc data structure.Produces an OpenAjax 'method' element.

</description><parameter name="method" datatype="Object" usage="required">

<description>JSDoc object that holds info on method</description></parameter><parameter name="indent" datatype="Number" usage="required">

<description>Current indent level for pretty printing</description></parameter>

</method>

Sample JavaScript with JSDoc/*** Processes a method found in the JSDoc data structure.* Produces an OpenAjax 'method' element.* @param {object} method JSDoc object that holds info on this method* @param {number} indent Current indent level for pretty printing*/this.method_element = function(method, indent) { … }

Corresponding OpenAjax Metadata

<method name="method_element"><description>

Processes a method found in the JSDoc data structure.Produces an OpenAjax 'method' element.

</description><parameter name="method" datatype="Object" usage="required">

<description>JSDoc object that holds info on method</description></parameter><parameter name="indent" datatype="Number" usage="required">

<description>Current indent level for pretty printing</description></parameter>

</method>

Interoperable Ajax Tools and Mashups 19

OpenAjax Metadata for Widgets

<widget name="Calendar" id="…" spec="0.1" jsClass="Calendar"sandbox="true" xmlns="http://openajax.org/metadata">

<requires><require type="library" name="dojo" version="1.1" copy="false"/> <require type="javascript" src="calendar.js"/><require type="css" library="dojo" src="dojo/resources/dojo.css"/> <require type="css" library="dojo" src="dijit/themes/tundra/tundra.css"/> <require type="css" src="../../lib/dijit/themes/tundra/tundra_rtl.css"/>

</requires><properties>

<property name='date' datatype='Date' publish='true' topic='date'/></properties> <content type='fragment'>

<![CDATA[ <input ID="__WID___calendar" class='tundra' lang="en-us"

style="background-color:#f5f5f5" dojoType="dijit._Calendar"/> ]]>

</content><javascript location="atEnd">

this.init();</javascript>

</widget>

<widget name="Calendar" id="…" spec="0.1" jsClass="Calendar"sandbox="true" xmlns="http://openajax.org/metadata">

<requires><require type="library" name="dojo" version="1.1" copy="false"/> <require type="javascript" src="calendar.js"/><require type="css" library="dojo" src="dojo/resources/dojo.css"/> <require type="css" library="dojo" src="dijit/themes/tundra/tundra.css"/> <require type="css" src="../../lib/dijit/themes/tundra/tundra_rtl.css"/>

</requires><properties>

<property name='date' datatype='Date' publish='true' topic='date'/></properties> <content type='fragment'>

<![CDATA[ <input ID="__WID___calendar" class='tundra' lang="en-us"

style="background-color:#f5f5f5" dojoType="dijit._Calendar"/> ]]>

</content><javascript location="atEnd">

this.init();</javascript>

</widget>

Interoperable Ajax Tools and Mashups 20

OpenAjax Metadata for Widgets

<widget name="Calendar" id="…" spec="0.1" jsClass="Calendar"sandbox="true" xmlns="http://openajax.org/metadata">

<requires><require type="library" name="dojo" version="1.1" copy="false"/> <require type="javascript" src="calendar.js"/><require type="css" library="dojo" src="dojo/resources/dojo.css"/> <require type="css" library="dojo" src="dijit/themes/tundra/tundra.css"/> <require type="css" src="../../lib/dijit/themes/tundra/tundra_rtl.css"/>

</requires><properties>

<property name='date' datatype='Date' publish='true' topic='date'/></properties> <content type='fragment'>

<![CDATA[ <input ID="__WID___calendar" class='tundra' lang="en-us"

style="background-color:#f5f5f5" dojoType="dijit._Calendar"/> ]]>

</content><javascript location="atEnd">

this.init();</javascript>

</widget>

<widget name="Calendar" id="…" spec="0.1" jsClass="Calendar"sandbox="true" xmlns="http://openajax.org/metadata">

<requires><require type="library" name="dojo" version="1.1" copy="false"/> <require type="javascript" src="calendar.js"/><require type="css" library="dojo" src="dojo/resources/dojo.css"/> <require type="css" library="dojo" src="dijit/themes/tundra/tundra.css"/> <require type="css" src="../../lib/dijit/themes/tundra/tundra_rtl.css"/>

</requires><properties>

<property name='date' datatype='Date' publish='true' topic='date'/></properties> <content type='fragment'>

<![CDATA[ <input ID="__WID___calendar" class='tundra' lang="en-us"

style="background-color:#f5f5f5" dojoType="dijit._Calendar"/> ]]>

</content><javascript location="atEnd">

this.init();</javascript>

</widget>

<widget> is the root element.

Interoperable Ajax Tools and Mashups 21

OpenAjax Metadata for Widgets

<widget name="Calendar" id="…" spec="0.1" jsClass="Calendar"sandbox="true" xmlns="http://openajax.org/metadata">

<requires><require type="library" name="dojo" version="1.1" copy="false"/> <require type="javascript" src="calendar.js"/><require type="css" library="dojo" src="dojo/resources/dojo.css"/> <require type="css" library="dojo" src="dijit/themes/tundra/tundra.css"/> <require type="css" src="../../lib/dijit/themes/tundra/tundra_rtl.css"/>

</requires><properties>

<property name='date' datatype='Date' publish='true' topic='date'/></properties> <content type='fragment'>

<![CDATA[ <input ID="__WID___calendar" class='tundra' lang="en-us"

style="background-color:#f5f5f5" dojoType="dijit._Calendar"/> ]]>

</content><javascript location="atEnd">

this.init();</javascript>

</widget>

<widget name="Calendar" id="…" spec="0.1" jsClass="Calendar"sandbox="true" xmlns="http://openajax.org/metadata">

<requires><require type="library" name="dojo" version="1.1" copy="false"/> <require type="javascript" src="calendar.js"/><require type="css" library="dojo" src="dojo/resources/dojo.css"/> <require type="css" library="dojo" src="dijit/themes/tundra/tundra.css"/> <require type="css" src="../../lib/dijit/themes/tundra/tundra_rtl.css"/>

</requires><properties>

<property name='date' datatype='Date' publish='true' topic='date'/></properties> <content type='fragment'>

<![CDATA[ <input ID="__WID___calendar" class='tundra' lang="en-us"

style="background-color:#f5f5f5" dojoType="dijit._Calendar"/> ]]>

</content><javascript location="atEnd">

this.init();</javascript>

</widget>

<require> elements specify the various resources that the widget needs to run successfully

Interoperable Ajax Tools and Mashups 22

OpenAjax Metadata for Widgets

<widget name="Calendar" id="…" spec="0.1" jsClass="Calendar"sandbox="true" xmlns="http://openajax.org/metadata">

<requires><require type="library" name="dojo" version="1.1" copy="false"/> <require type="javascript" src="calendar.js"/><require type="css" library="dojo" src="dojo/resources/dojo.css"/> <require type="css" library="dojo" src="dijit/themes/tundra/tundra.css"/> <require type="css" src="../../lib/dijit/themes/tundra/tundra_rtl.css"/>

</requires><properties>

<property name='date' datatype='Date' publish='true' topic='date'/></properties> <content type='fragment'>

<![CDATA[ <input ID="__WID___calendar" class='tundra' lang="en-us"

style="background-color:#f5f5f5" dojoType="dijit._Calendar"/> ]]>

</content><javascript location="atEnd">

this.init();</javascript>

</widget>

<widget name="Calendar" id="…" spec="0.1" jsClass="Calendar"sandbox="true" xmlns="http://openajax.org/metadata">

<requires><require type="library" name="dojo" version="1.1" copy="false"/> <require type="javascript" src="calendar.js"/><require type="css" library="dojo" src="dojo/resources/dojo.css"/> <require type="css" library="dojo" src="dijit/themes/tundra/tundra.css"/> <require type="css" src="../../lib/dijit/themes/tundra/tundra_rtl.css"/>

</requires><properties>

<property name='date' datatype='Date' publish='true' topic='date'/></properties> <content type='fragment'>

<![CDATA[ <input ID="__WID___calendar" class='tundra' lang="en-us"

style="background-color:#f5f5f5" dojoType="dijit._Calendar"/> ]]>

</content><javascript location="atEnd">

this.init();</javascript>

</widget>

<property> elements specify the list of widget parameters that should appear in property editor dialogs.

You can say whether a given property should participate in cross-widget message via ‘publish’ and ‘subscribe’attributes. (Also, there is a <topic> element)

Interoperable Ajax Tools and Mashups 23

OpenAjax Metadata for Widgets

<widget name="Calendar" id="…" spec="0.1" jsClass="Calendar"sandbox="true" xmlns="http://openajax.org/metadata">

<requires><require type="library" name="dojo" version="1.1" copy="false"/> <require type="javascript" src="calendar.js"/><require type="css" library="dojo" src="dojo/resources/dojo.css"/> <require type="css" library="dojo" src="dijit/themes/tundra/tundra.css"/> <require type="css" src="../../lib/dijit/themes/tundra/tundra_rtl.css"/>

</requires><properties>

<property name='date' datatype='Date' publish='true' topic='date'/></properties> <content type='fragment'>

<![CDATA[ <input ID="__WID___calendar" class='tundra' lang="en-us"

style="background-color:#f5f5f5" dojoType="dijit._Calendar"/> ]]>

</content><javascript location="atEnd">

this.init();</javascript>

</widget>

<widget name="Calendar" id="…" spec="0.1" jsClass="Calendar"sandbox="true" xmlns="http://openajax.org/metadata">

<requires><require type="library" name="dojo" version="1.1" copy="false"/> <require type="javascript" src="calendar.js"/><require type="css" library="dojo" src="dojo/resources/dojo.css"/> <require type="css" library="dojo" src="dijit/themes/tundra/tundra.css"/> <require type="css" src="../../lib/dijit/themes/tundra/tundra_rtl.css"/>

</requires><properties>

<property name='date' datatype='Date' publish='true' topic='date'/></properties> <content type='fragment'>

<![CDATA[ <input ID="__WID___calendar" class='tundra' lang="en-us"

style="background-color:#f5f5f5" dojoType="dijit._Calendar"/> ]]>

</content><javascript location="atEnd">

this.init();</javascript>

</widget>

<content> element contains the HTML snippet for the visual rendering of the widget.

Interoperable Ajax Tools and Mashups 24

OpenAjax Metadata for Widgets

<widget name="Calendar" id="…" spec="0.1" jsClass="Calendar"sandbox="true" xmlns="http://openajax.org/metadata">

<requires><require type="library" name="dojo" version="1.1" copy="false"/> <require type="javascript" src="calendar.js"/><require type="css" library="dojo" src="dojo/resources/dojo.css"/> <require type="css" library="dojo" src="dijit/themes/tundra/tundra.css"/> <require type="css" src="../../lib/dijit/themes/tundra/tundra_rtl.css"/>

</requires><properties>

<property name='date' datatype='Date' publish='true' topic='date'/></properties> <content type='fragment'>

<![CDATA[ <input ID="__WID___calendar" class='tundra' lang="en-us"

style="background-color:#f5f5f5" dojoType="dijit._Calendar"/> ]]>

</content><javascript location="atEnd">

this.init();</javascript>

</widget>

<widget name="Calendar" id="…" spec="0.1" jsClass="Calendar"sandbox="true" xmlns="http://openajax.org/metadata">

<requires><require type="library" name="dojo" version="1.1" copy="false"/> <require type="javascript" src="calendar.js"/><require type="css" library="dojo" src="dojo/resources/dojo.css"/> <require type="css" library="dojo" src="dijit/themes/tundra/tundra.css"/> <require type="css" src="../../lib/dijit/themes/tundra/tundra_rtl.css"/>

</requires><properties>

<property name='date' datatype='Date' publish='true' topic='date'/></properties> <content type='fragment'>

<![CDATA[ <input ID="__WID___calendar" class='tundra' lang="en-us"

style="background-color:#f5f5f5" dojoType="dijit._Calendar"/> ]]>

</content><javascript location="atEnd">

this.init();</javascript>

</widget>

<javascript> elements are mainly for initialization logic. The “this” object will be set to the widget instance.

Interoperable Ajax Tools and Mashups 25

Standards improve industry efficiency and unleash innovation

Ajax libraries can produce one format (OAM) for their APIsTheir library will now be compatible with many IDEsIf the library uses JSDoc, then auto-generation of OpenAjax MetadataWe are investigating auto-generation for other inline documentation formats, such as what Dojo uses

Ajax IDEs can consume one format (OAM)That IDE will now support dozens of Ajax libraries

By unifying the industry around a single XML file, IDEs can now innovate and compete in other areas

Ajax libraries can produce one format (OAM) for their APIsTheir library will now be compatible with many IDEsIf the library uses JSDoc, then auto-generation of OpenAjax MetadataWe are investigating auto-generation for other inline documentation formats, such as what Dojo uses

Ajax IDEs can consume one format (OAM)That IDE will now support dozens of Ajax libraries

By unifying the industry around a single XML file, IDEs can now innovate and compete in other areas

Interoperable Ajax Tools and Mashups 26

IDE WG Participants

Aptana Studio (chair of the WG)

Adobe Dreamweaver (Spry toolkit)

Microsoft Visual Studio (ASP.NET AJAX toolkit)

Eclipse ATF and JSDT

Sun jMaki/Netbeans

TIBCO (GI toolkit)

OpenLink SW (OAT framework)

Aptana Studio (chair of the WG)

Adobe Dreamweaver (Spry toolkit)

Microsoft Visual Studio (ASP.NET AJAX toolkit)

Eclipse ATF and JSDT

Sun jMaki/Netbeans

TIBCO (GI toolkit)

OpenLink SW (OAT framework)

Interoperable Ajax Tools and Mashups 27

Current status

SpecificationWe have a complete draft spec for OpenAjax MetadataNow in the implementation phase (see 2008 InteropFest, subsequent slide)

Schema (in RelaxNG) and validator

Open source implementationOpenAjax’s open source mashup tool implements the widget formatEclipse JSDT has implemented the JavaScript API featuresVersion 0.1 of JSDoc to OpenAjax Metadata is available

Commercial implementationAdobe Dreamweaver is implementing the widget features in the spec Aptana Studio is implementing the JavaScript APIs features

SpecificationWe have a complete draft spec for OpenAjax MetadataNow in the implementation phase (see 2008 InteropFest, subsequent slide)

Schema (in RelaxNG) and validator

Open source implementationOpenAjax’s open source mashup tool implements the widget formatEclipse JSDT has implemented the JavaScript API featuresVersion 0.1 of JSDoc to OpenAjax Metadata is available

Commercial implementationAdobe Dreamweaver is implementing the widget features in the spec Aptana Studio is implementing the JavaScript APIs features

Interoperable Ajax Tools and Mashups 28

Agenda

Introducing OpenAjax Alliance

Ajax IDEs

OpenAjax Metadata (for Ajax Libraries)

Mashups

OpenAjax Hub 1.1

OpenAjax Metadata (for Widgets)

Summary

Introducing OpenAjax Alliance

Ajax IDEs

OpenAjax Metadata (for Ajax Libraries)

Mashups

OpenAjax Hub 1.1

OpenAjax Metadata (for Widgets)

Summary

Interoperable Ajax Tools and Mashups 29

Mashups – the self-service business pattern

Interoperable Ajax Tools and Mashups 30

Business value of mashups• Faster, cheaper delivery of applications

• Save time and money through reuse and lightweight integration techniques

• Lower skill set needed to assembly new applications

• Support innovation and new business opportunities• Users empowered to innovate and explore

• Gain valuable insights• Due to remixing enterprise and web

information• Better align IT and business

• Do-it-yourself IT will be expected by Facebook generation

• Extend reach and value of SOA• Service reuse illuminates the business value

of SOA

Interoperable Ajax Tools and Mashups 31

Mashup software

• Mashup tools• Widget and feed discovery• Application assembly• Instant deployment

• Widgets • Pre-packaged, remixable mini-applications• Usually tied to a back-end web service

• Sometimes leveraging previous investment in SOA

• Public or company-private• Key enabler of the long tail

Interoperable Ajax Tools and Mashups 32

Widget innovation – no shortage

Interoperable Ajax Tools and Mashups 33

Industry challenges

InteroperabilityDozens of proprietary technologiesGood news: many use the “Web Runtime” (i.e., Ajax)!Bad news: even when using the Web Runtime, widgets are not interoperable

SecurityThe power of mashups – comes largely from discovering and integrating great widgets from 3rd partiesBut 3rd party widgets might be malicious

InteroperabilityDozens of proprietary technologiesGood news: many use the “Web Runtime” (i.e., Ajax)!Bad news: even when using the Web Runtime, widgets are not interoperable

SecurityThe power of mashups – comes largely from discovering and integrating great widgets from 3rd partiesBut 3rd party widgets might be malicious

Interoperable Ajax Tools and Mashups 34

OpenAjax – Addressing the challenges

Web browserURL: http://example.com/mashup_builder/my_mashup1

Widget-C Widget-E

Widget-A

Communicates in the background with one of the company’s web

servers

Company server

Communicates in the background with a public web server

(trusted)

Message passing between

the widgets

Public server

Communicates in the background with a public web server

(untrusted)

Public server

(untrusted)

(1) OpenAjax Hub 1.1provides framework for

loading/isolating widgets and secure message

management

(4) Open source mini-mashup application

shows how to use all of these technologies

(2) OpenAjax Metadatadefines an industry

standard widget wrapper format

(3) Open source transcodersconvert popular existing

proprietary gadget formats into OpenAjax Metadata

Interoperable Ajax Tools and Mashups 35

Agenda

Introducing OpenAjax Alliance

Ajax IDEs

OpenAjax Metadata (for Ajax Libraries)

Mashups

OpenAjax Hub 1.1

OpenAjax Metadata (for Widgets)

Summary

Introducing OpenAjax Alliance

Ajax IDEs

OpenAjax Metadata (for Ajax Libraries)

Mashups

OpenAjax Hub 1.1

OpenAjax Metadata (for Widgets)

Summary

Interoperable Ajax Tools and Mashups 36

OpenAjax Hub 1.0

What is it?Small bit of standard JavaScript (< 3K after compaction)Enables multiple Ajax runtimes to work together

Key use case: Developer mashupsWhere a professional developer mashes up components using HTML+JavaScript+…

Version 1.0 featuresAjax library registration

• OpenAjax.hub.registerLibrary() Simple publish/subscribe engine (the pub sub hub)

• OpenAjax.hub.publish(topicName, payload)• OpenAjax.hub.subscribe(topicName, callbackFunction)

What is it?Small bit of standard JavaScript (< 3K after compaction)Enables multiple Ajax runtimes to work together

Key use case: Developer mashupsWhere a professional developer mashes up components using HTML+JavaScript+…

Version 1.0 featuresAjax library registration

• OpenAjax.hub.registerLibrary() Simple publish/subscribe engine (the pub sub hub)

• OpenAjax.hub.publish(topicName, payload)• OpenAjax.hub.subscribe(topicName, callbackFunction)

Interoperable Ajax Tools and Mashups 37

OpenAjax Hub 1.0 – an example

OpenAjax Hub 1.0 ExampleThis is a mockup of a Web application that uses UI controls from multiple Ajax toolkits.

Assume multiple Ajax toolkits:• UTILS.js – Various utils, inc. XHR

• CALENDAR.js – Calendar control

• DATAGRID.js – Powerful tables

• CHARTS.js – Charting utilitiesThe visual controls need to react to new server data and to each other and update their views appropriately.

Interoperable Ajax Tools and Mashups 38

Example – under the hood

<html><head>

...<script type="text/javascript" src="OpenAjax.js"/><script type="text/javascript" src="UTILS.js"/><script type="text/javascript" src="CALENDAR.js"/><script type="text/javascript" src="CHARTS.js"/><script type="text/javascript" src="DATAGRID.js"/><script type="text/javascript">...function MyCalendarCallback(...) {

OpenAjax.hub.publish("myapp.newdate", newdate);}...function NewDateCallback(eventname, publisherData, subscriberData) {

...update the given visualization widget...}OpenAjax.hub.subscribe("myapp.newdate", NewDateCallback);...

</script></head>...

Interoperable Ajax Tools and Mashups 39

OpenAjax InteropFest

Objectives: Allows OpenAjax Alliance to verify that OpenAjax Hub is reliable, performant, and suitableAllows members to verify that they are OpenAjax Conformant

Objectives: Allows OpenAjax Alliance to verify that OpenAjax Hub is reliable, performant, and suitableAllows members to verify that they are OpenAjax Conformant

12 toolkits participatedhttp://www.openajax.org/member/wiki/InteropFest_2007_March

Jan-March 2007 July-Sept 2007

14 organizations, 20 toolkits participatedhttp://www.openajax.org/member/wiki/InteropFest_1.0

Interoperable Ajax Tools and Mashups 40

InteropFest Demos

For people who are just looking at the slide deck, some InteropFest demos can be found at:

http://www.openajax.org/member/wiki/InteropFest_1.0

For people who are just looking at the slide deck, some InteropFest demos can be found at:

http://www.openajax.org/member/wiki/InteropFest_1.0Participating organizations Participating toolkits

24SevenOfficeApache XAPDojo FoundationIBMILOGDWR/GetaheadIT MillLightstreamerMicrosoftNexawebOpenLink SWOpen SpotSoftware AGSun MicrosystemsTIBCO

AjaxEngineApache XAPDojo ToolkitExtILOG JViewsIT Mill ToolkitjMakiJQueryLightstreamerMicrosoft Ajax LibraryNexaweb Ajax ClientOAT: OpenLink AJAX ToolkitOpenSpot CalcDeskPrototypescript.aculo.usSoftware AG's webMethods/CAFTIBCO General Interface24SevenOffice ViliYUI

Interoperable Ajax Tools and Mashups 41

OpenAjax Hub 1.0

StatusApproved

Specificationhttp://www.openajax.org/member/wiki/OpenAjax_Hub_1.0_Specification

Reference implementation at SourceForgehttp://openajaxallianc.sourceforge.net

StatusApproved

Specificationhttp://www.openajax.org/member/wiki/OpenAjax_Hub_1.0_Specification

Reference implementation at SourceForgehttp://openajaxallianc.sourceforge.net

Interoperable Ajax Tools and Mashups 42

OpenAjax Hub 1.1 – New features

OpenAjax Hub 1.0Key use case: Developer mashupsKey technology: pub/sub within a single browser frame

OpenAjax Hub 1.1Key use case: Secure end-user mashupsKey technologies

• Widget isolation (for security)• Pub/sub across browser frames • Security manager mediates all cross-widget messages

OpenAjax Hub 1.0Key use case: Developer mashupsKey technology: pub/sub within a single browser frame

OpenAjax Hub 1.1Key use case: Secure end-user mashupsKey technologies

• Widget isolation (for security)• Pub/sub across browser frames • Security manager mediates all cross-widget messages

Interoperable Ajax Tools and Mashups 43

Security vulnerabilities

Web browserURL: http://example.com/mashup_builder/my_mashup1

Widget-C Widget-E

Widget-A

Communicates in the background with one of the company’s web

servers

Company server

Communicates in the background with a public web server

(trusted)

Message passing between

the widgets

Public server

Communicates in the background with a public web server

(untrusted)

Public server

What if one of the widgets is malicious?

(untrusted)

Interoperable Ajax Tools and Mashups 44

Browser Security

Browser same-origin policyIFRAMEs isolation - IFRAMEs from different domains (and subdomains) cannot communicate with each other via DOM bridging or JavaScript bridgingImplemented in all popular Web browsers today

Today’s tricks for cross-domain mashupsDynamic SCRIPT tag to another serverServer-side proxies“IFrame proxy” (window.location fragment identifier)New browsers: W3C postMessage() and Access Control

Browser same-origin policyIFRAMEs isolation - IFRAMEs from different domains (and subdomains) cannot communicate with each other via DOM bridging or JavaScript bridgingImplemented in all popular Web browsers today

Today’s tricks for cross-domain mashupsDynamic SCRIPT tag to another serverServer-side proxies“IFrame proxy” (window.location fragment identifier)New browsers: W3C postMessage() and Access Control

Interoperable Ajax Tools and Mashups 45

SMash

SMash stands for “Secure Mashups”Secure handling of 3rd party mashup componentsRuns in today’s browsers (without plugins)

Designed and implemented at IBM™ Research (beginning of 2007)

Open-sourced (openajaxallianc.sourceforge.net) in August 2007Research Paper describing SMash in WWW 2008 Conference

High-level APIs, independent of implementation technology

Fragment communication, HTML5 postMessage, Java™ platform, Flash etc.Will still work when browsers add native support for secure cross-frame messaging

SMash stands for “Secure Mashups”Secure handling of 3rd party mashup componentsRuns in today’s browsers (without plugins)

Designed and implemented at IBM™ Research (beginning of 2007)

Open-sourced (openajaxallianc.sourceforge.net) in August 2007Research Paper describing SMash in WWW 2008 Conference

High-level APIs, independent of implementation technology

Fragment communication, HTML5 postMessage, Java™ platform, Flash etc.Will still work when browsers add native support for secure cross-frame messaging

Interoperable Ajax Tools and Mashups 46

OpenAjax Hub 1.1: Plug-in communication providers

Hub 1.1 Code

HTML5 postMessage provider

FIM provider

SPI

inline provider

Mashup assembly toolHub 1.1 Code

FIM provider

Widget 1

Hub 1.1 Code

inline provider

Widget 2

Hub 1.1 Code

HTML5 provider

Widget 3

Interoperable Ajax Tools and Mashups 47

OpenAjax Hub 1.1: Simple exampleWeb browser

URL: http://example.com/mashup_builder/my_mashup1

Widget-C Widget-E

Widget-A

Mashup container

Hub 1.1smash provider

Hub 1.1 (Managed Hub)

inline provider

smash provider

Security manager

Broadcast an event usingconnHandle.publish()

Invoke the callback function

Subscribe to a topic and register a callback function using connHandle.subscribe()

Hub 1.1inline provider

Hub 1.1smash provider

Interoperable Ajax Tools and Mashups 48

OpenAjax Hub 1.1: the stepsWeb browser

URL: http://example.com/mashup_builder/my_mashup1

Widget-C Widget-E

Widget-A

Mashup container

Hub 1.1smash provider

Hub 1.1 (Managed Hub)

inline provider

smash provider

Security manager

Broadcast an event usingconnHandle.publish()

Invoke the callback function

Subscribe to a topic and register a callback function using connHandle.subscribe()

Initialize and create a “Managed Hub”

Load the widgets used in the mashup

Hub 1.1inline provider

Hub 1.1smash provider

1 2

3

4

568

97

10

11

12

Interoperable Ajax Tools and Mashups 49

Hub 1.1 status

SpecificationFirst draft spec – far alonghttp://www.openajax.org/member/wiki/OpenAjax_Hub_1.1_Specification

Reference implementation at SourceForgeFirst implementation (far along)http://openajaxallianc.sourceforge.net

Timeline for Hub 1.1August-October 2008: 2008 InteropFestEnd of 2008: Finalize and approve

SpecificationFirst draft spec – far alonghttp://www.openajax.org/member/wiki/OpenAjax_Hub_1.1_Specification

Reference implementation at SourceForgeFirst implementation (far along)http://openajaxallianc.sourceforge.net

Timeline for Hub 1.1August-October 2008: 2008 InteropFestEnd of 2008: Finalize and approve

Interoperable Ajax Tools and Mashups 50

Agenda

Introducing OpenAjax Alliance

Ajax IDEs

OpenAjax Metadata (for Ajax Libraries)

Mashups

OpenAjax Hub 1.1

OpenAjax Metadata (for Widgets)

Summary

Introducing OpenAjax Alliance

Ajax IDEs

OpenAjax Metadata (for Ajax Libraries)

Mashups

OpenAjax Hub 1.1

OpenAjax Metadata (for Widgets)

Summary

Interoperable Ajax Tools and Mashups 51

Widget innovation – no shortage

Interoperable Ajax Tools and Mashups 52

OpenAjax Metadata

Mashup shortcomings todayWidget interoperability

• Many widget formats (Google, Yahoo, Apple, Microsoft…)• Widget developers usually have to build different versions of their widgets

to work with different containers

Security• No comprehensive, standards-based approach to widget isolation

OpenAjax Metadata addresses these two shortcomingsWidget interoperability

• OpenAjax Metadata defines industry standard XML for mashup widgets• Very close to Google Gadgets (easy to transcode with XSLT)

Security• OpenAjax Metadata designed to work with OpenAjax Hub 1.1 (which

provides a secure mashup runtime)

Mashup shortcomings todayWidget interoperability

• Many widget formats (Google, Yahoo, Apple, Microsoft…)• Widget developers usually have to build different versions of their widgets

to work with different containers

Security• No comprehensive, standards-based approach to widget isolation

OpenAjax Metadata addresses these two shortcomingsWidget interoperability

• OpenAjax Metadata defines industry standard XML for mashup widgets• Very close to Google Gadgets (easy to transcode with XSLT)

Security• OpenAjax Metadata designed to work with OpenAjax Hub 1.1 (which

provides a secure mashup runtime)

Interoperable Ajax Tools and Mashups 53

OpenAjax Widgets

<widget name="Calendar" id="…" spec="0.1" jsClass="Calendar"sandbox="true" xmlns="http://openajax.org/metadata">

<requires><require type="library" name="dojo" version="1.1" copy="false"/> <require type="javascript" src="calendar.js"/><require type="css" library="dojo" src="dojo/resources/dojo.css"/> <require type="css" library="dojo" src="dijit/themes/tundra/tundra.css"/> <require type="css" src="../../lib/dijit/themes/tundra/tundra_rtl.css"/>

</requires><properties>

<property name='date' datatype='Date' publish='true' topic='date'/></properties> <content type='fragment'>

<![CDATA[ <input ID="__WID___calendar" class='tundra' lang="en-us"

style="background-color:#f5f5f5" dojoType="dijit._Calendar"/> ]]>

</content><javascript location="atEnd">

this.init();</javascript>

</widget>

<widget name="Calendar" id="…" spec="0.1" jsClass="Calendar"sandbox="true" xmlns="http://openajax.org/metadata">

<requires><require type="library" name="dojo" version="1.1" copy="false"/> <require type="javascript" src="calendar.js"/><require type="css" library="dojo" src="dojo/resources/dojo.css"/> <require type="css" library="dojo" src="dijit/themes/tundra/tundra.css"/> <require type="css" src="../../lib/dijit/themes/tundra/tundra_rtl.css"/>

</requires><properties>

<property name='date' datatype='Date' publish='true' topic='date'/></properties> <content type='fragment'>

<![CDATA[ <input ID="__WID___calendar" class='tundra' lang="en-us"

style="background-color:#f5f5f5" dojoType="dijit._Calendar"/> ]]>

</content><javascript location="atEnd">

this.init();</javascript>

</widget>

Interoperable Ajax Tools and Mashups 54

Widget Isolation and Security

Widget content is either a stand-alone HTML snippet (a DIV) or an entire HTML page

Container manages the widgetWidget loading and unloadingWidget isolation (e.g., widget in its own IFRAME)Inter-widget communication – container provides connection handle

• connHandle.publish()• connHandle.subscribe()

Container implements pub/sub securityContainer includes a “policy manager” (who can pub/sub to what)Widget is oblivious to message passing technology

• fragment identifiers, postMessage, window.Name or whatever

Widget content is either a stand-alone HTML snippet (a DIV) or an entire HTML page

Container manages the widgetWidget loading and unloadingWidget isolation (e.g., widget in its own IFRAME)Inter-widget communication – container provides connection handle

• connHandle.publish()• connHandle.subscribe()

Container implements pub/sub securityContainer includes a “policy manager” (who can pub/sub to what)Widget is oblivious to message passing technology

• fragment identifiers, postMessage, window.Name or whatever

Interoperable Ajax Tools and Mashups 55

OpenAjax Metadata and Google Gadgets

Google GadgetsThe gorilla is the “Web Widget” space (tens of thousands of Gadgets)Solid technology

OpenAjax Metadata strategyMatch Google Gadgets wherever possibleOpen source XSLT transcoders to/from Google Gadgets

Google GadgetsThe gorilla is the “Web Widget” space (tens of thousands of Gadgets)Solid technology

OpenAjax Metadata strategyMatch Google Gadgets wherever possibleOpen source XSLT transcoders to/from Google Gadgets

Interoperable Ajax Tools and Mashups 56

OpenAjax Metadata status

SpecificationFirst draft spec - far alonghttp://www.openajax.org/member/wiki/OpenAjax_Metadata_Specification

Open sourceMini mashup applicationIncludes support for Google Gadgets (via transcoder)

Timeline for OpenAjax MetadataAugust-October 2008: 2008 InteropFestFall 2008: Finalize and approve

SpecificationFirst draft spec - far alonghttp://www.openajax.org/member/wiki/OpenAjax_Metadata_Specification

Open sourceMini mashup applicationIncludes support for Google Gadgets (via transcoder)

Timeline for OpenAjax MetadataAugust-October 2008: 2008 InteropFestFall 2008: Finalize and approve

Interoperable Ajax Tools and Mashups 57

OpenAjax – Addressing the challenges

Web browserURL: http://example.com/mashup_builder/my_mashup1

Widget-C Widget-E

Widget-A

Communicates in the background with one of the company’s web

servers

Company server

Communicates in the background with a public web server

(trusted)

Message passing between

the widgets

Public server

Communicates in the background with a public web server

(untrusted)

Public server

(untrusted)

(1) OpenAjax Hub 1.1provides framework for

loading/isolating widgets and secure message

management

(4) Open source mini-mashup application

shows how to use all of these technologies

(2) OpenAjax Metadatadefines an industry

standard widget wrapper format

(3) Open source transcodersconvert popular existing

proprietary gadget formats into OpenAjax Metadata

Interoperable Ajax Tools and Mashups 58

OpenAjax Mashups in action

Interoperable Ajax Tools and Mashups 59

2008 InteropFest

ObjectivesTest OpenAjax Metadata interoperability across multiple vendorsTest OpenAjax Hub 1.1 for reliability, performance, and suitability

WhenAugust – October, 2008

ObjectivesTest OpenAjax Metadata interoperability across multiple vendorsTest OpenAjax Hub 1.1 for reliability, performance, and suitability

WhenAugust – October, 2008

http://www.openajax.org/member/wiki/2008_InteropFesthttp://www.openajax.org/2008_InteropFest/refimpl

Interoperable Ajax Tools and Mashups 60

Agenda

Introducing OpenAjax Alliance

Ajax IDEs

OpenAjax Metadata (for Ajax Libraries)

Mashups

OpenAjax Hub 1.1

OpenAjax Metadata (for Widgets)

Summary

Introducing OpenAjax Alliance

Ajax IDEs

OpenAjax Metadata (for Ajax Libraries)

Mashups

OpenAjax Hub 1.1

OpenAjax Metadata (for Widgets)

Summary

Interoperable Ajax Tools and Mashups 61

Summary

Ajax IDEs aren’t realizing their potential yetInteoperability challenges

Mashups aren’t realizing their potential yetSecurity challengesInteroperability challenges

OpenAjax Alliance is addressing the challengesFor Ajax IDEs

• OpenAjax Metadata addresses IDE interop challenges

For mashups• OpenAjax Hub 1.1 addresses security challenges• OpenAjax Metadata addresses widget interop challenges

Ajax IDEs aren’t realizing their potential yetInteoperability challenges

Mashups aren’t realizing their potential yetSecurity challengesInteroperability challenges

OpenAjax Alliance is addressing the challengesFor Ajax IDEs

• OpenAjax Metadata addresses IDE interop challenges

For mashups• OpenAjax Hub 1.1 addresses security challenges• OpenAjax Metadata addresses widget interop challenges

Interoperable Ajax Tools and Mashups 62

For More Information

Web site: http://www.openajax.org

Wiki: http://www.openajax.org/member/wiki

Blog: http://www.openajax.org/blog

Mail list: [email protected]

Email: Jon Ferraiolo <[email protected]>

Web site: http://www.openajax.org

Wiki: http://www.openajax.org/member/wiki

Blog: http://www.openajax.org/blog

Mail list: [email protected]

Email: Jon Ferraiolo <[email protected]>