<commit_before>/*
 (c) 2013, Vladimir Agafonkin
 RBush, a JavaScript library for high-performance 2D spatial indexing of points and rectangles.
 https://github.com/mourner/rbush
*/

(function () { 'use strict';

function rbush(maxFill, minFill) {
    if (!(this instanceof rbush)) {
        // jshint newcap: false
        return new rbush(maxFill, minFill);
    }

    if (!maxFill) {
        throw new Error("Provide a maxFill argument to rbush constructor");
    }
    this._maxFill = Math.max(4, maxFill);

    if (!this._minFill) {
        this._minFill = Math.max(2, Math.floor(this._maxFill * 0.4));
    }
    this._minFill = minFill;
};

rbush.prototype = {

    // redefine the next 3 methods to suit your data format

    // compare functions for sorting by x and y coordinate
    sortX: function (a, b) { return a[0] > b[0] ? 1 : -1; },
    sortY: function (a, b) { return a[1] > b[1] ? 1 : -1; },

    // get bounding box in the form of [minX, minY, maxX, maxY] given a data item
    toBBox: function (a) { return a; },

    // recursively search for objects in a given bbox
    search: function (bbox) {
        var result = [];
        this._search(bbox, this.data, result);
        return result;
    },

    // bulk load all data and recursively build the tree from stratch
    load: function (data) {
        this.data = this._build(data.slice(), 0);
        this._calcBBoxes(this.data);

        return this;
    },

    addOne: function (item) {
        var node = this._chooseSubtree(this.toBBox(item), this.data);
        // TODO reinsert, split (choose split axis, choose split index), insert
    },

    toJSON: function () {
        return this.data;
    },

    fromJSON: function (data) {
        this.data = data;
        return this;
    },

    _search: function (bbox, node, result) {

        if (!this._intersects(bbox, node.bbox)) { return; }

        var i, child,
            len = node.children.length;

        for (i = 0; i < len; i++) {
            child = node.children[i];

            if (!node.leaf) {
                this._search(bbox, child, result);
            } else if (this._intersects(bbox, this.toBBox(child))) {
                result.push(child);
            }
        }
    },

    // bulk load data with the OMT algorithm
    _build: function (items, level) {

        var node = {},
            N = items.length,
            M = this._maxFill;

        if (N <= M) {
            node.children = items;
            node.leaf = true;
            return node;
        }

        node.children = [];

        if (!level) {
            // target number of root entries
            M = Math.ceil(N / Math.pow(M, Math.ceil(Math.log(N) / Math.log(M)) - 1));

            items.sort(this.sortX);
        }

        var N1 = Math.ceil(N / M) * Math.ceil(Math.sqrt(M)),
            N2 = Math.ceil(N / M),
            sortFn = level % 2 === 1 ? this.sortX : this.sortY,
            i, j, slice, sliceLen, childNode;

        // create S x S entries for the node and build from there recursively
        for (i = 0; i < N; i += N1) {
            slice = items.slice(i, i + N1).sort(sortFn);

            for (j = 0, sliceLen = slice.length; j < sliceLen; j += N2) {
                childNode = this._build(slice.slice(j, j + N2), level + 1);
                node.children.push(childNode);
            }
        }

        return node;
    },

    // recursively calculate all node bboxes in the tree
    _calcBBoxes: function (node) {

        node.bbox = [Infinity, Infinity, -Infinity, -Infinity];

        for (var i = 0, len = node.children.length, child; i < len; i++) {
            child = node.children[i];

            if (node.leaf) {
                this._extend(node.bbox, this.toBBox(child));
            } else {
                this._calcBBoxes(child);
                this._extend(node.bbox, child.bbox);
            }
        }
    },

    _chooseSubtree: function (bbox, node) {

        if (node.leaf) { return node; }

        var i, len, child, targetNode,
            area, enlargement, overlap, minArea, minEnlargement, minOverlap;

        minArea = minEnlargement = minOverlap = Infinity;

        for (var i = 0, len = node.children.length; i < len; i++) {
            child = node.children[i];

            area = this._area(child.bbox);
            enlargement = this._enlargedArea(bbox, child.bbox) - area;
            // overlap = child.leaf && this._overlapArea(bbox, child);

            // choose the node with the least overlap
            if (overlap < minOverlap) {
                minOverlap = overlap;
                targetNode = child;

            } else if (!overlap || overlap === minOverlap) {
                // otherwise choose one with the least area enlargement
                if (enlargement < minEnlargement) {
                    minEnlargement = enlargement;
                    targetNode = child;

                } else if (enlargement === minEnlargement) {
                    // otherwise choose one with the smallest area
                    if (area < minArea) {
                        minArea = area;
                        targetNode = child;
                    }
                }
            }
        }

        return this._chooseSubtree(bbox, targetNode);
    },

    _intersects: function (bbox, bbox2) {
        return bbox2[0] <= bbox[2] &&
               bbox2[1] <= bbox[3] &&
               bbox2[2] >= bbox[0] &&
               bbox2[3] >= bbox[1];
    },

    _extend: function (bbox, bbox2) {
        bbox[0] = Math.min(bbox[0], bbox2[0]);
        bbox[1] = Math.min(bbox[1], bbox2[1]);
        bbox[2] = Math.max(bbox[2], bbox2[2]);
        bbox[3] = Math.max(bbox[3], bbox2[3]);
    },

    _area: function (bbox) {
        return (bbox[2] - bbox[0]) * (bbox[3] - bbox[1]);
    },

    _enlargedArea: function (bbox, bbox2) {
        return (Math.max(bbox2[2], bbox[2]) - Math.min(bbox2[0], bbox[0])) *
               (Math.max(bbox2[3], bbox[3]) - Math.min(bbox2[1], bbox[1]));
    },

    _overlapArea: function (bbox, node) {
        for (var i = 0, sum = 0, len = node.children.length, bbox2; i < len; i++) {
            bbox2 = this.toBBox(node.children[i]);
            sum += this._intersects(bbox, bbox2) ? this._intersectionArea(bbox, bbox2) : 0;
        }
        return sum;
    },

    _intersectionArea: function (bbox, bbox2) {
        var minX = Math.max(bbox[0], bbox2[0]),
            maxX = Math.min(bbox[2], bbox2[2]),
            minY = Math.max(bbox[1], bbox2[1]),
            maxY = Math.min(bbox[3], bbox2[3]);

        return Math.max(0, maxX - minX) * Math.max(0, maxY - minY);
    }
};

if (typeof module !== 'undefined') {
    module.exports = rbush;
} else {
    window.rbush = rbush;
}

})();
<commit_msg>rename maxFill to maxEntries, remove minFill argument<commit_after>/*
 (c) 2013, Vladimir Agafonkin
 RBush, a JavaScript library for high-performance 2D spatial indexing of points and rectangles.
 https://github.com/mourner/rbush
*/

