text:
/**
 * (c) 2010-2017 Torstein Honsi
 *
 * License: www.highcharts.com/license
 */
'use strict';
import H from './Globals.js';
import './Utilities.js';
import './Color.js';
import './Legend.js';
import './Series.js';
import './Options.js';
var animObject = H.animObject,
    color = H.color,
    each = H.each,
    extend = H.extend,
    isNumber = H.isNumber,
    LegendSymbolMixin = H.LegendSymbolMixin,
    merge = H.merge,
    noop = H.noop,
    pick = H.pick,
    Series = H.Series,
    seriesType = H.seriesType,
    svg = H.svg;
/**
 * The column series type.
 *
 * @constructor seriesTypes.column
 * @augments    Series
 */

/**
 * Column series display one column per value along an X axis.
 *
 * @sample       {highcharts} highcharts/demo/column-basic/ Column chart
 * @sample       {highstock} stock/demo/column/ Column chart
 *
 * @extends      {plotOptions.line}
 * @product      highcharts highstock
 * @excluding    connectNulls,dashStyle,gapSize,gapUnit,linecap,lineWidth,
 *               marker,connectEnds,step
 * @optionparent plotOptions.column
 */
seriesType('column', 'line', {

    /**
     * The corner radius of the border surrounding each column or bar.
     *
     * @type    {Number}
     * @sample  {highcharts} highcharts/plotoptions/column-borderradius/
     *          Rounded columns
     * @default 0
     * @product highcharts highstock
     */
    borderRadius: 0,

    /**
     * When using automatic point colors pulled from the `options.colors`
     * collection, this option determines whether the chart should receive
     * one color per series or one color per point.
     *
     * @type      {Boolean}
     * @see       [series colors](#plotOptions.column.colors)
     * @sample    {highcharts} highcharts/plotoptions/column-colorbypoint-false/
     *            False by default
     * @sample    {highcharts} highcharts/plotoptions/column-colorbypoint-true/
     *            True
     * @default   false
     * @since     2.0
     * @product   highcharts highstock
     * @apioption plotOptions.column.colorByPoint
     */

    /**
     * A series specific or series type specific color set to apply instead
     * of the global [colors](#colors) when [colorByPoint](
     * #plotOptions.column.colorByPoint) is true.
     *
     * @type      {Array<Color>}
     * @since     3.0
     * @product   highcharts highstock
     * @apioption plotOptions.column.colors
     */

    /**
     * When true, each column edge is rounded to its nearest pixel in order
     * to render sharp on screen. In some cases, when there are a lot of
     * densely packed columns, this leads to visible difference in column
     * widths or distance between columns. In these cases, setting `crisp`
     * to `false` may look better, even though each column is rendered
     * blurry.
     *
     * @sample  {highcharts} highcharts/plotoptions/column-crisp-false/
     *          Crisp is false
     * @since   5.0.10
     * @product highcharts highstock
     */
    crisp: true,

    /**
     * Padding between each value groups, in x axis units.
     *
     * @sample  {highcharts} highcharts/plotoptions/column-grouppadding-default/
     *          0.2 by default
     * @sample  {highcharts} highcharts/plotoptions/column-grouppadding-none/
     *          No group padding - all columns are evenly spaced
     * @product highcharts highstock
     */
    groupPadding: 0.2,

    /**
     * Whether to group non-stacked columns or to let them render independent
     * of each other. Non-grouped columns will be laid out individually
     * and overlap each other.
     *
     * @type      {Boolean}
     * @sample    {highcharts} highcharts/plotoptions/column-grouping-false/
     *            Grouping disabled
     * @sample    {highstock} highcharts/plotoptions/column-grouping-false/
     *            Grouping disabled
     * @default   true
     * @since     2.3.0
     * @product   highcharts highstock
     * @apioption plotOptions.column.grouping
     */

    /**
     * @ignore-option
     */
    marker: null, // point options are specified in the base options

    /**
     * The maximum allowed pixel width for a column, translated to the height
     * of a bar in a bar chart. This prevents the columns from becoming
     * too wide when there is a small number of points in the chart.
     *
     * @type      {Number}
     * @see       [pointWidth](#plotOptions.column.pointWidth)
     * @sample    {highcharts} highcharts/plotoptions/column-maxpointwidth-20/
     *            Limited to 50
     * @sample    {highstock} highcharts/plotoptions/column-maxpointwidth-20/
     *            Limited to 50
     * @default   null
     * @since     4.1.8
     * @product   highcharts highstock
     * @apioption plotOptions.column.maxPointWidth
     */

    /**
     * Padding between each column or bar, in x axis units.
     *
     * @sample  {highcharts} highcharts/plotoptions/column-pointpadding-default/
     *          0.1 by default
     * @sample  {highcharts} highcharts/plotoptions/column-pointpadding-025/
     *          0.25
     * @sample  {highcharts} highcharts/plotoptions/column-pointpadding-none/
     *          0 for tightly packed columns
     * @product highcharts highstock
     */
    pointPadding: 0.1,

    /**
     * A pixel value specifying a fixed width for each column or bar. When
     * `null`, the width is calculated from the `pointPadding` and
     * `groupPadding`.
     *
     * @type      {Number}
     * @see       [maxPointWidth](#plotOptions.column.maxPointWidth)
     * @sample    {highcharts} highcharts/plotoptions/column-pointwidth-20/
     *            20px wide columns regardless of chart width or the amount
     *            of data points
     * @default   null
     * @since     1.2.5
     * @product   highcharts highstock
     * @apioption plotOptions.column.pointWidth
     */

    /**
     * The minimal height for a column or width for a bar. By default,
     * 0 values are not shown. To visualize a 0 (or close to zero) point,
     * set the minimal point length to a pixel value like 3\. In stacked
     * column charts, minPointLength might not be respected for tightly
     * packed values.
     *
     * @sample  {highcharts}
     *          highcharts/plotoptions/column-minpointlength/
     *          Zero base value
     * @sample  {highcharts}
     *          highcharts/plotoptions/column-minpointlength-pos-and-neg/
     *          Positive and negative close to zero values
     * @product highcharts highstock
     */
    minPointLength: 0,

    /**
     * When the series contains less points than the crop threshold, all
     * points are drawn, event if the points fall outside the visible plot
     * area at the current zoom. The advantage of drawing all points (including
     * markers and columns), is that animation is performed on updates.
     * On the other hand, when the series contains more points than the
     * crop threshold, the series data is cropped to only contain points
     * that fall within the plot area. The advantage of cropping away invisible
     * points is to increase performance on large series. .
     *
     * @product highcharts highstock
     */
    cropThreshold: 50,

    /**
     * The X axis range that each point is valid for. This determines the
     * width of the column. On a categorized axis, the range will be 1
     * by default (one category unit). On linear and datetime axes, the
     * range will be computed as the distance between the two closest data
     * points.
     *
     * The default `null` means it is computed automatically, but this option
     * can be used to override the automatic value.
     *
     * @type    {Number}
     * @sample  {highcharts} highcharts/plotoptions/column-pointrange/
     *          Set the point range to one day on a data set with one week
     *          between the points
     * @since   2.3
     * @product highcharts highstock
     */
    pointRange: null,

    states: {

        /**
         * Options for the hovered point. These settings override the normal
         * state options when a point is moused over or touched.
         *
         * @extends   plotOptions.series.states.hover
         * @excluding halo,lineWidth,lineWidthPlus,marker
         * @product   highcharts highstock
         */
        hover: {

            /** @ignore-option */
            halo: false,

            /**
             * A specific border color for the hovered point. Defaults to
             * inherit the normal state border color.
             *
             * @type      {Color}
             * @product   highcharts
             * @apioption plotOptions.column.states.hover.borderColor
             */

            /**
             * A specific color for the hovered point.
             *
             * @type      {Color}
             * @default   undefined
             * @product   highcharts
             * @apioption plotOptions.column.states.hover.color
             */

        }

    },

    dataLabels: {
        align: null, // auto
        verticalAlign: null, // auto
        y: null
    },

    /**
     * When this is true, the series will not cause the Y axis to cross
     * the zero plane (or [threshold](#plotOptions.series.threshold) option)
     * unless the data actually crosses the plane.
     *
     * For example, if `softThreshold` is `false`, a series of 0, 1, 2,
     * 3 will make the Y axis show negative values according to the `minPadding`
     * option. If `softThreshold` is `true`, the Y axis starts at 0.
     *
     * @since   4.1.9
     * @product highcharts highstock
     */
    softThreshold: false,

    // false doesn't work well: http://jsfiddle.net/highcharts/hz8fopan/14/
    /**
     * @ignore-option
     */
    startFromThreshold: true,

    stickyTracking: false,

    tooltip: {
        distance: 6
    },

    /**
     * The Y axis value to serve as the base for the columns, for distinguishing
     * between values above and below a threshold. If `null`, the columns
     * extend from the padding Y axis minimum.
     *
     * @since   2.0
     * @product highcharts
     */
    threshold: 0

}, /** @lends seriesTypes.column.prototype */ {
    cropShoulder: 0,
    // When tooltip is not shared, this series (and derivatives) requires direct
    // touch/hover. KD-tree does not apply.
    directTouch: true,
    trackerGroups: ['group', 'dataLabelsGroup'],
    // use separate negative stacks, unlike area stacks where a negative point
    // is substracted from previous (#1910)
    negStacks: true,

    /**
     * Initialize the series. Extends the basic Series.init method by
     * marking other series of the same type as dirty.
     *
     * @function #init
     * @memberOf seriesTypes.column
     *
     */
    init: function () {
        Series.prototype.init.apply(this, arguments);

        var series = this,
            chart = series.chart;

        // if the series is added dynamically, force redraw of other
        // series affected by a new column
        if (chart.hasRendered) {
            each(chart.series, function (otherSeries) {
                if (otherSeries.type === series.type) {
                    otherSeries.isDirty = true;
                }
            });
        }
    },

    /**
     * Return the width and x offset of the columns adjusted for grouping,
     * groupPadding, pointPadding, pointWidth etc.
     */
    getColumnMetrics: function () {

        var series = this,
            options = series.options,
            xAxis = series.xAxis,
            yAxis = series.yAxis,
            reversedXAxis = xAxis.reversed,
            stackKey,
            stackGroups = {},
            columnCount = 0;

        // Get the total number of column type series. This is called on every
        // series. Consider moving this logic to a chart.orderStacks() function
        // and call it on init, addSeries and removeSeries
        if (options.grouping === false) {
            columnCount = 1;
        } else {
            each(series.chart.series, function (otherSeries) {
                var otherOptions = otherSeries.options,
                    otherYAxis = otherSeries.yAxis,
                    columnIndex;
                if (
                    otherSeries.type === series.type &&
                    (
                        otherSeries.visible ||
                        !series.chart.options.chart.ignoreHiddenSeries
                    ) &&
                    yAxis.len === otherYAxis.len &&
                    yAxis.pos === otherYAxis.pos
                ) {  // #642, #2086
                    if (otherOptions.stacking) {
                        stackKey = otherSeries.stackKey;
                        if (stackGroups[stackKey] === undefined) {
                            stackGroups[stackKey] = columnCount++;
                        }
                        columnIndex = stackGroups[stackKey];
                    } else if (otherOptions.grouping !== false) { // #1162
                        columnIndex = columnCount++;
                    }
                    otherSeries.columnIndex = columnIndex;
                }
            });
        }

        var categoryWidth = Math.min(
                Math.abs(xAxis.transA) * (
                    xAxis.ordinalSlope ||
                    options.pointRange ||
                    xAxis.closestPointRange ||
                    xAxis.tickInterval ||
                    1
                ), // #2610
                xAxis.len // #1535
            ),
            groupPadding = categoryWidth * options.groupPadding,
            groupWidth = categoryWidth - 2 * groupPadding,
            pointOffsetWidth = groupWidth / (columnCount || 1),
            pointWidth = Math.min(
                options.maxPointWidth || xAxis.len,
                pick(
                    options.pointWidth,
                    pointOffsetWidth * (1 - 2 * options.pointPadding)
                )
            ),
            pointPadding = (pointOffsetWidth - pointWidth) / 2,
            // #1251, #3737
            colIndex = (series.columnIndex || 0) + (reversedXAxis ? 1 : 0),
            pointXOffset =
                pointPadding +
                (
                    groupPadding +
                    colIndex * pointOffsetWidth -
                    (categoryWidth / 2)
                ) *    (reversedXAxis ? -1 : 1);

        // Save it for reading in linked series (Error bars particularly)
        series.columnMetrics = {
            width: pointWidth,
            offset: pointXOffset
        };
        return series.columnMetrics;

    },

    /**
     * Make the columns crisp. The edges are rounded to the nearest full pixel.
     */
    crispCol: function (x, y, w, h) {
        var chart = this.chart,
            borderWidth = this.borderWidth,
            xCrisp = -(borderWidth % 2 ? 0.5 : 0),
            yCrisp = borderWidth % 2 ? 0.5 : 1,
            right,
            bottom,
            fromTop;

        if (chart.inverted && chart.renderer.isVML) {
            yCrisp += 1;
        }

        // Horizontal. We need to first compute the exact right edge, then round
        // it and compute the width from there.
        if (this.options.crisp) {
            right = Math.round(x + w) + xCrisp;
            x = Math.round(x) + xCrisp;
            w = right - x;
        }

        // Vertical
        bottom = Math.round(y + h) + yCrisp;
        fromTop = Math.abs(y) <= 0.5 && bottom > 0.5; // #4504, #4656
        y = Math.round(y) + yCrisp;
        h = bottom - y;

        // Top edges are exceptions
        if (fromTop && h) { // #5146
            y -= 1;
            h += 1;
        }

        return {
            x: x,
            y: y,
            width: w,
            height: h
        };
    },

    /**
     * Translate each point to the plot area coordinate system and find shape
     * positions
     */
    translate: function () {
        var series = this,
            chart = series.chart,
            options = series.options,
            dense = series.dense =
                series.closestPointRange * series.xAxis.transA < 2,
            borderWidth = series.borderWidth = pick(
                options.borderWidth,
                dense ? 0 : 1  // #3635
            ),
            yAxis = series.yAxis,
            threshold = options.threshold,
            translatedThreshold = series.translatedThreshold =
                yAxis.getThreshold(threshold),
            minPointLength = pick(options.minPointLength, 5),
            metrics = series.getColumnMetrics(),
            pointWidth = metrics.width,
            // postprocessed for border width
            seriesBarW = series.barW =
                Math.max(pointWidth, 1 + 2 * borderWidth),
            pointXOffset = series.pointXOffset = metrics.offset;

        if (chart.inverted) {
            translatedThreshold -= 0.5; // #3355
        }

        // When the pointPadding is 0, we want the columns to be packed tightly,
        // so we allow individual columns to have individual sizes. When
        // pointPadding is greater, we strive for equal-width columns (#2694).
        if (options.pointPadding) {
            seriesBarW = Math.ceil(seriesBarW);
        }

        Series.prototype.translate.apply(series);

        // Record the new values
        each(series.points, function (point) {
            var yBottom = pick(point.yBottom, translatedThreshold),
                safeDistance = 999 + Math.abs(yBottom),
                plotY = Math.min(
                    Math.max(-safeDistance, point.plotY),
                    yAxis.len + safeDistance
                ), // Don't draw too far outside plot area (#1303, #2241, #4264)
                barX = point.plotX + pointXOffset,
                barW = seriesBarW,
                barY = Math.min(plotY, yBottom),
                up,
                barH = Math.max(plotY, yBottom) - barY;

            // Handle options.minPointLength
            if (minPointLength && Math.abs(barH) < minPointLength) {
                barH = minPointLength;
                up = (!yAxis.reversed && !point.negative) ||
                    (yAxis.reversed && point.negative);

                // Reverse zeros if there's no positive value in the series
                // in visible range (#7046)
                if (
                    point.y === threshold &&
                    series.dataMax <= threshold &&
                    yAxis.min < threshold // and if there's room for it (#7311)
                ) {
                    up = !up;
                }

                // If stacked...
                barY = Math.abs(barY - translatedThreshold) > minPointLength ?
                        // ...keep position
                        yBottom - minPointLength :
                        // #1485, #4051
                        translatedThreshold - (up ? minPointLength : 0);
            }

            // Cache for access in polar
            point.barX = barX;
            point.pointWidth = pointWidth;

            // Fix the tooltip on center of grouped columns (#1216, #424, #3648)
            point.tooltipPos = chart.inverted ?
            [
                yAxis.len + yAxis.pos - chart.plotLeft - plotY,
                series.xAxis.len - barX - barW / 2, barH
            ] :
            [barX + barW / 2, plotY + yAxis.pos - chart.plotTop, barH];

            // Register shape type and arguments to be used in drawPoints
            point.shapeType = 'rect';
            point.shapeArgs = series.crispCol.apply(
                series,
                point.isNull ?
                    // #3169, drilldown from null must have a position to work
                    // from #6585, dataLabel should be placed on xAxis, not
                    // floating in the middle of the chart
                    [barX, translatedThreshold, barW, 0] :
                    [barX, barY, barW, barH]
            );
        });

    },

    getSymbol: noop,

    /**
     * Use a solid rectangle like the area series types
     */
    drawLegendSymbol: LegendSymbolMixin.drawRectangle,

    /**
     * Columns have no graph
     */
    drawGraph: function () {
        this.group[
            this.dense ? 'addClass' : 'removeClass'
        ]('highcharts-dense-data');
    },

    /**
     * Draw the columns. For bars, the series.group is rotated, so the same
     * coordinates apply for columns and bars. This method is inherited by
     * scatter series.
     */
    drawPoints: function () {
        var series = this,
            chart = this.chart,
            options = series.options,
            renderer = chart.renderer,
            animationLimit = options.animationLimit || 250,
            shapeArgs;

        // draw the columns
        each(series.points, function (point) {
            var plotY = point.plotY,
                graphic = point.graphic,
                verb = graphic && chart.pointCount < animationLimit ?
                    'animate' : 'attr';

            if (isNumber(plotY) && point.y !== null) {
                shapeArgs = point.shapeArgs;

                if (graphic) { // update
                    graphic[verb](
                        merge(shapeArgs)
                    );

                } else {
                    point.graphic = graphic =
                        renderer[point.shapeType](shapeArgs)
                            .add(point.group || series.group);
                }

                // Border radius is not stylable (#6900)
                if (options.borderRadius) {
                    graphic.attr({
                        r: options.borderRadius
                    });
                }

                graphic.addClass(point.getClassName(), true);

            } else if (graphic) {
                point.graphic = graphic.destroy(); // #1269
            }
        });
    },

    /**
     * Animate the column heights one by one from zero
     * @param {Boolean} init Whether to initialize the animation or run it
     */
    animate: function (init) {
        var series = this,
            yAxis = this.yAxis,
            options = series.options,
            inverted = this.chart.inverted,
            attr = {},
            translateProp = inverted ? 'translateX' : 'translateY',
            translateStart,
            translatedThreshold;

        if (svg) { // VML is too slow anyway
            if (init) {
                attr.scaleY = 0.001;
                translatedThreshold = Math.min(
                    yAxis.pos + yAxis.len,
                    Math.max(yAxis.pos, yAxis.toPixels(options.threshold))
                );
                if (inverted) {
                    attr.translateX = translatedThreshold - yAxis.len;
                } else {
                    attr.translateY = translatedThreshold;
                }
                series.group.attr(attr);

            } else { // run the animation
                translateStart = series.group.attr(translateProp);
                series.group.animate(
                    { scaleY: 1 },
                    extend(animObject(series.options.animation
                ), {
                    // Do the scale synchronously to ensure smooth updating
                    // (#5030, #7228)
                    step: function (val, fx) {

                        attr[translateProp] =
                            translateStart +
                            fx.pos * (yAxis.pos - translateStart);
                        series.group.attr(attr);
                    }
                }));

                // delete this function to allow it only once
                series.animate = null;
            }
        }
    },

    /**
     * Remove this series from the chart
     */
    remove: function () {
        var series = this,
            chart = series.chart;

        // column and bar series affects other series of the same type
        // as they are either stacked or grouped
        if (chart.hasRendered) {
            each(chart.series, function (otherSeries) {
                if (otherSeries.type === series.type) {
                    otherSeries.isDirty = true;
                }
            });
        }

        Series.prototype.remove.apply(series, arguments);
    }
});

