DEFMARK – Company of iVisioned.com

Custom Size – 1

.mediaViewInfo {
–web-view-name: Custom Size – 1;
–web-view-id: Custom_Size__1;
–web-scale-on-resize: true;
–web-enable-deep-linking: true;
}
:root {
–web-view-ids: Custom_Size__1;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
border: none;
}
#Custom_Size__1 {
position: absolute;
width: 1599px;
height: 913px;
background: linear-gradient(135deg, rgba(0,0,0,1) 0%, rgba(80,80,80,1) 62.41%, rgba(128,128,128,1) 100%);
overflow: hidden;
–web-view-name: Custom Size – 1;
–web-view-id: Custom_Size__1;
–web-scale-on-resize: true;
–web-enable-deep-linking: true;
}
#About {
opacity: 0.65;
left: 757px;
top: 60px;
position: absolute;
overflow: visible;
width: 55px;
white-space: nowrap;
text-align: left;
font-family: Segoe UI;
font-style: normal;
font-weight: normal;
font-size: 20px;
color: rgba(255,255,255,1);
}
#TVRadio {
opacity: 0.65;
left: 871px;
top: 60px;
position: absolute;
overflow: visible;
width: 83px;
white-space: nowrap;
text-align: left;
font-family: Segoe UI;
font-style: normal;
font-weight: normal;
font-size: 20px;
color: rgba(255,255,255,1);
}
#Fashion {
opacity: 0.65;
left: 1013px;
top: 60px;
position: absolute;
overflow: visible;
width: 68px;
white-space: nowrap;
text-align: left;
font-family: Segoe UI;
font-style: normal;
font-weight: normal;
font-size: 20px;
color: rgba(255,255,255,1);
}
#Lifestyle {
opacity: 0.65;
left: 1140px;
top: 60px;
position: absolute;
overflow: visible;
width: 72px;
white-space: nowrap;
text-align: left;
font-family: Segoe UI;
font-style: normal;
font-weight: normal;
font-size: 20px;
color: rgba(255,255,255,1);
}
#Blog {
opacity: 0.65;
left: 1271px;
top: 60px;
position: absolute;
overflow: visible;
width: 41px;
white-space: nowrap;
text-align: left;
font-family: Segoe UI;
font-style: normal;
font-weight: normal;
font-size: 20px;
color: rgba(255,255,255,1);
}
#Shop {
opacity: 0.65;
left: 1371px;
top: 60px;
position: absolute;
overflow: visible;
width: 46px;
white-space: nowrap;
text-align: left;
font-family: Segoe UI;
font-style: normal;
font-weight: normal;
font-size: 20px;
color: rgba(255,255,255,1);
}
#Ellipse_2 {
fill: rgba(255,255,255,1);
stroke: rgba(112,112,112,1);
stroke-width: 1px;
stroke-linejoin: miter;
stroke-linecap: butt;
stroke-miterlimit: 4;
shape-rendering: auto;
}
.Ellipse_2 {
position: absolute;
overflow: visible;
width: 18.845px;
height: 0px;
left: 29px;
top: 164px;
}
#Icon_awesome-search {
opacity: 0.65;
fill: rgba(255,255,255,1);
}
.Icon_awesome-search {
overflow: visible;
position: absolute;
width: 19px;
height: 19px;
left: 1476px;
top: 64px;
transform: matrix(1,0,0,1,0,0);
}
#Home {
left: 643px;
top: 60px;
position: absolute;
overflow: visible;
width: 55px;
white-space: nowrap;
text-align: left;
font-family: Segoe UI;
font-style: normal;
font-weight: normal;
font-size: 20px;
color: rgba(239,200,98,1);
}
#Line_1 {
fill: transparent;
stroke: rgba(239,200,98,1);
stroke-width: 1px;
stroke-linejoin: miter;
stroke-linecap: butt;
stroke-miterlimit: 4;
shape-rendering: auto;
}
.Line_1 {
overflow: visible;
position: absolute;
width: 74.512px;
height: 1.869px;
left: 632.75px;
top: 107px;
transform: matrix(1,0,0,1,0,0);
}
#photo {
mix-blend-mode: hard-light;
position: absolute;
width: 98px;
height: 98px;
left: 673px;
top: 359px;
overflow: visible;
}
#Untitled_design_2 {
opacity: 0.85;
position: absolute;
width: 1599px;
height: 999.212px;
left: 0px;
top: 279.5px;
overflow: visible;
}
#Rectangle_1 {
opacity: 0.35;
fill: rgba(49,49,50,0);
stroke: rgba(112,112,112,1);
stroke-width: 1px;
stroke-linejoin: miter;
stroke-linecap: butt;
stroke-miterlimit: 4;
shape-rendering: auto;
}
.Rectangle_1 {
mix-blend-mode: multiply;
filter: drop-shadow(0px 3px 6px rgba(0, 0, 0, 0.161));
position: absolute;
overflow: visible;
width: 791px;
height: 292px;
left: 722px;
top: 271px;
}
#n_Theres_still_time_to_fulfill {
opacity: 0.65;
left: 866px;
top: 503px;
position: absolute;
overflow: visible;
width: 487px;
white-space: nowrap;
text-align: left;
font-family: Lucida Handwriting;
font-style: italic;
font-weight: normal;
font-size: 18px;
color: rgba(255,255,255,1);
letter-spacing: 1.1px;
}
#Path_1 {
fill: rgba(49,49,50,0);
stroke: rgba(112,112,112,1);
stroke-width: 1px;
stroke-linejoin: miter;
stroke-linecap: butt;
stroke-miterlimit: 4;
shape-rendering: auto;
}
.Path_1 {
mix-blend-mode: multiply;
filter: drop-shadow(0px 3px 6px rgba(0, 0, 0, 0.161));
overflow: visible;
position: absolute;
width: 504px;
height: 428px;
left: 95px;
top: 211px;
transform: matrix(1,0,0,1,0,0);
}
#M__A__R__K__E__T__I__N__G {
opacity: 0.3;
left: 225px;
top: 301px;
position: absolute;
overflow: visible;
width: 306px;
white-space: nowrap;
text-align: left;
font-family: Segoe UI;
font-style: normal;
font-weight: normal;
font-size: 31px;
color: rgba(255,255,255,1);
}
#D_I_G_I_T_A_L_ {
opacity: 0.48;
left: 137px;
top: 248px;
position: absolute;
overflow: visible;
width: 258px;
white-space: nowrap;
text-align: left;
font-family: Segoe UI;
font-style: normal;
font-weight: normal;
font-size: 47px;
color: rgba(255,255,255,1);
}
#Icon_awesome-arrow-alt-circle- {
fill: rgba(112,112,112,1);
}
.Icon_awesome-arrow-alt-circle- {
overflow: visible;
position: absolute;
width: 34.875px;
height: 34.875px;
left: 431.563px;
top: 266.125px;
transform: matrix(1,0,0,1,0,0);
}
#AdobeStock_81237497 {
opacity: 0.65;
mix-blend-mode: lighten;
position: absolute;
width: 389px;
height: 218px;
left: 125px;
top: 348px;
overflow: visible;
}
#N_E_X_T {
left: 270px;
top: 31px;
position: absolute;
overflow: visible;
width: 180px;
white-space: nowrap;
text-align: left;
font-family: Segoe UI;
font-style: normal;
font-weight: normal;
font-size: 56px;
color: rgba(255,255,255,0);
}
#B__I__G {
left: 286.5px;
top: 39px;
position: absolute;
overflow: visible;
width: 268px;
white-space: nowrap;
text-align: left;
font-family: Segoe UI;
font-style: normal;
font-weight: normal;
font-size: 102px;
color: rgba(255,255,255,0);
}
#T_H_I_N_G {
left: 319.5px;
top: 107px;
position: absolute;
overflow: visible;
width: 235px;
white-space: nowrap;
text-align: left;
font-family: Segoe UI;
font-style: normal;
font-weight: normal;
font-size: 58px;
color: rgba(255,255,255,0);
}
#THE {
opacity: 0.6;
left: 273px;
top: 31px;
position: absolute;
overflow: visible;
width: 34px;
white-space: nowrap;
text-align: left;
font-family: Segoe UI;
font-style: normal;
font-weight: normal;
font-size: 19px;
color: rgba(239,200,98,1);
}
#Icon_awesome-facebook {
opacity: 0.65;
fill: rgba(255,255,255,1);
stroke: rgba(112,112,112,1);
stroke-width: 1px;
stroke-linejoin: miter;
stroke-linecap: butt;
stroke-miterlimit: 4;
shape-rendering: auto;
}
.Icon_awesome-facebook {
overflow: visible;
position: absolute;
width: 35.875px;
height: 35.749px;
left: 802.358px;
top: 588.39px;
transform: matrix(1,0,0,1,0,0);
}
#Icon_awesome-instagram {
opacity: 0.65;
fill: rgba(255,255,255,1);
stroke: rgba(112,112,112,1);
stroke-width: 1px;
stroke-linejoin: miter;
stroke-linecap: butt;
stroke-miterlimit: 4;
shape-rendering: auto;
}
.Icon_awesome-instagram {
overflow: visible;
position: absolute;
width: 32.665px;
height: 32.658px;
left: 927.483px;
top: 589.966px;
transform: matrix(1,0,0,1,0,0);
}
#Icon_awesome-twitter {
fill: rgba(0,0,0,1);
}
.Icon_awesome-twitter {
overflow: visible;
position: absolute;
width: 36px;
height: 29.239px;
left: 43.2px;
top: 0px;
transform: matrix(1,0,0,1,0,0);
}
#Icon_awesome-twitter_bb {
opacity: 0.65;
fill: rgba(255,255,255,1);
stroke: rgba(112,112,112,1);
stroke-width: 1px;
stroke-linejoin: miter;
stroke-linecap: butt;
stroke-miterlimit: 4;
shape-rendering: auto;
}
.Icon_awesome-twitter_bb {
overflow: visible;
position: absolute;
width: 37.664px;
height: 30.297px;
left: 1049.25px;
top: 592.238px;
transform: matrix(1,0,0,1,0,0);
}
#Icon_awesome-pinterest {
opacity: 0.65;
fill: rgba(255,255,255,1);
stroke: rgba(112,112,112,1);
stroke-width: 1px;
stroke-linejoin: miter;
stroke-linecap: butt;
stroke-miterlimit: 4;
shape-rendering: auto;
}
.Icon_awesome-pinterest {
overflow: visible;
position: absolute;
width: 35.875px;
height: 35.875px;
left: 1175.5px;
top: 589.42px;
transform: matrix(1,0,0,1,0,0);
}
#Icon_simple-tiktok {
opacity: 0.65;
fill: rgba(255,255,255,1);
stroke: rgba(112,112,112,1);
stroke-width: 1px;
stroke-linejoin: miter;
stroke-linecap: butt;
stroke-miterlimit: 4;
shape-rendering: auto;
}
.Icon_simple-tiktok {
mix-blend-mode: screen;
overflow: visible;
position: absolute;
width: 35.879px;
height: 35.664px;
left: 1300.625px;
top: 588.39px;
transform: matrix(1,0,0,1,0,0);
}
#Ellipse_4 {
opacity: 0.4;
fill: rgba(255,255,255,0.722);
stroke: rgba(112,112,112,1);
stroke-width: 1px;
stroke-linejoin: miter;
stroke-linecap: butt;
stroke-miterlimit: 4;
shape-rendering: auto;
}
.Ellipse_4 {
position: absolute;
overflow: visible;
width: 8px;
height: 9px;
left: 310px;
top: 584px;
}
#Ellipse_5 {
fill: rgba(255,255,255,0.722);
stroke: rgba(112,112,112,1);
stroke-width: 1px;
stroke-linejoin: miter;
stroke-linecap: butt;
stroke-miterlimit: 4;
shape-rendering: auto;
}
.Ellipse_5 {
position: absolute;
overflow: visible;
width: 8px;
height: 9px;
left: 268px;
top: 584px;
}
#Ellipse_6 {
opacity: 0.4;
fill: rgba(255,255,255,0.722);
stroke: rgba(112,112,112,1);
stroke-width: 1px;
stroke-linejoin: miter;
stroke-linecap: butt;
stroke-miterlimit: 4;
shape-rendering: auto;
}
.Ellipse_6 {
position: absolute;
overflow: visible;
width: 8px;
height: 9px;
left: 352px;
top: 584px;
}
#Ellipse_7 {
opacity: 0.4;
fill: rgba(255,255,255,0.722);
stroke: rgba(112,112,112,1);
stroke-width: 1px;
stroke-linejoin: miter;
stroke-linecap: butt;
stroke-miterlimit: 4;
shape-rendering: auto;
}
.Ellipse_7 {
position: absolute;
overflow: visible;
width: 8px;
height: 9px;
left: 394px;
top: 584px;
}
#Developed__Designed_by_Talha_S {
left: 626px;
top: 632px;
position: absolute;
overflow: visible;
width: 317px;
white-space: nowrap;
text-align: center;
font-family: Segoe UI;
font-style: normal;
font-weight: normal;
font-size: 13px;
color: rgba(239,200,98,1);
}
#n_CEF89E6-51CA-4653-A843-5D271 {
position: absolute;
width: 235px;
height: 235px;
left: 71px;
top: -12px;
overflow: visible;
}
#Icon_material-arrow-drop-up {
opacity: 0.65;
fill: rgba(255,255,255,1);
}
.Icon_material-arrow-drop-up {
overflow: visible;
position: absolute;
width: 15px;
height: 7.5px;
left: 959.5px;
top: 73.5px;
transform: matrix(1,0,0,1,0,0);
}
#He_is_a_Pakistani_American_Bus {
opacity: 0.65;
left: 817px;
top: 327px;
position: absolute;
overflow: visible;
width: 585px;
white-space: nowrap;
line-height: 21px;
margin-top: -3.5px;
text-align: center;
font-family: Segoe UI;
font-style: normal;
font-weight: normal;
font-size: 14px;
color: rgba(255,255,255,1);
letter-spacing: 2px;
}
#T_A_L_H_A___S_A_K_R_A_N_I {
opacity: 0.65;
left: 811px;
top: 290px;
position: absolute;
overflow: visible;
width: 598px;
white-space: nowrap;
text-align: left;
font-family: Lucida Handwriting;
font-style: italic;
font-weight: normal;
font-size: 20px;
color: rgba(255,255,255,1);
letter-spacing: 7px;
}

