text:
package org.hisp.dhis.chart.impl;

import org.apache.commons.math3.analysis.UnivariateFunction;
import org.apache.commons.math3.analysis.interpolation.SplineInterpolator;
import org.apache.commons.math3.analysis.interpolation.UnivariateInterpolator;
import org.apache.commons.math3.exception.MathRuntimeException;
import org.apache.commons.math3.stat.regression.SimpleRegression;
import org.hisp.dhis.analytics.AnalyticsService;
import org.hisp.dhis.analytics.event.EventAnalyticsService;
import org.hisp.dhis.chart.BaseChart;
import org.hisp.dhis.chart.Chart;
import org.hisp.dhis.chart.ChartService;
import org.hisp.dhis.chart.ChartType;
import org.hisp.dhis.common.*;
import org.hisp.dhis.dataelement.DataElement;
import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
import org.hisp.dhis.dataelement.DataElementOperand;
import org.hisp.dhis.datavalue.DataValue;
import org.hisp.dhis.datavalue.DataValueService;
import org.hisp.dhis.i18n.I18nFormat;
import org.hisp.dhis.indicator.Indicator;
import org.hisp.dhis.minmax.MinMaxDataElement;
import org.hisp.dhis.minmax.MinMaxDataElementService;
import org.hisp.dhis.organisationunit.OrganisationUnit;
import org.hisp.dhis.organisationunit.OrganisationUnitService;
import org.hisp.dhis.period.Period;
import org.hisp.dhis.period.PeriodService;
import org.hisp.dhis.period.RelativePeriods;
import org.hisp.dhis.system.grid.GridUtils;
import org.hisp.dhis.system.util.MathUtils;
import org.hisp.dhis.user.CurrentUserService;
import org.hisp.dhis.user.User;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
import org.jfree.chart.plot.*;
import org.jfree.chart.renderer.category.*;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.Range;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DefaultValueDataset;
import org.jfree.data.general.ValueDataset;
import org.jfree.ui.RectangleInsets;
import org.jfree.util.TableOrder;
import org.springframework.transaction.annotation.Transactional;

import java.awt.*;
import java.util.*;
import java.util.List;
import java.util.Map.Entry;

import static org.hisp.dhis.common.DimensionalObject.DIMENSION_SEP;
import static org.hisp.dhis.commons.collection.ListUtils.getArray;

/**
 * @author Lars Helge Overland
 */
