/// <reference path="avweb.js" />

/// <reference path="screenLock.js" />

/// <reference path="common.js" />

/// <reference path="i18n.js" />

/// <reference path="jquery-1.8.1.min.js" />

/// <reference path="jquery-ui-1.8.23.custom.min.js" />

/// <reference path="jquery.toastmessage.js" />

/// <reference path="pageViewer.js" />


// =============================================================================================
// Constants [start]
// =============================================================================================
var Consts = {
    // Display mode: 1 -> Bookshelf
    ConstDisplayMode_BookShelf: 1,
    // Display mode: 0 -> List
    ConstDisplayMode_List: 2,

    // Order setting: 1 -> ascending
    ConstOrderSetting_Asc: 1,

    // Order setting: 0 -> descending
    ConstOrderSetting_Desc: 2,

    // Language: English
    ConstLanguage_En: "en",
    // Language: Japanese
    ConstLanguage_Ja: "ja",
    // Language: Korean
    ConstLanguage_Ko: "ko",
    ConstLanguage_Th: "th",
    ConstLanguage_In: "in",

    // API result: success
    ConstAPI_SUCCESS: "success",
    // API result: fail
    ConstAPI_FAIL: "fail",

    // 初回ログイン時パスワード強制変更: 0:なし
    ConstServiceOption_NON: 0,
    // 初回ログイン時パスワード強制変更: 1:催促
    ConstServiceOption_REGULAR: 1,
    // 初回ログイン時パスワード強制変更: 2:強制
    ConstServiceOption_FORCE: 2,

    // Lock screen timer
    ConstLockScreenTime: 1800000
};

/*
    Define short keys for content view
*/
var ShortKeys = {
    // Move previous: arrow left <-
    MovePrevious: 37,
    // Move next: arrow right ->
    MoveNext: 39,
    // Zoom in: ","
    ZoomIn: 188,
    // Zoom out: "."
    ZoomOut: 190,
    // Fit: Enter
    ZoomFit: 13,
    // Show, hide toolbar: "["
    ShowHideToolbar: 219,
    // Show, hide marking: "]"
    ShowHideMarking: 221
};

// -------------------------------------------------
// Define all keys for local/session storage [start]
// -------------------------------------------------

var ScreenIds = {
    Login: './../login.html',
    Home : 'home.html',
    ContentView : 'contentview.html',
    Setting : 'settings.html',
    BookmarkList : 'bookmark.html',
    ContentSearch : 'contentsearch.html',
    History: 'history.html'
};

var Keys = {
    zoom_ratioPre: 'zoom_ratioPre',

    IsRefresh: 'IsRefresh',
    // Local
    BookmarkScreen: 'BookmarkScreen',
    // Local
    IsJumpBack: 'IsJumpBack',
    // Local:
    JumpQueue: 'JumpQueue',
    // Local
    ContentViewDetail: 'ContentViewDetail',
    // Session
    userInfo_userName: 'userInfo_userName',
    // Local
    ContentLogData: 'ContentLogData',
    // Session: true/false
    IsLocked: 'IsLocked',
    // Local: true/false
    IsHideToolbar: 'IsHideToolbar',
    // Local: true/false
    IsAddingMemo: 'IsAddingMemo',
    // Local: true/false
    IsAddingMarking: 'IsAddingMarking',
    // Local: true/false
    IsDisplayMarking: 'IsDisplayMarking',
    // Local: true/false
    IsDisplayMemo: 'IsDisplayMemo',
    // Local
    MarkingType: 'MarkingType',
    // Local
    ReadingContentIds: 'ReadingContentIds',
    // Local
    BookMarkData: 'BookMarkData',
    // Local
    MarkingData: 'MarkingData',
    // Local
    MemoData: 'MemoData',
    // Local
    ResourceVersion: 'ResourceVersion',
    // Local
    MetaVersion: 'MetaVersion',

    // Local :ユーザオプション(userOpt)_ログアウトモード: Interger(0:logout with backup, 1:logout without backup)
    userOpt_logoutMode: 'logoutMode',

    // Session :コンテンツ詳細情報(contentInfo)_サムネール: String (base64string)
    contentInfo_contentThumbnail: 'contentInfo_contentThumbnail',

    // Local: isChangedMemo: boolean (true: changed, false: not change)
    isChangedMemo: 'isChangedMemo',
    // Local: isChangedMakingData: boolean (true: changed, false: not change)
    isChangedMarkingData: 'isChangedMarkingData',
    // Local: isChangedBookmark: boolean (true: changed, false: not change)
    isChangedBookmark: 'isChangedBookmark',

    // Session:パスワード要変更(requirePasswordChange):String (0:不要, 1:初回, 2:定期変更)
    requirePasswordChange: 'requirePasswordChange',

    /* -------------------------------------------------------------------------------- */
    // Session:ユーザ情報(userInfo)_セッションID:String
    userInfo_sid: 'sid',
    // Session :事業者オプション(serviceOpt)_初回ログイン時パスワード強制変更:Integer(0:なし, 1:催促, 2:強制)
    serviceOpt_force_pw_change_on_login: 'force_pw_change_on_login',
    // Session :事業者オプション(serviceOpt)_定期ログイン時パスワード強制変更:Integer(0:なし, 1:催促, 2:強制)
    serviceOpt_force_pw_change_periodically: 'force_pw_change_periodically',
    // Session:事業者オプション(serviceOpt)_メモ・マーキングデータバックアップ使用:Char(Y:可能, N:不可)
    serviceOpt_user_data_backup: 'user_data_backup',
    // Session :事業者オプション(serviceOpt)_マーキング機能使用:Char(Y:可能, N:不可)
    serviceOpt_marking: 'marking',
    // Session :事業者オプション(serviceOpt)_一定期間経過後アプリロック:Char(Y:可能, N:不可)
    serviceOpt_force_login_periodically: 'force_login_periodically',
    // Session :共通(common)_コンテンツID:Integer
    common_contentId: 'common_contentId',
    // Local :共通(common)_コンテンツID:Integer
    common_preContentId: 'common_preContentId',
    // Session: 共通(common)_コンテンツデータチェックフラグ: Integer(true/false, true:メモ、マーキング、しおりを削除する処理を行える false:メモ、マーキング、しおりを削除する処理をしない)
    common_contentDataChkFlg: 'common_contentDataChkFlg',
    // Session :ページ情報データ(pageInfo)_ページNo:Integer
    pageInfo_pageNo: 'pageInfo_pageNo',
    // Local :ページ情報データ(pageInfo)_ページNo:Integer
    common_prePageNo: 'common_prePageNo',
    // Session :ページ情報データ(pageInfo)_ページテキスト:String
    pageInfo_pageText: 'pageText',
    // Session :ページ情報データ(pageInfo)_コンテンツサムネイル:Integer
    pageInfo_pageImgResrcId: 'pageImgResrcId',
    // Session :コンテンツ内リンク(linkInfo)_リンク位置のx座標:Integer
    linkInfo_linkLocationX: 'linkLocationX',
    // Session :コンテンツ内リンク(linkInfo)_リンク位置のy座標:Integer
    linkInfo_linkLocationY: 'linkLocationY',
    // Session :コンテンツ内リンク(linkInfo)_リンク領域の幅:Integer
    linkInfo_linkLocationWidth: 'linkLocationWidth',
    // Session :コンテンツ内リンク(linkInfo)_リンク領域の高さ:Integer
    linkInfo_linkLocationHeight: 'linkLocationHeight',
    // Session :コンテンツ内リンク(linkInfo)_リンクタイプ:Integer(0/1)
    linkInfo_linkKind: 'linkKind',
    // Session :コンテンツ内リンク(linkInfo)_ターゲットURI:String(0/1)
    linkInfo_destURI: 'destURI',
    // Session :コンテンツ内リンク(linkInfo)_ターゲットページNo:Integer(0/1)
    linkInfo_destPageNumber: 'linkInfo_destPageNumber',
    // Session :閲覧ログ(log)_コンテンツ閲覧開始時刻:Datetime
    log_contentStartViewDt: 'contentStartViewDt',
    // Session :コンテンツ詳細情報(contentInfo)_コンテンツID:Integer
    contentInfo_contentId: 'contentInfo_contentId',
    // Session :コンテンツ詳細情報(contentInfo)_カテゴリID:Integer
    contentInfo_categoryId: 'categoryId',
    // Session :コンテンツ詳細情報(contentInfo)_コンテンツ名:String
    contentInfo_contentName: 'contentName',
    // Session :コンテンツ詳細情報(contentInfo)_コンテンツ名(カナ):String
    contentInfo_contentNameKana: 'contentNameKana',
    // Session :コンテンツ詳細情報(contentInfo)_コンテンツ詳細:String
    contentInfo_contentDetail: 'contentDetail',
    // Session :コンテンツ詳細情報(contentInfo)_公開開始日:Datetime
    contentInfo_deliveryStartDate: 'deliveryStartDate',
    // Session :コンテンツ詳細情報(contentInfo)_公開終了日:Datetime
    contentInfo_deliveryEndDate: 'deliveryEndDate',
    // Session :コンテンツ詳細情報(contentInfo)_本棚サムネール名:Interger
    contentInfo_thumbnailName: 'thumbnailName',
    // Session :コンテンツ詳細情報(contentInfo)_詳細画面サムネール名:Interger
    contentInfo_thumbnailBigName: 'thumbnailBigName',
    // Session :コンテンツ詳細情報(contentInfo)_メタ更新バージョン:Interger
    contentInfo_metaVersion: 'contentInfo_metaVersion',
    // Session :コンテンツ詳細情報(contentInfo)_リソース更新バージョン:Interger
    contentInfo_resourceVersion: 'contentInfo_resourceVersion',
    // Session :コンテンツ詳細情報(contentInfo)_PDF総ページ数:Interger
    contentInfo_allPageNum: 'allPageNum',
    // Session :検索条件(searchCond)_検索テキスト:String
    searchCond_searchText: 'searchText',
    // Session :検索条件(searchCond)_検索区分:Interger(1:コンテンツ検索, 2:タグ検索, 3:全文検索)
    searchCond_searchDivision: 'searchCond_searchDivision',
    // Session :検索条件(searchCond)_ソート基準:Interger(1:タイトル名, 2:タイトル名(かな), 3:公開順)
    searchCond_sortType: 'searchCond_sortType',
    // Session :検索条件(searchCond)_ソート方法:Interger(1:昇順, 2:降順)
    searchCond_sortOrder: 'sortOrder',
    // Session :検索条件(searchCond)_レコードFrom:Interger
    searchCond_recordFrom: 'recordFrom',
    // Session :検索条件(searchCond)_レコードTo:Interger
    searchCond_recordTo: 'recordTo',
    // Session :検索条件(searchCond)_カテゴリID:Interger
    searchCond_genreId: 'genreId',
    // Session :検索条件(searchCond)_グループID:Interger
    searchCond_groupId: 'groupId',
    // Local :ペン書式設定(penOpt)_色:String
    penOpt_color: 'penOpt_color',
    // Local :ペン書式設定(penOpt)_サイズ:Interger
    penOpt_size: 'penOpt_size',
    // Local :マーカ書式設定(maker)_色:String
    maker_color: 'maker_color',
    // Local :マーカ書式設定(maker)_サイズ:Interger
    maker_size: 'maker_size',
    // Local :消しゴム書式設定(erase)_色:String
    erase_color: 'erase_color',
    // Local :消しゴム書式設定(erase)_サイズ:Interger
    erase_size: 'erase_size',
    // Local :ユーザ情報(userInfo)_ログインID:String
    userInfo_loginId: 'loginId',
    // Local :ユーザ情報(userInfo)_アカウントパス:String
    userInfo_accountPath: 'accountPath',
    // Local :ユーザ情報(userInfo)_アカウント情報記憶フラグ:Char(Y:可能, N:不可)
    userInfo_rememberLogin: 'rememberLogin',
    // Local :ユーザ情報(userInfo)_最終ログイン日時:Datetime
    userInfo_lastLoginTime: 'lastLoginTime',
    // Local :ユーザ情報(userInfo)_パスワードスキップ日時:Datetime
    userInfo_pwdSkipDt: 'pwdSkipDt',
    // Local :ユーザオプション(userOpt)_動画繰り返しフラグ:Interger(0: 繰り返しなし, 1: 繰り返しあり)
    userOpt_videoMode: 'videoMode',
    // Local :ユーザオプション(userOpt)_音楽繰り返しフラグ:Interger(0: 繰り返しなし, 1: 繰り返しあり)
    userOpt_musicMode: 'musicMode',
    // Local :ユーザオプション(userOpt)_マーキング表示設定:Interger(0:表示しない, 1:表示する)
    userOpt_makingDsp: 'makingDsp',
    // Local :ユーザオプション(userOpt)_アラート表示設定:Interger(0:表示しない, 1:表示する)
    userOpt_closeOrRefreshAlert: 'userOpt_closeOrRefreshAlert',
    // Local :ユーザオプション(userOpt)_バックアップ確認フラグ:Interger(0:する, 1:しない)
    userOpt_bkConfirmFlg: 'bkConfirmFlg',
    // Local :並び順(sortOpt)_表示モード:Interger(0:本棚, 1:リスト)
    sortOpt_viewMode: 'viewMode',
    // Local :並び順(sortOpt)_表示区分:Interger(0:ジャンル, 1:グループ)
    sortOpt_viewType: 'viewType',
    // Local :並び順(sortOpt)_ソート基準:Interger(1:コンテンツ検索, 2:タグ検索, 3:全文検索)
    sortOpt_searchDivision: 'sortOpt_searchDivision',
    // Local: 並び順(sortOpt)_ソート方法:Interger(1:タイトル名, 2:タイトル名(かな), 3:公開順)
    sortOpt_sortType: 'sortOpt_sortType',
    // Local :しおりデータ(bookmark)_ページNo:Interger
    bookmark_pageNo: 'bookmark_pageNo',
    // Local :メモデータ(memo)_コンテンツID:Interger
    memo_contentNo: 'memo_contentNo',
    // Local :メモデータ(memo)_ページNo:Interger
    memo_pageNo: 'memo_pageNo',
    // Local :メモ(memo)_CopyText:String
    memo_copyText: 'memo_copyText'
    /* -------------------------------------------------------------------------------- */
    
};