///////////////////////////////////////
// INITIALIZATION
///////////////////////////////////////

/**
* Functionality for scaling, showing by media query, and navigation between multiple pages on a single page.
* Code subject to change.
**/

if (window.console==null) { window[“console”] = { log : function() {} } }; // some browsers do not set console

var Application = function() {
// event constants
this.prefix = “–web-“;
this.NAVIGATION_CHANGE = “viewChange”;
this.VIEW_NOT_FOUND = “viewNotFound”;
this.VIEW_CHANGE = “viewChange”;
this.VIEW_CHANGING = “viewChanging”;
this.STATE_NOT_FOUND = “stateNotFound”;
this.APPLICATION_COMPLETE = “applicationComplete”;
this.APPLICATION_RESIZE = “applicationResize”;
this.SIZE_STATE_NAME = “data-is-view-scaled”;
this.STATE_NAME = this.prefix + “state”;

this.lastTrigger = null;
this.lastView = null;
this.lastState = null;
this.lastOverlay = null;
this.currentView = null;
this.currentState = null;
this.currentOverlay = null;
this.currentQuery = {index: 0, rule: null, mediaText: null, id: null};
this.inclusionQuery = “(min-width: 0px)”;
this.exclusionQuery = “none and (min-width: 99999px)”;
this.LastModifiedDateLabelName = “LastModifiedDateLabel”;
this.viewScaleSliderId = “ViewScaleSliderInput”;
this.pageRefreshedName = “showPageRefreshedNotification”;
this.application = null;
this.applicationStylesheet = null;
this.showByMediaQuery = null;
this.mediaQueryDictionary = {};
this.viewsDictionary = {};
this.addedViews = [];
this.viewStates = [];
this.views = [];
this.viewIds = [];
this.viewQueries = {};
this.overlays = {};
this.overlayIds = [];
this.numberOfViews = 0;
this.verticalPadding = 0;
this.horizontalPadding = 0;
this.stateName = null;
this.viewScale = 1;
this.viewLeft = 0;
this.viewTop = 0;
this.horizontalScrollbarsNeeded = false;
this.verticalScrollbarsNeeded = false;

// view settings
this.showUpdateNotification = false;
this.showNavigationControls = false;
this.scaleViewsToFit = false;
this.scaleToFitOnDoubleClick = false;
this.actualSizeOnDoubleClick = false;
this.scaleViewsOnResize = false;
this.navigationOnKeypress = false;
this.showViewName = false;
this.enableDeepLinking = true;
this.refreshPageForChanges = false;
this.showRefreshNotifications = true;

// view controls
this.scaleViewSlider = null;
this.lastModifiedLabel = null;
this.supportsPopState = false; // window.history.pushState!=null;
this.initialized = false;

// refresh properties
this.refreshDuration = 250;
this.lastModifiedDate = null;
this.refreshRequest = null;
this.refreshInterval = null;
this.refreshContent = null;
this.refreshContentSize = null;
this.refreshCheckContent = false;
this.refreshCheckContentSize = false;

var self = this;

self.initialize = function(event) {
var view = self.getVisibleView();
var views = self.getVisibleViews();
if (view==null) view = self.getInitialView();
self.collectViews();
self.collectOverlays();
self.collectMediaQueries();

for (let index = 0; index < views.length; index++) {
var view = views[index];
self.setViewOptions(view);
self.setViewVariables(view);
self.centerView(view);
}

// sometimes the body size is 0 so we call this now and again later
if (self.initialized) {
window.addEventListener(self.NAVIGATION_CHANGE, self.viewChangeHandler);
window.addEventListener("keyup", self.keypressHandler);
window.addEventListener("keypress", self.keypressHandler);
window.addEventListener("resize", self.resizeHandler);
window.document.addEventListener("dblclick", self.doubleClickHandler);

if (self.supportsPopState) {
window.addEventListener('popstate', self.popStateHandler);
}
else {
window.addEventListener('hashchange', self.hashChangeHandler);
}

// we are ready to go
window.dispatchEvent(new Event(self.APPLICATION_COMPLETE));
}

if (self.initialized==false) {
if (self.enableDeepLinking) {
self.syncronizeViewToURL();
}

if (self.refreshPageForChanges) {
self.setupRefreshForChanges();
}

self.initialized = true;
}

if (self.scaleViewsToFit) {
self.viewScale = self.scaleViewToFit(view);

if (self.viewScale<0) {
setTimeout(self.scaleViewToFit, 500, view);
}
}
else if (view) {
self.viewScale = self.getViewScaleValue(view);
self.centerView(view);
self.updateSliderValue(self.viewScale);
}
else {
// no view found
}

if (self.showUpdateNotification) {
self.showNotification();
}

//"addEventListener" in window ? null : window.addEventListener = window.attachEvent;
//"addEventListener" in document ? null : document.addEventListener = document.attachEvent;
}

///////////////////////////////////////
// AUTO REFRESH
///////////////////////////////////////

self.setupRefreshForChanges = function() {
self.refreshRequest = new XMLHttpRequest();

if (!self.refreshRequest) {
return false;
}

// get document start values immediately
self.requestRefreshUpdate();
}

/**
* Attempt to check the last modified date by the headers
* or the last modified property from the byte array (experimental)
**/
self.requestRefreshUpdate = function() {
var url = document.location.href;
var protocol = window.location.protocol;
var method;

try {

if (self.refreshCheckContentSize) {
self.refreshRequest.open('HEAD', url, true);
}
else if (self.refreshCheckContent) {
self.refreshContent = document.documentElement.outerHTML;
self.refreshRequest.open('GET', url, true);
self.refreshRequest.responseType = "text";
}
else {

// get page last modified date for the first call to compare to later
if (self.lastModifiedDate==null) {

// File system does not send headers in FF so get blob if possible
if (protocol=="file:") {
self.refreshRequest.open("GET", url, true);
self.refreshRequest.responseType = "blob";
}
else {
self.refreshRequest.open("HEAD", url, true);
self.refreshRequest.responseType = "blob";
}

self.refreshRequest.onload = self.refreshOnLoadOnceHandler;

// In some browsers (Chrome & Safari) this error occurs at send:
//
// Chrome – Access to XMLHttpRequest at 'file:///index.html' from origin 'null'
// has been blocked by CORS policy:
// Cross origin requests are only supported for protocol schemes:
// http, data, chrome, chrome-extension, https.
//
// Safari – XMLHttpRequest cannot load file:///Users/user/Public/index.html. Cross origin requests are only supported for HTTP.
//
// Solution is to run a local server, set local permissions or test in another browser
self.refreshRequest.send(null);

// In MS browsers the following behavior occurs possibly due to an AJAX call to check last modified date:
//
// DOM7011: The code on this page disabled back and forward caching.

// In Brave (Chrome) error when on the server
// index.js:221 HEAD https://www.example.com/ net::ERR_INSUFFICIENT_RESOURCES
// self.refreshRequest.send(null);

}
else {
self.refreshRequest = new XMLHttpRequest();
self.refreshRequest.onreadystatechange = self.refreshHandler;
self.refreshRequest.ontimeout = function() {
self.log("Couldn't find page to check for updates");
}

var method;
if (protocol=="file:") {
method = "GET";
}
else {
method = "HEAD";
}

//refreshRequest.open('HEAD', url, true);
self.refreshRequest.open(method, url, true);
self.refreshRequest.responseType = "blob";
self.refreshRequest.send(null);
}
}
}
catch (error) {
self.log("Refresh failed for the following reason:")
self.log(error);
}
}

self.refreshHandler = function() {
var contentSize;

try {

if (self.refreshRequest.readyState === XMLHttpRequest.DONE) {

if (self.refreshRequest.status === 2 ||
self.refreshRequest.status === 200) {
var pageChanged = false;

self.updateLastModifiedLabel();

if (self.refreshCheckContentSize) {
var lastModifiedHeader = self.refreshRequest.getResponseHeader("Last-Modified");
contentSize = self.refreshRequest.getResponseHeader("Content-Length");
//lastModifiedDate = refreshRequest.getResponseHeader("Last-Modified");
var headers = self.refreshRequest.getAllResponseHeaders();
var hasContentHeader = headers.indexOf("Content-Length")!=-1;

if (hasContentHeader) {
contentSize = self.refreshRequest.getResponseHeader("Content-Length");

// size has not been set yet
if (self.refreshContentSize==null) {
self.refreshContentSize = contentSize;
// exit and let interval call this method again
return;
}

if (contentSize!=self.refreshContentSize) {
pageChanged = true;
}
}
}
else if (self.refreshCheckContent) {

if (self.refreshRequest.responseText!=self.refreshContent) {
pageChanged = true;
}
}
else {
lastModifiedHeader = self.getLastModified(self.refreshRequest);

if (self.lastModifiedDate!=lastModifiedHeader) {
self.log("lastModifiedDate:" + self.lastModifiedDate + ",lastModifiedHeader:" +lastModifiedHeader);
pageChanged = true;
}

}

if (pageChanged) {
clearInterval(self.refreshInterval);
self.refreshUpdatedPage();
return;
}

}
else {
self.log('There was a problem with the request.');
}

}
}
catch( error ) {
//console.log('Caught Exception: ' + error);
}
}

self.refreshOnLoadOnceHandler = function(event) {

// get the last modified date
if (self.refreshRequest.response) {
self.lastModifiedDate = self.getLastModified(self.refreshRequest);

if (self.lastModifiedDate!=null) {

if (self.refreshInterval==null) {
self.refreshInterval = setInterval(self.requestRefreshUpdate, self.refreshDuration);
}
}
else {
self.log("Could not get last modified date from the server");
}
}
}

self.refreshUpdatedPage = function() {
if (self.showRefreshNotifications) {
var date = new Date().setTime((new Date().getTime()+10000));
document.cookie = encodeURIComponent(self.pageRefreshedName) + "=true" + "; max-age=6000;" + " path=/";
}

document.location.reload(true);
}

self.showNotification = function(duration) {
var notificationID = self.pageRefreshedName+"ID";
var notification = document.getElementById(notificationID);
if (duration==null) duration = 4000;

if (notification!=null) {return;}

notification = document.createElement("div");
notification.id = notificationID;
notification.textContent = "PAGE UPDATED";
var styleRule = ""
styleRule = "position: fixed; padding: 7px 16px 6px 16px; font-family: Arial, sans-serif; font-size: 10px; font-weight: bold; left: 50%;";
styleRule += "top: 20px; background-color: rgba(0,0,0,.5); border-radius: 12px; color:rgb(235, 235, 235); transition: all 2s linear;";
styleRule += "transform: translateX(-50%); letter-spacing: .5px; filter: drop-shadow(2px 2px 6px rgba(0, 0, 0, .1)); cursor: pointer";
notification.setAttribute("style", styleRule);

notification.className = "PageRefreshedClass";
notification.addEventListener("click", function() {
notification.parentNode.removeChild(notification);
});

document.body.appendChild(notification);

setTimeout(function() {
notification.style.opacity = "0";
notification.style.filter = "drop-shadow( 0px 0px 0px rgba(0,0,0, .5))";
setTimeout(function() {
try {
notification.parentNode.removeChild(notification);
} catch(error) {}
}, duration)
}, duration);

document.cookie = encodeURIComponent(self.pageRefreshedName) + "=; max-age=1; path=/";
}

/**
* Get the last modified date from the header
* or file object after request has been received
**/
self.getLastModified = function(request) {
var date;

// file protocol – FILE object with last modified property
if (request.response && request.response.lastModified) {
date = request.response.lastModified;
}

// http protocol – check headers
if (date==null) {
date = request.getResponseHeader("Last-Modified");
}

return date;
}

self.updateLastModifiedLabel = function() {
var labelValue = "";

if (self.lastModifiedLabel==null) {
self.lastModifiedLabel = document.getElementById("LastModifiedLabel");
}

if (self.lastModifiedLabel) {
var seconds = parseInt(((new Date().getTime() – Date.parse(document.lastModified)) / 1000 / 60) * 100 + "");
var minutes = 0;
var hours = 0;

if (seconds 60) {
hours = parseInt((seconds/60/60) +””);
labelValue += hours==1 ? ” hour” : ” hours”;
}
else {
labelValue = minutes+””;
labelValue += minutes==1 ? ” minute” : ” minutes”;
}
}

if (seconds<10) {
labelValue = "Updated now";
}
else {
labelValue = "Updated " + labelValue + " ago";
}

if (self.lastModifiedLabel.firstElementChild) {
self.lastModifiedLabel.firstElementChild.textContent = labelValue;

}
else if ("textContent" in self.lastModifiedLabel) {
self.lastModifiedLabel.textContent = labelValue;
}
}
}