@Transactional
public class DefaultChartService
    extends GenericAnalyticalObjectService<Chart>
    implements ChartService
{
    private static final Font TITLE_FONT = new Font( Font.SANS_SERIF, Font.BOLD, 12 );
    private static final Font SUB_TITLE_FONT = new Font( Font.SANS_SERIF, Font.PLAIN, 11 );
    private static final Font LABEL_FONT = new Font( Font.SANS_SERIF, Font.PLAIN, 10 );

    private static final String TREND_PREFIX = "Trend - ";

    private static final Color[] COLORS = {
    	Color.decode( "#ffd700" ), Color.decode( "#ff8c00" ), Color.decode( "#8b2500" ), Color.decode( "#cdcd00" ),
    	Color.decode( "#551a8b" ), Color.decode( "#458b00" ), Color.decode( "#00b2ee" ), Color.decode( "#104e8b" ),
    	Color.decode( "#191970" ), Color.decode( "#ee3b3b" ), Color.decode( "#458b74" ), Color.decode( "#838b8b" ),
    	Color.decode( "#8a2be2" ), Color.decode( "#cd5b45" ), Color.decode( "#6495ed" ), Color.decode( "#8b4500" ),
    	Color.decode( "#8b3a62" ), Color.decode( "#607b8b" ), Color.decode( "#00868b" ), Color.decode( "#8b1a1a" ) };

    private static final Color COLOR_TRANSPARENT = new Color( 255, 255, 255, 0 );
    private static final Color COLOR_LIGHT_GRAY = Color.decode( "#dddddd" );
    private static final Color COLOR_LIGHTER_GRAY = Color.decode( "#eeeeee" );

    // -------------------------------------------------------------------------
    // Dependencies
    // -------------------------------------------------------------------------

    private AnalyticalObjectStore<Chart> chartStore;

    public void setChartStore( AnalyticalObjectStore<Chart> chartStore )
    {
        this.chartStore = chartStore;
    }

    private PeriodService periodService;

    public void setPeriodService( PeriodService periodService )
    {
        this.periodService = periodService;
    }

    private DataValueService dataValueService;

    public void setDataValueService( DataValueService dataValueService )
    {
        this.dataValueService = dataValueService;
    }

    private MinMaxDataElementService minMaxDataElementService;

    public void setMinMaxDataElementService( MinMaxDataElementService minMaxDataElementService )
    {
        this.minMaxDataElementService = minMaxDataElementService;
    }

    private CurrentUserService currentUserService;

    public void setCurrentUserService( CurrentUserService currentUserService )
    {
        this.currentUserService = currentUserService;
    }

    private OrganisationUnitService organisationUnitService;

    public void setOrganisationUnitService( OrganisationUnitService organisationUnitService )
    {
        this.organisationUnitService = organisationUnitService;
    }

    private AnalyticsService analyticsService;

    public void setAnalyticsService( AnalyticsService analyticsService )
    {
        this.analyticsService = analyticsService;
    }

    private EventAnalyticsService eventAnalyticsService;

    public void setEventAnalyticsService( EventAnalyticsService eventAnalyticsService )
    {
        this.eventAnalyticsService = eventAnalyticsService;
    }

    // -------------------------------------------------------------------------
    // ChartService implementation
    // -------------------------------------------------------------------------

    @Override
    protected AnalyticalObjectStore<Chart> getAnalyticalObjectStore()
    {
        return chartStore;
    }

    @Override
    public JFreeChart getJFreeChart( int id, I18nFormat format )
    {
        Chart chart = getChart( id );

        return chart != null ? getJFreeChart( chart, format ) : null;
    }

    @Override
    public JFreeChart getJFreeChart( BaseChart chart, I18nFormat format )
    {
        return getJFreeChart( chart, null, null, format );
    }

    @Override
    public JFreeChart getJFreeChart( BaseChart chart, Date date, OrganisationUnit organisationUnit, I18nFormat format )
    {
        return getJFreeChart( chart, date, organisationUnit, format, currentUserService.getCurrentUser() );
    }

    @Override
    public JFreeChart getJFreeChart( BaseChart chart, Date date, OrganisationUnit organisationUnit, I18nFormat format, User currentUser )
    {
        User user = (currentUser != null ? currentUser : currentUserService.getCurrentUser());

        if ( organisationUnit == null && user != null )
        {
            organisationUnit = user.getOrganisationUnit();
        }

        List<OrganisationUnit> atLevels = new ArrayList<>();
        List<OrganisationUnit> inGroups = new ArrayList<>();

        if ( chart.hasOrganisationUnitLevels() )
        {
            atLevels.addAll( organisationUnitService.getOrganisationUnitsAtLevels( chart.getOrganisationUnitLevels(), chart.getOrganisationUnits() ) );
        }

        if ( chart.hasItemOrganisationUnitGroups() )
        {
            inGroups.addAll( organisationUnitService.getOrganisationUnits( chart.getItemOrganisationUnitGroups(), chart.getOrganisationUnits() ) );
        }

        chart.init( user, date, organisationUnit, atLevels, inGroups, format );

        JFreeChart resultChart = getJFreeChart( chart );

        chart.clearTransientState();

        return resultChart;
    }

    // -------------------------------------------------------------------------
    // Specific chart methods
    // -------------------------------------------------------------------------

    @Override
    public JFreeChart getJFreePeriodChart( Indicator indicator, OrganisationUnit unit, boolean title, I18nFormat format )
    {
        List<Period> periods = periodService.reloadPeriods(
            new RelativePeriods().setLast12Months( true ).getRelativePeriods( format, true ) );

        Chart chart = new Chart();

        if ( title )
        {
            chart.setName( indicator.getName() );
        }

        chart.setType( ChartType.LINE );
        chart.setDimensions( DimensionalObject.DATA_X_DIM_ID, DimensionalObject.PERIOD_DIM_ID, DimensionalObject.ORGUNIT_DIM_ID );
        chart.setHideLegend( true );
        chart.addDataDimensionItem( indicator );
        chart.setPeriods( periods );
        chart.getOrganisationUnits().add( unit );
        chart.setHideSubtitle( title );
        chart.setFormat( format );

        return getJFreeChart( chart );
    }

    @Override
    public JFreeChart getJFreeOrganisationUnitChart( Indicator indicator, OrganisationUnit parent, boolean title,
        I18nFormat format )
    {
        List<Period> periods = periodService.reloadPeriods(
            new RelativePeriods().setThisYear( true ).getRelativePeriods( format, true ) );

        Chart chart = new Chart();

        if ( title )
        {
            chart.setName( indicator.getName() );
        }

        chart.setType( ChartType.COLUMN );
        chart.setDimensions( DimensionalObject.DATA_X_DIM_ID, DimensionalObject.ORGUNIT_DIM_ID, DimensionalObject.PERIOD_DIM_ID );
        chart.setHideLegend( true );
        chart.addDataDimensionItem( indicator );
        chart.setPeriods( periods );
        chart.setOrganisationUnits( parent.getSortedChildren() );
        chart.setHideSubtitle( title );
        chart.setFormat( format );

        return getJFreeChart( chart );
    }

    @Override
    public JFreeChart getJFreeChart( String name, PlotOrientation orientation, CategoryLabelPositions labelPositions,
        Map<String, Double> categoryValues )
    {
        DefaultCategoryDataset dataSet = new DefaultCategoryDataset();

        for ( Entry<String, Double> entry : categoryValues.entrySet() )
        {
            dataSet.addValue( entry.getValue(), name, entry.getKey() );
        }

        CategoryPlot plot = getCategoryPlot( dataSet, getBarRenderer(), orientation, labelPositions );

        JFreeChart jFreeChart = getBasicJFreeChart( plot );
        jFreeChart.setTitle( name );

        return jFreeChart;
    }

    @Override
    public JFreeChart getJFreeChartHistory( DataElement dataElement, DataElementCategoryOptionCombo categoryOptionCombo,
        DataElementCategoryOptionCombo attributeOptionCombo, Period lastPeriod, OrganisationUnit organisationUnit,
        int historyLength, I18nFormat format )
    {
        lastPeriod = periodService.reloadPeriod( lastPeriod );

        List<Period> periods = periodService.getPeriods( lastPeriod, historyLength );

        MinMaxDataElement minMax = minMaxDataElementService.getMinMaxDataElement( organisationUnit, dataElement,
            categoryOptionCombo );

        UnivariateInterpolator interpolator = new SplineInterpolator();

        Integer periodCount = 0;
        List<Double> x = new ArrayList<>();
        List<Double> y = new ArrayList<>();

        // ---------------------------------------------------------------------
        // DataValue, MinValue and MaxValue DataSets
        // ---------------------------------------------------------------------

        DefaultCategoryDataset dataValueDataSet = new DefaultCategoryDataset();
        DefaultCategoryDataset metaDataSet = new DefaultCategoryDataset();

        for ( Period period : periods )
        {
            ++periodCount;

            period.setName( format.formatPeriod( period ) );

            DataValue dataValue = dataValueService.getDataValue( dataElement, period, organisationUnit,
                categoryOptionCombo, attributeOptionCombo );

            double value = 0;

            if ( dataValue != null && dataValue.getValue() != null && MathUtils.isNumeric( dataValue.getValue() ) )
            {
                value = Double.parseDouble( dataValue.getValue() );

                x.add( periodCount.doubleValue() );
                y.add( value );
            }

            dataValueDataSet.addValue( value, dataElement.getShortName(), period.getName() );

            if ( minMax != null )
            {
                metaDataSet.addValue( minMax.getMin(), "Min value", period.getName() );
                metaDataSet.addValue( minMax.getMax(), "Max value", period.getName() );
            }
        }

        // ---------------------------------------------------------------------
        // Interpolation DataSet
        // ---------------------------------------------------------------------

        if ( x.size() >= 3 ) // minimum 3 points required for interpolation
        {
            periodCount = 0;

            double[] xa = getArray( x );

            int min = MathUtils.getMin( xa ).intValue();
            int max = MathUtils.getMax( xa ).intValue();

            try
            {
                UnivariateFunction function = interpolator.interpolate( xa, getArray( y ) );

                for ( Period period : periods )
                {
                    if ( ++periodCount >= min && periodCount <= max )
                    {
                        metaDataSet.addValue( function.value( periodCount ), "Regression value", period.getName() );
                    }
                }
            }
            catch ( MathRuntimeException ex )
            {
                throw new RuntimeException( "Failed to interpolate", ex );
            }
        }

        // ---------------------------------------------------------------------
        // Plots
        // ---------------------------------------------------------------------

        CategoryPlot plot = getCategoryPlot( dataValueDataSet, getBarRenderer(), PlotOrientation.VERTICAL,
            CategoryLabelPositions.UP_45 );

        plot.setDataset( 1, metaDataSet );
        plot.setRenderer( 1, getLineRenderer() );

        JFreeChart jFreeChart = getBasicJFreeChart( plot );

        return jFreeChart;
    }

    // -------------------------------------------------------------------------
    // Supportive methods
    // -------------------------------------------------------------------------

    /**
     * Returns a basic JFreeChart.
     */
    private JFreeChart getBasicJFreeChart( CategoryPlot plot )
    {
        JFreeChart jFreeChart = new JFreeChart( null, TITLE_FONT, plot, false );

        jFreeChart.setBackgroundPaint( Color.WHITE );
        jFreeChart.setAntiAlias( true );

        return jFreeChart;
    }

    /**
     * Returns a CategoryPlot.
     */
    private CategoryPlot getCategoryPlot( CategoryDataset dataSet, CategoryItemRenderer renderer,
        PlotOrientation orientation, CategoryLabelPositions labelPositions )
    {
        CategoryPlot plot = new CategoryPlot( dataSet, new CategoryAxis(), new NumberAxis(), renderer );

        plot.setDatasetRenderingOrder( DatasetRenderingOrder.FORWARD );
        plot.setOrientation( orientation );

        CategoryAxis xAxis = plot.getDomainAxis();
        xAxis.setCategoryLabelPositions( labelPositions );

        return plot;
    }

    /**
     * Returns a bar renderer.
     */
    private BarRenderer getBarRenderer()
    {
        BarRenderer renderer = new BarRenderer();

        renderer.setMaximumBarWidth( 0.07 );

        for ( int i = 0; i < COLORS.length; i++ )
        {
            renderer.setSeriesPaint( i, COLORS[i] );
            renderer.setShadowVisible( false );
        }

        return renderer;
    }

    /**
     * Returns a line and shape renderer.
     */
    private LineAndShapeRenderer getLineRenderer()
    {
        LineAndShapeRenderer renderer = new LineAndShapeRenderer();

        for ( int i = 0; i < COLORS.length; i++ )
        {
            renderer.setSeriesPaint( i, COLORS[i] );
        }

        return renderer;
    }

    /**
     * Returns a stacked bar renderer.
     */
    private StackedBarRenderer getStackedBarRenderer()
    {
        StackedBarRenderer renderer = new StackedBarRenderer();

        for ( int i = 0; i < COLORS.length; i++ )
        {
            renderer.setSeriesPaint( i, COLORS[i] );
            renderer.setShadowVisible( false );
        }

        return renderer;
    }

    /**
     * Returns a stacked area renderer.
     */
    private AreaRenderer getStackedAreaRenderer()
    {
        StackedAreaRenderer renderer = new StackedAreaRenderer();

        for ( int i = 0; i < COLORS.length; i++ )
        {
            renderer.setSeriesPaint( i, COLORS[i] );
        }

        return renderer;
    }

    /**
     * Returns a horizontal line marker for the given x value and label.
     */
    private Marker getMarker( Double value, String label )
    {
        Marker marker = new ValueMarker( value );
        marker.setPaint( Color.BLACK );
        marker.setStroke( new BasicStroke( 1.1f ) );
        marker.setLabel( label );
        marker.setLabelOffset( new RectangleInsets( -10, 50, 0, 0 ) );
        marker.setLabelFont( SUB_TITLE_FONT );

        return marker;
    }

    /**
     * Returns a JFreeChart of type defined in the chart argument.
     */
    private JFreeChart getJFreeChart( BaseChart chart )
    {
        final CategoryDataset[] dataSets = getCategoryDataSet( chart );
        final CategoryDataset dataSet = dataSets[0];

        final BarRenderer barRenderer = getBarRenderer();
        final LineAndShapeRenderer lineRenderer = getLineRenderer();

        // ---------------------------------------------------------------------
        // Plot
        // ---------------------------------------------------------------------

        CategoryPlot plot = null;

        if ( chart.isType( ChartType.LINE ) )
        {
            plot = new CategoryPlot( dataSet, new CategoryAxis(), new NumberAxis(), lineRenderer );
            plot.setOrientation( PlotOrientation.VERTICAL );
        }
        else if ( chart.isType( ChartType.COLUMN ) )
        {
            plot = new CategoryPlot( dataSet, new CategoryAxis(), new NumberAxis(), barRenderer );
            plot.setOrientation( PlotOrientation.VERTICAL );
        }
        else if ( chart.isType( ChartType.BAR ) )
        {
            plot = new CategoryPlot( dataSet, new CategoryAxis(), new NumberAxis(), barRenderer );
            plot.setOrientation( PlotOrientation.HORIZONTAL );
        }
        else if ( chart.isType( ChartType.AREA ) )
        {
            return getStackedAreaChart( chart, dataSet );
        }
        else if ( chart.isType( ChartType.PIE ) )
        {
            return getMultiplePieChart( chart, dataSets );
        }
        else if ( chart.isType( ChartType.STACKED_COLUMN ) )
        {
            return getStackedBarChart( chart, dataSet, false );
        }
        else if ( chart.isType( ChartType.STACKED_BAR ) )
        {
            return getStackedBarChart( chart, dataSet, true );
        }
        else if ( chart.isType( ChartType.RADAR ) )
        {
            return getRadarChart( chart, dataSet );
        }
        else if ( chart.isType( ChartType.GAUGE ) )
        {
            Number number = dataSet.getValue( 0, 0 );
            ValueDataset valueDataSet = new DefaultValueDataset( number );

            return getGaugeChart( chart, valueDataSet );
        }
        else
        {
            throw new IllegalArgumentException( "Illegal or no chart type: " + chart.getType() );
        }

        if ( chart.isRegression() )
        {
            plot.setDataset( 1, dataSets[1] );
            plot.setRenderer( 1, lineRenderer );
        }

        JFreeChart jFreeChart = new JFreeChart( chart.getName(), TITLE_FONT, plot, !chart.isHideLegend() );

        setBasicConfig( jFreeChart, chart );

        if ( chart.isTargetLine() )
        {
            plot.addRangeMarker( getMarker( chart.getTargetLineValue(), chart.getTargetLineLabel() ) );
        }

        if ( chart.isBaseLine() )
        {
            plot.addRangeMarker( getMarker( chart.getBaseLineValue(), chart.getBaseLineLabel() ) );
        }

        if ( chart.isHideSubtitle() )
        {
            jFreeChart.addSubtitle( getSubTitle( chart ) );
        }

        plot.setDatasetRenderingOrder( DatasetRenderingOrder.FORWARD );

        // ---------------------------------------------------------------------
        // Category label positions
        // ---------------------------------------------------------------------

        CategoryAxis domainAxis = plot.getDomainAxis();
        domainAxis.setCategoryLabelPositions( CategoryLabelPositions.UP_45 );
        domainAxis.setLabel( chart.getDomainAxisLabel() );

        ValueAxis rangeAxis = plot.getRangeAxis();
        rangeAxis.setLabel( chart.getRangeAxisLabel() );

        return jFreeChart;
    }

    private JFreeChart getStackedAreaChart( BaseChart chart, CategoryDataset dataSet )
    {
        JFreeChart stackedAreaChart = ChartFactory.createStackedAreaChart( chart.getName(), chart.getDomainAxisLabel(),
            chart.getRangeAxisLabel(), dataSet, PlotOrientation.VERTICAL, !chart.isHideLegend(), false, false );

        setBasicConfig( stackedAreaChart, chart );

        CategoryPlot plot = (CategoryPlot) stackedAreaChart.getPlot();
        plot.setOrientation( PlotOrientation.VERTICAL );
        plot.setRenderer( getStackedAreaRenderer() );

        CategoryAxis xAxis = plot.getDomainAxis();
        xAxis.setCategoryLabelPositions( CategoryLabelPositions.UP_45 );
        xAxis.setLabelFont( LABEL_FONT );

        return stackedAreaChart;
    }

    private JFreeChart getRadarChart( BaseChart chart, CategoryDataset dataSet )
    {
        SpiderWebPlot plot = new SpiderWebPlot( dataSet, TableOrder.BY_ROW );
        plot.setLabelFont( LABEL_FONT );

        JFreeChart radarChart = new JFreeChart( chart.getName(), TITLE_FONT, plot, !chart.isHideLegend() );

        setBasicConfig( radarChart, chart );

        return radarChart;
    }

    private JFreeChart getStackedBarChart( BaseChart chart, CategoryDataset dataSet, boolean horizontal )
    {
        JFreeChart stackedBarChart = ChartFactory.createStackedBarChart( chart.getName(), chart.getDomainAxisLabel(),
            chart.getRangeAxisLabel(), dataSet, PlotOrientation.VERTICAL, !chart.isHideLegend(), false, false );

        setBasicConfig( stackedBarChart, chart );

        CategoryPlot plot = (CategoryPlot) stackedBarChart.getPlot();
        plot.setOrientation( horizontal ? PlotOrientation.HORIZONTAL : PlotOrientation.VERTICAL );
        plot.setRenderer( getStackedBarRenderer() );

        CategoryAxis xAxis = plot.getDomainAxis();
        xAxis.setCategoryLabelPositions( CategoryLabelPositions.UP_45 );

        return stackedBarChart;
    }

    private JFreeChart getMultiplePieChart( BaseChart chart, CategoryDataset[] dataSets )
    {
        JFreeChart multiplePieChart = ChartFactory.createMultiplePieChart( chart.getName(), dataSets[0], TableOrder.BY_ROW,
            !chart.isHideLegend(), false, false );

        setBasicConfig( multiplePieChart, chart );

        if ( multiplePieChart.getLegend() != null )
        {
            multiplePieChart.getLegend().setItemFont( SUB_TITLE_FONT );
        }

        MultiplePiePlot multiplePiePlot = (MultiplePiePlot) multiplePieChart.getPlot();
        JFreeChart pieChart = multiplePiePlot.getPieChart();
        pieChart.setBackgroundPaint( COLOR_TRANSPARENT );
        pieChart.getTitle().setFont( SUB_TITLE_FONT );

        PiePlot piePlot = (PiePlot) pieChart.getPlot();
        piePlot.setBackgroundPaint( COLOR_TRANSPARENT );
        piePlot.setOutlinePaint( COLOR_TRANSPARENT );
        piePlot.setLabelFont( LABEL_FONT );
        piePlot.setLabelGenerator( new StandardPieSectionLabelGenerator( "{2}" ) );
        piePlot.setSimpleLabels( true );
        piePlot.setIgnoreZeroValues( true );
        piePlot.setIgnoreNullValues( true );
        piePlot.setShadowXOffset( 0d );
        piePlot.setShadowYOffset( 0d );

        for ( int i = 0; i < dataSets[0].getColumnCount(); i++ )
        {
            piePlot.setSectionPaint( dataSets[0].getColumnKey( i ), COLORS[(i % COLORS.length)] );
        }

        return multiplePieChart;
    }

    private JFreeChart getGaugeChart( BaseChart chart, ValueDataset dataSet )
    {
        MeterPlot meterPlot = new MeterPlot( dataSet );

        meterPlot.setUnits( "" );
        meterPlot.setRange( new Range( 0.0d, 100d ) );

        for ( int i = 0; i < 10; i++ )
        {
            double start = i * 10;
            double end = start + 10;
            String label = String.valueOf( start );

            meterPlot.addInterval( new MeterInterval( label, new Range( start, end ), COLOR_LIGHT_GRAY, null, COLOR_LIGHT_GRAY ) );
        }

        meterPlot.setMeterAngle(180);
        meterPlot.setDialBackgroundPaint( COLOR_LIGHT_GRAY );
        meterPlot.setDialShape( DialShape.CHORD );
        meterPlot.setNeedlePaint( COLORS[0] );
        meterPlot.setTickLabelsVisible( true );
        meterPlot.setTickLabelFont( LABEL_FONT );
        meterPlot.setTickLabelPaint( Color.BLACK );
        meterPlot.setTickPaint( COLOR_LIGHTER_GRAY );
        meterPlot.setValueFont( TITLE_FONT );
        meterPlot.setValuePaint( Color.BLACK );

        JFreeChart meterChart = new JFreeChart( chart.getName(), meterPlot );
        setBasicConfig( meterChart, chart );
        meterChart.removeLegend();

        return meterChart;
    }

    /**
     * Sets basic configuration including title font, subtitle, background paint and
     * anti-alias on the given JFreeChart.
     */
    private void setBasicConfig( JFreeChart jFreeChart, BaseChart chart)
    {
        jFreeChart.getTitle().setFont( TITLE_FONT );

        jFreeChart.setBackgroundPaint( COLOR_TRANSPARENT );
        jFreeChart.setAntiAlias( true );

        if ( !chart.isHideTitle() )
        {
            jFreeChart.addSubtitle( getSubTitle( chart ) );
        }

        Plot plot = jFreeChart.getPlot();
        plot.setBackgroundPaint( COLOR_TRANSPARENT );
        plot.setOutlinePaint( COLOR_TRANSPARENT );
    }

    private TextTitle getSubTitle( BaseChart chart )
    {
        TextTitle textTitle = new TextTitle();

        String title = chart.hasTitle() ? chart.getTitle() : chart.generateTitle();

        textTitle.setFont( SUB_TITLE_FONT );
        textTitle.setText( title );

        return textTitle;
    }

    private CategoryDataset[] getCategoryDataSet( BaseChart chart )
    {
        Map<String, Object> valueMap = new HashMap<>();

        if ( chart.isAnalyticsType( AnalyticsType.AGGREGATE ) )
        {
            valueMap = analyticsService.getAggregatedDataValueMapping( chart );
        }
        else if ( chart.isAnalyticsType( AnalyticsType.EVENT ) )
        {
            Grid grid = eventAnalyticsService.getAggregatedEventData( chart );

            chart.setDataItemGrid( grid );

            valueMap = GridUtils.getMetaValueMapping( grid, ( grid.getWidth() - 1 ) );
        }

        DefaultCategoryDataset regularDataSet = new DefaultCategoryDataset();
        DefaultCategoryDataset regressionDataSet = new DefaultCategoryDataset();

        SimpleRegression regression = new SimpleRegression();

        BaseAnalyticalObject.sortKeys( valueMap );

        List<NameableObject> seriez = new ArrayList<>( chart.series() );
        List<NameableObject> categories = new ArrayList<>( chart.category() );

        if ( chart.hasSortOrder() )
        {
            categories = getSortedCategories( categories, chart, valueMap );
        }

        for ( NameableObject series : seriez )
        {
            double categoryIndex = 0;

            for ( NameableObject category : categories )
            {
                categoryIndex++;

                String key = getKey( series, category, chart.getAnalyticsType() );

                Object object = valueMap.get( key );

                Number value = object != null && object instanceof Number ? (Number) object : null;

                regularDataSet.addValue( value, series.getShortName(), category.getShortName() );

                if ( chart.isRegression() && value != null && value instanceof Double && !MathUtils.isEqual( (Double) value, MathUtils.ZERO ) )
                {
                    regression.addData( categoryIndex, (Double) value );
                }
            }

            if ( chart.isRegression() ) // Period must be category
            {
                categoryIndex = 0;

                for ( NameableObject category : chart.category() )
                {
                    final double value = regression.predict( categoryIndex++ );

                    // Enough values must exist for regression

                    if ( !Double.isNaN( value ) )
                    {
                        regressionDataSet.addValue( value, TREND_PREFIX + series.getShortName(), category.getShortName() );
                    }
                }
            }
        }

        return new CategoryDataset[]{ regularDataSet, regressionDataSet };
    }

    /**
     * Creates a key based on the given input. Sorts the key on its components
     * to remove significance of column order.
     */
    private String getKey( NameableObject series, NameableObject category, AnalyticsType analyticsType )
    {
        String key = series.getUid() + DIMENSION_SEP + category.getUid();

        // Replace potential operand separator with dimension separator

        key = AnalyticsType.AGGREGATE.equals( analyticsType ) ? key.replace( DataElementOperand.SEPARATOR, DIMENSION_SEP ) : key;

        // TODO fix issue with keys including -.

        return BaseAnalyticalObject.sortKey( key );
    }

    /**
     * Returns a list of sorted nameable objects. Sorting is defined per the
     * corresponding value in the given value map.
     */
    private List<NameableObject> getSortedCategories( List<NameableObject> categories, BaseChart chart, Map<String, Object> valueMap )
    {
        NameableObject series = chart.series().get( 0 );

        int sortOrder = chart.getSortOrder();

        List<NumericSortWrapper<NameableObject>> list = new ArrayList<>();

        for ( NameableObject category : categories )
        {
            String key = getKey( series, category, chart.getAnalyticsType() );

            Object value = valueMap.get( key );

            if ( value != null && value instanceof Number )
            {
                list.add( new NumericSortWrapper<NameableObject>( category, (Double ) value, sortOrder ) );
            }
        }

        Collections.sort( list );

        return NumericSortWrapper.getObjectList( list );
    }

    // -------------------------------------------------------------------------
    // CRUD operations
    // -------------------------------------------------------------------------

    @Override
    public int addChart( Chart chart )
    {
        chartStore.save( chart );

        return chart.getId();
    }

    @Override
    public void updateChart( Chart chart )
    {
        chartStore.update( chart );
    }

    @Override
    public Chart getChart( int id )
    {
        return chartStore.get( id );
    }

    @Override
    public Chart getChart( String uid )
    {
        return chartStore.getByUid( uid );
    }

    @Override
    public Chart getChartNoAcl( String uid )
    {
        return chartStore.getByUidNoAcl( uid );
    }

    @Override
    public void deleteChart( Chart chart )
    {
        chartStore.delete( chart );
    }

    @Override
    public List<Chart> getAllCharts()
    {
        return chartStore.getAll();
    }

    @Override
    public Chart getChartByName( String name )
    {
        return chartStore.getByName( name );
    }

    @Override
    public int getChartCount()
    {
        return chartStore.getCount();
    }

    @Override
    public int getChartCountByName( String name )
    {
        return chartStore.getCountLikeName( name );
    }

    @Override
    public List<Chart> getChartsBetween( int first, int max )
    {
        return chartStore.getAllOrderedName( first, max );
    }

    @Override
    public List<Chart> getChartsBetweenByName( String name, int first, int max )
    {
        return chartStore.getAllLikeName( name, first, max );
    }
}