(function () { 'use strict';

function rbush(maxEntries) {
    if (!(this instanceof rbush)) {
        // jshint newcap: false
        return new rbush(maxEntries);
    }

    if (!maxEntries) {
        throw new Error("Provide a maxEntries argument to rbush constructor");
    }
    this._maxEntries = Math.max(4, maxEntries);
    this._minFill = Math.max(2, Math.floor(this._maxEntries * 0.4));
};

rbush.prototype = {

    // redefine the next 3 methods to suit your data format

    // compare functions for sorting by x and y coordinate
    sortX: function (a, b) { return a[0] > b[0] ? 1 : -1; },
    sortY: function (a, b) { return a[1] > b[1] ? 1 : -1; },

    // get bounding box in the form of [minX, minY, maxX, maxY] given a data item
    toBBox: function (a) { return a; },

    // recursively search for objects in a given bbox
    search: function (bbox) {
        var result = [];
        this._search(bbox, this.data, result);
        return result;
    },

    // bulk load all data and recursively build the tree from stratch
    load: function (data) {
        this.data = this._build(data.slice(), 0);
        this._calcBBoxes(this.data);

        return this;
    },

    addOne: function (item) {
        var node = this._chooseSubtree(this.toBBox(item), this.data);
        // TODO reinsert, split (choose split axis, choose split index), insert
    },

    toJSON: function () {
        return this.data;
    },

    fromJSON: function (data) {
        this.data = data;
        return this;
    },

    _search: function (bbox, node, result) {

        if (!this._intersects(bbox, node.bbox)) { return; }

        var i, child,
            len = node.children.length;

        for (i = 0; i < len; i++) {
            child = node.children[i];

            if (!node.leaf) {
                this._search(bbox, child, result);
            } else if (this._intersects(bbox, this.toBBox(child))) {
                result.push(child);
            }
        }
    },

    // bulk load data with the OMT algorithm
    _build: function (items, level) {

        var node = {},
            N = items.length,
            M = this._maxEntries;

        if (N <= M) {
            node.children = items;
            node.leaf = true;
            return node;
        }

        node.children = [];

        if (!level) {
            // target number of root entries
            M = Math.ceil(N / Math.pow(M, Math.ceil(Math.log(N) / Math.log(M)) - 1));

            items.sort(this.sortX);
        }

        var N1 = Math.ceil(N / M) * Math.ceil(Math.sqrt(M)),
            N2 = Math.ceil(N / M),
            sortFn = level % 2 === 1 ? this.sortX : this.sortY,
            i, j, slice, sliceLen, childNode;

        // create S x S entries for the node and build from there recursively
        for (i = 0; i < N; i += N1) {
            slice = items.slice(i, i + N1).sort(sortFn);

            for (j = 0, sliceLen = slice.length; j < sliceLen; j += N2) {
                childNode = this._build(slice.slice(j, j + N2), level + 1);
                node.children.push(childNode);
            }
        }

        return node;
    },

    // recursively calculate all node bboxes in the tree
    _calcBBoxes: function (node) {

        node.bbox = [Infinity, Infinity, -Infinity, -Infinity];

        for (var i = 0, len = node.children.length, child; i < len; i++) {
            child = node.children[i];

            if (node.leaf) {
                this._extend(node.bbox, this.toBBox(child));
            } else {
                this._calcBBoxes(child);
                this._extend(node.bbox, child.bbox);
            }
        }
    },

    _chooseSubtree: function (bbox, node) {

        if (node.leaf) { return node; }

        var i, len, child, targetNode,
            area, enlargement, overlap, minArea, minEnlargement, minOverlap;

        minArea = minEnlargement = minOverlap = Infinity;

        for (var i = 0, len = node.children.length; i < len; i++) {
            child = node.children[i];

            area = this._area(child.bbox);
            enlargement = this._enlargedArea(bbox, child.bbox) - area;
            // overlap = child.leaf && this._overlapArea(bbox, child);

            // choose the node with the least overlap
            if (overlap < minOverlap) {
                minOverlap = overlap;
                targetNode = child;

            } else if (!overlap || overlap === minOverlap) {
                // otherwise choose one with the least area enlargement
                if (enlargement < minEnlargement) {
                    minEnlargement = enlargement;
                    targetNode = child;

                } else if (enlargement === minEnlargement) {
                    // otherwise choose one with the smallest area
                    if (area < minArea) {
                        minArea = area;
                        targetNode = child;
                    }
                }
            }
        }

        return this._chooseSubtree(bbox, targetNode);
    },

    _intersects: function (bbox, bbox2) {
        return bbox2[0] <= bbox[2] &&
               bbox2[1] <= bbox[3] &&
               bbox2[2] >= bbox[0] &&
               bbox2[3] >= bbox[1];
    },

    _extend: function (bbox, bbox2) {
        bbox[0] = Math.min(bbox[0], bbox2[0]);
        bbox[1] = Math.min(bbox[1], bbox2[1]);
        bbox[2] = Math.max(bbox[2], bbox2[2]);
        bbox[3] = Math.max(bbox[3], bbox2[3]);
    },

    _area: function (bbox) {
        return (bbox[2] - bbox[0]) * (bbox[3] - bbox[1]);
    },

    _enlargedArea: function (bbox, bbox2) {
        return (Math.max(bbox2[2], bbox[2]) - Math.min(bbox2[0], bbox[0])) *
               (Math.max(bbox2[3], bbox[3]) - Math.min(bbox2[1], bbox[1]));
    },

    _overlapArea: function (bbox, node) {
        for (var i = 0, sum = 0, len = node.children.length, bbox2; i < len; i++) {
            bbox2 = this.toBBox(node.children[i]);
            sum += this._intersects(bbox, bbox2) ? this._intersectionArea(bbox, bbox2) : 0;
        }
        return sum;
    },

    _intersectionArea: function (bbox, bbox2) {
        var minX = Math.max(bbox[0], bbox2[0]),
            maxX = Math.min(bbox[2], bbox2[2]),
            minY = Math.max(bbox[1], bbox2[1]),
            maxY = Math.min(bbox[3], bbox2[3]);

        return Math.max(0, maxX - minX) * Math.max(0, maxY - minY);
    }
};

if (typeof module !== 'undefined') {
    module.exports = rbush;
} else {
    window.rbush = rbush;
}

})();
<|endoftext|>


<commit_before>module.exports = {
  plugins: [
    'react'
  ],
  ecmaFeatures: {
    jsx: true
  },

  rules: {
    // JSX //
    //-----//
    'jsx-quotes': [2, 'prefer-double'],

    // React //
    //-------//
    'react/display-name': [2, { ignoreTranspilerName: true }],
    'react/jsx-boolean-value': 2,
    'react/jsx-closing-bracket-location': [2, {location: 'tag-aligned'}],
    'react/jsx-curly-spacing': [2, 'never'],
    'react/jsx-indent-props': [2, 4],
    'react/jsx-max-props-per-line': 0,
    'react/jsx-no-duplicate-props': 2,
    'react/jsx-no-literals': 0,
    'react/jsx-no-undef': 2,
    'react/jsx-sort-prop-types': 0,
    'react/jsx-sort-props': 0,
    'react/jsx-uses-react': 2,
    'react/jsx-uses-vars': 2,
    'react/no-danger': 2,
    'react/no-did-mount-set-state': 1,
    'react/no-did-update-set-state': 1,
    'react/no-multi-comp': 2,
    'react/no-set-state': 0,
    'react/no-unknown-property': 2,
    'react/prop-types': 1,
    'react/react-in-jsx-scope': 2,
    'react/self-closing-comp': 2,
    'react/sort-comp': 0,
    'react/jsx-wrap-multilines': 2
  }
};
<commit_msg>Use transpiler name for display name when available<commit_after>module.exports = {
  plugins: [
    'react'
  ],
  ecmaFeatures: {
    jsx: true
  },

  rules: {
    // JSX //
    //-----//
    'jsx-quotes': [2, 'prefer-double'],

    // React //
    //-------//
    'react/display-name': [2, { ignoreTranspilerName: false }],
    'react/jsx-boolean-value': 2,
    'react/jsx-closing-bracket-location': [2, {location: 'tag-aligned'}],
    'react/jsx-curly-spacing': [2, 'never'],
    'react/jsx-indent-props': [2, 4],
    'react/jsx-max-props-per-line': 0,
    'react/jsx-no-duplicate-props': 2,
    'react/jsx-no-literals': 0,
    'react/jsx-no-undef': 2,
    'react/jsx-sort-prop-types': 0,
    'react/jsx-sort-props': 0,
    'react/jsx-uses-react': 2,
    'react/jsx-uses-vars': 2,
    'react/no-danger': 2,
    'react/no-did-mount-set-state': 1,
    'react/no-did-update-set-state': 1,
    'react/no-multi-comp': 2,
    'react/no-set-state': 0,
    'react/no-unknown-property': 2,
    'react/prop-types': 1,
    'react/react-in-jsx-scope': 2,
    'react/self-closing-comp': 2,
    'react/sort-comp': 0,
    'react/jsx-wrap-multilines': 2
  }
};
<|endoftext|>


<commit_before>Session.setDefault('showLoadingText', true);

Template.worklistResult.helpers({
    /**
     * Returns a sorted instance of the WorklistStudies Collection
     * by Patient name and Study Date in Ascending order.
     */
    studies() {
        const instance = Template.instance();
        let studies;
        let sortOption = {
            patientName: 1,
            studyDate: 1
        };

        // Update sort option if session is defined
        if (Session.get('sortOption')) {
            sortOption = Session.get('sortOption');
        }

        // Pagination parameters
        const rowsPerPage = instance.rowsPerPage.get();
        const currentPage = instance.currentPage.get();
        const offset = rowsPerPage * currentPage;
        const limit = offset + rowsPerPage;

        studies = WorklistStudies.find({}, {
            sort: sortOption
        }).fetch();

        if (!studies) {
            return;
        }

        // Update record count
        instance.recordCount.set(studies.length);

        // Limit studies
        return studies.slice(offset, limit);
    },

    numberOfStudies() {
        return WorklistStudies.find().count();
    },

    sortingColumnsIcons() {
        const instance = Template.instance();

        let sortingColumnsIcons = {};
        Object.keys(instance.sortingColumns.keys).forEach(key => {
            const value = instance.sortingColumns.get(key);

            if (value === 1) {
                sortingColumnsIcons[key] = 'fa fa-fw fa-sort-up';
            } else if (value === -1) {
                sortingColumnsIcons[key] = 'fa fa-fw fa-sort-down';
            } else {
                // fa-fw is blank
                sortingColumnsIcons[key] = 'fa fa-fw';
            }
        });
        return sortingColumnsIcons;
    }
});

var studyDateFrom;
var studyDateTo;
var filter;

