
//名前空間用のオブジェクトを用意する
var COMMON = {};

// =============================================================================================
// 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",

    // 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
    
};

/*Content Type Keys*/
var ContentTypeKeys = {
    Type_PDF : 'pdf',
    Type_Image : 'image',
    Type_Video : 'movie',
    Type_Music : 'music',
    Type_Others : 'other',
    Type_NoFile : 'none',
    Type_Html: 'html',
    Type_Enquete : 'enquete'
};

/*
    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,
    // Zoom out : "-"
    ZoomOutAlt: 189,
    //Zoom in: "+"
    ZoomInAlt: 187,
    //Zoom out: "-" firefox/opera
    ZoomOutAlt_Firefox: 173,
    //Zoom in : "+" firefox/opera
    ZoominAlt_Firefox: 59
};

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

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

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',
    // No.8: do not use this value: serviceOpt_force_login_periodically
    // Session :事業者オプション(serviceOpt)_一定期間経過後アプリロック:Char(Y：可能, N：不可)
    //serviceOpt_force_login_periodically: 'force_login_periodically',
    // No.8: スクリーンロック
    // Session :事業者オプション(serviceOpt)_スクリーンロック(Web版):Char(Y：可能, N：不可)
    serviceOpt_web_screen_lock: 'web_screen_lock',
    // Session :事業者オプション(serviceOpt)_スクリーンロック待ち時間:Interger
    serviceOpt_web_screen_lock_wait: 'web_screen_lock_wait',
    // Session :事業者オプション(serviceOpt)_GPS使用可:Char(Y：可能, N：不可)
    serviceOpt_usable_readinglog_gps: 'usable_readinglog_gps',
    // Session :事業者オプション(serviceOpt)_詳細ログ使用可:Char(Y：可能, N：不可)
    serviceOpt_usable_readinglog_object: 'usable_readinglog_object',
    // Session :事業者オプション(serviceOpt)_カタログエディション:Char(Y：可能, N：不可)
    serviceOpt_catalog_edition: 'catalog_edition',
    // Session :事業者オプション(serviceOpt)_日比谷カスタム:Char(Y：可能, N：不可)
    serviceOpt_hibiyakadan_catalog: 'hibiyakadan_catalog',
    // Session :事業者オプション(serviceOpt)_DHカスタム:Char(Y：可能, N：不可)
    serviceOpt_daihatsu: 'daihatsu',
    
    // 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 :(contentType):String
    contentInfo_contentType: 'allPageNum',
    // Session :検索条件(searchCond)_検索テキスト:String
    searchCond_searchText: 'searchText',
    // Session :検索条件(searchCond)_検索区分:Interger(1:コンテンツ検索, 2:タグ検索, 3:全文検索)
    searchCond_searchDivision: 'searchCond_searchDivision',
    // Session :検索条件(searchCond)_ソート基準:Interger(１：タイトル名, ２：タイトル名（かな）, ３：公開順)
    searchCond_sortType: 'searchCond_sortType',
    // Session :検索条件(searchCond)_ソート方法:Interger(1：昇順, ２：降順)
    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',
    // Session :通知情報(pushInfo)_新着件数:Interger
    pushInfo_newMsgNumber: 'pushInfo_newMsgNumber',
    // 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(１：タイトル名, ２：タイトル名（かな）, ３：公開順)
    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',
	// Local :ユーザオプション(userOpt)_バックアップデフォルト_マーキング:Interger
    userOpt_bkMakingFlag: 'userOpt_bkMakingFlag',
	// Local :ユーザオプション(userOpt)_バックアップデフォルト_メモ:Interger
    userOpt_bkMemoFlag: 'userOpt_bkMemoFlag',
	// Local :ユーザオプション(userOpt)_バックアップデフォルト_しおり:Interger
    userOpt_bkShioriFlag: 'userOpt_bkShioriFlag',
	// Local :ユーザオプション(userOpt)_ビューのアニメーション種類:Interger
    userOpt_pageTransition: 'userOpt_pageTransition',
	// Local :ユーザオプション(userOpt)_アニメーション時間:Float
    userOpt_pageTransitionPeriod: 'userOpt_pageTransitionPeriod'
	
    /* -------------------------------------------------------------------------------- */
    
};

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