redpajama_set_name: RedPajamaGithub


A visit to the Holy Land is the experience of a lifetime, a journey to the very source of our faith, for wherever you set foot you are stepping on ground with religious and spiritual history.
The unique spiritual experience of visiting the Holy Land is a much-cherished dream of every Christian, whatever their denomination. We are the experts in fulfilling that dream.
We will offer you a large choice of programs which can be adjusted to your specific request. We will book masses, incorporate special events and visits into the program and be in daily touch with the minister or tour leader.
We will do everything to ensure your clients experience the trip of a lifetime.


The full Cebora MIG welding range is available at TBWS. The Cebora MIG Power Sources range from 160 to 500 amps welding outputs with single and three phase machines available. Cebora's MIG Welders come as Compacts and Separates to suit all uses. The full MIG range feature Power Factor Correction to provide economical running costs. Cebora MIG Welders offer great build quality and high end features including Pulse, Double Pulse and Synergic functionality on selected lines. The Pulse technology incorporated in Cebora MIG equipment is particularly suited to the welding of Aluminium metals, giving neat, TIG like appearing welds. Many of the Cebora machines feature the option to upgrade to pulse and double pulse functionality, giving flexibility to add options later if required.
One of the most popular machines in the range, the Jaguar Sound MIG 2060 is unique among other welding inverters, allowing the user to run x2 MIG torches from one power source. This is an added bonus, perfect if running 2 MIG wire types at one time and reducing changeover of one wire to another.
The range is mostly available next day and come as standard, with a 2 year manufacturers warranty.
TBWS are able to supply all genuine accessories and consumables, as well as PPE. To discuss your requirements, arrange a package price or to take advantage of further discounts, please call our sales line.


