text:
var FaceOperations = {};
var FO = FaceOperations;

var Face = function() {
    this.mark = FO.VISIBLE;
    this.outside = null;
};

FO.VISIBLE = 1;
FO.NON_CONVEX = 2;
FO.DELETED = 3;

FO.computeCentroid = function(face) {
    var halfEdge = face.halfEdge0;
    face.centroid = VectorOperations.zerovector();

    do {
        face.centroid = VectorOperations.add(face.centroid, halfEdge.head.point);
        halfEdge = halfEdge.next;
    } while (halfEdge !== face.halfEdge0);

    face.centroid = VectorOperations.scaldiv(face.numberOfVertices, face.centroid);
};

FO.computeNormal = function(face, minArea) {
    var halfEdgeMax, lenSqrMax, lenMax,
        halfEdge, lenSqr,
        headPoint, tailPoint, u, dot;

    var halfEdge1 = face.halfEdge0.next;
    var halfEdge2 = halfEdge1.next;

    var point0 = face.halfEdge0.head.point;
    var point2 = halfEdge1.head.point;

    var d2p = VectorOperations.sub(point0, point2);
    var d1p;

    face.normal = VectorOperations.zerovector();
    face.numberOfVertices = 2;

    while (halfEdge2 !== face.halfEdge0) {
        d1p = d2p;

        point2 = halfEdge2.head.point;
        d2p = VectorOperations.sub(point0, point2);

        face.normal = VectorOperations.add(face.normal, VectorOperations.cross(d1p, d2p));

        halfEdge2 = halfEdge2.next;
        face.numberOfVertices++;
    }

    face.area = VectorOperations.abs(face.normal);
    face.normal = VectorOperations.scaldiv(face.area, face.normal);

    if (minArea === void 0) {
        return;
    }

    if (face.area < minArea) {
        halfEdgeMax = null;
        lenSqrMax = 0;

        halfEdge = face.halfEdge0;

        do {
            lenSqr = halfEdge.lengthSqr();

            if (lenSqr > lenSqrMax) {
                halfEdgeMax = halfEdge;
                lenSqrMax = lenSqr;
            }

            halfEdge = halfEdge.next;
        } while (halfEdge !== face.halfEdge0);

        headPoint = halfEdgeMax.head.point;
        tailPoint = HEO.tail(halfEdgeMax).point;

        lenMax = Math.sqrt(lenSqrMax);

        u = VectorOperations.scaldiv(lenMax, VectorOperations.sub(headPoint, tailPoint));
        dot = VectorOperations.scalproduct(u, face.normal);

        face.normal = VectorOperations.sub(face.normal, VectorOperations.scalmul(dot, u));
    }
};

FO.getEdge = function(face, index) {
    var halfEdge = face.halfEdge0;

    while (index > 0) {
        index--;
        halfEdge = halfEdge.next;
    }

    while (index < 0) {
        index++;
        halfEdge = halfEdge.previous;
    }

    return halfEdge;
};

FO.findEdge = function(face, tailVertex, headVertex) {
    var halfEdge = face.halfEdge0;

    do {
        if (halfEdge.head.index === headVertex.index) {
            if (HEO.tail(halfEdge).index === tailVertex.index) {
                return halfEdge;
            } else {
                return null;
            }
        }

        halfEdge = halfEdge.next;
    } while (halfEdge !== face.halfEdge);

    return null;
};

FO.distanceToPlane = function(face, point) {
    return VectorOperations.scalproduct(face.normal, point) - face.planeOffset;
};

FO.getVertexString = function(face) {
    var result = face.halfEdge0.head.index,
        halfEdge = face.halfEdge0.next;

    while (halfEdge !== face.halfEdge0) {
        result += ' ' + halfEdge.head.index;
        halfEdge = halfEdge.next;
    }

    return result;
};

FO.getVertexIndices = function(face) {
    var result = [],
        halfEdge = face.halfEdge0;

    do {
        result.push(halfEdge.head.index);
        halfEdge = halfEdge.next;
    } while (halfEdge !== face.halfEdge0);

    return result;
};

FO._checkConsistency = function(face) {
    // do a sanity check on the face
    var hedge = face.halfEdge0;
    var maxd = 0;
    var numv = 0;

    if (face.numberOfVertices < 3) {
        throw new Error('degenerate face: ' + FO.getVertexString(face));
    }

    do {
        var hedgeOpp = hedge.opposite;
        if (hedgeOpp === null) {
            throw new Error('face ' + FO.getVertexString(face) + ': ' +
                'unreflected half edge ' + HEO.getVertexString(hedge));
        } else if (hedgeOpp.opposite !== hedge) {
            throw new Error('face ' + FO.getVertexString(face) + ': ' +
                'opposite half edge ' + HEO.getVertexString(hedgeOpp) +
                ' has opposite ' + hedgeOpp.opposite.getVertexString());
        }
        if (hedgeOpp.head !== HEO.tail(hedge) || hedge.head !== HEO.tail(hedgeOpp)) {
            throw new Error('face ' + FO.getVertexString(face) + ': ' +
                'half edge ' + HEO.getVertexString(hedge)) +
                ' reflected by ' + HEO.getVertexString(hedgeOpp);
        }
        var oppFace = hedgeOpp.face;
        if (oppFace === null) {
            throw new Error('face ' + FO.getVertexString(face) + ': ' +
                    'no face on half edge ' + HEO.getVertexString(hedgeOpp));
        } else if (oppFace.mark === FO.DELETED) {
            throw new Error('face ' + FO.getVertexString(face) + ': ' +
                    'opposite face ' + FO.getVertexString(oppFace) +
                    ' not on hull');
        }

        var d = Math.abs(FO.distanceToPlane(face, hedge.head.point));

        if (d > maxd) {
            maxd = d;
        }

        numv++;
        hedge = hedge.next;
    } while (hedge !== face.halfEdge0);

    if (numv !== face.numberOfVertices) {
        throw new Error('face ' + FO.getVertexString(face) + ' numVerts=' + face.numberOfVertices + ' should be ' + numv);
    }
};

FO.mergeAdjacentFace = function(face, hedgeAdj, discarded) {
    var numDiscarded = 0,
        oppFace = HEO.oppositeFace(hedgeAdj);

    discarded[numDiscarded++] = oppFace;

    oppFace.mark = FO.DELETED;

    var hedgeOpp = hedgeAdj.opposite;

    var hedgeAdjPrev = hedgeAdj.previous;
    var hedgeAdjNext = hedgeAdj.next;
    var hedgeOppPrev = hedgeOpp.previous;
    var hedgeOppNext = hedgeOpp.next;

    while (HEO.oppositeFace(hedgeAdjPrev) === oppFace) {
        hedgeAdjPrev = hedgeAdjPrev.previous;
        hedgeOppNext = hedgeOppNext.next;
    }

    while (HEO.oppositeFace(hedgeAdjNext) === oppFace) {
        hedgeOppPrev = hedgeOppPrev.previous;
        hedgeAdjNext = hedgeAdjNext.next;
    }

    var hedge;

    for (hedge = hedgeOppNext; hedge !== hedgeOppPrev.next; hedge = hedge.next) {
        hedge.face = face;
    }

    if (hedgeAdj === face.halfEdge0) {
        face.halfEdge0 = hedgeAdjNext;
    }

    // handle the half edges at the head
    var discardedFace;

    discardedFace = FO._connectHalfEdges(face, hedgeOppPrev, hedgeAdjNext);

    if (discardedFace !== null) {
        discarded[numDiscarded++] = discardedFace;
    }

    // handle the half edges at the tail
    discardedFace = FO._connectHalfEdges(face, hedgeAdjPrev, hedgeOppNext);

    if (discardedFace !== null) {
        discarded[numDiscarded++] = discardedFace;
    }

    FO._computeNormalAndCentroid(face);
    FO._checkConsistency(face);

    return numDiscarded;
};

FO.getSquaredArea = function(face, hedge0, hedge1) {
    // return the squared area of the triangle defined
    // by the half edge hedge0 and the point at the
    // head of hedge1.

    var p0 = HEO.tail(hedge0).point;
    var p1 = hedge0.head.point;
    var p2 = hedge1.head.point;

    var dx1 = p1.x - p0.x;
    var dy1 = p1.y - p0.y;
    var dz1 = p1.z - p0.z;

    var dx2 = p2.x - p0.x;
    var dy2 = p2.y - p0.y;
    var dz2 = p2.z - p0.z;

    var x = dy1 * dz2 - dz1 * dy2;
    var y = dz1 * dx2 - dx1 * dz2;
    var z = dx1 * dy2 - dy1 * dx2;

    return x * x + y * y + z * z;
};

FO.triangulate = function(face, newFaces, minArea) {
    if (face.numberOfVertices < 4) {
        return;
    }

    var v0 = face.halfEdge0.head;
    var prevFace = null;
    var hedge = face.halfEdge0.next;
    var oppPrev = hedge.opposite;
    var face0 = null;
    var newFace;

    for (hedge = hedge.next; hedge !== face.halfEdge0.previous; hedge = hedge.next) {
        newFace = FO.createTriangle(v0, hedge.previous.head, hedge.head, minArea);
        HEO.setOpposite(newFace.halfEdge0.next, oppPrev);
        HEO.setOpposite(newFace.halfEdge0.previous, hedge.opposite);
        oppPrev = newFace.halfEdge0;
        newFaces.push(newFace);
        if (face0 === null) {
            face0 = newFace;
        }
    }

    hedge = new HalfEdge(face.halfEdge0.previous.previous.head, face);
    HEO.setOpposite(hedge, oppPrev);

    hedge.previous = face.halfEdge0;
    hedge.previous.next = hedge;

    hedge.next = face.halfEdge0.previous;
    hedge.next.previous = hedge;

    FO.computeNormalAndCentroid(face, minArea);
    FO.checkConsistency(face);

    for (var f = face0; f !== null; f = f.next) {
        FO.checkConsistency(f);
    }
};

FO._computeNormalAndCentroid = function(face, minArea) {
    var numberOfVertices, halfEdge;

    FO.computeNormal(face, minArea);
    FO.computeCentroid(face);
    face.planeOffset = VectorOperations.scalproduct(face.normal, face.centroid);

    if (minArea !== void 0) {
        numberOfVertices = 0;
        halfEdge = face.halfEdge0;

        do {
            numberOfVertices++;
            halfEdge = halfEdge.next;
        } while (halfEdge !== face.halfEdge0);

        if (numberOfVertices !== face.numberOfVertices) {
            throw new Error('Face ' + FO.getVertexString(face) + ' should be ' + face.numberOfVertices);
        }
    }
};

FO._connectHalfEdges = function(face, hedgePrev, hedge) {
    var discardedFace = null,
        oppFace = HEO.oppositeFace(hedge),
        hedgeOpp;

    if (HEO.oppositeFace(hedgePrev) === oppFace) {
        if (hedgePrev === face.halfEdge0) {
            face.halfEdge0 = hedge;
        }

        if (oppFace.numberOfVertices === 3) {
            hedgeOpp = hedge.opposite.previous.opposite;
            oppFace.mark = FO.DELETED;
            discardedFace = oppFace;
        } else {
            hedgeOpp = hedge.opposite.next;

            if (oppFace.halfEdge0 === hedgeOpp.previous) {
                oppFace.halfEdge0 = hedgeOpp;
            }

            hedgeOpp.previous = hedgeOpp.previous.previous;
            hedgeOpp.previous.next = hedgeOpp;
        }

        hedge.previous = hedgePrev.previous;
        hedge.previous.next = hedge;

        hedge.opposite = hedgeOpp;
        hedgeOpp.opposite = hedge;

        FO._computeNormalAndCentroid(oppFace);
    } else {
        hedgePrev.next = hedge;
        hedge.previous = hedgePrev;
    }

    return discardedFace;
};

FO.create = function(vertices, indices) {
    var face = new Face(),
        hePrev = null;

    indices.forEach(function(index) {
        var he = new HalfEdge(vertices[index], face);

        if (hePrev !== null) {
            he.previous = hePrev;
            hePrev.next = he;
        } else {
            face.halfEdge0 = he;
        }

        hePrev = he;
    });

    face.halfEdge0.previous = hePrev;
    hePrev.next = face.halfEdge0;

    FO._computeNormalAndCentroid(face);

    return face;
};

