text:
var currentTablename = "";

// Records / page
var recordsPerPage = 100;

// Start record
var startRecord = 0;

// Sort information
var globalSortOrder = '';
var globalSortTarget = '';

function initClientMessage() {
    //
    // User management
    //
    addClientMessage('USERMGMTS', {'en':'User Management', 'ja':'ユーザー管理'});
    addClientMessage('USER_CHG_PW', {'en':'Change Password', 'ja':'パスワードの変更'});
    addClientMessage('OPE_LOG', {'en':'Operation log', 'ja':'操作ログ'});

    //
    // ODBC configuration
    //
    addClientMessage('ODBC_CONNECTION', {'en':'ODBC Connections', 'ja':'ODBC接続'});
    addClientMessage('ODBC_CONNECTIONS', {'en':'ODBC Conn', 'ja':'ODBC接続'});
    addClientMessage('ODBC_CONNSTR_GUIDE', {
        'en':'Configure ODBC connection.
Select the connection target DBMS and specify the ODBC connection string.
As this is 64-bit application software, this string should be specified for the use of a 64-bit ODBC driver. As a prerequisite, a 64-bit ODBC driver needs to be installed on the operating system where CmdFreak is installed.
',
        'ja':'ODBC接続の設定を行います。
接続対象のDBMSを選択し,ODBCの接続文字列を指定してください。
本ソフトウェアは64ビットアプリケーションのため,ODBC接続文字列には,64ビット版ODBCドライバを使用するように指定を行ってください。CmdFreakをインストールしたオペレーティングシステムには,あらかじめ64ビット版ODBCドライバがインストールされている必要があります。
'
    });
    addClientMessage('ODBC_SELECTION', {'en':'Select DBMS : ', 'ja':'DBMSの選択 : '});
    addClientMessage('ODBC_CONFAILURE', {
        'en':'DBMS connection failed.
This may be caused by one of the following issues:
- The DBMS is not working properly.
- No ODBC driver is installed.
- The ODBC connection string is invalid.
- There are issues with the DBMS on the network.
',
        'ja':'DBMSとの接続に失敗しました。
次の要因が考えられます。
- DBMSが適切に起動していない。
- ODBCドライバがインストールされていない。
- ODBCの接続文字列が不正。
- DBMSとの接続経路に何らかの問題がある。
'
    });

    //
    // Service information
    //
    addClientMessage('SVCINFO', {'en':'Information', 'ja':'情報'});
    addClientMessage('SVCINFOS', {'en':'Info', 'ja':'情報'});
    addClientMessage('SVCINFO_TRACELOG', {
        'en':'The trace log is displayed below.
Times are as per the time zone of the web server\'s location.',
        'ja':'以下にトレースログが表示されます。
表示される時刻はWebサーバーが配置された地域の時刻となります。'
    });
    addClientMessage('SVCINFO_LOGTIME', {'en':'Logging time', 'ja':'ログ出力時刻'});
    addClientMessage('SVCINFO_LOGMSG', {'en':'Message', 'ja':'メッセージ'});

    //
    // Filtering dialog
    //
    addClientMessage('FILTERING', {'en':'Filtering', 'ja':'フィルタリング'});
    addClientMessage('FILTERING_NO_TABLE', {'en':'The operation cannot be performed because the target table for filtering does not exist.', 'ja':'フィルタリングの対象となるテーブルが存在しないため操作を継続できません。'});
    addClientMessage('FILTERING_DESC', {
        'en':'Filter settings can be specified here.
Records are filtered according to the specified criteria.
Up to five filter items can be specified.
All items are treated as logical AND operators.',
        'ja':'ここではフィルタリングの設定を行うことができます。
指定した条件でレコード情報がフィルタリングされます。
フィルタリング項目は最大5件を指定することができます。
各フィルタリング項目間は論理積[AND]で結合されます。'
    });
    addClientMessage('FILTERING_UNSPECIFY', {'en':'Unspecified', 'ja':'未指定'});
    addClientMessage('FILTERING_INVALID', {
        'en':'The filter conditions set do not match the current table schema.
Do you want to clear the filter conditions?',
        'ja':'設定されているフィルタリング条件は現在のテーブルのスキーマと一致していません。
フィルタリング条件をクリアしてよいですか?'
    });
    addClientMessage('FILTERING_ON', {'en':'Filtering On', 'ja':'フィルタリング有効'});

    //
    // Table information
    //
    addClientMessage('TABLEINFO', {'en':'Table Information', 'ja':'テーブル情報'});
    addClientMessage('TABLEINFO_SHOWN', {'en':'Detailed information on the specified table is shown below.', 'ja':'以下に指定されたテーブルの詳細情報を表示します。'});
    addClientMessage('TABLEINFO_TARGET', {'en':'The target table: ', 'ja':'対象テーブル: '});
    addClientMessage('TABLEINFO_NOTEXIST', {'en':'The operation cannot be performed because the target table for display does not exist.', 'ja':'表示対象のテーブルが存在しないため操作を継続できません。'});
    addClientMessage('TABLEINFO_COLUMNNAME', {'en':'Column name', 'ja':'カラム名'});
    addClientMessage('TABLEINFO_COLUMNTYPE', {'en':'Column type', 'ja':'種別'});
    addClientMessage('TABLEINFO_ISNULL', {'en':'Is nullable', 'ja':'NULL指定'});

    //
    // View Setting dialog
    //
    addClientMessage('VIEWSETTING', {'en':'View Setting', 'ja':'ビュー設定'});
    addClientMessage('VIEWSETTING_RECORDS_PER_PAGE', {'en':'Records / Page:', 'ja':'レコード数 / ページ:'});
    addClientMessage('VIEWSETTING_PAGE', {'en':'Page:', 'ja':'ページ:'});
    addClientMessage('VIEWSETTING_INVALID_VALUE', {'en':'An invalid value is presented.', 'ja':'不正な値が指定されました。'});
    addClientMessage('VIEWSETTING_INVALID_RANGE_ERROR', {'en':'The value specified is out of range.', 'ja':'指定された値は許容範囲外です。'});
    addClientMessage('VIEWSETTING_NO_TABLE', {'en':'The operation cannot be performed because the target table for view setting does not exist.', 'ja':'ビュー設定の対象となるテーブルが存在しないため操作を継続できません。'});

    //
    // Errors, Common
    //
    addClientMessage('WELCOME_MSG', {'en':'Welcome to the CmdFreak page!', 'ja':'ようこそ,CmdFreakのページです!'});
    addClientMessage('WELCOME_CONFIGODBC', {
        'en':'To refer to data in a database using this software, the ODBC connection needs to be configured first.',
        'ja':'本ソフトウェアを使用してデータベースのデータを参照するには,まずはじめにODBC接続の設定を行ってください。'
    });
    addClientMessage('CONNERR', {
        'en':'Connection with REST API service failed. This may be caused by one of the following issues:
(1) REST API service cannot be started.
(2) REST API service is not registered as a firewall exception.
(3) The definition file [nginx.conf and/or sample.conf] for the host name and port number in the network connectivity settings is invalid.
(4) A timeout has occurred when waiting for data from REST API server.
',
        'ja':'REST APIサービスとの通信が失敗しました。次の要因が考えられます。
(1) REST APIサービスが開始されていない。
(2) REST APIサービスがファイアウォールに例外登録されていない。
(3) 接続先ホスト名およびポート番号の定義ファイル [nginx.conf , sample.conf] が不正。
(4) REST APIサーバからのデータ取得中にタイムアウトが発生した。
'
    });
    addClientMessage('DLG_CLOSE', {'en':'Close', 'ja':'閉じる'});
    addClientMessage('DLG_OK', {'en':'OK', 'ja':'OK'});
    addClientMessage('DLG_CANCEL', {'en':'Cancel', 'ja':'キャンセル'});
    addClientMessage('SERVER_ERROR', {'en':'An error occurred at server side.', 'ja':'サーバ側でエラーが発生しました。'});
    addClientMessage('COMADD', {'en':'Add', 'ja':'追加'});
    addClientMessage('COMUPDATE', {'en':'Update', 'ja':'更新'});
    addClientMessage('COMDELETE', {'en':'Delete', 'ja':'削除'});
    addClientMessage('NOCOLUMNS', {'en':'No columns', 'ja':'カラムが存在しません'});
    addClientMessage('NORECORDS', {'en':'No records', 'ja':'レコードが存在しません'});
}

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

function transDisplayOdbcConfig() {
    var contents = [{ method: 'GET', url: '/api/odbcinfo/', request: { 'query': 'default' }, keystring: 'API_GET_ODBCINFO_DEFAULT' },
                    { method: 'GET', url: '/api/odbcinfo/', request: { 'query': 'configured' }, keystring: 'API_GET_ODBCINFO_CONFIGURED' }
    ];
    MultiApiCall(contents, displayOdbcConfig);
}