// Entity for Memo
function MemoEntity() {
    this.contentid=  "";
    this.pageNo = 0;
    this.posX = -1;
    this.posY = -1;
    this.Text = "";
	
	//Add for phase2
	this.memoid = "";	
	this.registerDate = new Date();
};

// Entity for marking
function MarkingEntity() {
    this.contentid = "";
    this.pageNo = -1;
    this.content = "";
	
	//Add for phase2
	this.markingid = "";	
	this.registerDate = new Date();
};
// Entity for log
function LogEntity() {
    this.contentid = "";
    this.readingStartDate = new Date();
    this.readingEndDate = null;
    this.readingTime = 0;
    this.deviceTypeId = 4;
    //ページログ配列
    this.pageLogArray = [];
    //詳細ログ配列
    this.objectLogArray = [];
};
// Entity for PageLog
function PageLogEntity(){
    this.contentid = "";
    this.pageNo = 1;
    this.readingStartDate = new Date();
    this.readingEndDate = null;
    this.readingTime = 0;
};
// Entity for ObjectLog
function ObjectLogEntity(){
    this.contentid = "";
    this.actionDate = new Date();
    this.pageNo = 1;
    this.objectId = "";
    this.resourceId = "";
    this.mediaType = "";
    this.actionType = "";
    this.actionValue = "";
    this.actionTime = "0";
    this.locationX = "";
    this.locationY = "";
    this.locationHeight = "";
    this.locationWidth = "";
};

// No.17 Phase 2: do not use this function
// 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,
            // Add for phase 2
            memoid:ClientData.MemoData()[nIndex].memoid,
	        registerDate: ClientData.MemoData()[nIndex].registerDate
        };
        template1.data.push(oneItem2);
    }
    result.push(template1);

    return result;
};
*/
// No.17 Phase 2: do not use this function
/*
  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 for phase2
				obj.memoid = oneType.data[nIndex1].memoid;
				obj.registerDate = oneType.data[nIndex1].registerDate;
				
                // 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 for phase2
				obj.markingid = oneType.data[nIndex1].markingid;
				obj.registerDate = oneType.data[nIndex1].registerDate;
				
                // 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 for phase2
				obj.bookmarkid = oneType.data[nIndex1].bookmarkid;
				
                // Add object to client
                arrBookMark.push(obj);
            }
        }
    }
    ClientData.BookMarkData(arrBookMark);
    ClientData.MarkingData(arrMarking);
    ClientData.MemoData(arrMemo);

    return data;
};
*/

/*
 * Extract memo data from result of API and merge with local memo
 */
function getDataMemo(jsonString) {
    var memoDataFromServer = jsonString.data;

    var arrLocalMemo = ClientData.MemoData();
    
    for (var i = 0; i < memoDataFromServer.length; i++) {
        var objServerMemo = new MemoEntity();
        objServerMemo.contentid = memoDataFromServer[i].contentid;
        objServerMemo.pageNo = memoDataFromServer[i].pageNo;
        objServerMemo.posX = memoDataFromServer[i].posX;
        objServerMemo.posY = memoDataFromServer[i].posY;
        objServerMemo.Text = memoDataFromServer[i].Text;

        //Add for phase2
        objServerMemo.memoid = memoDataFromServer[i].memoid;  // UUID
        objServerMemo.registerDate = memoDataFromServer[i].registerDate;  // UTC+0

        // Searching memoid in local that is matching with memo of server
        var nIndexFoundLocalMemo = -1;
        for (var nIndexLocalMemo = 0; nIndexLocalMemo < arrLocalMemo.length; nIndexLocalMemo++) {
            if (arrLocalMemo[nIndexLocalMemo].memoid == objServerMemo.memoid) {
                nIndexFoundLocalMemo = nIndexLocalMemo;
                break;
            }
        }
        // Found local memo that has memoid = memoid of server memo
        if (nIndexFoundLocalMemo >= 0) {

            // Local date is older than server date -> restore
            if (arrLocalMemo[nIndexFoundLocalMemo].registerDate < objServerMemo.registerDate) {

                arrLocalMemo[nIndexFoundLocalMemo].contentid = objServerMemo.contentid;
                arrLocalMemo[nIndexFoundLocalMemo].pageNo = objServerMemo.pageNo;
                arrLocalMemo[nIndexFoundLocalMemo].posX = objServerMemo.posX;
                arrLocalMemo[nIndexFoundLocalMemo].posY = objServerMemo.posY;
                arrLocalMemo[nIndexFoundLocalMemo].Text = objServerMemo.Text;
                arrLocalMemo[nIndexFoundLocalMemo].registerDate = objServerMemo.registerDate;
            }

        } else {    // Not found: [local memo].memoid = [server memo].memoid
            
            // Merge server memo to local
            arrLocalMemo.push(objServerMemo);

        }

    }
    ClientData.MemoData(arrLocalMemo);
};

