text:
/**
 * Used by dataTables (views/dataTables.html)
 * This script is in Static to allow caching
 * Dynamic constants (e.g. Internationalised strings) are set in server-generated script
 */

var oDataTable = new Array();
var fnInitDataTable;

var tableCnt = 1;
var tableId = new Array();
var myList = new Array();

function toggleDiv(divId) {
   $('#display' + divId).toggle();
   $('#full' + divId).toggle();
}

function hideSubRows(groupid){
    var sublevel = '.sublevel' + groupid.substr(6);
    $(sublevel).each(function (){
        obj = $(this)
        if (obj.hasClass('group') && obj.is(':visible')){
            // Get the group_xxx class
            var classList = obj.attr('class').split(/\s+/);
            var objGroupid = '';
            $.each( classList, function(index, item){
                if (item.substr(0, 6) == 'group_'){
                    objGroupid = item;
                }
            });
            hideSubRows(objGroupid);
        }
    });
    $(sublevel).hide();
    // Close all the arrows
    $('.arrow_e' + groupid).show();
    $('.arrow_s' + groupid).hide();
    // Remove any active row class
    $('.' + groupid).removeClass('activeRow');
}

function showSubRows(groupid){
    var sublevel = '.sublevel' + groupid.substr(6);
    $(sublevel).show();
    // Open the arrow
    $('.arrow_e' + groupid).hide();
    $('.arrow_s' + groupid).show();
    // Add the active row class
    $('.' + groupid).addClass('activeRow');
    // If this has opened groups then open the first row in the group
    var firstObj = $(sublevel + ':first')
    if (firstObj.hasClass('collapsable')){
        var classList = firstObj.attr('class').split(/\s+/);
        $.each( classList, function(index, groupLevel){
            if (groupLevel.substr(0, 6) == 'group_'){
                showSubRows(groupLevel);
            }
        });
    }
}

function toggleRow(groupid){
    var sublevel = '.sublevel' + groupid.substr(6);
    if ($(sublevel).is(':visible')){
        // Close all sublevels and change the icon to collapsed
        hideSubRows(groupid);
        $(sublevel).hide();
        $('#' + groupid + '_in').show();
        $('#' + groupid + '_out').hide();
    } else {
        // Open the immediate sublevel and change the icon to expanded
        $(sublevel).show();
        $('#' + groupid + '_in').hide();
        $('#' + groupid + '_out').show();
    }
}

/********************************************************************/
/* This function can be called by other scripts to attach the
/* accordion functionality to the row, not just the icon, as follows:
/*
/* $('.collapsable').click(function(){thisAccordionRow(0,this);});
/*
/********************************************************************/
function thisAccordionRow(t, obj){
    var level = '';
    var groupid = '';
    var classList = $(obj).attr('class').split(/\s+/);
    $.each( classList, function(index, rootClass){
        if (rootClass.substr(0, 6) == 'level_'){
            level = rootClass;
        }
        if (rootClass.substr(0, 6) == 'group_'){
            groupid = rootClass;
        }
    });
    accordionRow(t, level, groupid);
}

function accordionRow(t, level, groupid){
    /******************************************************************/
    /* Close all rows with a level higher than then level passed in   */
    /******************************************************************/
    // Get the level being opened
    var lvlOpened = level.substr(6);
    // Get a list of levels from the table
    var classList = $(tableId[t]).attr('class').split(/\s+/);
    $.each( classList, function(index, groupLevel){
        if (groupLevel.substr(0, 6) == 'level_'){
            var lvlNo = groupLevel.substr(6);
            if (lvlNo >= lvlOpened){
                // find all groups at this level which are active
                // and then close all opened rows
                var activeRow = $('.activeRow.' + groupLevel);
                $.each(activeRow , function(index, itemClass){
                    var classList2 = $(itemClass).attr('class').split(/\s+/);
                    $.each( classList2, function(index, rowClass){
                        if (rowClass.substr(0, 6) == 'group_'){
                            //var sublevel = 'sublevel' + item.substr(6);
                            hideSubRows(rowClass);
                        }
                    });
                }); // looping through each active row at the given level
            }
        }
    }); // close looping through the tables levels
    /******************************************************************/
    /* Open the items that are members of the clicked group           */
    /******************************************************************/
    showSubRows(groupid);
}