/**
 * A `column` series. If the [type](#series.column.type) option is
 * not specified, it is inherited from [chart.type](#chart.type).
 *
 * @type      {Object}
 * @extends   series,plotOptions.column
 * @excluding connectNulls,dashStyle,dataParser,dataURL,gapSize,gapUnit,linecap,
 *            lineWidth,marker,connectEnds,step
 * @product   highcharts highstock
 * @apioption series.column
 */

/**
 * @excluding halo,lineWidth,lineWidthPlus,marker
 * @product   highcharts highstock
 * @apioption series.column.states.hover
 */

/**
 * @excluding halo,lineWidth,lineWidthPlus,marker
 * @product   highcharts highstock
 * @apioption series.column.states.select
 */

/**
 * An array of data points for the series. For the `column` series type,
 * points can be given in the following ways:
 *
 * 1.  An array of numerical values. In this case, the numerical values
 * will be interpreted as `y` options. The `x` values will be automatically
 * calculated, either starting at 0 and incremented by 1, or from `pointStart`
 * and `pointInterval` given in the series options. If the axis has
 * categories, these will be used. Example:
 *
 *  ```js
 *  data: [0, 5, 3, 5]
 *  ```
 *
 * 2.  An array of arrays with 2 values. In this case, the values correspond
 * to `x,y`. If the first value is a string, it is applied as the name
 * of the point, and the `x` value is inferred.
 *
 *  ```js
 *     data: [
 *         [0, 6],
 *         [1, 2],
 *         [2, 6]
 *     ]
 *  ```
 *
 * 3.  An array of objects with named values. The objects are point
 * configuration objects as seen below. If the total number of data
 * points exceeds the series' [turboThreshold](#series.column.turboThreshold),
 * this option is not available.
 *
 *  ```js
 *     data: [{
 *         x: 1,
 *         y: 9,
 *         name: "Point2",
 *         color: "#00FF00"
 *     }, {
 *         x: 1,
 *         y: 6,
 *         name: "Point1",
 *         color: "#FF00FF"
 *     }]
 *  ```
 *
 * @type      {Array<Object|Array|Number>}
 * @extends   series.line.data
 * @excluding marker
 * @sample    {highcharts} highcharts/chart/reflow-true/
 *            Numerical values
 * @sample    {highcharts} highcharts/series/data-array-of-arrays/
 *            Arrays of numeric x and y
 * @sample    {highcharts} highcharts/series/data-array-of-arrays-datetime/
 *            Arrays of datetime x and y
 * @sample    {highcharts} highcharts/series/data-array-of-name-value/
 *            Arrays of point.name and y
 * @sample    {highcharts} highcharts/series/data-array-of-objects/
 *            Config objects
 * @product   highcharts highstock
 * @apioption series.column.data
 */