self.getShortString = function(string, length) {
if (length==null) length = 30;
string = string!=null ? string.substr(0, length).replace(/\n/g, "") : "[String is null]";
return string;
}

self.getShortNumber = function(value, places) {
if (places==null || places1 && self.enableDeepLinking) {

if (self.supportsPopState==false) {
self.setFragment(viewId);
}
else {
if (viewFragment!=window.location.hash) {

if (window.location.hash==null) {
window.history.replaceState({name:viewId}, null, viewFragment);
}
else {
window.history.pushState({name:viewId}, null, viewFragment);
}
}
}
}
}

self.updateURLState = function(view, stateName) {
stateName = view && (stateName==”” || stateName==null) ? self.getStateNameByViewId(view.id) : stateName;

if (self.supportsPopState==false) {
self.setFragment(stateName);
}
else {
if (stateName!=window.location.hash) {

if (window.location.hash==null) {
window.history.replaceState({name:view.viewId}, null, stateName);
}
else {
window.history.pushState({name:view.viewId}, null, stateName);
}
}
}
}

self.setFragment = function(value) {
window.location.hash = “#” + value;
}

self.setTooltip = function(element, value) {
// setting the tooltip in edge causes a page crash on hover
if (/Edge/.test(navigator.userAgent)) { return; }

if (“title” in element) {
element.title = value;
}
}

self.getStylesheetRules = function(styleSheet) {
try {
if (styleSheet) return styleSheet.cssRules || styleSheet.rules;

return document.styleSheets[0][“cssRules”] || document.styleSheets[0][“rules”];
}
catch (error) {
// ERRORS:
// SecurityError: The operation is insecure.
// Errors happen when script loads before stylesheet or loading an external css locally

// InvalidAccessError: A parameter or an operation is not supported by the underlying object
// Place script after stylesheet

console.log(error);
if (error.toString().indexOf(“The operation is insecure”)!=-1) {
console.log(“Load the stylesheet before the script or load the stylesheet inline until it can be loaded on a server”)
}
return [];
}
}

/**
* If single page application hide all of the views.
* @param {Number} selectedIndex if provided shows the view at index provided
**/
self.hideViews = function(selectedIndex, animation) {
var rules = self.getStylesheetRules();
var queryIndex = 0;
var numberOfRules = rules!=null ? rules.length : 0;

// loop through rules and hide media queries except selected
for (var i=0;i<numberOfRules;i++) {
var rule = rules[i];
var cssText = rule && rule.cssText;

if (rule.media!=null && cssText.match("–web-view-name:")) {

if (queryIndex==selectedIndex) {
self.currentQuery.mediaText = rule.conditionText;
self.currentQuery.index = selectedIndex;
self.currentQuery.rule = rule;
self.enableMediaQuery(rule);
}
else {
if (animation) {
self.fadeOut(rule)
}
else {
self.disableMediaQuery(rule);
}
}

queryIndex++;
}
}

self.numberOfViews = queryIndex;
self.updateViewLabel();
self.updateURL();

self.dispatchViewChange();

var view = self.getVisibleView();
var viewIndex = view ? self.getViewIndex(view) : -1;

return viewIndex==selectedIndex ? view : null;
}

/**
* If single page application hide all of the views.
* @param {HTMLElement} selectedView if provided shows the view passed in
**/
self.hideAllViews = function(selectedView, animation) {
var views = self.views;
var queryIndex = 0;
var numberOfViews = views!=null ? views.length : 0;

// loop through rules and hide media queries except selected
for (var i=0;i<numberOfViews;i++) {
var viewData = views[i];
var view = viewData && viewData.view;
var mediaRule = viewData && viewData.mediaRule;

if (view==selectedView) {
self.currentQuery.mediaText = mediaRule.conditionText;
self.currentQuery.index = queryIndex;
self.currentQuery.rule = mediaRule;
self.enableMediaQuery(mediaRule);
}
else {
if (animation) {
self.fadeOut(mediaRule)
}
else {
self.disableMediaQuery(mediaRule);
}
}

queryIndex++;
}

self.numberOfViews = queryIndex;
self.updateViewLabel();
self.updateURL();
self.dispatchViewChange();

var visibleView = self.getVisibleView();

return visibleView==selectedView ? selectedView : null;
}