text:
Miriam Escofet Elected Member of the Royal Society of Portrait Painters
Miriam Escofet with "Childhood Consecration" - mixed media drawing on panel 80 x 60 cm
Albemarle artist Miriam Escofet has been elected as a member of the prestigious Royal Society of Portrait Painters. Her impressive body of work has featured in the Royal Portrait annual exhibitions since 2012 and has consistently featured each year.
This incredible achievement comes just two years after Escofet won the BP Portrait Award in 2018 for her remarkable portrait of her mother, "An Angel At My Table".

redpajama_set_name: RedPajamaCommonCrawl


A new collaboration between Placed, Kantar and Inscape is using data collected from 8 million Visio internet-connected TVs and over 350 million location enabled mobile devices to analyze the relationships between TV ads for over 100 brands on over 100 channels and real-life store visits. Simply put, the goal is to determine what types of TV ads are most likely to result in someone actually going into a store. Different products and services can track how the utility of their ads changes on different days of the week, different time slots and different networks.
Placed, Inscape and Kantsr are collaborating on a project to analyze data in order to learn what kinds of ads are most likely to result in a real world store visit.
The project involves using Vizio internet-enabled TVs and over 350 million location-enabled devices to associate ads with people actually going into stores.
Some channels, like Food Network and Golf Channel, are better at turning ads into visitors, while factors like time and day of the week are also important.
How will the Amazon-Whole Foods deal affect restaurants?