// Entity for Bookmark
function BookMarkEntity() {
    this.contentid = "";
    this.pageNo = 0;
    // More info
    this.contentTitle = "";
    this.contentTitleKana = "";
    this.registerDate = new Date();
};

// Entity for Memo
function MemoEntity() {
    this.contentid=  "";
    this.pageNo = 0;
    this.posX = -1;
    this.posY = -1;
    this.Text = "";
};

// Entity for marking
function MarkingEntity() {
    this.contentid = "";
    this.pageNo = -1;
    this.content = "";
};
// Entity for log
function LogEntity() {
    this.contentid = "";
    this.readingStartDate = new Date();
    this.readingEndDate = null;
    this.readingTime = 0;
    this.deviceTypeId = 4;
};

// Build memo/marking/bookmark to base64string
function buildBackupData() {
    var result =[];
    var template1 = { type: 1, data: [] };
    var template2 = { type: 2, data: [] };
    var template3 = { type: 3, data: [] };


    // Build for bookmark
    for (var nIndex = 0; nIndex < ClientData.BookMarkData().length; nIndex++) {
        
        var oneItem = { contentid: ClientData.BookMarkData()[nIndex].contentid,
                        pageNo: ClientData.BookMarkData()[nIndex].pageNo,
                        contentTitle: ClientData.BookMarkData()[nIndex].contentTitle,
                        contentTitleKana: ClientData.BookMarkData()[nIndex].contentTitleKana,
                        registerDate: ClientData.BookMarkData()[nIndex].registerDate
                        };
        template3.data.push(oneItem);

    }
    result.push(template3);

    // Build for marking
    for (var nIndex = 0; nIndex < ClientData.MarkingData().length; nIndex++) {
        var oneItem1 = { contentid: ClientData.MarkingData()[nIndex].contentid, pageNo: ClientData.MarkingData()[nIndex].pageNo, content: ClientData.MarkingData()[nIndex].content };
        template2.data.push(oneItem1);
    }
    result.push(template2);

    // Build for memo
    for (var nIndex = 0; nIndex < ClientData.MemoData().length; nIndex++) {
        var oneItem2 = { contentid: ClientData.MemoData()[nIndex].contentid,
            pageNo: ClientData.MemoData()[nIndex].pageNo,
            posX: ClientData.MemoData()[nIndex].posX,
            posY: ClientData.MemoData()[nIndex].posY,
            Text: ClientData.MemoData()[nIndex].Text
        };
        template1.data.push(oneItem2);
    }
    result.push(template1);

    return result;
};