function tableIdReverse(id) {
    for (var t=0; t < tableCnt; t++) {
        if (tableId[t] == id) {
            return t;
        }
    }
    return -1
}
$(document).ready(function() {
    /* dataTables handling */
    // Create an array for the column settings (this is required, otherwise the column widths don't autosize)
    var ColumnSettings = new Array();
    if (S3.dataTables.id) {
        tableCnt = S3.dataTables.id.length;
        for (var t=0; t < tableCnt; t++) {
            id = '#' + S3.dataTables.id[t];
            tableId[t] = id;
            myList[t] = $(id);
        }
    } else {
        id = '#list';
        tableId[0] = id;
        myList[0] = $(id);
    }

    // The configuration details for each table
    var aoTableConfig = new Array(); // Passed in from the server
    var sDom = new Array();
    var sPagination = new Array();
    var sPaginationType = new Array();
    var fnAjaxCallback = new Array();
    var fnActionCallBacks = new Array();
    var oGroupColumns = new Array();
    var aHiddenFieldsID = new Array();
    var selectedRows = new Array();
    var selectionMode = new Array();
    var cache = new Array();
    var textDisplay = new Array();

    for (var t=0; t < tableCnt; t++) {
        // First get the config details for each table
        aoTableConfig[t] = jQuery.parseJSON($(tableId[t] + '_configurations').val());
        sDom[t] = aoTableConfig[t]['sDom'];
        sPaginationType[t] = aoTableConfig[t]['paginationType'];

        fnActionCallBacks[t] = new Array();
        var ColumnCount = myList[t].find('thead tr').first().children().length;

        ColumnSettings[t] = new Array();
        // Buffer the array so that the default settings are preserved for the rest of the columns
        for (var c=0; c < ColumnCount; c++) {
            ColumnSettings[t][c] = null;
        }
        if (aoTableConfig[t]['rowActions'].length < 1) {
            if (S3.dataTables.Actions) {
                aoTableConfig[t]['rowActions'] = S3.dataTables.Actions;
            }
        }
        if (aoTableConfig[t]['rowActions'].length > 0) {
            ColumnSettings[t][aoTableConfig[t]['actionCol']] = {
                'sTitle': ' ',
                'bSortable': false
            }
        }
        if (aoTableConfig[t]['bulkActions']) {
            ColumnSettings[t][aoTableConfig[t]['bulkCol']] = {
                'sTitle': '<select id="bulk_select_options"><option></option><option id="modeSelectionAll">Select All</option><option id="modeSelectionNone">Deselect All</option></select>',
                'bSortable': false
            }
        }
        textDisplay[t] = [aoTableConfig[t]['textMaxLength'],aoTableConfig[t]['textShrinkLength']];

        cache[t] = { iCacheLower: -1 };
        if (aoTableConfig[t]['group'].length > 0) {
            groupList = aoTableConfig[t]['group'];
            var gList = [];
            for (var gCnt=0; gCnt<groupList.length; gCnt++) {
                gList.push(groupList[gCnt][0]);
            }
            oGroupColumns[t] = { 'bVisible': false, 'aTargets': gList }
        } else {
            oGroupColumns[t] = { 'bVisible': false, 'aTargets': [ ] }
        }

        /* Code to calculate the bulk action buttons

           They will actually be placed on the dataTable inside the fnHeaderCallback
           It is necessary to do this inside of the callback because the dataTable().fnDraw
           that these buttons trigger will remove the on click binding. */
        if (aoTableConfig[t]['bulkActions']) {
            var bulk_submit = '';
            for (var i=0, iLen=aoTableConfig[t]['bulkActions'].length; i < iLen; i++) {
                bulk_submit += '<input type="submit" id="submitSelection"  name="' + aoTableConfig[t]['bulkActions'][i] + '" value="' + aoTableConfig[t]['bulkActions'][i] + '"> ';
            }
            var bulk_action_controls = '<span class="dataTable-action">' + bulk_submit + '<span>';
            // Add hidden fields to the form to record what has been selected
            bulkSelectionID = tableId[t] + '_dataTable_bulkSelection';
            selected =  jQuery.parseJSON($(bulkSelectionID).val())
            if (selected == null)
                selected = [];
            selectedRows[t] = selected;
            selectionMode[t] = 'Inclusive';
            if ($(tableId[t] + '_dataTable_bulkSelectAll').val()) {
                selectionMode[t] = 'Exclusive';
            }
            aHiddenFieldsID[t] = [tableId[t] + '_dataTable_bulkMode',
                                  tableId[t] + '_dataTable_bulkSelection'
                                  ];
        }

        // The call back used to manage the paganation
        if (aoTableConfig[t]['pagination'] == 'true') {
            // Cache the pages to reduce server-side calls
            var bServerSide = true;
            var bProcessing = true;
            var iDisplayLength = aoTableConfig[t]['displayLength'];
            var aoData = [{name: 'iDisplayLength', value: iDisplayLength},
                          {name: 'iDisplayStart', value: 0},
                          {name: 'sEcho', value: 1}]

            function fnSetKey( aoData, sKey, mValue ) {
                for (var i=0, iLen=aoData.length; i < iLen; i++) {
                    if ( aoData[i].name == sKey ) {
                        aoData[i].value = mValue;
                    }
                }
            }
            function fnGetKey( aoData, sKey ) {
                for (var i=0, iLen=aoData.length; i < iLen; i++) {
                    if ( aoData[i].name == sKey ) {
                        return aoData[i].value;
                    }
                }
                return null;
            }
            function fnDataTablesPipeline ( sSource, aoData, fnCallback ) {
                var table = '#' + this[0].id;
                var t = tableIdReverse(table);
                var iRequestLength = fnGetKey(aoData, 'iDisplayLength');
                // Adjust the pipe size depending on the page size
                if (iRequestLength == iDisplayLength) {
                    var iPipe = 6;
                } else if (iRequestLength > 49 || iRequestLength == -1) {
                    var iPipe = 2;
                } else {
                    // iRequestLength == 25
                    var iPipe = 4;
                }
                var bNeedServer = false;
                var sEcho = fnGetKey(aoData, 'sEcho');
                var iRequestStart = fnGetKey(aoData, 'iDisplayStart');
                var iRequestEnd = iRequestStart + iRequestLength;
                var oCache = cache[t];
                oCache.iDisplayStart = iRequestStart;
                // outside pipeline?
                if ( oCache.iCacheUpper !== -1 && /* If Display All oCache.iCacheUpper == -1 */
                     ( iRequestLength == -1 || oCache.iCacheLower < 0 || iRequestStart < oCache.iCacheLower || iRequestEnd > oCache.iCacheUpper )
                    ) {
                    bNeedServer = true;
                }

                // sorting etc changed?
                if ( oCache.lastRequest && !bNeedServer ) {
                    for (var i=0, iLen=aoData.length; i < iLen; i++) {
                        if ( aoData[i].name != 'iDisplayStart' && aoData[i].name != 'iDisplayLength' && aoData[i].name != 'sEcho' ) {
                            if ( aoData[i].value != oCache.lastRequest[i].value ) {
                                bNeedServer = true;
                                break;

                            }
                        }
                    }
                }
                // Store the request for checking next time around
                oCache.lastRequest = aoData.slice();
                if ( bNeedServer ) {
                    if (iRequestStart < oCache.iCacheLower) {
                        iRequestStart = iRequestStart - (iRequestLength * (iPipe - 1));
                        if ( iRequestStart < 0 ) {
                            iRequestStart = 0;
                        }
                    }
                    oCache.iCacheLower = iRequestStart;
                    oCache.iDisplayLength = fnGetKey( aoData, 'iDisplayLength' );
                    if (iRequestLength == -1) {
                        oCache.iCacheUpper = -1; // flag for all records are in Cache
                        fnSetKey( aoData, 'iDisplayStart', "None" ); // No Filter
                        fnSetKey( aoData, 'iDisplayLength', "None" );  // No Filter
                    } else {
                        oCache.iCacheUpper = iRequestStart + (iRequestLength * iPipe);
                        fnSetKey( aoData, 'iDisplayStart', iRequestStart );
                        fnSetKey( aoData, 'iDisplayLength', iRequestLength * iPipe );
                    }
                    $.getJSON(sSource, aoData, function (json) {
                        // Callback processing
                        oCache.lastJson = jQuery.extend(true, {}, json);
                        if ( oCache.iCacheLower != oCache.iDisplayStart ) {
                            json.aaData.splice( 0, oCache.iDisplayStart - oCache.iCacheLower );
                        }
                        if (oCache.iDisplayLength !== -1) {
                            json.aaData.splice( oCache.iDisplayLength, json.aaData.length );
                        }
                        fnCallback(json)
                    } );
                } else {
                    json = jQuery.extend(true, {}, oCache.lastJson);
                    json.sEcho = sEcho; // Update the echo for each response
                    if (iRequestLength !== -1) {
                        json.aaData.splice( 0, iRequestStart - oCache.iCacheLower );
                        json.aaData.splice( iRequestLength, json.aaData.length );
                    }
                    fnCallback(json);
                }
            }
            fnAjaxCallback[t] = fnDataTablesPipeline
            // end of pagination code
        } else {
            var bServerSide = false;
            var bProcessing = false;
            aoTableConfig[t]['ajaxUrl'] = null;
            function fnDataTablesPipeline ( url, data, callback ) {
                $.ajax( {
                    'url': url,
                    'data': data,
                    'success': callback,

                    'dataType': 'json',
                    'cache': false,
                    'error': function (xhr, error, thrown) {
                        if (error == 'parsererror') {
                            alert('DataTables warning: JSON data from server could not be parsed. ' +
                                  'This is caused by a JSON formatting error.');
                        }
                    }
                } );
            }
            fnAjaxCallback[t] = fnDataTablesPipeline

        } // end of no pagination code
    } // end of loop for each dataTable

    /*********************************************************************/
    /* Helper functions                                                  */
    /*********************************************************************/
    function createSubmitBtn(t) {
        if (aoTableConfig[t]['bulkActions']) {
            // Make sure that the details of the selected records are stored in the hidden fields
            $(aHiddenFieldsID[t][0]).val(selectionMode[t]);
            $(aHiddenFieldsID[t][1]).val(selectedRows[t].join(','));
            // Add the bulk action controls to the dataTable
            $('.dataTable-action').remove();
            $(bulk_action_controls).insertBefore('#bulk_select_options');
        }
    }

    function inList(id, list) {
    /* The selected items for bulk actions is held in the list parameter
       This function finds if the given id is in the list. */
        for (var cnt=0, lLen=list.length; cnt < lLen; cnt++) {
            if (id == list[cnt]) {
                return cnt;
            }
        }
        return -1;
    }

    function bindButtons(t) {
    /* This will bind the row action and the bulk action buttons to their callback function */
        if (aoTableConfig[t]['rowActions'].length > 0) {
            for (var i=0; i < fnActionCallBacks[t].length; i++){
                var currentID = '#' + fnActionCallBacks[t][i][0];
                $(currentID).unbind('click');
                $(currentID).bind('click', fnActionCallBacks[t][i][1]);
            }
        }
        if (aoTableConfig[t]['bulkActions']) {
            $('.bulkcheckbox').unbind('change');
            $('.bulkcheckbox').change( function(event){
                id = this.id.substr(6)
                var posn = inList(id, selectedRows[t])
                if (posn == -1) {
                    selectedRows[t].push(id);
                    posn = 0 // force the row to be selected
                } else {
                    selectedRows[t].splice(posn, 1);
                    posn = -1 // force the row to be deselected
                }
                row = $(this).parent().parent()
                setSelectionClass(t, row, posn);
            });
        }

    }

    function setSelectionClass(t, row, index){
    /* This function is used to show which rows have been selected for a bulk select action */
        if (selectionMode[t] == 'Inclusive') {
            $('#totalSelected').text(selected.length);
            if (index == -1) {
                $(row).removeClass('row_selected');
                $(".bulkcheckbox", row).attr('checked', false);
            } else {
                $(row).addClass('row_selected');
                $(".bulkcheckbox", row).attr('checked', true);
            }
        }
        if (selectionMode[t] == 'Exclusive') {
            $('#totalSelected').text(parseInt($('#totalAvaliable').text()) - selected.length);
            if (index == -1) {
                $(row).addClass('row_selected');
                $('.bulkcheckbox', row).attr('checked', true);
            } else {
                $(row).removeClass('row_selected');
                $('.bulkcheckbox', row).attr('checked', false);
            }
        }
        createSubmitBtn(t);
    }

    function setModeSelectionAll(event) {
        wrapper = $(this).parents('.dataTables_wrapper')[0].id
        selector = '#' + wrapper.substr(0, wrapper.length - 8);
        t = tableIdReverse(selector);
        selectionMode[t] = 'Exclusive';
        selectedRows[t] = [];
        oDataTable[t].fnDraw(false);
    }

    function setModeSelectionNone(event) {
        wrapper = $(this).parents('.dataTables_wrapper')[0].id;
        selector = '#' + wrapper.substr(0, wrapper.length - 8);
        t = tableIdReverse(selector);
        selectionMode[t] = 'Inclusive';
        selectedRows[t] = [];
        oDataTable[t].fnDraw(false);
    }

    function buildGroups(oSettings, t, group, groupTitles, level) {
        var shrink = aoTableConfig[t]['shrinkGroupedRows'] == 'individual';
        var accordion = aoTableConfig[t]['shrinkGroupedRows'] == 'accordion';
        var nTrs = $(tableId[t] + ' tbody tr');
        var iColspan = $(tableId[t] + ' thead tr')[0].getElementsByTagName('th').length;
        var sLastGroup = '';
        var groupCnt = 0;
        var dataCnt = 0;
        var levelClass = 'level_' + level;
        var sublevel = '';
        $(tableId[t]).addClass(levelClass);
        for (var i=0; i<nTrs.length; i++) {
            if ($(nTrs[i]).hasClass('group')) {
                // Calculate the sublevel which can be used for the next new group
                var classList = $(nTrs[i]).attr('class').split(/\s+/);
                $.each( classList, function(index, item){
                    if (item.substr(0, 6) == 'group_'){
                        sublevel = 'sublevel' + item.substr(6);
                    }
                });
                sLastGroup = '';
                continue;
            }
            var sGroup = oSettings.aoData[ oSettings.aiDisplay[dataCnt] ]._aData[group];
            if ( sGroup != sLastGroup ) {  // New group
                // Add an indentation of the grouping depth
                var levelDisplay = '';
                for (var lvl=1; lvl<level; lvl++) {
                    levelDisplay += "<div style='float:left; width:10px;'> </div>";
                }
                if (level > 1) { levelDisplay += "<div class='ui-icon ui-icon-play' style='float:left;'></div>"; }
                // Add the subtotal counts (if provided)
                var groupCount = '';
                if (groupTitles[sGroup]) {
                    groupCount = ' (' + groupTitles[sGroup] + ')';
                }
                // Create the new HTML elements
                var nGroup = document.createElement( 'tr' );
                nGroup.className = 'group';
                var nCell = document.createElement( 'td' );
                if (shrink || accordion) {
                    groupCnt++;
                    var groupClass = 'group_' + t + level + groupCnt;
                    $(nGroup).addClass('headerRow');
                    $(nGroup).addClass(groupClass);
                    $(nGroup).addClass(levelClass);
                    if (sublevel){
                        $(nGroup).addClass(sublevel);
                        $(nGroup).addClass('collapsable');
                    }
                    if (shrink) {
                        var iconin = '<a id="' + groupClass + '_in" href="javascript:toggleRow(\'' + groupClass + '\');" class="ui-icon ui-icon-arrowthick-1-e" style="float:right"></a>';
                        var iconout = '<a id="' + groupClass + '_out" href="javascript:toggleRow(\'' + groupClass + '\');" class="ui-icon ui-icon-arrowthick-1-s" style="float:right; display:none"></a>';
                    } else {
                        var iconin = '<a href="javascript:accordionRow(\'' + t + '\', \'' + levelClass + '\', \'' + groupClass + '\');" class="ui-icon ui-icon-arrowthick-1-e arrow_e'+groupClass+'" style="float:right"></a>';
                        var iconout = '<a href="javascript:accordionRow(\'' + t + '\', \'' + levelClass + '\', \'' + groupClass + '\');" class="ui-icon ui-icon-arrowthick-1-s arrow_s'+groupClass+'" style="float:right; display:none"></a>';
                    }
                    htmlText = sGroup + groupCount+ iconin + iconout;
                } else {
                    htmlText = sGroup + groupCount;
                }
                nCell.colSpan = iColspan;
                nCell.innerHTML = levelDisplay + htmlText;
                nGroup.appendChild( nCell );
                nTrs[i].parentNode.insertBefore( nGroup, nTrs[i] );
                sLastGroup = sGroup;
            } // end of processing for a new group
            dataCnt += 1;
            if (shrink || accordion) {
                // Hide the detail row
                $(nTrs[i]).hide();
            }
        } // end of loop for each row
    }

    for (var tcnt=0; tcnt < tableCnt; tcnt++) {
      initDataTable(myList[tcnt], tcnt, false);
      // Delay in milliseconds to prevent too many AJAX calls
      oDataTable[tcnt].fnSetFilteringDelay(450);
    } // end of loop through for each table

    function initDataTable(oTable, t, bReplace) {
      oDataTable[t] = $(oTable).dataTable({
        'bDestroy': bReplace,
        'sDom': sDom[t],
        'sPaginationType': sPaginationType[t],
        'bServerSide': bServerSide,
        'bAutoWidth' : false,
        'bFilter': aoTableConfig[t]['bFilter'] == 'true',
        'bSort': true,
        'bDeferRender': true,
        'aaSorting': aoTableConfig[t]['aaSort'],
        "aaSortingFixed": aoTableConfig[t]['group'],
        "aoColumnDefs": [ oGroupColumns[t] ],
        'aoColumns': ColumnSettings[t],
        'iDisplayLength': aoTableConfig[t]['displayLength'],
        'aLengthMenu': [[ 25, 50, -1], [ 25, 50, S3.i18n.all]],
        'bProcessing': bProcessing,
        'sAjaxSource': aoTableConfig[t]['ajaxUrl'],
        'fnServerData': fnAjaxCallback[t],
        'fnHeaderCallback' : function (nHead, aasData, iStart, iEnd, aiDisplay) {
            $('#modeSelectionAll').on('click', setModeSelectionAll);
            $('#modeSelectionNone').on('click', setModeSelectionNone);
        },
        'fnRowCallback': function( nRow, aData, iDisplayIndex ) {
            // Extract the id # from the link
            t = tableIdReverse(this.selector);
            var actionCol = aoTableConfig[t]['actionCol'];
            var re = />(.*)</i;
            var result = re.exec(aData[actionCol]);
            if (result == null) {
                var id = aData[actionCol];
            } else {
                var id = result[1];
            }
            // Set the action buttons in the id column for each row
            if (aoTableConfig[t]['rowActions'].length > 0 || aoTableConfig[t]['bulkActions']) {
                var Buttons = '';
                if (aoTableConfig[t]['rowActions'].length > 0) {
                    var Actions = aoTableConfig[t]['rowActions'];
                    // Loop through each action to build the button
                    for (var i=0; i < Actions.length; i++) {

                        $('th:eq(0)').css( { 'width': 'auto' } );

                        // Check if action is restricted to a subset of records
                        if ('restrict' in Actions[i]) {
                            if (inList(id, Actions[i].restrict) == -1) {
                                continue;
                            }
                        }
                        var c = Actions[i]._class;
                        var label = S3.Utf8.decode(Actions[i].label);
                        re = /%5Bid%5D/g;
                        if (Actions[i]._onclick) {
                            var oc = Actions[i]._onclick.replace(re, id);
                            Buttons = Buttons + '<a class="' + c + '" onclick="' + oc + '">' + label + '</a>' + ' ';
                        } else if (Actions[i]._jqclick) {
                            Buttons = Buttons + '<span class="' + c + '" id="' + id + '">' + label + '</span>' + ' ';
                            fnActionCallBacks[t].push([id, S3ActionCallBack]);
                        }else {
                            if (Actions[i].icon) {
                                label = '<img src="'+Actions[i].icon+'" alt="'+label+'" title="'+label+'">';
                            }
                            var url = Actions[i].url.replace(re, id);
                            Buttons = Buttons + '<a class="'+ c + '" href="' + url + '">' + label + '</a>' + ' ';
                        }
                    }
                }
                // Put the actions buttons in the actionCol
                if ((aoTableConfig[t]['group'].length > 0) && (aoTableConfig[t]['group'][0][0] < actionCol)){
                    actionCol -= 1;
                }
                $('td:eq(' + actionCol + ')', nRow).html( Buttons );
            }
            // Code to toggle the selection of the row
            if (aoTableConfig[t]['bulkActions']) {
                setSelectionClass(t, nRow, inList(id, selectedRows[t]));
            }
            styles = aoTableConfig[t]['rowStyles'];
            for (style in styles) {
                if (inList(id, styles[style]) > -1) {
                    $(nRow).addClass( style );
                }
            }
            // Code to condense any text that is longer than the display limits
            tdposn = 0;
            gList = [];
            if (aoTableConfig[t]['group'].length > 0) {
                groupList = aoTableConfig[t]['group'];
                var gList = [];
                for (var gCnt=0; gCnt<groupList.length; gCnt++) {
                    gList.push(groupList[gCnt][0]);
                }
            }
            for (var i=0; i<aData.length; i++) {
                // Ignore any columns used for groups
                if ($.inArray(i, gList) != -1) { continue; }
                // Ignore if the data starts with an html open tag
                if (aData[i][0] == '<') {
                    tdposn++;
                    continue;
                }
                if (aData[i].length > textDisplay[t][0]) {
                    uniqueid = '_' + t + iDisplayIndex + i;
                    icon = '<a href="javascript:toggleDiv(\''+uniqueid+'\');" class="ui-icon ui-icon-zoomin" style="float:right"></a>';
                    display = '<div id="display'+uniqueid+'">' + icon + aData[i].substr(0,textDisplay[t][1]) + "…</div>";
                    icon = '<a href="javascript:toggleDiv(\''+uniqueid+'\');" class="ui-icon ui-icon-zoomout" style="float:right"></a>';
                    display += '<div  style="display:none" id="full'+uniqueid+'">' + icon + aData[i] + "</div>";
                    $('td:eq(' + tdposn + ')', nRow).html( display );
                }
                tdposn++; // increment the count of the td tags (don't do this for groups)
            }
            return nRow;
        }, // end of fnRowCallback
        'fnDrawCallback': function(oSettings) {
            table = '#' + oSettings.nTable.id;
            t = tableIdReverse(table);
            bindButtons(t);
            if ( oSettings.aiDisplay.length == 0 ) {
                return;
            }
            if (aoTableConfig[t]['group'].length > 0) {
                groupList = aoTableConfig[t]['group'];
                for (var gCnt=0; gCnt<groupList.length; gCnt++) {
                    group = groupList[gCnt];
                    groupTitles = [];
                    if (aoTableConfig[t]['groupTitles'].length > gCnt) {
                        groupTitles = aoTableConfig[t]['groupTitles'][gCnt];
                    }
                    buildGroups(oSettings, t, group[0], groupTitles, gCnt + 1);
                }
                // Now loop through each row and add the subLevel controls for row collapsing
                var shrink = aoTableConfig[t]['shrinkGroupedRows'] == 'individual';
                var accordion = aoTableConfig[t]['shrinkGroupedRows'] == 'accordion';
                if (shrink || accordion) {
                    var nTrs = $(tableId[t] + ' tbody tr');
                    var sublevel = '';
                    for (var i=0; i<nTrs.length; i++) {
                        obj = $(nTrs[i]);
                        // If the row is a headerRow get the level
                        if (obj.hasClass('headerRow')){
                            var classList = obj.attr('class').split(/\s+/);
                            $.each( classList, function(index, item){
                                if (item.substr(0, 6) == 'group_'){
                                    sublevel = 'sublevel' + item.substr(6);
                                }
                            });
                        } else {
                            $(nTrs[i]).addClass(sublevel);
                            $(nTrs[i]).addClass('collapsable');
                        }
                    }
                    $('.collapsable').hide();
                    if (accordion) {
                        accordionRow(t, 'level_1', 'group_' + t + '11');
                    }
               } // end of collapsable rows
            }
            if (Math.ceil((oSettings.fnRecordsDisplay()) / oSettings._iDisplayLength) > 1)  {
                $(tableId[t] + '_paginate').css('display', "block");
            } else {
                $(tableId[t] + '_paginate').css('display', 'none');
            }
        }
      });
    } // end of initDataTable function

    // Allow dataTables to be initialised outside of this function.
    fnInitDataTable = initDataTable;

    if (S3.dataTables.Resize) {
        // Resize the Columns after hiding extra data
        $('.dataTable').dataTable().fnAdjustColumnSizing();
    }

    /* Messaging */
    /* Taken a different route for now, although this might come back to open form dynamically
       - change views/_search.html if-so
    $('#msg_datatables-btn').click( function(evt) {
        // @ToDo: Display the Compose form

        // @ToDo: Focus on form
        //$('#msg_log_message').focus();

        evt.preventDefault();
    }); */
});