text:
Q: TideSDK google fonts support I'm facing some problems with the google fonts, using TideSDK.
I took a code snippet, 100% working, from a previous web project I did.
CSS3 code:
body {
font-family: 'Open Sans', Arial, Helvetica, sans-serif;

}
HTML5 code:
<!-- Google Fonts link -->
    <link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Open%20Sans">

I've seen that this question has been asked already here on stackoverflow, but since that the answers I've found are a bit outdated and closed, I tought that it was a good idea to open a new one regarding this topic.
The question is: how can I implement google fonts into the TideSDK app? Because the same snipppet that I've taken from a previous tested web app here doesn't work.
Thanks in advance.

redpajama_set_name: RedPajamaStackExchange


Inaugural semester comes and goes for Texas' first AACSB-accredited DBA program.
They commute from as far away as Houston. One student moved to Dallas from Brazil. Half of them already have a degree from UD. With an average age of 49 years, and 13 years on average of executive management experience, they are the inaugural class of the Satish & Yasmin Gupta College of Business Doctor of Business Administration (DBA) Program, which launched in August with a full class.
The programs curriculum, which has been designed to quickly respond to rapidly changing business landscapes, will focus on applied research.
The DBA is broader in approach than a PhD, said Director of Executive Learning Rodney Williams. Coursework isnt limited to the theoretical. Our students will actively test researched theories within their own workplaces.
The programs launch has brought many alumni back to school, and back to UD.
The high-quality faculty was a significant contributor in my decision to pursue the DBA, and equally important is the strong commitment our faculty have to create an optimal learning environment for my cohort, said Mark Brightenburg, MBA 11, director at Fidelity Investments and one of the university's DBA students.
During their first semester this fall, students cut their teeth on topics like strategic and interpersonal engagement, cross-cultural competency and designing applied research.
My present research inquiry, under Sri Beldonas guidance, takes a global perspective on how emotional intelligence influences the relationship between leadership style and employee outcomes within China as compared to the United States, said Brightenburg.
The DBA students represent a wide variety of industries from accounting to aerospace.
All in all, students were excited and empowered by a busy first semester of doctoral coursework with Satish & Yasmin Gupta College of Business faculty.
I have many wonderful memories, including having dinner with my classmates and faculty at President Keefes home, a group exercise on learning styles, a panel discussion with faculty, presenting an article on global business, and enjoying meals with my new friends, said Brightenburg.


text:
B − L je ve fyzice vysokých energií rozdíl mezi baryonovým číslem (B) a leptonovým číslem (L).

Podrobnosti
Toto kvantové číslo je náboj globální kalibrační U(1) symetrie v některých modelech teorie velkého sjednocení nazývaná U(1)B−L. Na rozdíl od samotného baryonového čísla nebo samotného leptonového čísla by tato hypotetická symetrie, pokud je globální, neměla být narušena chirálními anomáliemi nebo gravitačními anomáliemi, což je důvod proč je často zmiňována. Pokud B−L existuje jako symetrie, musí být spontánně narušena, čímž se získá nenulová klidová hmotnost neutrin, pokud předpokládáme houpačkový mechanismus. Kalibrační bosony spojené s touto symetrií se obvykle nazývají jako bosony X a Y.

Anomálie, které naruší zachování baryonového čísla a leptonového čísla se jednotlivě naruší vždy takovým způsobem, že B−L zůstane zachováno. Jeden hypotetický příklad je rozpadu protonu (B = 1, L = 0) rozpadá na pion (B = 0, L = 0) a pozitron (B = 0, L = −1).

Slabý hypernáboj YW se vztahuje k B − L přes:
X + 2 YW = 5 (B − L)
kde X je U(1) symetrie teorie velkého sjednocení spojená se zachovávajícím se kvantovým číslem.

Reference

Fyzika částic
Jaderná fyzika
Elementární částice

redpajama_set_name: RedPajamaWikipedia


When talking to Donna about her inspirations and her work, you soon realize that she has stories to tell about each of her paintings. How they came to be, and how they evolved. Each work representing a small part of her personal journey, her inner world.
Singer/songwriter Murray Rodgers will be performing from his new CD "I'm A Shoe"; a wonderful collection of original bluesy pop songs, recorded right here in the area. Cover for the CD was designed by Try it ART artist, Bernhard Cociancig.
As with each Try it ART exhibition, we are fundraising for a local non-profit. This time we thought it was suiting to help raise funds for the Bragg Creek Community Center.
Small artworks, donated by various local and international artists will be for sale for the duration of the exhibit. Full proceeds (100%) will benefit this deserving local cause.
Join us for the vernissage!
Our new gallery nestled in the trees of West Bragg Creek, Donna's thought-provoking images on canvas, and music by singer-songwriter Murray Rodgers will guarantee you a great afternoon!
Join us for this special vernissage on Saturday, March 2nd, from 2:00-5:00 PM. Tickets are free, kindly RSVP before February 26 via Eventbrite.
Can't make it to the opening? You will have to miss Murray, but the exhibit runs till April 1, 2019.
This entry was posted in Art Exhibitions, Events and tagged art exhibitions, artshow, Donna Winn, Murray Rodgers, original art, vernissage. Bookmark the permalink.


text:
Coalition, opposition MKs support bill to put freed terrorists on probation retroactively
Legislation aims to ensure that freed prisoners returning to terrorism will continue previous prison sentences and be convicted for new crimes they commit.
By LAHAV HARKOV
Candlelight vigil, protest of prisoner release 370
(photo credit: Marc Israel Sellem/The Jerusalem Post)
Terrorists released in negotiations and prisoner exchanges in the past or slated to be released in the future will not be considered pardoned, if a bill submitted by Knesset Foreign Affairs and Defense Committee chairman Ze'ev Elkin (Likud Beytenu) on Thursday passes.
The legislation has support on the Right and the Left, including from Labor faction chairman Eitan Cabel, coalition chairman Yariv Levin and several other lawmakers from Likud Beytenu, Shas, United Torah Judaism, Bayit Yehudi, Hatnua and Yesh Atid.
The proposal comes just days after 51 terrorists, earlier freed as part of the exchange of 1,027 Palestinian prisoners for captive soldier Gilad Schalit, were re-arrested.
The measure is meant to ensure that, if a freed prisoner returns to committing terrorism, he will continue his previous prison sentence and be convicted for the new crime he committed.
Prisoners will no longer be pardoned by the president in cases of trades or releases during diplomatic negotiations; rather, they will officially be on parole.
In addition, if the organization of which a terrorist is a member kidnaps someone, the government may cancel any previous prisoner exchanges and put all members of the organization who were released back in jail.
The bill's explanatory portion states that "in most cases, terrorists who were freed were involved in serious and despicable terrorist attacks and their release is an outrage and a stab in the heart."
"Terrorists need to know that criminal kidnapping of the sort [we saw recently] puts terrorists in jail and doesn't free them," Elkin explained. "Every terrorist organization has to understand that it does not pay to kidnap."
According to Elkin, if the bill passes, terrorists will have to take into consideration the fact that anyone who was released can be put back in prison before they plan another kidnapping.
Tags israel palestinian negotiations israel releases terrorists