/*
 * Extract marking data from result of API and replace to local marking
 */
function getDataMarking(jsonString) {
    var data = jsonString.data;
    var arr = ClientData.MarkingData();
    arr.clear();
    ClientData.MarkingData(arr);

    var arrMarking = [];
    for (var nIndex1 = 0; nIndex1 < data.length; nIndex1++) {
        var obj = new MarkingEntity();
        obj.contentid = data[nIndex1].contentid;
        obj.pageNo = data[nIndex1].pageNo;
        obj.content = data[nIndex1].content;

        //Add for phase2
        obj.markingid = data[nIndex1].markingid;
        obj.registerDate = data[nIndex1].registerDate;

        // Add object to client
        arrMarking.push(obj);
    }
    ClientData.MarkingData(arrMarking);
};

/*
 * Extract bookmark data from result of API and replace to local bookmark
 */
function getDataBookmark(jsonString) {
    var data = jsonString.data;
    var arr = ClientData.BookMarkData();
    arr.clear();
    ClientData.BookMarkData(arr);

    var arrBookmark = [];
    for (var nIndex1 = 0; nIndex1 < data.length; nIndex1++) {
        var obj = new BookMarkEntity();
        obj.contentid = data[nIndex1].contentid;
        obj.pageNo = data[nIndex1].pageNo;
        obj.contentTitle = data[nIndex1].contentTitle;
        obj.contentTitleKana = data[nIndex1].contentTitleKana;
        obj.registerDate = data[nIndex1].registerDate;

        //Add for phase2
        obj.bookmarkid = data[nIndex1].bookmarkid;

        // Add object to client
        arrBookmark.push(obj);
    }
    ClientData.BookMarkData(arrBookmark);
};