function s3FormatRequest(representation, tableid, url){
    t = tableIdReverse('#' + tableid);
    dt = oDataTable[t];
    oSetting = dt.dataTableSettings[t];
    if (oSetting) {
        argData = 'id=' + tableid;
        serverFilterArgs = $('#' + tableid + '_dataTable_filter');
        if (serverFilterArgs.val() != '') {
            argData += '&sFilter=' + serverFilterArgs.val();
        }
        argData += '&sSearch=' + oSetting.oPreviousSearch['sSearch'];
        sSort = Array();
        aaSort = ( oSetting.aaSortingFixed !== null ) ?
                 oSetting.aaSortingFixed.concat( oSetting.aaSorting ) :
                 oSetting.aaSorting.slice();
        argData += '&iSortingCols=' + aaSort.length;
        for ( i=0 ; i<aaSort.length ; i++ ){
                argData += '&iSortCol_' + i + '=' + aaSort[i][0];
                argData += '&sSortDir_' + i + '=' +aaSort[i][1];
        }
        url = url + '.' + representation + '?' + argData;
    } else {
        url =  url + '.' + representation;
    }
    window.location = url;
}

function s3_gis_search_layer_loadend(event) {
    // Search results have Loaded
    var layer = event.object;
    // Zoom to Bounds
    var bounds = layer.getDataExtent();
    if (bounds) {
        map.zoomToExtent(bounds);
    }
    // Re-enable Clustering
    Ext.iterate(layer.strategies, function(key, val, obj) {
        if (key.CLASS_NAME == 'OpenLayers.Strategy.AttributeCluster') {
            layer.strategies[val].activate();
        }
    });
    // Disable this event
    layer.events.un({
        'loadend': s3_gis_search_layer_loadend
    });
}