/**
* Hide view
* @param {Object} view element to hide
**/
self.hideView = function(view) {
var rule = view ? self.mediaQueryDictionary[view.id] : null;

if (rule) {
self.disableMediaQuery(rule);
}
}

/**
* Hide overlay
* @param {Object} overlay element to hide
**/
self.hideOverlay = function(overlay) {
var rule = overlay ? self.mediaQueryDictionary[overlay.id] : null;

if (rule) {
self.disableMediaQuery(rule);

//if (self.showByMediaQuery) {
overlay.style.display = "none";
//}
}
}

/**
* Show the view by media query. Does not hide current views
* Sets view options by default
* @param {Object} view element to show
* @param {Boolean} setViewOptions sets view options if null or true
*/
self.showViewByMediaQuery = function(view, setViewOptions) {
var id = view ? view.id : null;
var query = id ? self.mediaQueryDictionary[id] : null;
var isOverlay = view ? self.isOverlay(view) : false;
setViewOptions = setViewOptions==null ? true : setViewOptions;

if (query) {
self.enableMediaQuery(query);

if (isOverlay && view && setViewOptions) {
self.setViewVariables(null, view);
}
else {
if (view && setViewOptions) self.setViewOptions(view);
if (view && setViewOptions) self.setViewVariables(view);
}
}
}

/**
* Show the view. Does not hide current views
*/
self.showView = function(view, setViewOptions) {
var id = view ? view.id : null;
var query = id ? self.mediaQueryDictionary[id] : null;
var display = null;
setViewOptions = setViewOptions==null ? true : setViewOptions;

if (query) {
self.enableMediaQuery(query);
if (view==null) view =self.getVisibleView();
if (view && setViewOptions) self.setViewOptions(view);
}
else if (id) {
display = window.getComputedStyle(view).getPropertyValue("display");
if (display=="" || display=="none") {
view.style.display = "block";
}
}

if (view) {
if (self.currentView!=null) {
self.lastView = self.currentView;
}

self.currentView = view;
}
}

self.showViewById = function(id, setViewOptions) {
var view = id ? self.getViewById(id) : null;

if (view) {
self.showView(view);
return;
}

self.log("View not found '" + id + "'");
}

self.getElementView = function(element) {
var view = element;
var viewFound = false;

while (viewFound==false || view==null) {
if (view && self.viewsDictionary[view.id]) {
return view;
}
view = view.parentNode;
}
}

/**
* Show overlay over view
* @param {Event | HTMLElement} event event or html element with styles applied
* @param {String} id id of view or view reference
* @param {Number} x x location
* @param {Number} y y location
*/
self.showOverlay = function(event, id, x, y) {
var overlay = id && typeof id === 'string' ? self.getViewById(id) : id ? id : null;
var query = overlay ? self.mediaQueryDictionary[overlay.id] : null;
var centerHorizontally = false;
var centerVertically = false;
var anchorLeft = false;
var anchorTop = false;
var anchorRight = false;
var anchorBottom = false;
var display = null;
var reparent = true;
var view = null;

if (overlay==null || overlay==false) {
self.log("Overlay not found, '"+ id + "'");
return;
}

// get enter animation – event target must have css variables declared
if (event) {
var button = event.currentTarget || event; // can be event or htmlelement
var buttonComputedStyles = getComputedStyle(button);
var actionTargetValue = buttonComputedStyles.getPropertyValue(self.prefix+"action-target").trim();
var animation = buttonComputedStyles.getPropertyValue(self.prefix+"animation").trim();
var isAnimated = animation!="";
var targetType = buttonComputedStyles.getPropertyValue(self.prefix+"action-type").trim();
var actionTarget = self.application ? null : self.getElement(actionTargetValue);
var actionTargetStyles = actionTarget ? actionTarget.style : null;

if (actionTargetStyles) {
actionTargetStyles.setProperty("animation", animation);
}

if ("stopImmediatePropagation" in event) {
event.stopImmediatePropagation();
}
}

if (self.application==false || targetType=="page") {
document.location.href = "./" + actionTargetValue;
return;
}

// remove any current overlays
if (self.currentOverlay) {

// act as switch if same button
if (self.currentOverlay==actionTarget || self.currentOverlay==null) {
if (self.lastTrigger==button) {
self.removeOverlay(isAnimated);
return;
}
}
else {
self.removeOverlay(isAnimated);
}
}

if (reparent) {
view = self.getElementView(button);
if (view) {
view.appendChild(overlay);
}
}

if (query) {
//self.setElementAnimation(overlay, null);
//overlay.style.animation = animation;
self.enableMediaQuery(query);

var display = overlay && overlay.style.display;

if (overlay && display=="" || display=="none") {
overlay.style.display = "block";
//self.setViewOptions(overlay);
}

// add animation defined in event target style declaration
if (animation && self.supportAnimations) {
self.fadeIn(overlay, false, animation);
}
}
else if (id) {

display = window.getComputedStyle(overlay).getPropertyValue("display");

if (display=="" || display=="none") {
overlay.style.display = "block";
}

// add animation defined in event target style declaration
if (animation && self.supportAnimations) {
self.fadeIn(overlay, false, animation);
}
}

// do not set x or y position if centering
var horizontal = self.prefix + "center-horizontally";
var vertical = self.prefix + "center-vertically";
var style = overlay.style;
var transform = [];

centerHorizontally = self.getIsStyleDefined(id, horizontal) ? self.getViewPreferenceBoolean(overlay, horizontal) : false;
centerVertically = self.getIsStyleDefined(id, vertical) ? self.getViewPreferenceBoolean(overlay, vertical) : false;
anchorLeft = self.getIsStyleDefined(id, "left");
anchorRight = self.getIsStyleDefined(id, "right");
anchorTop = self.getIsStyleDefined(id, "top");
anchorBottom = self.getIsStyleDefined(id, "bottom");

if (self.viewsDictionary[overlay.id] && self.viewsDictionary[overlay.id].styleDeclaration) {
style = self.viewsDictionary[overlay.id].styleDeclaration.style;
}

if (centerHorizontally) {
style.left = "50%";
style.transformOrigin = "0 0";
transform.push("translateX(-50%)");
}
else if (anchorRight && anchorLeft) {
style.left = x + "px";
}
else if (anchorRight) {
//style.right = x + "px";
}
else {
style.left = x + "px";
}

if (centerVertically) {
style.top = "50%";
transform.push("translateY(-50%)");
style.transformOrigin = "0 0";
}
else if (anchorTop && anchorBottom) {
style.top = y + "px";
}
else if (anchorBottom) {
//style.bottom = y + "px";
}
else {
style.top = y + "px";
}

if (transform.length) {
style.transform = transform.join(" ");
}

self.currentOverlay = overlay;
self.lastTrigger = button;
}

self.goBack = function() {
if (self.currentOverlay) {
self.removeOverlay();
}
else if (self.lastView) {
self.goToView(self.lastView.id);
}
}

self.removeOverlay = function(animate) {
var overlay = self.currentOverlay;
animate = animate===false ? false : true;

if (overlay) {
var style = overlay.style;

if (style.animation && self.supportAnimations && animate) {
self.reverseAnimation(overlay, true);

var duration = self.getAnimationDuration(style.animation, true);

setTimeout(function() {
self.setElementAnimation(overlay, null);
self.hideOverlay(overlay);
self.currentOverlay = null;
}, duration);
}
else {
self.setElementAnimation(overlay, null);
self.hideOverlay(overlay);
self.currentOverlay = null;
}
}
}

/**
* Reverse the animation and hide after
* @param {Object} target element with animation
* @param {Boolean} hide hide after animation ends
*/
self.reverseAnimation = function(target, hide) {
var lastAnimation = null;
var style = target.style;

style.animationPlayState = "paused";
lastAnimation = style.animation;
style.animation = null;
style.animationPlayState = "paused";

if (hide) {
//target.addEventListener("animationend", self.animationEndHideHandler);

var duration = self.getAnimationDuration(lastAnimation, true);
var isOverlay = self.isOverlay(target);

setTimeout(function() {
self.setElementAnimation(target, null);

if (isOverlay) {
self.hideOverlay(target);
}
else {
self.hideView(target);
}
}, duration);
}

setTimeout(function() {
style.animation = lastAnimation;
style.animationPlayState = "paused";
style.animationDirection = "reverse";
style.animationPlayState = "running";
}, 30);
}

self.animationEndHandler = function(event) {
var target = event.currentTarget;
self.dispatchEvent(new Event(event.type));
}

self.isOverlay = function(view) {
var result = view ? self.getViewPreferenceBoolean(view, self.prefix + "is-overlay") : false;

return result;
}

self.animationEndHideHandler = function(event) {
var target = event.currentTarget;
self.setViewVariables(null, target);
self.hideView(target);
target.removeEventListener("animationend", self.animationEndHideHandler);
}

self.animationEndShowHandler = function(event) {
var target = event.currentTarget;
target.removeEventListener("animationend", self.animationEndShowHandler);
}