/*
  Restore data from server to local
*/
function restoreData(jsonString) {

    var data = jsonString;
    //var data = JSON.parse(jsonString);

    // Clear memo in client
    var arr = ClientData.MemoData();
    arr.clear();
    ClientData.MemoData(arr);

    // Clear marking in client
    arr = ClientData.MarkingData();
    arr.clear();
    ClientData.MarkingData(arr);

    // Clear marking in client
    arr = ClientData.BookMarkData();
    arr.clear();
    ClientData.BookMarkData(arr);

    var arrMarking = [];
    var arrBookMark = [];
    var arrMemo = [];
    for (var nIndex = 0; nIndex < data.length; nIndex++) {


        var oneType = data[nIndex];
        // Memo
        if (oneType.type == 1) {
            for (var nIndex1 = 0; nIndex1 < oneType.data.length; nIndex1++) {
                var obj = new MemoEntity();
                obj.contentid = oneType.data[nIndex1].contentid;
                obj.pageNo = oneType.data[nIndex1].pageNo;
                obj.posX = oneType.data[nIndex1].posX;
                obj.posY = oneType.data[nIndex1].posY;
                obj.Text = oneType.data[nIndex1].Text;
                // Add object to client
                arrMemo.push(obj);
            }
        }

        // Marking
        if (oneType.type == 2) {
            for (var nIndex1 = 0; nIndex1 < oneType.data.length; nIndex1++) {
                var obj = new MarkingEntity();
                obj.contentid = oneType.data[nIndex1].contentid;
                obj.pageNo = oneType.data[nIndex1].pageNo;
                obj.content = oneType.data[nIndex1].content;
                // Add object to client
                arrMarking.push(obj);
            }
        }
        // Bookmark
        if (oneType.type == 3) {

            for (var nIndex1 = 0; nIndex1 < oneType.data.length; nIndex1++) {
                var obj = new BookMarkEntity();
                obj.contentid = oneType.data[nIndex1].contentid;
                obj.pageNo = oneType.data[nIndex1].pageNo;
                obj.contentTitle = oneType.data[nIndex1].contentTitle;
                obj.contentTitleKana = oneType.data[nIndex1].contentTitleKana;
                obj.registerDate = oneType.data[nIndex1].registerDate;
                // Add object to client
                arrBookMark.push(obj);
            }
        }
    }
    ClientData.BookMarkData(arrBookMark);
    ClientData.MarkingData(arrMarking);
    ClientData.MemoData(arrMemo);

    return data;
};
/*
    Get data from localstorage and sessionstorage synchronization
    If has any param (args.length > 0) -> setter
    If has not param (args.length = 0) -> getter
        . Get from session:
          + if it existed and key existed in localstorage -> return result
          + else: 
            * set value from local to sessionstorage -> return value of sessionstorage if value is not empty, 
              otherwise, return default result.

*/
function operateData(args, strKey, returnDefaultData) {

    if (args.length > 0) {
        var data = args[0];
        LocalStorageUtils.set(strKey, data);
        SessionStorageUtils.set(strKey, JSON.stringify(data));
    } else {
        if (SessionStorageUtils.get(strKey) != 'undefined'
            && SessionStorageUtils.get(strKey) != undefined
            && SessionStorageUtils.get(strKey) != ''
            && SessionStorageUtils.get(strKey) != null
            && SessionStorageUtils.get(strKey) != 'null') {
            if (LocalStorageUtils.existKey(strKey) == true) {
                return JSON.parse(SessionStorageUtils.get(strKey));
            }
            else {
                return returnDefaultData;
            }
        }
        else {
            if (LocalStorageUtils.existKey(strKey) == true) {
                SessionStorageUtils.set(strKey, JSON.stringify(LocalStorageUtils.get(strKey)));
                return JSON.parse(SessionStorageUtils.get(strKey));
            }
//            SessionStorageUtils.set(strKey, JSON.stringify(LocalStorageUtils.get(strKey)));
//            if (SessionStorageUtils.get(strKey) != 'undefined'
//                && SessionStorageUtils.get(strKey) != undefined
//                && SessionStorageUtils.get(strKey) != ''
//                && SessionStorageUtils.get(strKey) != null
//                && SessionStorageUtils.get(strKey) != 'null') {
//                return JSON.parse(SessionStorageUtils.get(strKey));
//            }
            return returnDefaultData;
        }
    }
};
var ClientData = {
    zoom_ratioPre: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.zoom_ratioPre, JSON.stringify(data));
        } else {
            if (SessionStorageUtils.get(Keys.zoom_ratioPre) != 'undefined'
                && SessionStorageUtils.get(Keys.zoom_ratioPre) != undefined
                && SessionStorageUtils.get(Keys.zoom_ratioPre) != ''
                && SessionStorageUtils.get(Keys.zoom_ratioPre) != null
                && SessionStorageUtils.get(Keys.zoom_ratioPre) != 'null') {
                return JSON.parse(SessionStorageUtils.get(Keys.zoom_ratioPre));
            }
            return 1;
        }
    },
    // Local :ユーザ情報(userInfo)_アカウントパス:String
    userInfo_accountPath: function (data) {
        if (arguments.length > 0) {
            avwUserSetting().set(Keys.userInfo_accountPath, data);
        } else {
            return avwUserSetting().get(Keys.userInfo_accountPath);
        }
    },
    // Local: ユーザ情報(userInfo)_セッションID:String
    userInfo_sid_local: function (data) {
        if (arguments.length > 0) {
            avwUserSetting().set(Keys.userInfo_sid, data);
        } else {
            return avwUserSetting().get(Keys.userInfo_sid);
        }
    },
    // Local :ユーザ情報(userInfo)_ログインID:String
    userInfo_loginId: function (data) {
        if (arguments.length > 0) {
            avwUserSetting().set(Keys.userInfo_loginId, data);
        } else {
            return avwUserSetting().get(Keys.userInfo_loginId);
        }
    },
    // Local :ユーザ情報(userInfo)_アカウント情報記憶フラグ:Char(Y:可能, N:不可)
    userInfo_rememberLogin: function (data) {
        if (arguments.length > 0) {
            avwUserSetting().set(Keys.userInfo_rememberLogin, data);
        } else {
            return avwUserSetting().get(Keys.userInfo_rememberLogin);
        }
    },

    // Local 
    JumpQueue: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.JumpQueue, []);
        }
        else {
            return operateData(arguments, Keys.JumpQueue, []);
        }
    },
    // Local
    ResourceVersion: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.ResourceVersion, []);
        }
        else {
            return operateData(arguments, Keys.ResourceVersion, []);
        }
    },
    // Local
    ContentViewDetail: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.ContentViewDetail, []);
        }
        else {
            return operateData(arguments, Keys.ContentViewDetail, []);
        }
    },
    // Local
    MetaVersion: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.MetaVersion, []);
        }
        else {
            return operateData(arguments, Keys.MetaVersion, []);
        }
    },

    // Local
    ReadingContentIds: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.ReadingContentIds, []);
        }
        else {
            return operateData(arguments, Keys.ReadingContentIds, []);
        }
    },

    // Local: Bookmark collection
    BookMarkData: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.BookMarkData, []);
        }
        else {
            return operateData(arguments, Keys.BookMarkData, []);
        }
    },
    // Local: Marking collection
    MarkingData: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.MarkingData, []);
        }
        else {
            return operateData(arguments, Keys.MarkingData, []);
        }
    },

    // Local: content log collection
    ContentLogData: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.ContentLogData, []);
        }
        else {
            return operateData(arguments, Keys.ContentLogData, []);
        }
    },
    // Local: Memo collection
    MemoData: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.MemoData, []);
        }
        else {
            return operateData(arguments, Keys.MemoData, []);
        }
    },
    // Local
    IsJumpBack: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.IsJumpBack, undefined);
        }
        else {
            return operateData(arguments, Keys.IsJumpBack, undefined);
        }
    },
    // Local
    IsHideToolbar: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.IsHideToolbar, undefined);
        }
        else {
            return operateData(arguments, Keys.IsHideToolbar, undefined);
        }
    },
    // Local
    IsAddingMarking: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.IsAddingMarking, undefined);
        }
        else {
            return operateData(arguments, Keys.IsAddingMarking, undefined);
        }
    },
    // Local
    IsAddingMemo: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.IsAddingMemo, undefined);
        }
        else {
            return operateData(arguments, Keys.IsAddingMemo, undefined);
        }
    },
    // Local
    IsDisplayMarking: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.IsDisplayMarking, undefined);
        }
        else {
            return operateData(arguments, Keys.IsDisplayMarking, undefined);
        }
    },
    // Local
    IsDisplayMemo: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.IsDisplayMemo, undefined);
        }
        else {
            return operateData(arguments, Keys.IsDisplayMemo, undefined);
        }
    },

    // Local
    MarkingType: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.MarkingType, undefined);
        }
        else {
            return operateData(arguments, Keys.MarkingType, undefined);
        }
    },
    // Local :ユーザオプション(userOpt)_ログアウトモード: Interger(0:logout with backup, 1:logout without backup)
    userOpt_logoutMode: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.userOpt_logoutMode, undefined);
        }
        else {
            return operateData(arguments, Keys.userOpt_logoutMode, undefined);
        }
    },
    // Local
    BookmarkScreen: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.BookmarkScreen, undefined);
        }
        else {
            return operateData(arguments, Keys.BookmarkScreen, undefined);
        }
    },
    // Local: isChangedMemo:  boolean (true: changed, false: not change)
    isChangedMemo: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.isChangedMemo, undefined);
        }
        else {
            return operateData(arguments, Keys.isChangedMemo, undefined);
        }
    },
    // Local: isChangedMakingData:  boolean (true: changed, false: not change)
    isChangedMarkingData: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.isChangedMarkingData, undefined);
        }
        else {
            return operateData(arguments, Keys.isChangedMarkingData, undefined);
        }
    },

    // Local: isChangedBookmark:  boolean (true: changed, false: not change)
    isChangedBookmark: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.isChangedBookmark, undefined);
        }
        else {
            return operateData(arguments, Keys.isChangedBookmark, undefined);
        }
    },

    // Local :共通(common)_コンテンツID:Integer
    common_preContentId: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.common_preContentId, undefined);
        }
        else {
            return operateData(arguments, Keys.common_preContentId, undefined);
        }
    },
    // Local :ページ情報データ(common)_ページNo:Integer
    common_prePageNo: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.common_prePageNo, undefined);
        }
        else {
            return operateData(arguments, Keys.common_prePageNo, undefined);
        }
    },
    // Local :ペン書式設定(penOpt)_色:String
    penOpt_color: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.penOpt_color, undefined);
        }
        else {
            return operateData(arguments, Keys.penOpt_color, undefined);
        }
    },

    // Local :ペン書式設定(penOpt)_サイズ:Interger
    penOpt_size: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.penOpt_size, undefined);
        }
        else {
            return operateData(arguments, Keys.penOpt_size, undefined);
        }
    },

    // Local :マーカ書式設定(maker)_色:String
    maker_color: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.maker_color, undefined);
        }
        else {
            return operateData(arguments, Keys.maker_color, undefined);
        }
    },

    // Local :マーカ書式設定(maker)_サイズ:Interger
    maker_size: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.maker_size, undefined);
        }
        else {
            return operateData(arguments, Keys.maker_size, undefined);
        }
    },

    // Local :消しゴム書式設定(erase)_色:String
    erase_color: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.erase_color, undefined);
        }
        else {
            return operateData(arguments, Keys.erase_color, undefined);
        }
    },

    // Local :消しゴム書式設定(erase)_サイズ:Interger
    erase_size: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.erase_size, undefined);
        }
        else {
            return operateData(arguments, Keys.erase_size, undefined);
        }
    },
    // Local :ユーザ情報(userInfo)_最終ログイン日時:Datetime
    userInfo_lastLoginTime: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.userInfo_lastLoginTime, undefined);
        }
        else {
            return operateData(arguments, Keys.userInfo_lastLoginTime, undefined);
        }
    },

    // Local :ユーザ情報(userInfo)_パスワードスキップ日時:Datetime
    userInfo_pwdSkipDt: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.userInfo_pwdSkipDt, undefined);
        }
        else {
            return operateData(arguments, Keys.userInfo_pwdSkipDt, undefined);
        }
    },
    // Local :ユーザオプション(userOpt)_動画繰り返しフラグ:Interger(0: 繰り返しなし, 1: 繰り返しあり)
    userOpt_videoMode: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.userOpt_videoMode, undefined);
        }
        else {
            return operateData(arguments, Keys.userOpt_videoMode, undefined);
        }
    },
    // Local :ユーザオプション(userOpt)_音楽繰り返しフラグ:Interger(0: 繰り返しなし, 1: 繰り返しあり)
    userOpt_musicMode: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.userOpt_musicMode, undefined);
        }
        else {
            return operateData(arguments, Keys.userOpt_musicMode, undefined);
        }
    },

    // Local :ユーザオプション(userOpt)_マーキング表示設定:Interger(0:表示しない, 1:表示する)
    userOpt_makingDsp: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.userOpt_makingDsp, undefined);
        }
        else {
            return operateData(arguments, Keys.userOpt_makingDsp, undefined);
        }
    },
    // Local :ユーザオプション(userOpt)_アラート表示設定:Interger(0:表示しない, 1:表示する)
    userOpt_closeOrRefreshAlert: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.userOpt_closeOrRefreshAlert, undefined);
        }
        else {
            return operateData(arguments, Keys.userOpt_closeOrRefreshAlert, undefined);
        }
    },
    // Local :ユーザオプション(userOpt)_バックアップ確認フラグ:Interger(0:する, 1:しない)
    userOpt_bkConfirmFlg: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.userOpt_bkConfirmFlg, undefined);
        }
        else {
            return operateData(arguments, Keys.userOpt_bkConfirmFlg, undefined);
        }
    },
    // Local :並び順(sortOpt)_表示モード:Interger(0:本棚, 1:リスト)
    sortOpt_viewMode: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.sortOpt_viewMode, undefined);
        }
        else {
            return operateData(arguments, Keys.sortOpt_viewMode, undefined);
        }
    },

    // Local :並び順(sortOpt)_表示区分:Interger(0:ジャンル, 1:グループ)
    sortOpt_viewType: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.sortOpt_viewType, undefined);
        }
        else {
            return operateData(arguments, Keys.sortOpt_viewType, undefined);
        }
    },

    // Local :並び順(sortOpt)_ソート基準:Interger(1:コンテンツ検索, 2:タグ検索, 3:全文検索)
    sortOpt_searchDivision: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.sortOpt_searchDivision, undefined);
        }
        else {
            return operateData(arguments, Keys.sortOpt_searchDivision, undefined);
        }
    },

    // Local: 並び順(sortOpt)_ソート方法:Interger(1:タイトル名, 2:タイトル名(かな), 3:公開順)
    sortOpt_sortType: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.sortOpt_sortType, undefined);
        }
        else {
            return operateData(arguments, Keys.sortOpt_sortType, undefined);
        }
    },
    // Local :しおりデータ(bookmark)_ページNo:Interger
    bookmark_pageNo: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.bookmark_pageNo, undefined);
        }
        else {
            return operateData(arguments, Keys.bookmark_pageNo, undefined);
        }
    },

    // Local :メモデータ(memo)_コンテンツID:Interger
    memo_contentNo: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.memo_contentNo, undefined);
        }
        else {
            return operateData(arguments, Keys.memo_contentNo, undefined);
        }
    },

    // Local :メモデータ(memo)_ページNo:Interger
    memo_pageNo: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.memo_pageNo, undefined);
        }
        else {
            return operateData(arguments, Keys.memo_pageNo, undefined);
        }
    },
    // Session
    memo_copyText: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.memo_copyText, JSON.stringify(data));
        } else {
            if (SessionStorageUtils.get(Keys.memo_copyText) != 'undefined'
                && SessionStorageUtils.get(Keys.memo_copyText) != undefined
                && SessionStorageUtils.get(Keys.memo_copyText) != ''
                && SessionStorageUtils.get(Keys.memo_copyText) != null
                && SessionStorageUtils.get(Keys.memo_copyText) != 'null') {
                return JSON.parse(SessionStorageUtils.get(Keys.memo_copyText));
            }
            return null;
        }
    },
    // Session
    IsRefresh: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.IsRefresh, JSON.stringify(data));
        } else {
            if (SessionStorageUtils.get(Keys.IsRefresh) != 'undefined'
                && SessionStorageUtils.get(Keys.IsRefresh) != undefined
                && SessionStorageUtils.get(Keys.IsRefresh) != ''
                && SessionStorageUtils.get(Keys.IsRefresh) != null
                && SessionStorageUtils.get(Keys.IsRefresh) != 'null') {
                return JSON.parse(SessionStorageUtils.get(Keys.IsRefresh));
            }
            return false;
        }
    },
    // Session
    userInfo_userName: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.userInfo_userName, data);
        } else {
            return SessionStorageUtils.get(Keys.userInfo_userName);
        }
    },

    // Session :コンテンツ詳細情報(contentInfo)_サムネール: String (base64string)
    contentInfo_contentThumbnail: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.contentInfo_contentThumbnail, data);
        } else {
            return SessionStorageUtils.get(Keys.contentInfo_contentThumbnail);
        }
    },

    // Session:パスワード要変更(requirePasswordChange):String (0:不要, 1:初回, 2:定期変更)
    requirePasswordChange: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.requirePasswordChange, data);
        } else {
            return SessionStorageUtils.get(Keys.requirePasswordChange);
        }
    },

    // Session:ユーザ情報(userInfo)_セッションID:String
    userInfo_sid: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.userInfo_sid, data);
            avwUserSetting().set(Keys.userInfo_sid, data);
        } else {
            //return avwUserSetting().get(Keys.userInfo_sid);
            if (avwUserSession()) {
                return SessionStorageUtils.get(Keys.userInfo_sid);
            }
            return null;
        }
    },

    // Session :事業者オプション(serviceOpt)_初回ログイン時パスワード強制変更:Integer(0:なし, 1:催促, 2:強制)
    serviceOpt_force_pw_change_on_login: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.serviceOpt_force_pw_change_on_login, data);
        } else {
            return SessionStorageUtils.get(Keys.serviceOpt_force_pw_change_on_login);
        }
    },

    // Session :事業者オプション(serviceOpt)_定期ログイン時パスワード強制変更:Integer(0:なし, 1:催促, 2:強制)
    serviceOpt_force_pw_change_periodically: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.serviceOpt_force_pw_change_periodically, data);
        } else {
            return SessionStorageUtils.get(Keys.serviceOpt_force_pw_change_periodically);
        }
    },

    // Session:事業者オプション(serviceOpt)_メモ・マーキングデータバックアップ使用:Char(Y:可能, N:不可)
    serviceOpt_user_data_backup: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.serviceOpt_user_data_backup, data);
        } else {
            return SessionStorageUtils.get(Keys.serviceOpt_user_data_backup);
        }
    },

    // Session :事業者オプション(serviceOpt)_マーキング機能使用:Char(Y:可能, N:不可)
    serviceOpt_marking: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.serviceOpt_marking, data);
        } else {
            return SessionStorageUtils.get(Keys.serviceOpt_marking);
        }
    },

    // Session :事業者オプション(serviceOpt)_一定期間経過後アプリロック:Char(Y:可能, N:不可)
    serviceOpt_force_login_periodically: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.serviceOpt_force_login_periodically, data);
        } else {
            return SessionStorageUtils.get(Keys.serviceOpt_force_login_periodically);
        }
    },

    // Session :共通(common)_コンテンツID:Integer
    common_contentId: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.common_contentId, data);
        } else {
            return SessionStorageUtils.get(Keys.common_contentId);
        }
    },

    // Session: 共通(common)_コンテンツデータチェックフラグ: Integer(true/false, true:メモ、マーキング、しおりを削除する処理を行える false:メモ、マーキング、しおりを削除する処理をしない)
    common_contentDataChkFlg: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.common_contentDataChkFlg, data);
        } else {
            return SessionStorageUtils.get(Keys.common_contentDataChkFlg);
        }
    },
    // Session :ページ情報データ(pageInfo)_ページNo:Integer
    pageInfo_pageNo: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.pageInfo_pageNo, data);
        } else {
            return SessionStorageUtils.get(Keys.pageInfo_pageNo);
        }
    },

    // Session :ページ情報データ(pageInfo)_ページテキスト:String
    pageInfo_pageText: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.pageInfo_pageText, data);
        } else {
            return SessionStorageUtils.get(Keys.pageInfo_pageText);
        }
    },

    // Session :ページ情報データ(pageInfo)_コンテンツサムネイル:Integer
    pageInfo_pageImgResrcId: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.pageInfo_pageImgResrcId, data);
        } else {
            return SessionStorageUtils.get(Keys.pageInfo_pageImgResrcId);
        }
    },

    // Session :コンテンツ内リンク(linkInfo)_リンク位置のx座標:Integer
    linkInfo_linkLocationX: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.linkInfo_linkLocationX, data);
        } else {
            return SessionStorageUtils.get(Keys.linkInfo_linkLocationX);
        }
    },

    // Session :コンテンツ内リンク(linkInfo)_リンク位置のy座標:Integer
    linkInfo_linkLocationY: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.linkInfo_linkLocationY, data);
        } else {
            return SessionStorageUtils.get(Keys.linkInfo_linkLocationY);
        }
    },

    // Session :コンテンツ内リンク(linkInfo)_リンク領域の幅:Integer
    linkInfo_linkLocationWidth: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.linkInfo_linkLocationWidth, data);
        } else {
            return SessionStorageUtils.get(Keys.linkInfo_linkLocationWidth);
        }
    },

    // Session :コンテンツ内リンク(linkInfo)_リンク領域の高さ:Integer
    linkInfo_linkLocationHeight: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.linkInfo_linkLocationHeight, data);
        } else {
            return SessionStorageUtils.get(Keys.linkInfo_linkLocationHeight);
        }
    },

    // Session :コンテンツ内リンク(linkInfo)_リンクタイプ:Integer(0/1)
    linkInfo_linkKind: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.linkInfo_linkKind, data);
        } else {
            return SessionStorageUtils.get(Keys.linkInfo_linkKind);
        }
    },

    // Session :コンテンツ内リンク(linkInfo)_ターゲットURI:String(0/1)
    linkInfo_destURI: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.linkInfo_destURI, data);
        } else {
            return SessionStorageUtils.get(Keys.linkInfo_destURI);
        }
    },

    // Session :コンテンツ内リンク(linkInfo)_ターゲットページNo:Integer(0/1)
    linkInfo_destPageNumber: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.linkInfo_destPageNumber, data);
        } else {
            return SessionStorageUtils.get(Keys.linkInfo_destPageNumber);
        }
    },

    // Session :閲覧ログ(log)_コンテンツ閲覧開始時刻:Datetime
    log_contentStartViewDt: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.log_contentStartViewDt, data);
        } else {
            return SessionStorageUtils.get(Keys.log_contentStartViewDt);
        }
    },

    // Session :コンテンツ詳細情報(contentInfo)_コンテンツID:Integer
    contentInfo_contentId: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.contentInfo_contentId, data);
        } else {
            return SessionStorageUtils.get(Keys.contentInfo_contentId);
        }
    },

    // Session :コンテンツ詳細情報(contentInfo)_カテゴリID:Integer
    contentInfo_categoryId: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.contentInfo_categoryId, data);
        } else {
            return SessionStorageUtils.get(Keys.contentInfo_categoryId);
        }
    },

    // Session :コンテンツ詳細情報(contentInfo)_コンテンツ名:String
    contentInfo_contentName: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.contentInfo_contentName, data);
        } else {
            return SessionStorageUtils.get(Keys.contentInfo_contentName);
        }
    },

    // Session :コンテンツ詳細情報(contentInfo)_コンテンツ名(カナ):String
    contentInfo_contentNameKana: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.contentInfo_contentNameKana, data);
        } else {
            return SessionStorageUtils.get(Keys.contentInfo_contentNameKana);
        }
    },

    // Session :コンテンツ詳細情報(contentInfo)_コンテンツ詳細:String
    contentInfo_contentDetail: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.contentInfo_contentDetail, data);
        } else {
            return SessionStorageUtils.get(Keys.contentInfo_contentDetail);
        }
    },

    // Session :コンテンツ詳細情報(contentInfo)_公開開始日:Datetime
    contentInfo_deliveryStartDate: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.contentInfo_deliveryStartDate, data);
        } else {
            return SessionStorageUtils.get(Keys.contentInfo_deliveryStartDate);
        }
    },

    // Session :コンテンツ詳細情報(contentInfo)_公開終了日:Datetime
    contentInfo_deliveryEndDate: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.contentInfo_deliveryEndDate, data);
        } else {
            return SessionStorageUtils.get(Keys.contentInfo_deliveryEndDate);
        }
    },

    // Session :コンテンツ詳細情報(contentInfo)_本棚サムネール名:Interger
    contentInfo_thumbnailName: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.contentInfo_thumbnailName, data);
        } else {
            return SessionStorageUtils.get(Keys.contentInfo_thumbnailName);
        }
    },

    // Session :コンテンツ詳細情報(contentInfo)_詳細画面サムネール名:Interger
    contentInfo_thumbnailBigName: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.contentInfo_thumbnailBigName, data);
        } else {
            return SessionStorageUtils.get(Keys.contentInfo_thumbnailBigName);
        }
    },

    // Session :コンテンツ詳細情報(contentInfo)_メタ更新バージョン:Interger
    contentInfo_metaVersion: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.contentInfo_metaVersion, data);
        } else {
            return SessionStorageUtils.get(Keys.contentInfo_metaVersion);
        }
    },

    // Session :コンテンツ詳細情報(contentInfo)_リソース更新バージョン:Interger
    contentInfo_resourceVersion: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.contentInfo_resourceVersion, data);
        } else {
            return SessionStorageUtils.get(Keys.contentInfo_resourceVersion);
        }
    },

    // Session :コンテンツ詳細情報(contentInfo)_PDF総ページ数:Interger
    contentInfo_allPageNum: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.contentInfo_allPageNum, data);
        } else {
            return SessionStorageUtils.get(Keys.contentInfo_allPageNum);
        }
    },

    // Session :検索条件(searchCond)_検索テキスト:String
    searchCond_searchText: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.searchCond_searchText, data);
        } else {
            return SessionStorageUtils.get(Keys.searchCond_searchText);
        }
    },

    // Session :検索条件(searchCond)_検索区分:Interger(1:コンテンツ検索, 2:タグ検索, 3:全文検索)
    searchCond_searchDivision: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.searchCond_searchDivision, data);
        } else {
            return SessionStorageUtils.get(Keys.searchCond_searchDivision);
        }
    },

    // Session :検索条件(searchCond)_ソート基準:Interger(1:タイトル名, 2:タイトル名(かな), 3:公開順)
    searchCond_sortType: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.searchCond_sortType, data);
        } else {
            return SessionStorageUtils.get(Keys.searchCond_sortType);
        }
    },

    // Session :検索条件(searchCond)_ソート方法:Interger(1:昇順, 2:降順)
    searchCond_sortOrder: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.searchCond_sortOrder, data);
        } else {
            return SessionStorageUtils.get(Keys.searchCond_sortOrder);
        }
    },

    // Session :検索条件(searchCond)_レコードFrom:Interger
    searchCond_recordFrom: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.searchCond_recordFrom, data);
        } else {
            return SessionStorageUtils.get(Keys.searchCond_recordFrom);
        }
    },

    // Session :検索条件(searchCond)_レコードTo:Interger
    searchCond_recordTo: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.searchCond_recordTo, data);
        } else {
            return SessionStorageUtils.get(Keys.searchCond_recordTo);
        }
    },

    // Session :検索条件(searchCond)_カテゴリID:Interger
    searchCond_genreId: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.searchCond_genreId, data);
        } else {
            return SessionStorageUtils.get(Keys.searchCond_genreId);
        }
    },

    // Session :検索条件(searchCond)_グループID:Interger
    searchCond_groupId: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.searchCond_groupId, data);
        } else {
            return SessionStorageUtils.get(Keys.searchCond_groupId);
        }
    },

    // Session :ユーザ情報(userInfo)_ログインID:String
    userInfo_loginId_session: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.userInfo_loginId, data);
        } else {
            return SessionStorageUtils.get(Keys.userInfo_loginId);
        }
    },

    // Session :ユーザ情報(userInfo)_アカウントパス:String
    userInfo_accountPath_session: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.userInfo_accountPath, data);
        } else {
            return SessionStorageUtils.get(Keys.userInfo_accountPath);
        }
    }
};