/**
 * The color of the border surrounding the column or bar.
 *
 * In styled mode, the border stroke can be set with the `.highcharts-point`
 * rule.
 *
 * @type      {Color}
 * @sample    {highcharts} highcharts/plotoptions/column-bordercolor/
 *            Dark gray border
 * @default   undefined
 * @product   highcharts highstock
 * @apioption series.column.data.borderColor
 */

/**
 * The width of the border surrounding the column or bar.
 *
 * In styled mode, the stroke width can be set with the `.highcharts-point`
 * rule.
 *
 * @type      {Number}
 * @sample    {highcharts} highcharts/plotoptions/column-borderwidth/
 *            2px black border
 * @default   undefined
 * @product   highcharts highstock
 * @apioption series.column.data.borderWidth
 */


text:
package gorocksdb

// #include "rocksdb/c.h"
import "C"

// A Comparator object provides a total order across slices that are
// used as keys in an sstable or a database.
type Comparator interface {
	// Three-way comparison. Returns value:
	//   < 0 iff "a" < "b",
	//   == 0 iff "a" == "b",
	//   > 0 iff "a" > "b"
	Compare(a, b []byte) int

	// The name of the comparator.
	Name() string
}

// NewNativeComparator creates a Comparator object.
func NewNativeComparator(c *C.rocksdb_comparator_t) Comparator {
	return nativeComparator{c}
}

type nativeComparator struct {
	c *C.rocksdb_comparator_t
}

func (c nativeComparator) Compare(a, b []byte) int { return 0 }
func (c nativeComparator) Name() string            { return "" }

// Hold references to comperators.
var comperators = NewCOWList()

type comperatorWrapper struct {
	name       *C.char
	comparator Comparator
}

func registerComperator(cmp Comparator) int {
	return comperators.Append(comperatorWrapper{C.CString(cmp.Name()), cmp})
}

//export gorocksdb_comparator_compare
func gorocksdb_comparator_compare(idx int, cKeyA *C.char, cKeyALen C.size_t, cKeyB *C.char, cKeyBLen C.size_t) C.int {
	keyA := charToByte(cKeyA, cKeyALen)
	keyB := charToByte(cKeyB, cKeyBLen)
	return C.int(comperators.Get(idx).(comperatorWrapper).comparator.Compare(keyA, keyB))
}

//export gorocksdb_comparator_name
func gorocksdb_comparator_name(idx int) *C.char {
	return comperators.Get(idx).(comperatorWrapper).name
}

redpajama_set_name: RedPajamaGithub


text:
package com.github.vvinston.functional;

import javax.annotation.Nonnull;
import java.util.function.BiConsumer;

public final class GuardedBiConsumerBuilder {
    public <INPUT1, INPUT2> GuardedBiConsumerBuilderStepOne doTry(@Nonnull final BiConsumer<INPUT1, INPUT2> success) {
        return new GuardedBiConsumerBuilderStepOne<>(success);
    }
}


text:
const { Socket } = require('net')
const { run, wait } = require('f-promise')
const { sshPoints } = require('slrun-remote-client')
const reverseSSHTunnel = require('./reverse-ssh-tunnel')
const createServiceApp = require('./create-service-app')

const localhost = '127.0.0.1'

function add (options) {
  return run(() => {
    const sshPoint = wait(sshPoints.getNextPoint())
    const { sshProxyPort, onSocket } = wait(reverseSSHTunnel(sshPoint))
    const serviceAppInfo = wait(createServiceApp(options))
    const service = {
      ...options,
      localPort: serviceAppInfo.port
    }
    console.log(service, sshProxyPort)
    onSocket((info, accept) => {
      const localSocket = new Socket()
      localSocket.connect(service.localPort, localhost, () => {
        const proxySocket = accept()
        localSocket.pipe(proxySocket).pipe(localSocket)
      })
    })
    return service
  })
}

module.exports = add


text:
require 'pathname' # JJM WORK_AROUND #14073
require Pathname.new(__FILE__).dirname.dirname.expand_path + 'crmsh'

Puppet::Type.type(:cs_rsc_defaults).provide(:crm, :parent => Puppet::Provider::Crmsh) do
  desc 'Specific provider for a rather specific type since I currently have no plan to
        abstract corosync/pacemaker vs. keepalived. This provider will check the state
        of Corosync global defaults for resource options.'

  # Path to the crm binary for interacting with the cluster configuration.
  commands :crm           => 'crm'
  commands :cibadmin      => 'cibadmin'

  def self.instances

    block_until_ready

    instances = []

    cmd = [ command(:crm), 'configure', 'show', 'xml' ]
    if Puppet::PUPPETVERSION.to_f < 3.4
      raw, status = Puppet::Util::SUIDManager.run_and_capture(cmd)
    else
      raw = Puppet::Util::Execution.execute(cmd)
      status = raw.exitstatus
    end
    doc = REXML::Document.new(raw)

    REXML::XPath.each(doc, '//configuration/rsc_defaults/meta_attributes/nvpair') do |e|
      items = e.attributes
      rsc_defaults = { :name => items['name'], :value => items['value'] }

      rsc_defaults_instance = {
        :name       => rsc_defaults[:name],
        :ensure     => :present,
        :value      => rsc_defaults[:value],
        :provider   => self.name
      }
      instances << new(rsc_defaults_instance)
    end
    instances
  end

  # Create just adds our resource to the property_hash and flush will take care
  # of actually doing the work.
  def create
    @property_hash = {
      :name   => @resource[:name],
      :ensure => :present,
      :value  => @resource[:value],
    }
  end

  # Unlike create we actually immediately delete the item.
  def destroy
    debug('Removing resource default')
    cibadmin('--scope', 'rsc_defaults', '--delete', '--xpath', "//configuration/rsc_defaults/meta_attributes/nvpair[@name='#{resource[:name]}']")
    @property_hash.clear
  end

  # Getters that obtains the first and second primitives and score in our
  # ordering definintion that have been populated by prefetch or instances
  # (depends on if your using puppet resource or not).
  def value
    @property_hash[:value]
  end

  # Our setters for the first and second primitives and score.  Setters are
  # used when the resource already exists so we just update the current value
  # in the property hash and doing this marks it to be flushed.
  def value=(should)
    @property_hash[:value] = should
  end

  # Flush is triggered on anything that has been detected as being
  # modified in the property_hash.  It generates a temporary file with
  # the updates that need to be made.  The temporary file is then used
  # as stdin for the crm command.
  def flush
    unless @property_hash.empty?
      # clear this on properties, in case it's set from a previous
      # run of a different corosync type
      ENV['CIB_shadow'] = nil
      crm('configure', 'rsc_defaults', '$id="rsc-options"', "#{@property_hash[:name]}=#{@property_hash[:value]}")
    end
  end
end


text:
require 'spec_helper'

describe Admin::UsersController do
  let(:admin) { FactoryGirl.create(:user, admin: true)}
  let(:user) { FactoryGirl.create(:user) }

  def as_admin
    session[:user_id] = admin.id
  end

  describe 'edit' do
    it 'requires login by an administrator' do
      expect { get :edit, params: { id: user.id }}.to raise_error(QA::NotAuthorised)
    end

    it 'is successful as admin' do
      as_admin
      get :edit, params: { id: user.id }
      expect(response).to be_success
    end

    it 'loads the user data' do
      as_admin
      get :edit, params: { id: user.id }
      expect(assigns(:user)).to be_a(User)
    end
  end

  describe 'update' do
    it 'requires login by an administrator' do
      expect { put :update, params: { id: user.id }}.to raise_error(QA::NotAuthorised)
    end

    it 'redirects to the user page' do
      as_admin
      put :update, params: { id: user.id, user: { admin: false, moderator: false }}
      expect(response).to redirect_to(user)
    end
  end
end