self.setViewOptions = function(view) {

if (view) {
self.minimumScale = self.getViewPreferenceValue(view, self.prefix + "minimum-scale");
self.maximumScale = self.getViewPreferenceValue(view, self.prefix + "maximum-scale");
self.scaleViewsToFit = self.getViewPreferenceBoolean(view, self.prefix + "scale-to-fit");
self.scaleToFitType = self.getViewPreferenceValue(view, self.prefix + "scale-to-fit-type");
self.scaleToFitOnDoubleClick = self.getViewPreferenceBoolean(view, self.prefix + "scale-on-double-click");
self.actualSizeOnDoubleClick = self.getViewPreferenceBoolean(view, self.prefix + "actual-size-on-double-click");
self.scaleViewsOnResize = self.getViewPreferenceBoolean(view, self.prefix + "scale-on-resize");
self.enableScaleUp = self.getViewPreferenceBoolean(view, self.prefix + "enable-scale-up");
self.centerHorizontally = self.getViewPreferenceBoolean(view, self.prefix + "center-horizontally");
self.centerVertically = self.getViewPreferenceBoolean(view, self.prefix + "center-vertically");
self.navigationOnKeypress = self.getViewPreferenceBoolean(view, self.prefix + "navigate-on-keypress");
self.showViewName = self.getViewPreferenceBoolean(view, self.prefix + "show-view-name");
self.refreshPageForChanges = self.getViewPreferenceBoolean(view, self.prefix + "refresh-for-changes");
self.refreshPageForChangesInterval = self.getViewPreferenceValue(view, self.prefix + "refresh-interval");
self.showNavigationControls = self.getViewPreferenceBoolean(view, self.prefix + "show-navigation-controls");
self.scaleViewSlider = self.getViewPreferenceBoolean(view, self.prefix + "show-scale-controls");
self.enableDeepLinking = self.getViewPreferenceBoolean(view, self.prefix + "enable-deep-linking");
self.singlePageApplication = self.getViewPreferenceBoolean(view, self.prefix + "application");
self.showByMediaQuery = self.getViewPreferenceBoolean(view, self.prefix + "show-by-media-query");
self.showUpdateNotification = document.cookie!="" ? document.cookie.indexOf(self.pageRefreshedName)!=-1 : false;
self.imageComparisonDuration = self.getViewPreferenceValue(view, self.prefix + "image-comparison-duration");
self.supportAnimations = self.getViewPreferenceBoolean(view, self.prefix + "enable-animations", true);

if (self.scaleViewsToFit) {
var newScaleValue = self.scaleViewToFit(view);

if (newScaleValue<0) {
setTimeout(self.scaleViewToFit, 500, view);
}
}
else {
self.viewScale = self.getViewScaleValue(view);
self.viewToFitWidthScale = self.getViewFitToViewportWidthScale(view, self.enableScaleUp)
self.viewToFitHeightScale = self.getViewFitToViewportScale(view, self.enableScaleUp);
self.updateSliderValue(self.viewScale);
}

if (self.imageComparisonDuration!=null) {
// todo
}

if (self.refreshPageForChangesInterval!=null) {
self.refreshDuration = Number(self.refreshPageForChangesInterval);
}
}
}

self.previousView = function(event) {
var rules = self.getStylesheetRules();
var view = self.getVisibleView()
var index = view ? self.getViewIndex(view) : -1;
var prevQueryIndex = index!=-1 ? index-1 : self.currentQuery.index-1;
var queryIndex = 0;
var numberOfRules = rules!=null ? rules.length : 0;

if (event) {
event.stopImmediatePropagation();
}

if (prevQueryIndex<0) {
return;
}

// loop through rules and hide media queries except selected
for (var i=0;i=numberOfMediaQueries) {
return;
}

// loop through rules and hide media queries except selected
for (var i=0;i<numberOfRules;i++) {
var rule = rules[i];

if (rule.media!=null) {

if (queryIndex==nextQueryIndex) {
self.currentQuery.mediaText = rule.conditionText;
self.currentQuery.index = nextQueryIndex;
self.currentQuery.rule = rule;
self.enableMediaQuery(rule);
self.updateViewLabel();
self.updateURL();
self.dispatchViewChange();
}
else {
self.disableMediaQuery(rule);
}

queryIndex++;
}
}
}

/**
* Enables a view via media query
*/
self.enableMediaQuery = function(rule) {

try {
rule.media.mediaText = self.inclusionQuery;
}
catch(error) {
//self.log(error);
rule.conditionText = self.inclusionQuery;
}
}

self.disableMediaQuery = function(rule) {

try {
rule.media.mediaText = self.exclusionQuery;
}
catch(error) {
rule.conditionText = self.exclusionQuery;
}
}

self.dispatchViewChange = function() {
try {
var event = new Event(self.NAVIGATION_CHANGE);
window.dispatchEvent(event);
}
catch (error) {
// In IE 11: Object doesn't support this action
}
}

self.getNumberOfMediaRules = function() {
var rules = self.getStylesheetRules();
var numberOfRules = rules ? rules.length : 0;
var numberOfQueries = 0;

for (var i=0;i<numberOfRules;i++) {
if (rules[i].media!=null) { numberOfQueries++; }
}

return numberOfQueries;
}

/////////////////////////////////////////
// VIEW SCALE
/////////////////////////////////////////

self.sliderChangeHandler = function(event) {
var value = self.getShortNumber(event.currentTarget.value/100);
var view = self.getVisibleView();
self.setViewScaleValue(view, false, value, true);
}

self.updateSliderValue = function(scale) {
var slider = document.getElementById(self.viewScaleSliderId);
var tooltip = parseInt(scale * 100 + "") + "%";
var inputType;
var inputValue;

if (slider) {
inputValue = self.getShortNumber(scale * 100);
if (inputValue!=slider["value"]) {
slider["value"] = inputValue;
}
inputType = slider.getAttributeNS(null, "type");

if (inputType!="range") {
// input range is not supported
slider.style.display = "none";
}

self.setTooltip(slider, tooltip);
}
}

self.viewChangeHandler = function(event) {
var view = self.getVisibleView();
var matrix = view ? getComputedStyle(view).transform : null;

if (matrix) {
self.viewScale = self.getViewScaleValue(view);

var scaleNeededToFit = self.getViewFitToViewportScale(view);
var isViewLargerThanViewport = scaleNeededToFit=scaleNeededToFitWidth;
canCenterHorizontally = scaleNeededToFitWidth>=1 && enableScaleUp==false;

if (isSliderChange) {
canCenterHorizontally = desiredScale1 && (enableScaleUp || isSliderChange)) {
transformValue = “scale(” + desiredScale + “)”;
}
else if (desiredScale>=1 && enableScaleUp==false) {
transformValue = “scale(” + 1 + “)”;
}
else {
transformValue = “scale(” + desiredScale + “)”;
}

if (self.centerVertically) {
if (canCenterVertically) {
translateY = “-50%”;
topPosition = “50%”;
}
else {
translateY = “0”;
topPosition = “0”;
}

if (style.top != topPosition) {
style.top = topPosition + “”;
}

if (canCenterVertically) {
transformValue += ” translateY(” + translateY+ “)”;
}
}

if (self.centerHorizontally) {
if (canCenterHorizontally) {
translateX = “-50%”;
leftPosition = “50%”;
}
else {
translateX = “0”;
leftPosition = “0”;
}

if (style.left != leftPosition) {
style.left = leftPosition + “”;
}

if (canCenterHorizontally) {
transformValue += ” translateX(” + translateX+ “)”;
}
}

style.transformOrigin = “0 0”;
style.transform = transformValue;

self.viewScale = desiredScale;
self.viewToFitWidthScale = scaleNeededToFitWidth;
self.viewToFitHeightScale = scaleNeededToFitHeight;
self.viewLeft = leftPosition;
self.viewTop = topPosition;

return desiredScale;
}

// scale to fit height
if (scaleToHeight && scaleToWidth==false) {
//canCenterVertically = scaleNeededToFitHeight>=scaleNeededToFitWidth;
//canCenterHorizontally = scaleNeededToFitHeight=scaleNeededToFitWidth;
canCenterHorizontally = scaleNeededToFitWidth>=1 && enableScaleUp==false;

if (isSliderChange) {
canCenterHorizontally = desiredScale=scaleNeededToFitHeight && enableScaleUp==false;
}

desiredScale = self.getShortNumber(desiredScale);

canCenterHorizontally = self.canCenterHorizontally(view, “height”, enableScaleUp, desiredScale, minimumScale, maximumScale);
canCenterVertically = self.canCenterVertically(view, “height”, enableScaleUp, desiredScale, minimumScale, maximumScale);

if (desiredScale>1 && (enableScaleUp || isSliderChange)) {
transformValue = “scale(” + desiredScale + “)”;
}
else if (desiredScale>=1 && enableScaleUp==false) {
transformValue = “scale(” + 1 + “)”;
}
else {
transformValue = “scale(” + desiredScale + “)”;
}

if (self.centerHorizontally) {
if (canCenterHorizontally) {
translateX = “-50%”;
leftPosition = “50%”;
}
else {
translateX = “0”;
leftPosition = “0”;
}

if (style.left != leftPosition) {
style.left = leftPosition + “”;
}

if (canCenterHorizontally) {
transformValue += ” translateX(” + translateX+ “)”;
}
}

if (self.centerVertically) {
if (canCenterVertically) {
translateY = “-50%”;
topPosition = “50%”;
}
else {
translateY = “0”;
topPosition = “0”;
}

if (style.top != topPosition) {
style.top = topPosition + “”;
}

if (canCenterVertically) {
transformValue += ” translateY(” + translateY+ “)”;
}
}

style.transformOrigin = “0 0”;
style.transform = transformValue;

self.viewScale = desiredScale;
self.viewToFitWidthScale = scaleNeededToFitWidth;
self.viewToFitHeightScale = scaleNeededToFitHeight;
self.viewLeft = leftPosition;
self.viewTop = topPosition;

return scaleNeededToFitHeight;
}

if (scaleToFitType==”fit”) {
//canCenterVertically = scaleNeededToFitHeight>=scaleNeededToFitWidth;
//canCenterHorizontally = scaleNeededToFitWidth>=scaleNeededToFitHeight;
canCenterVertically = scaleNeededToFitHeight>=scaleNeededToFit;
canCenterHorizontally = scaleNeededToFitWidth>=scaleNeededToFit;

if (hasMinimumScale) {
desiredScale = Math.max(desiredScale, Number(minimumScale));
}

desiredScale = self.getShortNumber(desiredScale);

if (isSliderChange || scaleToFit==false) {
canCenterVertically = scaleToFitFullHeight>=desiredScale;
canCenterHorizontally = desiredScale=1) {
canCenter = true;
}
}
else if (type==”height”) {
minScale = Math.min(1, scaleNeededToFitHeight);
if (minimumScale!=”” && maximumScale!=””) {
minScale = Math.max(minimumScale, Math.min(maximumScale, scaleNeededToFitHeight));
}
else {
if (minimumScale!=””) {
minScale = Math.max(minimumScale, scaleNeededToFitHeight);
}
if (maximumScale!=””) {
minScale = Math.max(minimumScale, Math.min(maximumScale, scaleNeededToFitHeight));
}
}

if (scaleUp && maximumScale==””) {
canCenter = false;
}
else if (scaleNeededToFitWidth>=minScale) {
canCenter = true;
}
}
else if (type==”fit”) {
canCenter = scaleNeededToFitWidth>=scaleNeededToFit;
}
else {
if (scaleUp) {
canCenter = false;
}
else if (scaleNeededToFitWidth>=1) {
canCenter = true;
}
}

self.horizontalScrollbarsNeeded = canCenter;

return canCenter;
}