*Save $80 on HP 15.6″ Touch-Screen Laptop with Intel® Core™ i3 Processor and 1TB Hard Drive! from Best Buy Co, Inc. Coupon Code: No Code Required. Price: Not Specified. Discount: $80. Categories: Laptops, Sponsored. Coupon Rating: 4.5 Stars out of 5. Store Rating: 4.8 Stars out of 5. Coupon Recommendation: Recommended. Available Until: May 20. Thoughts: Deal Score 70 out of 100.
*Get $50 Off on first order of Purium® Organic SuperFoods geared to lose weight with Coupon Code SAVE – be your ideal body weight Now! from Purium. Coupon Code: SAVE . Price: Not Specified. Discount: $50. Categories: Food Suppliments & Vitamins, Sponsored. Coupon Rating: 4.5 Stars out of 5. Store Rating: 4.5 Stars out of 5. Coupon Recommendation: Recommended. Available Until: Not Specified. Thoughts: Deal Score 60 out of 100.
*25% Off Entire Purchase with Code: D5088. Valid 5/5-6/1! from Drapers and Damon's. Coupon Code: D5088. Price: Not Specified. Discount: 25%. Categories: Fashion Jewelry, Sponsored. Coupon Rating: 4.5 Stars out of 5. Store Rating: 4.6 Stars out of 5. Coupon Recommendation: Recommended. Available Until: Jun 2. Thoughts: Deal Score 55 out of 100.
*33% OFF Discount for Lixada Men's Athletic Compression T shirt Top Tee Quick Dry Running Baselayer Sport Shirt from Tomtop. Coupon Code: No Code Required. Price: Not Specified. Discount: 33%. Categories: T-Shirts, Sponsored. Coupon Rating: 4.3 Stars out of 5. Store Rating: 4.6 Stars out of 5. Coupon Recommendation: Recommended. Available Until: May 25. Thoughts: Deal Score 60 out of 100.
*Dad's Are Rad! Give Yours The Gift of Travel Today! Save Up to $9 on Flights and Hotels with Promo Code MYDAD9. Book Now! from CheapOair.com. Coupon Code: MYDAD9. Price: Not Specified. Discount: $9. Categories: Flight Deals, Sponsored. Coupon Rating: 4.0 Stars out of 5. Store Rating: 4.6 Stars out of 5. Coupon Recommendation: Recommended. Available Until: Jun 20. Thoughts: Deal Score 65 out of 100.
*Save $200 PhunkeeDuck – Monster Duck Self-Balancing Scooter – Black from Best Buy. Coupon Code: No Code Required. Price: $449.99. Discount: $200. Categories: Kid's Toys, Sponsored. Coupon Rating: 4.4 Stars out of 5. Store Rating: 4.8 Stars out of 5. Coupon Recommendation: Strongly Recommended. Available Until: Not Specified. Thoughts: Deal Score 70 out of 100.
*Save $500 Samsung – 75″ – LED – NU8000 Series – 2160p – Smart – 4K UHD TV with HDR from Best Buy. Coupon Code: No Code Required. Price: $2,499.99. Discount: $500. Categories: Luxury Electronics, Sponsored. Coupon Rating: 4.4 Stars out of 5. Store Rating: 4.8 Stars out of 5. Coupon Recommendation: Strongly Recommended. Available Until: Not Specified. Thoughts: Deal Score 70 out of 100.
*Save $50 on Garmin Speak Plus with Amazon Alexa and Built-In Dash Camera! from Best Buy Co, Inc. Coupon Code: No Code Required. Price: Not Specified. Discount: $50. Categories: Electronics Coupons, Sponsored. Coupon Rating: 4.5 Stars out of 5. Store Rating: 4.5 Stars out of 5. Coupon Recommendation: Recommended. Available Until: May 19. Thoughts: Deal Score 65 out of 100.
*Save up to $100 on Select Desktop Towers and All-in-One Computers! from Best Buy Co, Inc. Coupon Code: No Code Required. Price: Not Specified. Discount: $100. Categories: Office Computers & Electronics, Sponsored. Coupon Rating: 4.3 Stars out of 5. Store Rating: 4.8 Stars out of 5. Coupon Recommendation: Recommended. Available Until: May 20. Thoughts: Deal Score 65 out of 100.
*Save $50 JVC – 6.8″ – Android Auto/Apple® CarPlay™ – Built-in Bluetooth – In-Dash CD/DVD/DM Receiver – Black from Best Buy. Coupon Code: No Code Required. Price: $449.99. Discount: $50. Categories: Car accessories, Sponsored. Coupon Rating: 4.2 Stars out of 5. Store Rating: 4.8 Stars out of 5. Coupon Recommendation: Recommended. Available Until: Not Specified. Thoughts: Deal Score 60 out of 100.


text:
package btools.mapcreator;

import java.io.File;

import btools.util.DenseLongMap;
import btools.util.TinyDenseLongMap;

/**
 * WayCutter does 2 step in map-processing:
 *
 * - cut the way file into 45*30 - pieces
 * - enrich ways with relation information
 *
 * @author ab
 */
public class WayCutter extends MapCreatorBase
{
  private DenseLongMap tileIndexMap;

  public static void main(String[] args) throws Exception
  {
    System.out.println("*** WayCutter: Soft-Cut way-data into tiles");
    if (args.length != 3)
    {
      System.out.println("usage: java WayCutter <node-tiles-in> <way-file-in> <way-tiles-out>" );

      return;
    }
    new WayCutter().process( new File( args[0] ), new File( args[1] ), new File( args[2] ) );
  }

  public void process( File nodeTilesIn, File wayFileIn, File wayTilesOut ) throws Exception
  {
    init( wayTilesOut );

    new NodeIterator( this, false ).processDir( nodeTilesIn, ".tlf" );

    // *** finally process the way-file, cutting into pieces
    new WayIterator( this, true ).processFile( wayFileIn );
    finish();
  }

  public void init( File wayTilesOut ) throws Exception
  {
    this.outTileDir = wayTilesOut;

    // *** read all nodes into tileIndexMap
    tileIndexMap = Boolean.getBoolean( "useDenseMaps" ) ? new DenseLongMap() : new TinyDenseLongMap();
  }

  public void finish() throws Exception
  {
    closeTileOutStreams();
  }

  @Override
  public void nextNode( NodeData n ) throws Exception
  {
    tileIndexMap.put( n.nid, getTileIndex( n.ilon, n.ilat ) );
  }

  @Override
  public void nextWay( WayData data ) throws Exception
  {
    long waytileset = 0;
    int nnodes = data.nodes.size();

    // determine the tile-index for each node
    for (int i=0; i<nnodes; i++ )
    {
      int tileIndex = tileIndexMap.getInt( data.nodes.get(i) );
      if ( tileIndex != -1 )
      {
        waytileset |= ( 1L << tileIndex );
      }
    }

    // now write way to all tiles hit
    for( int tileIndex=0; tileIndex<54; tileIndex++ )
    {
      if ( ( waytileset & ( 1L << tileIndex ) ) == 0 )
      {
        continue;
      }
      data.writeTo( getOutStreamForTile( tileIndex ) );
    }
  }

  public int getTileIndexForNid( long nid )
  {
    return tileIndexMap.getInt( nid );
  }

  private int getTileIndex( int ilon, int ilat )
  {
     int lon = ilon / 45000000;
     int lat = ilat / 30000000;
     if ( lon < 0 || lon > 7 || lat < 0 || lat > 5 ) throw new IllegalArgumentException( "illegal pos: " + ilon + "," + ilat );
     return lon*6 + lat;
  }

  public String getNameForTile( int tileIndex )
  {
    int lon = (tileIndex / 6 ) * 45 - 180;
    int lat = (tileIndex % 6 ) * 30 - 90;
    String slon = lon < 0 ? "W" + (-lon) : "E" + lon;
    String slat = lat < 0 ? "S" + (-lat) : "N" + lat;
    return slon + "_" + slat + ".wtl";
  }

}