// -------------------------------------------------
// Define all keys for local/session storage [ end ]
// -------------------------------------------------

// =============================================================================================
// Constants [ end ]
// =============================================================================================

/*
* Operations for local storage
*/
var LocalStorageUtils = {
    getUniqueId: function () {
        var uniqueId = "";

        if (avwUserSetting().get(Keys.userInfo_accountPath)) {
            uniqueId += avwUserSetting().get(Keys.userInfo_accountPath);
        }
        if (avwUserSetting().get(Keys.userInfo_loginId)) {
            uniqueId += "." + avwUserSetting().get(Keys.userInfo_loginId);
        }
        if (uniqueId != "") {
            uniqueId += ".";
        }

        return uniqueId;
    },
    get: function (strKey) {
        var key = this.getUniqueId() + strKey;

        return avwUserSetting().get(key);
    },
    set: function (strKey, objValue) {
        var key = this.getUniqueId() + strKey;
        avwUserSetting().set(key, objValue);
    },
    remove: function (strKey) {
        var key = this.getUniqueId() + strKey;
        avwUserSetting().remove(key);
        SessionStorageUtils.remove(strKey);
    },
    clear: function () {
        var localStorageKeys = avwUserSetting().keys();
        for (var nIndex = 0; nIndex < localStorageKeys.length; nIndex++) {
            var strKey = localStorageKeys[nIndex];

            if ((strKey + "").contains(this.getUniqueId())) {
                avwUserSetting().remove(strKey);
            }
        }
    },
    existKey: function (strKey) {
        var keys = avwUserSetting().keys();
        var findKey = this.getUniqueId() + strKey;
        var isExisted = false;
        if (keys != null && keys != undefined) {
            for (var nIndex = 0; nIndex < keys.length; nIndex++) {
                if (keys[nIndex] == findKey) {
                    isExisted = true;
                    break;
                }
            }
        }
        return isExisted;
    }
};