/*
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(１：タイトル名, ２：タイトル名（かな）, ３：公開順)
    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);
        }
    },
	
	// Local :ユーザオプション(userOpt)_バックアップデフォルト_マーキング:Interger
    userOpt_bkMakingFlag: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.userOpt_bkMakingFlag, undefined);
        }
        else {
            return operateData(arguments, Keys.userOpt_bkMakingFlag, undefined);
        }
    },
	
	// Local :ユーザオプション(userOpt)_バックアップデフォルト_メモ:Interger
    userOpt_bkMemoFlag: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.userOpt_bkMemoFlag, undefined);
        }
        else {
            return operateData(arguments, Keys.userOpt_bkMemoFlag, undefined);
        }
    },
	
	// Local :ユーザオプション(userOpt)_バックアップデフォルト_しおり:Interger
    userOpt_bkShioriFlag: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.userOpt_bkShioriFlag, undefined);
        }
        else {
            return operateData(arguments, Keys.userOpt_bkShioriFlag, undefined);
        }
    },
	
	// Local :ユーザオプション(userOpt)_ビューのアニメーション種類:Interger
    userOpt_pageTransition: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.userOpt_pageTransition, undefined);
        }
        else {
            return operateData(arguments, Keys.userOpt_pageTransition, undefined);
        }
    },
	
	// Local :ユーザオプション(userOpt)_アニメーション時間:Float
    userOpt_pageTransitionPeriod: function (data) {
        if (arguments.length > 0) {
            operateData(arguments, Keys.userOpt_pageTransitionPeriod, undefined);
        }
        else {
            return operateData(arguments, Keys.userOpt_pageTransitionPeriod, 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);
        }
    },
    // No.8: do not use this value: serviceOpt_force_login_periodically
    // 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 :事業者オプション(serviceOpt)_GPS使用可:Char(Y：可能, N：不可)
    serviceOpt_usable_readinglog_gps: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.serviceOpt_usable_readinglog_gps, data);
        } else {
            return SessionStorageUtils.get(Keys.serviceOpt_usable_readinglog_gps);
        }
    },
    // Session :事業者オプション(serviceOpt)_詳細ログ使用可:Char(Y：可能, N：不可)
    serviceOpt_usable_readinglog_object: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.serviceOpt_usable_readinglog_object, data);
        } else {
            return SessionStorageUtils.get(Keys.serviceOpt_usable_readinglog_object);
        }
    },
    // Session :事業者オプション(serviceOpt)_カタログエディション:Char(Y：可能, N：不可)
    serviceOpt_catalog_edition: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.serviceOpt_catalog_edition, data);
        } else {
            return SessionStorageUtils.get(Keys.serviceOpt_catalog_edition);
        }
    },
    // Session :事業者オプション(serviceOpt)_日比谷対応:Char(Y：可能, N：不可)
    serviceOpt_hibiyakadan_catalog: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.serviceOpt_hibiyakadan_catalog, data);
        } else {
            return SessionStorageUtils.get(Keys.serviceOpt_hibiyakadan_catalog);
        }
    },
    // Session :事業者オプション(serviceOpt)_DH対応:Char(Y：可能, N：不可)
    serviceOpt_daihatsu: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.serviceOpt_daihatsu, data);
        } else {
            return SessionStorageUtils.get(Keys.serviceOpt_daihatsu);
        }
    },

    // 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 :(contentType):String
    contentInfo_contentType: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.contentInfo_contentType, data);
        } else {
            return SessionStorageUtils.get(Keys.contentInfo_contentType);
        }
    },
    // 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(１：タイトル名, ２：タイトル名（かな）, ３：公開順)
    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：昇順, ２：降順)
    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 :通知情報(pushInfo)_新着件数:Interger
    pushInfo_newMsgNumber: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.pushInfo_newMsgNumber, data);
        } else {
            return SessionStorageUtils.get(Keys.pushInfo_newMsgNumber);
        }
    },

    // 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);
        }
    },
    // Session :事業者オプション(serviceOpt)_スクリーンロック(Web版):Char(Y：可能, N：不可)
    serviceOpt_web_screen_lock: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.serviceOpt_web_screen_lock, data);
        } else {
            return SessionStorageUtils.get(Keys.serviceOpt_web_screen_lock);
        }
    },
	// Session :事業者オプション(serviceOpt)_スクリーンロック待ち時間:Interger
    serviceOpt_web_screen_lock_wait: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(Keys.serviceOpt_web_screen_lock_wait, data);
        } else {
            return SessionStorageUtils.get(Keys.serviceOpt_web_screen_lock_wait);
        }
    }
};

// -------------------------------------------------
// 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;

};
/*
yyyy/MM/dd
*/
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;

};
/*
HH:mm:ss
*/
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;

};
/*
HH:mm
*/
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;

};
/*
yyyyMMddHHmmss
*/
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);
    },
    // Password
    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);
    },
    // Alphabet + Nunber + Symbol
    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);
    },
    // Get the total of types in array
    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
    },
    // Special character: *
    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);
    }
};

// Get format based64 string to show inline
function getBase64Image(imgSource) {
    return imgSource.replace(/^data:image\/(png|jpg);base64,/, "");
};