text:
/*
 * 2012-3 Red Hat Inc. and/or its affiliates and other contributors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.overlord.rtgov.analytics.service;

import static org.junit.Assert.*;

import org.junit.Test;
import org.overlord.rtgov.analytics.service.OperationDefinition;
import org.overlord.rtgov.analytics.service.RequestFaultDefinition;
import org.overlord.rtgov.analytics.service.RequestResponseDefinition;

public class OperationDefinitionTest {

    private static final String FAULT_1 = "fault1";
    private static final String FAULT_2 = "fault2";

    @Test
    public void testMergeNoReqResp() {

        OperationDefinition od1=new OperationDefinition();

        OperationDefinition od2=new OperationDefinition();

        RequestResponseDefinition rr1=new RequestResponseDefinition();
        od2.setRequestResponse(rr1);

        od1.merge(od2);

        if (od1.getRequestResponse() == null) {
            fail("Failed to req/resp");
        }
    }

    @Test
    public void testMergeMissingReqFault() {

        OperationDefinition od1=new OperationDefinition();

        RequestResponseDefinition rr1=new RequestResponseDefinition();
        od1.setRequestResponse(rr1);

        RequestFaultDefinition rf1=new RequestFaultDefinition();
        rf1.setFault(FAULT_1);
        od1.getRequestFaults().add(rf1);

        OperationDefinition od2=new OperationDefinition();

        RequestFaultDefinition rf2=new RequestFaultDefinition();
        rf2.setFault(FAULT_2);
        od2.getRequestFaults().add(rf2);

        od1.merge(od2);

        if (od1.getRequestResponse() == null) {
            fail("Failed to req/resp");
        }

        if (od1.getRequestFaults().size() != 2) {
            fail("Expecting 2 faults: "+od1.getRequestFaults().size());
        }

        if (od1.getRequestFault(FAULT_1) == null) {
            fail("Failed to get fault 1");
        }

        if (od1.getRequestFault(FAULT_2) == null) {
            fail("Failed to get fault 2");
        }
    }
}


text:
layout: post
title:  "Apiman 2.1.5.Final has been released - please update if you're on an old version"
date: 2021-12-20 14:00:00 GMT
author: marc_savy
categories: apiman release
---

Hi, Apiman fans!

I hope you're all well, and Season's Greetings to those of you who celebrate Christmas 🎄.

I'd like to remind Apiman users to consider updating to Apiman 2.1.5 promptly, as it contains fixes for the now well-known log4j2 bugs.
You can download Apiman from all the usual official places: [Apiman Downloads](https://www.apiman.io/latest/download.html) or the [GitHub release](https://github.com/apiman/apiman/releases/tag/2.1.5.Final)

[If you have questions about this release, please join us on GitHub Discussions](https://github.com/apiman/apiman/discussions/1722)


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management.Automation;
using System.Reflection;
using System.Collections.ObjectModel;

namespace Slack.Webhooks.PowerShell
{
    /// <summary>
    /// <para type="synopsis">Used to create a SlackMessage object.</para>
    /// <para type="description">Used to create a SlackMessage that you can send to a Slack incoming webhook.</para>
    /// <para type="description">A SlackMessage can be thought of as a vehicle forwhich your text, Attachments and fields travel to the API.</para>
    /// <para type="description">Only a SlackMessage can be sent to the webhook, however you may put an array of attachments into a SlackMessage.</para>
    /// <para type="link" uri="(https://api.slack.com/docs/message-formatting)">[Slack Message Formatting]</para>
    /// </summary>
    /// <example>
    ///     <code>$message = New-SlackMessage -Text "Something has happened and I'm sending a message about it" -Username "Mr Magoo"
Send-SlackMessage -URI "https://hooks.slack.com/services/T63QJj9PJ/B63335SU9/BaCnMZ1Gf27CPM2gYWPuptHk" -Message $message </code>
    ///     <para>In this example I am sending a simple, plain text message.</para>
    /// </example>
    /// <example>
    ///     <code>$message = New-SlackMessage -Text "<!everyone> some kind of thing has happened and I'm sending a message about it" -Username "Mr Magoo"  -NoMarkdown
Send-SlackMessage -URI "https://hooks.slack.com/services/T63QJj9PJ/B63335SU9/BaCnMZ1Gf27CPM2gYWPuptHk" -Message $message </code>
    ///     <para>In this example I am sending a simple, plain text message.</para>
    /// </example>
    [Cmdlet(VerbsCommon.New, "SlackMessage", SupportsShouldProcess = true, SupportsTransactions = false)]
    [OutputType(typeof(SlackMessage))]
    public class CreateSlackMessage : PSCmdlet, IDynamicParameters
    {
        /// <summary>
        /// <para type="description">The Channel you want to post the message to. Must include the # at the front of the channel name.</para>
        /// </summary>
        [Parameter(
            Mandatory = false,
            Position = 0,
            HelpMessage = "The Channel you want to post the message to. Must include the # at the front of the channel name."
            )]
        public string Channel { get; set; }

        /// <summary>
        /// <para type="description">The main text of the message.</para>
        /// </summary>
        [Parameter(
            Mandatory = false,
            Position = 1,
            HelpMessage = "The main text of the message."
            )]
        [ValidateNotNullOrEmpty()]
        public string Text { get; set; }

        private static RuntimeDefinedParameterDictionary _staticStorage;
        //https://msdn.microsoft.com/en-us/library/bb336630(v=vs.110).aspx
        /// <summary>
        /// <para type="description">A Slack Emoji to use as the avatar</para>
        /// </summary>
        /// <returns></returns>
        public object GetDynamicParameters()
        {
            IEnumerable<string> emojinames = typeof(Emoji).GetProperties().Select(x => x.Name);
            var runtimeDefinedParameterDictionary = new RuntimeDefinedParameterDictionary();
            var attrib = new Collection<Attribute>()
            {
                new ParameterAttribute() { HelpMessage = "A Slack Emoji to use as the avatar", Mandatory = false},
                new ValidateSetAttribute(emojinames.ToArray())
            };
            var parameter = new RuntimeDefinedParameter("IconEmoji", typeof(String), attrib);
            runtimeDefinedParameterDictionary.Add("IconEmoji", parameter);
            _staticStorage = runtimeDefinedParameterDictionary;
            return runtimeDefinedParameterDictionary;
        }
        /// <summary>
        /// <para type="description">The name that you want to post a message as. Doesn't have to be an existing user.</para>
        /// </summary>
        [Parameter(
            Mandatory = false,
            Position = 2,
            HelpMessage = "The name that you want to post a message as. Doesn't have to be an existing user."
            )]
        public string Username { get; set; }

        /// <summary>
        /// <para type="description">By default, Slack will not linkify channel names (starting with a '#') and usernames (starting with an '@').
        /// Include this switch to enable this behaviour.
        /// If you've set Parse to 'full' then this is enabled already enabled.
        /// </para>
        /// </summary>
        [Parameter(Mandatory = false,
                    HelpMessage = "By default, Slack will not linkify channel names (starting with a '#') and usernames (starting with an '@')\nInclude this switch to enable this behaviour.\nIf you've set Parse to 'full' then this is enabled already enabled.")]
        public SwitchParameter LinkNames { get; set; }

        /// <summary>
        /// <para type="description">Turn off Markdown processing on the message</para>
        /// </summary>
        [Parameter(Mandatory = false,
            HelpMessage = "Turn off Markdown processing on the message")]
        public SwitchParameter NoMarkdown {get;set;}
        /// <summary>
        /// <para type="description">If you don't want Slack to perform any processing on your message, pass an argument of none
        /// If you want Slack to treat your message as completely unformatted, use "full".
        /// This will ignore any markup formatting you added to your message.
        /// </para>
        /// </summary>
        [Parameter(
            Mandatory = false,
            HelpMessage = "If you don't want Slack to perform any processing on your message, pass an argument of none\nIf you want Slack to treat your message as completely unformatted, use \"full\". This will ignore any markup formatting you added to your message."
            )]
        [ValidateSet("full", "none")]
        public string ParseMode {get; set;}
        /// <summary>
        /// <para type="description">A URL to a small image that will become the avatar for the message.
        /// IconEmoji takes precedence over this.
        /// </para>
        /// </summary>
        [Parameter(Mandatory = false,
            HelpMessage = "A URL to a small image that will become the avatar for the message.\nIconEmoji takes precedence over this"
            )]
        public string IconUrl {get; set;}
        /// <summary>
        /// <para type="description">An attachment or array of attachments to add to the message.
        /// Note this is not a file attachment.
        /// </para>
        /// </summary>
        [Parameter(Mandatory = false,
                    ValueFromPipeline = true,
                    HelpMessage = "An attachment or array of attachments to add to the message.\nNote this is not a file attachment.")]
        public SlackAttachment[] Attachments {get; set;}
        /// <summary>
        /// <para type="description">Throw caution to the wind and carry on!</para>
        /// </summary>
        [Parameter(Mandatory = false,
            HelpMessage = "Throw caution to the wind and carry on!"
            )]
        public SwitchParameter Force { get; set; }

        protected override void BeginProcessing()
        {
        }

        protected override void ProcessRecord()
        {

            WriteDebug("Instansiating SlackMessage");
            SlackMessage message = new SlackMessage
            {
                Channel = Channel,
                Text = Text,
                Username = Username,
                Parse = ParseMode,
                Attachments = new List<SlackAttachment>()
            };

            if (!string.IsNullOrEmpty(IconUrl))
            {
                WriteDebug("Building IconUrl URIBuilder");
                UriBuilder IconURI = new UriBuilder(IconUrl);
                message.IconUrl = IconURI.Uri;
            }
            if (NoMarkdown) { message.Mrkdwn = false; }
            if (LinkNames) { message.LinkNames = true; }
            if (Attachments != null)
            {
                //need to stop people from adding more than 20 attachments..unless the lib already does this?
                if ((Attachments.Length > 20 && Attachments.Length < 100) || Force)
                {
                    //ignore the guidelines that say you should not send a message with over 100 attachments.
                    ErrorRecord x = new ErrorRecord(new IndexOutOfRangeException("Number of SlackAttachments exceeds 20"), "Number of SlackAttachments exceeds 20", ErrorCategory.LimitsExceeded, Attachments);
                    ThrowTerminatingError(x);
                }
                else if (Attachments.Length > 100)
                {
                    //might as well kill it here, the API won't process more than 100 attachments.
                    ErrorRecord x = new ErrorRecord(new IndexOutOfRangeException("Number of SlackAttachments exceeds 100"), "Number of SlackAttachments exceeds 100", ErrorCategory.LimitsExceeded, Attachments);
                    ThrowTerminatingError(x);
                }
                WriteDebug("Attachments Found. Converting to list");
                message.Attachments = new List<SlackAttachment>(Attachments);
            }
            var IconEmojiRuntime = new RuntimeDefinedParameter();
            _staticStorage.TryGetValue("IconEmoji", out IconEmojiRuntime);

            if (IconEmojiRuntime.IsSet)
            {
                WriteDebug("setting emoji property info");

                PropertyInfo emojiProperty = typeof(Emoji).GetProperty(IconEmojiRuntime.Value.ToString());
                WriteDebug("Selecting Emoji");
                message.IconEmoji = (string)emojiProperty.GetValue(null, null);
            }

            WriteDebug("Message Created Ouputting to pipeline");
            WriteObject(message);
        }

        protected override void EndProcessing()
        {
            base.EndProcessing();
        }
    }
}


text:
package de.fraunhofer.fokus.movepla.model;

import com.liferay.portal.kernel.bean.AutoEscapeBeanHandler;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.util.StringBundler;
import com.liferay.portal.model.BaseModel;
import com.liferay.portal.model.impl.BaseModelImpl;
import com.liferay.portal.util.PortalUtil;

import de.fraunhofer.fokus.movepla.service.RelatedApplicationsLocalServiceUtil;

import java.io.Serializable;

import java.lang.reflect.Proxy;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class RelatedApplicationsClp extends BaseModelImpl<RelatedApplications>
    implements RelatedApplications {
    private long _RelatedApplicationsID;
    private long _companyId;
    private long _userId;
    private String _userUuid;
    private Date _createDate;
    private Date _modifiedDate;
    private long _applicationId;
    private long _applicationId2;
    private BaseModel<?> _relatedApplicationsRemoteModel;

    public RelatedApplicationsClp() {
    }

    public Class<?> getModelClass() {
        return RelatedApplications.class;
    }

    public String getModelClassName() {
        return RelatedApplications.class.getName();
    }

    public long getPrimaryKey() {
        return _RelatedApplicationsID;
    }

    public void setPrimaryKey(long primaryKey) {
        setRelatedApplicationsID(primaryKey);
    }

    public Serializable getPrimaryKeyObj() {
        return new Long(_RelatedApplicationsID);
    }

    public void setPrimaryKeyObj(Serializable primaryKeyObj) {
        setPrimaryKey(((Long) primaryKeyObj).longValue());
    }

    @Override
    public Map<String, Object> getModelAttributes() {
        Map<String, Object> attributes = new HashMap<String, Object>();

        attributes.put("RelatedApplicationsID", getRelatedApplicationsID());
        attributes.put("companyId", getCompanyId());
        attributes.put("userId", getUserId());
        attributes.put("createDate", getCreateDate());
        attributes.put("modifiedDate", getModifiedDate());
        attributes.put("applicationId", getApplicationId());
        attributes.put("applicationId2", getApplicationId2());

        return attributes;
    }

    @Override
    public void setModelAttributes(Map<String, Object> attributes) {
        Long RelatedApplicationsID = (Long) attributes.get(
                "RelatedApplicationsID");

        if (RelatedApplicationsID != null) {
            setRelatedApplicationsID(RelatedApplicationsID);
        }

        Long companyId = (Long) attributes.get("companyId");

        if (companyId != null) {
            setCompanyId(companyId);
        }

        Long userId = (Long) attributes.get("userId");

        if (userId != null) {
            setUserId(userId);
        }

        Date createDate = (Date) attributes.get("createDate");

        if (createDate != null) {
            setCreateDate(createDate);
        }

        Date modifiedDate = (Date) attributes.get("modifiedDate");

        if (modifiedDate != null) {
            setModifiedDate(modifiedDate);
        }

        Long applicationId = (Long) attributes.get("applicationId");

        if (applicationId != null) {
            setApplicationId(applicationId);
        }

        Long applicationId2 = (Long) attributes.get("applicationId2");

        if (applicationId2 != null) {
            setApplicationId2(applicationId2);
        }
    }

    public long getRelatedApplicationsID() {
        return _RelatedApplicationsID;
    }

    public void setRelatedApplicationsID(long RelatedApplicationsID) {
        _RelatedApplicationsID = RelatedApplicationsID;
    }

    public long getCompanyId() {
        return _companyId;
    }

    public void setCompanyId(long companyId) {
        _companyId = companyId;
    }

    public long getUserId() {
        return _userId;
    }

    public void setUserId(long userId) {
        _userId = userId;
    }

    public String getUserUuid() throws SystemException {
        return PortalUtil.getUserValue(getUserId(), "uuid", _userUuid);
    }

    public void setUserUuid(String userUuid) {
        _userUuid = userUuid;
    }

    public Date getCreateDate() {
        return _createDate;
    }

    public void setCreateDate(Date createDate) {
        _createDate = createDate;
    }

    public Date getModifiedDate() {
        return _modifiedDate;
    }

    public void setModifiedDate(Date modifiedDate) {
        _modifiedDate = modifiedDate;
    }

    public long getApplicationId() {
        return _applicationId;
    }

    public void setApplicationId(long applicationId) {
        _applicationId = applicationId;
    }

    public long getApplicationId2() {
        return _applicationId2;
    }

    public void setApplicationId2(long applicationId2) {
        _applicationId2 = applicationId2;
    }

    public BaseModel<?> getRelatedApplicationsRemoteModel() {
        return _relatedApplicationsRemoteModel;
    }

    public void setRelatedApplicationsRemoteModel(
        BaseModel<?> relatedApplicationsRemoteModel) {
        _relatedApplicationsRemoteModel = relatedApplicationsRemoteModel;
    }

    public void persist() throws SystemException {
        if (this.isNew()) {
            RelatedApplicationsLocalServiceUtil.addRelatedApplications(this);
        } else {
            RelatedApplicationsLocalServiceUtil.updateRelatedApplications(this);
        }
    }

    @Override
    public RelatedApplications toEscapedModel() {
        return (RelatedApplications) Proxy.newProxyInstance(RelatedApplications.class.getClassLoader(),
            new Class[] { RelatedApplications.class },
            new AutoEscapeBeanHandler(this));
    }

    @Override
    public Object clone() {
        RelatedApplicationsClp clone = new RelatedApplicationsClp();

        clone.setRelatedApplicationsID(getRelatedApplicationsID());
        clone.setCompanyId(getCompanyId());
        clone.setUserId(getUserId());
        clone.setCreateDate(getCreateDate());
        clone.setModifiedDate(getModifiedDate());
        clone.setApplicationId(getApplicationId());
        clone.setApplicationId2(getApplicationId2());

        return clone;
    }

    public int compareTo(RelatedApplications relatedApplications) {
        long primaryKey = relatedApplications.getPrimaryKey();

        if (getPrimaryKey() < primaryKey) {
            return -1;
        } else if (getPrimaryKey() > primaryKey) {
            return 1;
        } else {
            return 0;
        }
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }

        RelatedApplicationsClp relatedApplications = null;

        try {
            relatedApplications = (RelatedApplicationsClp) obj;
        } catch (ClassCastException cce) {
            return false;
        }

        long primaryKey = relatedApplications.getPrimaryKey();

        if (getPrimaryKey() == primaryKey) {
            return true;
        } else {
            return false;
        }
    }

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

    @Override
    public String toString() {
        StringBundler sb = new StringBundler(15);

        sb.append("{RelatedApplicationsID=");
        sb.append(getRelatedApplicationsID());
        sb.append(", companyId=");
        sb.append(getCompanyId());
        sb.append(", userId=");
        sb.append(getUserId());
        sb.append(", createDate=");
        sb.append(getCreateDate());
        sb.append(", modifiedDate=");
        sb.append(getModifiedDate());
        sb.append(", applicationId=");
        sb.append(getApplicationId());
        sb.append(", applicationId2=");
        sb.append(getApplicationId2());
        sb.append("}");

        return sb.toString();
    }

    public String toXmlString() {
        StringBundler sb = new StringBundler(25);

        sb.append("<model><model-name>");
        sb.append("de.fraunhofer.fokus.movepla.model.RelatedApplications");
        sb.append("</model-name>");

        sb.append(
            "<column><column-name>RelatedApplicationsID</column-name><column-value><![CDATA[");
        sb.append(getRelatedApplicationsID());
        sb.append("]]></column-value></column>");
        sb.append(
            "<column><column-name>companyId</column-name><column-value><![CDATA[");
        sb.append(getCompanyId());
        sb.append("]]></column-value></column>");
        sb.append(
            "<column><column-name>userId</column-name><column-value><![CDATA[");
        sb.append(getUserId());
        sb.append("]]></column-value></column>");
        sb.append(
            "<column><column-name>createDate</column-name><column-value><![CDATA[");
        sb.append(getCreateDate());
        sb.append("]]></column-value></column>");
        sb.append(
            "<column><column-name>modifiedDate</column-name><column-value><![CDATA[");
        sb.append(getModifiedDate());
        sb.append("]]></column-value></column>");
        sb.append(
            "<column><column-name>applicationId</column-name><column-value><![CDATA[");
        sb.append(getApplicationId());
        sb.append("]]></column-value></column>");
        sb.append(
            "<column><column-name>applicationId2</column-name><column-value><![CDATA[");
        sb.append(getApplicationId2());
        sb.append("]]></column-value></column>");

        sb.append("</model>");

        return sb.toString();
    }
}


text:
JGI / KBase Push to KBase integration tests
===========================================

This repo contains JUnit tests that exercise the the
[Push to KBase](https://kbase.us/transfer-jgi-data/) (PtKB)
functionality jointly developed by [KBase](http://kbase.us) and
[JGI](http://jgi.doe.gov/).

Warning and prerequisites
-------------------------

The tests contained here are time consuming and difficult to set up due to the
number and complexity of the systems involved. There are probably only a few
people that will need to set up and run the tests, and more or less these
people are presumed to be experts in the KBase and JGI APIs and systems.

### Prerequisites

Anyone attempting to run the tests should have a reasonable working knowledge
of (versions are given as of the time of writing):

* [KBase runtime](https://github.com/kbase/bootstrap)
* [KBase dev_container](https://github.com/kbase/dev_container)
* [KBase Workspace Service](https://github.com/kbase/workspace_deluxe) (WSS) 0.3.4
* [KBase Shock Service](https://github.com/kbase/shock_service) 0.9.6
* [KBase Handle Service](https://github.com/kbase/handle_service) 5eda76e
* [KBase Handle Manager](https://github.com/kbase/handle_mngr) 81297d5
* [KBase Authentication](https://github.com/kbase/auth)
* [KBase common libraries](https://github.com/kbase/kbapi_common)
* [KBase Type Compiler](https://github.com/kbase/typecomp) (1)
* [PtKB operations](https://kbase.us/transfer-jgi-data/)
* [JGI Genome Portal](http://genome.jgi.doe.gov/)
* [Jenkins](https://jenkins-ci.org/) and specifically the [KBase Jenkins instance](https://jenkins.kbase.us)
* [nginx](https://www.nginx.com/)
* [MySQL](https://www.mysql.com/)
* [MongoDB](https://www.mongodb.com)
* [Ubuntu](http://www.ubuntu.com/)
* git and github
* [Java](http://www.oracle.com/technetwork/java/javaee/overview/index.html) 1.7
* [ant](http://ant.apache.org/) 1.8.4
* [Python](https://www.python.org/) 2.7

(1) The type compiler is only strictly necessary if the wipe server's API needs
to be changed and recompiled. However, the WSS and Handle services are also
accessed via type compiler generated clients.

Additionally, to really understand what's going on, some knowledge of the JGI
Java Server Faces front end, JGI Sequence Data Management (SDM) server, JGI JAMO
data management system, NERSC High Performance Storage System (HPSS), and
NERSC high.q job queue is useful.

PtKB sequence of events
-----------------------

* A user selects file(s) from a JGI genome portal organism page
  (e.g. [Blastococcus sp. URHD0036](http://genome.jgi.doe.gov/pages/dynamicOrganismDownload.jsf?organism=BlaspURHD0036))
  and completes the steps necessary to push the file(s) to KBase via the web UI.
* The JGI Java Server Faces front end passes the request to the SDM server.
* The SDM server runs a job on the NERSC high speed queue (high.q) to perform
  the PtKB operation.
* The job checks with JAMO to retrieve the file metadata and location for the
  file.
* If the file has previously been pushed to KBase, the Shock node ID for the
  file is retrieved and reused rather than pushing the file again. The job
  queries the Shock node to ensure it exists. If the file has never been pushed
  or the Shock node no longer exists:
  * If the data is not available in the disk cache, the job pulls the
    data from HPSS and stores it in a disk cache.
  * The file is uploaded to Shock and a Shock node ID returned.
  * The Shock node ID is stored in an associative data structure with the file ID
    so the Shock node can be reused in later pushes.
* A handle for the Shock node is created (for a new Shock node) or looked up
  (for an existing node) in the Handle Service.
* If not already extant, a workspace is created in the WSS name for the
  organism and the PtKB user. This workspace is shared, read-only, with the
  user.
* A workspace object containing the handle and other data about the file,
  along with a provenance object, is uploaded to the Workspace service.

Endpoints
---------

[http://genome.jgi.doe.gov](http://genome.jgi.doe.gov) is the production
endpoint for PtKB (and all other Genome Portal operations). This endpoint
pushes to KBase production systems.

[http://genomeportal.jgi.doe.gov](http://genomeportal.jgi.doe.gov) is the
dev/test endpoint for PtKB (and etc...). This endpoint currently pushes to
dev03.berkeley.kbase.us.

**NOTE:** the dev/test endpoint *cannot* retrieve data from HPSS. If a push
includes data that is only available on HPSS it will fail. The workaround is
to manually download the data from the JGI organism page, which will create
a disk cache that expires in 90 days.

Install
-------

Note that without working with JGI to change where the dev/test endpoint
pushes, building a new test server won't do much good. Currently the test
server is dev03.berkeley.kbase.us - this is also a good reference to consult
if trying to duplicate or move the test server.

1. Obtain an Ubuntu machine with the KBase runtime installed (from the
   `bootstrap` repo). You probably already have access to such a machine if
   you work for KBase. If not, install the runtime as per directions (after
   installing Ubuntu if necessary).
2. Install the `dev_container` as per instructions.
3. Install `shock_service`, workspace service (`workspace_deluxe` repo),
   `handle_service`, `handle_mngr`, `auth`, and `kbapi_common` as per
   instructions.
3. Clone this repo.
4. Install nginx.

Configure
---------

These instructions assume:

* The services will be accessed via nginx, and [nginx will be configured with a self signed certificate](https://www.digitalocean.com/community/tutorials/how-to-create-a-ssl-certificate-on-nginx-for-ubuntu-12-04) (SSC).
* MongoDB will run on the default port without auth.
* MySQL will run on the default port with no root password. It wouldn't be
  difficult to change this but hasn't so far been necessary.

1. Configure the Shock server as per instructions. Make sure to specify an
   administrative user (note in 0.9.6, the admin user in the config seems to
   be ignored. The wipe server contains a hack to work around this).
2. Configure the Handle Service as per instructions.
  1. Note that there are hardcoded system calls to curl in the Handle Service
     implementation file (produced by the type compiler). Since nginx uses a
     SSC, the implementation file must be hand edited to provide the
     `--insecure` command line option to all curl calls.
  2. As part of the configuration, you will need to set up appropriate MySQL
     tables for the use of the Handle Service.
3. Configure the Handle Manager as per instructions.
  1. Note that there are hardcoded system calls to curl in the Handle Manager
     implementation file (produced by the type compiler). Since nginx uses a
     SSC, the implementation file must be hand edited to provide the
     `--insecure` command line option to all curl calls.
  2. Ensure the shock administrator credentials provided in the deploy.cfg file
     match the administrator in the Shock configuration file.
4. Configure the Workspace service as per instructions.
  1. Ensure the handle manager credentials provided in the deploy.cfg file
     match the allowed user in the handle manager configuration file.
5. Configure the wipe server.
  1. The configuration for the Wipe server is contained in the server
     implementation file in this repo at
     `lib/biokbase/wipe_dev03/impl.py`.
  2. The wipe server depends on libaries in `kbapi_common` and `auth`. For
     simplicity's sake, just link them appropriately. Assuming the
     working directory is `/kb/dev_container/modules/jgi_kbase_integration_tests/lib`:
    1. `ln -s /kb/dev_container/modules/auth/python-libs/biokbase/nexus/ biokbase/nexus`
    2. `ln -s /kb/dev_container/modules/kbapi_common/lib/biokbase/log.py biokbase/log.py`
    3. Alternately the standard KBase deploy process can be used to deploy the
       libraries along with the other services and configure the path.
6. Configure the tests
  1. User accounts are configured in ./test.cfg to avoid checking credentials
     into git. In any case, use throwaway accounts to run the tests as they
     may be exposed publicly.
  2. The remaining configuration is in the main test file at
     src/us/kbase/jgiintegration/test/JGIIntegrationTest.java.
7. Configure nginx
  1. Example configurations are in nginx_example_conf
  2. See the documentation linked above for setting up a SSC.
8. Load the JGI typespecs
   ([KBaseFile](https://narrative.kbase.us/functional-site/#/spec/module/KBaseFile))
   and
   ([KBaseCommon](https://narrative.kbase.us/functional-site/#/spec/module/KBaseCommon))
   into the workspace
  1. The types are also available in the `types` directory of this repo, but
     the KBase production types should be considered the source of truth in
     the case of inconsistency

Note that the shock administration user has to be set consistently in many
places - currently in the Shock configuration file, the Handle Manger
configuration file, the Wipe Server impl.py file, and the test.cfg file.

Start services
--------------

This list assumes MySQL and nginx start on boot.

1. Start MongoDB without auth. A typical command line:
   `/kb/runtime/bin/mongod --dbpath /mnt2/mongodata/mongodata >> /mnt2/mongodata/mongolog 2>&1 &`
2. Start shock with the start script listed in the wipe server config:
   ` /kb/deployment/services/shock_service/start_service`
3. Start the Handle Service:
  1. Since nginx is configured with an SSC, tell the Perl LWP module to allow them:
     `export PERL_LWP_SSL_VERIFY_HOSTNAME=0`
  2. Start the service:
     `/kb/deployment/services/handle_service/start_service`
4. Start the Handle Manager:
  1. Since nginx is configured with an SSC, tell the Perl LWP module to allow them:
     `export PERL_LWP_SSL_VERIFY_HOSTNAME=0`
  2. Start the service:
     `/kb/deployment/services/handle_mngr/start_service &`
5. Start the workspace service:
   `/kb/deployment/services/workspace/start_service`
6. Start the wipe service:

        export PYTHONPATH=/kb/dev_container/modules/jgi_kbase_integration_tests/lib/
        cd /kb/dev_container/modules/jgi_kbase_integration_tests/lib/
        python biokbase/wipe_dev03/server.py --host 0.0.0.0 --port 9000 >> wipelog 2>&1 &

Run tests
---------

To run tests, simply run `make` and the Makefile will run the tests. Java,
Python, and ant will need to be correctly configured.

**Notes:**

* Do not run the tests in parallel (e.g. if Jenkins is running the tests,
  don't start them locally). The tests change state both in the KBase services
  (WS, Handle, Shock) and in the JGI SDM server, and the tests are not
  designed to handle state changes not caused by said tests. They'll most
  likely fail.
* Ensure that all pushes have completed from one test run (for example,
  aborting the run may leave jobs on the NERSC queue) before starting another.
* One of the tests causes a failure email to be sent to the JGI / KBase email
  list. This is expected.

### Jenkins

Below is a typical config from the "Execute shell" portion of the KBase
Jenkins config. The rest of the configuration is pretty standard.

    export KB_RUNTIME=/kbase/runtimes/20140109-prod
    export JAVA_HOME=$KB_RUNTIME/java
    export PATH=$KB_RUNTIME/bin:$JAVA_HOME/bin:$PATH
    export ANT_HOME=$KB_RUNTIME/ant

    make test TESTCFG=/home/jenkins/gavin/jgi_kbase_integration_tests/test.cfg

Make sure all the Jenkins workers have the test.cfg properly filled out.

Common (and not so common) errors
---------------------------------

The first thing to try, if the tests fail and the cause is not obvious, is
manually pushing some files and observing the results. However, some common
errors and their potential causes are listed below.

* If tests are timing out with messages similar to
  `Timed out attempting to access object 6133.1.38460.TGCTGG.adnq.fastq.gz with version 1 in workspace Bacillus_sp_JGI_001005J19_kbasetest after 1800 sec`
  and failure emails are sent with the contents `failed to restore all files in 9 hour period`
  the probable (but not definite) explanation is that the JGI disk cache for
  the file in question has expired and the file is only available on HPSS.
  Download the file from the production JGI endpoint to recreate the cache.

* If tests are failing because the workspace is throwing 404s, 502s,
  connection refused, or consistently timing out it's probably due to [WOR-204](https://atlassian.kbase.us/browse/WOR-204).
  A PermGen error being thrown or occurring in the workspace logs is strong
  confirmation. If this occurs `kill -9` the workspace and restart.

* Tests occasionally fail because a portion of the JGI front end page fails to
  load according to HTMLUnit. Errors commonly look like
  `Timed out waiting for file group QC Filtered Raw Data to open after 60 seconds`,
  `Timed out waiting for PtKB button to load after 20 seconds`, or
  `Timed out waiting for files to push to Kbase after 60 seconds`. So
  far trying to determine the exact cause for these failures has been
  unsuccessful, they rarely occur, and the fix for a user would be simply
  reloading the page (although these errors have never been observed while
  interacting with the web page directly), so debugging the problem has
  been low priority. The cause may be a bug in HTMLUnit, an occasional failure
  of the JGI server, or a transport problem between the two servers. If **all**
  tests fail for the same error, then the problem is almost certainly due to
  the JGI SDM server.

* If a test causes a push but fails before the push can complete, the next
  test may fail with an error similar to that shown below. This occurs because
  test 1 fails, but the push email is still sent while test 2 is in progress,
  and so the email contents are unexpected. Errors like this can be safely
  ignored - just run the test again once test 1 is fixed.
  `correct email urls`
  `Expected: is <{7625.2.79179.AGTTCC.adnq.fastq.gz=https://narrative.kbase.us/functional-site/#/jgi/import/Blastococcus_sp_URHD0036_kbasetest/7625.2.79179.AGTTCC.adnq.fastq.gz}>`
   `got: <{final.assembly.fasta=https://narrative.kbase.us/functional-site/#/jgi/import/Burkholderia_sp_B13_kbasetest/final.assembly.fasta}>`

* Avast (and presumably other antivirus software) can interfere with
  javamail and cause errors and hangs, even when disabled by the program UI.


text:
local dsp = require "luci.dispatcher"
local nixio  = require "nixio"

m = Map("ocserv", translate("OpenConnect VPN"))

if m.uci:get("ocserv", "config", "auth") == "plain" then

--[[Users]]--

function m.on_commit(map)
	luci.sys.call("/etc/init.d/ocserv restart >/dev/null 2>&1")
end

s = m:section(TypedSection, "ocservusers", translate("Available users"))
s.anonymous = true
s.addremove = true
s.template = "cbi/tblsection"

s:option(Value, "name", translate("Name")).rmempty = true
s:option(DummyValue, "group", translate("Group")).rmempty = true
pwd = s:option(Value, "password", translate("Password"))
pwd.password = false

function pwd.write(self, section, value)
	local pass
	if string.match(value, "^%$%d%$.*") then
		pass = value
	else
		local t = tonumber(nixio.getpid()*os.time())
		local salt = "$1$" .. t .. "$"
		pass = nixio.crypt(value, salt)
	end
	Value.write(self, section, pass)
end

--[[if plain]]--
end

local lusers = { }
local fd = io.popen("/usr/bin/occtl show users", "r")
if fd then local ln
	repeat
		ln = fd:read("*l")
		if not ln then break end

		local id, user, group, vpn_ip, ip, device, time, cipher, status =
			ln:match("^%s*(%d+)%s+([-_%w]+)%s+([%(%)%.%*-_%w]+)%s+([%:%.-_%w]+)%s+([%:%.-_%w]+)%s+([%:%.-_%w]+)%s+([%:%.-_%w]+)%s+([%(%)%:%.-_%w]+)%s+([%:%.-_%w]+).*")
		if id then
			table.insert(lusers, {id, user, group, vpn_ip, ip, device, time, cipher, status})
		end
	until not ln
	fd:close()
end

--[[Active Users]]--

local s = m:section(Table, lusers, translate("Active users"))
s.anonymous = true
s.template = "cbi/tblsection"

s:option(DummyValue, 1, translate("ID"))
s:option(DummyValue, 2, translate("Username"))
s:option(DummyValue, 3, translate("Group"))
s:option(DummyValue, 4, translate("IP"))
s:option(DummyValue, 5, translate("VPN IP"))
s:option(DummyValue, 6, translate("Device"))
s:option(DummyValue, 7, translate("Time"))
s:option(DummyValue, 8, translate("Cipher"))
s:option(DummyValue, 9, translate("Status"))

return m


text:
'use strict';

var which = require('which');

try {
  which.sync('ruby');
} catch (ignored) {
  return console.log('WARNING: "ruby" executable not found in PATH!  Ruby is ' +
    'required.');
}

try {
  which.sync('jekyll');
} catch (ignored) {
  return console.log('WARNING: "jekyll" executable not found in PATH!  ' +
    'Jekyll is required.  Try "gem install jekyll"');
}

console.log('INFO: "jekyll" executable found; installation looks good');


text:
FROM node:18.10-slim

# Arbitrary but conventional working directory
WORKDIR /usr/src/app

# The firestore emulator uses Java
RUN apt update && apt install -y default-jre

# Install NPM dependencies
COPY package.json package-lock.json ./
COPY packages/catalog-server/package.json packages/catalog-server/
RUN npm ci

# We only need these firestore configuration files
COPY packages/catalog-server/firestore* packages/catalog-server/firebase* packages/catalog-server/

# Launch the emulator
WORKDIR packages/catalog-server
CMD [ "npm", "run", "emulators:start" ]


text:
import test from 'ava';
const { before, after, serial } = test;
import { resolve } from 'node:path';
import { getEngine } from '../util/engine.js';
import { startServer, stopServer } from '../util/httpserver.js';
import { fileURLToPath } from 'node:url';
import path from 'node:path';
const __dirname = path.dirname(fileURLToPath(import.meta.url));

const timeout = 20_000;

let engine;

function getPath(file) {
  return resolve(__dirname, '..', 'data', 'commandscripts', file);
}

before('Setup the HTTP server', () => {
  return startServer();
});

after.always('Stop the HTTP server', () => {
  return stopServer();
});

serial.beforeEach('Start the browser', async t => {
  t.timeout(timeout);
  engine = getEngine({ browser: 'chrome' });
  return engine.start();
});

serial('Run Chrome specific commands', async t => {
  const result = await engine.runMultiple([getPath('chrome.cjs')], {
    scripts: {
      uri: 'document.documentURI'
    }
  });

  t.deepEqual(
    result[0].browserScripts[0].scripts.uri,
    'http://127.0.0.1:3000/simple/'
  );
});


text:
<?php

namespace PSX\Api\Tests;

use Doctrine\Common\Annotations\SimpleAnnotationReader;
use PHPUnit\Framework\TestCase;
use PSX\Api\ApiManager;
use PSX\Schema\SchemaManager;

/**
 * ApiManagerTest
 *
 * @author  Christoph Kappestein <christoph.kappestein@gmail.com>
 * @license http://www.apache.org/licenses/LICENSE-2.0
 * @link    https://phpsx.org
 */
