protected function create(Import\ImportStream $stream, Import\ImportContext $context) {
        $reports = $stream->get('reports');
        if (empty($reports)) {
            return;
        }

        $this->datasourceName = $context->get('datasourceName');
        $readOnly = gd_datasource_is_property($this->datasourceName, 'readonly');
        if ($readOnly) {
            $metamodel = data_controller_get_metamodel();
            $this->datasets = $metamodel->datasets;
        } else {
            $this->datasets = $stream->get('datasets');
        }

        if (empty($this->datasets)) {
            throw new Exception('Must have datasets to create reports.');
        }


        foreach ( $reports as $reportKey => $report ) {
            $node = $this->createReport($report);
            if ( !empty($node->nid ) ) {
                $reports[$reportKey] = $node;
            } else {
                throw new Exception('Report node creation failed');
            }
        }

        $stream->set('reports',$reports);
    }
    public function getView( array $options = array() ) {
        $scrollHeight = 400;
        $heightAdj = 0;
        if ( $this->ReportConfig->showTitle() || $this->ReportConfig->showMenu() ) {
            $heightAdj = (GD_REPORT_TITLE_HEIGHT);
        }

        $reportSize = $this->ReportConfig->getDisplaySize();
        if ( !empty($reportSize) ) {
            $scrollHeight = $reportSize->height;
        }

        if ( isset($_REQUEST['h']) && isset($_REQUEST['w']) ) {
            $scrollHeight = $_REQUEST['h'];
        }

        $scrollHeight -= $heightAdj;
        $width = isset($_REQUEST['w']) ? $_REQUEST['w'] . 'px' : '100%';

        $datasourceName = $this->ReportConfig->getNode() != null ? get_node_field_value($this->ReportConfig->getNode(), 'field_report_datasource') : null;
        if (!isset($datasourceName)) {
            $datasourceName = gd_datasource_get_active();
        }
        $viewStart = gd_datasource_is_property($datasourceName, 'draft') ?
          '<img id="report-'.intval($this->ReportConfig->getId()).'-overlay" class="report-draft-overlay" src="/sites/all/modules/custom/report/includes/images/draft.png"/>
          <script type="text/javascript">
            jQuery("#report-'.intval($this->ReportConfig->getId()).'-overlay").bind("mouseenter mouseleave click dblclick foucsout hover mousedown mousemove mouseout mouseover mouseup", function (e) {
                if (navigator.appName == "Microsoft Internet Explorer") {
                    jQuery("#report-'.intval($this->ReportConfig->getId()).'-overlay").hide();
                    var target = document.elementFromPoint(e.clientX, e.clientY);
                    jQuery(target).trigger(e.type);
                    jQuery("#report-'.intval($this->ReportConfig->getId()).'-overlay").show();
                }
            });
          </script>' : '';
        $viewStart .= '<div class="report report-custom" id="report-'.intval($this->ReportConfig->getId()).'" style="width:' . $width . ';height:' . $scrollHeight . 'px;clear:both; overflow:hidden;position:relative;">';
        $viewEnd = '</div>';
        $viewBody = $this->getBody($options);

        return
          $viewStart.
            $viewBody.
          $viewEnd;
    }
    protected function create(Import\ImportStream $stream, Import\ImportContext $context) {
        $dashboards = (array) $stream->get('dashboards');
        if (empty($dashboards)) {
            return;
        }

        $this->datasourceName = $context->get('datasourceName');

        $this->reports = (array) $stream->get('reports');

        $readOnly = gd_datasource_is_property($this->datasourceName, 'readonly');
        if ($readOnly) {
            $metamodel = data_controller_get_metamodel();
            $this->datasets = $metamodel->datasets;
        } else {
            $this->datasets = (array) $stream->get('datasets');
        }

        if ( !empty($reports) && empty($datasets) ) {
            throw new Exception('Missing datasets for dashboard reports.');
        }

        foreach ( $dashboards as $dashboardKey => $dashboard ) {
            $node = $this->createDashboard($dashboard);
            if ( !empty($node->nid ) ) {
                $dashboards[$dashboardKey] = $node;
            } else {
                throw new Exception('Dashboard node creation failed');
            }
        }

        // update report/dashboard ids in config, for linking
        foreach ( $dashboards as $dashboardKey => $dashboard ) {
            $config = json_decode($dashboard->field_dashboard_config[$dashboard->language][0]['value']);

            $this->processConfigDashboards($config);

            $dashboards[$dashboardKey]->field_dashboard_config[$dashboards[$dashboardKey]->language][0]['value'] = json_encode($config);
            gd_dashboard_save($dashboards[$dashboardKey]);
        }

        $stream->set('dashboards',$dashboards);
    }
    public function export(Export\ExportStream $stream, Export\ExportContext $context) {
        $datasource = gd_datasource_get_active();
        $readOnly = gd_datasource_is_property($datasource, 'readonly');
        if ($readOnly) {
            return;
        }

        $metamodel = data_controller_get_metamodel();

        // get datasets
        $datasets = array();
        foreach ($metamodel->datasets as $dataset) {
            if (!isset($dataset->nid)) {
                continue;
            }
            $datasets[] = $dataset;
        }

        $stream->set('datasets',$datasets);
    }
 <?php if ((gd_datasource_is_property(gd_datasource_get_active(), 'draft'))) { ?>
     var overlay = null;
     if (navigator.appVersion.indexOf("MSIE 9.") !== -1) {
         overlay = $('<svg class="report-draft-overlay" xmlns="http://www.w3.org/2000/svg" xmlns:xlink= "http://www.w3.org/1999/xlink"><image alt="Draft Overlay" title="Draft Overlay" aria-label="Draft Overlay"  xlink:href="/sites/all/modules/custom/report/includes/images/draft.png" x="0" y="0" height="<?php echo $height > $width ? ('100%') : ($width . 'px'); ?>" width="<?php echo $width > $height ? ('100%') : ($height . 'px'); ?>"/></svg>');
     } else {
         overlay = $('<img alt="Draft Overlay" title="Draft Overlay" aria-label="Draft Overlay" class="report-draft-overlay" src="/sites/all/modules/custom/report/includes/images/draft.png" style="<?php echo $height > $width ? ( 'height') : ('width'); ?>: 100%;">');
     }
     $('#report-<?php echo $reportId; ?>').append(overlay);
 <?php } ?>
 var urlOptions = {
     url: "<?php echo $url; ?>"
 };
 global.GD.PivotTableFactory.createTable(<?php echo $reportId; ?>, "#report-<?php echo $reportId;?>",
     {
         measures: <?php echo json_encode($measures); ?>,
         draft: <?php echo (gd_datasource_is_property(gd_datasource_get_active(), 'draft') ? "true" : "false"); ?>,
         rows: <?php echo isset($rows) ? json_encode($rows): '[]'; ?>,
         cols: <?php echo isset($cols) ? json_encode($cols): '[]'; ?>,
         columns: <?php echo json_encode($columns); ?>,
         url: urlOptions,
         allowDragDrop: <?php echo $disableDrag; ?>,
         callType: "<?php echo ( isset($admin) ? "POST" : "GET" ) ?>",
         getDataObject: function(columns, measure) {
             if (!columns) {
                 columns = [];
             }
             if (measure) {
                 columns.push(measure);
             }
             <?php if (isset($admin) && !isset($dashboard)) {
                 echo 'var config = GovdashReportBuilder.getReport().getConfig();';
/**
 * @return array
 * @throws Exception
 * @throws IllegalArgumentException
 */
function gd_dashboard_index_variables () {
    $dashboards = array();
    $active_datasource_name = gd_datasource_find_active();
    $current_dashboard = gd_dashboard_get_current();
    global $user;

    if ( gd_account_user_is_admin() ) {

        // can see all datasources
        $datasources = gd_datasource_get_all();

        if ( $current_dashboard ) {
            gd_datasource_set_active(get_node_field_value($current_dashboard,'field_dashboard_datasource'));
        } else if ( !$active_datasource_name ) {
            if (isset($_GET['ds'])) {
                gd_datasource_set_active($_GET['ds']);
            } else {
                gd_datasource_set_active(key($datasources));
            }
        }

        // don't pick up any dashboards if there are no published datamarts - causes logic bomb further down
        if ( !empty($datasources) ) {
            $dashboards = gd_dashboard_findall_by_datasource(LOAD_ENTITY);
        }

    } else if ( $user->uid ) {

        // get view privileges for all dashboards
        $results = gd_account_user_get_dashboards();

        // pick up the datasources from the dashboards
        $datasources = gd_account_user_get_datasources();
        foreach ( $results as $dashboard ) {
            if ( !isset($datasources[get_node_field_value($dashboard,'field_dashboard_datasource')]) ) {
                $datasource = gd_datasource_get(get_node_field_value($dashboard,'field_dashboard_datasource'));
                $datasources[$datasource->name] = $datasource;
            }
        }

        // set current datasource
        if ( $current_dashboard ) {
            gd_datasource_set_active(get_node_field_value($current_dashboard,'field_dashboard_datasource'));
        } else {
            if ( !$active_datasource_name ) {
                if ( isset($_GET['ds']) && isset($datasources[$_GET['ds']]) ) {
                    gd_datasource_set_active($_GET['ds']);
                } else {
                    reset($results);
                    try {
                        if (!empty($results[key($results)])) {
                            $active_datasource_name = get_node_field_value($results[key($results)],'field_dashboard_datasource');
                            gd_datasource_set_active($active_datasource_name);
                        } else {
                            return 'You have not been granted permission to view any dashboards.';
                        }
                    } catch (Exception $e) {
                        drupal_set_message('No default datasource set.', 'error');
                        LogHelper::log_error($e->getMessage());
                    }
                }
            }
        }

        // remove dashboards that do not belong to datasource of current dashboard
        $active_datasource_name = gd_datasource_get_active();
        $dashboards = array();
        foreach ( $results as $key => $dashboard ) {
            if ( $active_datasource_name === get_node_field_value($dashboard,'field_dashboard_datasource') ) {
                $dashboards[$key] = $dashboard;
            }
        }

        // remove dashboards that were not created by the user
        if ( gd_datasource_is_property($active_datasource_name, 'personal') ) {
            global $user;
            $userCreatedDashboards = array();
            foreach ( $dashboards as $key => $dashboard ) {
                if ( $user->uid == $dashboard->uid ) {
                    $userCreatedDashboards[$key] = $dashboard;
                }
            }
            $dashboards = $userCreatedDashboards; // overwrite dashboard list
        }

    } else {

        // get datasources that belong to the dashboards
        // weed out dashboards with missing datasource
        $datasources = array();
        $publicDashboards = array();
        foreach ( gd_dashboard_get_dashboards_public(LOAD_ENTITY) as $dashboard ) {
            $datasourceName = get_node_field_value($dashboard,'field_dashboard_datasource');
            $datasource = gd_datasource_find($datasourceName);
            if ( !$datasource ) {
                continue;
            }
            $publicDashboards[$dashboard->nid] = $dashboard;
            if ( !isset($datasources[$datasourceName]) ) {
                $datasources[$datasource->name] = $datasource;
            }
        }

        // set current datamart
        if ( $current_dashboard ) {
            gd_datasource_set_active(get_node_field_value($current_dashboard,'field_dashboard_datasource'));
        } else {
            if ( isset($_GET['ds']) && isset($datasources[$_GET['ds']]) ) {
                gd_datasource_set_active($_GET['ds']);
            } else {
                gd_datasource_set_active(get_node_field_value($publicDashboards[key($publicDashboards)],'field_dashboard_datasource'));
            }
        }

        // remove dashboards that do not belong to datamart of current dashboard
        $active_datasource_name = gd_datasource_get_active();
        $dashboards = array();
        foreach ( $publicDashboards as $key => $dashboard ) {
            if ( $active_datasource_name === get_node_field_value($dashboard,'field_dashboard_datasource') ) {
                $dashboards[$key] = $dashboard;
            }
        }
    }

    reset($datasources);
    reset($dashboards);

    // sort the dashboard list by name
    usort($dashboards, function($a, $b) {
        if (strtolower($a->title) === strtolower($b->title)){
            return strnatcmp($a->title,$b->title);
        }
        return strnatcasecmp($a->title,$b->title);
    });

    // which dashboard to display
    if ( $current_dashboard ) {
        $dashboard = $current_dashboard;
    } else if (!empty($dashboards) ) {
        $dashboard = $dashboards[0];
    } else {
        $dashboard = null;
    }

    $display_dashboards = array();
    if ( !empty($dashboards) ) {
        $dashboard_ids = array(); // index of any parents from $dashboards
        $drilldown_dashboard_ids = array();
        foreach ( $dashboards as $d ) {
            $config = new GD_DashboardConfig($d);
            $dashboard_ids[] = (int)$d->nid;
            foreach( $config->drilldowns as $drilldown) {
                if ( is_object($drilldown->dashboard) ) {
                    $drilldown_dashboard_ids[] = (int)$drilldown->dashboard->id; // for backwards compatibility
                } else {
                    $drilldown_dashboard_ids[] = (int)$drilldown->dashboard;
                }
            }
        }
        $drilldown_dashboard_ids = array_unique($drilldown_dashboard_ids);
        $display_dashboard_ids = array_diff($dashboard_ids, $drilldown_dashboard_ids);
        $display_dashboards = array();
        foreach ( $dashboards as $d ) {
            if ( in_array($d->nid,$display_dashboard_ids) ) {
                $display_dashboards[] = $d;
            }
        }
        // if initial dashboard is a drilldown dashboard, load first non-drilldown dashboard instead
        if ( in_array($dashboard->nid, $drilldown_dashboard_ids) && empty($_GET['id']) ) {
            $dashboardKeys = array_keys($display_dashboard_ids);
            $dashboard = $dashboards[array_shift($dashboardKeys)];
        }
    }

    // force a dashboard id into the url for javascript libs
    // TODO doing a redirect is wasteful, find some other way
    if ( empty($_GET['id']) &&  isset($dashboard) ) {
        drupal_goto('dashboards',array('query'=>array('id'=>$dashboard->nid)));
    }

    foreach ( $datasources as $k => $ds ) {
        if ( $ds->name == gd_datasource_get_active() ) {
            $datasources[$k]->active = true;
        }
    }

    return array($datasources, $dashboard, $display_dashboards);
}
    public function export(Export\ExportStream $stream, Export\ExportContext $context) {
        $datasource = gd_datasource_get_active();
        $readOnly = gd_datasource_is_property($datasource, 'readonly');
        if ($readOnly) {
            return;
        }

        $metamodel = data_controller_get_metamodel();

        // get reference points that have ref to the dataset in this datamart
        $datasetNames = array();
        foreach ( $stream->get('datasets') as $d ) {
            $datasetNames[] = $d->name;
        }

        $referencePoints = array();
        $referencePointNodes = gd_reference_get_reference_points_by_dataset($datasetNames, LOAD_ENTITY);
        $referencePointNids = array();
        foreach ( $referencePointNodes as $ref_point ) {
            $export = new stdClass();

            $export->id = (int) $ref_point->nid;
            $export->title = $ref_point->title;

            $dataset = $metamodel->getDataset(get_node_field_value($ref_point,'field_ref_point_dataset_sysname',0,'value',true));
            $export->dataset = $dataset->uuid;

            $export->columns = array();
            foreach ( (array) get_node_field_value($ref_point,'field_ref_point_column_sysname',null) as $column ) {
                $export->columns[] = $column;
            }

            $referencePoints[] = $export;
            $referencePointNids[] = (int) $ref_point->nid;
        }

        // find all references with above reference points
        $references = array();
        $referenceNodes = gd_reference_get_references_by_reference_points($referencePointNids, LOAD_ENTITY);
        foreach ( $referenceNodes as $reference ) {
            $export = new stdClass();

            $export->id = (int) $reference->nid;
            $export->title = $reference->title;

            $export->sysname = get_node_field_value($reference,'field_reference_sysname');

            foreach ( (array) get_node_field_node_ref($reference,'field_reference_point',null) as $referencePointNid ) {
                foreach ( $referencePoints as $referencePoint ){
                    if ( $referencePointNid == $referencePoint->id ) {
                        $export->referencePoints[] = $referencePoint;
                    }
                }
            }

            if ( empty($export->referencePoints) ) {
                throw new Exception('Reference missing reference points.');
            }

            $references[] = $export;
        }

        $stream->set('references',$references);
    }
    protected function getDataTableScript( $tableId, $scrollHeight, $tableSummary = '', $admin = TRUE, $public = FALSE, $external = FALSE, $sorting = null ) {
        $datasourceName = $this->ReportConfig->getNode() != null ? get_node_field_value($this->ReportConfig->getNode(), 'field_report_datasource') : null;
        if (!isset($datasourceName)) {
            $datasourceName = gd_datasource_get_active();
        }
        //  We can't use repeating background images because IE 9 does not reliably print them
        $overlay = gd_datasource_is_property($datasourceName, 'draft') ?
            '$("#' . $tableId . '").dataTable().fnSettings().aoDrawCallback.push({
                "fn": function () {
                    if ($("#' . $tableId . '").width() > $("#' . $tableId . '_wrapper > .table-content").width()) {
                        $("#report-'.intval($this->ReportConfig->getId()).'-overlay").height($("#' . $tableId . '_wrapper > .table-content").height() - 14);
                    }
                    if ($("#' . $tableId . '").height() > $("#' . $tableId . '_wrapper > .table-content").height()) {
                        $("#report-'.intval($this->ReportConfig->getId()).'-overlay").width($("#' . $tableId . '_wrapper > .table-content").width() - 14);
                    }

                    //  Table is taller than the actual image forcing us to manually repeat the image
                    if ($("#' . $tableId . '_wrapper > .table-content").height() > 1008) {
                        var diff = $("#' . $tableId . '").height() - 1008;
                        var num = Math.ceil(diff/1008);
                        for (var i = 1; i <= num; i++) {
                            $("#' . $tableId . '_wrapper").append($(\'<img alt="Draft Overlay" title="Draft Overlay" aria-label="Draft Overlay" class="report-draft-overlay" src="/sites/all/modules/custom/report/includes/images/draft.png"/>\').css("top", (1008 * i) + "px"));
                        }
                    } else if ($("#' . $tableId . '_wrapper > .table-content").width() > 1080) {
                        var diff = $("#' . $tableId . '").width() - 1008;
                        var num = Math.ceil(diff/1008);
                        for (var i = 1; i <= num; i++) {
                            $("#' . $tableId . '_wrapper").append($(\'<img alt="Draft Overlay" title="Draft Overlay" aria-label="Draft Overlay" class="report-draft-overlay" src="/sites/all/modules/custom/report/includes/images/draft.png"/>\').css("left", (1008 * i) + "px"));
                        }
                    }
                }
           });
           $("#' . $tableId . '_wrapper").append(\'<img alt="Draft Overlay" title="Draft Overlay" aria-label="Draft Overlay" id="report-'.intval($this->ReportConfig->getId()).'-overlay" class="report-draft-overlay" src="/sites/all/modules/custom/report/includes/images/draft.png"/>\');
           $("#report-'.intval($this->ReportConfig->getId()).'-overlay").bind("mouseenter mouseleave click dblclick focusout hover mousedown mousemove mouseout mouseover mouseup", function (e) {
                if (navigator.appName == "Microsoft Internet Explorer") {
                    jQuery("#report-'.intval($this->ReportConfig->getId()).'-overlay").hide();
                    var target = document.elementFromPoint(e.clientX, e.clientY);
                    if (jQuery(target).is("a") && jQuery(target).attr("href") != "#" && e.type == "click") {
                        window.location = jQuery(target).attr("href");
                    }
                    jQuery(target).trigger(e.type);
                    jQuery("#report-'.intval($this->ReportConfig->getId()).'-overlay").show();
                }
           });' : '';

        /*
         * TODO Move to actual JS file
         * For right now this has to kept in PHP due to how report render is done.
         * The JS below needs report configuration data (tableID, scrollHeight, etc.) for the table;
         *  which means that to move this to a separate JS file, we need to send back
         *  the raw table HTML + the configuration information that the JS needs, which
         *  isn't done right now.
         */
        $dataTableScript =
            '<script type="text/javascript">
                (function (global) {
                !function($,undefined) {
                    var func = function() {
                        $("#report-' . intval($this->ReportConfig->getId()) . '").on("ready.report.render", function() {
                            if ($.fn.DataTable.isDataTable("#' . $tableId . '"))' . (!$admin ? ('return;') : '$("#' . $tableId . '").dataTable().fnDestroy();') . '
                            var ROWS_PER_PAGE = ' . (GD_TABLE_ROWS_PER_PAGE) . ';

                            var dashboardId = $("#dash_viewer").attr("dashboard_id");
                            //$.fn.dataTableExt.sErrMode = "throw";
                            var sortable = [];
                            var sortableColumns = [];

                            $("#' . $tableId . '").find("th").each(function () {
                                if ( $(this).attr("column-name").indexOf("measure") != -1 ) {
                                    sortableColumns[$(this).attr("column-index")] = true;
                                } else if ( $(this).attr("column-name").indexOf("column") != -1 ) {
                                    sortableColumns[$(this).attr("column-index")] = false;
                                } else {
                                    sortableColumns[$(this).attr("column-index")] = null;
                                }
                            });

                            var disableMeasures = $.inArray(true, sortableColumns) != -1 && $.inArray(false, sortableColumns) != -1;
                            if ( disableMeasures ) {
                                $.each(sortableColumns, function (i, v) {
                                    if ( v === true ) {
                                        sortable.push( {"bSortable": false} );
                                    } else {
                                        sortable.push(null);
                                    }
                                });
                            } else {
                                $.each(sortableColumns, function (i, v) {
                                    sortable.push(null);
                                });
                            }
                            $("#' . $tableId . '").dataTable({
                                "sDom": \'<"clear-table clearfix"i><"table-content"rt><"table-paging clearfix"p>\',
                                "bServerSide": true,
                                "bProcessing": true,
                                "aoColumns": sortable,
                                ' . (isset($sorting) ? '"aaSorting": ' . $sorting . ',' : '') . '
                                "iDisplayLength": ROWS_PER_PAGE,
                                "oLanguage": {
                                    "sInfo": "Showing _START_ to _END_ of _TOTAL_ records",
                                    "sProcessing": "<div class=\"ldng datatableProcessing\"></div>"
                                },
                                "fnServerData": function  ( sSource, aoData, fnCallback, oSettings ) {
                                    var page = Math.ceil(oSettings._iDisplayStart / oSettings._iDisplayLength);
                                    var orderBys = [];
                                    $.each(oSettings.aaSorting, function(i, sorting) {
                                        var sortedColumn = sorting[0];
                                        var columnName = $("#' . $tableId . ' > thead > tr > th[column-index=" + sortedColumn + "]").attr("sort-column");
                                        orderBys.push({ "column": columnName, "order": sorting[1] });
                                    });
                                    oSettings.jqXHR = $.ajax({
                                        "dataType": ' . ($external ? '"jsonp"' : '"json"') . ',
                                        "type": "' . ($admin ? "POST" : "GET") . '",
                                        "url": "' . ($this->getCallbackUrl($admin, $public, $external)) . '",
                                        "data": {
                                            ' . $this->getServerArgs($admin) . ',
                                            "orderBy": orderBys,
                                            "offset": page * ROWS_PER_PAGE,
                                            "limit": ROWS_PER_PAGE
                                        },
                                        "beforeSend": function(xhr, settings) {
                                            xhr.setRequestHeader("X-CSRF-Token",((typeof GovDashboard !== "undefined")? GovDashboard.token : GD.options.csrf));
                                        },
                                        "success": function (data) {
                                            if ($("#' . $tableId . '").length) {
                                                var json = {};
                                                if (data["code"] == null || data["code"] == 200) {
                                                    $.each(aoData, function (i, o) {
                                                        if ( o["name"] == "sEcho" ) {
                                                            json.sEcho = o["value"];
                                                            return false;
                                                        }
                                                    });
                                                    json.iTotalDisplayRecords = data["response"]["totalRows"];
                                                    json.iTotalRecords = data["response"]["totalRows"];
                                                    json.aaData = [];

                                                    var columns = [];
                                                    for ( var i = 0; i < oSettings.aoColumns.length; i++ ) {
                                                        columns.push($("#' . $tableId . ' > thead > tr > th[column-index=\'" + i + "\']").attr("column-name"));
                                                    }

                                                    $.each(data["response"]["data"], function (i, r) {
                                                        var row = r["record"];
                                                        var obj = [];
                                                        $.each(columns, function (i, c) {
                                                            obj.push(row[c]);
                                                        });
                                                        json.aaData.push(obj);
                                                    });

                                                    $("#' . $tableId . '_wrapper").find("th").attr("title", function () {
                                                        return "Click to sort column";
                                                    });

                                                    if (data["response"]["totalRows"] > json.aaData.length) {
                                                        var height = $("#' . $tableId . '_wrapper > div.table-content").css("height");
                                                        $("#' . $tableId . '_wrapper > div.table-content").css("height", ' . $scrollHeight . ' - 45 - $("#gd-report-footer-' . intval($this->ReportConfig->getId()) . '").height());
                                                        $("#' . $tableId . '_wrapper").find("div.dataTables_paginate").css("line-height", 0);
                                                        $("#' . $tableId . '_wrapper > div.table-paging").find("a").attr("tabindex", "3000");
                                                    } else {
                                                        $("#' . $tableId . '_wrapper > div.table-content").css("height", ' . $scrollHeight . ' - $("#gd-report-footer-' . intval($this->ReportConfig->getId()) . '").height());
                                                        $("#' . $tableId . '_wrapper > div.table-paging").hide();
                                                    }
                                                    $("#' . $tableId . '_wrapper > div.table-content").find("thead").addClass("gd-table-header");
                                                    $("#' . $tableId . '_wrapper > div.table-content").find("th").attr("scope", "col");
                                                    $("#' . $tableId . '_wrapper > div.table-content").find("th").attr("tabindex", "3000");
                                                    $("#' . $tableId . '_wrapper > div.table-content").find("tbody").removeAttr("role");
                                                    $("#' . $tableId . '_wrapper > div.table-content").find("tbody").removeAttr("aria-live");
                                                    $("#' . $tableId . '_wrapper > div.table-content").find("tbody").removeAttr("aria-relevant");
                                                    ' . ((!isset($this->ReportConfig->options['visual']['advTableDisplayHeader'])) || $this->ReportConfig->options['visual']['advTableDisplayHeader'] === TRUE ? '' : '$("#' . $tableId . '_wrapper > div.table-content").find("thead").hide();') . '
                                                    fnCallback(json);
                                                    $("#' . $tableId . '_wrapper > div.table-content").find("th").attr("title", function() { return $(this).attr("column-title") + ": activate to sort column " + ($(this).hasClass("sorting_desc") ? "descending" : "ascending"); });
                                                    $("#' . $tableId . '_wrapper > div.table-paging").find("li.paginate_button, a").attr("tabindex", "3000");

                                                    //$("div.dataTables_info").show();
                                                } else if(data["code"] == 500) {
                                                    $("#' . $tableId . '").dataTable().fnSettings().oLanguage.sEmptyTable = "There was an error retrieving table data. Please contact the site administrator.";
                                                    $("#' . $tableId . '").dataTable().fnDraw();
                                                }
                                            }
                                        }
                                    }).fail(function (jqXHR, textStatus, errorThrown) {
                                        ' . ($admin ? $this->getAdminError() : '') . '
                                    });
                                }
                            });

                            $("#' . $tableId . '_wrapper > .table-content").css("width", "100%");
                            $("#' . $tableId . '_wrapper > .table-content").attr("tabindex", "3000");
                            $("#' . $tableId . '_wrapper > .table-content").css("overflow", "auto");
                            $("#' . $tableId . '_wrapper > div.table-content > table").attr("summary", "' . $tableSummary . '");
                            ' . $overlay . '
                        });
                    };
                    ' . (!$external ? ('func();') : ('GD.ExecuteTable' . intval($this->ReportConfig->getId()) . ' = func;')) . '
                    }(global.GD_jQuery ? global.GD_jQuery : jQuery);
                })(!window ? this : window);
            </script>'
        ;

        return $dataTableScript;
    }
"
                };
                global.GD.PivotTableFactory.createTable(<?php 
echo $reportId;
?>
, "#report-<?php 
echo $reportId;
?>
",
                    {
                        measures: <?php 
echo json_encode($measures);
?>
,
                        draft: <?php 
echo gd_datasource_is_property(gd_datasource_get_active(), 'draft') ? "true" : "false";
?>
,
                        rows: <?php 
echo isset($rows) ? json_encode($rows) : '[]';
?>
,
                        cols: <?php 
echo isset($cols) ? json_encode($cols) : '[]';
?>
,
                        columns: <?php 
echo json_encode($columns);
?>
,
                        url: urlOptions,