ReviewStudio

1. Introduction

1.1. ReviewStudio Advantages

1.2. Technical Requirements


3. Supported Formats


4. ReviewStudio Embedding

4.1. CSS and JavaScript Libraries

4.2. ReviewStudio Enterprise HTML Document

4.3. ReviewStudio Controller

4.4. ReviewStudio Version

5.1. User Configuration

5.2. Collaborators Configuration

5.3. Items Configuration

5.4. User Roles Configuration

5.5. Callbacks Configuration

5.6. Miscellaneous Configuration

5.7. Compare Mode Configuration



ReviewStudio Documentation

Client Integration Guide

1. Introduction

ReviewStudio Enterprise is a client/server solution that enables the synchronous and asynchronous display, presentation and annotation of rich media content from most modern web browsers. ReviewStudio Enterprise offers a highly configurable and customizable environment that is designed to be integrated into an existing Content Management System (CMS) or other Service Oriented Architecture (SOA).

1.1. ReviewStudio Advantages

  • Provides an easy-to-use, web-based interface for reviewing and annotating a wide range of digital media content.
  • Supports both asynchronous and synchronous modes of collaboration so collaborators can either leave feedback on their own or groups can participate in live, synchronized real-time review sessions.
  • Supports synchronized real-time video playback with on-frame markup.
  • Fully compliant with W3C standards for HTML5. Highly configurable to support any business process workflow.

1.2. Technical Requirements

The ReviewStudio Collaboration Client requires an HTML5 compliant web browser. Currently this includes Safari, Firefox, Chrome and IE 10+. Note that limitations in HTML5 support in Internet Explorer may limit some functionality. Please contact us for the most recent compatibility information.

The ReviewStudio Collaboration Server requires Linux OS.

Back to top

2. ReviewStudio Enterprise Integration Overview

The ReviewStudio Enterprise architecture consists of two components:

Web Client:
An HTML5 compliant web client that is used to display, present and annotate content.
Server:
A server that manages the communication between the ReviewStudio clients and stores all annotation data for all collaboration sessions.

ReviewStudio Enterprise is designed to be integrated into an existing CMS or other SOA as shown in the diagram below:

ice1
Typically the CMS/SOA manages all issues related to user authentication and roles, content and project workflow management, and user communication and notifications. A typical scenario for integrating ReviewStudio Enterprise into the content management workflow would involve the following processes:

  • A user identifies one or more files that require feedback, approval and/or presentation using ReviewStudio.
  • In addition the user identifies the group of other users who will have access to collaborate on the file(s) in ReviewStudio. Each user may have a specific role that determines what functionality will be enabled for them during the collaboration.
  • If necessary, the selected files will be encoded to an associated set of proxy files that are in a format supported by ReviewStudio. This encoding process is not part of the ReviewStudio solution (See Supported Formats).
  • Once the set of files and collaborators are identified the user initiates the creation of a specific ReviewStudio session. Other configuration options may be specified (See ReviewStudio Configuration).
  • The user can notify collaborators of the specific URL of the new session. The CMS can manage notifications, tasks, milestones and other management workflow issues related to the availability and accessibility of the session.
  • During the active lifespan of a session, callbacks can be used to communicate specific events that have occurred within ReviewStudio (i.e. Annotations, approvals, visits, downloads). Information passed back can be integrated into the CMS and used to trigger specific workflow related actions such as notifications.

Back to top

3. Supported Formats

ReviewStudio Enterprise supports the following formats:

Image:
HTML5 provides native support for jpg, png and gif. Other formats need to be converted into one of these formats. A good open source image conversion for servers is ImageMagick. There is no restriction on the resolution of the image that can be displayed.
HTML5 provides native support for jpg, png and gif. Other formats need to be converted into one of these formats. A good open source image conversion for servers is ImageMagick. There is no restriction on the resolution of the image that can be displayed.
Video:
The <video> tag has been adopted as an HMTL5 standard but currently different browsers are providing integrated support for different Codecs. Safari and IE9 provide support for mp4 (H264) while Firefox and Chrome are adopting ogg Theora and Google webm. If maximum browser compatibility is an issue for your application then you can undertake dual encoding and ReviewStudio will use the appropriate format for each browser.
Vector and Text:
SVG has been adopted as an HTML5 standard for vector graphics. A good source for development tools that can convert PDF to SVG is PDFTron(specifically their pdf2svg product).

4. ReviewStudio Embedding

Embedding ReviewStudio in your web pages only requires a few easy steps:

  1. Include a few CSS and JavaScript libraries in the <head> of your document.
  2. Include the ReviewStudio HTML document somewhere in the <body> of your document.
  3. Create the ReviewStudio controller and pass it your configuration options once your document is loaded.

You can find a fully working, heavily commented, example of use of ReviewStudio in fileexample.php and its associated directory example. To run the example, simply point your browser to example.php. The example requires a PHP enabled web server with the Crypt_HMAC2package installed. You can install it through the PHP package manager:

pear install Crypt_HMAC2

4.1. CSS and JavaScript Libraries

The ReviewStudio Collaboration Client consists of a small number of CSS and JavaScript files that you will need to load into your document. Furthermore, it depends on the popular open source jQuery and jQueryUI libraries which you will also have to load into your document.

You can do this by adding the following lines to your HTML document:

<link rel="stylesheet" type="text/css"
      href="http://ajax.googleapis.com/ajax/libs/
            jqueryui/1.8.9/themes/smoothness/jquery-ui.css" />
<link rel="stylesheet" type="text/css" href="ice.css" />
<script type="text/javascript"
        src="http://ajax.googleapis.com/ajax/libs/
             jquery/1.4.4/jquery.min.js"></script>
<script type="text/javascript"
        src="http://ajax.googleapis.com/ajax/libs/
             jqueryui/1.8.9/jquery-ui.min.js"></script>
<script src="ice.deps.js" type="text/javascript"></script>
<script src="ice.min.js" type="text/javascript"></script>

Note: “ICE” stands for ReviewStudio’s “Integrated Collaboration Environment”.

4.2. ReviewStudio Enterprise HTML Document

The ReviewStudio Collaboration Client is an HTML document that starts at a <div> element with id attribute value of ice-container. This HTML document is contained in file ice.html; you should include this HTML code in the <body> of your page. If you are using PHP, you can, for example, include the contents of ice.html as follows:

<? readfile("ice.html"); ?>

4.3. ReviewStudio Controller

Once your HTML document is loaded, all you have left to do is create the main ReviewStudio controller object and pass it your configuration options (see ReviewStudio Configuration section for a description of these options):

var options = { /* Your configuration options here */ };
var controller = ICE.makeController(options);

You can use jQuery’s facilities to create the ReviewStudio controller as soon as the HTML document is created, without waiting for all the rest of the resources to load:

<script type="text/javascript">
/* <![CDATA[ */
  $(document).ready(function () {
    var options = { /* Your configuration options here */ };
    var controller = ICE.makeController(options);
  });
/* ]]> */
</script>

The controller object exposes the following properties:

selectItem [function]:
Call this function to select an item given its index in the items array.
selectNote [function]:
Call this function to select a note given its ID.
canClose [function]:
Call this function to know if all server communication has finished and the page can be closed without losing data.
close [function]:
Call this function to close all server connections.

4.4. ReviewStudio Version

You can find out the version and date of the ReviewStudio distribution you are using, by accessing the version and date properties of the ICE object; both are strings.

Back to top

5. ReviewStudio Configuration

ReviewStudio needs to be configured with a user, a list of collaborators, a list of items and several other parameters. These configuration options are passed to the ICE client controller as a JavaScript object. An example is shown below (see example/options.php for details).