abstract class ApiManagerTestCase extends TestCase
{
    protected SchemaManager $schemaManager;
    protected ApiManager $apiManager;

    protected function setUp(): void
    {
        $this->schemaManager = new SchemaManager();
        $this->apiManager    = new ApiManager($this->schemaManager);
    }
}


text:
#include <DTK_ConfigDefs.hpp>
#include <DTK_Version.hpp>

#include <Teuchos_UnitTestHarness.hpp>

#include <iostream>
#include <sstream>

TEUCHOS_UNIT_TEST( DataTransferKitRuntimeAPI, return_version )
{
    auto const dtk_version = DataTransferKit::version();
    TEST_ASSERT( !dtk_version.empty() );
    std::cout << "DataTransferKit version " << dtk_version << std::endl;

    auto const dtk_commit_hash = DataTransferKit::gitCommitHash();
    TEST_ASSERT( !dtk_commit_hash.empty() );
    std::cout << "DataTransferKit commit hash " << dtk_commit_hash << std::endl;
}

namespace dummy
{
struct Foo
{
    Foo( std::ostream &os ) { os << DTK_MARK_REGION( "hello world" ); }
};
void bar( std::ostream &os ) { os << DTK_MARK_REGION( "it works" ); }
} // namespace dummy

TEUCHOS_UNIT_TEST( DataTransferKitMacros, mark_parallel_region )
{
    std::stringstream ss;
    dummy::Foo foo( ss );
    TEST_EQUALITY( ss.str(), "DTK_hello world" );

    ss.clear();
    ss.str( "" );
    dummy::bar( ss );
    TEST_EQUALITY( ss.str(), "DTK_it works" );
}