/*
 * Operations for session storage [start]
 */

var SessionStorageUtils = {
    login: function () {
        if (avwUserSession()) {
            // Skip this case
        }
        else {
            avwCreateUserSession();
        }
    },
    get: function (strKey) {
        return avwUserSession().get(strKey);
    },
    set: function (strKey, objValue) {
        avwUserSession().set(strKey, objValue);
    },
    clear: function () {
        if (avwUserSession()) {
            avwUserSession().destroy();
        }
    },
    remove: function (strKey) {
        avwUserSession().set(strKey, null);
    }
};
/*
 * Operations for session storage [ end ]
 */


// =============================================================================================
// Utils for string, date, number [start]
// =============================================================================================

/*
* Convert date to JP format date time [start]
*/

/*
YYYY/MM/DD HH:MM:SS
*/
Date.prototype.jpDateTimeString = function () {
    var strResult = "";
    var strYear = this.getFullYear() + "";
    var strMonth = (this.getMonth() + 1) + "";
    var strDayInMonth = this.getDate() + "";
    var strHour = this.getHours() + "";
    var strMinute = this.getMinutes() + "";
    var strSecond = this.getSeconds() + "";

    strResult += strYear.padLeft("0", 4) + "/" + strMonth.padLeft("0", 2) + "/" + strDayInMonth.padLeft("0", 2);
    strResult += " " + strHour.padLeft("0", 2) + ":" + strMinute.padLeft("0", 2) + ":" + strSecond.padLeft("0", 2);
    return strResult;

};
/*
YYYY-MM-DD HH:MM:SS
*/
Date.prototype.jpDateTimeString1 = function () {
    var strResult = "";
    var strYear = this.getFullYear() + "";
    var strMonth = (this.getMonth() + 1) + "";
    var strDayInMonth = this.getDate() + "";
    var strHour = this.getHours() + "";
    var strMinute = this.getMinutes() + "";
    var strSecond = this.getSeconds() + "";

    strResult += strYear.padLeft("0", 4) + "-" + strMonth.padLeft("0", 2) + "-" + strDayInMonth.padLeft("0", 2);
    strResult += " " + strHour.padLeft("0", 2) + ":" + strMinute.padLeft("0", 2) + ":" + strSecond.padLeft("0", 2);
    return strResult;

};
Date.prototype.jpDateString = function () {
    var strResult = "";
    var strYear = this.getFullYear() + "";
    var strMonth = (this.getMonth() + 1) + "";
    var strDayInMonth = this.getDate() + "";

    strResult += strYear.padLeft("0", 4) + "/" + strMonth.padLeft("0", 2) + "/" + strDayInMonth.padLeft("0", 2);

    return strResult;

};
Date.prototype.jpTimeString = function () {
    var strResult = "";
    var strHour = this.getHours() + "";
    var strMinute = this.getMinutes() + "";
    var strSecond = this.getSeconds() + "";

    strResult += " " + strHour.padLeft("0", 2) + ":" + strMinute.padLeft("0", 2) + ":" + strSecond.padLeft("0", 2);
    return strResult;

};
Date.prototype.jpShortTimeString = function () {
    var strResult = "";
    var strHour = this.getHours() + "";
    var strMinute = this.getMinutes() + "";
    var strSecond = this.getSeconds() + "";

    strResult += " " + strHour.padLeft("0", 2) + ":" + strMinute.padLeft("0", 2);
    return strResult;

};
Date.prototype.toIdString = function () {
    var strResult = "";
    var strYear = this.getFullYear() + "";
    var strMonth = (this.getMonth() + 1) + "";
    var strDayInMonth = this.getDate() + "";
    var strHour = this.getHours() + "";
    var strMinute = this.getMinutes() + "";
    var strSecond = this.getSeconds() + "";
    var strMilisecond = this.getMilliseconds() + "";

    strResult += strYear.padLeft("0", 4) + strMonth.padLeft("0", 2) + strDayInMonth.padLeft("0", 2);
    strResult += strHour.padLeft("0", 2) + strMinute.padLeft("0", 2) + strSecond.padLeft("0", 2) + strMilisecond.padLeft("0", 3);
    return strResult;
};
// Subtract date to get days
Date.prototype.subtractByDays = function (targetDate) {
var milis = Math.abs(this - targetDate);
var days = Math.floor(milis / (60 * 60 * 24 * 1000));
return days;
};
Date.prototype.addSeconds = function (plusSeconds) {
var newDate = new Date(this.getTime() + plusSeconds * 1000);
return newDate;
};