// get time wait lockscreen
function getTimeWaitLockScreen() {
    var timeWaitLockScreen = -1;
    if (ClientData.serviceOpt_web_screen_lock() == "Y") 
    {
        var sysSettings = avwSysSetting();
        if (isNaN(ClientData.serviceOpt_web_screen_lock_wait())) {
            timeWaitLockScreen = sysSettings.screenlockTimeDefault * 60000;
        }
        else 
        {
            var temp = ClientData.serviceOpt_web_screen_lock_wait();
            timeWaitLockScreen = temp * 60000; // time unit is minute
            if (timeWaitLockScreen < 0 || temp % 1 != 0) {
                timeWaitLockScreen = sysSettings.screenlockTimeDefault * 60000;
            }
            else if (timeWaitLockScreen == 0) { // no lockscreen
                timeWaitLockScreen = -1;
            }
        }
    }    
    return timeWaitLockScreen;
};

// Do locking screen after idle time
function LockScreen() {    
    if (avwUserSession()) {

        // no lockscreen for user anonymous
        if (isAnonymousLogin()) {
            return;
        }
        var timeWaitLockScreen = getTimeWaitLockScreen();        
        if (timeWaitLockScreen > 0) {
            //var message = i18nText("sysInfoScrLock01");
            screenLock({                
                timeout: timeWaitLockScreen,
                html: '<img src="img/1222.png" alt="Screen Lock" /><br />', //+ message,
                unlockFunc: unlockFunction,
                errorMessage: i18nText('msgLoginErrWrong')
            });
        }

        //        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')
        //            });
        //        }

    }
};


// The function will be called at the time: loading
$(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);
        }

        // Set default value for options backup: marking -> checked
        if (ClientData.userOpt_bkMakingFlag() == null || ClientData.userOpt_bkMakingFlag() == undefined) {
            ClientData.userOpt_bkMakingFlag(1);
        }
        // Set default value for options backup: memo -> checked
        if (ClientData.userOpt_bkMemoFlag() == null || ClientData.userOpt_bkMemoFlag() == undefined) {
            ClientData.userOpt_bkMemoFlag(1);
        }
        // Set default value for options backup: bookmark -> checked
        if (ClientData.userOpt_bkShioriFlag() == null || ClientData.userOpt_bkShioriFlag() == undefined) {
            ClientData.userOpt_bkShioriFlag(1);
        }

        // Set default value for logoutMode (backup auto and logout)
        if (ClientData.userOpt_logoutMode() == null || ClientData.userOpt_logoutMode() == undefined) {
            ClientData.userOpt_logoutMode(0);
        }

        // set default page transition No.4

        if (ClientData.userOpt_pageTransition() == null || ClientData.userOpt_logoutMode() == undefined) {
            ClientData.userOpt_pageTransition(0);
        }
        if (ClientData.userOpt_pageTransitionPeriod() == null || ClientData.userOpt_pageTransitionPeriod() == undefined) {
            ClientData.userOpt_pageTransitionPeriod(1);
        }

    }
});

// Unlock the locked screen by inputing password on screen to check authentication
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();

	                // update status wait lockscreen
	                var serviceOptionList = data.serviceOptionList;
	                $.each(serviceOptionList, function (i, option) {

	                    if (option.serviceName == 'web_screen_lock') {
	                        ClientData.serviceOpt_web_screen_lock(option.value);
	                    }
	                    else if (option.serviceName == 'web_screen_lock_wait') {
	                        ClientData.serviceOpt_web_screen_lock_wait(option.value);	                        
	                    }
	                });

	            }
	        },
	        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, 'newTimeout': getTimeWaitLockScreen() };
};



/*
  Set starting log for reading content
*/
function SetStartLog(strContentId) {

	//abe pageLogもセット

    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);
        
        //PageLog 1ページ目セット（１レコードは必須）
        var pageLog = new PageLogEntity();
        pageLog.contentid = strContentId;
        log.pageLogArray.push(pageLog);
        
        // Add to storage
        arrContentLogs.push(log);
    }
    
    // Set back to storage
    ClientData.ContentLogData(arrContentLogs);
};