text:
import { combineReducers } from 'redux';

// bringing in the reducers
import appReducer from './app.reducer';
import userReducer from './user.reducer';
import postReducer from './post.reducer';

// combining the reducers
var reducers = combineReducers({
	appState: appReducer,
	userState: userReducer,
	postState: postReducer
});

export default reducers;


text:
CKEDITOR.plugins.setLang( 'sourcearea', 'no', {
	toolbar: 'Kilde'
} );


text:
package com.amplifino.obelix.timeseries;

import java.time.Instant;
import java.util.Comparator;
import java.util.Optional;
import java.util.stream.Stream;

import org.osgi.annotation.versioning.ProviderType;

import com.amplifino.obelix.pairs.OrderedPair;
import com.amplifino.obelix.sets.SortedInfiniteMap;

@ProviderType
public interface TimeSeries<V> extends SortedInfiniteMap<Instant, V> {

	@Override
	TimeSeries<V> put(Instant instant, V value);

	@Override
	Stream<? extends TimeSeriesElement<V>> graph();

	@Override
	Stream<? extends TimeSeriesElement<V>> graph(Optional<Instant> start, Optional<Instant>  end);

	@Override
	default Stream<? extends TimeSeriesElement<V>> graph(Stream<Instant> instants) {
		return instants.map(OrderedPair.graph(this::get))
			.filter(OrderedPair.filterValue(Optional::isPresent))
			.map(OrderedPair.mapPair((instant , optional) -> TimeSeriesElement.of(instant , optional.get())));
	}