function displayOdbcConfig() {
    var odbcConfig = $('
');
    showInputModal(getClientMessage('ODBC_CONNECTION'), odbcConfig);

    if (statusCode['API_GET_ODBCINFO_DEFAULT'] == 200 && statusCode['API_GET_ODBCINFO_CONFIGURED'] == 200) {
        // Nothing to do
    } else if (statusCode['API_GET_ODBCINFO_DEFAULT'] == 400 || statusCode['API_GET_ODBCINFO_CONFIGURED'] == 400) {
        if (statusCode['API_GET_ODBCINFO_DEFAULT'] == 400) {
            displayAlertDanger('#odbcconfig', getSvrMsg(responseData['API_GET_ODBCINFO_DEFAULT']));
        }
        if (statusCode['API_GET_ODBCINFO_CONFIGURED'] == 400) {
            displayAlertDanger('#odbcconfig', getSvrMsg(responseData['API_GET_ODBCINFO_CONFIGURED']));
        }
        odbcConfig.append('
<button type="button" id="closeOdbcConfig" class="btn btn-dark" onclick="closeInputModal()">' + getClientMessage('DLG_CLOSE') + '</button>
');
        return;
    } else if (statusCode['API_GET_ODBCINFO_DEFAULT'] == 401) {
        displayAlertDanger('#odbcconfig', getSvrMsg(responseData['API_GET_ODBCINFO_CONFIGURED']));
        odbcConfig.append('
<button type="button" id="closeOdbcConfig" class="btn btn-dark" onclick="closeInputModal()">' + getClientMessage('DLG_CLOSE') + '</button>
');
        return;
    } else {
        displayAlertDanger('#odbcconfig', getClientMessage('CONNERR'));
        odbcConfig.append('
<button type="button" id="closeOdbcConfig" class="btn btn-dark" onclick="closeInputModal()">' + getClientMessage('DLG_CLOSE') + '</button>
');
        return;
    }

    var odbcInfos = getArray(responseData['API_GET_ODBCINFO_DEFAULT'].Data.OdbcInfo);
    var odbcInfoConfigured = responseData['API_GET_ODBCINFO_CONFIGURED'].Data.OdbcInfo;

    odbcConfig.append(getClientMessage('ODBC_CONNSTR_GUIDE'));

    var configuredOdbc = '';
    if (odbcInfoConfigured.DbType === 'MariaDB') {
        configuredOdbc = 'MariaDB';
    } else if (odbcInfoConfigured.DbType === 'PostgreSQL' || odbcInfoConfigured.DbType === 'Init') {
        configuredOdbc = 'PostgreSQL';
    } else if (odbcInfoConfigured.DbType === 'MySQL') {
        configuredOdbc = 'MySQL';
    }
    var btnGrp = $('
');
    btnGrp.append('<button type="button" class="btn btn-dark dropdown-toggle" data-toggle="dropdown" aria-expanded="false">' + configuredOdbc + '</button>');
    var ddMenu = $('
');
    ddMenu.append('
MariaDB
');
    ddMenu.append('
PostgreSQL
');
    ddMenu.append('
MySQL
');
    btnGrp.append(ddMenu);
    odbcConfig.append('
');
    odbcConfig.append(getClientMessage('ODBC_SELECTION'));
    odbcConfig.append(btnGrp);
    odbcConfig.append('
');

    odbcConfig.append('<textarea class="form-control" id="connstr" rows="3" style="margin-top: 0px; margin-bottom: 0px; height: 100px;"></textarea>');
    if (odbcInfoConfigured.DbType === 'Init') {
        $('#connstr').val(odbcInfos[1].ConnStr);
    } else {
        var csReplaced = odbcInfoConfigured.ConnStr;
        csReplaced = csReplaced.replace(/&/g, "&");
        csReplaced = csReplaced.replace(/</g, "<");
        csReplaced = csReplaced.replace(/>/g, ">");
        csReplaced = csReplaced.replace(/\"/g, """);
        $('#connstr').append(csReplaced);
    }

    odbcConfig.append('
');
    odbcConfig.append('<button type="button" id="okOdbcConfig" class="btn btn-dark" onclick="closeDbmsConfig()">' + getClientMessage('DLG_OK') + '</button> ');
    odbcConfig.append('<button type="button" id="cancelOdbcConfig" class="btn btn-dark" onclick="closeInputModal()">' + getClientMessage('DLG_CANCEL') + '</button> ');
    odbcConfig.append('
');
}

function eventDbmsSelected(dbmsindex) {
    var odbcInfos = getArray(responseData['API_GET_ODBCINFO_DEFAULT'].Data.OdbcInfo);
    $('#dbmsselector').text(odbcInfos[dbmsindex].DbType);
    $('#connstr').val(odbcInfos[dbmsindex].ConnStr);
}

function closeDbmsConfig() {
    var selectedDbmsName = $('#dbmsselector').text();
    var tmpstr = $('#connstr').val().replace(/[\n\r]/g, '');
    var reqDatDf = { 'DbType': selectedDbmsName, 'ConnStr': tmpstr };
    apiCall('POST', '/api/odbcinfo/', reqDatDf, 'API_POST_ODBCINFO', refreshInfo);
    closeInputModal();
}

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

function transDisplayInformation() {
    var contents = [{ method: 'GET', url: '/api/logs/', request: null, keystring: 'API_GET_LOGS' },
                    { method: 'GET', url: '/api/system/', request: null, keystring: 'API_GET_SYSTEM' }
    ];
    MultiApiCall(contents, displayInformation);
}

function displayInformation() {
    var svcInfo = $('
');
    showInputModal(getClientMessage('SVCINFO'), svcInfo);
    var buildTime = "";
    var startTime = "";
    var productName = "";
    var version = "";
    if (statusCode['API_GET_SYSTEM'] == 200) {
        buildTime = responseData['API_GET_SYSTEM'].Data.BuildTime;
        startTime = responseData['API_GET_SYSTEM'].Data.StartTime;
        productName = responseData['API_GET_SYSTEM'].Data.ProductName;
        version = responseData['API_GET_SYSTEM'].Data.Version;
    } else if (statusCode['API_GET_SYSTEM'] == 401) {
        displayAlertDanger('#svcinfo', getSvrMsg(responseData['API_GET_SYSTEM']));
        svcInfo.append('
<button type="button" id="closeSvcInfo" class="btn btn-dark" onclick="closeInputModal()">' + getClientMessage('DLG_CLOSE') + '</button>
');
        return;
    } else {
        displayAlertDanger('#svcinfo', getClientMessage('CONNERR'));
        svcInfo.append('
<button type="button" id="closeSvcInfo" class="btn btn-dark" onclick="closeInputModal()">' + getClientMessage('DLG_CLOSE') + '</button>
');
        return;
    }
    var Logs = [];
    if (statusCode['API_GET_LOGS'] == 200) {
        if (responseData['API_GET_LOGS'].Data.Log instanceof Array) {
            Logs = responseData['API_GET_LOGS'].Data.Log;
        } else if (responseData['API_GET_LOGS'].Data.Log) {
            Logs.push(responseData['API_GET_LOGS'].Data.Log);
        }
    } else {
        displayAlertDanger('#svcinfo', getClientMessage('CONNERR'));
        svcInfo.append('
<button type="button" id="closeSvcInfo" class="btn btn-dark" onclick="closeInputModal()">' + getClientMessage('DLG_CLOSE') + '</button>
');
        return;
    }

    svcInfo.append('

');
    svcInfo.append('
' + productName + ' ' + version + '
');
    svcInfo.append('
');
    svcInfo.append('Copyright (C) 2020 Shinya Takeuchi
All Rights Reserved.');
    svcInfo.append('
');
    svcInfo.append('Build Time = ' + buildTime + '
');
    svcInfo.append('Service Start Time = ' + startTime + '
');
    svcInfo.append('
');
    svcInfo.append('
' + getClientMessage('SVCINFO_TRACELOG') + '
');

    var logData = $('
');
    logData.addClass('table table-striped');

    var tHead = $('
');
    tHead.append('
' + getClientMessage('SVCINFO_LOGTIME') + '	' + getClientMessage('SVCINFO_LOGMSG') + '
');
    logData.append(tHead);

    var tBody = $('
');
    for (var Loop = 0; Loop < Logs.length; Loop++) {
        if (getClientLanguage() == 1) {
            tBody.append('
' + Logs[Loop].Time + '	' + Logs[Loop].MsgJa + '
');
        } else {
            tBody.append('
' + Logs[Loop].Time + '	' + Logs[Loop].MsgEn + '
');
        }
    }
    logData.append(tBody);

    svcInfo.append(logData);
    svcInfo.append('
<button type="button" id="closeSvcInfo" class="btn btn-dark" onclick="closeInputModal()">' + getClientMessage('DLG_CLOSE') + '</button>
');
}

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

function checkOdbcConnection() {
    drowContainerFluid('

');

    if (statusCode['API_GET_ODBCINFO_CONFIGURED'] == 200 && statusCode['API_GET_TABLEINFO'] == 200) {
        // Nothing to do
    } else if (statusCode['API_GET_ODBCINFO_CONFIGURED'] == 401) {
        displayAlertDanger('#cmdfreakdata', getSvrMsg(responseData['API_GET_ODBCINFO_CONFIGURED']));
        return;
    } else {
        displayAlertDanger('#cmdfreakdata', getClientMessage('CONNERR'));
        return;
    }
    if (responseData['API_GET_ODBCINFO_CONFIGURED'].Data.OdbcInfo.DbType === 'Init') {
        displayAlertInfo('#cmdfreakdata', getClientMessage('WELCOME_MSG') + '
' + getClientMessage('WELCOME_CONFIGODBC') + '
');
        return;
    }
    if (responseData['API_GET_ODBCINFO_CONFIGURED'].Data.OdbcInfo.Status === 'unconnectable') {
        displayAlertDanger('#cmdfreakdata', getClientMessage('ODBC_CONFAILURE'));
        return;
    }
    displayTableList();
}

function displayTableList() {
    if (responseData['API_GET_TABLEINFO'].Data.TableInfo === undefined) {
        return;
    }

    var tableInfos = getArray(responseData['API_GET_TABLEINFO'].Data.TableInfo);
    var foundIndex = -1;
    for (var tableIndex = 0; tableIndex < tableInfos.length; tableIndex++) {
        var targetName = escapeString(tableInfos[tableIndex].Name);
        addDropDownMenu(tableIndex, targetName, 'selectTable(' + tableIndex + ')');
        if (tableInfos[tableIndex].Name === currentTablename) {
            foundIndex = tableIndex;
        }
        if (tableIndex == 0 && currentTablename == "") {
            currentTablename = tableInfos[tableIndex].Name;
            foundIndex = tableIndex;
        }
    }
    if (foundIndex != -1) {
        selectTable(foundIndex);
    } else {
        currentTablename = "";
    }
}

function selectTable(index) {
    var tableInfos = getArray(responseData['API_GET_TABLEINFO'].Data.TableInfo);
    currentTablename = tableInfos[index].Name;
    globalSortTarget = '';
    globalSortOrder = '';
    startRecord = 0;
    changeDropDownTitle(trimDropDownTitle(getDropDownMenu(index)));
    var reqDatGetTbl = { 'query': tableInfos[index].Name };
    var reqDatGetRec = { 'query': tableInfos[index].Name, 'limit': recordsPerPage, 'offset': startRecord * recordsPerPage };
    var contents = [{ method: 'GET', url: '/api/tableinfo/', request: reqDatGetTbl, keystring: 'API_GET_TABLEINFO_WITH_COL' },
                    { method: 'GET', url: '/api/records/', request: reqDatGetRec, keystring: 'API_GET_RECORDS' },
                    { method: 'GET', url: '/api/reccount/', request: { 'query': currentTablename }, keystring: 'API_GET_RECCOUNT' }
    ];
    MultiApiCall(contents, displayData);
}

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

function displayData() {
    drowContainerFluid('

');

    if (statusCode['API_GET_TABLEINFO_WITH_COL'] == -1 || statusCode['API_GET_TABLEINFO_WITH_COL'] == 0) {
        displayAlertDanger('#cmdfreakdata', getClientMessage('CONNERR'));
        return;
    } else if (statusCode['API_GET_TABLEINFO_WITH_COL'] != 200) {
        displayAlertDanger('#cmdfreakdata', getSvrMsg(responseData['API_GET_TABLEINFO_WITH_COL']));
        return;
    }
    if (statusCode['API_GET_RECORDS'] == -1 || statusCode['API_GET_RECORDS'] == 0) {
        displayAlertDanger('#cmdfreakdata', getClientMessage('CONNERR'));
        return;
    } else if (statusCode['API_GET_RECORDS'] != 200) {
        displayAlertDanger('#cmdfreakdata', getSvrMsg(responseData['API_GET_RECORDS']));
        return;
    }

    if (responseData['API_GET_TABLEINFO_WITH_COL'].Data.TableInfo.ColumnInfo === undefined) {
        $('#cmdfreakdata').append(getClientMessage('NOCOLUMNS'));
        return;
    }

    var colInfo = getArray(responseData['API_GET_TABLEINFO_WITH_COL'].Data.TableInfo.ColumnInfo);
    var recData = getArray(responseData['API_GET_RECORDS'].Data.Record);
    var colCount = colInfo.length;

    $('#cmdfreakdata').append('
' + escapeString(currentTablename) + '
');

    var cmdfreakDiv = $('
')
    var cmdfreakData = $('
');

    var tHead = $('
');
    var headStr = '
';
    for (var loop = 0; loop < colCount; loop++) {
        var targetTitle = escapeString(colInfo[loop].title);
        headStr += '' + targetTitle + '  	';
    }
    headStr += '
';
    tHead.append(headStr);
    cmdfreakData.append(tHead);

    var tBody = $('
');
    if (recData !== null) {
        for (var loopRec = 0; loopRec < recData.length; loopRec++) {
            var bodyStr = '
';
            for (var loopCol = 0; loopCol < colCount; loopCol++) {
                var targetData = escapeString(recData[loopRec][loopCol]);
                bodyStr += '' + targetData + '	';
            }
            bodyStr += '
';
            tBody.append(bodyStr);
        }
    } else {
        tBody.append('
' + getClientMessage('NORECORDS') + '
');
    }
    cmdfreakData.append(tBody);
    cmdfreakDiv.append(cmdfreakData);
    $('#cmdfreakdata').append(cmdfreakDiv);

    if (responseData['API_GET_RECORDS'].Data.Sort !== undefined) {
        var sortTarget = responseData['API_GET_RECORDS'].Data.Sort.Target;
        var sortOrder = responseData['API_GET_RECORDS'].Data.Sort.Order;
        for (var loop = 0; loop < colCount; loop++) {
            if (colInfo[loop].title === sortTarget && sortOrder === 'DESC') {
                $('#sortTarget-' + loop).addClass('icon icon-arrow-up');
            }
            if (colInfo[loop].title === sortTarget && sortOrder === 'ASC') {
                $('#sortTarget-' + loop).addClass('icon icon-arrow-down');
            }
        }
    }

    resizeComponent();
}

function columnSort(targetId) {
    startRecord = 0;
    if ($('#sortTarget-' + targetId).hasClass('icon icon-arrow-down')) {
        globalSortOrder = 'DESC';
    } else {
        globalSortOrder = "ASC";
    }
    var colInfo = getArray(responseData['API_GET_TABLEINFO_WITH_COL'].Data.TableInfo.ColumnInfo);
    globalSortTarget = colInfo[targetId].title;
    var contents = [{ method: 'GET', url: '/api/tableinfo/', request: { 'query': currentTablename }, keystring: 'API_GET_TABLEINFO_WITH_COL' },
                    { method: 'GET', url: '/api/records/', request: { 'query': currentTablename, 'sort': globalSortTarget, 'sortOrder': globalSortOrder, 'limit': recordsPerPage, 'offset': startRecord * recordsPerPage }, keystring: 'API_GET_RECORDS' },
                    { method: 'GET', url: '/api/reccount/', request: { 'query': currentTablename }, keystring: 'API_GET_RECCOUNT' }
    ];
    MultiApiCall(contents, displayData);
}

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

function transDisplayFilterModal() {
    var contents = [{ method: 'GET', url: '/api/tableinfo/', request: { 'query': currentTablename }, keystring: 'API_GET_TABLEINFO_WITH_COL' },
                    { method: 'GET', url: '/api/filterinfo/', request: null, keystring: 'API_GET_FILTERINFO' }
    ];
    MultiApiCall(contents, displayFilterModal);
}

function displayFilterModal() {
    var filteringDlg = $('
');
    showInputModal(getClientMessage('FILTERING'), filteringDlg);

    if (currentTablename == "") {
        displayAlertDanger('#filter', getClientMessage('FILTERING_NO_TABLE'));
        filteringDlg.append('
<button type="button" id="closeFilterDlg" class="btn btn-dark" onclick="closeInputModal()">' + getClientMessage('DLG_CLOSE') + '</button>
');
        return;
    }
    if (statusCode['API_GET_FILTERINFO'] == 200 && statusCode['API_GET_TABLEINFO_WITH_COL'] == 200) {
        // Nothing to do
    } else if (statusCode['API_GET_TABLEINFO_WITH_COL'] == 404) {
        displayAlertDanger('#filter', getSvrMsg(responseData['API_GET_TABLEINFO_WITH_COL']));
        filteringDlg.append('
<button type="button" id="closeFilterDlg" class="btn btn-dark" onclick="closeInputModal()">' + getClientMessage('DLG_CLOSE') + '</button>
');
        return;
    } else if (statusCode['API_GET_FILTERINFO'] == 401) {
        displayAlertDanger('#filter', getSvrMsg(responseData['API_GET_FILTERINFO']));
        filteringDlg.append('
<button type="button" id="closeFilterDlg" class="btn btn-dark" onclick="closeInputModal()">' + getClientMessage('DLG_CLOSE') + '</button>
');
        return;
    } else {
        displayAlertDanger('#filter', getClientMessage('CONNERR'));
        filteringDlg.append('
<button type="button" id="closeFilterDlg" class="btn btn-dark" onclick="closeInputModal()">' + getClientMessage('DLG_CLOSE') + '</button>
');
        return;
    }

    var columnInfos = getArray(responseData['API_GET_TABLEINFO_WITH_COL'].Data.TableInfo.ColumnInfo);

    var filterOn = '';
    if (responseData['API_GET_FILTERINFO'].Data.FilterInfo.Function === 'enable') {
        filterOn = 'checked';
    }
    filteringDlg.append($('
<input class="form-check-input" type="checkbox" id="filterOn" ' + filterOn + '>' + getClientMessage('FILTERING_ON') + '
'));

    filteringDlg.append('
');
    filteringDlg.append(getClientMessage('FILTERING_DESC'));
    filteringDlg.append('
');

    for (var loopFil = 0; loopFil < 5; loopFil++) {
        var btnCol = $('
<button id="paramCol' + loopFil + '" type="button" class="filter-wid-responsive btn btn-dark dropdown-toggle" data-toggle="dropdown" aria-expanded="false">' + getClientMessage('FILTERING_UNSPECIFY') + '</button>
');
        var colMenu = $('
');
        btnCol.append(colMenu);

        var btnOpe = $('
<button id="paramOpe' + loopFil + '" type="button" class="filter-wid-responsive btn btn-dark dropdown-toggle" data-toggle="dropdown" aria-expanded="false"></button>
');
        var opeMenu = $('
');
        btnOpe.append(opeMenu);

        var frmVal = $('
<input type="text" class="form-control" id="paramVal' + loopFil + '">
');

        filteringDlg.append('
');
        filteringDlg.append(btnCol);
        filteringDlg.append(btnOpe);
        filteringDlg.append(frmVal);
        filteringDlg.append($('
'));
        filteringDlg.append('
');
    }
    resizeComponent();

    var filterInfo = responseData['API_GET_FILTERINFO'].Data.FilterInfo.Criteria;

    for (var loopFil = 0; loopFil < 5; loopFil++) {
        $('#paramOpe' + loopFil).addClass('disabled');
        $('#paramVal' + loopFil).prop('disabled', true);
        var filFndFlag = false;
        $('#paramColMenu' + loopFil).append('
' + getClientMessage('FILTERING_UNSPECIFY') + '
');
        for (var loop = 0; columnInfos != null && loop < columnInfos.length; loop++) {
            $('#paramColMenu' + loopFil).append('
' + escapeString(columnInfos[loop].title) + '
');
            if (columnInfos[loop].title == filterInfo[loopFil].columnname) {
                $('#paramColTxt' + loopFil).text(columnInfos[loop].title);
                filFndFlag = true;
                eventParamColChanged(loopFil, loop);
            }
        }
        if (!filFndFlag && filterInfo[loopFil].columnname != '*') {
            filteringDlg.empty();
            filteringDlg.append(getClientMessage('FILTERING_INVALID'));
            filteringDlg.append('
');
            filteringDlg.append('<button type="button" id="clearFiltering" class="btn btn-dark" onclick="clearFilterModal()">' + getClientMessage('DLG_OK') + '</button> ');
            filteringDlg.append('<button type="button" id="cancelFiltering" class="btn btn-dark" onclick="closeInputModal()">' + getClientMessage('DLG_CANCEL') + '</button> ');
            filteringDlg.append('
');
            return;
        }
        if (filFndFlag) {
            $('#paramOpe' + loopFil).removeClass('disabled');
            $('#paramVal' + loopFil).prop('disabled', false);
        }
        switch (filterInfo[loopFil].opetype) {
            case 1: $('#paramOpeTxt' + loopFil).text('='); break;
            case 2: $('#paramOpeTxt' + loopFil).text('!='); break;
            case 3: $('#paramOpeTxt' + loopFil).text('<='); break;
            case 4: $('#paramOpeTxt' + loopFil).text('<'); break;
            case 5: $('#paramOpeTxt' + loopFil).text('>='); break;
            case 6: $('#paramOpeTxt' + loopFil).text('>'); break;
            case 10: $('#paramOpeTxt' + loopFil).text('contains'); break;
            case 11: $('#paramOpeTxt' + loopFil).text('does not contain'); break;
            case 20: $('#paramOpeTxt' + loopFil).text('is NULL'); $('#paramVal' + loopFil).prop('disabled', true); break;
            case 21: $('#paramOpeTxt' + loopFil).text('is not NULL'); $('#paramVal' + loopFil).prop('disabled', true); break;
        }
        $('#paramVal' + loopFil).val(filterInfo[loopFil].value);
    }

    filteringDlg.append('
');
    filteringDlg.append('<button type="button" id="okFiltering" class="btn btn-dark" onclick="okFilterModal()">' + getClientMessage('DLG_OK') + '</button> ');
    filteringDlg.append('<button type="button" id="cancelFiltering" class="btn btn-dark" onclick="closeInputModal()">' + getClientMessage('DLG_CANCEL') + '</button> ');
    filteringDlg.append('
');
}

function eventParamColChanged(indexFil, indexCol) {
    var columnInfos = getArray(responseData['API_GET_TABLEINFO_WITH_COL'].Data.TableInfo.ColumnInfo);
    if (indexCol == -1) {
        $('#paramColTxt' + indexFil).text(getClientMessage('FILTERING_UNSPECIFY'));
        $('#paramOpe' + indexFil).addClass('disabled');
        $('#paramVal' + indexFil).prop('disabled', true);
        return;
    }
    $('#paramColTxt' + indexFil).text(columnInfos[indexCol].title);
    $('#paramOpe' + indexFil).removeClass('disabled');
    $('#paramVal' + indexFil).prop('disabled', false);

    $('#paramOpeMenu' + indexFil).empty();
    $('#paramOpeMenu' + indexFil).append('
=
');
    $('#paramOpeMenu' + indexFil).append('
!=
');
    if (columnInfos[indexCol].dataType === 'integer' ||
        columnInfos[indexCol].dataType === 'float') {
        $('#paramOpeMenu' + indexFil).append('
<=
');
        $('#paramOpeMenu' + indexFil).append('
<
');
        $('#paramOpeMenu' + indexFil).append('
>=
');
        $('#paramOpeMenu' + indexFil).append('
>
');
    }
    if (columnInfos[indexCol].dataType === 'string') {
        $('#paramOpeMenu' + indexFil).append('
contains
');
        $('#paramOpeMenu' + indexFil).append('
does not contain
');
    }
    $('#paramOpeMenu' + indexFil).append('
is NULL
');
    $('#paramOpeMenu' + indexFil).append('
is not NULL
');
    $('#paramOpeTxt' + indexFil).text('=');
}

function eventParamOpeChanged(indexFil, ope) {
    if (ope == "is NULL" || ope == "is not NULL") {
        $('#paramVal' + indexFil).prop('disabled', true);
    } else {
        $('#paramVal' + indexFil).prop('disabled', false);
    }
    $('#paramOpeTxt' + indexFil).text(ope);
}

function okFilterModal() {
    var criteria = [{ index: 0, columnname: "", opetype: 0, value: "" },
                    { index: 0, columnname: "", opetype: 0, value: "" },
                    { index: 0, columnname: "", opetype: 0, value: "" },
                    { index: 0, columnname: "", opetype: 0, value: "" },
                    { index: 0, columnname: "", opetype: 0, value: "" }
    ];
    for (var loop = 0; loop < 5; loop++) {
        var paramCol = $('#paramColTxt' + loop).text();
        var paramOpe = $('#paramOpeTxt' + loop).text();
        var paramVal = $('#paramVal' + loop).val();
        var paramOpeInt = 0;

        if (typeof paramCol === 'undefined' || typeof paramOpe === 'undefined' || typeof paramVal === 'undefined') {
            paramCol = '*';
            paramVal = '';
        } else if (paramCol === getClientMessage('FILTERING_UNSPECIFY') || paramOpe === '') {
            paramCol = '*';
            paramVal = '';
        } else {
            switch (paramOpe) {
                case '=': paramOpeInt = 1; break;
                case '!=': paramOpeInt = 2; break;
                case '<=': paramOpeInt = 3; break;
                case '<': paramOpeInt = 4; break;
                case '>=': paramOpeInt = 5; break;
                case '>': paramOpeInt = 6; break;
                case 'contains': paramOpeInt = 10; break;
                case 'does not contain': paramOpeInt = 11; break;
                case 'is NULL': paramOpeInt = 20; break;
                case 'is not NULL': paramOpeInt = 21; break;
            }
        }
        criteria[loop].index = loop + 1;
        criteria[loop].columnname = paramCol;
        criteria[loop].opetype = paramOpeInt;
        criteria[loop].value = paramVal;
    }

    startRecord = 0;
    var reqDatDf = { "Criteria": criteria };
    var reqDatSw = {};
    if ($('#filterOn').prop('checked') == true) {
        reqDatSw = { "Function": "enable" };
    } else {
        reqDatSw = { "Function": "disable" };
    }
    var contents = [{ method: 'POST', url: '/api/filterinfo/', request: reqDatDf, keystring: 'API_POST_FILTERINFO' },
                    { method: 'POST', url: '/api/filterinfo/', request: reqDatSw, keystring: 'API_POST_FILTERINFO' }
    ];
    MultiApiCall(contents, completeFilterModal);
    closeInputModal();
}

function clearFilterModal() {
    var criteria = [{ index: 1, columnname: "*", opetype: 0, value: "" },
                    { index: 2, columnname: "*", opetype: 0, value: "" },
                    { index: 3, columnname: "*", opetype: 0, value: "" },
                    { index: 4, columnname: "*", opetype: 0, value: "" },
                    { index: 5, columnname: "*", opetype: 0, value: "" }
    ];
    var reqDatDf = { "Criteria": criteria };
    reqDatSw = { "Function": "disable" };
    var contents = [{ method: 'POST', url: '/api/filterinfo/', request: reqDatDf, keystring: 'API_POST_FILTERINFO' },
                    { method: 'POST', url: '/api/filterinfo/', request: reqDatSw, keystring: 'API_POST_FILTERINFO' }
    ];
    MultiApiCall(contents, completeFilterModal);
    closeInputModal();
}

function completeFilterModal() {
    var contents = [{ method: 'GET', url: '/api/tableinfo/', request: { 'query': currentTablename }, keystring: 'API_GET_TABLEINFO_WITH_COL' },
                    { method: 'GET', url: '/api/records/', request: { 'query': currentTablename, 'sort': globalSortTarget, 'sortOrder': globalSortOrder, 'limit': recordsPerPage, 'offset': startRecord * recordsPerPage }, keystring: 'API_GET_RECORDS' },
                    { method: 'GET', url: '/api/reccount/', request: { 'query': currentTablename }, keystring: 'API_GET_RECCOUNT' }
    ];
    MultiApiCall(contents, displayData);
}

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

function transDisplayTableInfo() {
    var contents = [{ method: 'GET', url: '/api/tableinfo/', request: { 'query': currentTablename }, keystring: 'API_GET_TABLEINFO_WITH_COL' }];
    MultiApiCall(contents, displayTableInfo);
}

function displayTableInfo() {
    var tableInfo = $('
');
    showInputModal(getClientMessage('TABLEINFO'), tableInfo);

    if (currentTablename == "") {
        displayAlertDanger('#tableinfo', getClientMessage('TABLEINFO_NOTEXIST'));
        tableInfo.append('
<button type="button" class="btn btn-dark" onclick="closeInputModal()">' + getClientMessage('DLG_CLOSE') + '</button>
');
        return;
    }
    if (statusCode['API_GET_TABLEINFO_WITH_COL'] == 200) {
        // Nothing to do
    } else if (statusCode['API_GET_TABLEINFO_WITH_COL'] == 404 || statusCode['API_GET_TABLEINFO_WITH_COL'] == 401) {
        displayAlertDanger('#tableinfo', getSvrMsg(responseData['API_GET_TABLEINFO_WITH_COL']));
        tableInfo.append('
<button type="button" class="btn btn-dark" onclick="closeInputModal()">' + getClientMessage('DLG_CLOSE') + '</button>
');
        return;
    } else {
        displayAlertDanger('#tableinfo', getClientMessage('CONNERR'));
        tableInfo.append('
<button type="button" class="btn btn-dark" onclick="closeInputModal()">' + getClientMessage('DLG_CLOSE') + '</button>
');
        return;
    }

    var tblInfo = responseData['API_GET_TABLEINFO_WITH_COL'].Data.TableInfo;
    var columnInfos = [];
    if (tblInfo.Name === currentTablename) {
        columnInfos = getArray(responseData['API_GET_TABLEINFO_WITH_COL'].Data.TableInfo.ColumnInfo);
    } else {
        displayAlertDanger('#tableinfo', getClientMessage('TABLEINFO_NOTEXIST'));
        tableInfo.append('
<button type="button" class="btn btn-dark" onclick="closeInputModal()">' + getClientMessage('DLG_CLOSE') + '</button>
');
        return;
    }

    tableInfo.append('
' + getClientMessage('TABLEINFO_SHOWN') + '
');
    tableInfo.append(getClientMessage('TABLEINFO_TARGET') + escapeString(currentTablename));

    var tblDataDiv = $('
')
    var tblData = $('
');
    tblData.addClass('table table-striped');
    var tHead = $('
');
    tHead.append('
' + getClientMessage('TABLEINFO_COLUMNNAME') + '	' + getClientMessage('TABLEINFO_COLUMNTYPE') + '	' + getClientMessage('TABLEINFO_ISNULL') + '
');
    tblData.append(tHead);
    var tBody = $('
');
    for (var colLoop = 0; colLoop < columnInfos.length; colLoop++) {
        tBody.append('
' + escapeString(columnInfos[colLoop].title) + '	' + columnInfos[colLoop].coltype + '	' + columnInfos[colLoop].isnull + '
');
    }
    tblData.append(tBody);
    tblDataDiv.append(tblData);
    tableInfo.append(tblDataDiv);

    tableInfo.append('
');
    tableInfo.append('
<button type="button" class="btn btn-dark" onclick="closeInputModal()">' + getClientMessage('DLG_CLOSE') + '</button>
');
    tableInfo.append('
');
}

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

function transViewSetting() {
    displayViewSetting()
}

function displayViewSetting() {
    var viewSettingDlg = $('
');
    showInputModal(getClientMessage('VIEWSETTING'), viewSettingDlg);

    if (currentTablename == "") {
        displayAlertDanger('#viewsetting', getClientMessage('VIEWSETTING_NO_TABLE'));
        viewSettingDlg.append('
<button type="button" class="btn btn-dark" onclick="closeInputModal()">' + getClientMessage('DLG_CLOSE') + '</button>
');
        return;
    }
    if (statusCode['API_GET_RECCOUNT'] == 200) {
        // Nothing to do
    } else if (statusCode['API_GET_RECCOUNT'] == 404 || statusCode['API_GET_RECCOUNT'] == 401) {
        displayAlertDanger('#viewsetting', getSvrMsg(responseData['API_GET_RECCOUNT']));
        viewSettingDlg.append('
<button type="button" class="btn btn-dark" onclick="closeInputModal()">' + getClientMessage('DLG_CLOSE') + '</button>
');
        return;
    } else {
        displayAlertDanger('#viewsetting', getClientMessage('CONNERR'));
        viewSettingDlg.append('
<button type="button" class="btn btn-dark" onclick="closeInputModal()">' + getClientMessage('DLG_CLOSE') + '</button>
');
        return;
    }
    var numOfRecords = responseData['API_GET_RECCOUNT'].Data.NumOfRecords;

    viewSettingDlg.append(getClientMessage('VIEWSETTING_RECORDS_PER_PAGE') + '  ');
    var btnRecords = $('<button id="paramRecords" type="button" class="btn btn-dark dropdown-toggle" data-toggle="dropdown" aria-expanded="false"></button>');
    var recordsMenu = $('
');
    recordsMenu.append('
50
');
    recordsMenu.append('
100
');
    recordsMenu.append('
200
');
    recordsMenu.append('
400
');
    viewSettingDlg.append(btnRecords);
    viewSettingDlg.append(recordsMenu);
    viewSettingDlg.append('
');
    $('#paramRecordsText').text(recordsPerPage);

    viewSettingDlg.append('
' + getClientMessage('VIEWSETTING_PAGE') + '
');
    var textboxPage = $('
<input type="text" class="form-control" id="paramPage">

&nbsp /
');
    viewSettingDlg.append(textboxPage);
    viewSettingDlg.append('
' + (parseInt((numOfRecords - 1) / recordsPerPage)  + 1) + '
');
    viewSettingDlg.append('

');
    $('#paramPage').val(startRecord + 1);

    viewSettingDlg.append('
');
    viewSettingDlg.append('
');
    viewSettingDlg.append('<button type="button" id="okViewSetting" class="btn btn-dark" onclick="okViewSettingModal()">' + getClientMessage('DLG_OK') + '</button> ');
    viewSettingDlg.append('<button type="button" id="cancelViewSetting" class="btn btn-dark" onclick="closeInputModal()">' + getClientMessage('DLG_CANCEL') + '</button> ');
    viewSettingDlg.append('
');
}

function eventParamRecordsChanged(records, numOfRecords) {
    $('#paramRecordsText').text(records);
    $('#paramPage').val(1);
    $('#paramMaxPage').text((parseInt((numOfRecords - 1) / records) + 1));
}

function okViewSettingModal() {
    if (!$('#paramPage').val().match(/^[0-9]+$/)) {
        displayAlertDanger('#viewsetting_msg', getClientMessage('VIEWSETTING_INVALID_VALUE'));
        return;
    }

    var tmpRecordsPerPage = $('#paramRecordsText').text();
    var tmpStartRecord = parseInt($('#paramPage').val());

    var numOfRecords = responseData['API_GET_RECCOUNT'].Data.NumOfRecords;
    if (tmpStartRecord <= 0 || tmpStartRecord > (parseInt((numOfRecords - 1) / tmpRecordsPerPage) + 1)) {
        displayAlertDanger('#viewsetting_msg', getClientMessage('VIEWSETTING_INVALID_RANGE_ERROR'));
        return;
    }

    startRecord = tmpStartRecord - 1;
    recordsPerPage = tmpRecordsPerPage;

    closeInputModal();

    var contents = [{ method: 'GET', url: '/api/tableinfo/', request: { 'query': currentTablename }, keystring: 'API_GET_TABLEINFO_WITH_COL' },
                    { method: 'GET', url: '/api/records/', request: { 'query': currentTablename, 'sort': globalSortTarget, 'sortOrder': globalSortOrder, 'limit': recordsPerPage, 'offset': startRecord * recordsPerPage }, keystring: 'API_GET_RECORDS' },
                    { method: 'GET', url: '/api/reccount/', request: { 'query': currentTablename }, keystring: 'API_GET_RECCOUNT' }
    ];
    MultiApiCall(contents, completeViewSettingModal);
}

function pageForward() {
    var numOfRecords = responseData['API_GET_RECCOUNT'].Data.NumOfRecords;
    if (startRecord + 1 >= (parseInt((numOfRecords - 1) / recordsPerPage) + 1)) {
        return;
    }

    startRecord++;
    var contents = [{ method: 'GET', url: '/api/tableinfo/', request: { 'query': currentTablename }, keystring: 'API_GET_TABLEINFO_WITH_COL' },
                    { method: 'GET', url: '/api/records/', request: { 'query': currentTablename, 'sort': globalSortTarget, 'sortOrder': globalSortOrder, 'limit': recordsPerPage, 'offset': startRecord * recordsPerPage }, keystring: 'API_GET_RECORDS' },
                    { method: 'GET', url: '/api/reccount/', request: { 'query': currentTablename }, keystring: 'API_GET_RECCOUNT' }
    ];
    MultiApiCall(contents, displayData);
}

function pageBackward() {
    if (startRecord <= 0) {
        return;
    }

    startRecord--;
    var contents = [{ method: 'GET', url: '/api/tableinfo/', request: { 'query': currentTablename }, keystring: 'API_GET_TABLEINFO_WITH_COL' },
                    { method: 'GET', url: '/api/records/', request: { 'query': currentTablename, 'sort': globalSortTarget, 'sortOrder': globalSortOrder, 'limit': recordsPerPage, 'offset': startRecord * recordsPerPage }, keystring: 'API_GET_RECORDS' },
                    { method: 'GET', url: '/api/reccount/', request: { 'query': currentTablename }, keystring: 'API_GET_RECCOUNT' }
    ];
    MultiApiCall(contents, displayData);
}

function completeViewSettingModal() {
    displayData();
}

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

function initCmdFreak() {
    if (statusCode['API_GET_LANG'] == -1 || statusCode['API_GET_LANG'] == 0) {
        displayAlertDanger('body', getClientMessage('CONNERR'));
        return;
    }
    if (responseData['API_GET_LANG'].Data.ClientLanguage == 'ja') {
        setClientLanguage(1);
    } else {
        setClientLanguage(0);
    }
    showLoginModal(checkLogin);
}

function refreshInfo() {
    currentTablename = "";
    clearRsCommand();
    addDropDown(trimDropDownTitle('Tables'));
    addRsCommand('transDisplayFilterModal()', 'icon-filter', true);
    addRsCommand('transViewSetting()', 'icon-eye', true);
    addRsCommand('pageBackward()', 'icon-circle-left', true);
    addRsCommand('pageForward()', 'icon-circle-right', true);
    var contents = [{ method: 'GET', url: '/api/tableinfo/', request: null, keystring: 'API_GET_TABLEINFO' },
                    { method: 'GET', url: '/api/odbcinfo/', request: { 'query': 'configured' }, keystring: 'API_GET_ODBCINFO_CONFIGURED' }
    ];
    MultiApiCall(contents, checkOdbcConnection);
}

function checkLogin(dummyId, dummyPw) {
    setAuthenticationToken(dummyId + ' ' + dummyPw);
    apiCall('GET', '/api/user/', null, 'API_GET_USER', checkLoginAfterApiCall);
}

function checkLoginAfterApiCall() {
    if (statusCode['API_GET_USER'] == -1 || statusCode['API_GET_USER'] == 0) {
        setLoginResult(2);
        return;
    } else if (statusCode['API_GET_USER'] != 200) {
        setLoginResult(1);
        return;
    } else {
        var userRole = responseData['API_GET_USER'].Data.User.Role;
        var menuContents = [];
        if (userRole == 0) {
            menuContents = [
                { actApiName: 'transDisplayOdbcConfig()', title: getClientMessage('ODBC_CONNECTIONS') },
                { actApiName: 'transDisplayInformation()', title: getClientMessage('SVCINFOS') }
            ];
        } else {
            menuContents = [
                { actApiName: 'transDisplayInformation()', title: getClientMessage('SVCINFOS') }
            ];
        }
        initMainPage('CmdFreak', 'img/cristal_image48c.png', menuContents, 'refreshInfo()');

        let usermenuContents = [];
        if (userRole == 1) {
            usermenuContents = [
                { actApiName: 'transDisplayLogInfo()', title: getClientMessage('OPE_LOG') },
                { actApiName: 'transDisplayChgPassword()', title: getClientMessage('USER_CHG_PW') }
            ];
        } else {
            usermenuContents = [
                { actApiName: 'transDisplayLogInfo()', title: getClientMessage('OPE_LOG') },
                { actApiName: 'transDisplayUser()', title: getClientMessage('USERMGMTS') },
                { actApiName: 'transDisplayChgPassword()', title: getClientMessage('USER_CHG_PW') }
            ];
        }
        addRsUserMenu(usermenuContents);

        refreshInfo();
        setLoginResult(0);
        return;
    }
}

function trimDropDownTitle(dropdownTitle) {
    if (dropdownTitle === '') {
        return;
    }
    var wsize = $(window).width();
    var length = 0;
    if (wsize >= 1200) {
        length = 32;
    } else if (wsize >= 992) {
        length = 16;
    } else if (wsize >= 576) {
        length = 8;
    } else if (wsize >= 400) {
        length = 6;
    } else {
        length = 3;
    }
    var tmpTitle = dropdownTitle.substring(0, length);
    if (tmpTitle !== dropdownTitle) {
        tmpTitle = tmpTitle + '...';
    }
    return tmpTitle;
}

function resizeComponent() {
    var wsize = $(window).width();

    var horizontal = false;
    if (wsize >= 1200) {
        horizontal = true;
        wsize = 300;
    } else if (wsize >= 992) {
        horizontal = true;
        wsize = 240;
    } else if (wsize >= 576) {
        horizontal = false;
        wsize = 400;
    } else if (wsize >= 400) {
        horizontal = false;
        wsize = 300;
    } else {
        horizontal = false;
        wsize = 240;
    }
    if (horizontal == true) {
        $(".filter-col-responsive").css("margin-left", "0px");
        $(".filter-ope-responsive").css("margin-left", "0px");
        $(".filter-val-responsive").css("margin-left", "0px");
        $(".filter-col-responsive").css("float", "left");
        $(".filter-ope-responsive").css("float", "left");
        $(".filter-val-responsive").css("float", "left");
    } else {
        $(".filter-col-responsive").css("margin-left", "0px");
        $(".filter-ope-responsive").css("margin-left", "15px");
        $(".filter-val-responsive").css("margin-left", "30px");
        $(".filter-col-responsive").css("float", "top");
        $(".filter-ope-responsive").css("float", "top");
        $(".filter-val-responsive").css("float", "top");
    }
    $(".filter-wid-responsive").css("width", wsize + "px");

    var hsize = $(window).height() - 82;
    $(".table-responsive").css("height", hsize + "px");
}

$(document).ready(function () {
    resizeComponent();
    changeDropDownTitle(trimDropDownTitle(currentTablename));
});

$(window).resize(function () {
    resizeComponent();
    changeDropDownTitle(trimDropDownTitle(currentTablename));
});

window.onload = function () {
    initClientMessage();
    var contents = [{ method: 'GET', url: '/api/language/', request: null, keystring: 'API_GET_LANG' }];
    MultiApiCall(contents, initCmdFreak);
}


text:
gosteno-prettify is a command line tool which parses json formatted log lines
from file(s), or stdin, and displays a more human friendly version of each line
to stdout.

## Setup

    go get -u github.com/cloudfoundry/gosteno
    cd $GOPATH/src/github.com/cloudfoundry/gosteno/gosteno-prettify
    go install

Don't forget to add the $GOPATH/bin to the $PATH

## Usage

    gosteno-prettify [OPTS] [FILE(s)]

Examples :

    gosteno-prettify f - g
        Prettify f's contents, then standard input, then g's contents.

    gosteno-prettify
        Prettify contents of stdin.

Fire `gosteno-prettify -h` to see more options.

redpajama_set_name: RedPajamaGithub


text:
<ivysettings>
  <property name="ivy.shared.default.root"
            value="${env.HOME}/repos" override="true"/>
  <property name="ivy.shared.default.ivy.pattern"
            value="[organisation]/[module]/[revision]/[type]s/[artifact].[ext]"
            override="false"/>
  <property name="ivy.shared.default.artifact.pattern"
            value="[organisation]/[module]/[revision]/[type]s/[artifact].[ext]"
            override="false"/>
  <resolvers>
    <!--
        <filesystem name="shared">
        <ivy pattern="${ivy.shared.default.root}/${ivy.shared.default.ivy.pattern}" />
        <artifact pattern="${ivy.shared.default.root}/${ivy.shared.default.artifact.pattern}" />
        </filesystem>

        <ssh name="shared" user="kfs" host="192.168.7.242" userPassword="kfs123">
          <ivy pattern="${ivy.shared.default.root}/${ivy.shared.default.ivy.pattern}" />
          <artifact pattern="${ivy.shared.default.root}/${ivy.shared.default.artifact.pattern}" />
        </ssh>
    -->
    <ssh host="source.3zso.com">
      <ivy pattern="${ivy.shared.default.root}/${ivy.shared.default.ivy.pattern}" />
      <artifact pattern="${ivy.shared.default.root}/${ivy.shared.default.artifact.pattern}" />
    </ssh>
  </resolvers>
</ivysettings>


text:
function TitaniumStub() {
    this.UI = new UIStub();
    this.API = new APIStub();
    this.Filesystem = new FileSystemStub();
}

function TiStub() {
    this.UI = new UIStub();
    this.API = new APIStub();
}

function APIStub() {
    this.info = function(msg) {
    };
}

function UIStub() {
    this.iPhone = new iPhoneStub();
    this.createButton = function(obj) {
        return new ObjectStub(obj);
    }
    this.createImageView = function(obj) {
        return new ObjectStub(obj);
    }
    this.createLabel = function(obj) {
        return new ObjectStub(obj)
    }
    this.createView = function(obj) {
        return new ObjectStub(obj);
    }
    this.create2DMatrix = function() {
        return new ObjectStub();
    }
    this.createAnimation = function(obj) {
        return new ObjectStub(obj);
    }
    this.createWindow = function(obj) {
        return new ObjectStub(obj);
    }
}

function FileSystemStub() {
    this.getFile = function() {
        return new FileStub()
    };
    this.resourcesDirectory = "Resources";
}

function FileStub() {
    this.getDirectoryListing = function() {
        var files = [];
        files.push("file1");
        return files;
    }
}

function ObjectStub(obj) {

    if (obj != null) {
        this.backgroundColor = obj.backgroundColor;
        this.backgroundImage = obj.backgroundImage;
        this.bottom = obj.bottom;
        this.color = obj.color;
        this.height = obj.height;
        this.hidden = false;
        this.image = obj.image;
        this.text = obj.text;
        this.textAlign = obj.textAlign;
        this.title = obj.title;
        this.top = obj.top;
        this.width = obj.width;
        this.zIndex = obj.zIndex;
    }

    this.hide = function() {
        hidden = true
    };
    this.addEventListener = function(event, callback) {
        if (event == "click") {
            this.click = callback;
        }
    };

    var children = [];
    this.children = children;
    this.add = function(obj) {
        children.push(obj)
    };
    this.scale = function(scaleFactor) {
        this.scaleFactor = scaleFactor;
    }

    this.animate = function() {};
    this.open = function() {};
}

function iPhoneStub() {
    this.AnimationStyle = new AnimationStyleStub();
}

function AnimationStyleStub() {
    this.CURL_UP = 1;
}

var Ti = new TiStub();


text:
import mpp.api
import mpp.utils
import mpp.cout

class Plugin(mpp.api.Plugin, mpp.api.IRunable):

    def run(self, args):
        loader = self.get_plugin('mpp.dbf').get_loader()
        # get previous db file loader
        loader_prev = self.get_plugin('mpp.dbf').get_loader_prev()

        exit_code = 0
        for path in (args if len(args) > 0 else [""]):
            added_lines = 0
            file_iterator = loader.iterate_file_data(path)
            if file_iterator == None:
                mpp.utils.report_bad_path(path)
                exit_code += 1
                continue
            for file_data in file_iterator:
                added_lines += self._compare_file(file_data, loader, loader_prev)
            mpp.cout.notify(path, '', mpp.cout.SEVERITY_INFO,
                            "Change trend report",
                            [('Added lines', added_lines)])
        return exit_code

    def _compare_file(self, file_data, loader, loader_prev):
        # compare file with previous and return number of new lines
        file_data_prev = loader_prev.load_file_data(file_data.get_path())
        if file_data_prev == None:
            return self._sum_file_regions_lines(file_data)
        elif file_data.get_checksum() != file_data_prev.get_checksum():
            return self._compare_file_regions(file_data, file_data_prev)

    def _sum_file_regions_lines(self, file_data):
        # just sum up the metric for all regions
        result = 0
        for region in file_data.iterate_regions():
            result += region.get_data('std.code.lines', 'total')

    def _compare_file_regions(self, file_data, file_data_prev):
        # compare every region with previous and return number of new lines
        matcher = mpp.utils.FileRegionsMatcher(file_data, file_data_prev)
        result = 0
        for region in file_data.iterate_regions():
            if matcher.is_matched(region.get_id()) == False:
                # if added region, just add the lines
                result += region.get_data('std.code.lines', 'total')
            elif matcher.is_modified(region.get_id()):
                # if modified, add the difference in lines
                region_prev = file_data_prev.get_region(
                    matcher.get_prev_id(region.get_id()))
                result += (region.get_data('std.code.lines', 'total') -
                           region_prev.get_data('std.code.lines', 'total'))
        return result


text:
package fakes

import (
	"sync"

	"github.com/pivotal-cf/om/api"
)

type StemcellService struct {
	UploadStub        func(api.StemcellUploadInput) (api.StemcellUploadOutput, error)
	uploadMutex       sync.RWMutex
	uploadArgsForCall []struct {
		arg1 api.StemcellUploadInput
	}
	uploadReturns struct {
		result1 api.StemcellUploadOutput
		result2 error
	}
	invocations      map[string][][]interface{}
	invocationsMutex sync.RWMutex
}

func (fake *StemcellService) Upload(arg1 api.StemcellUploadInput) (api.StemcellUploadOutput, error) {
	fake.uploadMutex.Lock()
	fake.uploadArgsForCall = append(fake.uploadArgsForCall, struct {
		arg1 api.StemcellUploadInput
	}{arg1})
	fake.recordInvocation("Upload", []interface{}{arg1})
	fake.uploadMutex.Unlock()
	if fake.UploadStub != nil {
		return fake.UploadStub(arg1)
	} else {
		return fake.uploadReturns.result1, fake.uploadReturns.result2
	}
}

func (fake *StemcellService) UploadCallCount() int {
	fake.uploadMutex.RLock()
	defer fake.uploadMutex.RUnlock()
	return len(fake.uploadArgsForCall)
}

func (fake *StemcellService) UploadArgsForCall(i int) api.StemcellUploadInput {
	fake.uploadMutex.RLock()
	defer fake.uploadMutex.RUnlock()
	return fake.uploadArgsForCall[i].arg1
}

func (fake *StemcellService) UploadReturns(result1 api.StemcellUploadOutput, result2 error) {
	fake.UploadStub = nil
	fake.uploadReturns = struct {
		result1 api.StemcellUploadOutput
		result2 error
	}{result1, result2}
}

func (fake *StemcellService) Invocations() map[string][][]interface{} {
	fake.invocationsMutex.RLock()
	defer fake.invocationsMutex.RUnlock()
	fake.uploadMutex.RLock()
	defer fake.uploadMutex.RUnlock()
	return fake.invocations
}

func (fake *StemcellService) recordInvocation(key string, args []interface{}) {
	fake.invocationsMutex.Lock()
	defer fake.invocationsMutex.Unlock()
	if fake.invocations == nil {
		fake.invocations = map[string][][]interface{}{}
	}
	if fake.invocations[key] == nil {
		fake.invocations[key] = [][]interface{}{}
	}
	fake.invocations[key] = append(fake.invocations[key], args)
}


text:
layout: 	project_page
title:  	"PreOrder"
date:   	2016-09-07 23:30:00 +0100
category: 	school-project
thumb: 		/assets/preorder.png

excerpt: |
  Art installation where you discover an archive from an old civilization.

type: "Interactive installation"
platforms: "Android"
inputs: "Touch"
tools: "Unity / Wwise"

abstract: |
  The goal of this exercise was to create at least 4 different landscapes and tell a story through them. The main constraint was to not having a living person, because this would have created questions like : who are them ? why are they here ?

banner: {"type": "image", "src": "/assets/preorder-fresque.jpg"}

team:
  - {"name": "Tara Quinsac", "role": "Artist"}
  - {"name": "Noémie Szmrzsik-Cohard", "role": "Artist"}
  - {"name": "Charlotte Couder", "role": "Game designer"}
  - {"name": "Anize Amestoy", "role": "Sound designer"}
  - {"name": "Yannis Attard", "role": "Developer"}
  - {"name": "Clément Rondeau", "role": "Developer"}

tasks:
  - Touch screen controls
  - Scratch effect
  - Music integration

screenshots: {"/assets/preorder/1.jpg", "/assets/preorder/2.jpg"}
---
Our main idea was to tell the story of an old civilization, with the following landscapes : a desert of skin and hair, a mountain of flesh and muscles, a river of dead bodies, a mountain of household appliances, a forest of pylon and cameras.

The visitor must scratch the tablet to discover a fresco on which they can move with touch controls. The device was hidden in a box that the visitor must open to begin the experience.

To make this possible I've created a big texture that fit the size of the fresco, when the user touch the screen with one finger I've drawn a circle in the texture. To draw the circle I've used the Bresenham circle algorithm.

The main problem with this method is that the CPU overhead is really high, for an art installation it was okay but it would not be possible for a game. The idea that I've to fix this problem is to divide the texture in multiple smaller textures, but it has never been implemented for the moment.


text:
var showWindown = true;
var templateSrc = "/data/images/base"; //璁剧疆loading.gif璺


text:
namespace metis {
namespace path {

bool exists(const char *path);

}  // namespace path
}  // namespace metis


text:
package com.team254.lib.util.gyro;

import com.team254.lib.util.Util;
import edu.wpi.first.wpilibj.Notifier;
import edu.wpi.first.wpilibj.TimerEventHandler;

import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

/**
 * Thread which is responsible for reading the gyro
 */
public class GyroThread {

    private static final int K_READING_RATE = 200;
    private static final int K_ZEROING_SAMPLES = 6 * K_READING_RATE;
    private static final int K_STARTUP_SAMPLES = 2 * K_READING_RATE;

    // synchronized access object
    private final Timer mTimer = new Timer("Gyro");
    // owned by the background thread
    private final GyroInterface mGyroInterface = new GyroInterface();

    private UpdateHandler mUpdateHandler = new UpdateHandler();
    private Notifier mNotifier = new Notifier(mUpdateHandler, this);

    // thread communication variables
    private volatile boolean mVolatileHasData = false;
    private volatile double mVolatileAngle = 0;
    private volatile double mVolatileRate = 0;
    private volatile boolean mVolatileShouldReZero = true;

    // owned by the accesser of this object
    private double mZeroHeading = 0;

    public void start() {
        synchronized (mTimer) {
            mTimer.schedule(new InitTask(), 0);
        }
    }

    public boolean hasData() {
        return mVolatileHasData;
    }

    public double getAngle() {
        return mVolatileAngle - mZeroHeading;
    }

    public double getRate() {
        return mVolatileRate;
    }

    public void rezero() {
        mVolatileShouldReZero = true;
    }

    public void reset() {
        mZeroHeading = mVolatileAngle;
    }

    /**
     * Initializes the gyro, verifying the its self-test results
     */
    private class InitTask extends TimerTask {
        @Override
        public void run() {
            boolean initialized = false;
            while (!initialized) {
                try {
                    mGyroInterface.initializeGyro();
                    initialized = true;
                } catch (GyroInterface.GyroException e) {
                    System.out.println("Gyro failed to initialize: " + e.getMessage());
                }
                if (!initialized) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            System.out.println("gyo initialized, part ID: 0x" + Integer.toHexString(mGyroInterface.readPartId()));
            synchronized (mNotifier) {
                mNotifier.startPeriodic(1.0 / K_READING_RATE);
            }
        }
    }

    /**
     * Updates the actual gyro data (zeroing and accumulation)
     */
    private class UpdateHandler implements TimerEventHandler {
        private int mRemainingStartupCycles = K_STARTUP_SAMPLES;
        private boolean mIsZerod = false;
        private double[] mZeroRateSamples = new double[K_ZEROING_SAMPLES];
        private int mZeroRateSampleIndex = 0;
        private boolean mHasEnoughZeroingSamples;
        private double mZeroBias;
        private double mAngle = 0;
        private double mLastTime = 0;

        @Override
        public void update(Object param) {
            int reading;
            try {
                reading = mGyroInterface.getReading();
            } catch (GyroInterface.GyroException e) {
                System.out.println("Gyro read failed: " + e.getMessage());
                return;
            }
            GyroInterface.StatusFlag status = GyroInterface.extractStatus(reading);
            List<GyroInterface.ErrorFlag> errors = GyroInterface.extractErrors(reading);
            if (GyroInterface.StatusFlag.VALID_DATA != status || !errors.isEmpty()) {
                System.out.println("Gyro read failed. Status: " + status + ". Errors: " + Util.joinStrings(", ", errors));
                return;
            }

            if (mRemainingStartupCycles > 0) {
                mRemainingStartupCycles--;
                return;
            }

            if (mVolatileShouldReZero) {
                mVolatileShouldReZero = false;
                mVolatileHasData = false;
                mIsZerod = false;
            }

            double unbiasedAngleRate = GyroInterface.extractAngleRate(reading);
            mZeroRateSamples[mZeroRateSampleIndex] = unbiasedAngleRate;
            mZeroRateSampleIndex++;
            if (mZeroRateSampleIndex >= K_ZEROING_SAMPLES) {
                mZeroRateSampleIndex = 0;
                mHasEnoughZeroingSamples = true;
            }
            if (!mIsZerod) {
                if (!mHasEnoughZeroingSamples) {
                    return;
                }
                mZeroBias = 0;
                for (Double sample : mZeroRateSamples) {
                    mZeroBias += sample / K_ZEROING_SAMPLES;
                }
                mAngle = 0;
                mVolatileAngle = 0;
                GyroThread.this.reset();
                mIsZerod = true;
                return;
            }

            double now = edu.wpi.first.wpilibj.Timer.getFPGATimestamp();
            double timeElapsed = mLastTime == 0 ? 1.0 / K_READING_RATE : now - mLastTime;
            mLastTime = now;

            mVolatileRate = unbiasedAngleRate - mZeroBias;
            mAngle += mVolatileRate * timeElapsed;
            mVolatileAngle = mAngle;
            mVolatileHasData = true;
        }
    }
}


text:
#import "JLRoutes.h"

NSString *const kJLRoutePatternKey = @"JLRoutePattern";
NSString *const kJLRouteURLKey = @"JLRouteURL";
NSString *const kJLRouteNamespaceKey = @"JLRouteNamespace";
NSString *const kJLRouteWildcardComponentsKey = @"JLRouteWildcardComponents";
NSString *const kJLRoutesGlobalNamespaceKey = @"JLRoutesGlobalNamespace";

static NSMutableDictionary *routeControllersMap = nil;
static BOOL verboseLoggingEnabled = NO;
static BOOL shouldDecodePlusSymbols = YES;

@interface JLRoutes ()

@property (nonatomic, strong) NSMutableArray *routes;
@property (nonatomic, strong) NSString *namespaceKey;

+ (void)verboseLogWithFormat:(NSString *)format, ...;
+ (BOOL)routeURL:(NSURL *)URL withController:(JLRoutes *)routesController parameters:(NSDictionary *)parameters;
- (BOOL)isGlobalRoutesController;

@end

@interface NSString (JLRoutes)

- (NSString *)JLRoutes_URLDecodedString;
- (NSDictionary *)JLRoutes_URLParameterDictionary;

@end

@implementation NSString (JLRoutes)

- (NSString *)JLRoutes_URLDecodedString {
    NSString *input = shouldDecodePlusSymbols ? [self stringByReplacingOccurrencesOfString:@"+" withString:@" " options:NSLiteralSearch range:NSMakeRange(0, self.length)] : self;
    return [input stringByRemovingPercentEncoding];
}

- (NSDictionary *)JLRoutes_URLParameterDictionary {
    NSMutableDictionary *parameters = [NSMutableDictionary dictionary];

    if (self.length && [self rangeOfString:@"="].location != NSNotFound) {
        NSArray *keyValuePairs = [self componentsSeparatedByString:@"&"];
        for (NSString *keyValuePair in keyValuePairs) {
            NSArray *pair = [keyValuePair componentsSeparatedByString:@"="];
            // don't assume we actually got a real key=value pair. start by assuming we only got @[key] before checking count
            NSString *paramValue = pair.count == 2 ? pair[1] : @"";
            // CFURLCreateStringByReplacingPercentEscapesUsingEncoding may return NULL
            parameters[pair[0]] = [paramValue JLRoutes_URLDecodedString] ?: @"";
        }
    }

    return parameters;
}

@end

@interface NSURL (JLRoutes)

- (NSArray *)JLRoutes_fragmentPathComponents;
- (NSString *)JLRoutes_fragmentQuery;

@end

@implementation NSURL (JLRoutes)

- (NSArray *)JLRoutes_fragmentPathComponents {
    NSString *fragment = self.fragment;
    if (!fragment) {
        return nil;
    }

    NSURL *URL = [[NSURL alloc] initWithString:fragment];
    return URL.pathComponents;
}

- (NSString *)JLRoutes_fragmentQuery {
    NSString *fragment = self.fragment;
    if (!fragment) {
        return nil;
    }

    NSURL *URL = [[NSURL alloc] initWithString:fragment];
    return URL.query;
}

@end

@interface _JLRoute : NSObject

@property (nonatomic, weak) JLRoutes *parentRoutesController;
@property (nonatomic, strong) NSString *pattern;
@property (nonatomic, strong) BOOL (^block)(NSDictionary *parameters);
@property (nonatomic, assign) NSUInteger priority;
@property (nonatomic, strong) NSArray *patternPathComponents;
@property (nonatomic, strong) NSArray *patternFragmentComponents;
@property (nonatomic, assign) BOOL matchFragmentComponents;

- (NSDictionary *)parametersForURL:(NSURL *)URL pathComponents:(NSArray *)pathComponents fragmentComponents:(NSArray *)fragmentComponents;

@end

@implementation _JLRoute

- (NSDictionary *)parametersForURL:(NSURL *)URL pathComponents:(NSArray *)pathComponents fragmentComponents:(NSArray *)fragmentComponents {

    if (!self.patternPathComponents) {
        NSString *fragmentIdentifier = @"#";
        NSRange range = [self.pattern rangeOfString:fragmentIdentifier];

        NSString *pathPattern;
        NSString *fragmentPattern;

        if (range.location != NSNotFound) {
            pathPattern = [self.pattern substringToIndex:range.location];
            fragmentPattern = [self.pattern substringFromIndex:range.location + fragmentIdentifier.length];
            self.matchFragmentComponents = YES;
        } else {
            pathPattern = self.pattern;
        }

        NSPredicate *filterSlashesPredicate = [NSPredicate predicateWithFormat:@"NOT SELF like '/'"];
        self.patternPathComponents = [[pathPattern pathComponents] filteredArrayUsingPredicate:filterSlashesPredicate];
        self.patternFragmentComponents = [[fragmentPattern pathComponents] filteredArrayUsingPredicate:filterSlashesPredicate];
    }

    NSMutableDictionary *routeParameters = [NSMutableDictionary dictionary];

    NSDictionary *pathParameters = [self parametersForURL:URL patternComponents:self.patternPathComponents components:pathComponents];
    if (!pathParameters) {
        return nil;
    }

    NSDictionary *fragmentParameters;
    if (self.matchFragmentComponents) {
        fragmentParameters = [self parametersForURL:URL patternComponents:self.patternFragmentComponents components:fragmentComponents];
        if (!fragmentParameters) {
            return nil;
        }

        [routeParameters addEntriesFromDictionary:fragmentParameters];
    }

    [routeParameters addEntriesFromDictionary:pathParameters];

    return routeParameters;
}

- (NSDictionary *)parametersForURL:(NSURL *)URL patternComponents:(NSArray *)patternComponents components:(NSArray *)components {
    NSDictionary *routeParameters = nil;

    // do a quick component count check to quickly eliminate incorrect patterns
    BOOL componentCountEqual = patternComponents.count == components.count;
    BOOL patternContainsWildcard = [patternComponents containsObject:@"*"];
    if (componentCountEqual || patternContainsWildcard) {
        // now that we've identified a possible match, move component by component to check if it's a match
        NSUInteger componentIndex = 0;
        NSMutableDictionary *variables = [NSMutableDictionary dictionary];
        BOOL isMatch = YES;

        for (NSString *patternComponent in patternComponents) {
            NSString *URLComponent = nil;
            if (componentIndex < [components count]) {
                URLComponent = components[componentIndex];
            } else if ([patternComponent isEqualToString:@"*"]) { // match /foo by /foo/*
                URLComponent = [components lastObject];
            }

            if ([patternComponent hasPrefix:@":"]) {
                // this component is a variable
                NSString *variableName = [patternComponent substringFromIndex:1];
                NSString *variableValue = URLComponent;
                NSString *urlDecodedVariableValue = [variableValue JLRoutes_URLDecodedString];
                if ([variableName length] > 0 && [urlDecodedVariableValue length] > 0) {
                    variables[variableName] = urlDecodedVariableValue;
                }
                else {
                    NSMutableArray * newComponents = [NSMutableArray arrayWithArray:components];
                    [newComponents addObject:@""];
                    components = newComponents;
                }
            } else if ([patternComponent isEqualToString:@"*"]) {
                // match wildcards
                variables[kJLRouteWildcardComponentsKey] = [components subarrayWithRange:NSMakeRange(componentIndex, components.count-componentIndex)];
                isMatch = YES;
                break;
            } else if (![patternComponent isEqualToString:URLComponent]) {
                // a non-variable component did not match, so this route doesn't match up - on to the next one
                isMatch = NO;
                break;
            }
            componentIndex++;
        }

        if (isMatch) {
            routeParameters = variables;
        }
    }

    return routeParameters;
}

- (NSString *)description {
    return [NSString stringWithFormat:@"JLRoute %@ (%@)", self.pattern, @(self.priority)];
}

@end

@implementation JLRoutes

- (id)init {
    if ((self = [super init])) {
        self.routes = [NSMutableArray array];
    }
    return self;
}

+ (void)setShouldDecodePlusSymbols:(BOOL)shouldDecode {
    shouldDecodePlusSymbols = shouldDecode;
}

+ (BOOL)shouldDecodePlusSymbols {
    return shouldDecodePlusSymbols;
}

#pragma mark -
#pragma mark Routing API

+ (instancetype)globalRoutes {
    return [self routesForScheme:kJLRoutesGlobalNamespaceKey];
}

+ (instancetype)routesForScheme:(NSString *)scheme {
    JLRoutes *routesController = nil;

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        routeControllersMap = [[NSMutableDictionary alloc] init];
    });

    if (!routeControllersMap[scheme]) {
        routesController = [[self alloc] init];
        routesController.namespaceKey = scheme;
        routeControllersMap[scheme] = routesController;
    }

    routesController = routeControllersMap[scheme];

    return routesController;
}

+ (void)addRoute:(NSString *)routePattern handler:(BOOL (^)(NSDictionary<NSString *, NSString *> *parameters))handlerBlock {
    [[self globalRoutes] addRoute:routePattern handler:handlerBlock];
}

+ (void)addRoutes:(NSArray<NSString *> *)routePatterns handler:(BOOL (^)(NSDictionary<NSString *, NSString *> *parameters))handlerBlock {
    for (NSString *routePattern in routePatterns) {
        [self addRoute:routePattern handler:handlerBlock];
    }
}

+ (void)addRoute:(NSString *)routePattern priority:(NSUInteger)priority handler:(BOOL (^)(NSDictionary<NSString *, NSString *> *parameters))handlerBlock {
    [[self globalRoutes] addRoute:routePattern priority:priority handler:handlerBlock];
}

- (void)addRoute:(NSString *)routePattern handler:(BOOL (^)(NSDictionary<NSString *, NSString *> *parameters))handlerBlock {
    [self addRoute:routePattern priority:0 handler:handlerBlock];
}

- (void)addRoutes:(NSArray<NSString *> *)routePatterns handler:(BOOL (^)(NSDictionary<NSString *, NSString *> *parameters))handlerBlock {
    for (NSString *routePattern in routePatterns) {
        [self addRoute:routePattern handler:handlerBlock];
    }
}

- (void)addRoute:(NSString *)routePattern priority:(NSUInteger)priority handler:(BOOL (^)(NSDictionary<NSString *, NSString *> *parameters))handlerBlock {
    // if there's a pair of parenthesis, process optionals, trim the parenthesis, put it on trimmedRoute
    NSString *trimmedRoute = routePattern;

    // repeat until no parenthesis pair is found
    while ([trimmedRoute rangeOfString:@")" options:NSBackwardsSearch].location > [trimmedRoute rangeOfString:@"(" options:NSBackwardsSearch].location) {

        //Build route with the optionals
        NSString *patternWithOptionals = [trimmedRoute stringByReplacingOccurrencesOfString:@"(" withString:@""];
        patternWithOptionals = [patternWithOptionals stringByReplacingOccurrencesOfString:@")" withString:@""];
        [self registerRoute:patternWithOptionals priority:priority handler:handlerBlock];

        //Build route without optionals
        NSRange rangeOfLastParentheses = [trimmedRoute rangeOfString:@"(" options:NSBackwardsSearch];
        NSRange rangeToRemove = NSMakeRange(rangeOfLastParentheses.location, trimmedRoute.length - rangeOfLastParentheses.location);
        NSString *patternWithLastOptionalRemoved = [trimmedRoute stringByReplacingCharactersInRange:rangeToRemove withString:@""];
        //Remove any parenthesis for other optionals that might still be in the route
        NSString *patternWithoutOptionals = [patternWithLastOptionalRemoved stringByReplacingOccurrencesOfString:@"(" withString:@""];
        patternWithoutOptionals = [patternWithoutOptionals stringByReplacingOccurrencesOfString:@")" withString:@""];
        [self registerRoute:patternWithoutOptionals priority:priority handler:handlerBlock];

        trimmedRoute = patternWithLastOptionalRemoved;
    }

    //Only register original route if trimmedRoute haven't been modified.
    if (trimmedRoute == routePattern) {
        [self registerRoute:routePattern priority:priority handler:handlerBlock];
    }
}

- (void)registerRoute:(NSString *)routePattern priority:(NSUInteger)priority handler:(BOOL (^)(NSDictionary *parameters))handlerBlock {
    _JLRoute *route = [[_JLRoute alloc] init];
    route.pattern = routePattern;
    route.priority = priority;
    route.block = [handlerBlock copy];
    route.parentRoutesController = self;

    if (!route.block) {
        route.block = [^BOOL (NSDictionary *params) {
            return YES;
        } copy];
    }

    if (priority == 0 || self.routes.count == 0) {
        [self.routes addObject:route];
    } else {
        NSArray *existingRoutes = self.routes;
        NSUInteger index = 0;
        BOOL addedRoute = NO;

        // search through existing routes looking for a lower priority route than this one
        for (_JLRoute *existingRoute in existingRoutes) {
            if (existingRoute.priority < priority) {
                // if found, add the route after it
                [self.routes insertObject:route atIndex:index];
                addedRoute = YES;
                break;
            }
            index++;
        }

        // if we weren't able to find a lower priority route, this is the new lowest priority route (or same priority as self.routes.lastObject) and should just be added
        if (!addedRoute)
            [self.routes addObject:route];
    }
}

+ (void)removeRoute:(NSString *)routePattern {
    [[JLRoutes globalRoutes] removeRoute:routePattern];
}

- (void)removeRoute:(NSString *)routePattern {
    if (![routePattern hasPrefix:@"/"]) {
        routePattern = [NSString stringWithFormat:@"/%@", routePattern];
    }

    NSInteger routeIndex = NSNotFound;
    NSInteger index = 0;

    for (_JLRoute *route in self.routes) {
        if ([route.pattern isEqualToString:routePattern]) {
            routeIndex = index;
            break;
        }
        index++;
    }

    if (routeIndex != NSNotFound) {
        [self.routes removeObjectAtIndex:(NSUInteger)routeIndex];
    }
}

+ (void)removeAllRoutes {
    [[JLRoutes globalRoutes] removeAllRoutes];
}

- (void)removeAllRoutes {
    [self.routes removeAllObjects];
}

+ (void)unregisterRouteScheme:(NSString *)scheme {
    [routeControllersMap removeObjectForKey:scheme];
}

+ (BOOL)routeURL:(NSURL *)URL {
    return [self routeURL:URL withParameters:nil executeRouteBlock:YES];
}

+ (BOOL)routeURL:(NSURL *)URL withParameters:(NSDictionary *)parameters {
    return [self routeURL:URL withParameters:parameters executeRouteBlock:YES];
}

+ (BOOL)canRouteURL:(NSURL *)URL {
    return [self routeURL:URL withParameters:nil executeRouteBlock:NO];
}

+ (BOOL)canRouteURL:(NSURL *)URL withParameters:(NSDictionary *)parameters {
    return [self routeURL:URL withParameters:parameters executeRouteBlock:NO];
}

+ (BOOL)routeURL:(NSURL *)URL withParameters:(NSDictionary *)parameters executeRouteBlock:(BOOL)execute {
    if (!URL) {
        return NO;
    }

    // figure out which routes controller to use based on the scheme
    JLRoutes *routesController = routeControllersMap[[URL scheme]] ?: [self globalRoutes];

    return [self routeURL:URL withController:routesController parameters:parameters executeBlock:execute];
}

- (BOOL)routeURL:(NSURL *)URL {
    return [[self class] routeURL:URL withController:self];
}

- (BOOL)routeURL:(NSURL *)URL withParameters:(NSDictionary *)parameters {
    return [[self class] routeURL:URL withController:self parameters:parameters];
}

- (BOOL)canRouteURL:(NSURL *)URL {
    return [[self class] routeURL:URL withController:self parameters:nil executeBlock:NO];
}

- (BOOL)canRouteURL:(NSURL *)URL withParameters:(NSDictionary *)parameters {
    return [[self class] routeURL:URL withController:self parameters:parameters executeBlock:NO];
}

#pragma mark -
#pragma mark Debugging Aids

- (NSString *)description {
    return [self.routes description];
}

+ (NSString *)description {
    NSMutableString *descriptionString = [NSMutableString stringWithString:@"\n"];

    for (NSString *routesNamespace in routeControllersMap) {
        JLRoutes *routesController = routeControllersMap[routesNamespace];
        [descriptionString appendFormat:@"\"%@\":\n%@\n\n", routesController.namespaceKey, routesController.routes];
    }

    return descriptionString;
}

+ (void)setVerboseLoggingEnabled:(BOOL)loggingEnabled {
    verboseLoggingEnabled = loggingEnabled;
}

+ (BOOL)isVerboseLoggingEnabled {
    return verboseLoggingEnabled;
}

#pragma mark -
#pragma mark Internal API

+ (BOOL)routeURL:(NSURL *)URL withController:(JLRoutes *)routesController {
    return [self routeURL:URL withController:routesController parameters:nil executeBlock:YES];
}

+ (BOOL)routeURL:(NSURL *)URL withController:(JLRoutes *)routesController parameters:(NSDictionary *)parameters {
    return [self routeURL:URL withController:routesController parameters:parameters executeBlock:YES];
}

+ (BOOL)routeURL:(NSURL *)URL withController:(JLRoutes *)routesController parameters:(NSDictionary *)parameters executeBlock:(BOOL)executeBlock {
    [self verboseLogWithFormat:@"Trying to route URL %@", URL];
    BOOL didRoute = NO;
    NSArray *routes = routesController.routes;
    NSDictionary *queryParameters = [URL.query JLRoutes_URLParameterDictionary];
    [self verboseLogWithFormat:@"Parsed query parameters: %@", queryParameters];

    NSDictionary *fragmentParameters = [URL.fragment JLRoutes_URLParameterDictionary];
    [self verboseLogWithFormat:@"Parsed fragment parameters: %@", fragmentParameters];

    NSDictionary *fragmentQueryParameters = [URL.JLRoutes_fragmentQuery JLRoutes_URLParameterDictionary];
    [self verboseLogWithFormat:@"Parsed fragment query parameters: %@", fragmentParameters];

    // break the URL down into path components and filter out any leading/trailing slashes from it
    NSPredicate *filterSlashesPredicate = [NSPredicate predicateWithFormat:@"NOT SELF like '/'"];
    NSArray *pathComponents = [(URL.pathComponents ?: @[]) filteredArrayUsingPredicate:filterSlashesPredicate];
    NSArray *fragmentComponents = [(URL.JLRoutes_fragmentPathComponents ?: @[]) filteredArrayUsingPredicate:filterSlashesPredicate];

    if ([URL.host rangeOfString:@"."].location == NSNotFound && ![URL.host isEqualToString:@"localhost"]) {
        // For backward compatibility, handle scheme://path/to/resource as if path was part of the path
        pathComponents = [@[URL.host] arrayByAddingObjectsFromArray:pathComponents];
    }

    [self verboseLogWithFormat:@"URL path components: %@", pathComponents];

    [self verboseLogWithFormat:@"URL fragment components: %@", fragmentComponents];

    for (_JLRoute *route in routes) {
        NSDictionary *matchParameters = [route parametersForURL:URL pathComponents:pathComponents fragmentComponents:fragmentComponents];
        if (matchParameters) {
            [self verboseLogWithFormat:@"Successfully matched %@", route];
            if (!executeBlock) {
                return YES;
            }

            // add the URL parameters
            NSMutableDictionary *finalParameters = [NSMutableDictionary dictionary];

            // in increasing order of precedence: query, fragment, route, builtin
            [finalParameters addEntriesFromDictionary:queryParameters];
            if (route.matchFragmentComponents) {
                [finalParameters addEntriesFromDictionary:fragmentQueryParameters];
            } else {
                [finalParameters addEntriesFromDictionary:fragmentParameters];
            }
            [finalParameters addEntriesFromDictionary:matchParameters];
            [finalParameters addEntriesFromDictionary:parameters];
            finalParameters[kJLRoutePatternKey] = route.pattern;
            finalParameters[kJLRouteURLKey] = URL;
            __strong __typeof(route.parentRoutesController) strongParentRoutesController = route.parentRoutesController;
            finalParameters[kJLRouteNamespaceKey] = strongParentRoutesController.namespaceKey ?: [NSNull null];

            [self verboseLogWithFormat:@"Final parameters are %@", finalParameters];
            didRoute = route.block(finalParameters);
            if (didRoute) {
                break;
            }
        }
    }

    if (!didRoute) {
        [self verboseLogWithFormat:@"Could not find a matching route, returning NO"];
    }

    // if we couldn't find a match and this routes controller specifies to fallback and its also not the global routes controller, then...
    if (!didRoute && routesController.shouldFallbackToGlobalRoutes && ![routesController isGlobalRoutesController]) {
        [self verboseLogWithFormat:@"Falling back to global routes..."];
        didRoute = [self routeURL:URL withController:[self globalRoutes] parameters:parameters executeBlock:executeBlock];
    }

    // if, after everything, we did not route anything and we have an unmatched URL handler, then call it
    if (!didRoute && routesController.unmatchedURLHandler) {
        routesController.unmatchedURLHandler(routesController, URL, parameters);
    }

    return didRoute;
}

- (BOOL)isGlobalRoutesController {
    return [self.namespaceKey isEqualToString:kJLRoutesGlobalNamespaceKey];
}

+ (void)verboseLogWithFormat:(NSString *)format, ... {
    if (verboseLoggingEnabled && format) {
        va_list argsList;
        va_start(argsList, format);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat-nonliteral"
        NSString *formattedLogMessage = [[NSString alloc] initWithFormat:format arguments:argsList];
#pragma clang diagnostic pop

        va_end(argsList);
        NSLog(@"[JLRoutes]: %@", formattedLogMessage);
    }
}

#pragma mark -
#pragma mark Subscripting

- (void)setObject:(id)handlerBlock forKeyedSubscript:(NSString *)routePatten {
    [self addRoute:routePatten handler:handlerBlock];
}

@end


text:
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.7
// See http://java.sun.com/xml/jaxb
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2017.07.24 at 05:36:05 PM EEST
//

package lt.registrucentras.esaskaita.service.invoice.ubl.sig;

import java.io.Serializable;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlID;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.CollapsedStringAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import com.google.common.base.Objects;

/**
 *
Java class for ReferenceType complex type.
 *
 *
The following schema fragment specifies the expected content contained within this class.
 *
 *

 * <complexType name="ReferenceType">
 *   <complexContent>
 *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       <sequence>
 *         <element ref="{http://www.w3.org/2000/09/xmldsig#}Transforms" minOccurs="0"/>
 *         <element ref="{http://www.w3.org/2000/09/xmldsig#}DigestMethod"/>
 *         <element ref="{http://www.w3.org/2000/09/xmldsig#}DigestValue"/>
 *       </sequence>
 *       <attribute name="Id" type="{http://www.w3.org/2001/XMLSchema}ID" />
 *       <attribute name="URI" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
 *       <attribute name="Type" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
 *     </restriction>
 *   </complexContent>
 * </complexType>
 *

 *
 *
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "ReferenceType", propOrder = {
    "transforms",
    "digestMethod",
    "digestValue"
})
public class ReferenceType implements Serializable
{

    private final static long serialVersionUID = 1L;
    @XmlElement(name = "Transforms")
    protected TransformsType transforms;
    @XmlElement(name = "DigestMethod", required = true)
    protected DigestMethodType digestMethod;
    @XmlElement(name = "DigestValue", required = true)
    protected byte[] digestValue;
    @XmlAttribute(name = "Id")
    @XmlJavaTypeAdapter(CollapsedStringAdapter.class)
    @XmlID
    @XmlSchemaType(name = "ID")
    protected String id;
    @XmlAttribute(name = "URI")
    @XmlSchemaType(name = "anyURI")
    protected String uri;
    @XmlAttribute(name = "Type")
    @XmlSchemaType(name = "anyURI")
    protected String type;

    /**
     * Default no-arg constructor
     *
     */
    public ReferenceType() {
        super();
    }

    /**
     * Fully-initialising value constructor
     *
     */
    public ReferenceType(final TransformsType transforms, final DigestMethodType digestMethod, final byte[] digestValue, final String id, final String uri, final String type) {
        this.transforms = transforms;
        this.digestMethod = digestMethod;
        this.digestValue = digestValue;
        this.id = id;
        this.uri = uri;
        this.type = type;
    }

    /**
     * Gets the value of the transforms property.
     *
     * @return
     *     possible object is
     *     {@link TransformsType }
     *
     */
    public TransformsType getTransforms() {
        return transforms;
    }

    /**
     * Sets the value of the transforms property.
     *
     * @param value
     *     allowed object is
     *     {@link TransformsType }
     *
     */
    public void setTransforms(TransformsType value) {
        this.transforms = value;
    }

    /**
     * Gets the value of the digestMethod property.
     *
     * @return
     *     possible object is
     *     {@link DigestMethodType }
     *
     */
    public DigestMethodType getDigestMethod() {
        return digestMethod;
    }

    /**
     * Sets the value of the digestMethod property.
     *
     * @param value
     *     allowed object is
     *     {@link DigestMethodType }
     *
     */
    public void setDigestMethod(DigestMethodType value) {
        this.digestMethod = value;
    }

    /**
     * Gets the value of the digestValue property.
     *
     * @return
     *     possible object is
     *     byte[]
     */
    public byte[] getDigestValue() {
        return digestValue;
    }

    /**
     * Sets the value of the digestValue property.
     *
     * @param value
     *     allowed object is
     *     byte[]
     */
    public void setDigestValue(byte[] value) {
        this.digestValue = value;
    }

    /**
     * Gets the value of the id property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    public String getId() {
        return id;
    }

    /**
     * Sets the value of the id property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setId(String value) {
        this.id = value;
    }

    /**
     * Gets the value of the uri property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    public String getURI() {
        return uri;
    }

    /**
     * Sets the value of the uri property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setURI(String value) {
        this.uri = value;
    }

    /**
     * Gets the value of the type property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    public String getType() {
        return type;
    }

    /**
     * Sets the value of the type property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setType(String value) {
        this.type = value;
    }

    public ReferenceType withTransforms(TransformsType value) {
        setTransforms(value);
        return this;
    }

    public ReferenceType withDigestMethod(DigestMethodType value) {
        setDigestMethod(value);
        return this;
    }

    public ReferenceType withDigestValue(byte[] value) {
        setDigestValue(value);
        return this;
    }

    public ReferenceType withId(String value) {
        setId(value);
        return this;
    }

    public ReferenceType withURI(String value) {
        setURI(value);
        return this;
    }

    public ReferenceType withType(String value) {
        setType(value);
        return this;
    }

    @Override
    public String toString() {
        return Objects.toStringHelper(this).add("transforms", transforms).add("digestMethod", digestMethod).add("digestValue", digestValue).add("id", id).add("uri", uri).add("type", type).toString();
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(transforms, digestMethod, digestValue, id, uri, type);
    }

    @Override
    public boolean equals(Object other) {
        if (this == other) {
            return true;
        }
        if (other == null) {
            return false;
        }
        if (getClass()!= other.getClass()) {
            return false;
        }
        final ReferenceType o = ((ReferenceType) other);
        return (((((Objects.equal(transforms, o.transforms)&&Objects.equal(digestMethod, o.digestMethod))&&Objects.equal(digestValue, o.digestValue))&&Objects.equal(id, o.id))&&Objects.equal(uri, o.uri))&&Objects.equal(type, o.type));
    }

}


text:
==============
Data Structure
==============

The core data structure of mBuild is illustrated below. The primary building
blocks in an mBuild hierarchy inherit from the ``Compound`` class.
``Compounds`` maintain an ordered set of ``children`` which are other
``Compounds``.  In addition, an independent, ordered dictionary of ``labels``
is maintained through which users can reference any other ``Compound`` in the
hierarchy via descriptive strings.  Every ``Compound`` knows its parent
``Compound``, one step up in the hierarchy, and knows which ``Compounds``
reference it in their ``labels``.  ``Ports`` are a special type of ``Compound``
which are used internally to connect different ``Compounds`` using the
equivalence transformations described below.

``Compounds`` at the bottom of an mBuild hierarchy, the leafs of the tree, are
referred to as ``Particles`` and can be instantiated as
``foo = mb.Particle(name='bar')``. Note however, that this merely serves to
illustrate that this ``Compound`` is at the bottom of the hierarchy;
``Particle`` is just an alias for ``Compound`` which can be used to clarify
the intended role of an object you are creating. The method
``Compound.particles()`` traverses the hierarchy to the bottom and yields
those ``Compounds``. ``Compound.root()`` returns the compound at the top of
the hierarchy.

Compound
--------

.. autoclass:: mbuild.compound.Compound
    :members:

Port
----

.. autoclass:: mbuild.port.Port
    :members:


text:
using System;
using System.Collections.Generic;

namespace Csfeed.RetainedUI
{
	public enum Orientation
	{
		Horizontal,
		Vertical
	}

	public class MultiOrdered : Component
	{
		public List<Component> Children = new List<Component>();
		public Orientation Orientation = Orientation.Vertical;

		public override bool ResizableW { get { return false; } }
		public override bool ResizableH { get { return false; } }

		public override void Layout()
		{
			int accumPri = 0;
			int maxSnd = 0;

			RUI.PrepChildren(this, Children);

			foreach (var com in Children) {
				if (Orientation == Orientation.Horizontal) {
					com.X = X + accumPri;
					com.Y = Y;
					accumPri += com.W;
					maxSnd = (maxSnd < com.H) ? com.H : maxSnd;
				} else if (Orientation == Orientation.Vertical) {
					com.X = X;
					com.Y = Y + accumPri;
					accumPri += com.H;
					maxSnd = (maxSnd < com.W) ? com.W : maxSnd;
				}
			}

			W = (Orientation == Orientation.Horizontal) ? accumPri : maxSnd;
			H = (Orientation == Orientation.Horizontal) ? maxSnd : accumPri;

			// consider case of Multi inside Multi -> need to layout again (to update subchildren X, Y)
			RUI.PrepChildren(this, Children);
		}

		public override void Render(Painter painter)
		{
			RUI.RenderChildren(this, Children);
		}
	}
}


text:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>br.unicamp.ic.lsd.mercurius</groupId>
	<artifactId>product-mgr-spec</artifactId>
	<packaging>jar</packaging>

	<name>Product Manager Specification</name>

	<parent>
		<groupId>br.unicamp.ic.lsd.mercurius</groupId>
		<version>1.3</version>
		<artifactId>product-mgr</artifactId>
	</parent>

	<dependencies>
		<dependency>
			<groupId>br.unicamp.ic.lsd.mercurius</groupId>
			<artifactId>datatype</artifactId>
			<optional>true</optional>
		</dependency>

		<dependency>
			<groupId>br.unicamp.ic.lsd.mercurius</groupId>
			<artifactId>persistence-spec</artifactId>
			<optional>true</optional>
		</dependency>

		<dependency>
			<groupId>br.unicamp.ic.lsd.mercurius</groupId>
			<artifactId>category-mgr-spec</artifactId>
			<optional>true</optional>
		</dependency>

		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjrt</artifactId>
			<optional>true</optional>
		</dependency>

		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.codehaus.mojo</groupId>
				<artifactId>aspectj-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>