Ext.onReady(function(){
    // Are there any map Buttons?
    var s3_dataTables_mapButton = Ext.get('gis_datatables_map-btn');
    if (s3_dataTables_mapButton) {
        s3_dataTables_mapButton.on('click', function() {
            // Load the search results layer
            Ext.iterate(map.layers, function(key, val, obj) {
                if (key.s3_layer_id == 'search_results') {
                    var layer = map.layers[val];
                    // Set a new event when the layer is loaded
                    layer.events.on({
                        'loadend': s3_gis_search_layer_loadend
                    });
                    // Disable Clustering to get correct bounds
                    Ext.iterate(layer.strategies, function(key, val, obj) {
                        if (key.CLASS_NAME == 'OpenLayers.Strategy.AttributeCluster') {
                            layer.strategies[val].deactivate();
                        }
                    });
                    layer.setVisibility(true);
                }
            });
            if (S3.gis.polygonButton) {
                // Disable the polygon control
                S3.gis.polygonButton.disable();
            }
            S3.gis.mapWin.show();
            // Disable the crosshair on the Map Selector
            $('.olMapViewport').removeClass('crosshair');
            // Set the Tab to show as active
            $('#gis_datatables_map-btn').parent().addClass('tab_here');
            // Deactivate the list Tab
            $('#gis_datatables_list_tab').parent().removeClass('tab_here').addClass('tab_other');
            // Set to revert if Map closed
            $('div.x-tool-close').click( function(evt) {
                // Set the Tab to show as inactive
                $('#gis_datatables_map-btn').parent().removeClass('tab_here').addClass('tab_other');
                // Activate the list Tab
                $('#gis_datatables_list_tab').parent().removeClass('tab_other').addClass('tab_here');
            });
            // @ToDo: Close Map Window & revert if Tab clicked
        });
    }
    var s3_search_mapButton = Ext.get('gis_search_map-btn');
    if (s3_search_mapButton) {
        s3_search_mapButton.on('click', function() {
            // Enable the polygon control
            S3.gis.polygonButton.enable();
            // @ToDo: Set appropriate Bounds
            // Default to current gis_config
            // If there is an Options widget for Lx, then see if that is set & use this
            S3.gis.mapWin.show();
            // Enable the crosshair on the Map Selector
            $('.olMapViewport').addClass('crosshair');
        });
    }
});
// =========================================================================