	@Override
	default Stream<? extends TimeSeriesElement<V>> graph(Instant instant) {
		return this.get(instant)
			.map(value -> TimeSeriesElement.of(instant,value))
			.map(Stream::of)
			.orElse(Stream.empty());
	}

	@Override
	default Stream<? extends TimeSeriesElement<V>> graph(Instant lower, Instant upper) {
		return graph(Optional.of(lower), Optional.of(upper));
	}

	@Override
	default Stream<? extends TimeSeriesElement<V>> atLeast(Instant lower) {
		return graph(Optional.of(lower), Optional.empty());
	}

	@Override
	default Stream<? extends TimeSeriesElement<V>> lessThan(Instant upper) {
		return graph(Optional.empty(), Optional.of(upper));
	}

	@Override
	default Stream<? extends TimeSeriesElement<V>> sorted() {
		return graph(Optional.empty(), Optional.empty());
	}

	@Override
	default Comparator<Instant> comparator() {
		return Comparator.naturalOrder();
	}

}


text:
from __future__ import (print_function, division, absolute_import, unicode_literals)

from setuptools import find_packages, setup

execfile('tamia/version.py')
packages = [b'tamia'] + [b'tamia.{0}'.format(x) for x in find_packages(b'tamia',)]

setup(
    name='Tamia',
    version=__version__,
    description='A wrapper for pygit2',
    author='Olivier Meunier',
    author_email='olivier@neokraft.net',
    url='https://github.com/olivier-m/Tamia',
    license='MIT License',
    keywords='git vcs libgit2',
    install_requires=['pygit2==0.19.1'],
    packages=[b'tamia'],
    test_suite='test',
    classifiers=[
        'Development Status :: 4 - Beta',
        'Intended Audience :: Developers',
        'License :: OSI Approved :: MIT License',
        'Operating System :: OS Independent',
        'Programming Language :: Python :: 2.6',
        'Programming Language :: Python :: 2.7',
        'Topic :: Software Development :: Libraries',
        'Topic :: Utilities'
    ],
)


text:
using System;
using System.Collections.Generic;
using System.Text;
using Newtonsoft.Json;
using System.Runtime.Serialization;

namespace SuperMap.Connector.Utility
{
    /// <summary>
    /// 编辑结果类。
    /// <para>
    /// 编辑操作返回的结果对象,包含操作成功是否的标识,以及被编辑的地物 ID、地图受影响的范围和操作之后的地图描述。
    /// </para>
    /// </summary>
    [JsonObject(MemberSerialization.OptIn)]
#if WINDOWS_PHONE
    public sealed class EditResult
#else
    [Serializable]
    public sealed class EditResult : ISerializable
#endif
    {
        /// <summary>
        /// 默认的构造函数。
        /// </summary>
        public EditResult()
        { }

        ///// <summary>
        ///// 地图受影响的范围,即被编辑过的地图数据所对应的范围。
        ///// </summary>
        //[JsonProperty("bounds")]
        //public Rectangle2D Bounds
        //{
        //    get;
        //    set;
        //}

        /// <summary>
        /// 所有数据被更新的实体的 ID 数组。
        /// </summary>
        [JsonProperty("ids")]
        public int[] Ids { get; set; }

        /// <summary>
        /// 获取编辑过程中产生的相关信息。
        /// </summary>
        [JsonProperty("message")]
        public string Message { get; set; }

        /// <summary>
        /// 操作是否成功。
        /// </summary>
        [JsonProperty("succeed")]
        public bool Succeed { get; set; }

#if !WINDOWS_PHONE
        #region 序列化/反序列化
        private EditResult(SerializationInfo info, StreamingContext context)
        {
            //this.Bounds = (Rectangle2D)info.GetValue("Bounds", typeof(Rectangle2D));
            this.Ids = (int[])info.GetValue("Ids", typeof(int[]));
            this.Message = info.GetString("Message");
            this.Succeed = info.GetBoolean("Succeed");
        }

        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
        {
            //info.AddValue("Bounds",this.Bounds);
            info.AddValue("Ids",this.Ids);
            info.AddValue("Message",this.Message);
            info.AddValue("Succeed",this.Succeed);
        }
        #endregion
#endif
    }
}


text:
title: "License API"
linkTitle: "License API"
description: "The Sensu license API provides HTTP access to the active commercial license configuration. This reference includes examples for returning the active commercial license configuration and activating or updating a commercial license. Read on for the full reference."
api_title: "License API"
type: "api"
version: "6.2"
product: "Sensu Go"
menu:
  sensu-go-6.2:
    parent: api
---