// Set ending log for reading content
function SetEndLog(strContentId) {

	//abe pageLogもセット

    //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);
};

// １ページ分のページ閲覧ログを作成
function SetPageLog( strContentId, strPageNo ){
	
	var arrContentLogs = ClientData.ContentLogData();
	
	for(var nIndex = 0; nIndex < arrContentLogs.length; nIndex++) {
		if(arrContentLogs[nIndex].contentid == strContentId) {
			
			//PageLog追加
			var pageLog = new PageLogEntity();
			pageLog.contentid = strContentId;
			pageLog.pageNo = strPageNo + 1; //0始まりのページ番号
			arrContentLogs[nIndex].pageLogArray.push(pageLog);
			
		}
	}
	ClientData.ContentLogData(arrContentLogs);

}

// １アクションのオブジェクトログを作成
function SetObjectLog( strContentId, objectLog ){
	
	var arrContentLogs = ClientData.ContentLogData();
	
	for(var nIndex = 0; nIndex < arrContentLogs.length; nIndex++) {
		if(arrContentLogs[nIndex].contentid == strContentId) {
			
			//ObjectLog追加
			arrContentLogs[nIndex].objectLogArray.push(objectLog);
			
		}
	}
	ClientData.ContentLogData(arrContentLogs);

}

// 前回の１アクションのオブジェクトログの利用時間を設定
function SetObjectLogActionTime( strContentId, objectId, actionTime ){
	
	var arrContentLogs = ClientData.ContentLogData();
	
	for(var nIndex = 0; nIndex < arrContentLogs.length; nIndex++) {
		if(arrContentLogs[nIndex].contentid == strContentId) {
			if( arrContentLogs[nIndex].objectLogArray.length > 0 ){
				if( arrContentLogs[nIndex].objectLogArray[ arrContentLogs[nIndex].objectLogArray.length - 1].objectId == objectId ){
					arrContentLogs[nIndex].objectLogArray[ arrContentLogs[nIndex].objectLogArray.length - 1].actionTime = actionTime;
				}
			}
		}
	}
	ClientData.ContentLogData(arrContentLogs);

}