text:
module Testify
  module Middleware
    include Aliasable

    # By default, Testify middleware is initialized with only the next app on
    # the stack.  If you override this in a way that changes the signature, you
    # may also need to override Runner.construct_app_stack.
    #
    def initialize(app)
      @app = app
    end

    # By default, the middleware base class just calls the next app on the
    # stack - you will almost certainly want to override this method.
    #
    def call(env)
      @app.call(env)
    end
  end
end

redpajama_set_name: RedPajamaGithub


text:
class Order < ActiveRecord::Base
  belongs_to :user
  # after_action :generate_token, :only => :index
  # scope :completed, -> { where("token != ? OR token != ?", "", nil) }

  def self.backers
    Order.all.where("status = ?", true).uniq.pluck(:user_id).count
  end

  def self.revenue
     Order.all.where(:status => true).sum(:price).to_f
  end

  def self.goal
    Settings.project_goal
  end

  def self.percent
    (Order.revenue.to_f / Order.goal.to_f) * 100.to_f
  end
end


text:
require 'zip'

class Zipgenotypingfiles
  include Sidekiq::Worker
  sidekiq_options queue: :zipgenotyping, retry: 5, unique: true

  def perform(phenotype_id, variation, target_address)
    @user_phenotypes = UserPhenotype
      .where(phenotype_id: phenotype_id)
      .search(variation)
    @genotyping_files = []
    @user_phenotypes.each do |up|
      @user = User.find_by_id(up.user_id)
      if @user.genotypes.length != 0
        @user.genotypes.each do |g|
          @genotyping_files << g
        end
      end
    end

    if @genotyping_files != []
      @time = Time.now.to_s.gsub(':', '_')
      if File.exist?(::Rails.root.to_s + '/public/data/zip/' + phenotype_id.to_s + '.' + @time.to_s.gsub(' ', '_') + '.zip') == false
        Zip::File.open(::Rails.root.to_s + '/public/data/zip/' + phenotype_id.to_s + '.' + @time.to_s.gsub(' ', '_') + '.zip', Zip::File::CREATE) do |zipfile|
          @genotyping_files.each do |gen_file|
            zipfile.add('user' + gen_file.user_id.to_s + '_file' + gen_file.id.to_s + '_yearofbirth' + gen_file.user.yearofbirth + '_sex' + gen_file.user.sex + '.' + gen_file.filetype + '.txt', ::Rails.root.to_s + '/public/data/' + gen_file.fs_filename)
          end
        end
      end
      system('chmod 777 ' + ::Rails.root.to_s + '/public/data/zip/' + phenotype_id.to_s + '.' + @time.to_s.gsub(' ', '_') + '.zip')
      UserMailer.genotyping_results(target_address, '/data/zip/' + phenotype_id.to_s + '.' + @time.to_s.gsub(' ', '_') + '.zip', Phenotype.find_by_id(phenotype_id).characteristic, variation).deliver_later
    else
      UserMailer.no_genotyping_results(target_address, Phenotype.find_by_id(phenotype_id).characteristic, variation).deliver_later
    end
  end
end


text:
package org.robolectric.res;