/**
* Returns true if view can be centered horizontally
* @param {HTMLElement} view view to scale
* @param {String} type type of scaling
* @param {Boolean} scaleUp if scale up enabled
* @param {Number} scale target scale value
*/
self.canCenterVertically = function(view, type, scaleUp, scale, minimumScale, maximumScale) {
var scaleNeededToFit = self.getViewFitToViewportScale(view, scaleUp);
var scaleNeededToFitWidth = self.getViewFitToViewportWidthScale(view, scaleUp);
var scaleNeededToFitHeight = self.getViewFitToViewportHeightScale(view, scaleUp);
var canCenter = false;
var minScale;

type = type==null ? “none” : type;
scale = scale==null ? 1 : scale;
scaleUp = scaleUp == null ? false : scaleUp;

if (type==”width”) {
canCenter = scaleNeededToFitHeight>=scaleNeededToFitWidth;
}
else if (type==”height”) {
minScale = Math.max(minimumScale, Math.min(maximumScale, scaleNeededToFit));
canCenter = scaleNeededToFitHeight>=minScale;
}
else if (type==”fit”) {
canCenter = scaleNeededToFitHeight>=scaleNeededToFit;
}
else {
if (scaleUp) {
canCenter = false;
}
else if (scaleNeededToFitHeight>=1) {
canCenter = true;
}
}

self.verticalScrollbarsNeeded = canCenter;

return canCenter;
}

self.getViewFitToViewportScale = function(view, scaleUp) {
var enableScaleUp = scaleUp;
var availableWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
var availableHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
var elementWidth = parseFloat(getComputedStyle(view, “style”).width);
var elementHeight = parseFloat(getComputedStyle(view, “style”).height);
var newScale = 1;

// if element is not added to the document computed values are NaN
if (isNaN(elementWidth) || isNaN(elementHeight)) {
return newScale;
}

availableWidth -= self.horizontalPadding;
availableHeight -= self.verticalPadding;

if (enableScaleUp) {
newScale = Math.min(availableHeight/elementHeight, availableWidth/elementWidth);
}
else if (elementWidth > availableWidth || elementHeight > availableHeight) {
newScale = Math.min(availableHeight/elementHeight, availableWidth/elementWidth);
}

return newScale;
}

self.getViewFitToViewportWidthScale = function(view, scaleUp) {
// need to get browser viewport width when element
var isParentWindow = view && view.parentNode && view.parentNode===document.body;
var enableScaleUp = scaleUp;
var availableWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
var elementWidth = parseFloat(getComputedStyle(view, “style”).width);
var newScale = 1;

// if element is not added to the document computed values are NaN
if (isNaN(elementWidth)) {
return newScale;
}

availableWidth -= self.horizontalPadding;

if (enableScaleUp) {
newScale = availableWidth/elementWidth;
}
else if (elementWidth > availableWidth) {
newScale = availableWidth/elementWidth;
}

return newScale;
}

self.getViewFitToViewportHeightScale = function(view, scaleUp) {
var enableScaleUp = scaleUp;
var availableHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
var elementHeight = parseFloat(getComputedStyle(view, “style”).height);
var newScale = 1;

// if element is not added to the document computed values are NaN
if (isNaN(elementHeight)) {
return newScale;
}

availableHeight -= self.verticalPadding;

if (enableScaleUp) {
newScale = availableHeight/elementHeight;
}
else if (elementHeight > availableHeight) {
newScale = availableHeight/elementHeight;
}

return newScale;
}

self.keypressHandler = function(event) {
var rightKey = 39;
var leftKey = 37;

// listen for both events
if (event.type==”keypress”) {
window.removeEventListener(“keyup”, self.keypressHandler);
}
else {
window.removeEventListener(“keypress”, self.keypressHandler);
}

if (self.showNavigationControls) {
if (self.navigationOnKeypress) {
if (event.keyCode==rightKey) {
self.nextView();
}
if (event.keyCode==leftKey) {
self.previousView();
}
}
}
else if (self.navigationOnKeypress) {
if (event.keyCode==rightKey) {
self.nextView();
}
if (event.keyCode==leftKey) {
self.previousView();
}
}
}

///////////////////////////////////
// GENERAL FUNCTIONS
///////////////////////////////////