var configOptions = {
  userid: '9991',
  user: 'John Smith',
  roles: 'manager,moderator,approver,reviewer',

  collaborators: [{
    userid: '9991',
    user: 'John Smith',
    roles: 'manager,moderator,approver,reviewer'
  },
  {
    userid: '9992',
    user: 'Jane Doe',
    roles: 'reviewer'
  }],

  items: [
    {
      url: 'example/media/bird.jpg',
      type: 'image/jpeg',
      thumbnail: 'media/bird_thumb.jpg',
      session: 'bird.jpg',
      signature: '9xD6voFCVdMH6DWawvbJWqUfE/8='
    },
    {
      sources: [
        {
          url: 'example/media/oceans-clip.mp4',
          type: 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"'
        },
        {
          url: 'example/media/oceans-clip.ogg',
          type: 'video/ogg; codecs="theora, vorbis"'
        }
      ],
      framerate: 23.98,
      thumbnail: 'media/oceans-clip.png',
      session: 'oceans-clip',
      signature: '....'
    },
    {
      sources: ['example/media/page-1.svg',
            'example/media/page-2.svg'],
      type: 'image/svg+xml',
      thumbnail_text: 'pages',
      session: 'pages.svg',
      signature: '....',
      original_url: 'example/media/pages.pdf'
    },
    {
      sources: ['example/media/brochure.svg'],
      type: 'image/svg+xml',
      thumbnail: 'media/brochure_thumb.jpg',
      session: 'brochure.svg',
      signature: '....'
    }
  ],

  getCapabilities: function (user, item) {
    return { /* capabilities */ };
  },
  callbacks: { /* callbacks */ },

  imagePath: 'images',
  useSidebar: true,
  startSidebar: true,
  useThumbnails: false,
  startThumbnails: true,
  startItem: 0,
  folderSession: 'example_folder',
  lastDate: new Date('Oct 25 2010 GMT'),
  serverPath: 'http://s2.ReviewStudio.com/cream_collab',
  sessionPrefix: 'example',
  timeLimitToEditAnnotation: 10 * 60 * 1000,
  siteid: 'yoursiteid',
  expires: 1297909870
};

Note that compressed SVG files are also supported as long as your proxy server is configured to serve compressed files with the right headers. Here is an example configuration setting the required additional response headers in an Apache server configuration file:

Content-Type: image/svg+xml
Content-Encoding: gzip

5.1. User Configuration

ReviewStudio stores all annotations with a user id and user name, so these parameters are required. The UI also shows a list of collaborators participating in a particular session.

Required user properties:

userid [string]:
A unique user identifier; each annotation will get this userid, but it is not visible in the UI. Usually this will correspond to a user identification from the CMS.
user [string]:
This is the name of the user as it will be displayed in the UI.

Optional user properties:

roles [string]:
A list of possible user roles, comma separated. The number, names and allowed functionality of each role is configured using the getCapabilities function (see Configuring User Roles).

5.2. Collaborators Configuration

The collaborators property allows you to provide a starting list of users that are known to have access to the presentation. New users are automatically added to the session when they visit its URL; they do not need to be added to this list first.

collaborators [string]:
An array of user objects; each user object needs a userid, user, and roles using same definition as above. Note that a user may have more than one role.

5.3. Items Configuration

The items property is an array of item objects and describes all the items that are part of the presentation. Each item requires the session property:

session [string]:
A unique name that the collaboration server uses to store the annotations for the item (the collaboration session). Usually, this is the unique id of the item in your CMS.

The other properties of the item object depend on the item type. ReviewStudio Enterprise recognizes image, vector (SVG), and video types.

Image items have the following additional properties:

url [string]:
A unique resource location for the image file,
type [string]:
The mime type of the image file. Supported file types are: jpg, png and gif, with respective mime types: image/jpeg, image/png and image/gif. Other image file types will need to be converted to one of these formats.

Vector items have the following additional properties:

sources [array]:
An array of URLs of the SVG files making up the pages of a document,
type [string]:
The mime type of the vector file. Only one file type is supported: SVG, with respective mime type: image/svg+xml. Other vector file types, including PDF, will need to be converted to the SVG format, one file per page. See file formats chapter for more info.

Video items have the following additional properties:

sources [array]:
An array of objects specifying different encodings. Each encoding object must contain:

url [string]:
A URL to the video file,
type [string]:
The extended mime type of the video.
framerate [float] (optional):
HTML5 video does not have framerate meta data, so if you need frame control you need to specify the framerate of the video.

Each item also has optional signature, thumbnail (or thumbnail_text) and original_url properties:

signature [string]:
Used by the ReviewStudio collaboration server for validation, seesecurity section.
thumbnail [string]:
URL of a thumbnail image, used by the navigation UI to show a thumbnail
thumbnail_text [string]:
label to show instead of a thumbnail, used by the navigation UI to if you have no thumbnail for a particular item
original_url [string]:
Used to identify the original media associated to the item when the user downloads it by clicking on the Download original button in the UI. ReviewStudio supports only a specific set of media formats; all other formats must be encoded to the supported formats to be displayed in the ReviewStudio canvas. However, you may want to allow the user to download an item in its original format (e.g. a multi-page PDF file instead of one SVG file per page as used within ReviewStudio); in this case, you can provide the URL to the original using this property. If this property is absent, downloading the item will use the URL for the encoded item (the first of them in case of multiple video encodings or vector, SVG, items).

5.4. User Roles Configuration

getCapabilities [function]:
Used to control which features of ReviewStudio are available to a given user for the current item. It is called every time ReviewStudio moves to a new item.

ReviewStudio provides several features to a user, including the ability to annotate an item, approve/reject it, print reports, etc. You can control which of these features are available to a particular user working on a given item by providing your own function, mapping a user object and item object pair to a set of capabilities.

To make this easier, you may want to take advantage of the roles property of a user object and map user roles to capabilities.

The capabilities object returned by the getCapabilities function must have the following Boolean properties:

moderate:
If true, it allows the user to start and stop a presentation and to select which eligible collaborator can take control of a presentation.
approve:
If true, it allows the user to approve or reject the current item.
viewApprovals:
If true, it allows the user to see the approve/reject results of all the eligible collaborators.
viewUserRoles:
If true, it allows the user to see the roles of all the users listed in the Collaborators Panel. Otherwise, the user will still be able to see the list of collaborators, but will not know their roles.
annotate:
If true, it allows the user to annotate the current item.
reply:
If true, it allows the user the ability to reply to an existing comment.
edit:
If true, it allows the user to remove their own comments and replies. Note that even when this capability is set, the system will only allow removal of the last reply on a note (or the note itself if it has no replies) and only during the 15 minutes following its creation.
print:
If true, it allows the user to print the current item.
download:
If true, it allows the user to download the current item.

The example below show a scenario where a user can have multiple roles taken from admin, manager, moderator, approver, and reviewer. However, ReviewStudio does not give these strings any particular meaning and you can just as easily use your own set of roles as long as they are valid strings.

As a convenience, you can use the user.hasRole method of the user object to find out whether a user has a specific role. You can also check user.userid[string] and user.user[string] if you wish to access the current user’s id and name to make a decision on the capabilities enabled.

function getCapabilities1(user, item) {
  var admin = user.hasRole('admin') || user.hasRole('manager');
  var moderator = user.hasRole('moderator');
  var approver = user.hasRole('approver');
  var reviewer = user.hasRole('reviewer');

  return {
    moderate: admin || moderator,
    approve: admin || approver,
    viewApprovals: admin,
    viewUserRoles: admin,
    annotate: admin || reviewer,
    reply: admin || reviewer,
    edit: admin || reviewer,
    print: true,
    download: true
  };
}