FO.createTriangle = function(vertex0, vertex1, vertex2, minArea) {
    minArea = minArea || 0;

    var face = new Face(),
        halfEdge0 = new HalfEdge(vertex0, face),
        halfEdge1 = new HalfEdge(vertex1, face),
        halfEdge2 = new HalfEdge(vertex2, face);

    halfEdge0.previous = halfEdge2;
    halfEdge0.next = halfEdge1;

    halfEdge1.previous = halfEdge0;
    halfEdge1.next = halfEdge2;

    halfEdge2.previous = halfEdge1;
    halfEdge2.next = halfEdge0;

    face.halfEdge0 = halfEdge0;

    FO._computeNormalAndCentroid(face, minArea);

    return face;
};


text:
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs.Host.Loggers;
using Microsoft.Azure.WebJobs.Host.Protocols;

namespace Microsoft.Azure.WebJobs.Host.TestCommon
{
    public class NullFunctionInstanceLogger : IFunctionInstanceLogger
    {
        Task<string> IFunctionInstanceLogger.LogFunctionStartedAsync(FunctionStartedMessage message,
            CancellationToken cancellationToken)
        {
            return Task.FromResult(string.Empty);
        }

        Task IFunctionInstanceLogger.LogFunctionCompletedAsync(FunctionCompletedMessage message,
            CancellationToken cancellationToken)
        {
            return Task.FromResult(0);
        }

        Task IFunctionInstanceLogger.DeleteLogFunctionStartedAsync(string startedMessageId,
            CancellationToken cancellationToken)
        {
            return Task.FromResult(0);
        }
    }
}

redpajama_set_name: RedPajamaGithub


text:
<?php

namespace backend\controllers;

use backend\models\NewsletterForm;
use backend\utilities\BackendController;
use backend\utilities\SynchronizeFiles;
use common\models\EmailRecord;
use common\models\Newsletter;
use Yii;
use backend\models\NewsletterSearch;
use yii\db\Expression;
use yii\filters\AccessControl;
use yii\filters\VerbFilter;
use yii\helpers\Url;
use yii\web\NotFoundHttpException;

/**
 * NewsletterController implements the CRUD actions for Newsletter model.
 */
class NewsletterController extends BackendController
{
	/**
	 * @inheritdoc$
	 */
    public function behaviors()
    {
        return [
            'verbs' => [
                'class' => VerbFilter::className(),
                'actions' => [
                    'delete' => ['post'],
                ],
            ],
            'access' => [
	            'class' => AccessControl::className(),
	            'rules' => [
		            [
			            'actions' => ['view'],
			            'roles' => ['?'],
			            'allow' => true
		            ],
		            [
			            'roles' => ['user'],
			            'allow' => true
		            ]
	            ]
            ],
            'synchronize' => [
	            'class' => SynchronizeFiles::className(),
	            'only'  => [ 'create', 'update' ]
            ]
        ];
    }

    /**
     * Lists all Newsletter models.
     * @return mixed
     */
    public function actionIndex()
    {
        $searchModel = new NewsletterSearch();
        $dataProvider = $searchModel->search(Yii::$app->request->queryParams);

        return $this->render('index', compact('searchModel', 'dataProvider'));
    }

    /**
     * Creates a new Newsletter model.
     * If creation is successful, the browser will be redirected to the 'index' page.
     * @return mixed
     */
    public function actionCreate()
    {
        $model = new NewsletterForm();
	    $model->scenario = 'create';

        if ($model->load(Yii::$app->request->post()) && $model->validate()) {
	        $model->saveNewsletter();

	        $session = Yii::$app->session;
	        $session->setFlash('info', Yii::t('back', 'New page successfully added!'));

	        return $this->redirect(['index']);
        } else {
            return $this->render('create', compact('model'));
        }
    }

    /**
     * Updates an existing Newsletter model.
     * If update is successful, the browser will be redirected to the 'index' page.
     * @param integer $id
     * @return mixed
     */
    public function actionUpdate($id)
    {
        $model = new NewsletterForm($id);
        $model->scenario = 'update';

        if ($model->load(Yii::$app->request->post()) && $model->validate()) {
	        $model->saveNewsletter(false);

	        $session = Yii::$app->session;
	        $session->setFlash('info', Yii::t('back', 'Newsletter successfully updated!'));

	        return $this->redirect(['index']);
        } else {
            return $this->render('update', compact('model'));
        }
    }

    /**
     * Deletes an existing Newsletter model.
     * If deletion is successful, the browser will be redirected to the 'index' page.
     * @param integer $id
     * @return mixed
     */
    public function actionDelete($id)
    {
	    $model = new NewsletterForm($id);
	    $model->deleteNewsletter();

	    $session = Yii::$app->session;
	    $session->setFlash('info', Yii::t('back', 'Newsletter successfully deleted!'));

	    return $this->redirect(['index']);
    }

	public function actionView($id)
	{
		$model = Newsletter::findOne($id);
		if ($model) {
			$this->layout = '@backend/views/newsletter/layouts/' . $model->layout->filename;
			$viewMail = false;
			return $this->render('view', compact('model', 'viewMail'));
		} else {
			throw new NotFoundHttpException(Yii::t('back', 'The requested page does not exist.'));
		}
	}

	public function actionSend($id)
	{
		/** @var Newsletter $model */
		$model = Newsletter::findOne($id);
		if ($model) {
			$this->layout = '@backend/views/newsletter/layouts/' . $model->layout->filename;
			$viewMail = true;
			$htmlBody = $this->render('view', compact('model', 'viewMail'));
			$textBody = Yii::t('back', 'Dear user') . ",\n\n";
			$textBody .= Yii::t('back', 'we would send to you a pretty version of our newsletter. But your email client doesn\'t support it.') . "\n";
			$textBody .= Yii::t('back', 'Luckily you can see our newsletter at this link') . ": " . Url::to(['view', 'id' => $id], true) . "\n\n";
			$textBody .= Yii::t('back', 'Yours sincerely') . " " . Yii::$app->params['sendingEmailTitle'];

			$sendingEmail = Yii::$app->params['sendingEmail'];
			$targetEmailsChunks = array_chunk(EmailRecord::getActiveEmails(), Yii::$app->params['maxEmailsCount']);
			foreach ( $targetEmailsChunks as $targetEmailsChunk ) {
				Yii::$app->mailer->compose()
	                 ->setTo(Yii::$app->params['sendingEmail'])
	                 ->setBcc($targetEmailsChunk)
	                 ->setFrom([$sendingEmail => Yii::$app->params['sendingEmailTitle']])
	                 ->setSubject(Yii::$app->params['sendingEmailTitle'] . ' - ' . Yii::t('back', 'newsletter'))
	                 ->setTextBody($textBody)
	                 ->setHtmlBody($htmlBody)
	                 ->send();
			}

			$model->content_date = new Expression('DATE(NOW())');
			$model->content_time = new Expression('TIME(NOW())');
			$model->save(false);

			$session = Yii::$app->session;
			$session->setFlash('info', Yii::t('back', 'Newsletter successfuly sent!'));

			return $this->redirect(['index']);

		} else {
			throw new NotFoundHttpException(Yii::t('back', 'The requested page does not exist.'));
		}
	}
}


text:
package com.bogdan._4_multiple_locks;

import com.bogdan.common.Util;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * Created by zoomout on 11/21/16.
 */
class Worker {

    private Random random = new Random();
    private List<Integer> list1 = new ArrayList<>();
    private List<Integer> list2 = new ArrayList<>();
    private final Object lock1 = new Object();
    private final Object lock2 = new Object();

    private void stageOne() {
        Util.sleep(1);
        synchronized (lock1) {
            list1.add(random.nextInt(100));
        }
    }

    private void stageTwo() {
        Util.sleep(1);
        synchronized (lock2) {
            list2.add(random.nextInt(100));
        }
    }

    private void process() {
        for (int i = 0; i < 1000; i++) {
            stageOne();
            stageTwo();
        }
    }

    void main() {
        System.out.println("Starting...");
        long start = System.currentTimeMillis();
        Thread thread1 = new Thread(this::process);
        Thread thread2 = new Thread(this::process);
        thread1.start();
        thread2.start();
        try {
            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println("Time taken: " + (end - start));
        System.out.println("List1 size=" + list1.size() + "; List2 size=" + list2.size());
    }
}


text:
namespace Windows
{
namespace File
{
    FileSystemWatcherBase::FileSystemWatcherBase(FileSystemString const & dir,
        ::DWORD changeFlags,
        ::BOOL const watchSubDir,
        IFileSystemWatcher * const eventHandler,
        FileSystemString includeFilter,
        FileSystemString excludeFilter,
        std::vector<BYTE>::size_type const bufferSize) :
        _directoryInfo(dir, changeFlags, watchSubDir, eventHandler, includeFilter, excludeFilter),
        _terminate(false),
        BUFFER_SIZE(bufferSize > MAX_BUFFER_SIZE ? MAX_BUFFER_SIZE : bufferSize),
        _dirHandle(INVALID_HANDLE_VALUE),
        _eventThread(FileSystemWatcherBase::PopEventsProc),
        _popEvents(true),
        _isIncludeFilterActive(false),
        _isExcludeFilterActive(false),
        _includeFilters(),
        _excludeFilters(),
        _tmpOldFileName()
    {
        ResetOverlappedStructure();
        _buffer.resize(bufferSize);
        _backupBuffer.resize(bufferSize);
        //initialize filters
        InitializeFilters();
    }

    void FileSystemWatcherBase::BeginRead(::LPOVERLAPPED_COMPLETION_ROUTINE const notificationCallback, ::HANDLE const dirHandle)
    {
        ::DWORD dwBytes = 0U;
        // This call needs to be reissued after every APC.
        (void)::ReadDirectoryChangesW(  dirHandle,                           // handle to directory
                                        _buffer.data(),                      // read results buffer
                                        _buffer.size(),                      // length of buffer
                                        _directoryInfo._watchSubDirectories, // monitoring option
                                        _directoryInfo._changeFlags,         // filter conditions
                                        &dwBytes,                            // bytes returned
                                        &_overlapped,                        // overlapped buffer
                                        notificationCallback);               // completion routine
    }

    void FileSystemWatcherBase::DoPopEvents()
    {
        while (_popEvents)
        {
            ConqurrentQueue::value_type e;
            _eventQueue.wait_and_pop(e);
            ClassifyAndPostEvent(e);
        }
    }

    void FileSystemWatcherBase::InitializeFilters()
    {
        if(!_directoryInfo._includeFilter.empty())
        {
            _includeFilters.clear();
            _isIncludeFilterActive = ParseFilter(_directoryInfo._includeFilter, _includeFilters);
        }
        else
        {
            _isIncludeFilterActive = false;
        }
        if (!_directoryInfo._excludeFilter.empty())
        {
            _excludeFilters.clear();
            _isExcludeFilterActive = ParseFilter(_directoryInfo._excludeFilter, _excludeFilters);
        }
        else
        {
            _isExcludeFilterActive = false;
        }
    }

    bool FileSystemWatcherBase::ParseFilter(std::wstring const & filter, std::vector<std::wstring> & filters)const
    {
        auto start = 0U;
        auto end = filter.find(L";");
        while (end != std::wstring::npos)
        {
            filters.push_back(filter.substr(start, end - start));
            start = end + 1;
            end = filter.find(L";", start);
        }

        filters.push_back(filter.substr(start, end));

        return !filters.empty();
    }

    void FileSystemWatcherBase::SetIncludeFilter(IFileSystemWatcher::FileSystemString const & newInclusionFilter)
    {
        if (_directoryInfo._includeFilter != newInclusionFilter)
        {
            _directoryInfo._includeFilter = newInclusionFilter;
            InitializeFilters();
        }
    }

    void FileSystemWatcherBase::SetExcludeFilter(IFileSystemWatcher::FileSystemString const & newExclusionFilter)
    {
        if (_directoryInfo._excludeFilter != newExclusionFilter)
        {
            _directoryInfo._excludeFilter = newExclusionFilter;
            InitializeFilters();
        }
    }