/**
 * Transforms an input string into a search filter for
 * the Worklist Search call
 *
 * @param filter The input string to be searched for
 * @returns {*}
 */
function getFilter(filter) {
    if (filter && filter.length && filter.substr(filter.length - 1) !== '*') {
        filter += '*';
    }

    return filter;
}

/**
 * Search for a value in a string
 */
function isIndexOf(mainVal, searchVal) {
    if (mainVal === undefined || mainVal === '' || mainVal.indexOf(searchVal) > -1){
        return true;
    }

    return false;
}

/**
 * Replace object if undefined
 */
function replaceUndefinedColumnValue(text) {
    if (text === undefined || text === 'undefined') {
        return '';
    } else {
        return text.toUpperCase();
    }
}

/**

/**
 * Convert string to study date
 */
function convertStringToStudyDate(dateStr) {
    const y = dateStr.substring(0, 4);
    const m = dateStr.substring(4, 6);
    const d = dateStr.substring(6, 8);
    const newDateStr = m + '/' + d + '/' + y;
    return new Date(newDateStr);
}

/**
 * Runs a search for studies matching the worklist query parameters
 * Inserts the identified studies into the WorklistStudies Collection
 */
function search() {
    console.log('search()');

    // Show loading message
    Session.set('showLoadingText', true);

    // Create the filters to be used for the Worklist Search
    filter = {
        patientName: getFilter($('input#patientName').val()),
        patientId: getFilter($('input#patientId').val()),
        accessionNumber: getFilter($('input#accessionNumber').val()),
        studyDescription: getFilter($('input#studyDescription').val()),
        studyDateFrom: studyDateFrom,
        studyDateTo: studyDateTo
    };

    // Make sure that modality has a reasonable value, since it is occasionally
    // returned as 'undefined'
    const modality = replaceUndefinedColumnValue($('input#modality').val());

    // Clear all current studies
    WorklistStudies.remove({});

    Meteor.call('WorklistSearch', filter, (error, studies) => {
        console.log('WorklistSearch');
        if (error) {
            log.warn(error);
            return;
        }

        // Hide loading text
        Session.set('showLoadingText', false);

        if (!studies) {
            return;
        }

        // Loop through all identified studies
        studies.forEach(study => {
            // Search the rest of the parameters that aren't done via the server call
            if (isIndexOf(study.modalities, modality) &&
                (new Date(studyDateFrom).setHours(0, 0, 0, 0) <= convertStringToStudyDate(study.studyDate) || !studyDateFrom || studyDateFrom === '') &&
                (convertStringToStudyDate(study.studyDate) <= new Date(studyDateTo).setHours(0, 0, 0, 0) || !studyDateTo || studyDateTo === '')) {

                // Convert numberOfStudyRelatedInstance string into integer
                study.numberOfStudyRelatedInstances = !isNaN(study.numberOfStudyRelatedInstances) ? parseInt(study.numberOfStudyRelatedInstances) : 0;

                // Insert any matching studies into the WorklistStudies Collection
                WorklistStudies.insert(study);
            }
        });
    });
}

Template.worklistResult.onCreated(() => {
    let instance = Template.instance();
    instance.sortOption = new ReactiveVar();
    instance.sortingColumns = new ReactiveDict();

    // Pagination parameters

    // Rows per page is 25 as default
    instance.rowsPerPage = new ReactiveVar(25);

    // Set currentPage indexed 0
    instance.currentPage = new ReactiveVar(0);
    instance.recordCount = new ReactiveVar();

    // Set sortOption
    const sortOptionSession = Session.get('sortOption');
    if (sortOptionSession) {
        instance.sortingColumns.set(sortOptionSession);
    } else {
        instance.sortingColumns.set({
            patientName: 1,
            studyDate: 1,
            patientId: 0,
            accessionNumber: 0,
            studyDescription: 0,
            modality: 0,
            numberOfStudyRelatedInstances: 0
        });
    }

    if (Worklist.subscriptions) {
        Worklist.subscriptions.forEach(collectionName => {
            instance.subscribe(collectionName);
        });
    }
});

Template.worklistResult.onRendered(() => {
    const instance = Template.instance();

    // Initialize daterangepicker
    instance.$('#studyDate').daterangepicker({
        ranges: {
            Today: [moment(), moment()],
            'Last 7 Days': [moment().subtract(6, 'days'), moment()],
            'Last 30 Days': [moment().subtract(29, 'days'), moment()]
        }
    });

    // Retrieve all studies
    search();
});

function resetSortingColumns(instance, sortingColumn) {
    Object.keys(instance.sortingColumns.keys).forEach(key => {
        if (key !== sortingColumn) {
            instance.sortingColumns.set(key, null);
        }
    });
}

Template.worklistResult.events({
    'keydown input'(event) {
        if (event.which === 13) { //  Enter
            search();
        }
    },

    'onsearch input'() {
        search();
    },

    'change #studyDate'(event) {
        let dateRange = $(event.currentTarget).val();

        // Remove all space chars
        dateRange = dateRange.replace(/ /g, '');

        // Split dateRange into subdates
        const dates = dateRange.split('-');
        studyDateFrom = dates[0];
        studyDateTo = dates[1];

        if (dateRange !== '') {
            search();
        }
    },

    'click div.sortingCell'(event, instance) {
        const elementId = event.currentTarget.id;

        // Remove _ from id
        const columnName = elementId.replace('_', '');

        let sortOption = {};
        resetSortingColumns(instance, columnName);

        const columnObject = instance.sortingColumns.get(columnName);
        if (columnObject) {
            instance.sortingColumns.set(columnName, columnObject * -1);
            sortOption[columnName] = columnObject * -1;
        } else {
            instance.sortingColumns.set(columnName, 1);
            sortOption[columnName] = 1;
        }

        instance.sortOption.set(sortOption);
        Session.set('sortOption', sortOption);
    }
});

<commit_msg>change default study level instance number to undefined<commit_after>Session.setDefault('showLoadingText', true);

Template.worklistResult.helpers({
    /**
     * Returns a sorted instance of the WorklistStudies Collection
     * by Patient name and Study Date in Ascending order.
     */
    studies() {
        const instance = Template.instance();
        let studies;
        let sortOption = {
            patientName: 1,
            studyDate: 1
        };

        // Update sort option if session is defined
        if (Session.get('sortOption')) {
            sortOption = Session.get('sortOption');
        }

        // Pagination parameters
        const rowsPerPage = instance.rowsPerPage.get();
        const currentPage = instance.currentPage.get();
        const offset = rowsPerPage * currentPage;
        const limit = offset + rowsPerPage;

        studies = WorklistStudies.find({}, {
            sort: sortOption
        }).fetch();

        if (!studies) {
            return;
        }

        // Update record count
        instance.recordCount.set(studies.length);

        // Limit studies
        return studies.slice(offset, limit);
    },

    numberOfStudies() {
        return WorklistStudies.find().count();
    },

    sortingColumnsIcons() {
        const instance = Template.instance();

        let sortingColumnsIcons = {};
        Object.keys(instance.sortingColumns.keys).forEach(key => {
            const value = instance.sortingColumns.get(key);

            if (value === 1) {
                sortingColumnsIcons[key] = 'fa fa-fw fa-sort-up';
            } else if (value === -1) {
                sortingColumnsIcons[key] = 'fa fa-fw fa-sort-down';
            } else {
                // fa-fw is blank
                sortingColumnsIcons[key] = 'fa fa-fw';
            }
        });
        return sortingColumnsIcons;
    }
});

var studyDateFrom;
var studyDateTo;
var filter;

/**
 * Transforms an input string into a search filter for
 * the Worklist Search call
 *
 * @param filter The input string to be searched for
 * @returns {*}
 */
function getFilter(filter) {
    if (filter && filter.length && filter.substr(filter.length - 1) !== '*') {
        filter += '*';
    }

    return filter;
}

/**
 * Search for a value in a string
 */
function isIndexOf(mainVal, searchVal) {
    if (mainVal === undefined || mainVal === '' || mainVal.indexOf(searchVal) > -1){
        return true;
    }

    return false;
}

/**
 * Replace object if undefined
 */
function replaceUndefinedColumnValue(text) {
    if (text === undefined || text === 'undefined') {
        return '';
    } else {
        return text.toUpperCase();
    }
}

/**

/**
 * Convert string to study date
 */
function convertStringToStudyDate(dateStr) {
    const y = dateStr.substring(0, 4);
    const m = dateStr.substring(4, 6);
    const d = dateStr.substring(6, 8);
    const newDateStr = m + '/' + d + '/' + y;
    return new Date(newDateStr);
}

/**
 * Runs a search for studies matching the worklist query parameters
 * Inserts the identified studies into the WorklistStudies Collection
 */
