diff --git a/contact-center/app/src/main/java/com/chatopera/cc/webim/web/handler/apps/contacts/ContactsController.java b/contact-center/app/src/main/java/com/chatopera/cc/webim/web/handler/apps/contacts/ContactsController.java
index 1b90970f..88113072 100644
--- a/contact-center/app/src/main/java/com/chatopera/cc/webim/web/handler/apps/contacts/ContactsController.java
+++ b/contact-center/app/src/main/java/com/chatopera/cc/webim/web/handler/apps/contacts/ContactsController.java
@@ -193,7 +193,7 @@ public class ContactsController extends Handler{
@Menu(type = "contacts" , subtype = "contacts")
public ModelAndView detail(ModelMap map , HttpServletRequest request , @Valid String id) {
map.addAttribute("contacts", contactsRes.findOne(id)) ;
- return request(super.createRequestPageTempletResponse("/apps/business/contacts/detail"));
+ return request(super.createAppsTempletResponse("/apps/business/contacts/detail"));
}
diff --git a/contact-center/app/src/main/resources/static/js/timeliner/.bower.json b/contact-center/app/src/main/resources/static/js/timeliner/.bower.json
new file mode 100644
index 00000000..e538b7c4
--- /dev/null
+++ b/contact-center/app/src/main/resources/static/js/timeliner/.bower.json
@@ -0,0 +1,14 @@
+{
+ "name": "timeliner",
+ "homepage": "https://github.com/technotarek/timeliner",
+ "_release": "2b17590fae",
+ "_resolution": {
+ "type": "branch",
+ "branch": "master",
+ "commit": "2b17590fae9d8fb2cc96746962ff14d825f2a122"
+ },
+ "_source": "https://github.com/technotarek/timeliner.git",
+ "_target": "*",
+ "_originalSource": "timeliner",
+ "_direct": true
+}
\ No newline at end of file
diff --git a/contact-center/app/src/main/resources/static/js/timeliner/README.md b/contact-center/app/src/main/resources/static/js/timeliner/README.md
new file mode 100644
index 00000000..d44e144c
--- /dev/null
+++ b/contact-center/app/src/main/resources/static/js/timeliner/README.md
@@ -0,0 +1,407 @@
+# Timeliner
+
+## Overview
+Build a simple, interactive, historical timeline with HTML, CSS, and jQuery. The benefits of this timeline script are that it's (1) simple, (2) able to handle nearly any form of content (including images, video, audio), (3) printer friendly, and highly customizable with just CSS and HTML.
+
+Please [drop me a line](http://www.technotarek.com/contact "drop me a line") if you do do something interesting with it. See below for samples from other users.
+
+## Demos and Live Implementations
+
+###### Advanced CSS3 Customization Demo
+https://technotarek.com/timeliner/demo-future/timeliner-future.html
+
+###### Implementation with Custom CSS: Investigating Power
+https://investigatingpower.org/civil-rights/
+
+###### Original Demo
+https://www.technotarek.com/timeliner/timeliner.html
+
+## Quick Start
+
+#### Load Plugin and Dependencies
+
+```html
+
+
+
+
+```
+
+#### Instantiate
+
+```html
+
+```
+
+#### Markup
+Using the plugin's defaults and recommended markup, a timeline with two major time markers (1976 and 1984) and a total of three events looks like this:
+
+```html
+
+```
+
+[Emmet](http://emmet.io/) snippet:
+
+ div#timeline.timeline-container>div.timeline-wrapper>h2.timeline-time+dl.timeline-series>dt.timeline-event#my-event-01+dd.timeline-event-content#my-event-01EX
+
+## Important Upgrade Notes
+
+Users wishing to upgrade from v1.x to v2.x should note that the default markup for timeliner.js has changed. Specifically, most of the default class names have changed.
+
+* screen.css was divided into two separate files, demo.css and timeliner.css
+* "timelineContainer" ==> "timeline-container"
+* "timelineMajor" ==> "timeline-wrapper"
+* "timelineMajorMarker" ==> "timeline-time"
+* "timelineMinor" ==> "timeline-series"
+* "timelineEvent" ==> "timeline-event-content"
+
+To resolve these changes, either update your markup and/or use the new customization options introducted with v2.0. For example, you could use the new "timelineSection" option to change the selector from "timeline-wrapper" back to "timelineMajor". Otherwise, simply replace your original timeliner javascript and css files with the 2.x versions.
+
+In addition, note:
+
+* Each minor marker tag needs a class of timeline-event
+* The display:none property from the previous timelineEvent (now timeline-event-content) element is no longer necessary
+* The expand/collapse element uses new and simplified markup. See the Usage section for details.
+* The license has been changed from a _Creative Commons Attribution-ShareAlike 3.0 Unported License_ to a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. The former continues to apply to version 1.x implementations.
+
+The 2.x changes provide an improved semantic markup. They also help other developers use a custom markup structure. Whereas version 1.x required the use of dl, dt, dd tags, it is now possible to use your own markup in coordination with the plugin's options. Other changes were made for the sake of consistency and to simplify future development.
+
+## Requirements
+* jQuery
+* Optional: Jack Moore's ColorBox jQuery plugin
+
+## Detailed Usage Instructions
+1. Include timeliner.css (or timeliner.min.css) and timeliner.js (or timeliner.min.js). Optionally, also include responsive.css / responsive.min.css for basic responsive behavior on phones and mobile devices below 480px wide (iPad responsive behavior forthcoming).
+
+2. Wrap your timeline in an element with an ID of "timeline" and CLASS of timeline-container. You can set your own container ID using the plugin's options. If you need to use a customized class value as well, update the CSS accordingly.
+
+```html
+
+ ...
+
+```
+
+3. Separate the major marker content (e.g., content for each century, year, decade etc) into elements with a class of timeline-wrapper. See the options if you need to customize this class value.
+
+```html
+
+ ...
+
+```
+
+4. Wrap the major markers in an element with a class of 'timeline-year'. See the options if you need to customize this class value.
+
+```html
+
1954
+```
+
+5. Separate the individual events into DL elements with a class of "timeline-series". See the options if you need to customize this class value.
+
+```html
+
+ ...
+
+```
+
+6. Wrap the title of the individual events in a DT tag surrounding an A tag; give each DT a unique ID and the class of "timeline-event".
+
+```html
+
+```
+
+7. Wrap the full event content in a DD tag; give each DD an ID based on the DT with 'EX' appended and a class of 'timeline-event-content'. See the options to customize these values.
+
+```html
+
+ ...
+
+```
+
+8. Instantiate:
+
+```js
+$.timeliner({});
+```
+
+9. Or, instantiate with multiple timelines:
+
+```js
+$.timeliner({timelineContainer: '#timeline'});
+$.timeliner({timelineContainer: '#timeline2'});
+```
+
+10. Or, instantiate with options. Use as many or as few as you like. If you're using multiple timelines on a single page, options can be set on each individual timeline.
+
+```js
+$.timeliner({
+ timelineContainer: '#timeline',
+ // Container for the element holding the entire timeline (e.g. a DIV)
+ // value: ID or class selector
+ // default: #timeline
+ // note: must be unique for each timeline on page
+
+ timelineSection: '.timeline-wrapper',
+ // Wrapper that contains items under a specific marker (e.g., all of the events under a year on the timeline)
+ // value: class selector
+ // default: .timeline-wrapper
+ // note: changing this selector from the default will require modifications to the CSS file in order to retain default styling
+
+ timelineSectionMarker: '.timeline-time',
+ // Class selector applied to each major item on the timeline, such as each year
+ // value: class selector
+ // default: .timeline-year
+
+ timelineTriggerContainer: '.timeline-series',
+ // Class assigned to wrappers surrounding each individual event
+ // value: selector
+ // default: .timeline-series
+ // note: changing this selector from the default will require modifications to the CSS file in order to retain default styling
+
+ timelineTriggerAnchor: '.timeline-event',
+ // Element that is wrapped around the event's title; when clicked, expands the event and reveals its full contents
+ // value: class selector
+ // default: .timeline-event
+ // note: changing this tag from the default will require modifications to the CSS file in order to retain default styling
+
+ timelineEventContainer: options['timelineEventContainer'] || 'dt',
+ // Wrapper surrounding a series of events corresponding to the timelineSectionMarker
+ // value: tag or class selector
+ // default: dt
+ // note: When leaving this value at its default, you do not need to apply a class to the dt element if you use the plugins recommended tag structure and markup
+ // note: Change this from the default, perhaps to a class like ".timeline-event", in the case that you do not want to use the plugins recommened markup structure and prefer to use anothe element (e.g, div) instead of a dt tag to mark each event within a series.
+ // note: Changing this value from the default will require modifications to the CSS file in order to retain default styling
+
+ timelineEXContent: '.timeline-event-content',
+ // Element that contains the event's full content to be displayed when event is expanded, an event's expanded ID should alway be on this item
+ // value: class selector
+ // default: .timeline-event-ex
+ // note: changing this selector from the default will require modifications to the CSS file in order to retain default styling
+
+ EXContentIdSuffix: 'EX',
+ // ID suffix to identify expanded (aka EX) content
+ // value: string
+ // default: EX
+
+ oneOpen: false,
+ // sets whether only one item on the timeline can be open at a time. If true, other items will close when one is opened.
+ // value: true | false
+ // default: false
+ // note: does not apply to events identified in startOpen option
+
+ startState: options['startState'] || 'closed',
+ // sets whether the timeline is initially collapsed, fully expanded, or "flat" mode
+ // value: closed | open | flat
+ // default: closed
+ // note: setting to "open" makes the startOpen option meaningless
+ // note: flat mode initally collapses the entire timeline except for the major markers
+ // note: the flat state is an initial display option only -- the timeline major markers return to normal once they've been opened/displayed
+
+ startOpen: options['startOpen'] || ['.start-open'],
+ // As of version 2.3, you can simply add the "start-open" class to each timeline-event you want to have open by default; see the demo source code or code sample below
+ // sets the events to display expanded on page load
+ // value: array of IDs of single timelineEvents (e.g., ['#event01'] or ['#event01','#event02'])
+ // default: ['.start-open']
+
+ baseSpeed: 200,
+ // sets the base speed for animation of an event
+ // value: numeric
+ // default: 200
+
+ speed: 4,
+ // multiplier applied to the base speed that sets the speed at which an event's contents are displayed and hidden
+ // value: numeric
+ // default: 4
+
+ fontOpen: '1.2em',
+ // sets the font size of an event after it is opened
+ // value: any valid CSS font-size value,
+ // default: 1.2em
+
+ fontClosed: '1em',
+ // sets the font size of an event after it is closed
+ // value: any valid CSS font-size value
+ // defaults: 1em
+
+ expandAllText: '+ expand all',
+ // sets the text of the expandAll selector after the timeline is fully collapsed
+ // value: string
+ // default: + expand all
+
+ collapseAllText: '- collapse all'
+ //sets the text of the expandAll selector after the timeline is fully expanded
+ // value: string
+ // default: - collapse all
+
+});
+```
+
+11. Add an expand/collapse all events by adding the following inside of the main #timeline. Use the expandAllText and collapseAllText options to customize this button. You may include more than one expand/collapse button per timeline, such as at the top and bottom of your timeline. When the state of one changes, it will update all others.
+
+```html
+
+```
+
+## Sample
+
+Using the plugins defaults and recommended markup, a timeline with only one time marker and two events would look like this:
+
+```html
+
Example of the timeliner.js jquery plugin with advanced, custom theming. All theming accomplished with CSS and minor modifications to the HTML markup. No modifications to the plugin's core javascript. Note that this demonstration does not fully support older browsers (e.g, before Internet Explorer 9) due to the use of CSS3 properties. Also view the original demo.
A flying car is hypothetical personal aircraft that provides door-to-door aerial transportation (e.g., from home to work or to the supermarket) as conveniently as a car but without the requirement for roads, runways or other specially-prepared operating areas.
+
The flying car has been depicted in works of fantasy and science fiction such as The Jetsons, Star Wars, Blade Runner, Back to the Future Part II and The Fifth Element. The Jetsons took place in 2062.
Teleportation, or Teletransportation, is the theoretical transfer of matter or energy from one point to another without traversing the physical space between them. It is a common subject of science fiction literature, film, and television.
+
+
The original Star Trek series is reported to have taken place from 2265 to 2271.
The technological singularity hypothesis is that accelerating progress in technologies will cause a runaway effect wherein artificial intelligence will exceed human intellectual capacity and control, thus radically changing or even ending civilization in an event called the singularity.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/contact-center/app/src/main/resources/static/js/timeliner/images/timeline_century_tick.gif b/contact-center/app/src/main/resources/static/js/timeliner/images/timeline_century_tick.gif
new file mode 100644
index 00000000..3b3d3075
Binary files /dev/null and b/contact-center/app/src/main/resources/static/js/timeliner/images/timeline_century_tick.gif differ
diff --git a/contact-center/app/src/main/resources/static/js/timeliner/images/timeline_decade_tick.gif b/contact-center/app/src/main/resources/static/js/timeliner/images/timeline_decade_tick.gif
new file mode 100644
index 00000000..534d2e14
Binary files /dev/null and b/contact-center/app/src/main/resources/static/js/timeliner/images/timeline_decade_tick.gif differ
diff --git a/contact-center/app/src/main/resources/static/js/timeliner/inc/colorbox.css b/contact-center/app/src/main/resources/static/js/timeliner/inc/colorbox.css
new file mode 100755
index 00000000..303b202b
--- /dev/null
+++ b/contact-center/app/src/main/resources/static/js/timeliner/inc/colorbox.css
@@ -0,0 +1,69 @@
+/*
+ Colorbox Core Style:
+ The following CSS is consistent between example themes and should not be altered.
+*/
+#colorbox, #cboxOverlay, #cboxWrapper{position:absolute; top:0; left:0; z-index:9999; overflow:hidden;}
+#cboxOverlay{position:fixed; width:100%; height:100%;}
+#cboxMiddleLeft, #cboxBottomLeft{clear:left;}
+#cboxContent{position:relative;}
+#cboxLoadedContent{overflow:auto; -webkit-overflow-scrolling: touch;}
+#cboxTitle{margin:0;}
+#cboxLoadingOverlay, #cboxLoadingGraphic{position:absolute; top:0; left:0; width:100%; height:100%;}
+#cboxPrevious, #cboxNext, #cboxClose, #cboxSlideshow{cursor:pointer;}
+.cboxPhoto{float:left; margin:auto; border:0; display:block; max-width:none; -ms-interpolation-mode:bicubic;}
+.cboxIframe{width:100%; height:100%; display:block; border:0;}
+#colorbox, #cboxContent, #cboxLoadedContent{box-sizing:content-box; -moz-box-sizing:content-box; -webkit-box-sizing:content-box;}
+
+/*
+ User Style:
+ Change the following styles to modify the appearance of Colorbox. They are
+ ordered & tabbed in a way that represents the nesting of the generated HTML.
+*/
+#cboxOverlay{background:url(images/overlay.png) repeat 0 0;}
+#colorbox{outline:0;}
+ #cboxTopLeft{width:21px; height:21px; background:url(images/controls.png) no-repeat -101px 0;}
+ #cboxTopRight{width:21px; height:21px; background:url(images/controls.png) no-repeat -130px 0;}
+ #cboxBottomLeft{width:21px; height:21px; background:url(images/controls.png) no-repeat -101px -29px;}
+ #cboxBottomRight{width:21px; height:21px; background:url(images/controls.png) no-repeat -130px -29px;}
+ #cboxMiddleLeft{width:21px; background:url(images/controls.png) left top repeat-y;}
+ #cboxMiddleRight{width:21px; background:url(images/controls.png) right top repeat-y;}
+ #cboxTopCenter{height:21px; background:url(images/border.png) 0 0 repeat-x;}
+ #cboxBottomCenter{height:21px; background:url(images/border.png) 0 -29px repeat-x;}
+ #cboxContent{background:#fff; overflow:hidden;}
+ .cboxIframe{background:#fff;}
+ #cboxError{padding:50px; border:1px solid #ccc;}
+ #cboxLoadedContent{margin-bottom:28px;}
+ #cboxTitle{position:absolute; bottom:4px; left:0; text-align:center; width:100%; color:#949494;}
+ #cboxCurrent{position:absolute; bottom:4px; left:58px; color:#949494;}
+ #cboxLoadingOverlay{background:url(images/loading_background.png) no-repeat center center;}
+ #cboxLoadingGraphic{background:url(images/loading.gif) no-repeat center center;}
+
+ /* these elements are buttons, and may need to have additional styles reset to avoid unwanted base styles */
+ #cboxPrevious, #cboxNext, #cboxSlideshow, #cboxClose {border:0; padding:0; margin:0; overflow:visible; width:auto; background:none; }
+
+ /* avoid outlines on :active (mouseclick), but preserve outlines on :focus (tabbed navigating) */
+ #cboxPrevious:active, #cboxNext:active, #cboxSlideshow:active, #cboxClose:active {outline:0;}
+
+ #cboxSlideshow{position:absolute; bottom:4px; right:30px; color:#0092ef;}
+ #cboxPrevious{position:absolute; bottom:0; left:0; background:url(images/controls.png) no-repeat -75px 0; width:25px; height:25px; text-indent:-9999px;}
+ #cboxPrevious:hover{background-position:-75px -25px;}
+ #cboxNext{position:absolute; bottom:0; left:27px; background:url(images/controls.png) no-repeat -50px 0; width:25px; height:25px; text-indent:-9999px;}
+ #cboxNext:hover{background-position:-50px -25px;}
+ #cboxClose{position:absolute; bottom:0; right:0; background:url(images/controls.png) no-repeat -25px 0; width:25px; height:25px; text-indent:-9999px;}
+ #cboxClose:hover{background-position:-25px -25px;}
+
+/*
+ The following fixes a problem where IE7 and IE8 replace a PNG's alpha transparency with a black fill
+ when an alpha filter (opacity change) is set on the element or ancestor element. This style is not applied to or needed in IE9.
+ See: http://jacklmoore.com/notes/ie-transparency-problems/
+*/
+.cboxIE #cboxTopLeft,
+.cboxIE #cboxTopCenter,
+.cboxIE #cboxTopRight,
+.cboxIE #cboxBottomLeft,
+.cboxIE #cboxBottomCenter,
+.cboxIE #cboxBottomRight,
+.cboxIE #cboxMiddleLeft,
+.cboxIE #cboxMiddleRight {
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#00FFFFFF,endColorstr=#00FFFFFF);
+}
\ No newline at end of file
diff --git a/contact-center/app/src/main/resources/static/js/timeliner/inc/colorbox.js b/contact-center/app/src/main/resources/static/js/timeliner/inc/colorbox.js
new file mode 100644
index 00000000..097d400b
--- /dev/null
+++ b/contact-center/app/src/main/resources/static/js/timeliner/inc/colorbox.js
@@ -0,0 +1,6 @@
+/*!
+ jQuery Colorbox v1.4.15 - 2013-04-22
+ (c) 2013 Jack Moore - jacklmoore.com/colorbox
+ license: http://www.opensource.org/licenses/mit-license.php
+*/
+(function(t,e,i){function o(i,o,n){var r=e.createElement(i);return o&&(r.id=te+o),n&&(r.style.cssText=n),t(r)}function n(){return i.innerHeight?i.innerHeight:t(i).height()}function r(t){var e=H.length,i=(j+t)%e;return 0>i?e+i:i}function h(t,e){return Math.round((/%/.test(t)?("x"===e?E.width():n())/100:1)*parseInt(t,10))}function l(t,e){return t.photo||t.photoRegex.test(e)}function s(t,e){return t.retinaUrl&&i.devicePixelRatio>1?e.replace(t.photoRegex,t.retinaSuffix):e}function a(t){"contains"in x[0]&&!x[0].contains(t.target)&&(t.stopPropagation(),x.focus())}function d(){var e,i=t.data(A,Z);null==i?(_=t.extend({},Y),console&&console.log&&console.log("Error: cboxElement missing settings object")):_=t.extend({},i);for(e in _)t.isFunction(_[e])&&"on"!==e.slice(0,2)&&(_[e]=_[e].call(A));_.rel=_.rel||A.rel||t(A).data("rel")||"nofollow",_.href=_.href||t(A).attr("href"),_.title=_.title||A.title,"string"==typeof _.href&&(_.href=t.trim(_.href))}function c(i,o){t(e).trigger(i),se.trigger(i),t.isFunction(o)&&o.call(A)}function u(){var t,e,i,o,n,r=te+"Slideshow_",h="click."+te;_.slideshow&&H[1]?(e=function(){clearTimeout(t)},i=function(){(_.loop||H[j+1])&&(t=setTimeout(J.next,_.slideshowSpeed))},o=function(){M.html(_.slideshowStop).unbind(h).one(h,n),se.bind(ne,i).bind(oe,e).bind(re,n),x.removeClass(r+"off").addClass(r+"on")},n=function(){e(),se.unbind(ne,i).unbind(oe,e).unbind(re,n),M.html(_.slideshowStart).unbind(h).one(h,function(){J.next(),o()}),x.removeClass(r+"on").addClass(r+"off")},_.slideshowAuto?o():n()):x.removeClass(r+"off "+r+"on")}function f(i){G||(A=i,d(),H=t(A),j=0,"nofollow"!==_.rel&&(H=t("."+ee).filter(function(){var e,i=t.data(this,Z);return i&&(e=t(this).data("rel")||i.rel||this.rel),e===_.rel}),j=H.index(A),-1===j&&(H=H.add(A),j=H.length-1)),g.css({opacity:parseFloat(_.opacity),cursor:_.overlayClose?"pointer":"auto",visibility:"visible"}).show(),V&&x.add(g).removeClass(V),_.className&&x.add(g).addClass(_.className),V=_.className,K.html(_.close).show(),$||($=q=!0,x.css({visibility:"hidden",display:"block"}),W=o(ae,"LoadedContent","width:0; height:0; overflow:hidden").appendTo(v),D=b.height()+k.height()+v.outerHeight(!0)-v.height(),B=C.width()+T.width()+v.outerWidth(!0)-v.width(),N=W.outerHeight(!0),z=W.outerWidth(!0),_.w=h(_.initialWidth,"x"),_.h=h(_.initialHeight,"y"),J.position(),u(),c(ie,_.onOpen),O.add(F).hide(),x.focus(),e.addEventListener&&(e.addEventListener("focus",a,!0),se.one(he,function(){e.removeEventListener("focus",a,!0)})),_.returnFocus&&se.one(he,function(){t(A).focus()})),w())}function p(){!x&&e.body&&(X=!1,E=t(i),x=o(ae).attr({id:Z,"class":t.support.opacity===!1?te+"IE":"",role:"dialog",tabindex:"-1"}).hide(),g=o(ae,"Overlay").hide(),S=o(ae,"LoadingOverlay").add(o(ae,"LoadingGraphic")),y=o(ae,"Wrapper"),v=o(ae,"Content").append(F=o(ae,"Title"),I=o(ae,"Current"),P=t('').attr({id:te+"Previous"}),R=t('').attr({id:te+"Next"}),M=o("button","Slideshow"),S,K=t('').attr({id:te+"Close"})),y.append(o(ae).append(o(ae,"TopLeft"),b=o(ae,"TopCenter"),o(ae,"TopRight")),o(ae,!1,"clear:left").append(C=o(ae,"MiddleLeft"),v,T=o(ae,"MiddleRight")),o(ae,!1,"clear:left").append(o(ae,"BottomLeft"),k=o(ae,"BottomCenter"),o(ae,"BottomRight"))).find("div div").css({"float":"left"}),L=o(ae,!1,"position:absolute; width:9999px; visibility:hidden; display:none"),O=R.add(P).add(I).add(M),t(e.body).append(g,x.append(y,L)))}function m(){function i(t){t.which>1||t.shiftKey||t.altKey||t.metaKey||t.control||(t.preventDefault(),f(this))}return x?(X||(X=!0,R.click(function(){J.next()}),P.click(function(){J.prev()}),K.click(function(){J.close()}),g.click(function(){_.overlayClose&&J.close()}),t(e).bind("keydown."+te,function(t){var e=t.keyCode;$&&_.escKey&&27===e&&(t.preventDefault(),J.close()),$&&_.arrowKey&&H[1]&&!t.altKey&&(37===e?(t.preventDefault(),P.click()):39===e&&(t.preventDefault(),R.click()))}),t.isFunction(t.fn.on)?t(e).on("click."+te,"."+ee,i):t("."+ee).live("click."+te,i)),!0):!1}function w(){var e,n,r,a=J.prep,u=++de;q=!0,U=!1,A=H[j],d(),c(le),c(oe,_.onLoad),_.h=_.height?h(_.height,"y")-N-D:_.innerHeight&&h(_.innerHeight,"y"),_.w=_.width?h(_.width,"x")-z-B:_.innerWidth&&h(_.innerWidth,"x"),_.mw=_.w,_.mh=_.h,_.maxWidth&&(_.mw=h(_.maxWidth,"x")-z-B,_.mw=_.w&&_.w<_.mw?_.w:_.mw),_.maxHeight&&(_.mh=h(_.maxHeight,"y")-N-D,_.mh=_.h&&_.h<_.mh?_.h:_.mh),e=_.href,Q=setTimeout(function(){S.show()},100),_.inline?(r=o(ae).hide().insertBefore(t(e)[0]),se.one(le,function(){r.replaceWith(W.children())}),a(t(e))):_.iframe?a(" "):_.html?a(_.html):l(_,e)?(e=s(_,e),t(U=new Image).addClass(te+"Photo").bind("error",function(){_.title=!1,a(o(ae,"Error").html(_.imgError))}).one("load",function(){var e;u===de&&(U.alt=t(A).attr("alt")||t(A).attr("data-alt")||"",_.retinaImage&&i.devicePixelRatio>1&&(U.height=U.height/i.devicePixelRatio,U.width=U.width/i.devicePixelRatio),_.scalePhotos&&(n=function(){U.height-=U.height*e,U.width-=U.width*e},_.mw&&U.width>_.mw&&(e=(U.width-_.mw)/U.width,n()),_.mh&&U.height>_.mh&&(e=(U.height-_.mh)/U.height,n())),_.h&&(U.style.marginTop=Math.max(_.mh-U.height,0)/2+"px"),H[1]&&(_.loop||H[j+1])&&(U.style.cursor="pointer",U.onclick=function(){J.next()}),U.style.width=U.width+"px",U.style.height=U.height+"px",setTimeout(function(){a(U)},1))}),setTimeout(function(){U.src=e},1)):e&&L.load(e,_.data,function(e,i){u===de&&a("error"===i?o(ae,"Error").html(_.xhrError):t(this).contents())})}var g,x,y,v,b,C,T,k,H,E,W,L,S,F,I,M,R,P,K,O,_,D,B,N,z,A,j,U,$,q,G,Q,J,V,X,Y={transition:"elastic",speed:300,fadeOut:300,width:!1,initialWidth:"600",innerWidth:!1,maxWidth:!1,height:!1,initialHeight:"450",innerHeight:!1,maxHeight:!1,scalePhotos:!0,scrolling:!0,inline:!1,html:!1,iframe:!1,fastIframe:!0,photo:!1,href:!1,title:!1,rel:!1,opacity:.9,preloading:!0,className:!1,retinaImage:!1,retinaUrl:!1,retinaSuffix:"@2x.$1",current:"image {current} of {total}",previous:"previous",next:"next",close:"close",xhrError:"This content failed to load.",imgError:"This image failed to load.",open:!1,returnFocus:!0,reposition:!0,loop:!0,slideshow:!1,slideshowAuto:!0,slideshowSpeed:2500,slideshowStart:"start slideshow",slideshowStop:"stop slideshow",photoRegex:/\.(gif|png|jp(e|g|eg)|bmp|ico|webp)((#|\?).*)?$/i,onOpen:!1,onLoad:!1,onComplete:!1,onCleanup:!1,onClosed:!1,overlayClose:!0,escKey:!0,arrowKey:!0,top:!1,bottom:!1,left:!1,right:!1,fixed:!1,data:void 0},Z="colorbox",te="cbox",ee=te+"Element",ie=te+"_open",oe=te+"_load",ne=te+"_complete",re=te+"_cleanup",he=te+"_closed",le=te+"_purge",se=t(""),ae="div",de=0;t.colorbox||(t(p),J=t.fn[Z]=t[Z]=function(e,i){var o=this;if(e=e||{},p(),m()){if(t.isFunction(o))o=t(""),e.open=!0;else if(!o[0])return o;i&&(e.onComplete=i),o.each(function(){t.data(this,Z,t.extend({},t.data(this,Z)||Y,e))}).addClass(ee),(t.isFunction(e.open)&&e.open.call(o)||e.open)&&f(o[0])}return o},J.position=function(t,e){function i(t){b[0].style.width=k[0].style.width=v[0].style.width=parseInt(t.style.width,10)-B+"px",v[0].style.height=C[0].style.height=T[0].style.height=parseInt(t.style.height,10)-D+"px"}var o,r,l,s=0,a=0,d=x.offset();E.unbind("resize."+te),x.css({top:-9e4,left:-9e4}),r=E.scrollTop(),l=E.scrollLeft(),_.fixed?(d.top-=r,d.left-=l,x.css({position:"fixed"})):(s=r,a=l,x.css({position:"absolute"})),a+=_.right!==!1?Math.max(E.width()-_.w-z-B-h(_.right,"x"),0):_.left!==!1?h(_.left,"x"):Math.round(Math.max(E.width()-_.w-z-B,0)/2),s+=_.bottom!==!1?Math.max(n()-_.h-N-D-h(_.bottom,"y"),0):_.top!==!1?h(_.top,"y"):Math.round(Math.max(n()-_.h-N-D,0)/2),x.css({top:d.top,left:d.left,visibility:"visible"}),t=x.width()===_.w+z&&x.height()===_.h+N?0:t||0,y[0].style.width=y[0].style.height="9999px",o={width:_.w+z+B,height:_.h+N+D,top:s,left:a},0===t&&x.css(o),x.dequeue().animate(o,{duration:t,complete:function(){i(this),q=!1,y[0].style.width=_.w+z+B+"px",y[0].style.height=_.h+N+D+"px",_.reposition&&setTimeout(function(){E.bind("resize."+te,J.position)},1),e&&e()},step:function(){i(this)}})},J.resize=function(t){$&&(t=t||{},t.width&&(_.w=h(t.width,"x")-z-B),t.innerWidth&&(_.w=h(t.innerWidth,"x")),W.css({width:_.w}),t.height&&(_.h=h(t.height,"y")-N-D),t.innerHeight&&(_.h=h(t.innerHeight,"y")),t.innerHeight||t.height||(W.css({height:"auto"}),_.h=W.height()),W.css({height:_.h}),J.position("none"===_.transition?0:_.speed))},J.prep=function(e){function i(){return _.w=_.w||W.width(),_.w=_.mw&&_.mw<_.w?_.mw:_.w,_.w}function n(){return _.h=_.h||W.height(),_.h=_.mh&&_.mh<_.h?_.mh:_.h,_.h}if($){var h,a="none"===_.transition?0:_.speed;W.empty().remove(),W=o(ae,"LoadedContent").append(e),W.hide().appendTo(L.show()).css({width:i(),overflow:_.scrolling?"auto":"hidden"}).css({height:n()}).prependTo(v),L.hide(),t(U).css({"float":"none"}),h=function(){function e(){t.support.opacity===!1&&x[0].style.removeAttribute("filter")}var i,n,h=H.length,d="frameBorder",u="allowTransparency";$&&(n=function(){clearTimeout(Q),S.hide(),c(ne,_.onComplete)},F.html(_.title).add(W).show(),h>1?("string"==typeof _.current&&I.html(_.current.replace("{current}",j+1).replace("{total}",h)).show(),R[_.loop||h-1>j?"show":"hide"]().html(_.next),P[_.loop||j?"show":"hide"]().html(_.previous),_.slideshow&&M.show(),_.preloading&&t.each([r(-1),r(1)],function(){var e,i,o=H[this],n=t.data(o,Z);n&&n.href?(e=n.href,t.isFunction(e)&&(e=e.call(o))):e=t(o).attr("href"),e&&l(n,e)&&(e=s(n,e),i=new Image,i.src=e)})):O.hide(),_.iframe?(i=o("iframe")[0],d in i&&(i[d]=0),u in i&&(i[u]="true"),_.scrolling||(i.scrolling="no"),t(i).attr({src:_.href,name:(new Date).getTime(),"class":te+"Iframe",allowFullScreen:!0,webkitAllowFullScreen:!0,mozallowfullscreen:!0}).one("load",n).appendTo(W),se.one(le,function(){i.src="//about:blank"}),_.fastIframe&&t(i).trigger("load")):n(),"fade"===_.transition?x.fadeTo(a,1,e):e())},"fade"===_.transition?x.fadeTo(a,0,function(){J.position(0,h)}):J.position(a,h)}},J.next=function(){!q&&H[1]&&(_.loop||H[j+1])&&(j=r(1),f(H[j]))},J.prev=function(){!q&&H[1]&&(_.loop||j)&&(j=r(-1),f(H[j]))},J.close=function(){$&&!G&&(G=!0,$=!1,c(re,_.onCleanup),E.unbind("."+te),g.fadeTo(_.fadeOut||0,0),x.stop().fadeTo(_.fadeOut||0,0,function(){x.add(g).css({opacity:1,cursor:"auto"}).hide(),c(le),W.empty().remove(),setTimeout(function(){G=!1,c(he,_.onClosed)},1)}))},J.remove=function(){x&&(x.stop(),t.colorbox.close(),x.stop().remove(),g.remove(),G=!1,x=null,t("."+ee).removeData(Z).removeClass(ee),t(e).unbind("click."+te))},J.element=function(){return t(A)},J.settings=Y)})(jQuery,document,window);
\ No newline at end of file
diff --git a/contact-center/app/src/main/resources/static/js/timeliner/inc/images/border.png b/contact-center/app/src/main/resources/static/js/timeliner/inc/images/border.png
new file mode 100755
index 00000000..f463a10d
Binary files /dev/null and b/contact-center/app/src/main/resources/static/js/timeliner/inc/images/border.png differ
diff --git a/contact-center/app/src/main/resources/static/js/timeliner/inc/images/controls.png b/contact-center/app/src/main/resources/static/js/timeliner/inc/images/controls.png
new file mode 100755
index 00000000..dcfd6fb9
Binary files /dev/null and b/contact-center/app/src/main/resources/static/js/timeliner/inc/images/controls.png differ
diff --git a/contact-center/app/src/main/resources/static/js/timeliner/inc/images/loading.gif b/contact-center/app/src/main/resources/static/js/timeliner/inc/images/loading.gif
new file mode 100755
index 00000000..b4695d81
Binary files /dev/null and b/contact-center/app/src/main/resources/static/js/timeliner/inc/images/loading.gif differ
diff --git a/contact-center/app/src/main/resources/static/js/timeliner/inc/images/loading_background.png b/contact-center/app/src/main/resources/static/js/timeliner/inc/images/loading_background.png
new file mode 100755
index 00000000..6ae83e69
Binary files /dev/null and b/contact-center/app/src/main/resources/static/js/timeliner/inc/images/loading_background.png differ
diff --git a/contact-center/app/src/main/resources/static/js/timeliner/inc/images/overlay.png b/contact-center/app/src/main/resources/static/js/timeliner/inc/images/overlay.png
new file mode 100755
index 00000000..53ea98f7
Binary files /dev/null and b/contact-center/app/src/main/resources/static/js/timeliner/inc/images/overlay.png differ
diff --git a/contact-center/app/src/main/resources/static/js/timeliner/js/jquery.min.js b/contact-center/app/src/main/resources/static/js/timeliner/js/jquery.min.js
new file mode 100644
index 00000000..198b3ff0
--- /dev/null
+++ b/contact-center/app/src/main/resources/static/js/timeliner/js/jquery.min.js
@@ -0,0 +1,4 @@
+/*! jQuery v1.7.1 jquery.com | jquery.org/license */
+(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"":"")+""),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){if(c!=="border")for(;g=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
a",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="
内容:Content about the event goes here.Content about the event goes here.Content about the event goes here.Content about the event goes here.Content about the event goes here.