import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ResName {
  private static final Pattern FQN_PATTERN = Pattern.compile("^([^:]*):([^/]+)/(.+)$");
  private static final int NAMESPACE = 1;
  private static final int TYPE = 2;
  private static final int NAME = 3;

  public final @NotNull String packageName;
  public final @NotNull String type;
  public final @NotNull String name;

  public final int hashCode;

  public ResName(@NotNull String packageName, @NotNull String type, @NotNull String name) {
    this.packageName = packageName;
    this.type = type;
    this.name = name.indexOf('.') != -1 ? name.replace('.', '_').trim() : name.trim();

    hashCode = computeHashCode();
  }

  public ResName(@NotNull String fullyQualifiedName) {
    Matcher matcher = FQN_PATTERN.matcher(fullyQualifiedName.trim());
    if (!matcher.find()) {
      throw new IllegalStateException("\"" + fullyQualifiedName + "\" is not fully qualified");
    }
    packageName = matcher.group(NAMESPACE);
    type = matcher.group(TYPE);
    String nameStr = matcher.group(NAME);
    name = nameStr.indexOf('.') != -1 ? nameStr.replace('.', '_') : nameStr;

    hashCode = computeHashCode();
    if (packageName.equals("xmlns")) throw new IllegalStateException("\"" + fullyQualifiedName + "\" unexpected");
  }

  /**
   * Returns null if the resource could not be qualified.
   */
  public static String qualifyResourceName(@NotNull String possiblyQualifiedResourceName, String defaultPackageName, String defaultType) {
    ResName resName = qualifyResName(possiblyQualifiedResourceName, defaultPackageName, defaultType);
    return resName != null ? resName.getFullyQualifiedName() : null;
  }

  public static ResName qualifyResName(@NotNull String possiblyQualifiedResourceName, ResName defaults) {
    return qualifyResName(possiblyQualifiedResourceName, defaults.packageName, defaults.type);
  }

  public static ResName qualifyResName(@NotNull String possiblyQualifiedResourceName, String defaultPackageName, String defaultType) {
    int indexOfColon = possiblyQualifiedResourceName.indexOf(':');
    int indexOfSlash = possiblyQualifiedResourceName.indexOf('/');
    String type = null;
    String packageName = null;
    String name = possiblyQualifiedResourceName;
    if (indexOfColon > indexOfSlash) {
      if (indexOfSlash > 0) {
        type = possiblyQualifiedResourceName.substring(0, indexOfSlash);
      }
      packageName = possiblyQualifiedResourceName.substring(indexOfSlash + 1, indexOfColon);
      name =  possiblyQualifiedResourceName.substring(indexOfColon + 1);
    } else if (indexOfSlash > indexOfColon) {
      if (indexOfColon > 0) {
        packageName = possiblyQualifiedResourceName.substring(0, indexOfColon);
      }
      type = possiblyQualifiedResourceName.substring(indexOfColon + 1, indexOfSlash);
      name = possiblyQualifiedResourceName.substring(indexOfSlash + 1);
    }

    if ((type == null && defaultType == null) || packageName == null && defaultPackageName == null) {
      return null;
    }

    return new ResName(packageName == null ? defaultPackageName : packageName,
        type == null ? defaultType : type,
        name);
  }

  public static Integer getResourceId(ResourceIndex resourceIndex, String possiblyQualifiedResourceName, String contextPackageName) {
    if (possiblyQualifiedResourceName == null) {
      return null;
    }

    if (possiblyQualifiedResourceName.equals("@null")) {
      return null;
    }

    // Was not able to fully qualify the resource name
    String fullyQualifiedResourceName = qualifyResourceName(possiblyQualifiedResourceName, contextPackageName, null);
    if (fullyQualifiedResourceName == null) {
      return null;
    }

    fullyQualifiedResourceName = fullyQualifiedResourceName.replaceAll("[@+]", "");
    Integer resourceId = resourceIndex.getResourceId(new ResName(fullyQualifiedResourceName));
    // todo warn if resourceId is null
    return resourceId;
  }

  public static ResName qualifyFromFilePath(@NotNull final String packageName, @NotNull final String filePath) {
    final FileFsFile filePathFile = new FileFsFile(new File(filePath));
    final String type = filePathFile.getParent().getName().split("-")[0];
    final String name = filePathFile.getBaseName();

    return new ResName(packageName, type, name);
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    ResName resName = (ResName) o;

    if (hashCode() != resName.hashCode()) return false;

    if (!packageName.equals(resName.packageName)) return false;
    if (!type.equals(resName.type)) return false;
    if (!name.equals(resName.name)) return false;

    return true;
  }

  @Override
  public int hashCode() {
    return hashCode;
  }

  @Override
  public String toString() {
    return "ResName{" + getFullyQualifiedName() + "}";
  }

  public String getFullyQualifiedName() {
    return packageName + ":" + type + "/" + name;
  }

  public String getNamespaceUri() {
    return "http://schemas.android.com/apk/res/" + packageName;
  }

  public ResName withPackageName(String packageName) {
    if (packageName.equals(this.packageName)) return this;
    return new ResName(packageName, type, name);
  }

  public void mustBe(String expectedType) {
    if (!type.equals(expectedType)) {
      throw new RuntimeException("expected " + getFullyQualifiedName() + " to be a " + expectedType + ", is a " + type);
    }
  }

  private int computeHashCode() {
    int result = packageName.hashCode();
    result = 31 * result + type.hashCode();
    result = 31 * result + name.hashCode();
    return result;
  }
}


text:
FROM golang:1.8

MAINTAINER Yuwei Ba <akabyw@gmail.com>

RUN go get github.com/ibigbug/GArrow/cmd/garrow

CMD ["garrow"]


text:
==================
V-USB Adapter
==================

Status: OK

TODO:
 - connect pullup with IO port

..  [[[cog
..  s=open('docs/template1.txt').read().format(project='vusb')
..  cog.outl(s)
..  ]]]

Schematic
---------

      .. eagle-image:: vusb.sch
                :resolution: 150

.. raw:: latex

  \newpage % hard pagebreak at exactly this position

Board
-----

top view:

      .. eagle-image:: vusb.brd
                :command:   display all
                :resolution: 300

wires only:

      .. eagle-image:: vusb.brd
                :resolution: 300
                :layers: document, pads, vias, top, dimension

bottom view mirrored:

      .. eagle-image:: vusb.brd
                :resolution: 300
                :layers: pads, vias, bottom, dimension
                :mirror:

Partlist
--------

      .. eagle-partlist:: vusb.brd
            :header: part, value , position

3D view
-------

-----
Front
-----

      .. eagle-image3d:: vusb.brd

----------
Right side
----------

      .. eagle-image3d:: vusb.brd
            :pcbrotate:  90,45,90

---------
Left side
---------

      .. eagle-image3d:: vusb.brd
            :pcbrotate:  90,-45,-90

------
Bottom
------

      .. eagle-image3d:: vusb.brd
            :pcbrotate:  0,0,180

..  [[[end]]]

original source
-------------------------------------

http://vusb.wikidot.com/hardware

.. image:: http://vusb.wikidot.com/local--files/hardware/level-conversion-with-zener.gif

"Solution B: Level conversion on D+ and D-
Level conversion with Zener diodes.

Instead of reducing the AVR's power supply,
we can limit the output voltage on D+ and D- with Zener diodes.
We recommend 3.6 V low power types, those that look like 1N4148
(usually 500 mW or less).
Low power types are required because they have less capacitance
and thus cause less distortion on the data lines.
And 3.6 V is better than 3.3 V because 3.3 V diodes yield only ca. 2.7 V
in conjunction with an 1.5 kΩ (or more exactly 10 kΩ) pull-up resistor.
With 3.3 V diodes, the device may not be detected reliably.

If you use Zener diodes for level conversion,
please measure the voltage levels to make sure that the diodes you have chosen
match the requirements.

Advantages of the Zener diode approach:

    * Low cost.
    * Easy to obtain.
    * Entire design can be at 5 V.
    * AVR can be clocked at high rates.

Disadvantages:

    * Not a clean solution, a compromise between all parameters must be found.
    * Zener diodes come with a broad range of characteristics, especially at low currents, results may not be reproducible.
    * High currents when sending high-level.
    * High level is different for signaling and in idle state because signaling uses high currents to drive the diodes while idle state is driven by a 1.5 kΩ pull-up resistor."


text:
title: The basics
author: Jasper Van der Jeugt
---

Building and cleaning
---------------------

If you followed along with the previous tutorial, you should now have the
example site up and running. By running `./site build`, you created two
directories:

- `_site`, with your site as HTML files, ready to be deployed;
- `_cache`, which Hakyll uses internally.

`./site clean` removes these directories, and `./site rebuild` performs a
`clean` and then a `build`.

In general, it's only necessary to use `rebuild` when you made changes to your
`site.hs`, and not when you just made changes to the contents of your website.

At this point, feel free to change some files, `./site build` and see what
happens!

Pages and metadata
------------------

You might've noticed that the markdown pages all start with a block:

    ---
    title: Contact
    ---

    I live...

This is entirely optional, but useful for providing extra information
("metadata") about items. All items can have metadata: since it's not really
convenient to add such a header to an image, you can also do this using a
separate file.

For a file called `images/foo.png`, you can add an `images/foo.png.metadata`
file with contents:

    title: An image of a cow


text:
<?php defined('SYSPATH') or die('No direct access allowed.');