{{% notice note %}}
**NOTE**: Requests to the license API require you to authenticate with a Sensu [API key](../#configure-an-environment-variable-for-api-key-authentication) or [access token](../#authenticate-with-the-authentication-api).
The code examples in this document use the [environment variable](../#configure-an-environment-variable-for-api-key-authentication) `$SENSU_API_KEY` to represent a valid API key in API requests.
{{% /notice %}}

For more information about commercial features designed for enterprises, read [Get started with commercial features][1].

## Get the active license configuration

The `/license` API endpoint provides HTTP GET access to the active license configuration.

### Example {#license-get-example}

The following example demonstrates a request to the `/license` API endpoint, resulting in a JSON array that contains the license definition.

{{}}
curl -X GET \
http://127.0.0.1:8080/api/enterprise/licensing/v2/license \
-H "Authorization: Key $SENSU_API_KEY" \
-H 'Content-Type: application/json'

HTTP/1.1 200 OK
{
  "type": "LicenseFile",
  "api_version": "licensing/v2",
  "metadata": {
    "labels": {
      "sensu.io/entity-count": "10",
      "sensu.io/entity-limit": "100"
    }
  },
  "spec": {
    "license": {
      "version": 1,
      "issuer": "Sensu, Inc.",
      "accountName": "my_account",
      "accountID": 1234567,
      "issued": "2019-01-01T13:40:25-08:00",
      "validUntil": "2020-01-01T13:40:25-08:00",
      "plan": "managed",
      "features": [
        "all"
      ],
      "signature": {
        "algorithm": "PSS",
        "hashAlgorithm": "SHA256",
        "saltLength": 20
      }
    },
    "signature": "XXXXXXXXXX",
    "metadata": {}
  }
}
{{}}

### API Specification {#license-get-specification}

/license (GET)  |
---------------|------
description    | Returns the active commercial license configuration. To download your license, [log in to your Sensu account][2] or [contact the Sensu sales team for a free trial][3].
example url    | http://hostname:8080/api/enterprise/licensing/v2/license
response type  | Map
response codes |

**Success**: 200 (OK)

**Error**: 500 (Internal Server Error)

output         | {{}}
{
  "type": "LicenseFile",
  "api_version": "licensing/v2",
  "metadata": {
    "labels": {
      "sensu.io/entity-count": "10",
      "sensu.io/entity-limit": "100"
    }
  },
  "spec": {
    "license": {
      "version": 1,
      "issuer": "Sensu, Inc.",
      "accountName": "my_account",
      "accountID": 1234567,
      "issued": "2019-01-01T13:40:25-08:00",
      "validUntil": "2020-01-01T13:40:25-08:00",
      "plan": "managed",
      "features": [
        "all"
      ],
      "signature": {
        "algorithm": "PSS",
        "hashAlgorithm": "SHA256",
        "saltLength": 20
      }
    },
    "signature": "XXXXXXXXXX",
    "metadata": {}
  }
}
{{}}

## Activate a commercial license

The `/license` API endpoint provides HTTP PUT access to activate a commercial license.

{{% notice note %}}
**NOTE**: For [clustered configurations](../../operations/deploy-sensu/cluster-sensu), you only need to activate your license for one of the backends within the cluster.
{{% /notice %}}

### Example {#license-put-example}

In the following example, an HTTP PUT request is submitted to the `/license` API endpoint to create the license definition.
The request returns a successful HTTP `201 Created` response.

{{}}
curl -X PUT \
-H "Authorization: Key $SENSU_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
  "type": "LicenseFile",
  "api_version": "licensing/v2",
  "metadata": {
    "labels": {
      "sensu.io/entity-count": "10",
      "sensu.io/entity-limit": "100"
    }
  },
  "spec": {
    "license": {
      "version": 1,
      "issuer": "Sensu, Inc.",
      "accountName": "my_account",
      "accountID": 1234567,
      "issued": "2019-01-01T13:40:25-08:00",
      "validUntil": "2020-01-01T13:40:25-08:00",
      "plan": "managed",
      "features": [
        "all"
      ],
      "signature": {
        "algorithm": "PSS",
        "hashAlgorithm": "SHA256",
        "saltLength": 20
      }
    },
    "signature": "XXXXXXXXXX",
    "metadata": {}
  }
}' \
http://127.0.0.1:8080/api/enterprise/licensing/v2/license

HTTP/1.1 201 Created
{{}}

### API Specification {#license-put-specification}

/license (PUT)  |
---------------|------
description    | Activates a commercial license or updates an existing license configuration. To download your license, [log in to your Sensu account][2] or [contact the Sensu sales team for a free trial][3].
example url    | http://hostname:8080/api/enterprise/licensing/v2/license
payload        | {{}}
{
  "type": "LicenseFile",
  "api_version": "licensing/v2",
  "metadata": {
    "labels": {
      "sensu.io/entity-count": "10",
      "sensu.io/entity-limit": "100"
    }
  },
  "spec": {
    "license": {
      "version": 1,
      "issuer": "Sensu, Inc.",
      "accountName": "my_account",
      "accountID": 1234567,
      "issued": "2019-01-01T13:40:25-08:00",
      "validUntil": "2020-01-01T13:40:25-08:00",
      "plan": "managed",
      "features": [
        "all"
      ],
      "signature": {
        "algorithm": "PSS",
        "hashAlgorithm": "SHA256",
        "saltLength": 20
      }
    },
    "signature": "XXXXXXXXXX",
    "metadata": {}
  }
}
{{}}
response codes |

**Success**: 201 (Created)

**Malformed**: 400 (Bad Request)

**Error**: 500 (Internal Server Error)

## Delete a commercial license

The `/license` API endpoint provides HTTP DELETE access to remove a commercial license.

### Example {#license-delete-example}

The following example shows a request to the `/license` API endpoint to delete the commercial license, resulting in a successful HTTP `204 No Content` response.

{{}}
curl -X DELETE \
http://127.0.0.1:8080/api/enterprise/licensing/v2/license \
-H "Authorization: Key $SENSU_API_KEY"

HTTP/1.1 204 No Content
{{}}

### API Specification {#license-delete-specification}

/license (DELETE)  |
-------------------|------
description    | Removes the commercial license.
example url    | http://hostname:8080/api/enterprise/licensing/v2/license
response codes |

**Success**: 204 (No Content)

**Missing**: 404 (Not Found)

**Error**: 500 (Internal Server Error)

[1]: ../../commercial/
[2]: https://account.sensu.io/
[3]: https://sensu.io/contact?subject=contact-sales


text:
package net.krinsoft.irc;

import net.krinsoft.chat.ChatCore;
import net.krinsoft.chat.api.Manager;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * @author krinsdeath
 */
public class IRCBot implements Manager {
    private final static Pattern    NICK                    = Pattern.compile("\\[nick\\]");

    private ChatCore                plugin;
    private FileConfiguration       configuration;
    private File                    config;

    public final String             NICKNAME;
    public final String             IDENTITY;
    public final String             REALNAME;
    public final String             DEFAULT_NETWORK;

    // messages
    public final String             STARTUP;
    public final String             IRC_TAG;
    public final String             PLAYER_JOIN_IRC;
    public final String             PLAYER_JOIN_MINECRAFT;
    public final String             PLAYER_QUIT_IRC;
    public final String             PLAYER_QUIT_MINECRAFT;

    private Map<String, Connection> connections             = new HashMap<String, Connection>();

    private List<String>            online                  = new ArrayList<String>();

    public IRCBot(ChatCore instance) throws IOException {
        plugin = instance;

        registerConfiguration();

        // bot information
        NICKNAME                = getConfig().getString("nickname");
        IDENTITY                = getConfig().getString("ident");
        REALNAME                = getConfig().getString("realname");
        boolean DEV             = getConfig().getBoolean("developer.run");
        if ((NICKNAME.equals("ChatSuite") || IDENTITY.equals("ChatSuite") || (REALNAME.equals("ChatSuite"))) && !DEV) {
            throw new InvalidIRCBotException("Please customize your IRC settings in 'irc.yml'.");
        }

        DEFAULT_NETWORK         = getConfig().getString("default");

        // messages
        STARTUP                 = getConfig().getString("messages.startup", "ChatSuite IRC Bot Initialized.");
        IRC_TAG                 = getConfig().getString("messages.tag", "[IRC]");
        PLAYER_JOIN_IRC         = getConfig().getString("messages.irc.join", "[nick] is now on IRC.");
        PLAYER_QUIT_IRC         = getConfig().getString("messages.irc.quit", "[nick] has quit IRC.");
        PLAYER_JOIN_MINECRAFT   = getConfig().getString("messages.mc.join", "[nick] has logged in.");
        PLAYER_QUIT_MINECRAFT   = getConfig().getString("messages.mc.quit", "[nick] has logged out.");

        initializeConnections();
    }

    public void clean() {
        for (Connection conn : connections.values()) {
            conn.stop();
        }
        connections.clear();
    }

    public FileConfiguration getConfig() {
        if (configuration == null) {
            configuration = YamlConfiguration.loadConfiguration(config);
            configuration.setDefaults(YamlConfiguration.loadConfiguration(config));
        }
        return configuration;
    }

    public void saveConfig() {
        try {
            getConfig().save(config);
        } catch (Exception e) {
            plugin.warn("An error occurred while saving 'irc.yml'");
        }
    }

    public ChatCore getPlugin() {
        return plugin;
    }

    public void registerConfiguration() {
        config = new File(plugin.getDataFolder(), "irc.yml");
        if (!config.exists() || getConfig().getConfigurationSection("networks") == null) {
            getConfig().setDefaults(YamlConfiguration.loadConfiguration(plugin.getClass().getResourceAsStream("/defaults/irc.yml")));
            getConfig().options().copyDefaults(true);
            saveConfig();
        }
    }

    public void initializeConnections() throws IOException {
        ConfigurationSection networks = getConfig().getConfigurationSection("networks");
        for (String network : networks.getKeys(false)) {
            String host     = networks.getString(   network + ".host");
            int port        = networks.getInt(      network + ".port");
            String channel  = networks.getString(   network + ".channel");
            String key      = networks.getString(   network + ".key");
            Connection conn = new Connection(this, network, host, port, channel, key);
            connections.put(network, conn);
        }
    }

    public void msg(String network, String chan, String message) {
        if (network == null) {
            network = DEFAULT_NETWORK;
        }
        if (chan == null) {
            chan = getConfig().getString("networks." + network + ".channel");
            if (chan == null) {
                return;
            }
        }
        Connection conn = connections.get(network);
        conn.chanMsg(chan, message);
    }

    public void initialize(String net) throws IOException {
        ConfigurationSection network = getConfig().getConfigurationSection("networks." + net);
        if (network == null) {
            throw new InvalidNetworkException("Unknown network.");
        }
        if (connections.get(net) != null) {
            throw new InvalidNetworkException("Network already initialized.");
        }
        String host     = network.getString("host");
        int port        = network.getInt("port");
        String channel  = network.getString("channel");
        String key      = network.getString("key");
        try {
            Connection conn = new Connection(this, net, host, port, channel, key);
            connections.put(net, conn);
        } catch (IOException e) {
            plugin.warn("An exception occurred while initializing the network '" + net + "': " + e.getLocalizedMessage());
        } catch (InvalidNetworkException e) {
            plugin.warn("InvalidNetworkException: " + e.getLocalizedMessage());
        }
    }

    /**
     * Creates a connection to the specified IRC network, and joins the given channel
     * @param network The network connection to connect to
     * @param c The channel to connect to
     * @param k A channel key, if applicable (for private IRC channels)
     * @return true if the command succeeds, false otherwise
     */
    public boolean connect(String network, String c, String k) {
        String channel = (c != null ? c : getConfig().getString("networks." + network + ".channel"));
        String key = (k != null ? k : getConfig().getString("networks." + network + ".key", ""));
        if (connections.get(network) != null && channel != null) {
            Connection conn = connections.get(network);
            conn.writeLine("JOIN " + channel + " " + key);
            return true;
        } else {
        }
        return false;
    }

    /**
     * Kills the specified network connection
     * @param network The network we're attempting to disconnect
     * @return true if the disconnection is successful, otherwise false
     */
    public void disconnect(String network) {
        if (network == null) {
            throw new InvalidNetworkException("Invalid network.");
        }
        if (connections.get(network) == null) {
            throw new InvalidNetworkException("Invalid network.");
        }
        connections.get(network).stop();
        connections.remove(network);
    }

    /**
     * Announces that a player has joined the minecraft server
     * @param network The IRC Network to send the message to
     * @param channel The IRC Channel to send the message to
     * @param nickname The nickname of the player joining the minecraft server
     */
    public void join(String network, String channel, String nickname) {
        msg(network, channel, NICK.matcher(PLAYER_JOIN_MINECRAFT).replaceAll(nickname));
    }

    /**
     * Announces that a player has quit minecraft
     * @param network The IRC Network to send the message to
     * @param channel The IRC Channel to send the message to
     * @param nickname The nickname of the quitting player
     */
    public void quit(String network, String channel, String nickname) {
        msg(network, channel, NICK.matcher(PLAYER_QUIT_MINECRAFT).replaceAll(nickname));
    }

    public boolean isOnline(String nickname) {
        return online.contains(nickname);
    }

    public void setOnline(String nickname, boolean val) {
        if (val) {
            online.add(nickname);
        } else {
            online.remove(nickname);
        }
    }

    public void create(String network, String host, String p, String channel, String key) {
        if (connections.get(network) != null) {
            throw new InvalidNetworkException("Network already exists.");
        }
        int port;
        try {
            port = Integer.parseInt(p);
        } catch (NumberFormatException e) {
            throw new InvalidNetworkException("Invalid port (try 6667).");
        }
        if (!channel.startsWith("#")) {
            throw new InvalidNetworkException("Channels must be prefixed with '#'!");
        }
        if (key == null) {
            key = "";
        }
        getConfig().set("networks." + network + ".host", host);
        getConfig().set("networks." + network + ".port", port);
        getConfig().set("networks." + network + ".channel", channel);
        getConfig().set("networks." + network + ".key", key);
        getConfig().set("networks." + network + ".auth", "");
        saveConfig();
    }

    /**
     * Returns a list of active connections
     * @return The connections active on this bot
     */
    public List<Connection> getConnections() {
        List<Connection> list = new ArrayList<Connection>();
        for (Connection conn : connections.values()) {
            list.add(conn);
        }
        return list;
    }

}