function search() {
    console.log('search()');

    // Show loading message
    Session.set('showLoadingText', true);

    // Create the filters to be used for the Worklist Search
    filter = {
        patientName: getFilter($('input#patientName').val()),
        patientId: getFilter($('input#patientId').val()),
        accessionNumber: getFilter($('input#accessionNumber').val()),
        studyDescription: getFilter($('input#studyDescription').val()),
        studyDateFrom: studyDateFrom,
        studyDateTo: studyDateTo
    };

    // Make sure that modality has a reasonable value, since it is occasionally
    // returned as 'undefined'
    const modality = replaceUndefinedColumnValue($('input#modality').val());

    // Clear all current studies
    WorklistStudies.remove({});

    Meteor.call('WorklistSearch', filter, (error, studies) => {
        console.log('WorklistSearch');
        if (error) {
            log.warn(error);
            return;
        }

        // Hide loading text
        Session.set('showLoadingText', false);

        if (!studies) {
            return;
        }

        // Loop through all identified studies
        studies.forEach(study => {
            // Search the rest of the parameters that aren't done via the server call
            if (isIndexOf(study.modalities, modality) &&
                (new Date(studyDateFrom).setHours(0, 0, 0, 0) <= convertStringToStudyDate(study.studyDate) || !studyDateFrom || studyDateFrom === '') &&
                (convertStringToStudyDate(study.studyDate) <= new Date(studyDateTo).setHours(0, 0, 0, 0) || !studyDateTo || studyDateTo === '')) {

                // Convert numberOfStudyRelatedInstance string into integer
                study.numberOfStudyRelatedInstances = !isNaN(study.numberOfStudyRelatedInstances) ? parseInt(study.numberOfStudyRelatedInstances) : undefined;

                // Insert any matching studies into the WorklistStudies Collection
                WorklistStudies.insert(study);
            }
        });
    });
}

Template.worklistResult.onCreated(() => {
    let instance = Template.instance();
    instance.sortOption = new ReactiveVar();
    instance.sortingColumns = new ReactiveDict();

    // Pagination parameters

    // Rows per page is 25 as default
    instance.rowsPerPage = new ReactiveVar(25);

    // Set currentPage indexed 0
    instance.currentPage = new ReactiveVar(0);
    instance.recordCount = new ReactiveVar();

    // Set sortOption
    const sortOptionSession = Session.get('sortOption');
    if (sortOptionSession) {
        instance.sortingColumns.set(sortOptionSession);
    } else {
        instance.sortingColumns.set({
            patientName: 1,
            studyDate: 1,
            patientId: 0,
            accessionNumber: 0,
            studyDescription: 0,
            modality: 0,
            numberOfStudyRelatedInstances: 0
        });
    }

    if (Worklist.subscriptions) {
        Worklist.subscriptions.forEach(collectionName => {
            instance.subscribe(collectionName);
        });
    }
});

Template.worklistResult.onRendered(() => {
    const instance = Template.instance();

    // Initialize daterangepicker
    instance.$('#studyDate').daterangepicker({
        ranges: {
            Today: [moment(), moment()],
            'Last 7 Days': [moment().subtract(6, 'days'), moment()],
            'Last 30 Days': [moment().subtract(29, 'days'), moment()]
        }
    });

    // Retrieve all studies
    search();
});

function resetSortingColumns(instance, sortingColumn) {
    Object.keys(instance.sortingColumns.keys).forEach(key => {
        if (key !== sortingColumn) {
            instance.sortingColumns.set(key, null);
        }
    });
}

Template.worklistResult.events({
    'keydown input'(event) {
        if (event.which === 13) { //  Enter
            search();
        }
    },

    'onsearch input'() {
        search();
    },

    'change #studyDate'(event) {
        let dateRange = $(event.currentTarget).val();

        // Remove all space chars
        dateRange = dateRange.replace(/ /g, '');

        // Split dateRange into subdates
        const dates = dateRange.split('-');
        studyDateFrom = dates[0];
        studyDateTo = dates[1];

        if (dateRange !== '') {
            search();
        }
    },

    'click div.sortingCell'(event, instance) {
        const elementId = event.currentTarget.id;

        // Remove _ from id
        const columnName = elementId.replace('_', '');

        let sortOption = {};
        resetSortingColumns(instance, columnName);

        const columnObject = instance.sortingColumns.get(columnName);
        if (columnObject) {
            instance.sortingColumns.set(columnName, columnObject * -1);
            sortOption[columnName] = columnObject * -1;
        } else {
            instance.sortingColumns.set(columnName, 1);
            sortOption[columnName] = 1;
        }

        instance.sortOption.set(sortOption);
        Session.set('sortOption', sortOption);
    }
});

<|endoftext|>


<commit_before>import { setupRerender } from 'preact/test-utils';
import React, {
	createElement,
	hydrate,
	Component,
	Fragment,
	Suspense
} from 'preact/compat';
import { logCall, getLog, clearLog } from '../../../test/_util/logCall';
import {
	createEvent,
	setupScratch,
	teardown
} from '../../../test/_util/helpers';
import { ul, li } from '../../../test/_util/dom';
import { createLazy } from './suspense-utils';