// Subtract date to get days
Date.prototype.subtractBySeconds = function (targetDate) {
var milis = Math.abs(this - targetDate);
var days = Math.floor(milis / 1000);
return days;
};

/*
* Convert date to JP format date time [ end ]
*/

//trimming space from both side of the string
String.prototype.trim = function () {
    return this.replace(/^\s+|\s+$/g, "");
};

//trimming space from left side of the string
String.prototype.trimLeft = function () {
    return this.replace(/^\s+/, "");
};

//trimming space from right side of the string
String.prototype.trimRight = function () {
    return this.replace(/\s+$/, "");
};

//String: pads left
String.prototype.padLeft = function (padString, length) {
    var str = this;
    while (str.length < length)
        str = padString + str;
    return str;
};

//String: pads right
String.prototype.padRight = function (padString, length) {
    var str = this;
    while (str.length < length)
        str = str + padString;
    return str;
};
// Check contain string
String.prototype.contains = function (string) {

    if (this.indexOf(string) != -1) {
        return true;
    }
    return false;
};

//Number: pads left
Number.prototype.padLeft = function (padString, length) {
    var str = this + "";
    return str.padLeft(padString, length);
};

//Number: pads right
Number.prototype.padRight = function (padString, length) {
    var str = this + "";
    return str.padRight(padString, length);
};
// Clear data of array
Array.prototype.clear = function () {
    this.splice(0, this.length);
};

/*
  Remove extension of specified name
  Ex: aaaa.mp3 -> aaa
*/
function removeExt(strName) {
    if (strName) {
        var arrString = strName.split('.');
        var strResult = "";
        if (arrString.length > 1) {
            var nLastIndex = strName.lastIndexOf('.');
            strResult = strName.substr(0, nLastIndex);
        }
        else {
            strResult = strName;
        }
        return strResult;
    }
    return "";
};