text:
Are the White Stripes the sexiest band of all time?
by Karina Longworth
Johnny Cash: The man in shades of black
One day, not so very long ago, I went over to a boy's house to make out, and I brought along my copy of White Blood Cells. He thought the White Stripes were boring and I had to force him to put the record on. It was business as usual for three tracks, until we got to 'Fell in Love with a Girl'. I rolled onto my back and, ignoring the boy next to me, I let myself get worked over by the most perfect pop song I had maybe ever heard. When it was over – that final thrust, that final chord – I caught my makeout partner with all the signs, the same condition that I knew he could see on me: mouth agape, eyes bleary, limbs limp. "I must be fine 'cus my heart's still beating…"
I watched them every night they played the Conan O'Brian show. I saw it with my own eyes, yet it felt like a vision. I saw that sweet little girl beating the hell out of her drum kit, like a convict attacking his last bucket of chicken. I saw that ghostly white man-child ripping his guitar to shreds like his life depended on it. And I saw the way they looked at each other. Like he was silently controlling her every move. Like she was defenceless, but like she liked it. I saw what was going on up there. I'm ready to testify. I don't like to mix my metaphors this much, going back and forth between religion and fucking, but The White Stripes sort of demand it.
They were married, you know. They're not really brother and sister. As Trevor Lord of the BBC put it, "splitting up has never sounded so good", and dear god, has any divorce ever looked so sexually active? The TV close-ups betrayed what the live show could never reveal: the ex-Mr. And Mrs. White in a mind-meld, inventing a whole new kind of sex up there on the TV stage. When the lumbering Conan would go out to shake their hands, the Whites seemed a bit embarrassed, like kids caught making out in the basement when they were supposed to be studying chemistry.
The White Stripes make music like the way I thought sex would be like, at 13, when I had only made out, and when making out was simply enough. Maybe that's sort of it. I think making out, as part of the ironic/nostalgic hipster lifestyle template, has had a popular resurgence of late- it's almost like the kids aren't even having sex anymore because it's, like, too much, it's like, trying too hard. It seems that the only cardinal sin in all the hipster world is intentionality, and hey, like, why can't it just be like junior high, when, like, making out was on its own like totally transgressive and there weren't like, expectations or whatever? Jack White continually makes the best make-out records of our era because he's continually locked in all kinds of adolescent battle. Everything about this 28 year-old man suggests that he's still trying to figure out how his dick works and what kind of responsibility it beckons. Same boy you've always known – well I guess I haven't grown… I guess not. At least he's conscious of it.
They were working the brother and sister act from the beginning – and as late as the first full length record, they're still married – but it gets progressively regressive, just as it gets slicker, more cohesive. It devolves from a vicious hoax to sweaty teenage fantasy. It's all there on White Blood Cells. now, now, Now, NOW, NOW, Meg and Jack lazily chant at the end of the album, and it sounds like a couple of kids forced by the 'rents to sing 'round the piano for company. It's palpable: the wink, tossed off from Meg to Jack, the signal that they can go sneak up to her room when this is all over. And this all has to be part of the appeal, don't you think? How sexy is incest? I guess I don't know, and that's why it turns me on. That's why it seems so hot to ask your wife to pretend to be your sister, to sing these trauma songs that dissect your relationship and be able to shrug it off, with a wink and put-opon back-woods drawl, "we's just kinfolk." To playfully cover a dirty blues song like "Your Southern Can is Mine," to have her bang her tambourine to lyrics like,
"Now baby, ashes to ashes, sand to sand
When I hit you momma then you'll feel my hand
Give you a punch through that barbed wire fence …
Well if I catch you momma down in the heart of town,
I'm gonna grab me a brick and tear your can on down,
your southern can belongs to me."
How many rock bands reference sexual taboo – even sexual violence – in such a palatable, literally candy-coated manner? Say what you will about the matching outfits, but The White Stripes have a subtlety of design that lets them get away with stuff that a freakshow diva like Marilyn Manson could only dream of. And I never had fantasies about Marilyn Manson, but Jesus Christ, those White kids …
I put on Elephant when I want to man eat. As in, behave like a man eater. I put it on while I decide what to wear. I put it on and have a drink and get ready to go out and put myself in this world where I have license to behave extremely badly. And my mind starts to race … I want Jack to buy me a scotch, like we both know what that means, like we both know what is going to happen. Like he's gonna take me down to the basement of his parents' house. Like he's gonna flick on a lamp that just barely casts a spot of light on a twin bed with a crotched white cover. Like he's gonna push me down on the bed, and from underneath him I'll look up and I'll just barely spot out Meg, curled up in the corner, in a white eyelet-trimmed cotton nightie, hands over her eyes and yes, she's peeking from the space between her fingers, catching my eye from beneath her brother. Husband. Brother. Definitely brother.
I sit and I drink my scotch and I play this out in my head, just to get it out of my system. The record gets me out of the house, at least, but at the same time the fantasy spoils my oft-compromised reality. There are times when my sexual escapades are like living inside a White Stripes song, but these are the best of times, and I get spoilt by this record for the rest of times. I have to keep reminding myself that living inside an ELO song is maybe good enough.
So what happened to their marriage? I lie awake at night trying to figure it out. Why would he leave her – I mean, look at her. And what could he have done to make her go away? Who do you think you're messing with, girl? Who do you think you're trying to fool? God, it was her! I thought you made up your mind. She found herself another man. "You think I care about me and only me – well you know it don't take much to satisfy me". There was only one way to send Jack White out the door, and it looks like Meg's done gone and done it. But you know, maybe Jack just didn't want try so hard, or whatever. Maybe being in a band with your wife was just like, too much. Maybe he had an inkling they weren't going to stay married for long. From their first, pre-divorce record: "Is this really love? Is she the one I love?" Ouch.
Jack White is just a junior-high tease – but watch out, because adolescent sexuality rules the world, and Jack and Meg know how to use it.
Karina Longworth 27 January 2008
The Greatest Documentary Ever Made


It happens to all of us. Yesterday we used a language, framework, skill, or technology that is seemed like second nature to us. And today, (maybe because of legacy issues, maintenance or other) we have to go back pick up that old skill we used to know like the back of other hands.
Sometimes we may not want to depart from that existing tech. but we must because of any of the above reasons.
It follows the rule which says the more you use something the more you get better at it. Conversely the less you use it, the worse you get.
I would speak more specifically in regards to frameworks, languages and technology in general. However these points apply to a broad category of any habit or skill you wish to regain.
Psych yourself up. It is true that old tech you want to pick up again has improved. It may also have gone through many changes in between that time you stopped using it and now. It can be demoralizing to think of the time needed to come back up to speed, and catch up with the current pace.
That is why the battle first starts within your mind. Believe you can and you are already halfway there.
Refer to old notes. Keep old notes you can refer to once you have to pick up that piece of technology again. There would have been old books or tutorials you used when you first studied the language. Go back to them. This time around it would only be a refresher, so the pace you go through them would be really fast.
Refer to your old code. When you used that technology the first time round you must have built some stuff with it. Refer to all those old pieces of materials. This is invaluable resource and one of the best reference points you could ever have. It is especially so since it is your own piece of code. In reading it you understand why you wrote it that way and not any other.
This is the single most useful piece of information I want to highlight for you.
Now you have done a lot of referencing and revision. It's now time to do. Build from scratch something new with the old piece of tech. This would be surprisingly easier than you think. We all learn by doing so this is just great for you.
Do not stop. Coming going at it. Be consistent in your determination to be competent with the skill you crave to regain.
When you hit a stumbling block refer online. Check out the usual suspects. Mainly Stack Overflow and the online forums for that technology. Do not be afraid that your question would sound cheap or silly.
Lastly, keep calm and keep believing. You still the knack for being strong again with the old skill you think you lost.
Thank you for your time. Now go regain that old skill.


A claw set brilliant cut 3 piece flexible bar bracelet by Diamondfire. Diamonfire stones feature an "ideal cut" with 57 facets precisely hand cut just like real diamonds. Each Diamonfire piece has a unique multilayer plating consisting of rhodium, palladium and platinum giving a sophisticated finish. 64/0523/1/082.


WMAs are increasingly important in providing a place for people to enjoy wildlife-associated recreation as more of the state is developed. The WMAs also contain key habitats for a diverse array of wildlife species from bats to black bears and spruce grouse to snowshoe hare.
The Vermont Fish & Wildlife Department annually manages 90 WMAs and many riverfront parcels totaling more than 133,000 acres to conserve fish, wildlife and their habitats and for people to enjoy while hunting, fishing, trapping and pursuing other wildlife-based recreation.
A key factor in providing places for many different wildlife species to feed, raise young and find shelter is to have an abundance of different types of habitat available. A mix of mature hardwood and softwood forests, as well as areas with young saplings and open fields, all help provide habitat that allows wildlife to prosper. Habitat is constantly changing as trees take over fields and as they grow through different stages of development. Maintaining different habitat types requires ongoing management and maintenance.
800 acres were purchased, conserving high priority habitat for wildlife and endangered plants.
4,400 trees were planted to stabilize riverbanks and restore floodplain forest habitat.
310 wild fruit and nut trees were maintained.
Eleven parcels ranging from three to 2,875 acres are currently in various stages of acquisition, according to a state press release. Seven to ten of these are expected to be acquired in 2017.
Federal taxes paid by hunters on firearms, ammunition and archery equipment, plus hunting license fees, have made it possible in the past to acquire WMA lands and restore and manage habitat for wildlife.
For more information download the full 2015 report on WMAs at www.vtfishandwildlife.com.