    void FileSystemWatcherBase::ResetOverlappedStructure()
    {
        ::ZeroMemory(&_overlapped, sizeof(::OVERLAPPED));
        _overlapped.hEvent = this;
    }
} // namespace File
} // namespace Windows

#pragma managed(pop)


text:
symbol-tree
===========
[![Travis CI Build Status](https://api.travis-ci.org/jsdom/js-symbol-tree.svg?branch=master)](https://travis-ci.org/jsdom/js-symbol-tree) [![Coverage Status](https://coveralls.io/repos/github/jsdom/js-symbol-tree/badge.svg?branch=master)](https://coveralls.io/github/jsdom/js-symbol-tree?branch=master)

Turn any collection of objects into its own efficient tree or linked list using `Symbol`.

This library has been designed to provide an efficient backing data structure for DOM trees. You can also use this library as an efficient linked list. Any meta data is stored on your objects directly, which ensures any kind of insertion or deletion is performed in constant time. Because an ES6 `Symbol` is used, the meta data does not interfere with your object in any way.

Node.js 4+, io.js and modern browsers are supported.

Example
-------
A linked list:

```javascript
const SymbolTree = require('symbol-tree');
const tree = new SymbolTree();

let a = {foo: 'bar'}; // or `new Whatever()`
let b = {foo: 'baz'};
let c = {foo: 'qux'};

tree.insertBefore(b, a); // insert a before b
tree.insertAfter(b, c); // insert c after b

console.log(tree.nextSibling(a) === b);
console.log(tree.nextSibling(b) === c);
console.log(tree.previousSibling(c) === b);

tree.remove(b);
console.log(tree.nextSibling(a) === c);
```

A tree:

```javascript
const SymbolTree = require('symbol-tree');
const tree = new SymbolTree();

let parent = {};
let a = {};
let b = {};
let c = {};

tree.prependChild(parent, a); // insert a as the first child
tree.appendChild(parent,c ); // insert c as the last child
tree.insertAfter(a, b); // insert b after a, it now has the same parent as a

console.log(tree.firstChild(parent) === a);
console.log(tree.nextSibling(tree.firstChild(parent)) === b);
console.log(tree.lastChild(parent) === c);

let grandparent = {};
tree.prependChild(grandparent, parent);
console.log(tree.firstChild(tree.firstChild(grandparent)) === a);
```

See [api.md](api.md) for more documentation.

Testing
-------
Make sure you install the dependencies first:

    npm install

You can now run the unit tests by executing:

    npm test

The line and branch coverage should be 100%.

API Documentation
-----------------


text:
package models;

import java.util.List;
import java.util.Map;

public class FishCell extends Cell{

	public FishCell(int state, Map<String, Double> cellResources) {
		super(state, cellResources);
		myBreedingTime = cellResources.get("breedTime");

	}

	@Override
	public int getNextState(Map<Integer, List<Patch>> neighbors) {
		return 0;
	}

}


text:
/* TEMPLATE GENERATED TESTCASE FILE
Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_cpy_81_goodG2B.cpp
Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml
Template File: sources-sink-81_goodG2B.tmpl.cpp
*/
/*
 * @description
 * CWE: 122 Heap Based Buffer Overflow
 * BadSource:  Allocate memory for a string, but do not allocate space for NULL terminator
 * GoodSource: Allocate enough memory for a string and the NULL terminator
 * Sinks: cpy
 *    BadSink : Copy string to data using wcscpy()
 * Flow Variant: 81 Data flow: data passed in a parameter to an virtual method called via a reference
 *
 * */
#ifndef OMITGOOD

#include "std_testcase.h"
#include "CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_cpy_81.h"

namespace CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_cpy_81
{

void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_cpy_81_goodG2B::action(wchar_t * data) const
{
    {
        wchar_t source[10+1] = SRC_STRING;
        /* POTENTIAL FLAW: data may not have enough space to hold source */
        wcscpy(data, source);
        printWLine(data);
        free(data);
    }
}

}
#endif /* OMITGOOD */


text:
package com.mykumi.crawler4j.model;

public class OptionItem {
	private String optionValue;
	private String optionText;
	private float optionPrice;

	public String getOptionValue() {
		return optionValue;
	}
	public void setOptionValue(String optionValue) {
		this.optionValue = optionValue;
	}
	public String getOptionText() {
		return optionText;
	}
	public void setOptionText(String optionText) {
		this.optionText = optionText;
	}
	public float getOptionPrice() {
		return optionPrice;
	}
	public void setOptionPrice(float optionPrice) {
		this.optionPrice = optionPrice;
	}
}


text:
/**
 * CPromotionGift.java	2010/07/26
 */

package com.ycsoft.beans.core.promotion;

import java.io.Serializable;

import com.ycsoft.daos.config.POJO;

/**
 * CPromotionGift -> C_PROMOTION_GIFT mapping
 */
@POJO(tn = "C_PROMOTION_GIFT", sn = "", pk = "")
public class CPromotionGift implements Serializable {

	// CPromotionGift all properties

	/**
	 *
	 */
	private static final long serialVersionUID = -6179908271168765350L;
	private String promotion_sn;
	private String gift_type;
	private Integer amount;
	private Integer money;
	private String area_id;
	private String county_id;

	/**
	 * default empty constructor
	 */
	public CPromotionGift() {
	}

	// promotion_sn getter and setter
	public String getPromotion_sn() {
		return promotion_sn;
	}

	public void setPromotion_sn(String promotion_sn) {
		this.promotion_sn = promotion_sn;
	}

	// gift_type getter and setter
	public String getGift_type() {
		return gift_type;
	}

	public void setGift_type(String gift_type) {
		this.gift_type = gift_type;
	}

	// amount getter and setter
	public Integer getAmount() {
		return amount;
	}

	public void setAmount(Integer amount) {
		this.amount = amount;
	}

	// money getter and setter
	public Integer getMoney() {
		return money;
	}

	public void setMoney(Integer money) {
		this.money = money;
	}

	// area_id getter and setter
	public String getArea_id() {
		return area_id;
	}

	public void setArea_id(String area_id) {
		this.area_id = area_id;
	}

	// county_id getter and setter
	public String getCounty_id() {
		return county_id;
	}

	public void setCounty_id(String county_id) {
		this.county_id = county_id;
	}

}


text:
from __future__ import absolute_import

def get_package_data():
    return {'hstphot.example_subpkg': ['data/*']}


text:
import React from 'react'
import { Route, IndexRoute } from 'react-router'

import { Index as IndexN, Show as ShowN } from './Notice'
import Layout from '../Layout'

const Widget = (
      <Route path='/'>
        <IndexRoute component={IndexN}/>
        <Route path="notices" component={IndexN}/>
        <Route path="notices/:id" component={ShowN}/>
      </Route>
);

export default Widget;


text:
namespace webkit_database {

const char DatabaseUtil::kJournalFileSuffix[] = "-journal";

bool DatabaseUtil::CrackVfsFileName(const string16& vfs_file_name,
                                    string16* origin_identifier,
                                    string16* database_name,
                                    string16* sqlite_suffix) {
  // 'vfs_file_name' is of the form <origin_identifier>/<db_name>#<suffix>.
  // <suffix> is optional.
  DCHECK(!vfs_file_name.empty());
  size_t first_slash_index = vfs_file_name.find('/');
  size_t last_pound_index = vfs_file_name.rfind('#');
  // '/' and '#' must be present in the string. Also, the string cannot start
  // with a '/' (origin_identifier cannot be empty) and '/' must come before '#'
  if ((first_slash_index == string16::npos) ||
      (last_pound_index == string16::npos) ||
      (first_slash_index == 0) ||
      (first_slash_index > last_pound_index)) {
    return false;
  }

  if (origin_identifier)
    *origin_identifier = vfs_file_name.substr(0, first_slash_index);
  if (database_name) {
    *database_name = vfs_file_name.substr(
        first_slash_index + 1, last_pound_index - first_slash_index - 1);
  }
  if (sqlite_suffix) {
    *sqlite_suffix = vfs_file_name.substr(
        last_pound_index + 1, vfs_file_name.length() - last_pound_index - 1);
  }
  return true;
}

FilePath DatabaseUtil::GetFullFilePathForVfsFile(
    DatabaseTracker* db_tracker, const string16& vfs_file_name) {
  string16 origin_identifier;
  string16 database_name;
  string16 sqlite_suffix;
  if (!CrackVfsFileName(vfs_file_name, &origin_identifier,
                        &database_name, &sqlite_suffix)) {
    return FilePath(); // invalid vfs_file_name
  }

  FilePath full_path = db_tracker->GetFullDBFilePath(
      origin_identifier, database_name);
  if (!full_path.empty() && !sqlite_suffix.empty()) {
    DCHECK(full_path.Extension().empty());
    full_path = full_path.InsertBeforeExtensionASCII(
        UTF16ToASCII(sqlite_suffix));
  }
  // Watch out for directory traversal attempts from a compromised renderer.
  if (full_path.value().find(FILE_PATH_LITERAL("..")) !=
          FilePath::StringType::npos)
    return FilePath();
  return full_path;
}

string16 DatabaseUtil::GetOriginIdentifier(const GURL& url) {
  string16 spec = UTF8ToUTF16(url.spec());
  return WebKit::WebSecurityOrigin::createFromString(spec).databaseIdentifier();
}

GURL DatabaseUtil::GetOriginFromIdentifier(const string16& origin_identifier) {
  WebKit::WebSecurityOrigin web_security_origin =
      WebKit::WebSecurityOrigin::createFromDatabaseIdentifier(
          origin_identifier);

  // We need this work-around for file:/// URIs as
  // createFromDatabaseIdentifier returns null origin_url for them.
  if (web_security_origin.isUnique()) {
    if (origin_identifier.find(UTF8ToUTF16("file__")) == 0)
      return GURL("file:///");
    return GURL();
  }

  return GURL(web_security_origin.toString());
}

}  // namespace webkit_database


text:
package cluster

import (
	"errors"

	"github.com/youzan/ZanRedisDB/common"
)

var (
	ErrKeyAlreadyExist           = errors.New("Key already exist")
	ErrKeyNotFound               = errors.New("Key not found")
	ErrLearnerRoleInvalidChanged = errors.New("node learner role should never be changed")
	ErrLearnerRoleUnsupported    = errors.New("node learner role is not supported")
	DCInfoTag                    = "dc_info"
)

type EpochType int64

type NodeInfo struct {
	RegID             uint64
	ID                string
	NodeIP            string
	Hostname          string
	RedisPort         string
	HttpPort          string
	RpcPort           string
	RaftTransportAddr string
	Version           string
	Tags              map[string]interface{}
	DataRoot          string
	RsyncModule       string
	LearnerRole       string
	epoch             EpochType
}

func (self *NodeInfo) GetID() string {
	return self.ID
}

func (self *NodeInfo) Epoch() EpochType {
	return self.epoch
}

func (self *NodeInfo) GetRegisterID() uint64 {
	return self.RegID
}

type ClusterMetaInfo struct {
	MaxGID   int64
	MaxRegID uint64
}

type NamespaceMetaInfo struct {
	PartitionNum int
	Replica      int
	// to verify the data of the create -> delete -> create with same namespace
	MagicCode        int64
	MinGID           int64
	metaEpoch        EpochType
	EngType          string
	OptimizedFsync   bool
	SnapCount        int
	Tags             map[string]interface{}
	ExpirationPolicy string
	DataVersion      string
}

func (self *NamespaceMetaInfo) MetaEpoch() EpochType {
	return self.metaEpoch
}

func (self *NamespaceMetaInfo) DeepClone() NamespaceMetaInfo {
	nm := *self
	nm.Tags = make(map[string]interface{})
	for k, v := range self.Tags {
		nm.Tags[k] = v
	}
	return nm
}

type RemovingInfo struct {
	RemoveTime      int64
	RemoveReplicaID uint64
}

type PartitionReplicaInfo struct {
	RaftNodes    []string
	RaftIDs      map[string]uint64
	Removings    map[string]RemovingInfo
	MaxRaftID    int64
	LearnerNodes map[string][]string
	epoch        EpochType
}

func (self *PartitionReplicaInfo) IsLearner(nid string) bool {
	for _, lrns := range self.LearnerNodes {
		for _, n := range lrns {
			if n == nid {
				return true
			}
		}
	}
	return false
}

func (self *PartitionReplicaInfo) GetISR() []string {
	if len(self.Removings) == 0 {
		return self.RaftNodes
	}
	isr := make([]string, 0, len(self.RaftNodes))
	for _, v := range self.RaftNodes {
		if _, ok := self.Removings[v]; ok {
			continue
		}
		isr = append(isr, v)
	}
	return isr
}

func (self *PartitionReplicaInfo) Epoch() EpochType {
	return self.epoch
}

func (self *PartitionReplicaInfo) DeepClone() PartitionReplicaInfo {
	tmp := PartitionReplicaInfo{
		RaftNodes:    make([]string, len(self.RaftNodes)),
		RaftIDs:      make(map[string]uint64),
		Removings:    make(map[string]RemovingInfo),
		MaxRaftID:    self.MaxRaftID,
		LearnerNodes: make(map[string][]string),
		epoch:        self.epoch,
	}
	copy(tmp.RaftNodes, self.RaftNodes)
	for k, v := range self.RaftIDs {
		tmp.RaftIDs[k] = v
	}
	for k, v := range self.Removings {
		tmp.Removings[k] = v
	}
	for k, v := range self.LearnerNodes {
		ln := make([]string, len(v))
		copy(ln, v)
		tmp.LearnerNodes[k] = ln
	}
	return tmp
}

type RealLeader struct {
	Leader string
	epoch  EpochType
}

type PartitionMetaInfo struct {
	Name          string
	Partition     int
	currentLeader RealLeader
	NamespaceMetaInfo
	PartitionReplicaInfo
}

func (self *PartitionMetaInfo) IsISRQuorum() bool {
	return len(self.GetISR()) > self.Replica/2
}

func (self *PartitionMetaInfo) GetRealLeader() string {
	return self.currentLeader.Leader
}

func (self *PartitionMetaInfo) GetCopy() *PartitionMetaInfo {
	newp := *self

	newp.PartitionReplicaInfo = self.PartitionReplicaInfo.DeepClone()
	newp.NamespaceMetaInfo = self.NamespaceMetaInfo.DeepClone()

	return &newp
}

func (self *PartitionMetaInfo) GetDesp() string {
	return common.GetNsDesp(self.Name, self.Partition)
}

type ConsistentStore interface {
	WriteKey(key, value string) error
	ReadKey(key string) (string, error)
	ListKey(key string) ([]string, error)
}

type SchemaInfo struct {
	Schema []byte
	Epoch  EpochType
}

type Register interface {
	InitClusterID(id string)
	Start()
	// all registered pd nodes.
	GetAllPDNodes() ([]NodeInfo, error)
	// should return both the meta info for namespace and the replica info for partition
	// epoch should be updated while return
	GetNamespacePartInfo(ns string, partition int) (*PartitionMetaInfo, error)
	// get directly from register without cache
	GetRemoteNamespaceReplicaInfo(ns string, partition int) (*PartitionReplicaInfo, error)
	// get  meta info only
	GetNamespaceMetaInfo(ns string) (NamespaceMetaInfo, error)
	GetNamespaceInfo(ns string) ([]PartitionMetaInfo, error)
	GetAllNamespaces() (map[string]map[int]PartitionMetaInfo, EpochType, error)
	GetNamespacesNotifyChan() chan struct{}
	GetNamespaceSchemas(ns string) (map[string]SchemaInfo, error)
	GetNamespaceTableSchema(ns string, table string) (*SchemaInfo, error)
	// the saved key should have the node info prefix to avoid conflict with each other data node
	// if it is designed to shared between data node, should use carefully with concurrent modify
	// note: the data key will be under the cluster root data path
	SaveKV(key string, value string) error
	GetKV(key string) (string, error)
	Stop()
}

// We need check leader before do any modify to etcd.
// Make sure all returned value should be copied to avoid modify by outside.
type PDRegister interface {
	Register
	Register(nodeData *NodeInfo) error // update
	Unregister(nodeData *NodeInfo) error
	// the cluster root modify index
	GetClusterEpoch() (EpochType, error)
	GetClusterMetaInfo() (ClusterMetaInfo, error)
	AcquireAndWatchLeader(leader chan *NodeInfo, stop chan struct{})

	GetDataNodes() ([]NodeInfo, error)
	// watching the cluster data node, should return the newest for the first time.
	WatchDataNodes(nodeC chan []NodeInfo, stopC chan struct{})
	// create and write the meta info to meta node
	CreateNamespace(ns string, meta *NamespaceMetaInfo) error
	UpdateNamespaceMetaInfo(ns string, meta *NamespaceMetaInfo, oldGen EpochType) error
	// create partition path
	CreateNamespacePartition(ns string, partition int) error
	IsExistNamespace(ns string) (bool, error)
	IsExistNamespacePartition(ns string, partition int) (bool, error)
	DeleteNamespacePart(ns string, partition int) error
	DeleteWholeNamespace(ns string) error
	//
	// update the replica info about replica node list, epoch for partition
	// Note: update should do check-and-set to avoid unexpected override.
	// the epoch in replicaInfo should be updated to the new epoch
	// if no partition, replica info node should create only once.
	UpdateNamespacePartReplicaInfo(ns string, partition int, replicaInfo *PartitionReplicaInfo, oldGen EpochType) error
	PrepareNamespaceMinGID() (int64, error)
	UpdateNamespaceSchema(ns string, table string, schema *SchemaInfo) error
}

type DataNodeRegister interface {
	Register
	// check the learner role before register, should never change the role
	Register(nodeData *NodeInfo) error // update
	Unregister(nodeData *NodeInfo) error
	// get the newest pd leader and watch the change of it.
	WatchPDLeader(leader chan *NodeInfo, stop chan struct{}) error
	GetNodeInfo(nid string) (NodeInfo, error)
	// while losing leader, update to empty nid
	// while became the new leader, update to my node
	UpdateNamespaceLeader(ns string, partition int, rl RealLeader, oldGen EpochType) (EpochType, error)
	GetNamespaceLeader(ns string, partition int) (string, EpochType, error)
	NewRegisterNodeID() (uint64, error)
}


text:
<?php

namespace app\form;

use Yii;
use yii\base\Model;
use app\models\ar\Manga;
use yii\data\ActiveDataProvider;

/**
 * ContactForm is the model behind the contact form.
 */
class FilterForm extends Model
{
    const YEAR_FROM = 1990;

    const SORT_VIEWS = 'views';
    const SORT_CREATED = 'created';
    const SORT_CHAPTERS = 'chapters';

    public $genres = [];
    public $declined_genres = [];
    public $author_id;
    public $is_finished = Manga\Model::IS_FINISHED_UNKNOWN;
    public $year_from;
    public $year_to;
    public $name;

    public $sort = self::SORT_VIEWS;

    /**
     * @return array the validation rules.
     */
    public function rules()
    {
        return [
            [['genres','declined_genres'], 'each','rule'=>['integer']],
            ['author_id', 'integer'],
            ['name', 'string', 'max' => 60,'min'=>3],
            ['is_finished', 'in','range'=>[Manga\Model::IS_FINISHED_UNKNOWN,Manga\Model::IS_FINISHED_YES,Manga\Model::IS_FINISHED_NO]],
            [['year_from','year_to'], 'integer','min'=>self::YEAR_FROM,'max'=>date('Y')],
        ];
    }

    /**
     * @return array customized attribute labels
     */
    public function attributeLabels()
    {
        return [
            'genres' => 'Жанры',
            'declined_genres' => 'Исключающие жанры',
            'author_id' => 'Автор',
            'is_finished' => 'Выпуск',
            'year_from' => 'Выпуск с года',
            'year_to' => 'Выпуск до года',
            'name' => 'Содержит',
        ];
    }

    public function getProvider() {
        $query = Manga\Model::find()->
            excludeHidden()->
            joinWith('mangaHasGenres')->
            groupBy('manga.manga_id');
        $genres = (is_array($this->genres) ? $this->genres : []);
        foreach ($genres as $genreId) {
            $query->andHaving('find_in_set('.intval($genreId).',group_concat(manga_has_genre.genre_id))>0');
        }
        $declinedGenres = (is_array($this->declined_genres) ? $this->declined_genres : []);
        foreach ($declinedGenres as $genreId) {
            $query->andHaving('find_in_set('.intval($genreId).',group_concat(manga_has_genre.genre_id))=0');
        }
        if ($this->author_id) {
            $query->andWhere('manga.author_id='.intval($this->author_id));
        }
        if ($this->is_finished == Manga\Model::IS_FINISHED_YES) {
            $query->andWhere('manga.is_finished="'.Manga\Model::IS_FINISHED_YES.'"');
        } else if ($this->is_finished == Manga\Model::IS_FINISHED_NO) {
            $query->andWhere('manga.is_finished="'.Manga\Model::IS_FINISHED_NO.'"');
        }
        if ($this->year_from) {
            $query->andWhere('manga.created>='.intval($this->year_from));
        }
        if ($this->year_to) {
            $query->andWhere('manga.created<='.intval($this->year_to));
        }
        if ($this->name) {
            $query->andWhere(
                [
                    'or',
                    'manga.title like :name',
                    'manga.english_title like :name',
                    'manga.original_title like :name'
                ],
                [':name'=>$this->name.'%']
            );
        }
        switch ($this->sort) {
            case self::SORT_VIEWS:
                $query->orderBy('manga.views desc');
                break;
            case self::SORT_CREATED:
                $query->orderBy('manga.created desc');
                break;

        }
        return new ActiveDataProvider([
            'query' => $query,
        ]);
    }
}


text:
<?php
namespace webvimark\components;

use webvimark\helpers\LittleBigHelper;
use webvimark\helpers\Singleton;
use webvimark\image\Image;
use yii\db\ActiveRecord;
use Yii;
use yii\db\Query;
use yii\helpers\FileHelper;
use yii\helpers\StringHelper;
use yii\validators\Validator;
use yii\web\NotFoundHttpException;
use yii\web\UploadedFile;

class BaseActiveRecord extends ActiveRecord
{
	// ================= Timestamps config starts =================

	/**
	 * Replacement of the TimestampBehavior
	 *
	 * @var bool
	 */
	protected $_timestamp_enabled = false;

	/**
	 * Replacement of the TimestampBehavior
	 *
	 * @var array
	 */
	protected $_timestamp_attributes = [
		'create_attribute'  => 'created_at',
		'update_attribute'  => 'updated_at',
	];

	// ----------------- Timestamps config ends -----------------

	// ================= Multilingual config starts =================

	protected $_i18n_enabled = false;

	/**
	 * @var array
	 */
	protected $_i18n_attributes = [];

	/**
	 * @var array
	 */
	protected $_i18n_admin_routes = [];

	/**
	 * @var string
	 */
	protected $_i18n_table = 'ml_translations';

	// ----------------- Multilingual config ends -----------------

	/**
	 * "thumbDir"=>["dimensions"]
	 * If "dimensions" is not array, then image will be saved without resizing (in original size)
	 *
	 * @var array
	 */
	public $thumbs = [
		'full'   => null,
		'medium' => [300, 300],
		'small'  => [50, 50]
	];

	/**
	 * @inheritdoc
	 */
	public function __set($name, $value)
	{
		if ( $this->_i18n_enabled && in_array($name, $this->_getI18NAttributes()) )
			$this->$name = $value;
		else
			parent::__set($name, $value);
	}

	/**
	 * @inheritdoc
	 */
	public function attributes()
	{
		if ( $this->_i18n_enabled )
		{
			return array_merge(parent::attributes(), $this->_getI18NAttributes());
		}

		return parent::attributes();
	}

	public function init()
	{
		parent::init();

		$this->_I18NInitialization();
	}

	/**
	 * TimestampBehavior replacement
	 */
	protected function _timeStampBehavior()
	{
		if ( $this->_timestamp_enabled )
		{
			$this->{$this->_timestamp_attributes['update_attribute']} = time();

			if ( $this->isNewRecord )
			{
				$this->{$this->_timestamp_attributes['create_attribute']} = time();
			}
		}
	}

	// ================= I18N methods starts here =================

	/**
	 * @param boolean $insert
	 */
	private function _preventI18NOverwritingInNonAdminRoutes($insert)
	{
		if ( $this->_i18n_enabled && !$insert && !in_array(Yii::$app->requestedRoute, $this->_i18n_admin_routes) )
		{
			foreach ($this->_i18n_attributes as $i18nAttribute)
			{
				if ( isset($this->oldAttributes[$i18nAttribute]) )
				{

				}
			}

		}
	}

	/**
	 * Create string validators for virtual i18n attributes (like name_ru)
	 */
	private function _I18NInitialization()
	{
		if ( $this->_i18n_enabled )
		{
			$singletonKey = 'i18n_initialize' . get_class($this);

			$initialized = Singleton::getData($singletonKey);

			if ( !$initialized )
			{
				// Remove unnecessary "/" from admin routes
				array_walk($this->_i18n_admin_routes, function(&$val, $key) {
					$val = trim($val, '/');
				});

				foreach ($this->_getI18NAttributes() as $attribute)
				{
					$validators = $this->getActiveValidators($attribute);

					if ( empty($validators) )
					{
						$this->getValidators()
							->append(Validator::createValidator('string', $this, $attribute));
					}
				}

				Singleton::setData($singletonKey, true);
			}
		}
	}

	/**
	 * @param boolean $insert
	 */
	private function _saveI18NAttributes($insert)
	{
		if ( $this->_i18n_enabled )
		{
			foreach ($this->_getI18NAttributes() as $attribute)
			{
				if ( isset($this->$attribute) AND $this->$attribute !== null)
				{
					$tmp = explode('_', $attribute);

					$language = array_pop($tmp);

					$originalAttribute = implode('_', $tmp);

					// Update I18N attribute only if current route is in admin routes
					if ( !$insert )
					{
						$oldValue = (new Query())
							->select('value')
							->from($this->_i18n_table)
							->where([
								'table_name' => $this->getTableSchema()->fullName,
								'model_id'   => $this->primaryKey,
								'attribute'  => $originalAttribute,
								'lang'       => $language,
							])
							->limit(1)
							->scalar();

						if ( $oldValue === false AND $this->$attribute !== '' )
						{
							$this->_i18nInsertHelper($originalAttribute, $language, $attribute);
						}
						elseif ( $oldValue != $this->$attribute )
						{
							$this->_i18nUpdateHelper($originalAttribute, $language, $attribute);
						}
					}
					elseif ( $this->$attribute !== '' ) // Insert only non empty values
					{
						$this->_i18nInsertHelper($originalAttribute, $language, $attribute);
					}
				}
			}
		}
	}

	private function _i18nInsertHelper($originalAttribute, $language, $attribute)
	{
		$this->getDb()->createCommand()
			->insert($this->_i18n_table, [
				'table_name' => $this->getTableSchema()->fullName,
				'attribute'  => $originalAttribute,
				'model_id'   => $this->primaryKey,
				'lang'       => $language,
				'value'      => $this->$attribute,
			])
			->execute();
	}
	private function _i18nUpdateHelper($originalAttribute, $language, $attribute)
	{
		$this->getDb()->createCommand()
			->update($this->_i18n_table, ['value'=>$this->$attribute], [
				'table_name' => $this->getTableSchema()->fullName,
				'attribute'  => $originalAttribute,
				'model_id'   => $this->primaryKey,
				'lang'       => $language,
			])
			->execute();
	}

	/**
	 * Delete translated attributes
	 */
	private function _deleteI18NAttributes()
	{
		if ( $this->_i18n_enabled )
		{
			$this->getDb()->createCommand()
				->delete($this->_i18n_table, [
					'table_name' => $this->getTableSchema()->fullName,
					'model_id'   => $this->primaryKey,
				])
				->execute();
		}
	}

	private function _findI18NAttributes()
	{
		if ( $this->_i18n_enabled )
		{
			if ( in_array(Yii::$app->requestedRoute, $this->_i18n_admin_routes) )
			{
				$translations = $this->mlGetTranslations();

				$replaceOriginalAttributes = false;
			}
			else
			{
				$translations = $this->mlGetLanguageSpecificTranslations();

				$replaceOriginalAttributes = Yii::$app->language !== Yii::$app->params['mlConfig']['default_language'];
			}

			foreach ($translations as $translate)
			{
				if ( $this->primaryKey == $translate['model_id'] )
				{
					if ( $replaceOriginalAttributes )
					{
						if ( $translate['lang'] == Yii::$app->language )
						{
							$this->{$translate['attribute']} = $translate['value'];
						}
					}
					elseif ( isset(Yii::$app->params['mlConfig']['languages'][$translate['lang']]) )
					{
						$attribute = $translate['attribute'] . '_' . $translate['lang'];

						$this->$attribute = $translate['value'];
					}
				}
			}
		}
	}

	/**
	 * @return array
	 */
	private function mlGetTranslations()
	{
		$values = Singleton::getData('_ml_' . $this->getTableSchema()->fullName);

		if ( $values === false )
		{
			$values = (new Query())
				->select(['model_id', 'attribute', 'value', 'lang'])
				->from($this->_i18n_table)
				->where([
					'table_name' => $this->getTableSchema()->fullName,
				])
				->all();

			Singleton::setData('_ml_' . $this->getTableSchema()->fullName, $values);
		}

		return $values;
	}

	/**
	 * @param null|string $language
	 *
	 * @return array
	 */
	private function mlGetLanguageSpecificTranslations($language = null)
	{
		if ( !$language )
			$language = Yii::$app->language;

		$values = Singleton::getData('_ml_' . $this->getTableSchema()->fullName . '_' . $language);

		if ( $values === false )
		{
			$values = (new Query())
				->select(['model_id', 'attribute', 'value', 'lang'])
				->from($this->_i18n_table)
				->where([
					'table_name' => $this->getTableSchema()->fullName,
					'lang'       => $language,
				])
				->all();

			Singleton::setData('_ml_' . $this->getTableSchema()->fullName . '_' . $language, $values);
		}

		return $values;
	}

	/**
	 * @return array
	 */
	private function _getI18NAttributes()
	{
		$singletonKey = '_mlAttributes_' . get_class($this);

		$mlAttributes = Singleton::getData($singletonKey);

		if ( $mlAttributes === false )
		{
			$mlAttributes = [];

			$languages = Yii::$app->params['mlConfig']['languages'];
//			unset($languages[Yii::$app->params['mlConfig']['default_language']]);

			foreach ($languages as $languageCode => $languageName)
			{
				foreach ($this->_i18n_attributes as $attribute)
				{
					$mlAttributes[] = $attribute . '_' . $languageCode;
				}
			}

			Singleton::setData($singletonKey, $mlAttributes);
		}

		return $mlAttributes;
	}

	// ----------------- I18N methods ends here -----------------

	/**
	 * @param mixed $condition
	 *
	 * @return bool
	 */
	public static function deleteIfExists($condition)
	{
		$model = static::findOne($condition);

		if ( $model )
		{
			$model->delete();
			return true;
		}

		return false;
	}

	/**
	 * Finds the model based on its primary key value.
	 * If the model is not found, a 404 HTTP exception will be thrown.
	 *
	 * @param mixed $condition
	 *
	 * @return static the loaded model
	 * @throws NotFoundHttpException if the model cannot be found
	 */
	public static function findOneOrException($condition)
	{
		if ( ($model = static::findOne($condition)) !== null )
		{
			return $model;
		}
		else
		{
			throw new NotFoundHttpException(Yii::t('yii', 'Page not found.'));
		}
	}

	/**
	 * getUploadDir
	 *
	 * + Создаёт директории, если их нет
	 *
	 * @return string
	 */
	public function getUploadDir()
	{
		return Yii::getAlias('@webroot') . '/images/' . trim($this->tableName(), '{}%');
	}

	/**
	 * saveImage
	 *
	 * @param UploadedFile $file
	 * @param string        $imageName
	 */
	public function saveImage($file, $imageName)
	{
		if ( ! $file )
			return;

		$uploadDir = $this->getUploadDir();

		$this->prepareUploadDir($uploadDir);

		if ( is_array($this->thumbs) AND !empty($this->thumbs) )
		{

			foreach ($this->thumbs as $dir => $size)
			{
				$img = Image::factory($file->tempName);

				// If $size is array of dimensions - resize, else - just save
				if ( is_array($size) )
					$img->resize(implode(',', $size))->save($uploadDir . '/'. $dir . '/' . $imageName);
				else
					$img->save($uploadDir . '/'. $dir . '/' . $imageName);
			}

			@unlink($file->tempName);
		}
		else
		{
			$file->saveAs($uploadDir . '/' . $imageName);

		}
	}

	/**
	 * Delete image from all directories
	 *
	 * @param string $image
	 */
	public function deleteImage($image)
	{
		$uploadDir = $this->getUploadDir();

		if ( is_array($this->thumbs) AND !empty($this->thumbs) )
		{
			foreach (array_keys($this->thumbs) as $thumbDir)
				@unlink($uploadDir.'/'.$thumbDir.'/'.$image);
		}
		else
		{
			@unlink($uploadDir.'/'.$image);
		}

		// Delete all cropped images from this object
		if ( is_dir($uploadDir . '/_cropped') )
		{
			$croppedImages = FileHelper::findFiles($uploadDir.'/_cropped', [
				'only'   => ['*_|_' . $image],
			]);

			foreach ($croppedImages as $croppedImage)
			{
				@unlink($croppedImage);
			}
		}
	}

	/**
	 * Provide array of image fields (like: ['logo', 'image'])
	 * then $model->$imageField will be deleted from all thumb directories (or main dir if there are no thumbs)
	 *
	 * @param array $imageFields
	 */
	public function bulkDeleteImages($imageFields)
	{
		foreach ($imageFields as $imageField)
		{
			$this->deleteImage($this->$imageField);
		}
	}

	/**
	 * getImageUrl
	 *
	 * @param string|null $dir
	 * @param string $attr
	 * @return string
	 */
	public function getImageUrl($dir = 'full', $attr = 'image')
	{
		if ( $dir )
			return Yii::$app->request->baseUrl . '/images/'.trim($this->tableName(), '{}%')."/{$dir}/".$this->{$attr};
		else
			return Yii::$app->request->baseUrl . '/images/'.trim($this->tableName(), '{}%').'/'.$this->{$attr};
	}

	/**
	 * getImagePath
	 *
	 * @param string|null $dir
	 * @param string $attr
	 * @return string
	 */
	public function getImagePath($dir = 'full', $attr = 'image')
	{
		if ( $dir )
			return $this->getUploadDir() . "/{$dir}/".$this->{$attr};
		else
			return $this->getUploadDir() . '/'.$this->{$attr};
	}

	/**
	 * @param integer $width
	 * @param integer $height
	 * @param string  $attr
	 *
	 * @return string
	 */
	public function getCroppedImagePath($width, $height, $attr = 'image')
	{
		$dir = $this->getUploadDir() . '/_cropped';

		if (! is_dir($dir))
		{
			mkdir($dir, 0777, true);
			chmod($dir, 0777);
		}

		return $dir . '/' . $width . '_' . $height . '_|_' . $this->{$attr};
	}

	/**
	 * @param integer       $width
	 * @param integer     $height
	 * @param string $dir
	 * @param string $attr
	 *
	 * @return string
	 */
	public function getCroppedImage($width, $height, $dir = 'full', $attr = 'image')
	{
		if ( !is_file($this->getCroppedImagePath($width, $height, $attr)) && is_file($this->getImagePath($dir, $attr)) )
		{
			$image = Image::factory($this->getImagePath($dir, $attr));

			$old_aspect = $image->width / $image->height;
			$new_aspect = $width / $height;

			if ($old_aspect == 1)
			{
				if ($width > $height)
				{
					$image->resize($width, $height, Image::WIDTH);
				}
				else
				{
					$image->resize($width, $height, Image::HEIGHT);
				}
			}
			elseif ($old_aspect < $new_aspect)
			{
				$image->resize($width, $height, Image::WIDTH);
			}
			else
			{
				$image->resize($width, $height, Image::HEIGHT);
			}

			$image->crop($width, $height);
			$image->save($this->getCroppedImagePath($width, $height, $attr));
		}

		return Yii::$app->request->baseUrl . '/images/' . trim($this->tableName(), '{}%') . '/_cropped/' .  $width . '_' . $height . '_|_' . $this->{$attr};
	}

	//=========== Rules ===========

	public function purgeXSS($attr)
	{
		$this->$attr = htmlspecialchars($this->$attr, ENT_QUOTES);
	}

	//----------- Rules -----------

	/**
	 * prepareUploadDir
	 *
	 * @param string $dir
	 */
	public function prepareUploadDir($dir)
	{
		if (! is_dir($dir))
		{
			mkdir($dir, 0777, true);
			chmod($dir, 0777);
		}

		// Если нужны папки с thumbs
		if ( is_array($this->thumbs) AND !empty($this->thumbs) )
		{
			foreach (array_keys($this->thumbs) as $thumbDir)
			{
				if (! is_dir($dir.'/'.$thumbDir))
				{
					mkdir($dir.'/'.$thumbDir, 0777, true);
					chmod($dir.'/'.$thumbDir, 0777);
				}
			}
		}
	}

	/**
	 * @param UploadedFile $file
	 *
	 * @return string
	 */
	public function generateFileName($file)
	{
		return uniqid() . '_' . LittleBigHelper::slug($file->baseName, '_') . '.' . $file->extension;
	}

	/**
	 * Check if some attributes uploaded via fileInput field
	 * and assign them with UploadedFile
	 *
	 * @inheritdoc
	 */
	public function setAttributes($values, $safeOnly = true)
	{
		parent::setAttributes($values, $safeOnly);

		// Looking only for file attributes (and fix null error on fly)
		if ( is_array($values) )
		{
			$attributes = array_flip($safeOnly ? $this->safeAttributes() : $this->attributes());

			$class = StringHelper::basename(get_called_class());

			foreach ($values as $name => $value)
			{
				if ( isset( $attributes[$name] ) )
				{
					if ( isset($_FILES[$class]['name'][$name]) )
					{
						$uploadedFile = UploadedFile::getInstance($this, $name);

						if ( $uploadedFile )
						{
							$this->$name = $uploadedFile;
						}
						elseif ( ! $this->isNewRecord )
						{
							$this->$name = $this->oldAttributes[$name];
						}
					}
				}
			}
		}
	}

	// ================= Events =================

	/**
	 * @inheritdoc
	 */
	public function beforeSave($insert)
	{
		if ( parent::beforeSave($insert) )
		{
			$this->_timeStampBehavior();

//			$this->_preventI18NOverwritingInNonAdminRoutes($insert);

			foreach ($this->attributes as $name => $val)
			{
				if ( $val instanceof UploadedFile )
				{
					if ( $val->name AND !$val->hasError )
					{
						$fileName = $this->generateFileName($val);

						if ( !$this->isNewRecord )
						{
							$this->deleteImage($this->oldAttributes[$name]);
						}

						$this->saveImage($val, $fileName);

						$this->$name = $fileName;
					}
					elseif ( !$this->isNewRecord )
					{
						$this->$name = $this->oldAttributes[$name];
					}
				}
			}

			return true;
		}

		return false;
	}

	/**
	 * @inheritdoc
	 */
	public function afterDelete()
	{
		$this->_deleteI18NAttributes();

		parent::afterDelete();
	}

	/**
	 * @inheritdoc
	 */
	public function afterSave($insert, $changedAttributes)
	{
		$this->_saveI18NAttributes($insert);

		parent::afterSave($insert, $changedAttributes);
	}

	/**
	 * @inheritdoc
	 */
	public function afterFind()
	{
		$this->_findI18NAttributes();

		parent::afterFind();
	}

}


text:
(function (enyo, scope) {
	/**
	* This is a [delegate]{@glossary delegate} (strategy) used by {@link enyo.DataList}
	* for vertically-oriented lists. This is used by all lists for this strategy; it
	* does not get copied, but is called directly from the list.
	*
	* @name enyo.DataList.delegates.vertical
	* @type Object
	* @private
	*/
	enyo.DataList.delegates.vertical = {

		/**
		* Used to determine the minimum size of the page. The page size will be at least this
		* number of times greater than the viewport size.
		*
		* @type {Number}
		* @default 2
		* @public
		*/
		pageSizeMultiplier: 2,

		/**
		* Sets the priority properties for this orientation, which can then be customized by
		* other [delegates]{@glossary delegate} that wish to share basic functionality.
		*
		* @param {enyo.DataList} list - The [list]{@link enyo.DataList} to perform this action on.
		* @private
		*/
		initList: function (list) {
			list.posProp   = 'top';
			list.upperProp = 'top';
			list.lowerProp = 'bottom';
			list.psizeProp = 'height';
			list.ssizeProp = 'width';
			// set the scroller options
			var so         = list.scrollerOptions? (list.scrollerOptions = enyo.clone(list.scrollerOptions)): (list.scrollerOptions = {});
			// this is a datalist...it has to be scroll or auto for vertical
			so.vertical    = so.vertical == 'scroll'? 'scroll': 'auto';
			so.horizontal  = so.horizontal || 'hidden';
			// determine if the _controlsPerPage_ property has been set on the list
			if (list.controlsPerPage !== null && !isNaN(list.controlsPerPage)) {
				list._staticControlsPerPage = true;
			}
		},

		/**
		* @private
		*/
		generate: function (list) {
			for (var i=0, p; (p=list.pages[i]); ++i) {
				this.generatePage(list, p, p.index);
			}
			this.adjustPagePositions(list);
			this.adjustBuffer(list);
		},

		/**
		* Performs a hard reset of the [list's]{@link enyo.DataList} pages and children.
		* Scrolls to the top and resets each page's children to have the correct indices.
		*
		* @param {enyo.DataList} list - The [list]{@link enyo.DataList} to perform this action on.
		* @private
		*/
		reset: function (list) {
			list.$.page1.index = 0;
			list.$.page2.index = 1;
			this.generate(list);
			list.hasReset = true;
			// reset the scroller so it will also start from the 'top' whatever that may
			// be (left/top)
			this.scrollTo(list, 0, 0);
		},

		/**
		* Retrieves [list]{@link enyo.DataList} pages, indexed by their position.
		*
		* @param {enyo.DataList} list - The [list]{@link enyo.DataList} to perform this action on.
		* @returns {Object} Returns a [hash]{@glossary Object} of the pages marked by their
		*	position as either 'firstPage' or 'lastPage'.
		* @private
		*/
		pagesByPosition: function (list) {
			var metrics     = list.metrics.pages,
				pos         = list.pagePositions || (list.pagePositions={}),
				upperProp   = list.upperProp,
				firstIndex  = list.$.page1.index || 0,
				secondIndex = (list.$.page2.index || list.$.page2.index === 0) ? list.$.page2.index : 1;
			pos.firstPage   = (
				metrics[firstIndex] && metrics[secondIndex] &&
				(metrics[secondIndex][upperProp] < metrics[firstIndex][upperProp])
				? list.$.page2
				: list.$.page1
			);
			pos.lastPage = (pos.firstPage === list.$.page1? list.$.page2: list.$.page1);
			return pos;
		},

		/**
		* Refreshes each page in the given [list]{@link enyo.DataList}, adjusting its position
		* and adjusting the buffer accordingly.
		*
		* @param {enyo.DataList} list - The [list]{@link enyo.DataList} to perform this action on.
		* @private
		*/
		refresh: function (list) {
			if (!list.hasReset) { return this.reset(list); }
			this.assignPageIndices(list);
			this.generate(list);
		},

		/**
		* Once the [list]{@link enyo.DataList} is initially rendered, it will generate its
		* [scroller]{@link enyo.Scroller} (so we know that is available). Now we need to
		* cache our initial size values and apply them to our pages individually.
		*
		* @param {enyo.DataList} list - The [list]{@link enyo.DataList} to perform this action on.
		* @private
		*/
		rendered: function (list) {
			if (list.$.scroller.addScrollListener) {
				list.usingScrollListener = true;
				list.$.scroller.addScrollListener(
					enyo.bindSafely(this, 'scrollHandler', list)
				);
			}
			// get our initial sizing cached now since we should actually have
			// bounds at this point
			this.updateBounds(list);
			// calc offset of pages to scroller client
			this.calcScrollOffset(list);
			// now if we already have a length then that implies we have a controller
			// and that we have data to render at this point, otherwise we don't
			// want to do any more initialization
			if (list.collection && list.collection.length) { this.reset(list); }
		},
		/**
		* Generates the markup for the page content.
		*
		* @private
		*/
		generatePage: function (list, page, index) {
			// Temporarily add logging code to make it easier for
			// QA and others to detect and report page-index issues
			if (index < 0) {
				enyo.warn('Invalid page index: ' + index);
			}
			// in case it hasn't been set we ensure it is marked correctly
			page.index  = index;
				// the collection of data with records to use
			var data    = list.collection,
				// the metrics for the entire list
				metrics = list.metrics,
				// controls per page
				perPage = this.controlsPerPage(list),
				// placeholder for the control we're going to update
				view;

			// the first index for this generated page
			page.start  = perPage * index;
			// the last index for this generated page
			page.end    = Math.min((data.length - 1), (page.start + perPage) - 1);

			// if generating a control we need to use the correct page as the control parent
			list.controlParent = page;
			for (var i=page.start; i <= page.end && i < data.length; ++i) {
				view = (page.children[i - page.start] || list.createComponent({}));
				// disable notifications until all properties to be updated
				// have been
				view.teardownRender();
				view.stopNotifications();
				view.set('model', data.at(i));
				view.set('index', i);
				this.checkSelected(list, view);
				view.set('selected', list.isSelected(view.model));
				view.startNotifications();
				view.canGenerate = true;
			}
			// if there are any controls that need to be hidden we do that now
			for (i=(i-page.start); i < page.children.length; ++i) {
				view = page.children[i];
				view.teardownRender();
				view.canGenerate = false;
			}
			// update the entire page at once - this removes old nodes and updates
			// to the correct ones
			page.render();
			// now to update the metrics
			metrics        = metrics.pages[index] || (metrics.pages[index] = {});
			metrics.height = this.pageHeight(list, page);
			metrics.width  = this.pageWidth(list, page);
			// update the childSize value now that we have measurements
			this.childSize(list);
		},

		/**
		* checks whether the control should have selected set based on selectionProperty
		*
		* @private
		*/
		checkSelected: function (list, view) {
			var s = list.selectionProperty;
			if (s && view.model.get(s) && !list.isSelected(view.model)) {
				list.select(view.index);
				// don't have to check opposite case (model is false and isSelected is true)
				// because that shouldn't happen
			}
		},

		/**
		* Generates a child size for the given [list]{@link enyo.DataList}.
		*
		* @private
		*/
		childSize: function (list) {
			if (!list.fixedChildSize) {
				var pageIndex = list.$.page1.index,
					sizeProp  = list.psizeProp,
					n         = list.$.page1.node || list.$.page1.hasNode(),
					size, props;
				if (pageIndex >= 0 && n) {
					props = list.metrics.pages[pageIndex];
					size  = props? props[sizeProp]: 0;
					list.childSize = Math.floor(size / (n.children.length || 1));
				}
			}
			return list.fixedChildSize || list.childSize || (list.childSize = 100); // we have to start somewhere
		},

		/**
		* Calculates the number of controls required to fill a page. This functionality is broken
		* out of [controlsPerPage]{@link DataList.delegates.vertical#controlsPerPage} so that it
		* can be overridden by delegates that inherit from this one.
		*
		* @private
		*/
		calculateControlsPerPage: function (list) {
			var fn              = this[list.psizeProp],
				multi           = list.pageSizeMultiplier || this.pageSizeMultiplier,
				childSize       = this.childSize(list);

			// using height/width of the available viewport times our multiplier value
			return Math.ceil(((fn.call(this, list) * multi) / childSize) + 1);
		},

		/**
		* When necessary, updates the the value of `controlsPerPage` dynamically to ensure that
		* the page size is always larger than the viewport size. Note that once a
		* [control]{@link enyo.Control} is instanced (if this number increases and then decreases),
		* the number of available controls will be used instead. This method updates the
		* [childSize]{@link enyo.DataList#childSize} and is used internally to calculate other
		* values, such as [defaultPageSize]{@link DataList.delegates.vertical#defaultPageSize}.
		*
		* @private
		*/
		controlsPerPage: function (list, forceUpdate) {
			if (list._staticControlsPerPage) {
				return list.controlsPerPage;
			} else {
				var updatedControls = list._updatedControlsPerPage,
					updatedBounds   = list._updatedBounds,
					perPage         = list.controlsPerPage;
				// if we've never updated the value or it was done longer ago than the most
				// recent updated sizing/bounds we need to update
				if (forceUpdate || !updatedControls || (updatedControls < updatedBounds)) {
					perPage = list.controlsPerPage = this.calculateControlsPerPage(list);
					// update our time for future comparison
					list._updatedControlsPerPage = enyo.perfNow();
				}
				return perPage;
			}
		},

		/**
		* Retrieves the page index for the given record index.
		*
		* @private
		*/
		pageForIndex: function (list, i) {
			var perPage = list.controlsPerPage || this.controlsPerPage(list);
			return Math.floor(i / (perPage || 1));
		},

		/**
		* An indirect interface to the list's scroller's scrollToControl()
		* method. We provide this to create looser coupling between the
		* delegate and the list / scroller, and to enable subkinds of the
		* delegate to easily override scrollToControl() functionality to
		* include options specific to the scroller being used.
		*
		* @private
		*/
		scrollToControl: function (list, control) {
			list.$.scroller.scrollToControl(control);
		},

		/**
		* An indirect interface to the list's scroller's scrollTo()
		* method. We provide this to create looser coupling between the
		* delegate and the list / scroller, and to enable subkinds of the
		* delegate to easily override scrollTo() functionality to
		* include options specific to the scroller being used.
		*
		* @private
		*/
		scrollTo: function (list, x, y) {
			list.$.scroller.scrollTo(x, y);
		},

		/**
		* Attempts to scroll to the given index.
		*
		* @param {enyo.DataList} list - The [list]{@link enyo.DataList} to perform this action on.
		* @param {Number} i - The index to scroll to.
		* @private
		*/
		scrollToIndex: function (list, i) {
				// first see if the child is already available to scroll to
			var c = this.childForIndex(list, i),
				// but we also need the page so we can find its position
				p = this.pageForIndex(list, i);
			// if there is no page then the index is bad
			if (p < 0 || p > this.pageCount(list)) { return; }
			// if there isn't one, then we know we need to go ahead and
			// update, otherwise we should be able to use the scroller's
			// own methods to find it
			list.$.scroller.stop();
			if (c) {
				this.scrollToControl(list, c);
			} else {
				// we do this to ensure we trigger the paging event when necessary
				this.resetToPosition(list, this.pagePosition(list, p));
				// now retry the original logic until we have this right
				list.startJob('vertical_delegate_scrollToIndex', function () {
					list.scrollToIndex(i);
				});
			}
		},

		/**
		* Returns the calculated height for the given page.
		*
		* @private
		*/
		pageHeight: function (list, page) {
			var h = page.node.offsetHeight;
			var m = list.metrics.pages[page.index];
			var len = list.collection? list.collection.length: 0;
			if (h === 0 && len && page.node.children.length) {
				list.heightNeedsUpdate = true;
				// attempt to reuse the last known height for this page
				h = m? m.height: 0;
			}
			return h;
		},

		/**
		* Returns the calculated width for the given page.
		*
		* @private
		*/
		pageWidth: function (list, page) {
			var w = page.node.offsetWidth;
			var m = list.metrics.pages[page.index];
			var len = list.collection? list.collection.length: 0;
			if (w === 0 && len && page.node.children.length) {
				list.widthNeedsUpdate = true;
				// attempt to reuse the last known width for this page
				w = m? m.width: 0;
			}
			return w;
		},

		/**
		* Attempts to intelligently decide when to force updates for [models]{@link enyo.Model}
		* being added, if the models are part of any visible pages. For now, an assumption is
		* made that records being added are ordered and sequential.
		*
		* @private
		*/
		modelsAdded: function (list, props) {

			// if the list has not already reset, reset
			if (!list.hasReset) return this.reset(list);

			var cpp = this.controlsPerPage(list),
				end = Math.max(list.$.page1.start, list.$.page2.start) + cpp;

			// note that this will refresh the following scenarios
			// 1. if the dataset was spliced in above the current indices and the last index added was
			//    less than the first index rendered
			// 2. if the dataset was spliced in above the current indices and overlapped some of the
			//    current indices
			// 3. if the dataset was spliced in above the current indices and completely overlapped
			//    the current indices (pushing them all down)
			// 4. if the dataset was spliced inside the current indices (pushing some down)
			// 5. if the dataset was appended to the current dataset and was inside the indices that
			//    should be currently rendered (there was a partially filled page)

			// the only time we don't refresh is if the first index of the contiguous set of added
			// models is beyond our final rendered page (possible) indices

			// in the case where it does not need to refresh the existing controls except the last page
			// if the last page is not fully filled, it will be filled with added models
			// so we should generate the last page.

			// it will update its measurements and page positions within the buffer
			// so scrolling can continue properly

			// if we need to refresh, do it now and ensure that we're properly setup to scroll
			// if we were adding to a partially filled page
			if (props.index <= end ) this.refresh(list);
			else {
				// we should confirm that the page which new models are added is need to update list.metrics
				var lastPageIndex = this.pageForIndex(list, props.index),
					// the last page before model added
					lastPage = list.metrics.pages[lastPageIndex],
					sp = list.psizeProp,
					// current page count after models added
					pc = this.pageCount(list),
					pageSize;

				// if there is more pages after lastPage, the lastPage metric needs to be updated
				if (lastPageIndex < pc) {
					pageSize = this.defaultPageSize(list);
					if (lastPage[sp] < pageSize) {
						lastPage[sp] = pageSize;
					}
				}

				// we still need to ensure that the metrics are updated so it knows it can scroll
				// past the boundaries of the current pages (potentially)
				this.adjustBuffer(list);
				this.adjustPagePositions(list);
			}
		},

		/**
		* Attempts to find the [control]{@link enyo.Control} for the requested index.
		*
		* @private
		*/
		childForIndex: function (list, i) {
			var p  = this.pageForIndex(list, i),
				p1 = list.$.page1,
				p2 = list.$.page2;
			p = (p==p1.index && p1) || (p==p2.index && p2);
			if (p) {
				for (var j=0, c; (c=p.children[j]); ++j) {
					if (c.index == i) {
						return c;
					}
				}
			}
		},

		/**
		* Attempts to intelligently decide when to force updates for [models]{@link enyo.Model}
		* being removed, if the models are part of any visible pages.
		*
		* @private
		*/
		modelsRemoved: function (list, props) {

			// if the list has not already reset, reset
			if (!list.hasReset) return this.reset(list);

			var pg1 = list.$.page1,
				pg2 = list.$.page2,
				lastIdx = Math.max(pg1.end, pg2.end);

			// props.models is removed modelList and the lowest index among removed models
			if (props.models.low <= lastIdx) {
				this.refresh(list);
			}
		},

		/**
		* Recalculates the buffer size based on the current metrics for the given list. This
		* may not be completely accurate until the final page is scrolled into view.
		*
		* @private
		*/
		adjustBuffer: function (list) {
			var pc = this.pageCount(list),
				ds = this.defaultPageSize(list),
				bs = 0, sp = list.psizeProp, ss = list.ssizeProp,
				n = list.$.buffer.node || list.$.buffer.hasNode(), p;
			if (n) {
				if (pc !== 0) {
					for (var i=0; i<pc; ++i) {
						p = list.metrics.pages[i];
						bs += (p && p[sp]) || ds;
					}
				}
				list.bufferSize = bs;
				n.style[sp] = bs + 'px';
				n.style[ss] = this[ss](list) + 'px';
				list.$.scroller.remeasure();
			}
		},

		/**
		* Ensures that the pages are positioned according to their calculated positions,
		* updating if necessary.
		*
		* @private
		*/
		adjustPagePositions: function (list) {
			for (var i=0, p; (p=list.pages[i]); ++i) {
				var pi = p.index,
					cp = this.pagePosition(list, p.index),
					mx = list.metrics.pages[pi] || (list.metrics.pages[pi] = {}),
					pp = list.posProp,
					up = list.upperProp,
					lp = list.lowerProp,
					sp = list.psizeProp;
				p.node.style[pp] = cp + 'px';
				p[up] = mx[up] = cp;
				p[lp] = mx[lp] = (mx[sp] + cp);
			}
			this.setScrollThreshold(list);
		},

		/**
		* Retrieves the assumed position for the requested page index.
		*
		* @private
		*/
		pagePosition: function (list, index) {
			var mx = list.metrics.pages,
				ds = this.defaultPageSize(list),
				tt = 0, sp = list.psizeProp, cp;
			while (index > 0) {
				cp = mx[--index];
				// if the index is > 0 then we need to ensure we have at least
				// the minimum height available so this is a deliberate 'fail-on-zero' case
				tt += (cp && cp[sp]? cp[sp]: ds);
			}
			return tt;
		},

		/**
		* Retrieves the default page size.
		*
		* @private
		*/
		defaultPageSize: function (list) {
			var perPage = list.controlsPerPage || this.controlsPerPage(list);
			return (perPage * (list.fixedChildSize || list.childSize || 100));
		},

		/**
		* Retrieves the number of pages for the given [list]{@link enyo.DataList}.
		*
		* @private
		*/
		pageCount: function (list) {
			var perPage = list.controlsPerPage || this.controlsPerPage(list);
			var len = list.collection? list.collection.length: 0;
			return (Math.ceil(len / (perPage || 1)));
		},

		/**
		* Retrieves the current (and desired) scroll position from the
		* [scroller]{@link enyo.Scroller} for the given list.
		*
		* @private
		*/
		getScrollPosition: function (list) {
			return list.$.scroller.getScrollTop();
		},

		/**
		* Sets the scroll position on the [scroller]{@link enyo.Scroller}
		* owned by the given list.
		*
		* @private
		*/
		setScrollPosition: function (list, pos) {
			list.$.scroller.setScrollTop(pos);
		},

		/**
		* @private
		*/
		scrollHandler: function (list, bounds) {
			var last = this.pageCount(list)-1,
				pos  = this.pagesByPosition(list);
			if ((bounds.xDir === 1 || bounds.yDir === 1) && pos.lastPage.index !== (last)) {
				this.generatePage(list, pos.firstPage, pos.lastPage.index + 1);
				this.adjustPagePositions(list);
				this.adjustBuffer(list);
				// note that the reference to the page positions has been udpated by
				// another method so we trust the actual pages
				list.triggerEvent('paging', {
					start: pos.firstPage.start,
					end: pos.lastPage.end,
					action: 'scroll'
				});
			} else if ((bounds.xDir === -1 || bounds.yDir === -1) && pos.firstPage.index !== 0) {
				this.generatePage(list, pos.lastPage, pos.firstPage.index - 1);
				this.adjustPagePositions(list);
				this.adjustBuffer(list);
				// note that the reference to the page positions has been udpated by
				// another method so we trust the actual pages
				list.triggerEvent('paging', {
					start: pos.firstPage.start,
					end: pos.lastPage.end,
					action: 'scroll'
				});
			}
		},

		/**
		* @private
		*/
		setScrollThreshold: function (list) {
			var threshold = list.scrollThreshold || (list.scrollThreshold={}),
				metrics   = list.metrics.pages,
				pos       = this.pagesByPosition(list),
				firstIdx  = pos.firstPage.index,
				lastIdx   = pos.lastPage.index,
				count     = this.pageCount(list)-1,
				lowerProp = list.lowerProp,
				upperProp = list.upperProp,
				fn        = upperProp == 'top'? this.height: this.width;
			// now to update the properties the scroller will use to determine
			// when we need to be notified of position changes requiring paging
			if (firstIdx === 0) {
				threshold[upperProp] = undefined;
			} else {
				threshold[upperProp] = (metrics[firstIdx][upperProp] + this.childSize(list));
			}
			if (lastIdx >= count) {
				threshold[lowerProp] = undefined;
			} else {
				threshold[lowerProp] = (metrics[lastIdx][lowerProp] - fn.call(this, list) - this.childSize(list));
			}
			if (list.usingScrollListener) {
				list.$.scroller.setScrollThreshold(threshold);
			}
		},

		/**
		* Determines which two pages to generate, based on a
		* specific target scroll position.
		*
		* @private
		*/
		assignPageIndices: function (list, targetPos) {
			var index1, index2, bias,
				pc = this.pageCount(list),
				last = Math.max(0, pc - 1),
				currentPos = this.getScrollPosition(list);

			// If no target position was specified, use the current position
			if (typeof targetPos == 'undefined') {
				targetPos = currentPos;
			}

			// Make sure the target position is in-bounds
			targetPos = Math.max(0, Math.min(targetPos, list.bufferSize));

			// First, we find the target page (the one that covers the target position)
			index1 = Math.floor(targetPos / this.defaultPageSize(list));
			index1 = Math.min(index1, last);

			// Our list always generates two pages worth of content, so -- now that we have
			// our target page -- we need to pick either the preceding page or the following
			// page to generate as well. To help us decide, we first determine how our
			// target position relates to our current position. If we know which direction
			// we're moving in, it's generally better to render the page that lies between
			// our current position and our target position, in case we are about to scroll
			// "lazily" to an element near the edge of our target page. If we don't have any
			// information to work with, we arbitrarily favor the following page.
			bias = (targetPos > currentPos) ? -1 : 1;

			// Now we know everything we need to choose our second page...
			index2 =
				// If our target page is the first page (index == 0), there is no preceding
				// page -- so we choose the following page (index == 1). Note that our
				// our target page will always be (index == 0) if the list is empty or has
				// only one page worth of content. Picking (index == 1) for our second page
				// in these cases is fine, though the page won't contain any elements.
				(index1 === 0) ? 1 :
				// If target page is the last page, there is no following page -- so we choose
				// the preceding page.
				(index1 === last) ? index1 - 1 :
				// In all other cases, we pick a page using our previously determined bias.
				index1 + bias;

			list.$.page1.index = index1;
			list.$.page2.index = index2;
		},

		/**
		* @private
		*/
		resetToPosition: function (list, px) {
			this.assignPageIndices(list, px);
			this.generate(list);
			list.triggerEvent('paging', {
				start: list.$.page1.start,
				end: list.$.page2.end,
				action: 'reset'
			});
		},
		/**
		* Handles scroll [events]{@glossary event} for the given [list]{@link enyo.DataList}.
		* The events themselves aren't helpful, as, depending on the underlying
		* `scrollStrategy`, they have varied information. This is a hefty method, but it is
		* contained to keep from calling too many [functions]{@glossary Function} whenever
		* this event is propagated.
		*
		* @private
		*/
		didScroll: function (list, event) {
			if (!list.usingScrollListener) {
				var threshold = list.scrollThreshold,
					bounds    = event.scrollBounds,
					ds        = this.defaultPageSize(list),
					lowerProp = list.lowerProp,
					upperProp = list.upperProp,
					pos       = bounds[upperProp],
					ut        = threshold[upperProp],
					lt        = threshold[lowerProp];
				if (bounds.xDir === 1 || bounds.yDir === 1) {
					if (!isNaN(lt)) {
						if (pos >= lt) {
							if (pos >= lt + ds) {
								// big jump
								this.resetToPosition(list, pos);
							} else {
								// continuous scrolling
								this.scrollHandler(list, bounds);
							}
						}
					}
				} else if (bounds.yDir === -1 || bounds.xDir === -1) {
					if (!isNaN(ut) && (pos <= ut)) {
						if (pos <= ut) {
							if (pos <= ut - ds) {
								// big jump
								this.resetToPosition(list, pos);
							} else {
								//continuous scrolling
								this.scrollHandler(list, bounds);
							}
						}
					}
				}
			}
		},

		/**
		* The delegate's `resize` event handler.
		*
		* @private
		*/
		didResize: function (list) {
			var prevCPP = list.controlsPerPage;

			list._updateBounds = true;
			this.updateBounds(list);
			// Need to update our controlsPerPage value immediately,
			// before any cached metrics are used
			this.controlsPerPage(list);
			if (prevCPP !== list.controlsPerPage) {
				// since we are now using a different number of controls per page,
				// we need to invalidate our cached page metrics
				list.metrics.pages = {};
			}
			this.resetToPosition(list);
		},

		/**
		* Returns the height for the given [list]{@link enyo.DataList}. This value
		* is cached and reused until the list is resized.
		*
		* @private
		*/
		height: function (list) {
			if (list._updateBounds) { this.updateBounds(list); }
			return list.boundsCache.height;
		},

		/**
		* Returns the width for the given [list]{@link enyo.DataList}. This value
		* is cached and reused until the list is resized.
		*
		* @private
		*/
		width: function (list) {
			if (list._updateBounds) { this.updateBounds(list); }
			return list.boundsCache.width;
		},

		/**
		* Updates the cached values for the sizing of the given list.
		*
		* @private
		*/
		updateBounds: function (list) {
			list.boundsCache    = list.getBounds();
			list._updatedBounds = enyo.perfNow();
			list._updateBounds  = false;
		},

		/**
		* Returns the `start` and `end` indices of the visible controls. Partially visible controls
		* are included if the amount visible exceeds the {@link enyo.DataList#visibleThreshold}.
		*
		* @private
		*/
		getVisibleControlRange: function (list) {
			var ret = {
					start: -1,
					end: -1
				},
				posProp = list.posProp,
				sizeProp = list.psizeProp,
				size = this[sizeProp](list),
				scrollPosition = this.getScrollPosition(list),
				pages = list.pages.slice(0).sort(function (a, b) {
					return a.start - b.start;
				}),
				i = 0,
				max = list.collection? list.collection.length - 1 : 0,
				cpp = list.controlsPerPage,
				adjustedScrollPosition, p, bounds, ratio;

			// find the first showing page and estimate the start and end indices
			while ((p = pages[i++])) {
				bounds = p.getBounds();
				bounds.right = list.bufferSize - bounds.left - bounds.width;

				adjustedScrollPosition = scrollPosition - list.scrollPositionOffset;

				if (scrollPosition >= bounds[posProp] && scrollPosition < bounds[posProp] + bounds[sizeProp]) {
					ratio = cpp/bounds[sizeProp];
					ret.start = Math.min(max, Math.max(0, Math.round((adjustedScrollPosition - bounds[posProp])*ratio) + p.start));
					ret.end = Math.min(max, Math.round(size*ratio) + ret.start);
					break;
				}
			}

			ret.start = this.adjustIndex(list, ret.start, p, bounds, adjustedScrollPosition, true);
			ret.end = Math.max(ret.start, this.adjustIndex(list, ret.end, p, bounds, adjustedScrollPosition + size, false));

			return ret;
		},

		/**
		* Calculates the scroll position offset to account for the dimensions of any controls that
		* are within the scroller but precede the pages.
		*
		* @param  {enyo.DataList} list            The instance of enyo.DataList
		* @private
		*/
		calcScrollOffset: function (list) {
			var wrapper = list.pages[0].parent.hasNode(),
				scroller = list.$.scroller.hasNode(),
				posProp = list.posProp,
				position;

			// these should always be truthy in production scenarios but since the nodes aren't
			// actually rendered in mocha, the tests fail so guarding against that.
			if (wrapper && scroller) {
				position = enyo.dom.calcNodePosition(wrapper, scroller);
				list.scrollPositionOffset = position[posProp];
			} else {
				list.scrollPositionOffset = 0;
			}
		},

		/**
		* Refines an estimated `index` to a precise index by evaluating the bounds of the control at
		* the estimated `index` against the visible area and adjusting it up or down based on the
		* actual bounds and the `list`'s {@link enyo.DataList#visibleThreshold}.
		*
		* @param {enyo.DataList} list
		* @param {Number}        index           Estimated index
		* @param {enyo.Control}  page            Page control containing control at `index`
		* @param {Object}        pageBounds      Bounds of `page`
		* @param {Number}        scrollBoundary  Edge of visible area (top, bottom, left, or right)
		* @param {Boolean}       start           `true` for start of boundary (top, right), `false`
		*   for end
		* @private
		*/
		adjustIndex: function (list, index, page, pageBounds, scrollBoundary, start) {
			var dir = start? -1 : 1,
				posProp = list.posProp,
				sizeProp  = list.psizeProp,
				max = list.collection? list.collection.length - 1 : 0,
				last, control, bounds,

				// edge of control
				edge,

				// distance from edge of control to scroll boundary
				dEdge,

				// distance from visible threshold to scroll boundary
				dThresh;

			do {
				control = list.getChildForIndex(index);

				// if index is on a boundary (other than 0) and the control is fully visible, the
				// control at index may not exist if the buffer page hasn't shifted to cover this
				// index range yet. If that's the case, revert to our previous index and stop.
				if (!control) {
					index = last;
					break;
				}

				// account for crossing page boundaries
				if (control.parent != page) {
					page = control.parent;
					pageBounds = page.getBounds();
				}

				bounds = control.getBounds();
				bounds.right = pageBounds.width - bounds.left - bounds.width;

				edge = bounds[posProp] + pageBounds[posProp] + (start? 0 : bounds[sizeProp]);
				dEdge = edge - scrollBoundary;
				dThresh = dEdge - dir*bounds[sizeProp]*(1-list.visibleThreshold)	;

				if ((start && dEdge > 0) || (!start && dEdge < 0)) {
					// control is fully visible
					if (last !== index + dir) {
						last = index;
						index += dir;
					} else {
						// if this control is fully visible but the last was too obscured, use this
						break;
					}
				} else if ((start && dThresh >= 0) || (!start && dThresh <= 0)) {
					// control is partially obscured but enough is visible
					break;
				} else {
					// control is too obscured
					if (last !== index - dir) {
						last = index;
						index -= dir;
					} else {
						// use the last since this is too obscured
						index = last;
						break;
					}
				}

				// guard against selecting an index that is out of bounds
				if (index < 0) {
					index = 0;
					break;
				} else if (index > max) {
					index = max;
					break;
				}
			} while (true);

			return index;
		}
	};

})(enyo, this);


text:
namespace gpkg {
    namespace detail {
        template<typename Visitor>
        struct geometry_ptr_visitor : boost::static_visitor<typename Visitor::result_type> {
          typename Visitor::result_type null_result;

          geometry_ptr_visitor(typename Visitor::result_type null_result) : null_result(null_result) {
          }

          typename Visitor::result_type operator()(const boost::blank &value) const {
            return null_result;
          }

          template<typename Geometry>
          typename Visitor::result_type operator()(const Geometry *value) const {
            return value != nullptr ? Visitor()(*value) : null_result;
          }
        };

        struct is_valid : boost::static_visitor<int> {
          template<typename Geometry>
          int operator()(const Geometry &geom) const {
            return boost::geometry::is_valid(geom);
          }

          int operator()(const gpkg::GeometryCollection &geom) const {
            for (auto it = geom.cbegin(); it < geom.cend(); ++it) {
              if (!boost::apply_visitor(*this, *it)) {
                return false;
              }
            }
            return true;
          }
        };

        struct is_simple : boost::static_visitor<int> {
          template<typename Geometry>
          int operator()(const Geometry &geom) const {
            return boost::geometry::is_simple(geom);
          }

          int operator()(const gpkg::GeometryCollection &geom) const {
            for (auto it = geom.cbegin(); it < geom.cend(); ++it) {
              if (!boost::apply_visitor(*this, *it)) {
                return false;
              }
            }
            return true;
          }
        };

        struct area : boost::static_visitor<double> {
          template<typename Geometry>
          double operator()(const Geometry &geom) const {
            return boost::geometry::area(geom);
          }

          double operator()(const gpkg::GeometryCollection &geom) const {
            double total = 0.0;

            for (auto it = geom.cbegin(); it < geom.cend(); ++it) {
              total += boost::apply_visitor(*this, *it);
            }

            return total;
          }
        };
    }

    int is_valid(GeometryPtr& geometry) {
      return boost::apply_visitor(detail::geometry_ptr_visitor<detail::is_valid>(true), geometry);
    }

    int is_simple(GeometryPtr& geometry) {
      return boost::apply_visitor(detail::geometry_ptr_visitor<detail::is_simple>(true), geometry);
    }

    double area(GeometryPtr& geometry) {
      return boost::apply_visitor(detail::geometry_ptr_visitor<detail::area>(0.0), geometry);
    }
}


text:
jQuery(function($){
	$( 'body' ).bind( 'click.wp-gallery', function(e){
		var target = $( e.target ), id, img_size;

		if ( target.hasClass( 'wp-set-header' ) ) {
			( window.dialogArguments || opener || parent || top ).location.href = target.data( 'location' );
			e.preventDefault();
		} else if ( target.hasClass( 'wp-set-background' ) ) {
			id = target.data( 'attachment-id' );
			img_size = $( 'input[name="attachments[' + id + '][image-size]"]:checked').val();

			jQuery.post(ajaxurl, {
				action: 'set-background-image',
				attachment_id: id,
				size: img_size
			}, function(){
				var win = window.dialogArguments || opener || parent || top;
				win.tb_remove();
				win.location.reload();
			});

			e.preventDefault();
		}
	});
});