See example/capabilities.js for more examples of capabilities mapping.

5.5. Callbacks Configuration

callbacks [object]:
This objects groups all the callback functions that ReviewStudio will call to notify you of relevant event happening during a collaboration session (e.g. when the user creates a new annotation or prints a report).

In order to tightly integrate ReviewStudio into your workflow, you may want to monitor the user actions within a collaboration session. You can do this by providing a set of callback functions to ReviewStudio and ReviewStudio will call them every time their corresponding events happen.

All callbacks are passed a context object as their first parameter. This context object can be used to identify the current item and session at the time the callback was triggered; it has the following properties (see the Items Configuration section for more information on these properties):

userid [string]:
The unique identifier of the current user.
items [array]:
The list of items in the presentation.
itemNo [integer]:
The index of current item in the presentation (starting from 0).
folderSession [string]:
The unique string identifying the set of items as group.
sessionPrefix [string]:
The prefix that is prepended to all item sessions.

The callback functions are grouped into a single object with the following properties:

presenterMode [function]:
This function is called every time a presentation is started or stopped. It takes the context object and one Boolean parameter: true if the presentation started; false if the presentation stopped.
item [function]:
This function is called every time the user moves to a new item. It takes the context object and an Integer parameter corresponding to the positional order of the item within the presentation, starting at zero.
Since 1.0.603 it takes a 3rd Boolean parameter indicating whether the item is loading (parameter is false) or loaded (parameter is true).
addedNote [function]:
This function is called when the user adds a new annotation. It takes the context object, a String parameter with the unique ID of the annotation, and a String parameter providing the text entered by the user.
addedReply [function]:
This function is called when the user replies to an annotation. It takes three parameters in addition to the context object. The first parameter is a string and is the unique ID of the annotation receiving the reply. The second parameter is a string with the unique ID of the reply. And the third parameter is also a string and contains the text entered by the user.
removedNote [function]:
This function is called when the user removes an existing note. It takes the context object and a String parameter providing the unique ID of the annotation being removed.
removedReply [function]:
This function is called when the user removes an existing reply. It takes two parameters in addition to the context object. The first parameter is a string and is the unique ID of the annotation containing the reply. The second parameter is also a string and is the unique ID of the reply being removed.
editedNote [function]:
This function is called when the user edited an existing note. It takes the same parameters as addedNote.
editedReply [function]:
This function is called when the user edited an existing reply. It takes the same parameters as addedReply.
approved [function]:
This function is called when the user approves or rejects an item. It takes two parameters in addition to the context object. The first parameter is a Boolean: true if the user approved the item; false if he rejected it. The second parameter is a string and contains the optional text entered by the user to explain his decision.
print [function]:
This function is called when the user prints the current item. It takes the context object as its only parameter.
download [function]:
This function is called when the user downloads the current item. It takes the context object and a String parameter specifying the URL of original media for the current item. This is the URL to the original media (or to the encoded media if the original URL was not provided for this item). IMPORTANT: this function must implement the actual download operation.
postTemplate [function]:
This function is called when the user interface instantiates a dynamic template from ice.html and allows the integrator to extend and or customize the ui for annotations, replies and approvals. It takes the context object, a String parameter indicating what kind of template is being instantiated, and a third parameter is a jQuery wrapper of the root element of the template.

See example/callbacks.js for an example of use of these callbacks.

5.6. Miscellaneous Configuration

Other important configuration options are:

prettyDate [function] (optional):
A function that takes a time in milliseconds and returns a string with the formatted date and time. It is used to display the timestamps on notes and approval comments.
imagePath [string] (optional):
A string specifying the path that the JavaScript code should use to find the image files for the UI (currently only used for cursor image files). If omitted, images are assumed to be in the images directory.
useSidebar [bool] (optional):
A Boolean specifying whether the sidebar should be accessible during the session. If true, the user will be able to show and hide the sidebar; otherwise, the sidebar and the button use to show and hide it will not be visible. If omitted, the sidebar is available.
startSidebar [bool] (optional):
A Boolean specifying whether the sidebar should be shown at the beginning of a session. If true, the sidebar is visible on startup; otherwise it is hidden. Note that the user will still be able to show and hide the sidebar at will during the course of the session. If omitted, the sidebar is initially visible.
allExpanded [bool] (optional):
A boolean specifying whther to open/close all the comments in the comments sidebar on startup. (The user can toggle this in the UI via the ‘Open/Close’ button.) If ommitted, the comments are initially closed (false).
useThumbnails [bool] (optional):
A Boolean specifying whether the item thumbnails should be accessible during the session. If true, the user will be able to show and hide the thumbnails with the item button; otherwise, the thumbnails will not be visible. If omitted, the thumbnails are not available.
startThumbnails [bool] (optional):
A Boolean specifying whether the thumbnails should be shown at the beginning of a session. If true, the thumbnails are visible on startup; otherwise they are hidden. Note that the user will still be able to show and hide the thumbnails at will during the course of the session. If omitted, the thumbnails are initially visible.
startItem [integer] (optional):
An integer specifying which item in the presentation should be initially displayed. Items are numbered starting from 0. If omitted, the presentation will start at item 0.
startNote [string] (optional):
A string specifying the id of the note that should be selected when a page is loaded. If omitted, no note will be selected.
folderSession [string]:
Unique string identifying the set of items as group. This is usually a folder in your CMS or backend system.
lastDate [string] (optional):
Last date and time that the current user visited this page. Specified as HTTP date format, RFC 822 (updated by RFC 1123); example: “Sun, 06 Nov 1994 08:49:37 GMT”. If specified, all items and annotations that have been added or modified since the date provided will be marked as New in the UI. If not specified no items will be shown as being new.
serverPath [string]:
URL of the collaboration server
sessionPrefix [string] (optional):
The session prefix will be prepended to the item sessions. For instance, you could use the folder URL of your CMS which contains all the items, and use the file name as the item sessions. ReviewStudio will then combine them to create the final session name.
timeLimitToEditAnnotation [integer] (optional):
Once a note comment or reply is created, its author has timeLimitToEditAnnotation milliseconds to edit or delete it. After that time, the comment or reply becomes read-only. Note also that only the last reply (or the initial comment if there are no replies) can be edited or deleted; this ensures that each annotation maintains a proper paper trail. As an alternative, iftimeLimitToEditAnnotation is set to null, notes and replies can be edited and deleted indefinitely. If not specified, the default time limit is 15 minutes.
siteid [string]:
The string identifying your siteid, it is supplied by ReviewStudio and you can find it in sitevars.php. Required when you use use item signatures.
expires [integer] (optional):
The time when the specified signatures become invalid, in seconds since epoch (January 1, 1970 GMT). Usually it is set to one or two hours after the time your web page was requested. It is used in the signature computation. If omitted the signature is never invalidated.
enablePanZoomModifiers [bool] (optional):
A Boolean specifying whether the pan/zoom modifier keys (shift and option on macs, respectively, and shift and control on windows/linux) are enabled. If omitted the pan/zoom modifier keys are enabled (true).
enableMultiStroke [bool] (optional):
A Boolean specifying whether it should be possible for the user to add more than one shape per comment. By default, ICE only allows the user to make one line or shape per comment. When enableMultiStroke is true, the user is provided the option of adding multiple lines or shapes per comment (both when it’s initially created and when editing it later). If omitted, enableMultiStroke is not enabled (false).
updateVectorOnSlide [bool] (optional):
A Boolean specifying whether the pages are loaded while dragging the page timeline. Default is true.
printContainer [function] (optional):
A function that returns a jQuery selector of the container that will get the printed annotations, called when the user presses the print button. Default will create a print overlay on top of the ICE client. Can be redefined to open the print in a new tab/window:
...
printContainer: function () {
var printWin = window.open(undefined, 'Print');
var printWin$ = $(printWin.document);
var container$ = $('<div>');
printWin$.find('body').append(container$);
// Style path has to be absolute:
printWin$.find('head').append('<link rel="stylesheet"
type="text/css" href="http://example.com/ice.css" />');
return container$;
},
...
make sure to include style definitions (requires absolute urls).

5.7. Compare Mode Configuration

ReviewStudio supports a mode for embedding two ICE clients in the same web page to enable the comparison of two items side by side. This mode would typically be used to allow a user to compare two sequential versions of the same media file in order to ensure that the instructions indicated with annotations on the first were implemented in the subsequent version. The mode can also be used to compare two (or more) variations of a design concept.

When compare mode is active, a new button is activated in each ICE client that allows the user to select which version of an item to display on each side. The most recent version of the item will be enabled for annotations while earlier versions of the item (along with any existing annotations) will be displayed “read-only” (i.e. no further annotations can be made to it).

A new button is also displayed in the right-side ICE client that allows the user to select additional display options available when comparison mode is active. These include:

  • Sync Navigation (on/off) – When this option is on, the navigation between files, between pages of multi-page PDF files, and the playing of video is synced between the two ICE clients. The sync between pages or video frames is “relative” – meaning that it’s possible for the user to set the starting point of the sync to a different location in each document or video.
  • Sync Zoom & Pan (on/off) – When this option is on the zoom and pan of each side is synchronized so that users can easily compare the same region of two versions of the media file displayed.

To configure ICE for comparison mode set the options as indicated in the following sample code:

var configOptions = {
  userid: '9991',
  user: 'John Smith',
  roles: 'manager,moderator,approver,reviewer'

  collaborators: [{
    userid: '9991',
    user:'John Smith',
    roles: 'manager,moderator,approver,reviewer'
  },
  {
    userid: '9992',
    user: 'Jane Doe',
    roles: 'reviewer'
  }],

  /* Comparison mode options */
  showSync: 'icon'
  showPresentation: false,

  /* Each item can be configured as an array of items, the most current
  version will be first with each subsequent version following in order. */
  items: [
    [{
      url: 'example/media/bird_v3.jpg',
      type: 'image/jpeg',
      thumbnail: 'media/bird_thumb.jpg',
      session: 'bird.jpg',
      signature: '....'
    },
    {
      url: 'example/media/bird_v2.jpg',
      type: 'image/jpeg',
      thumbnail: 'media/bird_thumb.jpg',
      session: 'bird_v2.jpg',
      signature: '....'
    },
    {
      url: 'example/media/bird_v1.jpg',
      type: 'image/jpeg',
      thumbnail: 'media/bird_thumb.jpg',
      session: 'bird_v3.jpg',
      signature: '....'
    }],
    [{
      sources: ['example/media/page_v2-1.svg',
      'example/media/page_v2-2.svg'],
      type: 'image/svg+xml',
      thumbnail_text: 'pages',
      session: 'pages_v2.svg',
      signature: '....',
    },
    {
      sources: ['example/media/page_v1_2.svg',
      'example/media/page_v1_2.svg'],
      type: 'image/svg+xml',
      thumbnail_text: 'pages',
      session: 'pages_v1.svg',
      signature: '....',
    }]
  ],
  getCapabilities: function (user, item) {
    return { /* capabilities */ };
  },
  callbacks: { /* callbacks */ },
  imagePath: 'images',
  useSidebar: true,
  startSidebar: true,
  useThumbnails: false,
  startThumbnails: true,
  startItem: 0,
  folderSession: 'compare_example_folder',
  lastDate: new Date('Oct 25 2010 GMT'),
  serverPath: 'http://162.243.14.111/collab',
  sessionPrefix: 'compare_example',
  timeLimitToEditAnnotation: 10 * 60 * 1000,
  siteid: 'yoursiteid',
  expires: 1297909870
};

enableSyncPage = true,
enableSyncPanZoom = true,
optionsLeft,
optionsRight,
controllerLeft,
controllerRight;

/* Combine all options for left ICE: */
optionsLeft = $.extend(
  true, /* deep copy! */
  {},
  options,
  queryStringToObject(),
  {
    c$: $('#left-ice'), /* select which ICE in the DOM, left one */
    id: 'left'          /* internal label, MUST BE unique */
  });
controllerLeft = ICE.makeController(optionsLeft);
optionsLeft.c$.find('#ice-sync-controls-button').hide();

/* Move version ui outside of ICE. (Optional) */
$('#left-version-selector').append(optionsLeft.c$.find('#ice-version-group'));

/* Combine all options for right ICE: */
optionsRight = $.extend(
  true, /* deep copy! */
  {},
  options,
  optionsRight2Versions,
  queryStringToObject(),
  {
    c$: $('#right-ice'), /* select which ICE in the DOM, right one */
    id: 'right'          /* internal label, MUST BE unique */
  });
controllerRight = ICE.makeController(optionsRight);
optionsRight.c$.find('#ice-collaborators-button').hide();

/* Move version ui outside of ICE (Optional) */
$('#right-version-selector').append(optionsRight.c$.find('#ice-version-group'));

/* Wait for both ICE (controllers) to initialize before hooking them up for compare/sync. */
$.when(controllerLeft.promise, controllerRight.promise).done(function (cLeft, cRight) {
  controllerLeft.syncICE(controllerRight, enableSyncPage, enableSyncPanZoom);
  controllerRight.syncICE(controllerLeft, enableSyncPage, enableSyncPanZoom);
});
}
$(document).ready(init);