$lang = array
(
	// Class errors
	'invalid_rule'  => 'Invalid validation rule used: %s',

	// General errors
	'unknown_error' => 'Unknown validation error while validating the %s field.',
	'required'      => 'The %s field is required.',
	'min_length'    => 'The %s field must be at least %d characters long.',
	'max_length'    => 'The %s field must be %d characters or fewer.',
	'exact_length'  => 'The %s field must be exactly %d characters.',
	'in_array'      => 'The %s field must be selected from the options listed.',
	'matches'       => 'The %s field must match the %s field.',
	'valid_url'     => 'The %s field must contain a valid URL.',
	'valid_email'   => 'The %s field must contain a valid email address.',
	'valid_ip'      => 'The %s field must contain a valid IP address.',
	'valid_type'    => 'The %s field must only contain %s characters.',
	'range'         => 'The %s field must be between specified ranges.',
	'regex'         => 'The %s field does not match accepted input.',
	'depends_on'    => 'The %s field depends on the %s field.',

	// Upload errors
	'user_aborted'  => 'The %s file was aborted during upload.',
	'invalid_type'  => 'The %s file is not an allowed file type.',
	'max_size'      => 'The %s file you uploaded was too large. The maximum size allowed is %s.',
	'max_width'     => 'The %s file you uploaded was too big. The maximum allowed width is %spx.',
	'max_height'    => 'The %s file you uploaded was too big. The maximum allowed height is %spx.',
	'min_width'     => 'The %s file you uploaded was too small. The minimum allowed width is %spx.',
	'min_height'    => 'The %s file you uploaded was too small. The minimum allowed height is %spx.',

	// Field types
	'alpha'         => 'alphabetical',
	'alpha_numeric' => 'alphabetical and numeric',
	'alpha_dash'    => 'alphabetical, dash, and underscore',
	'digit'         => 'digit',
	'numeric'       => 'numeric',
);


text:
package edu.psu.compbio.seqcode.gse.tools.seqdata;

import java.util.*;

import edu.psu.compbio.seqcode.gse.datasets.alignments.*;
import edu.psu.compbio.seqcode.gse.datasets.general.*;
import edu.psu.compbio.seqcode.gse.datasets.seqdata.*;
import edu.psu.compbio.seqcode.gse.datasets.species.*;
import edu.psu.compbio.seqcode.gse.tools.utils.Args;
import edu.psu.compbio.seqcode.gse.utils.*;
import edu.psu.compbio.seqcode.gse.utils.database.*;

/**
 * Tries to determine one or more control experiments to use for
 * one or more chipseq experiments.
 *
 * Usage:
 * java edu.psu.compbio.seqcode.gse.tools.chipseq.GuessControlExpt --species 'Mus musculus;mm9' --chipseq 'Sing ES CTCF E14;bowtie_unique'
 */
public class GuessControlExpt {

    private static SeqDataLoader loader;
    private static Collection<String> controlTypeNames;
    private static Collection<Integer> controlTypeIDs;
    private static MetadataLoader core;
    private static Genome genome;
    public static void main(String args[]) throws Exception {
        genome = Args.parseGenome(args).cdr();
        List<SeqLocator> locators = Args.parseSeqExpt(args);
        loader = new SeqDataLoader(false);
        core = new MetadataLoader();
        controlTypeNames = new ArrayList<String>();
        controlTypeNames.add("CONTROL");
        controlTypeNames.add("INPUT");
        controlTypeIDs = new ArrayList<Integer>();

        boolean strict = Args.parseFlags(args).contains("strict");

        for (String f : controlTypeNames) {
            ExptType type = core.findExptType(f);
            if (type != null) {
                controlTypeIDs.add(type.getDBID());
            }
        }

        Set<String> output = new HashSet<String>();
        for (SeqLocator l : locators) {
            Collection<SeqAlignment> alignments = new ArrayList<SeqAlignment>();
            if (l.getReplicates().size() == 0) {
                alignments.addAll(loader.loadAlignments(l.getExptName(),
                                                        null,
                                                        l.getAlignName(),
                                                        null,null,null,
                                                        null,null,null,
                                                        genome));
            } else {
                alignments.addAll(loader.loadAlignments(l, genome));
            }
            for (SeqAlignment a : alignments) {
                Collection<SeqAlignment> controls = controlsForAlignment(a);
                if (controls.size() == 0) {
                    System.err.println("No controls for " + a);
                    if (strict) {
                        System.exit(1);
                    }
                }
                for (SeqAlignment c : controls) {
                    output.add(c.getExpt().getName() + ";" + c.getName());
                }
            }
        }
        for (String a : output) {
            System.out.println(a);
        }

    }
    public static Collection<SeqAlignment> controlsForAlignment(SeqAlignment a) throws Exception {
        ArrayList<SeqAlignment> output = new ArrayList<SeqAlignment>();
        SeqExpt expt = a.getExpt();
        CellLine cells = expt.getCellLine();
        ExptCondition cond = expt.getExptCondition();
        for (Integer i : controlTypeIDs) {
            output.addAll(loader.loadAlignments(null,null,null,
                                                i, null, cond.getDBID(),
                                                null, cells.getDBID(), null,
                                                genome));
        }
        return output;
    }

}


text:
<?xml version="1.0" encoding="UTF-8"?>
<arquillian xmlns="http://jboss.org/schema/arquillian"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="
        http://jboss.org/schema/arquillian
        http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
	<container qualifier="widlfly-managed" default="true">
		<configuration>
			<property name="managementPort">19990</property>
			<property name="javaVmArguments">-Djboss.socket.binding.port-offset=10000</property>
		</configuration>
	</container>
</arquillian>


text:
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
            android:label="@string/action_search"
            android:hint="@string/action_search">
</searchable>


text:
{% load staticfiles %}
{% load i18n %}
{% load cache %}
{% load my %}

INSYDIA

{% trans 'RECENT NEWS' %}

                        {% for i in footer_news %}

                                       {% if i.news_main_cover|check_format == True %}

                                       {% else %}

                                       {% endif %}

                                                 {% if lang == 'eng' %}
                                                    {{ i.news_title_english }}
                                                {% elif lang == 'rus' %}
                                                    {{ i.news_title_russian }}
                                                {% else %}
                                                    {{ i.news_title_chinese }}
                                                {% endif %}

                        {% endfor %}

{% trans 'Categories' %}

{% trans 'Technology' %}

{% trans 'Entertainment' %}

{% trans 'Auto' %}

{% trans 'Space' %}

{% trans 'BIO' %}

{% trans 'Companies' %}

