More Related Content
Similar to Building Multi-Channel Data-Aware Applications (20)
Building Multi-Channel Data-Aware Applications
- 1. © 2013 IBM Corporation
Building Multi-Channel Data-Aware Applications
Christophe Jolif
Senior Software Engineer
IBM
TAD-1081
- 2. 22 © 2013 IBM Corporation
Please Note
IBM’s statements regarding its plans, directions, and intent are subject to change
or withdrawal without notice at IBM’s sole discretion.
Information regarding potential future products is intended to outline our general
product direction and it should not be relied on in making a purchasing decision.
The information mentioned regarding potential future products is not a
commitment, promise, or legal obligation to deliver any material, code or
functionality. Information about potential future products may not be incorporated
into any contract. The development, release, and timing of any future features or
functionality described for our products remains at our sole discretion.
Performance is based on measurements and projections using standard IBM
benchmarks in a controlled environment. The actual throughput or performance
that any user will experience will vary depending upon many factors, including
considerations such as the amount of multiprogramming in the user’s job stream,
the I/O configuration, the storage configuration, and the workload processed.
Therefore, no assurance can be given that an individual user will achieve results
similar to those stated here.
- 3. 33 © 2013 IBM Corporation
Agenda
Multi-Channel, Data-Aware Concepts & Challenges
Introduction to Dojo & Application Framework
Building an Application with Dojo Mobile & Dojo App Framework
Using Alternate UI Frameworks like jQuery Mobile
Conclusion
- 4. 44 © 2013 IBM Corporation
Introducing the concepts
4
- 5. 55 © 2013 IBM Corporation
Multi-Channel Concepts & Challenges
• Definition in Software: Ability to deploy a single application to several
devices and automatically deal with the underlying issues
• Common deployment targets: phones, tablets & desktop
‒ Web or standalone applications
‒ could imagine more targets like TVs, Cars…
• The following challenges need to be overcome for those type of
applications:
‒ The various platforms require specific skills and different programming
languages.
‒ The application layout might differ from one channel to another. The following
cases need to be taken into account:
screen size
form-factor
portrait vs landscape
screen density
‒ Interactions & display might differ depending on the channel (e.g. touch or
mouse-based)
The code base will have differences anyway
- 6. 66 © 2013 IBM Corporation
Multi-Channel Concepts & Challenges
For client-side applications, JavaScript-based toolkits are a good solution:
• They allow both Web & native (hybrid) so you can re-use skills & code
across platforms (thanks to IBM Worklight, Apache Cordova)
• They work practically identically on mobile & desktop devices
• They integrate well with CSS3 for advanced layout and transitions that
can be based on device characteristics thanks to media queries
• They integrate well with JSON for easy application configuration, an
application framework that deals with that here is a plus
• They usually provide abstraction layers to deal with interactions (e.g.
dojo/touch)
- 7. 77 © 2013 IBM Corporation
Data-Aware Concepts & Challenges
• Data-Aware Applications:
‒ Client-side applications bound to data coming from the server
‒ Automatically refresh when new data comes in
‒ Allow to update the server-based data from client input with possible validation
• Data-Aware in Multi-Channel brings additional challenges:
‒ Depending on the target loading data must be made smarter than in the
regular case to save battery/memory/network
‒ Data presentation might be different from one device to another (icons instead
of text, simple texts instead of paragraphs…)
• The framework you will be using must ease connection to data by
providing a data abstraction layer (e.g. dojo/store)
- 8. 88 © 2013 IBM Corporation
Dojo & Dojo App Framework
8
- 9. 99 © 2013 IBM Corporation
Introduction to Dojo
• An open source JavaScript toolkit to build Web and Mobile applications
• Provided & supported part of WebSphere Application Server or IBM
Worklight for you to build your own applications
• Latest release: 1.9 (RC)
• UI is built client-side, the code is totally server-side (PHP, Java…) and
data-format (JSON, XML…) agnostic
• Well suited for professional applications development with globalization,
accessibility, data stores, object oriented programming support
- 10. 1010 © 2013 IBM Corporation
Introduction to Dojo
Three main packages:
• Dojo
‒ Script module (AMD) loader and build tool
‒ DOM query & manipulation
‒ JavaScript, Promises, XHR etc… utilities
‒ Data access abstraction (dojo/store)
‒ Touch/Mouse interaction abstraction (dojo/touch)
• Dijit
‒ UI Framework
‒ Basic & Advanced Web-oriented components (button, tree…)
‒ Layout (accordion, tabs…)
• Dojox extensions to Dojo & Dijit
‒ Dojo Mobile (dojox/mobile)
‒ Dojo Application Framework (dojox/app)
‒ A lot more (including advanced charting, calendaring and gauges systems)
- 11. 1111 © 2013 IBM Corporation
Introduction to Dojo Application Framework
• dojox/app is a Dojo-based application framework that increases
maintainability and reduces coding effort by providing:
‒ A predefined JSON-based (possibly external) configuration file
‒ A typical application structure
‒ A notion of views, view templates, controllers and a transition system between
the views
‒ A set of controllers that the application can leverage including layout and
transition controllers
‒ A build system to bundle your application in a limited set of files to be
downloaded or installed onto the system
• Even if built on top of Dojo, dojox/app is UI Toolkit agnostic, and the
application views can be developed with:
‒ Dijit
‒ Dojo Mobile
‒ Any other JavaScript/HTML5 toolkit like jQuery Mobile
- 13. 1313 © 2013 IBM Corporation
Introduction to Dojo Application Framework
The JSON configuration contains:
• An application ID
• A set of application controllers
• A set of views with:
‒ Templates (View rendering)
‒ Controllers (View controllers)
‒ View Translation Files
‒ Possibly custom parameters
• A set of data stores that can be
shared at application level or
specific to a view
The configuration can leverage
dojo/has module to branch based
on the targeted platform
{
"id": “myApp",
"controllers": [
"dojox/app/controllers/Transition",
"dojox/app/controllers/History"
],
“stores": {
“myStore”: {
“type”: “myApp/MyStore”
}
}
"views": {
“list": {
"template": “myApp/list.html“,
“nls”: “myApp/nls/list”
},
“detail": {
"controller" : “myApp/detail",
"template": "myApp/list",
“nls”: “myApp/nls/detail”
}
}
- 14. 1414 © 2013 IBM Corporation
Building a Contacts App
14
- 15. 1515 © 2013 IBM Corporation
Building an Application
• The aim is to build a simple « contacts » application using the main
features of dojox/app and allowing to:
‒ Search & display your contacts
‒ Edit an existing contact including delete
‒ Add a new contact
• The code is based on Dojo Mobile & Application Framework 1.9
• We will see later how a given view (or all views) can be written in jQuery
Mobile instead of Dojo Mobile while still relying on the same application
structure
Tablet/Desktop Layout
Phone
Layout
- 17. 1717 © 2013 IBM Corporation
Building an Application
Create the main HTML file for your application
• This file must load Dojo (< 4ko)
<script type="text/javascript"
src="path-to-dojo/dojo/dojo.js"
data-dojo-config= "async: true " >
</script>
• The Dojo mobile CSS (if using Dojo Mobile):
<script type="text/javascript"
src="path-to-dojo/dojox/mobile/deviceTheme.js">
</script>
• Your application CSS file
<link rel="stylesheet" href="contacts.css">
• As well as your main application (AMD) module:
<script type="text/javascript">
require(["contactsApp/contacts "]);
</script>
- 18. 1818 © 2013 IBM Corporation
Building an Application
• Create the configuration file, contacts.json – it can be pretty minimal at
first, just the controllers, the stores, no views:
"id": "contactsApp",
"dependencies": [
"dojo/store/Memory",
],
"controllers": [
"dojox/app/controllers/Load",
"dojox/app/controllers/Transition",
"dojox/app/controllers/Layout",
"dojox/app/controllers/History"
],
"stores": {
"contacts": {
"type": "dojo/store/Memory",
"has": {" cordova" : { "type" : "dcordova/ContactsStore" } },
"observable": true
}
}
- 19. 1919 © 2013 IBM Corporation
Building an Application
• Add views definition, layout & possible transitions to the JSON:
"views": {
"list": {
"controller": "contactsApp/list",
"template": "contactsApp/list.html",
"nls": "contactsApp/nls/list",
"has": {
"!phone": {
"constraint": "left"
}
},
"detail": {
"controller": "contactsApp/detail",
"template": "contactsApp/detail.html",
"nls": "contactsApp/nls/detail"
}
}
- 20. 2020 © 2013 IBM Corporation
Building an Application
• Add initial view declaration:
"defaultView": "list",
• Create the main module for your application, make sure:
‒ it defines the configuration flags needed by the configuration file
‒ loads the configuration file to instantiate the application
define(["dojox/app/main", "dojo/sniff", "dojo/json",
"dojo/text!./contacts.json“],
function(Application, has, json, config, common){
has.add("phone", (window.innerWidth <= 500));
Application(json.parse(config));
});
- 21. 2121 © 2013 IBM Corporation
Building an Application
• Now the structure of the application is ready, you need to work on the
views, their templates, their controllers and translations files (not shown
here).
• “list” view template:
<div class="leftpanel mblBackground">
<script type="dojo/require">has: "dojo/has"</script>
<div data-dojo-type="dojox/mobile/Heading" data-dojo-props="fixed: 'top'">
${nls.contacts}
<button data-dojo-type="dojox/mobile/ToolBarButton"
style="position: absolute; right: 0“
data-dojo-props="target: 'detail', transitionOptions: { params: { edit: true } }"
data-dojo-attach-point="add">${nls.add}</button>
</div>
<div data-dojo-type="dojox/mobile/EdgeToEdgeStoreList"
data-dojo-mixins="dojox/mobile/FilteredListMixin“
data-dojo-attach-point="contacts"
data-dojo-props="store: this.loadedStores.contacts,
labelProperty: 'displayName',
itemRenderer: this.ContactListItem, placeHolder: '${nls.search}',
stateful: !has('phone')">
</div>
</div>
- 22. 2222 © 2013 IBM Corporation
Building an Application
• “detail” view template “header” section:
<div data-dojo-type="dojox/mobile/Heading" data-dojo-props="fixed: 'top'">
<button data-dojo-type="dojox/mobile/ToolBarButton"
data-dojo-attach-point="backButton"
data-dojo-props="arrow: 'left', back: true"
style="position: absolute; left: 0"
class="backButton"></button>
<button data-dojo-type="dojox/mobile/ToolBarButton"
data-dojo-attach-point="cancelButton"
style="position: absolute; left: 0; display: 'none'"
data-dojo-props="target: 'detail',
transitionOptions: { params: { edit: false } }">
${nls.cancel}
</button>
${nls.details}
<button data-dojo-type="dojox/mobile/ToolBarButton"
data-dojo-attach-point="editButton"
style="position: absolute; right: 0"
data-dojo-props="target: 'detail',
transitionOptions: { params: {} }"></button>
</div>
- 23. 2323 © 2013 IBM Corporation
Building an Application
• “detail” view template, “form” section:
<div data-dojo-type="dojox/mobile/FormLayout">
<div>
<label for="company">${nls.name}</label>
<fieldset>
<input id="firstname" name="firstname"
data-dojo-type="dojox/mobile/TextArea"
data-dojo-props="readOnly: true, placeHolder: '${nls.first}'"
data-dojo-attach-point="firstname">
<input id="lastname" name="lastname"
data-dojo-type="dojox/mobile/TextArea"
data-dojo-props="readOnly: true, placeHolder: '${nls.last}'"
data-dojo-attach-point="lastname">
</fieldset>
</div>
<!-- other fields -->
</div>
• These two sections of the “detail” view could maybe broken into two
sub-views for more flexibility. In which case the header part would have
two versions, an editable one and a view one.
- 24. 2424 © 2013 IBM Corporation
Building an Application
• Create the application CSS file that will provide the CSS for the views:
@media screen and (min-width: 501px) {
.leftpanel {
width: 250px;
border-right:1px solid black;
z-index:100;
}
.backButton {
display: none;
}
}
- 25. 2525 © 2013 IBM Corporation
Building an Application
• The “list” controller returns a specific ListItem subclass that deals in
particular with multi-channel (hiding the arrow on phones):
define(["dojo/_base/declare", "dojo/_base/array", "dojo/aspect", "dojo/has",
"dojox/mobile/ListItem"], function(declare, array, has, ListItem){
var ContactListItem = declare(ListItem, {
target: "detail",
clickable: true,
// we don't get an arrow if we are on a two panes layout (tablet)
noArrow: !has("phone"),
postMixInProperties: function(){
this.inherited(arguments);
this.transitionOptions = { params: { "id" : this.id } };
}
});
return {
ContactListItem: ContactListItem
};
});
- 26. 2626 © 2013 IBM Corporation
Building an Application
• The “detail” view controller is in charge of both adjusting the display
based on the channel as well as binding the data from the configuration
store to the form, for it is using the loadedStores property:
return {
beforeActivate: function(previousView){
// get the id of the displayed contact from the params
var id = this.params.id;
this._onHandler = this.editButton.on("click", lang.hitch(this, this._saveForm));
// let's fill the form with the currently selected contact
// if nothing selected skip that part
var view = this;
if(typeof id !== "undefined"){
id = id.toString();
// get the contact on the store
promise = this.loadedStores.contacts.get(id);
}
when(promise, function(contact){
this._fillForm();
});
},
_fillForm: function(){
},
_saveForm: function(){
// see next page
}
}
- 27. 2727 © 2013 IBM Corporation
Building an Application
_saveForm: function(){
var id = this.params.id, view = this;
// get the contact on the store
var promise = this.loadedStores.contacts.get(id);
when(promise, function(contact){
// if there is no contact create one
if(!contact){
view._createContact();
}else{
// otherwise update it
view._saveContact(contact);
// save the updated item into the store
view.loadedStores.contacts.put(contact);
}
});
},
_createContact: function(){
var contact = { };
this._saveContact(contact);
this.loadedStores.contacts.add(contact);
},
_saveContact: function(contact){
// get the data from the HTML fields and put it in "contact“
}
- 28. 2828 © 2013 IBM Corporation
Building an Application
• Leverage the View lifecycle methods to perform actions at the right
moment in your View controller:
‒ init, beforeActivate, afterActivate,…, destroy
• Each view can access the data through the loadedStores property.
Stores can either be shared or specific to a view.
• Each view can access its translation through the nls property. NLS can
either be shared or specific to a view, they are inherited.
• Easier to build for small size (phone) first and extend to larger screens
• In order to get a responsive design and the best performance, leverage
CSS and CSS media queries where possible to layout/display/hide
elements based on the destination channel characteristics
• Define « has » flags that corresponds to your different channels
• Leverage the flags both in the configuration file to configure the layout of
the application and in the view templates & controllers to possibly
change the behavior of the application based on the channel
- 29. 2929 © 2013 IBM Corporation
Building an Application
Thanks to dojox/app flexibility you can go a lot further:
• You can build the application for smarter deployment:
./build.sh --profile ../../contactsApp/build/build.profile.js
--appConfigFile ../../contactsApp/contacts.json
--appConfigLayer=contactsApp/contacts
• Once built instead of running the application through a Web interface
you can leverage IBM Worklight or Apache Cordova to bundle it as a
native/hybrid application. Doing that you can just switch your contacts
store by an implementation that wraps Cordova contacts API.
• For advanced needs you can change the default dojox/app view
mechanism or replace/customization/add to any of the available
controllers.
• This is particularly useful for the LayoutController. If you want a totally
different layout, in particular if you want it to be totally CSS-based you
can replace it by your own layout controller (see examples in
dojox/app/tests)
- 30. 3030 © 2013 IBM Corporation
Using Alternate UI Frameworks
30
- 31. 3131 © 2013 IBM Corporation
Using Alternate UI Frameworks like jQuery Mobile
• The template of a view can easily be written in any UI Framework.
jQuery Mobile version of “list” view would be:
<div class="leftpanel">
<div data-role="page">
<div data-role="header">
<h1>Contacts</h1>
<button class="ui-btn-right">Add</button>
</div>
<div data-role="content">
<ul data-role="listview" data-filter="true">
<li><a>Ed Chatelain</a></li>
<li><a>Christophe Jolif</a></li>
</ul>
</div>
</div>
</div>
- 32. 3232 © 2013 IBM Corporation
Using Alternate UI Frameworks like jQuery Mobile
• Obviously the controller must be adjusted accordingly to:
‒ Load jQuery & jQuery Mobile (using AMD)
‒ Adjust data binding to use jQuery Mobile APIs
define.amd.jQuery = true;
define(["jquery", "dojo/when"], function ($, when){
$(document).bind( "mobileinit", function(){
$.mobile.hashListeningEnabled = false;
$.mobile.pushStateEnabled = false;
});
return {
beforeActivate: function(){
var view = this;
require(["jquerym"], function (){
var html = "";
when(view.loadedStores.contacts.query(), function(contacts){
var i;
for(i = 0; i < contacts.length; i++){
html += '<li id="'+contacts[i].id+'">' + contacts[i].displayName + '</li>';
}
$(view.list).append($(html));
$(view.list).listview("refresh");
});
});
}
};
});
- 33. 3333 © 2013 IBM Corporation
Using Alternate UI Frameworks like jQuery Mobile
• Finally the application itself must be configure to use jQuery by:
‒ Providing the jQuery mobile CSS
‒ Configuring the AMD loader to find jQuery JavaScript libraries
<link rel="stylesheet"
href="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.css" />
<script type="text/javascript" src="../dojo/dojo.js"
data-dojo-config="async: true,
packages: [
{ name: 'jquery', location: 'http://code.jquery.com/',
main: 'jquery-1.9.1' },
{ name: 'jquerym', location: 'http://code.jquery.com/mobile/1.3.1/',
main: 'jquery.mobile-1.3.1' }
]">
</script>
- 34. 3434 © 2013 IBM Corporation
Conclusion
• Dojo Application Framework allows you to more easily build Data-
Aware Multi-Channel Applications using the UI Framework of choice
• dojox/app gives you access to your data through Dojo store
mechanism, you can go one step further and generalize the binding
between the store and your form using binding libraries. Dojo has an
experimental library for that (“dojox/mvc”) but it is not finalized yet.
• The entire code of the application we’ve worked on today is available
on github, so feel free to give it a try!
https://github.com/cjolif/dojo-contacts-app
• You might as well be interested in:
TMD-1079: Building Mobile Applications with
the Dojo Toolkit and jQuery
Date/Time: Tue, 30/Apr, 05:15 PM - 06:15 PM
Room: Venetian - Palazzo L
- 35. 3535 © 2013 IBM Corporation
Application Infrastructure Hands-on Proctored Labs
Get hands-on experience via the following scheduled lab sessions:
Session # Title Schedule
1628
Learn to Accelerate Your Web App Development with the Liberty
Profile
Tue, 30/Apr, 08:30 AM - 11:15 AM
Venetian - Murano 3205
Thu, 2/May, 02:15 PM - 04:45 PM
Venetian - Murano 3303
1681
Building EJB 3.1 and JPA 2.0 Applications with RAD and
WebSphere
Tue, 30/Apr, 04:00 PM - 06:15 PM
Venetian - Murano 3301B
1729 HTML5 + CSS3 + JavaScript + Dojo Practical Exercises
Tue, 30/Apr, 08:30 AM - 11:15 AM
Venetian - Murano 3301B
Wed, 1/May, 01:00 PM - 03:15 PM
Venetian - Murano 3303
3024 CICS Emerging Technologies
Tue, 30/Apr, 01:00 PM - 03:30 PM
Venetian - Murano 3205
1217
Diagnostic and Performance Tools for WebSphere Application
Server
Tue, 30/Apr, 01:00 PM - 03:30 PM
Venetian - Murano 3301B
Thu, 2/May, 01:00 PM - 03:15 PM
Venetian - Murano 3301B
1548 Deploy a Lightweight Scalable Mobile Infrastructure
Wed, 1/May, 01:00 PM - 03:15 PM
Venetian - Murano 3301B
1626 IBM WebSphere Application Server Migration Tools
Wed, 1/May, 03:45 PM - 06:00 PM
Venetian - Murano 3301B
1637
Build and Administer Your Own Liberty Application Cluster, New
in WAS 8.5.5
Wed, 1/May, 08:30 AM - 11:15 AM
Venetian - Murano 3301B
- 36. 3636 © 2013 IBM Corporation
Thank You! Any question?
christophe.jolif@fr.ibm.com
36
- 37. 3737 © 2013 IBM Corporation
We love your Feedback!
Don’t forget to submit your Impact session and speaker feedback!
•Your feedback is very important to us – we use it to improve next year’s
conference
•Go to the Impact 2013 SmartSite (http://impactsmartsite/com):
‒ Use the session ID number to locate the session
‒ Click the “Take Survey” link
‒ Submit your feedback
- 39. 3939 © 2013 IBM Corporation
Legal Disclaimer
• © IBM Corporation 2013. All Rights Reserved.
• The information contained in this publication is provided for informational purposes only. While efforts were made to verify the completeness and accuracy of the information contained
in this publication, it is provided AS IS without warranty of any kind, express or implied. In addition, this information is based on IBM’s current product plans and strategy, which are
subject to change by IBM without notice. IBM shall not be responsible for any damages arising out of the use of, or otherwise related to, this publication or any other materials. Nothing
contained in this publication is intended to, nor shall have the effect of, creating any warranties or representations from IBM or its suppliers or licensors, or altering the terms and
conditions of the applicable license agreement governing the use of IBM software.
• References in this presentation to IBM products, programs, or services do not imply that they will be available in all countries in which IBM operates. Product release dates and/or
capabilities referenced in this presentation may change at any time at IBM’s sole discretion based on market opportunities or other factors, and are not intended to be a commitment to
future product or feature availability in any way. Nothing contained in these materials is intended to, nor shall have the effect of, stating or implying that any activities undertaken by you
will result in any specific sales, revenue growth or other results.
• If the text contains performance statistics or references to benchmarks, insert the following language; otherwise delete:
Performance is based on measurements and projections using standard IBM benchmarks in a controlled environment. The actual throughput or performance that any user will
experience will vary depending upon many factors, including considerations such as the amount of multiprogramming in the user's job stream, the I/O configuration, the storage
configuration, and the workload processed. Therefore, no assurance can be given that an individual user will achieve results similar to those stated here.
• If the text includes any customer examples, please confirm we have prior written approval from such customer and insert the following language; otherwise delete:
All customer examples described are presented as illustrations of how those customers have used IBM products and the results they may have achieved. Actual environmental costs
and performance characteristics may vary by customer.
• Please review text for proper trademark attribution of IBM products. At first use, each product name must be the full name and include appropriate trademark symbols (e.g., IBM
Lotus® Sametime® Unyte™). Subsequent references can drop “IBM” but should include the proper branding (e.g., Lotus Sametime Gateway, or WebSphere Application Server).
Please refer to http://www.ibm.com/legal/copytrade.shtml for guidance on which trademarks require the ® or ™ symbol. Do not use abbreviations for IBM product names in your
presentation. All product names must be used as adjectives rather than nouns. Please list all of the trademarks that you use in your presentation as follows; delete any not included in
your presentation. IBM, the IBM logo, Lotus, Lotus Notes, Notes, Domino, Quickr, Sametime, WebSphere, UC2, PartnerWorld and Lotusphere are trademarks of International
Business Machines Corporation in the United States, other countries, or both. Unyte is a trademark of WebDialogs, Inc., in the United States, other countries, or both.
• If you reference Adobe® in the text, please mark the first use and include the following; otherwise delete:
Adobe, the Adobe logo, PostScript, and the PostScript logo are either registered trademarks or trademarks of Adobe Systems Incorporated in the United States, and/or other countries.
• If you reference Java™ in the text, please mark the first use and include the following; otherwise delete:
Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.
• If you reference Microsoft® and/or Windows® in the text, please mark the first use and include the following, as applicable; otherwise delete:
Microsoft and Windows are trademarks of Microsoft Corporation in the United States, other countries, or both.
• If you reference Intel® and/or any of the following Intel products in the text, please mark the first use and include those that you use as follows; otherwise delete:
Intel, Intel Centrino, Celeron, Intel Xeon, Intel SpeedStep, Itanium, and Pentium are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States and
other countries.
• If you reference UNIX® in the text, please mark the first use and include the following; otherwise delete:
UNIX is a registered trademark of The Open Group in the United States and other countries.
• If you reference Linux® in your presentation, please mark the first use and include the following; otherwise delete:
Linux is a registered trademark of Linus Torvalds in the United States, other countries, or both. Other company, product, or service names may be trademarks or service marks of
others.
• If the text/graphics include screenshots, no actual IBM employee names may be used (even your own), if your screenshots include fictitious company names (e.g., Renovations, Zeta
Bank, Acme) please update and insert the following; otherwise delete: All references to [insert fictitious company name] refer to a fictitious company and are used for illustration
purposes only.