6. Security

ReviewStudio Enterprise runs inside a browser and communicates with an ReviewStudio Server through HTTP and thus the ReviewStudio protocol can easily be viewed. This information can be used to setup a fake connection to the ReviewStudio Collaboration Server and to view and change the annotations.

To avoid fake connections we suggest you add a signature to each item definition. The signature is a hash computed from the combination of user and item properties and a secret that is shared between your web server and the ReviewStudio Collaboration Server. The secret in our example is defined in sitevars.php. This secret should never be included in any page/file (html or javascript) served by your web server.

The properties used in the signature are: session(id), siteid, userid, user(name), and optionally expires. First the properties and their values are combined into one string (this is called the canonical string). Each property name is concatenated with a colon (:) and its value, and then all these strings are concatenated with a newline (n), in key sorted order. For instance, the properties taken from the first item above (bird.jpg) are:

siteid: 'yoursiteid',
expires: 1297909870,
session: 'example'+'bird.jpg',
userid: '9991',
user: 'John Smith'

after evaluation (the quotes are JavaScript):

siteid:yoursiteid
expires:1297909870
session:examplebird.jpg
userid:9991
user:John Smith

after sorting by key and concatenation results in this string:

expires:1297909870nsessionid:examplebird.jpgnsiteid:yoursiteidnuserid:9991nusername:John Smith

Note that session has become sessionid and user has become username, this is for historical reasons. Also, note that n is the newline character (a single byte with value 10).

This canonical string must then be hashed with the SHA MAC hashing algorithm (which is initialized with your secret) and that hash is then Base64 encoded to get the signature.

Say your secret is thesecret then the Base64 SHA MAC hash of the canonical string is:

9xD6voFCVdMH6DWawvbJWqUfE/8=

Your secret is assigned by ReviewStudio and can be found in sitevars.php. It is hard coded in the ReviewStudio Collaboration Server you receive so do not change it.

The signature is very similar to the Amazon Web Services api signature, so if you need code for other languages, AWS libraries are good references.

For additional security you could run your web pages and the ReviewStudio Collaboration Server over a secure HTTP connection (HTTPS).