/*
  Register reading log of content to server by calling api
*/
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);

		//ページログJSONデータの作成
		var pageLogJson = "";
		var objectLogJson = "";
		if( ClientData.serviceOpt_usable_readinglog_object() == 'Y' ){
			var pageLogArray = arrContentLogs[nIndex].pageLogArray;
			//詳細ログオプションが有効ならページ閲覧ログデータ作成
			if( pageLogArray != null && pageLogArray.length > 0 ){
		
				var lines = [];
				//終了時間と閲覧時間の設定
				var pageLogStart;
				var pageLogEnd;
				//２レコード目からチェック
				for (var nIndex2 = 1; nIndex2 < pageLogArray.length; nIndex2++) {
					//一つ前のログの終了日時がnullなら次のレコードの開始日時をセット
					if( pageLogArray[nIndex2 -1].readingEndDate == null ){
						pageLogArray[nIndex2 -1].readingEndDate = pageLogArray[nIndex2].readingStartDate;
					}
					pageLogStart = new Date(pageLogArray[nIndex2 -1].readingStartDate);
					pageLogEnd = new Date(pageLogArray[nIndex2 -1].readingEndDate);
					//時間差から閲覧秒セット
					pageLogArray[nIndex2 -1].readingTime = pageLogEnd.subtractBySeconds(pageLogStart);
				
				}
				//最終レコードの処理
				if( pageLogArray[pageLogArray.length - 1].readingEndDate == null ){
					pageLogArray[pageLogArray.length - 1].readingEndDate = new Date();
				}
				pageLogStart = new Date(pageLogArray[pageLogArray.length - 1].readingStartDate);
				pageLogEnd = new Date(pageLogArray[pageLogArray.length - 1].readingEndDate);
				//時間差から閲覧秒セット
				pageLogArray[pageLogArray.length -1].readingTime = pageLogEnd.subtractBySeconds(pageLogStart);
			
				//JSONデータ作成
				for (var nIndex2 = 0; nIndex2 < pageLogArray.length; nIndex2++) {
					pageLogStart = new Date(pageLogArray[nIndex2].readingStartDate);
					pageLogEnd = new Date(pageLogArray[nIndex2].readingEndDate);
					//3秒以上なら記録する
					if( pageLogArray[nIndex2].readingTime > 2 ){
						var line = [];
						line.push(pageLogArray[nIndex2].pageNo);
						line.push(pageLogStart.jpDateTimeString1());
						line.push(pageLogEnd.jpDateTimeString1());
						line.push(pageLogArray[nIndex2].readingTime);
						lines.push(line);
						//alert("PageLog Line:" + JSON.stringify( line ) );
					}
				}
				//alert("PageLog Lines:" + JSON.stringify( lines ) );
				
				if( lines.length > 0 ){
					pageLogJson = "{ header:[\"pageNo\",\"readingStartDate\",\"readingEndDate\",\"readingTime\"],lines:";
					pageLogJson = pageLogJson + JSON.stringify( lines );
					pageLogJson = pageLogJson + "}";
					//alert("JSON:" + pageLogJson);
				}
			}
			
			var objectLogArray = arrContentLogs[nIndex].objectLogArray;
			//詳細ログオプションが有効ならページ閲覧ログデータ作成
			if( objectLogArray != null && objectLogArray.length > 0 ){
			
				var lines = [];
				var actionDate;
			
				//JSONデータ作成
				for (var nIndex2 = 0; nIndex2 < objectLogArray.length; nIndex2++) {
					actionDate = new Date(objectLogArray[nIndex2].actionDate);
					var line = [];
					
					if( objectLogArray[nIndex2].objectId ){
						line.push(actionDate.jpDateTimeString1());
						line.push(objectLogArray[nIndex2].pageNo);
						line.push(objectLogArray[nIndex2].objectId);
						line.push(objectLogArray[nIndex2].resourceId);
						line.push(objectLogArray[nIndex2].mediaType);
						line.push(objectLogArray[nIndex2].actionType);
						line.push(objectLogArray[nIndex2].actionValue);
						line.push(objectLogArray[nIndex2].actionTime);
						line.push(objectLogArray[nIndex2].locationX);
						line.push(objectLogArray[nIndex2].locationY);
						line.push(objectLogArray[nIndex2].locationHeight);
						line.push(objectLogArray[nIndex2].locationWidth);
						lines.push(line);
						//alert("ObjectLog Line:" + JSON.stringify( line ) );
					}
				}
				//alert("ObjectLog Lines:" + JSON.stringify( lines ) );
			
				if( lines.length > 0 ){
					objectLogJson = "{ header:[\"actionDate\",\"pageNo\",\"objectId\",\"resourceId\",\"mediaType\",\"actionType\",\"actionValue\",\"actionTime\",\"locationX\",\"locationY\",\"locationHeight\",\"locationWidth\"],";
					objectLogJson = objectLogJson + "lines:";
					objectLogJson = objectLogJson + JSON.stringify( lines );
					objectLogJson = objectLogJson + "}";
					//alert("JSON:" + objectLogJson);
				}
			
			}
			
		}

        var params = {
            sid: ClientData.userInfo_sid(),
            contentId: arrContentLogs[nIndex].contentid,
            readingStartDate: dateStart.jpDateTimeString1(),
            readingEndDate: dateEnd.jpDateTimeString1(),
            readingTime: arrContentLogs[nIndex].readingTime,
            deviceTypeId: 4,
            pageLog: pageLogJson,
            objectLog: objectLogJson
        };
        //API送信結果判定
        arrContentLogs[nIndex].sendResult = false;
        avwCmsApiSync(ClientData.userInfo_accountPath(), "contentReadingLog", 'post', params,
                        function (data) {
                           if (data.result == 'success') {
                               //成功したログは削除
                               arrContentLogs[nIndex].sendResult = true;
                           }
                        },
                        function (xhr, b, c) {
                            if (xhr.status != 0) {
                                isError = true;
                                var xhrData = JSON.parse(xhr.responseText);
                                if ( xhrData && xhrData.httpStatus == 500 ) {
                                   //なんらか不正なデータなので送信成功にして捨てる
                                   arrContentLogs[nIndex].sendResult = true;
                                }
                            }
                            else {
                                showSystemError();
                            }
                        });
    };
    if (avwHasError()) {
        return;
    }
    // Clear logs in local
    if (!isError) {
        ClientData.ContentLogData([]);
    } else {
        //送信成功したログは削除
        var arrTarget = [];
        for (var nIndex = 0; nIndex < arrContentLogs.length; nIndex++) {
            if( arrContentLogs[nIndex].sendResult == false ){
                arrTarget.push(arrContentLogs[nIndex]);
            }
        }
        ClientData.ContentLogData(arrTarget);
    }
};