/*
* String utilities [ end ]
*/

// =============================================================================================
// Utils for string, date, number [ end ]
// =============================================================================================

var ValidationUtil = {

    // 必須: Text
    CheckRequiredForText: function (value) {

        if (value == null || value == '') {
            return false;
        }
        return true;
    },

    //get byte count
    GetByteCount: function (value) {
        var escapedStr = encodeURI(value);
        if (escapedStr.indexOf("%") != -1) {
            var count = escapedStr.split("%").length - 1;
            if (count == 0) count++;  //perverse case; can't happen with real UTF-8
            var tmp = escapedStr.length - (count * 3);
            count = count + tmp;
        } else {
            count = escapedStr.length;
        }
        return count;
    },

    // 最小文字数
    CheckMinLengthForByte: function (value, len) {
        if (this.GetByteCount(value) < len)
            return false;
        return true;
    },

    // 最大文字数
    CheckMaxLengthForByte: function (value, len) {

        if (this.GetByteCount(value) > len)
            return false;
        return true;
    },

    // 半数字
    IsNumber: function (value) {
        var reg = new RegExp("^[0-9]+$");
        return reg.test(value);
    },

    // 半英字
    IsAlphabet: function (value) {
        var reg = new RegExp("^[a-zA-Z]+$");
        return reg.test(value);
    },

    // 半記号
    IsSymbol: function (value) {
        var reg = new RegExp("\u005b\u005e\u0027\u0060\u0027\u007e\u0027\u0021\u0027\u0040\u0027\u0023\u0027\u0024\u0027\u0025\u0027\u005e\u0027\u0026\u0027\u002a\u0027\u0028\u0027\u0029\u0027\u005f\u0027\u002b\u0027\u003d\u0027\u007b\u0027\u007d\u0027\u007c\u0027\u003a\u0027\u0022\u0027\u003b\u0027\u0027\u0027\u003c\u0027\u003e\u0027\u003f\u0027\u002f\u0027\u002e\u0027\u002c\u005c\u002d\u005b\u005c\u005d\u005c\u005c\u005d");
        return !reg.test(value);
    },

    // メール
    CheckEmailValid: function (value) {
        //Check if string is a valid email address
        var reg = new RegExp("^[0-9a-zA-Z]+@[0-9a-zA-Z]+[\\.]{1}[0-9a-zA-Z]+[\\.]?[0-9a-zA-Z]+$");
        return reg.test(value);
    },

    CheckPasswordValid: function (value) {
        //Check if string is a valid email address
        var reg = new RegExp("^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[#+-\\./:_]).{1,47}$");
        return reg.test(value);
    },

    IsAlphabetOrNumberOrSymbol: function (value) {
        //Check if string is alphabet or number or symbol
        var reg = new RegExp("\u005b\u005e\u0061\u002d\u007a\u0041\u002d\u005a\u0030\u002d\u0039\u0027\u0060\u0027\u007e\u0027\u0021\u0027\u0040\u0027\u0023\u0027\u0024\u0027\u0025\u0027\u005e\u0027\u0026\u0027\u002a\u0027\u0028\u0027\u0029\u0027\u005f\u0027\u002b\u0027\u003d\u0027\u007b\u0027\u007d\u0027\u007c\u0027\u003a\u0027\u0022\u0027\u003b\u0027\u0027\u0027\u003c\u0027\u003e\u0027\u003f\u0027\u002f\u0027\u002e\u0027\u002c\u005c\u002d\u005b\u005c\u005d\u005c\u005c\u005d");
        return !reg.test(value);
    },

    CheckNumberOfTypeInString: function (value) {
        var list = new Array();
        var c;
        for (var i = 0; i < value.length; i++) {
            c = value[i];
            for (var j = i + 1; j < value.length; j++) {
                if (value[j] == c) {
                    value = value.slice(0, j) + value.slice(j + 1, value.len);
                    j = j - 1;
                }
            }
            list[i] = c;
        }
        var count = list.length;
        return count
    },

    IsCharacterSpecial: function (value) {
        for (var i = 0; i < value.length; i++) {
            if (value[i] == '*')
                return true;
        }
        return false;
    },


    // 半記号
    IsPasswordSymbol: function (value) {
        var reg = new RegExp("\u005b\u005e\u0027\u0023\u0027\u002b\u005c\u002d\u0027\u002e\u0027\u002f\u0027\u003a\u0027\u005f\u005d");
        return !reg.test(value);
    },

    // 半記号
    IsPasswordAlphabetOrNumerOrSymbol: function (value) {
        var reg = new RegExp("\u005b\u005e\u0061\u002d\u007a\u0041\u002d\u005a\u0030\u002d\u0039\u0027\u0023\u0027\u002b\u005c\u002d\u0027\u002e\u0027\u002f\u0027\u003a\u0027\u005f\u005d");
        return !reg.test(value);
    }
};

function getBase64Image(imgSource) {
    return imgSource.replace(/^data:image\/(png|jpg);base64,/, "");
};

function LockScreen() {
	if(avwUserSession()) {
        if (ClientData.serviceOpt_force_login_periodically() == "Y") {
        	//var message = i18nText("sysInfoScrLock01");
            screenLock({
                timeout: Consts.ConstLockScreenTime,
                html: '<img src="img/1222.png" alt="Screen Lock" /><br />', //+ message,
                unlockFunc: unlockFunction,
                errorMessage: i18nText('msgLoginErrWrong')
            });
        }
    }
};

// Lock screen
$(function () {
    
    // Init setting values 
    if (avwUserSession()) {  // Logged

        // View mode default
        if (ClientData.sortOpt_viewMode() == null || ClientData.sortOpt_viewMode() == undefined) {
            ClientData.sortOpt_viewMode(Consts.ConstDisplayMode_BookShelf); // Bookshelf
        }

        // 動画、音楽繰り返し
        if (ClientData.userOpt_musicMode() == null || ClientData.userOpt_musicMode() == undefined) {
            ClientData.userOpt_musicMode(1);
        }
        if (ClientData.userOpt_videoMode() == null || ClientData.userOpt_videoMode() == undefined) {
            ClientData.userOpt_videoMode(1);
        }

        // マーキング(コンテンツを開いた時に表示する)
        if (ClientData.userOpt_makingDsp() == null || ClientData.userOpt_makingDsp() == undefined) {
            ClientData.userOpt_makingDsp(1);
        }

        // 毎回ログアウトの時、バックアップするかどうかは必ず確認する
        if (ClientData.userOpt_bkConfirmFlg() == null || ClientData.userOpt_bkConfirmFlg() == undefined) {
            ClientData.userOpt_bkConfirmFlg(1);
        }

        // タブ・ブラウザ終了・F5時のアラートが表示する
        if (ClientData.userOpt_closeOrRefreshAlert() == null || ClientData.userOpt_closeOrRefreshAlert() == undefined) {
            ClientData.userOpt_closeOrRefreshAlert(1);
        }
    }

});


function unlockFunction(inputPass) {
    var forceUnlockFunc = arguments[1]; // added secret arguments : forceUnlockFunction
    var result = false;
    var params = {
        previousSid: ClientData.userInfo_sid(),
        loginId: ClientData.userInfo_loginId_session(),
        password: inputPass,
        urlpath: ClientData.userInfo_accountPath()
    };

    // Get url to login
    var sysSettings = avwSysSetting();
    var apiLoginUrl = sysSettings.apiLoginUrl;
    var errorCode = '';
    avwCmsApiSyncWithUrl(apiLoginUrl, null, 'webClientLogin', 'GET', params,
	        function (data) {
	            if (data.result == 'success') {
	                ClientData.userInfo_sid(data.sid);
	                result = true;
	                //forceUnlockFunc();
	            }
	        },
	        function (xhr, statusText, errorThrown) {
	            if (xhr.responseText && xhr.status != 0) {
	                errorCode = JSON.parse(xhr.responseText);
	            }
	            else {
	                errorCode = { errorMessage: "E001" };
	            }
	        });

    
    if (result == true) {
        if (window.onUnlock) {
            onUnlock();
        }
    }
    return { 'result': result, 'errorCode': errorCode };
};



/*
  Set log for reading content
*/
function SetStartLog(strContentId) {
    var isFound = false;
    var arrContentLogs = ClientData.ContentLogData();

    for (var nIndex = 0;  nIndex < arrContentLogs.length; nIndex++) {
        if (arrContentLogs[nIndex].contentid == strContentId) {
            arrContentLogs[nIndex].readingStartDate = new Date();
            arrContentLogs[nIndex].readingEndDate = (new Date()).addSeconds(1);
            
            // Reading time
            arrContentLogs[nIndex].readingTime = arrContentLogs[nIndex].readingEndDate.subtractBySeconds(arrContentLogs[nIndex].readingStartDate);

            isFound = true;
            break;
        }
    }
    if(isFound == false) {
        var curr = new Date();
        var curr1 = new Date();
        var log = new LogEntity();
        log.readingStartDate = curr;
        log.contentid = strContentId;
        
        // Set 1 second
        curr1.setSeconds(curr.getSeconds() + 1);

        log.readingEndDate = curr1;

        // Reading time
        log.readingTime = log.readingEndDate.subtractBySeconds(log.readingStartDate);
        
        // Add to storage
        arrContentLogs.push(log);
    }
    
    // Set back to storage
    ClientData.ContentLogData(arrContentLogs);
};