self.getViewById = function(id) {
id = id ? id.replace(“#”, “”) : “”;
var view = self.viewIds.indexOf(id)!=-1 && self.getElement(id);
return view;
}

self.getViewIds = function() {
var viewIds = self.getViewPreferenceValue(document.body, self.prefix + “view-ids”);
var viewId = null;

viewIds = viewIds!=null && viewIds!=”” ? viewIds.split(“,”) : [];

if (viewIds.length==0) {
viewId = self.getViewPreferenceValue(document.body, self.prefix + “view-id”);
viewIds = viewId ? [viewId] : [];
}

return viewIds;
}

self.getInitialViewId = function() {
var viewId = self.getViewPreferenceValue(document.body, self.prefix + “view-id”);
return viewId;
}

self.getApplicationStylesheet = function() {
var stylesheetId = self.getViewPreferenceValue(document.body, self.prefix + “stylesheet-id”);
self.applicationStylesheet = document.getElementById(“applicationStylesheet”);
return self.applicationStylesheet.sheet;
}

self.getVisibleView = function() {
var viewIds = self.getViewIds();

for (var i=0;i<viewIds.length;i++) {
var viewId = viewIds[i].replace(/[\#?\.?](.*)/, "$" + "1");
var view = self.getElement(viewId);
var postName = "_Class";

if (view==null && viewId && viewId.lastIndexOf(postName)!=-1) {
view = self.getElement(viewId.replace(postName, ""));
}

if (view) {
var display = getComputedStyle(view).display;

if (display=="block" || display=="flex") {
return view;
}
}
}

return null;
}

self.getVisibleViews = function() {
var viewIds = self.getViewIds();
var views = [];

for (var i=0;i<viewIds.length;i++) {
var viewId = viewIds[i].replace(/[\#?\.?](.*)/, "$" + "1");
var view = self.getElement(viewId);
var postName = "_Class";

if (view==null && viewId && viewId.lastIndexOf(postName)!=-1) {
view = self.getElement(viewId.replace(postName, ""));
}

if (view) {
var display = getComputedStyle(view).display;

if (display=="none") {
continue;
}

if (display=="block" || display=="flex") {
views.push(view);
}
}
}

return views;
}

self.getStateNameByViewId = function(id) {
var state = self.viewsDictionary[id];
return state && state.stateName;
}

self.getMatchingViews = function(ids) {
var views = self.addedViews.slice(0);
var matchingViews = [];

if (self.showByMediaQuery) {
for (let index = 0; index < views.length; index++) {
var viewId = views[index];
var state = self.viewsDictionary[viewId];
var rule = state && state.rule;
var matchResults = window.matchMedia(rule.conditionText);
var view = self.views[viewId];

if (matchResults.matches) {
if (ids==true) {
matchingViews.push(viewId);
}
else {
matchingViews.push(view);
}
}
}
}

return matchingViews;
}

self.ruleMatchesQuery = function(rule) {
var result = window.matchMedia(rule.conditionText);
return result.matches;
}

self.getViewsByStateName = function(stateName, matchQuery) {
var views = self.addedViews.slice(0);
var matchingViews = [];

if (self.showByMediaQuery) {

// find state name
for (let index = 0; index < views.length; index++) {
var viewId = views[index];
var state = self.viewsDictionary[viewId];
var rule = state.rule;
var mediaRule = state.mediaRule;
var view = self.views[viewId];
var viewStateName = self.getStyleRuleValue(mediaRule, self.STATE_NAME, state);
var stateFoundAtt = view.getAttribute(self.STATE_NAME)==state;
var matchesResults = false;

if (viewStateName==stateName) {
if (matchQuery) {
matchesResults = self.ruleMatchesQuery(rule);

if (matchesResults) {
matchingViews.push(view);
}
}
else {
matchingViews.push(view);
}
}
}
}

return matchingViews;
}

self.getInitialView = function() {
var viewId = self.getInitialViewId();
viewId = viewId.replace(/[\#?\.?](.*)/, "$" + "1");
var view = self.getElement(viewId);
var postName = "_Class";

if (view==null && viewId && viewId.lastIndexOf(postName)!=-1) {
view = self.getElement(viewId.replace(postName, ""));
}

return view;
}

self.getViewIndex = function(view) {
var viewIds = self.getViewIds();
var id = view ? view.id : null;
var index = id && viewIds ? viewIds.indexOf(id) : -1;

return index;
}

self.syncronizeViewToURL = function() {
var fragment = self.getHashFragment();

if (self.showByMediaQuery) {
var stateName = fragment;

if (stateName==null || stateName=="") {
var initialView = self.getInitialView();
stateName = initialView ? self.getStateNameByViewId(initialView.id) : null;
}

self.showMediaQueryViewsByState(stateName);
return;
}

var view = self.getViewById(fragment);
var index = view ? self.getViewIndex(view) : 0;
if (index==-1) index = 0;
var currentView = self.hideViews(index);

if (self.supportsPopState && currentView) {

if (fragment==null) {
window.history.replaceState({name:currentView.id}, null, "#"+ currentView.id);
}
else {
window.history.pushState({name:currentView.id}, null, "#"+ currentView.id);
}
}

self.setViewVariables(view);
return view;
}

/**
* Set the currentView or currentOverlay properties and set the lastView or lastOverlay properties
*/
self.setViewVariables = function(view, overlay, parentView) {
if (view) {
if (self.currentView) {
self.lastView = self.currentView;
}
self.currentView = view;
}

if (overlay) {
if (self.currentOverlay) {
self.lastOverlay = self.currentOverlay;
}
self.currentOverlay = overlay;
}
}

self.getViewPreferenceBoolean = function(view, property, altValue) {
var computedStyle = window.getComputedStyle(view);
var value = computedStyle.getPropertyValue(property);
var type = typeof value;

if (value=="true" || (type=="string" && value.indexOf("true")!=-1)) {
return true;
}
else if (value=="" && arguments.length==3) {
return altValue;
}

return false;
}

self.getViewPreferenceValue = function(view, property, defaultValue) {
var value = window.getComputedStyle(view).getPropertyValue(property);

if (value===undefined) {
return defaultValue;
}

value = value.replace(/^[\s\"]*/, "");
value = value.replace(/[\s\"]*$/, "");
value = value.replace(/^[\s"]*(.*?)[\s"]*$/, function (match, capture) {
return capture;
});

return value;
}

self.getStyleRuleValue = function(cssRule, property) {
var value = cssRule ? cssRule.style.getPropertyValue(property) : null;

if (value===undefined) {
return null;
}

value = value.replace(/^[\s\"]*/, "");
value = value.replace(/[\s\"]*$/, "");
value = value.replace(/^[\s"]*(.*?)[\s"]*$/, function (match, capture) {
return capture;
});

return value;
}

/**
* Get the first defined value of property. Returns empty string if not defined
* @param {String} id id of element
* @param {String} property
*/
self.getCSSPropertyValueForElement = function(id, property) {
var styleSheets = document.styleSheets;
var numOfStylesheets = styleSheets.length;
var values = [];
var selectorIDText = "#" + id;
var selectorClassText = "." + id + "_Class";
var value;

for(var i=0;i<numOfStylesheets;i++) {
var styleSheet = styleSheets[i];
var cssRules = self.getStylesheetRules(styleSheet);
var numOfCSSRules = cssRules.length;
var cssRule;

for (var j=0;j<numOfCSSRules;j++) {
cssRule = cssRules[j];

if (cssRule.media) {
var mediaRules = cssRule.cssRules;
var numOfMediaRules = mediaRules ? mediaRules.length : 0;

for(var k=0;k<numOfMediaRules;k++) {
var mediaRule = mediaRules[k];

if (mediaRule.selectorText==selectorIDText || mediaRule.selectorText==selectorClassText) {

if (mediaRule.style && mediaRule.style.getPropertyValue(property)!="") {
value = mediaRule.style.getPropertyValue(property);
values.push(value);
}
}
}
}
else {

if (cssRule.selectorText==selectorIDText || cssRule.selectorText==selectorClassText) {
if (cssRule.style && cssRule.style.getPropertyValue(property)!="") {
value = cssRule.style.getPropertyValue(property);
values.push(value);
}
}
}
}
}

return values.pop();
}

self.getIsStyleDefined = function(id, property) {
var value = self.getCSSPropertyValueForElement(id, property);
return value!==undefined && value!="";
}

self.collectViews = function() {
var viewIds = self.getViewIds();

for (let index = 0; index < viewIds.length; index++) {
const id = viewIds[index];
const view = self.getElement(id);
self.views[id] = view;
}

self.viewIds = viewIds;
}

self.collectOverlays = function() {
var viewIds = self.getViewIds();
var ids = [];

for (let index = 0; index < viewIds.length; index++) {
const id = viewIds[index];
const view = self.getViewById(id);
const isOverlay = view && self.isOverlay(view);

if (isOverlay) {
ids.push(id);
self.overlays[id] = view;
}
}

self.overlayIds = ids;
}

self.collectMediaQueries = function() {
var viewIds = self.getViewIds();
var styleSheet = self.getApplicationStylesheet();
var cssRules = self.getStylesheetRules(styleSheet);
var numOfCSSRules = cssRules ? cssRules.length : 0;
var cssRule;
var id = viewIds.length ? viewIds[0]: ""; // single view
var selectorIDText = "#" + id;
var selectorClassText = "." + id + "_Class";
var viewsNotFound = viewIds.slice();
var viewsFound = [];
var selectorText = null;
var property = self.prefix + "view-id";
var stateName = self.prefix + "state";
var stateValue = null;
var view = null;

for (var j=0;j<numOfCSSRules;j++) {
cssRule = cssRules[j];

if (cssRule.media) {
var mediaRules = cssRule.cssRules;
var numOfMediaRules = mediaRules ? mediaRules.length : 0;
var mediaViewInfoFound = false;
var mediaId = null;

for(var k=0;k<numOfMediaRules;k++) {
var mediaRule = mediaRules[k];

selectorText = mediaRule.selectorText;

if (selectorText==".mediaViewInfo" && mediaViewInfoFound==false) {

mediaId = self.getStyleRuleValue(mediaRule, property);
stateValue = self.getStyleRuleValue(mediaRule, stateName);

selectorIDText = "#" + mediaId;
selectorClassText = "." + mediaId + "_Class";
view = self.getElement(mediaId);

// prevent duplicates from load and domcontentloaded events
if (self.addedViews.indexOf(mediaId)==-1) {
self.addView(view, mediaId, cssRule, mediaRule, stateValue);
}

viewsFound.push(mediaId);

if (viewsNotFound.indexOf(mediaId)!=-1) {
viewsNotFound.splice(viewsNotFound.indexOf(mediaId));
}

mediaViewInfoFound = true;
}

if (selectorIDText==selectorText || selectorClassText==selectorText) {
var styleObject = self.viewsDictionary[mediaId];
if (styleObject) {
styleObject.styleDeclaration = mediaRule;
}
break;
}
}
}
else {
selectorText = cssRule.selectorText;

if (selectorText==null) continue;

selectorText = selectorText.replace(/[#|\s|*]?/g, "");

if (viewIds.indexOf(selectorText)!=-1) {
view = self.getElement(selectorText);
self.addView(view, selectorText, cssRule, null, stateValue);

if (viewsNotFound.indexOf(selectorText)!=-1) {
viewsNotFound.splice(viewsNotFound.indexOf(selectorText));
}

break;
}
}
}

if (viewsNotFound.length) {
console.log("Could not find the following views:" + viewsNotFound.join(",") + "");
console.log("Views found:" + viewsFound.join(",") + "");
}
}

/**
* Adds a view
* @param {HTMLElement} view view element
* @param {String} id id of view element
* @param {CSSRule} cssRule of view element
* @param {CSSMediaRule} mediaRule media rule of view element
* @param {String} stateName name of state if applicable
**/
self.addView = function(view, viewId, cssRule, mediaRule, stateName) {
var viewData = {};
viewData.name = viewId;
viewData.rule = cssRule;
viewData.id = viewId;
viewData.mediaRule = mediaRule;
viewData.stateName = stateName;

self.views.push(viewData);
self.addedViews.push(viewId);
self.viewsDictionary[viewId] = viewData;
self.mediaQueryDictionary[viewId] = cssRule;
}

self.hasView = function(name) {

if (self.addedViews.indexOf(name)!=-1) {
return true;
}
return false;
}

/**
* Go to view by id. Views are added in addView()
* @param {String} id id of view in current
* @param {Boolean} maintainPreviousState if true then do not hide other views
* @param {String} parent id of parent view
**/
self.goToView = function(id, maintainPreviousState, parent) {
var state = self.viewsDictionary[id];

if (state) {
if (maintainPreviousState==false || maintainPreviousState==null) {
self.hideViews();
}
self.enableMediaQuery(state.rule);
self.updateViewLabel();
self.updateURL();
}
else {
var event = new Event(self.STATE_NOT_FOUND);
self.stateName = id;
window.dispatchEvent(event);
}
}

/**
* Go to the view in the event targets CSS variable
**/
self.goToTargetView = function(event) {
var button = event.currentTarget;
var buttonComputedStyles = getComputedStyle(button);
var actionTargetValue = buttonComputedStyles.getPropertyValue(self.prefix+"action-target").trim();
var animation = buttonComputedStyles.getPropertyValue(self.prefix+"animation").trim();
var targetType = buttonComputedStyles.getPropertyValue(self.prefix+"action-type").trim();
var targetView = self.application ? null : self.getElement(actionTargetValue);
var targetState = targetView ? self.getStateNameByViewId(targetView.id) : null;
var actionTargetStyles = targetView ? targetView.style : null;
var state = self.viewsDictionary[actionTargetValue];

// navigate to page
if (self.application==false || targetType=="page") {
document.location.href = "./" + actionTargetValue;
return;
}

// if view is found
if (targetView) {

if (self.currentOverlay) {
self.removeOverlay(false);
}

if (self.showByMediaQuery) {
var stateName = targetState;

if (stateName==null || stateName=="") {
var initialView = self.getInitialView();
stateName = initialView ? self.getStateNameByViewId(initialView.id) : null;
}
self.showMediaQueryViewsByState(stateName, event);
return;
}

// add animation set in event target style declaration
if (animation && self.supportAnimations) {
self.crossFade(self.currentView, targetView, false, animation);
}
else {
self.setViewVariables(self.currentView);
self.hideViews();
self.enableMediaQuery(state.rule);
self.scaleViewIfNeeded(targetView);
self.centerView(targetView);
self.updateViewLabel();
self.updateURL();
}
}
else {
var stateEvent = new Event(self.STATE_NOT_FOUND);
self.stateName = name;
window.dispatchEvent(stateEvent);
}

event.stopImmediatePropagation();
}

/**
* Cross fade between views
**/
self.crossFade = function(from, to, update, animation) {
var targetIndex = to.parentNode
var fromIndex = Array.prototype.slice.call(from.parentElement.children).indexOf(from);
var toIndex = Array.prototype.slice.call(to.parentElement.children).indexOf(to);

if (from.parentNode==to.parentNode) {
var reverse = self.getReverseAnimation(animation);
var duration = self.getAnimationDuration(animation, true);

// if target view is above (higher index)
// then fade in target view
// and after fade in then hide previous view instantly
if (fromIndextoIndex) {
self.setElementAnimation(to, null);
self.setElementAnimation(from, null);
self.showViewByMediaQuery(to);
self.fadeOut(from, update, reverse);

setTimeout(function() {
self.setElementAnimation(to, null);
self.setElementAnimation(from, null);
self.hideView(from);
self.updateURL();
self.setViewVariables(to);
}, duration)
}
}
}

self.fadeIn = function(element, update, animation) {
self.showViewByMediaQuery(element);

if (update) {
self.updateURL(element);

element.addEventListener(“animationend”, function(event) {
element.style.animation = null;
self.setViewVariables(element);
self.updateViewLabel();
element.removeEventListener(“animationend”, arguments.callee);
});
}

self.setElementAnimation(element, null);

element.style.animation = animation;
}

self.fadeOutCurrentView = function(animation, update) {
if (self.currentView) {
self.fadeOut(self.currentView, update, animation);
}
if (self.currentOverlay) {
self.fadeOut(self.currentOverlay, update, animation);
}
}

self.fadeOut = function(element, update, animation) {
if (update) {
element.addEventListener(“animationend”, function(event) {
element.style.animation = null;
self.hideView(element);
element.removeEventListener(“animationend”, arguments.callee);
});
}

element.style.animationPlayState = “paused”;
element.style.animation = animation;
element.style.animationPlayState = “running”;
}

self.getReverseAnimation = function(animation) {
if (animation && animation.indexOf(“reverse”)==-1) {
animation += ” reverse”;
}

return animation;
}

/**
* Get duration in animation string
* @param {String} animation animation value
* @param {Boolean} inMilliseconds length in milliseconds if true
*/
self.getAnimationDuration = function(animation, inMilliseconds) {
var duration = 0;
var expression = /.+(\d\.\d)s.+/;

if (animation && animation.match(expression)) {
duration = parseFloat(animation.replace(expression, “$” + “1”));
if (duration && inMilliseconds) duration = duration * 1000;
}

return duration;
}

self.setElementAnimation = function(element, animation, priority) {
element.style.setProperty(“animation”, animation, “important”);
}

self.getElement = function(id) {
id = id ? id.trim() : id;
var element = id ? document.getElementById(id) : null;

return element;
}

self.getElementById = function(id) {
id = id ? id.trim() : id;
var element = id ? document.getElementById(id) : null;

return element;
}

self.getElementByClass = function(className) {
className = className ? className.trim() : className;
var elements = document.getElementsByClassName(className);

return elements.length ? elements[0] : null;
}

self.resizeHandler = function(event) {

if (self.showByMediaQuery) {
if (self.enableDeepLinking) {
var stateName = self.getHashFragment();

if (stateName==null || stateName==””) {
var initialView = self.getInitialView();
stateName = initialView ? self.getStateNameByViewId(initialView.id) : null;
}
self.showMediaQueryViewsByState(stateName, event);
}
}
else {
var visibleViews = self.getVisibleViews();

for (let index = 0; index < visibleViews.length; index++) {
var view = visibleViews[index];
self.scaleViewIfNeeded(view);
}
}

window.dispatchEvent(new Event(self.APPLICATION_RESIZE));
}

self.scaleViewIfNeeded = function(view) {

if (self.scaleViewsOnResize) {
if (view==null) {
view = self.getVisibleView();
}

var isViewScaled = view.getAttributeNS(null, self.SIZE_STATE_NAME)=="false" ? false : true;

if (isViewScaled) {
self.scaleViewToFit(view, true);
}
else {
self.scaleViewToActualSize(view);
}
}
else if (view) {
self.centerView(view);
}
}

self.centerView = function(view) {

if (self.scaleViewsToFit) {
self.scaleViewToFit(view, true);
}
else {
self.scaleViewToActualSize(view); // for centering support for now
}
}

self.preventDoubleClick = function(event) {
event.stopImmediatePropagation();
}

self.getHashFragment = function() {
var value = window.location.hash ? window.location.hash.replace("#", "") : "";
return value;
}

self.showBlockElement = function(view) {
view.style.display = "block";
}

self.hideElement = function(view) {
view.style.display = "none";
}

self.showStateFunction = null;

self.showMediaQueryViewsByState = function(state, event) {
// browser will hide and show by media query (small, medium, large)
// but if multiple views exists at same size user may want specific view
// if showStateFunction is defined that is called with state fragment and user can show or hide each media matching view by returning true or false
// if showStateFunction is not defined and state is defined and view has a defined state that matches then show that and hide other matching views
// if no state is defined show view
// an viewChanging event is dispatched before views are shown or hidden that can be prevented

// get all matched queries
// if state name is specified then show that view and hide other views
// if no state name is defined then show
var matchedViews = self.getMatchingViews();
var matchMediaQuery = true;
var foundViews = self.getViewsByStateName(state, matchMediaQuery);
var showViews = [];
var hideViews = [];

// loop views that match media query
for (let index = 0; index < matchedViews.length; index++) {
var view = matchedViews[index];

// let user determine visible view
if (self.showStateFunction!=null) {
if (self.showStateFunction(view, state)) {
showViews.push(view);
}
else {
hideViews.push(view);
}
}
// state was defined so check if view matches state
else if (foundViews.length) {

if (foundViews.indexOf(view)!=-1) {
showViews.push(view);
}
else {
hideViews.push(view);
}
}
// if no state names are defined show view (define unused state name to exclude)
else if (state==null || state=="") {
showViews.push(view);
}
}

if (showViews.length) {
var viewChangingEvent = new Event(self.VIEW_CHANGING);
viewChangingEvent.showViews = showViews;
viewChangingEvent.hideViews = hideViews;
window.dispatchEvent(viewChangingEvent);

if (viewChangingEvent.defaultPrevented==false) {
for (var index = 0; index < hideViews.length; index++) {
var view = hideViews[index];

if (self.isOverlay(view)) {
self.removeOverlay(view);
}
else {
self.hideElement(view);
}
}

for (var index = 0; index < showViews.length; index++) {
var view = showViews[index];

if (index==showViews.length-1) {
self.clearDisplay(view);
self.setViewOptions(view);
self.setViewVariables(view);
self.centerView(view);
self.updateURLState(view, state);
}
}
}

var viewChangeEvent = new Event(self.VIEW_CHANGE);
viewChangeEvent.showViews = showViews;
viewChangeEvent.hideViews = hideViews;
window.dispatchEvent(viewChangeEvent);
}

}

self.clearDisplay = function(view) {
view.style.setProperty("display", null);
}

self.hashChangeHandler = function(event) {
var fragment = self.getHashFragment();
var view = self.getViewById(fragment);

if (self.showByMediaQuery) {
var stateName = fragment;

if (stateName==null || stateName=="") {
var initialView = self.getInitialView();
stateName = initialView ? self.getStateNameByViewId(initialView.id) : null;
}
self.showMediaQueryViewsByState(stateName);
}
else {
if (view) {
self.hideViews();
self.showView(view);
self.setViewVariables(view);
self.updateViewLabel();

window.dispatchEvent(new Event(self.VIEW_CHANGE));
}
else {
window.dispatchEvent(new Event(self.VIEW_NOT_FOUND));
}
}
}

self.popStateHandler = function(event) {
var state = event.state;
var fragment = state ? state.name : window.location.hash;
var view = self.getViewById(fragment);

if (view) {
self.hideViews();
self.showView(view);
self.updateViewLabel();
}
else {
window.dispatchEvent(new Event(self.VIEW_NOT_FOUND));
}
}

self.doubleClickHandler = function(event) {
var view = self.getVisibleView();
var scaleValue = view ? self.getViewScaleValue(view) : 1;
var scaleNeededToFit = view ? self.getViewFitToViewportScale(view) : 1;
var scaleNeededToFitWidth = view ? self.getViewFitToViewportWidthScale(view) : 1;
var scaleNeededToFitHeight = view ? self.getViewFitToViewportHeightScale(view) : 1;
var scaleToFitType = self.scaleToFitType;

// Three scenarios
// – scale to fit on double click
// – set scale to actual size on double click
// – switch between scale to fit and actual page size

if (scaleToFitType=="width") {
scaleNeededToFit = scaleNeededToFitWidth;
}
else if (scaleToFitType=="height") {
scaleNeededToFit = scaleNeededToFitHeight;
}

// if scale and actual size enabled then switch between
if (self.scaleToFitOnDoubleClick && self.actualSizeOnDoubleClick) {
var isViewScaled = view.getAttributeNS(null, self.SIZE_STATE_NAME);
var isScaled = false;

// if scale is not 1 then view needs scaling
if (scaleNeededToFit!=1) {

// if current scale is at 1 it is at actual size
// scale it to fit
if (scaleValue==1) {
self.scaleViewToFit(view);
isScaled = true;
}
else {
// scale is not at 1 so switch to actual size
self.scaleViewToActualSize(view);
isScaled = false;
}
}
else {
// view is smaller than viewport
// so scale to fit() is scale actual size
// actual size and scaled size are the same
// but call scale to fit to retain centering
self.scaleViewToFit(view);
isScaled = false;
}

view.setAttributeNS(null, self.SIZE_STATE_NAME, isScaled+"");
isViewScaled = view.getAttributeNS(null, self.SIZE_STATE_NAME);
}
else if (self.scaleToFitOnDoubleClick) {
self.scaleViewToFit(view);
}
else if (self.actualSizeOnDoubleClick) {
self.scaleViewToActualSize(view);
}

}

self.scaleViewToFit = function(view) {
return self.setViewScaleValue(view, true);
}

self.scaleViewToActualSize = function(view) {
self.setViewScaleValue(view, false, 1);
}

self.onloadHandler = function(event) {
self.initialize();
}

self.setElementHTML = function(id, value) {
var element = self.getElement(id);
element.innerHTML = value;
}

self.getStackArray = function(error) {
var value = "";

if (error==null) {
try {
error = new Error("Stack");
}
catch (e) {

}
}

if ("stack" in error) {
value = error.stack;
var methods = value.split(/\n/g);

var newArray = methods ? methods.map(function (value, index, array) {
value = value.replace(/\@.*/,"");
return value;
}) : null;

if (newArray && newArray[0].includes("getStackTrace")) {
newArray.shift();
}
if (newArray && newArray[0].includes("getStackArray")) {
newArray.shift();
}
if (newArray && newArray[0]=="") {
newArray.shift();
}

return newArray;
}

return null;
}

self.log = function(value) {
console.log.apply(this, [value]);
}

// initialize on load
// sometimes the body size is 0 so we call this now and again later
window.addEventListener("load", self.onloadHandler);
window.document.addEventListener("DOMContentLoaded", self.onloadHandler);
}

window.application = new Application();

About
TV/Radio
Fashion
Lifestyle
Blog
Shop
Home

-There’s still time to fulfill your dreams.
M A R K E T I N G
D I G I T A L

N E X T
B I G
T H I N G
THE
Developed & Designed by Talha Sakrani
defmark – IT & Marketing – Company of iVisioned.com

He is a Pakistani American Business Admin., Financial Officer,
Software Engineer, Designer, Marketer, Music Producer,
Audio & Video Editor, Photographer, Videographer, Model.
He has extensive experience in IT, marketing, aviation industries.
He has successfully managed and operated
multi international companies for more than 15+ years.
Moreover, he is an active volunteer social worker
for woman and children.
T A L H A S A K R A N I