{#
{% trans 'Reviews' %}
#}
                        {% if username.username %}

{% trans 'PRIVATE' %}

                        {% endif %}

{% trans 'Quick links' %}

{% trans 'About us' %}

{% trans 'Advertisement' %}

{% trans 'RSS feed' %}

{% trans 'Career' %}

INSYDIA

                Site by Eugene Privalov


text:
title: AsyncTaskManagerChanges 3.3
category: feature
authors: yair zaslavsky
wiki_category: Feature
wiki_title: Features/AsyncTaskManagerChanges 3.3
wiki_revision_count: 20
wiki_last_updated: 2013-07-06
---

# Async Task manager changes for oVirt 3.3

## Summary

The following feature page deals with improvements added to the engine async task manager mechanism.

## Owner

*   Name: Yair Zaslavsky (MyUser)

<!-- -->

*   Email: yzaslavs@redhat.com

## Current status

*   Last updated date: May 25, 2013

For oVirt 3.3 we would like to improve the current SPM tasks mechanism in the following areas:

*   Better handling of engine/vdsm crashes in cases of mismatch in the number of tasks (expected vs actual running tasks).
*   Providing better mechanism to query if an entity (i.e - StorageDomain, VM, Disk, etc...) has running tasks on.
*   Improving the mechanism for determining whether endAction (the last step of command invocation in case the command/its children created tasks) should be run.

## Detailed Description

### **Better handling of engine crashes in cases of mismatch in the number of tasks (expected vs actual running tasks)**.

*   Problem: Engine can crash, causing a wrong successful completion of commands due to mismatch between expected tasks and created tasks.
*   Example:

RemoveVM is run on a VM with 4 disks. After 2 out of the 4 disks are created at VDSM, and stored at engine, engine crashes. Engine restarts, the command ends successfully although 2 out of the 4 disks were not removed.

*   Detailed explanation of problem:

A parent command (for example - RemoveVmCommand) may create child commands that each one of them in turn creates a task (for example - RemoveImageCommand is a child command that is responsible for creating a task at VDSM for removing one of the images associated with the VM). The tasks information is kept at database at async_tasks table, and is used if engine crashes in order to restore association between tasks and commands and coordinate the endAction execution when all the tasks for the parent command have ended.

Currently, a new record is inserted into the async_tasks table only after the task is created at VDSM (TaskCreationInfo is returned from the VDSBroker with the vdsm tadk ID). The return tasked ID serves as a primary key for the table. If engine crashes- it may be that not all vdsm calls for creating all the tasks were issues, hence not all async_tasks records were added. Engine restarts and both vdsm and engine are aware only to a partial amount of the expected tasks , causing the parent command (for example, RemoveVm) to be successfully completed (for example - RemoveVm is successfully completed when only 2 out of 4 disks where removed).

*   Solution:

The suggested fix will distinguish between the vdsm task ID and the DB task ID, in addition, it will add all the expected tasks at the parent command, in a single transaction - when a VDSM task ID is obtained from vds broker, it will be associated to the proper aync_tasks record. If engine crashes , and for some aysnc_tasks records there is no VDSM task ID (in the given example - for each one of the 4 disks, a async_tasks record is added to the DB, and for 2 out of 4, there is no VDSM taskd ID), the parent command (RemoveVm in the example) will be ended with "failure" state.

### **Providing better mechanism to query if an entity (i.e - StorageDomain, VM, Disk, etc...) has running tasks on.**

*   Problem: The mechanism of querying an entity for running task is limited
*   Example: It is impossible to query for disk entity if there are running tasks, if the command is VM related.
*   Detailed explanation of problem:

Currently there are two mechanisms for querying whether a task is associated with a given entity - a. VdcActionParametersBase which is the base class for all commands parameters has a field that holds the entityID for which the task is created. There is no indication the entity type and in addition, only one entity ID can be associated with the task, so usually this is the top-most entity (VM, Template,Disk). b. async_task_entities table was introduced to overcome the issue - it contains an association between task id, and entity ID (and its type),

for example: 40fd52b-3400-4cdd-8d3f-c9d03704b0aa | 72e3a666-89e1-4005-a7ca-f7548004a9ab | Storage Indicates that task 40fd52b-3400-4cdd-8d3f-c9d03704b0aa is associated with entity 72e3a666-89e1-4005-a7ca-f7548004a9ab which is a storage domain. The current mechanism (both at DAO and BLL ) is incomplete in a sense that only one entity type can be associated with the usage of async_tasks table to varying number of entity IDs.

*   Solution:

The suggested fix will allow association of multiple entity types with multiple entity IDs. This mechanism can help in improving canDoAction checks, and behavior of compensation (for example - don't perform compensation to the initial state, if there are running tasks).

### **Improving the mechanism for determining whether endAction (the last step of command invocation in case the command/its children created tasks) should be run**

*   Problem: Current mechanism of endAction mechanism is limiting
*   Example: Two READ-ONLY commands (tasks that perform READ ONLY storage-related operations) cannot run on the same entity in parallel (Engine will start polling tasks of a command only after the first command has finished).
*   Detailed explanation of problem:

The current mechanism uses the combination of CommandType (i.e RemoveVm) and the entity ID (i.e the ID of the VM) in order to coordinate the execution of endAction when all tasks related for the command (i.e - all tasks created by the children of RemoveVm command are done). The current mechanism is problematic as it prevents the engine to start polling tasks for the same entity of different commands - for example, if there are two READ-ONLY asynchronous operations on the same entity (in case of read/write- this should be handled by canDoAction and the in-memory locking mechanism).

*   Solution:

Reach the decision of whether endAction should be executed based on the parent command Id. Async Task Manager should not postpone polling of commands - for READ-ONLY asynchronous operations there is no point. For write operation - it is the responsibility of canDoAction and the locking mechanism to approve such commands.

## Benefit to oVirt

The benefit for oVirt from these changes is to have better usage of SPM tasks in the system - by giving better handling of cases of engine crashes , providing a better mechanism for execution validation of commands and and to give better association between tasks and the command execution flows.

## Testing

This feature is mostly code change and introduces changes that should be implemented by various commands. Currently, 3 commands/flows in the system use the new mechanism:

*   Hibernate VM
*   Create Template
*   Create snapshot

The things that can be tested are: 1. Test case 1 (Check for regression) Make sure that the 3 commands are normally , as they did in oVirt 3.3 After each flow execution make sure that async_tasks table is clear.

2. Test case 2 (Restart ) Try to restart engine during execution of commands. The commands should not suceed, unless all tasks were executed on VDSM.

## Dependencies / Related Features

These fixes are a part of the on going effort around the Async Task Manager changes. See also [1](/develop/release-management/features/infra/asynctaskmanagerchanges/)

## Documentation / External references


text:
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var core_1 = require('@angular/core');
var hero_service_1 = require('../shared/hero.service');
var router_1 = require('@angular/router');
var core_2 = require('@angular/core');
var TowersComponent = (function () {
    function TowersComponent(router, heroService) {
        this.router = router;
        this.heroService = heroService;
        this.towers = [];
        this.state = 'inactive';
        this.stateButton = 'inactive';
    }
    TowersComponent.prototype.ngOnInit = function () {
        var _this = this;
        this.newTower = {
            _id: 0,
            title: '',
            name: '',
            display_label: false,
            heroes: []
        };
        this.heroService.getTowers()
            .then(function (towers) { return _this.towers = towers; });
    };
    TowersComponent.prototype.togglestates = function () {
        this.state = (this.state === 'inactive' ? 'active' : 'inactive');
        this.stateButton = (this.stateButton === 'inactive' ? 'active' : 'inactive');
    };
    TowersComponent.prototype.add = function (t, isValid) {
        var _this = this;
        if (isValid)
            this.newTower.heroes = [];
        this.heroService.createTower(this.newTower)
            .then(function (tower) {
            _this.towers.push(tower);
            _this.selectedTower = null;
        });
        console.log(this.towers);
    };
    TowersComponent.prototype.delete = function (tower) {
        var _this = this;
        this.heroService
            .deleteTower(tower._id)
            .then(function () {
            _this.towers = _this.towers.filter(function (t) { return t !== tower; });
            //if (this.selectedHero === hero) { this.selectedHero = null; }
        });
    };
    TowersComponent.prototype.gotoDetail = function (tower) {
        var link = ['/towers/' + tower._id];
        this.router.navigate(link);
    };
    TowersComponent.prototype.gotoTower = function (tower) {
        var link = ['/towers/' + tower._id + '/heroes'];
        this.router.navigate(link);
    };
    TowersComponent = __decorate([
        core_1.Component({
            moduleId: module.id,
            selector: 'towers-list',
            templateUrl: 'towers-list.component.html',
            styleUrls: ['towers-list.component.css'],
            animations: [
                core_2.trigger('towersState', [
                    core_2.state('inactive', core_2.style({
                        height: '0',
                        display: 'none'
                    })),
                    core_2.state('active', core_2.style({
                        height: '*',
                        display: 'block'
                    })),
                    core_2.transition('inactive => active', core_2.animate('100ms ease-in')),
                    core_2.transition('active => inactive', core_2.animate('100ms ease-out'))
                ])
            ]
        }),
        __metadata('design:paramtypes', [router_1.Router, hero_service_1.HeroService])
    ], TowersComponent);
    return TowersComponent;
}());
exports.TowersComponent = TowersComponent;
//# sourceMappingURL=towers-list.component.js.map