function SetEndLog(strContentId) {
    var log = new LogEntity();
    var arrContentLogs = ClientData.ContentLogData();
    
    for(var nIndex = 0; nIndex < arrContentLogs.length; nIndex++) {
        if(arrContentLogs[nIndex].contentid == strContentId) {
            // Found content -> set ending date
            var dateEnd = new Date();
            var dateStart = new Date(arrContentLogs[nIndex].readingStartDate);
            arrContentLogs[nIndex].readingEndDate = dateEnd;
            
            // Calculate to seconds
            arrContentLogs[nIndex].readingTime = dateEnd.subtractBySeconds(dateStart);
        }
    }
    ClientData.ContentLogData(arrContentLogs);
};
/*
  register reading log of content
*/
function RegisterLog() {
    var arrContentLogs = ClientData.ContentLogData();
    var isError = false;

    for (var nIndex = 0; nIndex < arrContentLogs.length; nIndex++) {
        var dateEnd = new Date(arrContentLogs[nIndex].readingEndDate);
        var dateStart = new Date(arrContentLogs[nIndex].readingStartDate);

        var params = {
            sid: ClientData.userInfo_sid(),
            contentId: arrContentLogs[nIndex].contentid,
            readingStartDate: dateStart.jpDateTimeString1(),
            readingEndDate: dateEnd.jpDateTimeString1(),
            readingTime: arrContentLogs[nIndex].readingTime,
            deviceTypeId: 4

        };
        avwCmsApiSync(ClientData.userInfo_accountPath(), "contentReadingLog", 'get', params,
                        null,
                        function (xhr, b, c) {
                            if (xhr.status != 0) {
                                isError = true;
                            }
                            else {
                                showSystemError();
                            }
                        });
    };
    if (avwHasError()) {
        return;
    }
    // Clear logs in local
    if (!isError) {
        ClientData.ContentLogData([]);
    }
};


// Disable specified objects
function disable() {

    for (var nIndex = 0; nIndex < arguments.length; nIndex++) {
        if($(arguments[nIndex])) {
            $(arguments[nIndex]).attr('disabled', 'disabled');
        }
    }
};
// Enable specified objects
function enable() {

    for (var nIndex = 0; nIndex < arguments.length; nIndex++) {
        if($(arguments[nIndex])) {
            $(arguments[nIndex]).removeAttr('disabled');
        }
    }
};

function StopWaitProcess() {
    $('#avw-sys-modal-wait').hide();
};
function WaitProcess() {
    if (document.getElementById('avw-sys-modal-wait')) {
        $('#avw-sys-modal-wait').show();
    }
    else {
        var tags = '<div id="avw-sys-modal-wait"><img id="avw-sys-modal-wait-img" src="img/data_loading.gif"/></div>';
        $('body').prepend(tags);
        $('#avw-sys-modal-wait').css({
            'opacity': 0.7,
            'position': 'fixed',
            'top': '0',
            'left': '0',
            'width': $(window).width(),
            'height': $(window).height(),
            'background': '#999',
            'z-index': 100
        });

        $("#avw-sys-modal-wait-img").center();
        
        // resize error page	
        $(window).resize(function () {
            $('#avw-sys-modal-wait').css({
                'width': $(window).width(),
                'height': $(window).height()
            });
            $("#avw-sys-modal-wait-img").center();
        });
    }
};

function unlockLayout() {
    $('#avw-sys-modal').hide();
};
function lockLayout() {
    if (document.getElementById('avw-sys-modal')) {
        $('#avw-sys-modal').show();
    }
    else {
        var tags = '<div id="avw-sys-modal"></div>';
        $('body').prepend(tags);
        $('#avw-sys-modal').css({
            'opacity': 0.6,
            'position': 'fixed',
            'top': '0',
            'left': '0',
            'width': $(window).width(),
            'height': $(window).height(),
            'background': '#000',
            'z-index': 100
        });
        // resize error page	
        $(window).resize(function () {
            $('#avw-sys-modal').css({
                'width': $(window).width(),
                'height': $(window).height()
            });
        });
    }
};
jQuery.fn.center = function () {
    this.css("position", "fixed");

    this.css("top", (($(window).height() - this.height()) / 2) + "px");
    this.css("left", (($(window).width() - this.width()) / 2) + "px");

    return this;
};
jQuery.fn.top = function () {
    this.css("position", "absolute");
    this.css("top", ($(window).scrollTop() + 1) + "px");

    return this;
};
jQuery.fn.right = function () {
    this.css("position", "absolute");
    this.css("left", ($(window).width() - this.width() - 5) + $(window).scrollLeft() + "px");

    return this;
};
jQuery.fn.bottom = function () {
    this.css("position", "absolute");
    this.css("top", ($(window).height() - this.height() - 5) + $(window).scrollTop() + "px");

    return this;
};
// Replace all text
String.prototype.replaceAll = function (oldText, newText) {
    var strResult = this;
    while (strResult.indexOf(oldText) >= 0) {
        strResult = strResult.replace(oldText, newText);
    }
    return strResult;
};

/*
  Get string by number of lines
*/
function getLines(source, number) {
    var result = "";
    var arrSource = new Array();
    arrSource = source.split('\n');
    for (var i = 0; i < number; i++) {
        if (i >= arrSource.length) {
            break;
        }
        //count \n character occured
        if (i < (source.split('\n').length) && i != 0) {
            result += "\n";
        }
        result += arrSource[i];
    }
    return result;
};

/*
Convert yyyy-MM-dd hh:mm:ss.f to Date
*/
function convertToDate(input) {
    var dateResult;
    var nYear = 0;
    var nMonth = 0;
    var nDay = 0;
    var nHour = 0;
    var nMinute = 0;
    var nSecond = 0;
    var strTemp = input;
    var nIndex;

    // Get year
    nIndex = strTemp.indexOf("-");
    nYear = Number(strTemp.substr(0, nIndex));
    // Get month
    strTemp = strTemp.substr(nIndex + 1);
    nIndex = strTemp.indexOf("-");
    nMonth = Number(strTemp.substr(0, nIndex));
    // Get day
    strTemp = strTemp.substr(nIndex + 1);
    nIndex = strTemp.indexOf(" ");
    nDay = Number(strTemp.substr(0, nIndex));
    // Get hour
    strTemp = strTemp.substr(nIndex + 1);
    nIndex = strTemp.indexOf(":");
    nHour = Number(strTemp.substr(0, nIndex));
    // Get minute
    strTemp = strTemp.substr(nIndex + 1);
    nIndex = strTemp.indexOf(":");
    nMinute = Number(strTemp.substr(0, nIndex));
    // Get second
    strTemp = strTemp.substr(nIndex + 1);
    nIndex = strTemp.indexOf(".");
    nSecond = Number(strTemp.substr(0, nIndex));

    dateResult = new Date();
    dateResult.setYear(nYear);
    dateResult.setMonth(nMonth);
    dateResult.setDate(nDay);
    dateResult.setHours(nHour);
    dateResult.setMinutes(nMinute);
    dateResult.setSeconds(nSecond);
    return dateResult;
};

/*
  Escape html
*/
function htmlEncode(value) {
    return jQuery('<div/>').text(value || '').html();
};

/*
  Check if browser is on touch device
*/
function isTouchDevice() {
    var is_touch_device = 'ontouchstart' in document.documentElement;
    if (is_touch_device) {
        return true;
    }

    return false;
};

/*
Get total bytes of jp chars
*/
function getBytes(value) {
    var escapedStr = encodeURI(value);

    if (escapedStr.indexOf("%") != -1) {
        var count = escapedStr.split("%").length - 1;
        if (count == 0) count++;   //perverse case; can't happen with real UTF-8
        var tmp = escapedStr.length - (count * 3);

        count = (count / 3) * 2 + tmp;

    } else {
        count = escapedStr.length
    }
    return count;
};
/*
Truncate by bytes
*/
function truncateByBytes(value, byteCount) {
    var strResult = "";
    for (var nIndex = 0; nIndex < value.length; nIndex++) {
        if (getBytes(strResult + value[nIndex]) <= byteCount) {
            strResult += value[nIndex];
        }
        else {
            break;
        }
    }
    return strResult;
};

function ToogleLogoutNortice() {
    var isShow = false;
    if (ClientData.userOpt_closeOrRefreshAlert() == 1) {    // Checked
        isShow = true;
    }

    if (isShow == false) {
        window.onbeforeunload = null;
    }
    else {
        avwSetLogoutNortice();
    }
};