We all need mentors and others to look up to. Fortunately, for Richardson & Richardson, we have an entire network of mentors. Last month, a few of our team members attended the Construction Leadership Network (CLN) conference in Tampa, Florida to practice win-win sharing. The CLN membership is comprised of a diverse group of entrepreneurs, commercial contractors, and construction industry providers from throughout the U.S. and Canada.
Vice President Brandon McCutcheon, Marketing Director Katy Richardson, pictured left, and Field Manager Byron Hodges, pictured below, spent three days in Tampa at the annual Construction Leadership Network conference. They learned about company differentiation, performance management, and how to find and develop the next generation of leadership.
They attended focus groups on marketing, business development, and time management. Katy explains, "We find our membership at CLN provides valuable relationships with other contractors throughout the United States and Canada. We appreciate the diversity of the companies and regions represented because it gives great insight into our market and industry. We also appreciate that CLN fosters a vibrant learning environment with special speakers and focus groups."
Our team also learned about creating a positive company culture and mastered seven actions for ensuring workplace safety. They met within peer groups and listened to panel experts talk about project management and C-Suite leadership. "I personally enjoyed both the inbound marketing and the RFP Questions You Hate seminars. With technology progressing so quickly, it was neat to see the tools available through HubSpot and to see the opportunities to galvanize our marketing with these tools. The RFP Questions You Hate seminar brought some good insight into how we can help owners better understand the benefits our experience can bring, and how we can do it by coming from a more authentic and empathetic place," says Katy.
Throughout the year, we are connected to the CLN membership by a web-based tool that enables us to communicate in forums, share documents, learn about each other's capabilities, and strengthen our bonds. We value our membership in the CLN because it makes us better contractors and construction managers, and we can use the information we learn in our businesses as well as on the jobsite.
The R&R team is already looking forward to next year's network meeting where we will have the opportunity to connect with our friends and mentors who share the same values and out-of-the-box thinking that we enjoy. Katy reflects that "We have seen that the benefits of creating relationships and sharing with our peers are two-fold: when pursuing projects in other regions that are unfamiliar in scope, we have been able to get advice or support from members, as well as information about new technology and programs. We have also been able to provide some of this support to some of the other members. This reciprocal sharing has been win-win for everyone involved and it's a good feeling to know you have the advice and experience of such a varied group at your disposal. Plus, the friendships forged at CLN last for years and go beyond just the annual meetings."


Chicago-based law firm Mayer Brown has advised South Africa's FirstRand Bank on a ten-year lease of Austin Friars House, EC2, for its London headquarters. The newly refurbished office space comprises over 9,000 square feet on the ground and sixth floors.
FirstRand is one of the big four South African retail, commercial and investment banks with offices throughout Africa, as well as in London, Dubai, Australia, China and India.
LABLAW has assisted SMA Finance - a company owned by the family of Italian entrepreneur Silvio Scaglia - on a successful auction bid for the prestigious Italian lingerie brand LA PERLA.
LABLAW founding partner Francesco Rotondi and his team represented SMA Finance in trade union negotiations and the agreement to lease the assets of the company until the final sale / purchase agreement is signed.
The €69 million deal, agreed at the bankruptcy tribunal in Bologna, will save 703 jobs.
The London office of global law firm Debevoise & Plimpton has represented clients in two separate disputes heard in the Grand Court of the Cayman Islands.
The first case involved Ace Limited and is related to its long running dispute with Liberia's Insurance Commissioner over losses arising from the Liberian Civil Wars.
After successfully arguing that a case brought against Ace should be dismissed, the company is now pursuing the third party funders of the litigation for costs.
The second case involves Dart Realty, and regarded opposition to a major redevelopment project planned for a stretch of the Cayman coast.
Debevoise successfully argued that a judicial review filed by a local group was without merit and out of time.
Debevoise's European and Asian chair of litigation, Lord Goldsmith QC, was the lead advocate on both cases.
Norton Rose Fullbright has advised JP Morgan and Numis as joint bookrunners and corporate brokers on The UNITE Group plc's £51.2 million fundraising.
UNITE is a leading UK developer and manager of student accommodation.
The transaction, which involved a cash box placing to existing and new institutional investors, was announced on 13 June 2013 and dealings in the new shares commenced on 18 June.
The Norton Rose Fulbright team included senior associate Fiona Millington, and associates Amy Reed and Kirsten Anderson.
Osborne Clarke and Proskauer Rose acted for UNITE.
Italian law firm NCTM has assisted private equity firm Arcadia Small Cap - which focuses on investments in small and medium enterprises - in the acquisition of an 80 per cent stake of high strength bolts and fasteners specialists VSP Bulloneria.
During the acquisition, Arcadia was advised by NCTM Studio Legale Associato with a team led by Matteo Trapani.
The Polato family, founders of VSP Bulloneria, was assisted by financial advisor Arietti & Partners, with a team led by Nino Dell'Arte.
Gianni Origoni Grippo Capelli & Partners acted as legal advisors, with a team led by Emanuele Grippo and made up of Gherardo Cadore and Nabor Zaffiri.


Item1956/0021 - Canning Road Board - Administration.
Item1956/0037 - Traffic regulations -amendments.
Item1956/0050 - Local Government - general - Betting Shops.
Item1956/0084 - Open Air Theatres.
Item 1956/0050 - Local Government - general - Betting Shops.
Local Government - general - Betting Shops.
Confirm Item Request: Local Government - general - Betting Shops.


Taro Kono, the Japanese foreign minister, has arrived in Dhaka on a brief visit to promote bilateral relationship between Bangladesh and Japan.
He will also discuss other issues of mutual interest, including the Rohingya crisis.
Foreign Secretary M Shahidul Haque received Kono at Hazrat Shahjalal International Airport on Tuesday afternoon, reports UNB.
Foreign Minister AH Mahmood Ali and Kono will hold a bilateral meeting at the state guesthouse Meghna on Tuesday evening, according to a senior official at the foreign ministry.
The Japanese foreign minister will meet Prime Minister Sheikh Hasina at her office at 5:30pm on Tuesday.
Kono visited Myanmar on Monday, before arriving in Bangladesh.
Kono was scheduled to visit Russia, Myanmar, and Bangladesh from July 30-August 8, as per a message from the Japanese Foreign Ministry about the foreign minister's attendance at Asean related Foreign Ministers' visits to these countries.
International media reported of the Japanese foreign minister and the State Counsellor of Myanmar, Aung San Suu Kyi, holding discussions on Monday about resolving the ongoing Rohingya crisis.
According to the Japanese Foreign Ministry, Japan will continue to provide full support to Bangladesh's development on all fronts, so the country can attain "newly industrialized economy" status by 2021, through the 39th Yen Loan Package- a total of 200.4 billion yen.
Earlier on May 14, Minister Kono held a bilateral meeting and had dinner at the Iikura Guest House with Foreign Minister Ali.
During the meeting, the Japanese minister stated Japan's desire to further promote Japan-Bangladesh comprehensive partnership, and assured Japan's support in ensuring Bangladesh's development on all fronts.
Japan will further strengthen bilateral relations ahead of the 50th anniversary of diplomatic relations in 2022, said Kono in the meeting. He requested the government of Bangladesh to continue ensuring the safety of Japanese people residing inside the country.
According to diplomatic sources, Japan lauded the efforts made by the Bangladeshi government in accepting Rohingyas from the Rakhine State of Myanmar, and the country's efforts at the ongoing dialogue with Myanmar government.


PROCOMM 3` FOOT CB / HAM RADIO ANTENNA RG58 A/U COAX WITH PL-259 MOLDED ENDS – Great value for the price, definitely recommend.
What is the PROCOMM 3` FOOT CB / HAM RADIO ANTENNA RG58 A/U COAX WITH PL-259 MOLDED ENDS good for?
I have found most affordable price of PROCOMM 3` FOOT CB / HAM RADIO ANTENNA RG58 A/U COAX WITH PL-259 MOLDED ENDS from Amazon store. It offers fast and free shipping. Best 2 way radios for sale will be limited stock of certain product and discount only for limited time, so do order now to get the best deals. Before you buy, check to see if a product is available online at store, read and compare experiences customers have had with 2 way radios below.
All the latest best 2 way radios reviews consumer reports are written by real customers on websites. You should read more consumer reviews and answered questions about PROCOMM 3` FOOT CB / HAM RADIO ANTENNA RG58 A/U COAX WITH PL-259 MOLDED ENDS below.


New year, new goals! Last year I only kept 2 of mine (move out of Norman and live in the moment more), so I'm going to try to be a bit more realistic with 2015.
1. Step my blog game up – I've already made a step toward improving my blog with the latest purchase of my first Canon DSLR camera (thanks, QVC!). I haven't been doing many Outfit of the Day posts lately, mostly because I wasn't happy with the quality of pictures. I'm excited to see how much more professional they will look with my big girl camera. I'm also planning to self-host my blog and have a new layout designed for me in the upcoming months! Blogging is my passion so I'm ready to invest more into making it as amazing as it can be.
2. Go on a beach vacation – While I loved going to Vegas in 2014, it was just a little too busy for me. I'm in serious need of a beach getaway with the BF. I've started looking into this and it's either going to be a Western Caribbean cruise (I've never been on one!) or a trip to Panama City. You just can't beat relaxing on the beach, swimming with dolphins, and doing nothing.
3. Do yoga twice a week – I always go to yoga once a week, and sometimes twice a week. This should be an easy goal to stick to considering how obsessed I am with it. Plus, my chiropractor says I need to go more often so I don't get out of alignment so easily (thank you, 7 years of pom!).
4. Open a savings account – We'll try this goal again because it's a good one. I DID get a 401k last year through my job, which I'm just going to let keep growing, so that counts for something. It's always good to have some extra money for emergencies and vacations.