/* eslint-env browser, mocha */
describe('suspense hydration', () => {
	/** @type {HTMLDivElement} */
	let scratch,
		rerender,
		unhandledEvents = [];

	const List = ({ children }) =>
{children}
;
	const ListItem = ({ children, onClick = null }) => (

{children}

	);

	function onUnhandledRejection(event) {
		unhandledEvents.push(event);
	}

	/** @type {() => void} */
	let increment;
	class Counter extends Component {
		constructor(props) {
			super(props);

			this.state = { count: 0 };
			increment = () => this.setState({ count: ++this.state.count });
		}

		render(props, { count }) {
			return
Count: {count}
;
		}
	}

	let resetAppendChild;
	let resetInsertBefore;
	let resetRemoveChild;
	let resetRemove;

	before(() => {
		resetAppendChild = logCall(Element.prototype, 'appendChild');
		resetInsertBefore = logCall(Element.prototype, 'insertBefore');
		resetRemoveChild = logCall(Element.prototype, 'removeChild');
		resetRemove = logCall(Element.prototype, 'remove');
	});

	after(() => {
		resetAppendChild();
		resetInsertBefore();
		resetRemoveChild();
		resetRemove();
	});

	beforeEach(() => {
		scratch = setupScratch();
		rerender = setupRerender();

		unhandledEvents = [];
		if ('onunhandledrejection' in window) {
			window.addEventListener('unhandledrejection', onUnhandledRejection);
		}
	});

	afterEach(() => {
		teardown(scratch);

		if ('onunhandledrejection' in window) {
			window.removeEventListener('unhandledrejection', onUnhandledRejection);

			if (unhandledEvents.length) {
				throw unhandledEvents[0].reason;
			}
		}
	});

	it('should leave DOM untouched when suspending while hydrating', () => {
		scratch.innerHTML = '
Hello
';
		clearLog();

		const [Lazy, resolve] = createLazy();
		hydrate(
			<Suspense>
				<Lazy />
			</Suspense>,
			scratch
		);
		rerender(); // Flush rerender queue to mimic what preact will really do
		expect(scratch.innerHTML).to.equal('
Hello
');
		expect(getLog()).to.deep.equal([]);
		clearLog();

		return resolve(() =>
Hello
).then(() => {
			rerender();
			expect(scratch.innerHTML).to.equal('
Hello
');
			expect(getLog()).to.deep.equal([]);
			clearLog();
		});
	});

	it('should properly attach event listeners when suspending while hydrating', () => {
		scratch.innerHTML = '
Hello

World
';
		clearLog();

		const helloListener = sinon.spy();
		const worldListener = sinon.spy();

		const [Lazy, resolve] = createLazy();
		hydrate(
			<Suspense>
				<Lazy />

World!

			</Suspense>,
			scratch
		);
		rerender(); // Flush rerender queue to mimic what preact will really do
		expect(scratch.innerHTML).to.equal('
Hello

World!
');
		expect(getLog()).to.deep.equal([]);
		clearLog();

		scratch.querySelector('div:last-child').dispatchEvent(createEvent('click'));
		expect(worldListener, 'worldListener 1').to.have.been.calledOnce;

		return resolve(() =>
Hello
).then(() => {
			rerender();
			expect(scratch.innerHTML).to.equal('
Hello

World!
');
			expect(getLog()).to.deep.equal([]);

			scratch
				.querySelector('div:first-child')
				.dispatchEvent(createEvent('click'));
			expect(helloListener, 'helloListener').to.have.been.calledOnce;

			scratch
				.querySelector('div:last-child')
				.dispatchEvent(createEvent('click'));
			expect(worldListener, 'worldListener 2').to.have.been.calledTwice;

			clearLog();
		});
	});

	it('should allow siblings to update around suspense boundary', () => {
		scratch.innerHTML = '
Count: 0

Hello
';
		clearLog();

		const [Lazy, resolve] = createLazy();
		hydrate(
			<Fragment>
				<Counter />
				<Suspense>
					<Lazy />
				</Suspense>
			</Fragment>,
			scratch
		);
		rerender(); // Flush rerender queue to mimic what preact will really do
		expect(scratch.innerHTML).to.equal('
Count: 0

Hello
');
		// Re: DOM OP below - Known issue with hydrating merged text nodes
		expect(getLog()).to.deep.equal(['
Count: .appendChild(#text)']);
		clearLog();

		increment();
		rerender();

		expect(scratch.innerHTML).to.equal('
Count: 1

Hello
');
		expect(getLog()).to.deep.equal([]);
		clearLog();

		return resolve(() =>
Hello
).then(() => {
			rerender();
			expect(scratch.innerHTML).to.equal('
Count: 1

Hello
');
			expect(getLog()).to.deep.equal([]);
			clearLog();
		});
	});

	it('should properly hydrate when there is DOM and Components between Suspense and suspender', () => {
		scratch.innerHTML = '

Hello

';
		clearLog();

		const [Lazy, resolve] = createLazy();
		hydrate(
			<Suspense>

					<Fragment>
						<Lazy />
					</Fragment>

			</Suspense>,
			scratch
		);
		rerender(); // Flush rerender queue to mimic what preact will really do
		expect(scratch.innerHTML).to.equal('

Hello

');
		expect(getLog()).to.deep.equal([]);
		clearLog();

		return resolve(() =>
Hello
).then(() => {
			rerender();
			expect(scratch.innerHTML).to.equal('

Hello

');
			expect(getLog()).to.deep.equal([]);
			clearLog();
		});
	});

	it('should properly hydrate suspense with Fragment siblings', () => {
		const originalHtml = ul(
			[li(0), li(1), li(2), li(3), li(4), li(5)].join('')
		);

		const listeners = [
			sinon.spy(),
			sinon.spy(),
			sinon.spy(),
			sinon.spy(),
			sinon.spy(),
			sinon.spy()
		];

		scratch.innerHTML = originalHtml;
		clearLog();

		const [Lazy, resolve] = createLazy();
		hydrate(

				<Fragment>

0

1

				</Fragment>
				<Suspense>
					<Lazy />
				</Suspense>
				<Fragment>

4

5

				</Fragment>

,
			scratch
		);
		rerender(); // Flush rerender queue to mimic what preact will really do
		expect(scratch.innerHTML).to.equal(originalHtml);
		expect(getLog()).to.deep.equal([]);
		expect(listeners[5]).not.to.have.been.called;

		clearLog();
		scratch.querySelector('li:last-child').dispatchEvent(createEvent('click'));
		expect(listeners[5]).to.have.been.calledOnce;

		return resolve(() => (
			<Fragment>

2

3

			</Fragment>
		)).then(() => {
			rerender();
			expect(scratch.innerHTML).to.equal(originalHtml);
			expect(getLog()).to.deep.equal([]);
			clearLog();

			scratch
				.querySelector('li:nth-child(4)')
				.dispatchEvent(createEvent('click'));
			expect(listeners[3]).to.have.been.calledOnce;

			scratch
				.querySelector('li:last-child')
				.dispatchEvent(createEvent('click'));
			expect(listeners[5]).to.have.been.calledTwice;
		});
	});

	it('should properly hydrate suspense with Component & Fragment siblings', () => {
		const originalHtml = ul(
			[li(0), li(1), li(2), li(3), li(4), li(5)].join('')
		);

		const listeners = [
			sinon.spy(),
			sinon.spy(),
			sinon.spy(),
			sinon.spy(),
			sinon.spy(),
			sinon.spy()
		];

		scratch.innerHTML = originalHtml;
		clearLog();

		const [Lazy, resolve] = createLazy();
		hydrate(
			<List>
				<Fragment>
					<ListItem onClick={listeners[0]}>0</ListItem>
					<ListItem onClick={listeners[1]}>1</ListItem>
				</Fragment>
				<Suspense>
					<Lazy />
				</Suspense>
				<Fragment>
					<ListItem onClick={listeners[4]}>4</ListItem>
					<ListItem onClick={listeners[5]}>5</ListItem>
				</Fragment>
			</List>,
			scratch
		);
		rerender(); // Flush rerender queue to mimic what preact will really do
		expect(scratch.innerHTML).to.equal(originalHtml);
		expect(getLog()).to.deep.equal([]);
		expect(listeners[5]).not.to.have.been.called;

		clearLog();
		scratch.querySelector('li:last-child').dispatchEvent(createEvent('click'));
		expect(listeners[5]).to.have.been.calledOnce;

		return resolve(() => (
			<Fragment>
				<ListItem onClick={listeners[2]}>2</ListItem>
				<ListItem onClick={listeners[3]}>3</ListItem>
			</Fragment>
		)).then(() => {
			rerender();
			expect(scratch.innerHTML).to.equal(originalHtml);
			expect(getLog()).to.deep.equal([]);
			clearLog();

			scratch
				.querySelector('li:nth-child(4)')
				.dispatchEvent(createEvent('click'));
			expect(listeners[3]).to.have.been.calledOnce;

			scratch
				.querySelector('li:last-child')
				.dispatchEvent(createEvent('click'));
			expect(listeners[5]).to.have.been.calledTwice;
		});
	});

	// TODO:
	// 1. What if props change between when hydrate suspended and suspense
	//    resolves?
	// 2. If using real Suspense, test re-suspending after hydrate suspense
	// 3. Put some DOM and components with state and event listeners between
	//    suspender and Suspense boundary
	// 4. Put some sibling DOM and components with state and event listeners
	//    sibling to suspender and under Suspense boundary
});
<commit_msg>Isolate test case where lazy resolves to a Fragment<commit_after>import { setupRerender } from 'preact/test-utils';
import React, {
	createElement,
	hydrate,
	Component,
	Fragment,
	Suspense
} from 'preact/compat';
import { logCall, getLog, clearLog } from '../../../test/_util/logCall';
import {
	createEvent,
	setupScratch,
	teardown
} from '../../../test/_util/helpers';
import { ul, li } from '../../../test/_util/dom';
import { createLazy } from './suspense-utils';

/* eslint-env browser, mocha */
describe('suspense hydration', () => {
	/** @type {HTMLDivElement} */
	let scratch,
		rerender,
		unhandledEvents = [];

	const List = ({ children }) =>
{children}
;
	const ListItem = ({ children, onClick = null }) => (

{children}

	);

	function onUnhandledRejection(event) {
		unhandledEvents.push(event);
	}

	/** @type {() => void} */
	let increment;
	class Counter extends Component {
		constructor(props) {
			super(props);

			this.state = { count: 0 };
			increment = () => this.setState({ count: ++this.state.count });
		}

		render(props, { count }) {
			return
Count: {count}
;
		}
	}

	let resetAppendChild;
	let resetInsertBefore;
	let resetRemoveChild;
	let resetRemove;

	before(() => {
		resetAppendChild = logCall(Element.prototype, 'appendChild');
		resetInsertBefore = logCall(Element.prototype, 'insertBefore');
		resetRemoveChild = logCall(Element.prototype, 'removeChild');
		resetRemove = logCall(Element.prototype, 'remove');
	});

	after(() => {
		resetAppendChild();
		resetInsertBefore();
		resetRemoveChild();
		resetRemove();
	});

	beforeEach(() => {
		scratch = setupScratch();
		rerender = setupRerender();

		unhandledEvents = [];
		if ('onunhandledrejection' in window) {
			window.addEventListener('unhandledrejection', onUnhandledRejection);
		}
	});

	afterEach(() => {
		teardown(scratch);

		if ('onunhandledrejection' in window) {
			window.removeEventListener('unhandledrejection', onUnhandledRejection);

			if (unhandledEvents.length) {
				throw unhandledEvents[0].reason;
			}
		}
	});

	it('should leave DOM untouched when suspending while hydrating', () => {
		scratch.innerHTML = '
Hello
';
		clearLog();

		const [Lazy, resolve] = createLazy();
		hydrate(
			<Suspense>
				<Lazy />
			</Suspense>,
			scratch
		);
		rerender(); // Flush rerender queue to mimic what preact will really do
		expect(scratch.innerHTML).to.equal('
Hello
');
		expect(getLog()).to.deep.equal([]);
		clearLog();

		return resolve(() =>
Hello
).then(() => {
			rerender();
			expect(scratch.innerHTML).to.equal('
Hello
');
			expect(getLog()).to.deep.equal([]);
			clearLog();
		});
	});

	it('should properly attach event listeners when suspending while hydrating', () => {
		scratch.innerHTML = '
Hello

World
';
		clearLog();

		const helloListener = sinon.spy();
		const worldListener = sinon.spy();

		const [Lazy, resolve] = createLazy();
		hydrate(
			<Suspense>
				<Lazy />

World!

			</Suspense>,
			scratch
		);
		rerender(); // Flush rerender queue to mimic what preact will really do
		expect(scratch.innerHTML).to.equal('
Hello

World!
');
		expect(getLog()).to.deep.equal([]);
		clearLog();

		scratch.querySelector('div:last-child').dispatchEvent(createEvent('click'));
		expect(worldListener, 'worldListener 1').to.have.been.calledOnce;

		return resolve(() =>
Hello
).then(() => {
			rerender();
			expect(scratch.innerHTML).to.equal('
Hello

World!
');
			expect(getLog()).to.deep.equal([]);

			scratch
				.querySelector('div:first-child')
				.dispatchEvent(createEvent('click'));
			expect(helloListener, 'helloListener').to.have.been.calledOnce;

			scratch
				.querySelector('div:last-child')
				.dispatchEvent(createEvent('click'));
			expect(worldListener, 'worldListener 2').to.have.been.calledTwice;

			clearLog();
		});
	});

	it('should allow siblings to update around suspense boundary', () => {
		scratch.innerHTML = '
Count: 0

Hello
';
		clearLog();

		const [Lazy, resolve] = createLazy();
		hydrate(
			<Fragment>
				<Counter />
				<Suspense>
					<Lazy />
				</Suspense>
			</Fragment>,
			scratch
		);
		rerender(); // Flush rerender queue to mimic what preact will really do
		expect(scratch.innerHTML).to.equal('
Count: 0

Hello
');
		// Re: DOM OP below - Known issue with hydrating merged text nodes
		expect(getLog()).to.deep.equal(['
Count: .appendChild(#text)']);
		clearLog();

		increment();
		rerender();

		expect(scratch.innerHTML).to.equal('
Count: 1

Hello
');
		expect(getLog()).to.deep.equal([]);
		clearLog();

		return resolve(() =>
Hello
).then(() => {
			rerender();
			expect(scratch.innerHTML).to.equal('
Count: 1

Hello
');
			expect(getLog()).to.deep.equal([]);
			clearLog();
		});
	});

	it('should properly hydrate when there is DOM and Components between Suspense and suspender', () => {
		scratch.innerHTML = '

Hello

';
		clearLog();

		const [Lazy, resolve] = createLazy();
		hydrate(
			<Suspense>

					<Fragment>
						<Lazy />
					</Fragment>

			</Suspense>,
			scratch
		);
		rerender(); // Flush rerender queue to mimic what preact will really do
		expect(scratch.innerHTML).to.equal('

Hello

');
		expect(getLog()).to.deep.equal([]);
		clearLog();

		return resolve(() =>
Hello
).then(() => {
			rerender();
			expect(scratch.innerHTML).to.equal('

Hello

');
			expect(getLog()).to.deep.equal([]);
			clearLog();
		});
	});

	it('should properly hydrate suspense with Fragment siblings', () => {
		const originalHtml = ul([li(0), li(1), li(2), li(3), li(4)].join(''));

		const listeners = [
			sinon.spy(),
			sinon.spy(),
			sinon.spy(),
			sinon.spy(),
			sinon.spy()
		];

		scratch.innerHTML = originalHtml;
		clearLog();

		const [Lazy, resolve] = createLazy();
		hydrate(

				<Fragment>

0

1

				</Fragment>
				<Suspense>
					<Lazy />
				</Suspense>
				<Fragment>

3

4

				</Fragment>

,
			scratch
		);
		rerender(); // Flush rerender queue to mimic what preact will really do
		expect(scratch.innerHTML).to.equal(originalHtml);
		expect(getLog()).to.deep.equal([]);
		expect(listeners[4]).not.to.have.been.called;

		clearLog();
		scratch.querySelector('li:last-child').dispatchEvent(createEvent('click'));
		expect(listeners[4]).to.have.been.calledOnce;

		return resolve(() => (
			<Fragment>

2

			</Fragment>
		)).then(() => {
			rerender();
			expect(scratch.innerHTML).to.equal(originalHtml);
			expect(getLog()).to.deep.equal([]);
			clearLog();

			scratch
				.querySelector('li:nth-child(3)')
				.dispatchEvent(createEvent('click'));
			expect(listeners[2]).to.have.been.calledOnce;

			scratch
				.querySelector('li:last-child')
				.dispatchEvent(createEvent('click'));
			expect(listeners[4]).to.have.been.calledTwice;
		});
	});

	it('should properly hydrate suspense with Component & Fragment siblings', () => {
		const originalHtml = ul([li(0), li(1), li(2), li(3), li(4)].join(''));

		const listeners = [
			sinon.spy(),
			sinon.spy(),
			sinon.spy(),
			sinon.spy(),
			sinon.spy()
		];

		scratch.innerHTML = originalHtml;
		clearLog();

		const [Lazy, resolve] = createLazy();
		hydrate(
			<List>
				<Fragment>
					<ListItem onClick={listeners[0]}>0</ListItem>
					<ListItem onClick={listeners[1]}>1</ListItem>
				</Fragment>
				<Suspense>
					<Lazy />
				</Suspense>
				<Fragment>
					<ListItem onClick={listeners[3]}>3</ListItem>
					<ListItem onClick={listeners[4]}>4</ListItem>
				</Fragment>
			</List>,
			scratch
		);
		rerender(); // Flush rerender queue to mimic what preact will really do
		expect(scratch.innerHTML).to.equal(originalHtml);
		expect(getLog()).to.deep.equal([]);
		expect(listeners[4]).not.to.have.been.called;

		clearLog();
		scratch.querySelector('li:last-child').dispatchEvent(createEvent('click'));
		expect(listeners[4]).to.have.been.calledOnce;

		return resolve(() => (
			<Fragment>
				<ListItem onClick={listeners[2]}>2</ListItem>
			</Fragment>
		)).then(() => {
			rerender();
			expect(scratch.innerHTML).to.equal(originalHtml);
			expect(getLog()).to.deep.equal([]);
			clearLog();

			scratch
				.querySelector('li:nth-child(3)')
				.dispatchEvent(createEvent('click'));
			expect(listeners[2]).to.have.been.calledOnce;

			scratch
				.querySelector('li:last-child')
				.dispatchEvent(createEvent('click'));
			expect(listeners[4]).to.have.been.calledTwice;
		});
	});

	it.skip('should properly hydrate suspense when resolves to a Fragment', () => {
		const originalHtml = ul(
			[li(0), li(1), li(2), li(3), li(4), li(5)].join('')
		);

		const listeners = [
			sinon.spy(),
			sinon.spy(),
			sinon.spy(),
			sinon.spy(),
			sinon.spy(),
			sinon.spy()
		];

		scratch.innerHTML = originalHtml;
		clearLog();

		const [Lazy, resolve] = createLazy();
		hydrate(
			<List>
				<Fragment>
					<ListItem onClick={listeners[0]}>0</ListItem>
					<ListItem onClick={listeners[1]}>1</ListItem>
				</Fragment>
				<Suspense>
					<Lazy />
				</Suspense>
				<Fragment>
					<ListItem onClick={listeners[4]}>4</ListItem>
					<ListItem onClick={listeners[5]}>5</ListItem>
				</Fragment>
			</List>,
			scratch
		);
		rerender(); // Flush rerender queue to mimic what preact will really do
		expect(scratch.innerHTML).to.equal(originalHtml);
		expect(getLog()).to.deep.equal([]);
		expect(listeners[5]).not.to.have.been.called;

		clearLog();
		scratch.querySelector('li:last-child').dispatchEvent(createEvent('click'));
		expect(listeners[5]).to.have.been.calledOnce;

		return resolve(() => (
			<Fragment>
				<ListItem onClick={listeners[2]}>2</ListItem>
				<ListItem onClick={listeners[3]}>3</ListItem>
			</Fragment>
		)).then(() => {
			rerender();
			expect(scratch.innerHTML).to.equal(originalHtml);
			expect(getLog()).to.deep.equal([]);
			clearLog();

			scratch
				.querySelector('li:nth-child(4)')
				.dispatchEvent(createEvent('click'));
			expect(listeners[3]).to.have.been.calledOnce;

			scratch
				.querySelector('li:last-child')
				.dispatchEvent(createEvent('click'));
			expect(listeners[5]).to.have.been.calledTwice;
		});
	});

	// TODO:
	// 1. What if props change between when hydrate suspended and suspense
	//    resolves?
	// 2. If using real Suspense, test re-suspending after hydrate suspense
	// 3. Put some DOM and components with state and event listeners between
	//    suspender and Suspense boundary
	// 4. Put some sibling DOM and components with state and event listeners
	//    sibling to suspender and under Suspense boundary
});
<|endoftext|>


<commit_before>import { isBuildStatus } from '../build-status.js'
import { createServiceTester } from '../tester.js'
export const t = await createServiceTester()

t.create('codeship (valid, no branch)')
  .get('/d6c1ddd0-16a3-0132-5f85-2e35c05e22b1.json')
  .expectBadge({
    label: 'build',
    message: isBuildStatus,
  })

t.create('codeship (valid, with branch)')
  .get('/0bdb0440-3af5-0133-00ea-0ebda3a33bf6/master.json')
  .expectBadge({
    label: 'build',
    message: isBuildStatus,
  })

t.create('codeship (repo not found)')
  .get('/not-a-repo.json')
  .expectBadge({ label: 'build', message: 'project not found' })

t.create('codeship (branch not found)')
  .get('/d6c1ddd0-16a3-0132-5f85-2e35c05e22b1/not-a-branch.json')
  .expectBadge({ label: 'build', message: 'branch not found' })
<commit_msg>tests: fix Codeship service tests (#7307)<commit_after>import { isBuildStatus } from '../build-status.js'
import { createServiceTester } from '../tester.js'
export const t = await createServiceTester()

t.create('codeship (valid, no branch)')
  .get('/30419df0-80ff-0135-f7fb-06994b6b032d.json')
  .expectBadge({
    label: 'build',
    message: isBuildStatus,
  })

t.create('codeship (valid, with branch)')
  .get('/0bdb0440-3af5-0133-00ea-0ebda3a33bf6/master.json')
  .expectBadge({
    label: 'build',
    message: isBuildStatus,
  })

t.create('codeship (repo not found)')
  .get('/not-a-repo.json')
  .expectBadge({ label: 'build', message: 'project not found' })

t.create('codeship (branch not found)')
  .get('/30419df0-80ff-0135-f7fb-06994b6b032d/not-a-branch.json')
  .expectBadge({ label: 'build', message: 'branch not found' })
<|endoftext|>


<commit_before>// (C) Copyright 2014-2016 Hewlett Packard Enterprise Development LP

import React, { Component } from 'react';
import Box from 'grommet/components/Box';
import Card from 'grommet/components/Card';
import Label from 'grommet/components/Label';
import Heading from 'grommet/components/Heading';
import Image from 'grommet/components/Image';
import Paragraph from 'grommet/components/Paragraph';
import Example from '../../../Example';

export default class Card8 extends Component {

  render () {
    return (
      <Example code={
        <Box colorIndex="light-2" pad="medium">
          <Card label={
              Featured Post
            }
            thumbnail={<Image src="/img/carousel-1.png" />}
            heading={
              <Heading tag="h2" strong={true}>
                The Key Steps to Reducing Software Spend
              </Heading>
            }
            description={
              <Paragraph>HPE Software Licensing and Management
              Solutions can help you optimize your software investments
              through control of complex negotiations and renewal
              processes</Paragraph>
            }
          />
        </Box>
      } />
    );
  }
};
<commit_msg>Updated custom Card example.<commit_after>// (C) Copyright 2014-2016 Hewlett Packard Enterprise Development LP

import React, { Component } from 'react';
import Box from 'grommet/components/Box';
import Card from 'grommet/components/Card';
import Label from 'grommet/components/Label';
import Heading from 'grommet/components/Heading';
import Image from 'grommet/components/Image';
import Paragraph from 'grommet/components/Paragraph';
import Example from '../../../Example';

export default class Card8 extends Component {

  render () {
    return (
      <Example code={
        <Box colorIndex="light-2" pad="medium">
          <Card label={
              Featured Post
            }
            thumbnail={<Image src="/img/carousel-1.png" />}
            heading={
              <Heading tag="h2" strong={true}>
                The Key Steps to Reducing Software Spend
              </Heading>
            }
            description={
              <Paragraph size="large" margin="medium">
                HPE Software Licensing and Management
                Solutions can help you optimize your software investments
                through control of complex negotiations and renewal
                processes
            </Paragraph>
            }
          />
        </Box>
      } />
    );
  }
};
<|endoftext|>


<commit_before>/*! Copyright (c) 2010 Tom Ellis (http://www.webmuse.co.uk)
* Licensed under the MIT License (LICENSE.txt).
* Ideas from Brandon Aaron's cssHooks
*/
(function($) {
    // Border Radius set and get hooks

	var div = document.createElement("div"),
	divStyle = div.style;

	var dirs = "TopLeft TopRight BottomRight BottomLeft".split(/\s/);

	$.support.borderRadius =
    divStyle.WebkitBorderRadius === ''? 'WebkitBorderRadius' :
	(divStyle.MozBorderRadius === ''? 'MozBorderRadius' :
	(divStyle.BorderRadius === ''? 'BorderRadius'
	: false));

	//Browsers support border radius corners differently

	//Top Left
	$.support.TopLeft =
    divStyle.WebkitBorderRadius === ''? 'WebkitBorderTopLeftRadius' :
	(divStyle.MozBorderRadius === ''? 'MozBorderRadiusTopleft' :
	(divStyle.borderRadius === ''? 'borderTopLeftRadius' : false));

	//Top Right
	$.support.TopRight =
    divStyle.WebkitBorderRadius === ''? 'WebkitBorderTopRightRadius' :
	(divStyle.MozBorderRadius === ''? 'MozBorderRadiusTopright' :
	(divStyle.borderRadius === ''? 'borderTopRightRadius' : false));

	//Bottom Left
	$.support.BottomLeft =
    divStyle.WebkitBorderRadius === ''? 'WebkitBorderBottomLeftRadius' :
	(divStyle.MozBorderRadius === ''? 'MozBorderRadiusBottomleft' :
	(divStyle.borderRadius === ''? 'borderBottomLeftRadius' : false));

	//Bottom Right
	$.support.BottomRight =
    divStyle.WebkitBorderRadius === ''? 'WebkitBorderBottomRightRadius' :
	(divStyle.MozBorderRadius === ''? 'MozBorderRadiusBottomright' :
	(divStyle.borderRadius === ''? 'borderBottomRightRadius' : false));

	if ( $.support.borderRadius && $.support.borderRadius !== "borderRadius" && $.cssHooks ) //make it only work with 1.4.3+
	{
		//BorderRadius
		$.cssHooks.borderRadius = {
			get: function( elem, computed, extra ) {

				return $.map(dirs, function( dir ) {
					return $.css( elem, $.support[dir] );
				}).join(" ");

			},
			set: function( elem, value ) {

				var parts = value.split(/\s/),
				values = {
					"TopLeft": parts[0],
					"TopRight": parts[1] || parts[0],
					"BottomLeft": parts[2] || parts[0],
					"BottomRight": parts[3] || parts[1] || parts[0]
				};

				//Not sure what is better to use
                /*$.each(dirs, function( i, dir ) {
					//alert(  $.support[dir] );
                    elem.style[ $.support[dir] ] = values[ dir ];
                });*/

				elem.style[ $.support.borderRadius ] = value;
			}
		};

		$.each( dirs, function( i, radius ) {

			$.cssHooks[ "border" + radius + "Radius"] = {
				get: function( elem, computed, extra ) {

					return $.css( elem, $.support[radius] );
				},
				set: function( elem, value ){

					elem.style[ $.support[radius] ] = value;
				}
			};

			$.fx.step[ "border" + radius + "Radius" ] = function( fx ) {
				$.cssHooks[ "border" + radius + "Radius" ].set( fx.elem, fx.now + fx.unit );
			};

		});

		// setup fx hooks
		$.fx.step.borderRadius = function( fx ) {
			$.cssHooks.borderRadius.set( fx.elem, fx.now + fx.unit );
		};

	}
	else if ( !$.support.borderRadius )
	{
		//BorderRadius Plugin
		$.cssHooks.borderRadius = {
			get: function( elem, computed, extra ) {

				return $.data(elem, "borderRadiusIE");
			},
			set: function( elem, value ) {

				var css = ($.data( elem, "borderRadiusIECSS")) ? $.data( elem, "borderRadiusIECSS") : document.createStyleSheet("ie_style.css");

				var parts = value.split(/\s/);
				var one = parts[0];
				var two = parts[1] || parts[0];
				var three = parts[2] || parts[0];
				var four = parts[3] || parts[1] || parts[0];

				var values = [
					one,
					two,
					three,
					four
				];

				css.cssText = "";
				css.addRule( "#results", "border-radius:" + values.join(" ") );

				elem.style.behavior = "url(js/border-radius.htc)";

				$.data(elem, "borderRadiusIE", values.join(" "));
				$.data( elem, "borderRadiusIECSS", css);

			}
		};

		//Todo: Add support for each corner
		$.each( dirs, function( i, radius ) {

			$.cssHooks[ "border" + radius + "Radius"] = {

				get: function( elem, computed, extra ) {

				},
				set: function( elem, value ){

				}
			};

		});

		// setup fx hooks
		$.fx.step.borderRadius = function( fx ) {

			//Todo: Doesn't seem to work correctly
			$(fx.elem).css("border-radius", fx.now + fx.unit);
			//$.cssHooks.borderRadius.set( fx.elem, fx.now + fx.unit );
		};

		$.fx.step[ "border" + radius + "Radius" ] = function( fx ) {
			//Todo: Add support for animation
			//$.cssHooks[ "border" + radius + "Radius" ].set( fx.elem, fx.now + fx.unit );
		};

	}

	div = divStyle = null;

})(jQuery);<commit_msg>improved regex reuse<commit_after>/*! Copyright (c) 2010 Tom Ellis (http://www.webmuse.co.uk)
* Licensed under the MIT License (LICENSE.txt).
*/
(function($) {
    // Border Radius set and get hooks

	var div = document.createElement("div"),
	divStyle = div.style,
	rWhiteSpace = /\s/;
	dirs = "TopLeft TopRight BottomRight BottomLeft".split(rWhiteSpace);

	$.support.borderRadius =
    divStyle.WebkitBorderRadius === ''? 'WebkitBorderRadius' :
	(divStyle.MozBorderRadius === ''? 'MozBorderRadius' :
	(divStyle.BorderRadius === ''? 'BorderRadius'
	: false));

	//Browsers support border radius corners differently

	//Top Left
	$.support.TopLeft =
    divStyle.WebkitBorderRadius === ''? 'WebkitBorderTopLeftRadius' :
	(divStyle.MozBorderRadius === ''? 'MozBorderRadiusTopleft' :
	(divStyle.borderRadius === ''? 'borderTopLeftRadius' : false));

	//Top Right
	$.support.TopRight =
    divStyle.WebkitBorderRadius === ''? 'WebkitBorderTopRightRadius' :
	(divStyle.MozBorderRadius === ''? 'MozBorderRadiusTopright' :
	(divStyle.borderRadius === ''? 'borderTopRightRadius' : false));

	//Bottom Left
	$.support.BottomLeft =
    divStyle.WebkitBorderRadius === ''? 'WebkitBorderBottomLeftRadius' :
	(divStyle.MozBorderRadius === ''? 'MozBorderRadiusBottomleft' :
	(divStyle.borderRadius === ''? 'borderBottomLeftRadius' : false));

	//Bottom Right
	$.support.BottomRight =
    divStyle.WebkitBorderRadius === ''? 'WebkitBorderBottomRightRadius' :
	(divStyle.MozBorderRadius === ''? 'MozBorderRadiusBottomright' :
	(divStyle.borderRadius === ''? 'borderBottomRightRadius' : false));

	if ( $.support.borderRadius && $.support.borderRadius !== "borderRadius" && $.cssHooks ) //make it only work with 1.4.3+
	{
		//BorderRadius
		$.cssHooks.borderRadius = {
			get: function( elem, computed, extra ) {

				return $.map(dirs, function( dir ) {
					return $.css( elem, $.support[dir] );
				}).join(" ");

			},
			set: function( elem, value ) {

				var parts = value.split(rWhiteSpace),
				values = {
					"TopLeft": parts[0],
					"TopRight": parts[1] || parts[0],
					"BottomLeft": parts[2] || parts[0],
					"BottomRight": parts[3] || parts[1] || parts[0]
				};

				//Not sure what is better to use
                /*$.each(dirs, function( i, dir ) {
					//alert(  $.support[dir] );
                    elem.style[ $.support[dir] ] = values[ dir ];
                });*/

				elem.style[ $.support.borderRadius ] = value;
			}
		};

		$.each( dirs, function( i, radius ) {

			$.cssHooks[ "border" + radius + "Radius"] = {
				get: function( elem, computed, extra ) {

					return $.css( elem, $.support[radius] );
				},
				set: function( elem, value ){

					elem.style[ $.support[radius] ] = value;
				}
			};

			$.fx.step[ "border" + radius + "Radius" ] = function( fx ) {
				$.cssHooks[ "border" + radius + "Radius" ].set( fx.elem, fx.now + fx.unit );
			};

		});

		// setup fx hooks
		$.fx.step.borderRadius = function( fx ) {
			$.cssHooks.borderRadius.set( fx.elem, fx.now + fx.unit );
		};

	}
	else if ( !$.support.borderRadius )
	{
		//BorderRadius Plugin
		$.cssHooks.borderRadius = {
			get: function( elem, computed, extra ) {

				return $.data(elem, "borderRadiusIE");
			},
			set: function( elem, value ) {

				var css = ($.data( elem, "borderRadiusIECSS")) ? $.data( elem, "borderRadiusIECSS") : document.createStyleSheet("ie_style.css");

				var parts = value.split(rWhiteSpace);
				var one = parts[0];
				var two = parts[1] || parts[0];
				var three = parts[2] || parts[0];
				var four = parts[3] || parts[1] || parts[0];

				var values = [
					one,
					two,
					three,
					four
				];

				css.cssText = "";
				css.addRule( "#results", "border-radius:" + values.join(" ") );

				elem.style.behavior = "url(js/border-radius.htc)";

				$.data(elem, "borderRadiusIE", values.join(" "));
				$.data( elem, "borderRadiusIECSS", css);

			}
		};

		//Todo: Add support for each corner
		$.each( dirs, function( i, radius ) {

			$.cssHooks[ "border" + radius + "Radius"] = {

				get: function( elem, computed, extra ) {

				},
				set: function( elem, value ){

				}
			};

		});

		// setup fx hooks
		$.fx.step.borderRadius = function( fx ) {

			//Todo: Doesn't seem to work correctly
			$(fx.elem).css("border-radius", fx.now + fx.unit);
			//$.cssHooks.borderRadius.set( fx.elem, fx.now + fx.unit );
		};

		$.fx.step[ "border" + radius + "Radius" ] = function( fx ) {
			//Todo: Add support for animation
			//$.cssHooks[ "border" + radius + "Radius" ].set( fx.elem, fx.now + fx.unit );
		};

	}

	div = divStyle = null;

})(jQuery);<|endoftext|>


<commit_before>// ==UserScript==
// @name         Remove Spiegel Online Adblock Popup Asynchronously
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  remove annoying Adblock nag screen from Spiegel.de
// @author       tsak
// @match        *://*.spiegel.de/*
// @grant        GM_addStyle
// ==/UserScript==

(function() {
    'use strict';

    // Neat trick from https://davidwalsh.name/detect-node-insertion
    GM_addStyle(
        "@keyframes nodeInserted {\n" +
        "from { opacity: 0.99; }\n" +
        "to { opacity: 1; }\n" +
        "}"
    );

    GM_addStyle(
        "body > .ua-detected {\n"+
        "animation-duration: 0.001s;\n"+
        "animation-name: nodeInserted;\n"+
        "}"
    );

    var insertListener = function(event){
        if (event.animationName == "nodeInserted") {
            // Remove nag screen
            var el = document.querySelectorAll('.ua-detected')[0];
            el.parentNode.removeChild(el);
            // Disable blur on content wrapper
            document.getElementById('wrapper-content').setAttribute('style', '');
        }
    };

    document.addEventListener("animationstart", insertListener, false); // standard + firefox
    document.addEventListener("MSAnimationStart", insertListener, false); // IE
    document.addEventListener("webkitAnimationStart", insertListener, false); // Chrome + Safari
})();
<commit_msg>chore: add Tamper Monkey URL tags and license info<commit_after>// ==UserScript==
// @name         Remove Spiegel Online Adblock Popup Asynchronously
// @namespace    http://tampermonkey.net/
// @homepageURL  https://github.com/tsak/spon-remove-adblock
// @updateURL    https://github.com/tsak/spon-remove-adblock/raw/master/spon-adblock-remover.user.js
// @supportURL   https://github.com/tsak/spon-remove-adblock/issues
// @version      0.1
// @license      MIT
// @description  remove annoying Adblock nag screen from Spiegel.de
// @author       tsak
// @match        *://*.spiegel.de/*
// @grant        GM_addStyle
// ==/UserScript==

(function() {
    'use strict';

    // Neat trick from https://davidwalsh.name/detect-node-insertion
    GM_addStyle(
        "@keyframes nodeInserted {\n" +
        "from { opacity: 0.99; }\n" +
        "to { opacity: 1; }\n" +
        "}"
    );

    GM_addStyle(
        "body > .ua-detected {\n"+
        "animation-duration: 0.001s;\n"+
        "animation-name: nodeInserted;\n"+
        "}"
    );

    var insertListener = function(event){
        if (event.animationName == "nodeInserted") {
            // Remove nag screen
            var el = document.querySelectorAll('.ua-detected')[0];
            el.parentNode.removeChild(el);
            // Disable blur on content wrapper
            document.getElementById('wrapper-content').setAttribute('style', '');
        }
    };

    document.addEventListener("animationstart", insertListener, false); // standard + firefox
    document.addEventListener("MSAnimationStart", insertListener, false); // IE
    document.addEventListener("webkitAnimationStart", insertListener, false); // Chrome + Safari
})();
<|endoftext|>