// 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');
        }
    }
};

// Stop waiting screen
function StopWaitProcess() {
    $('#avw-sys-modal-wait').hide();
};

// Show waiting screen
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();
        });
    }
};

// Hide the locking layout
function unlockLayout() {
    $('#avw-sys-modal').hide();
};

// Show the locking layout
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.7,
            'position': 'fixed',
            'top': '0',
            'left': '0',
            'width': $(window).width(),
            'height': $(window).height(),
            'background': '#999',
            'z-index': 100
        });
        // resize error page	
        $(window).resize(function () {
            $('#avw-sys-modal').css({
                'width': $(window).width(),
                'height': $(window).height()
            });
        });
    }
};

// Function to set position of object to center
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;
};
// Function to set position of object to top
jQuery.fn.top = function () {
    this.css("position", "absolute");
    this.css("top", ($(window).scrollTop() + 1) + "px");

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

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

    return this;
};
// Replace all text by new 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-1);
    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() {
    if (isAnonymousLogin()) {
        return;
    }
    var isShow = false;
    if (ClientData.userOpt_closeOrRefreshAlert() == 1) {    // Checked
        isShow = true;
    }

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

/*
Get UTC Time ( GMT + 0 )
*/
function getUtcTime() {
    var curTime = new Date();

    /* get time zone */
    var timeZone = curTime.getTimezoneOffset();

    var resultTime = new Date(curTime.getTime() + (timeZone * 60000));

    return resultTime;

};

// Convert UTC time to Date object
function convertUtcToDate(utcTime) {
    return new Date(Number(utcTime));
};

// Get UUID version 4
function getUUID() {
    return uuid.v4();
};

/*
Check is anonymous user login
*/
function isAnonymousLogin() {
    return avwSysSetting().anonymousLoginFlg;
}

/* Check if current browser is IE9 */
function isIE9() {
    var ua = window.navigator.userAgent.toLowerCase();
    
    if (/msie 9.0/.test(ua)) {
        return true;
    }
    return false;
};

/* Check if current browser is IE10 */
function isIE10() {
    var ua = window.navigator.userAgent.toLowerCase();
    if (/msie 10.0/.test(ua)) {
        return true;
    }
    /*
    if (window.navigator.msPointerEnabled) {
        return true;
    } else {
        var ua = window.navigator.userAgent.toLowerCase();
        if (/msie 10.0/.test(ua)) {
            return true;
        }
    }
    */
    return false;
};

//Web Logout Event
COMMON.webLogoutEvent = function(){

    var isExisted = false;

    var params = {
        sid: ClientData.userInfo_sid()
    };

    avwCmsApiSync(ClientData.userInfo_accountPath(), "webLogout", "GET", params,
                    function (data) {
                        isExisted = true;
                        SessionStorageUtils.clear();
                        avwUserSetting().remove(Keys.userInfo_sid);
                        // Move to login screen
                        //window.location = ScreenIds.Login;
                        avwScreenMove(ScreenIds.Login);
                    },
                    function (xmlHttpRequest, txtStatus, errorThrown) {
                        if (xmlHttpRequest.status == 403) {
                            isExisted = false;
                        }
                        else {
                            // Show system error
                            isExisted = true;
                        }
                    });
                    
    return isExisted;
};

