text:
import { MapLayer } from "./MapLayer"
import { TileTexSet } from "./TileTexSet";
import { GridSprite } from "./GridSprite";
import { TileAniSprite } from "./TileAniSprite";
import { IMap } from "./IMap";
import { Rectangle } from "../maths/Rectangle";
import { Sprite } from "../display/Sprite";
import { Loader } from "../net/Loader";
import { Handler } from "../utils/Handler";
import { ILaya } from "../../ILaya";
import { Texture } from "../resource/Texture";
import { HTMLCanvas } from "../resource/HTMLCanvas";
import { Point } from "../maths/Point";
import { Context } from "../resource/Context";

/**
 * tiledMap是整个地图的核心
 * 地图以层级来划分地图(例如:地表层,植被层,建筑层)
 * 每层又以分块(GridSprite)来处理显示对象,只显示在视口区域的区
 * 每块又包括N*N个格子(tile)
 * 格子类型又分为动画格子跟图片格子两种
 * @author ...
 */
export class TiledMap {
    //地图支持的类型(目前支持四边形地图,菱形地图,六边形地图)
    /**四边形地图*/
    static ORIENTATION_ORTHOGONAL: string = "orthogonal";
    /**菱形地图*/
    static ORIENTATION_ISOMETRIC: string = "isometric";
    /**45度交错地图*/
    static ORIENTATION_STAGGERED: string = "staggered";
    /**六边形地图*/
    static ORIENTATION_HEXAGONAL: string = "hexagonal";
    //地图格子(tile)的渲染顺序
    /**地图格子从左上角开始渲染*/
    static RENDERORDER_RIGHTDOWN: string = "right-down";
    /**地图格子从左下角开始渲染*/
    static RENDERORDER_RIGHTUP: string = "right-up";
    /**地图格子从右上角开始渲染*/
    static RENDERORDER_LEFTDOWN: string = "left-down";
    /**地图格子右下角开始渲染*/
    static RENDERORDER_LEFTUP: string = "left-up";

    //json数据
    private _jsonData: any;
    //存放地图中用到的所有子纹理数据
    private _tileTexSetArr: any[] = [];
    //主纹理数据,主要在释放纹理资源时使用
    private _texArray: any[] = [];
    //地图信息中的一些基本数据
    private _x: number = 0; //地图的坐标
    private _y: number = 0;
    //_width = _mapTileW * _mapW
    //_height = _mapTileH * _mapH
    private _width: number = 0; //地图的宽度
    private _height: number = 0; //地图的高度
    private _mapW: number = 0; //地图的横向格子数
    private _mapH: number = 0; //地图的竖向格子数
    private _mapTileW: number = 0; //tile的宽度
    private _mapTileH: number = 0; //tile的高度

    //用来存放地图的视口信息
    private _rect: Rectangle = new Rectangle();
    //用来存放地图的视口扩充区域
    private _paddingRect: Rectangle = new Rectangle();
    //地图的显示对象
    private _mapSprite: Sprite = null; //地图的显示对象
    private _layerArray: any[] = []; //这里保存所有的MapLayer对象
    private _renderLayerArray: any[] = [];//这里保存需要渲染的MapLayer对象
    private _gridArray: any[] = []; //保存所有的块数据
    //地图块相关的
    private _showGridKey: boolean = false; //是否显示块边界线(用来调试用)
    private _totalGridNum: number = 0; //一层中的GridSprite的总数
    private _gridW: number = 0; //地图的横向块数
    private _gridH: number = 0; //地图的坚向块数
    private _gridWidth: number = 450; //块的默认宽度
    private _gridHeight: number = 450; //块的默认高度

    private _jsonLoader: Loader = null; //用来加载JSON文件用的LOADER
    private _loader: Loader = null; //用来加载纹理数据用的LOADER
    private _tileSetArray: any[] = []; //用来存放还需要哪些儿纹理等待加载
    private _currTileSet: TileSet = null; //正在加载的纹理需要的数据源
    private _completeHandler: Handler = null; //地图创建完成的回调函数
    //用来裁剪块的区域(有当前视口和上次视口显示多少的块,就能哪些儿块需要显示或隐藏
    private _mapRect: GRect = new GRect(); //当前视口显示的块范围
    private _mapLastRect: GRect = new GRect(); //上次视口显示的块范围
    private _index: number = 0;
    private _animationDic: any = {}; //需要创建的动画数据
    private _properties: any; //当前地图的自定义属性
    private _tileProperties: any = {}; //图块属性
    private _tileProperties2: any = {};
    //默认的地图类型(具体要看JSON文件)
    private _orientation: string = "orthogonal";
    //默认的tile渲染顺序(具体要看JSON文件)
    private _renderOrder: string = "right-down";
    //调试用的颜色组合
    private _colorArray: any[] = ["FF", "00", "33", "66"];
    //缩放相关的操作
    private _scale: number = 1;
    private _pivotScaleX: number = 0.5;
    private _pivotScaleY: number = 0.5;
    private _centerX: number = 0;
    private _centerY: number = 0;
    /**@internal */
    _viewPortX: number = 0;
    /**@internal */
    _viewPortY: number = 0;
    private _viewPortWidth: number = 0;
    private _viewPortHeight: number = 0;
    //是否开启线性取样
    private _enableLinear: boolean = true;
    //资源的相对路径
    private _resPath: string;
    private _pathArray: any[];
    //把地图限制在显示区域
    private _limitRange: boolean = false;
    /**
     * 是否自动缓存没有动画的地块
     */
    autoCache: boolean = true;
    /**
     * 自动缓存类型,地图较大时建议使用normal
     */
    autoCacheType: string = "normal";
    /**
     * 是否合并图层,开启合并图层时,图层属性内可添加layer属性,运行时将会将相邻的layer属性相同的图层进行合并以提高性能
     */
    enableMergeLayer: boolean = false;
    /**
     * 是否移除被覆盖的格子,地块可添加type属性,type不为0时表示不透明,被不透明地块遮挡的地块将会被剔除以提高性能
     */
    removeCoveredTile: boolean = false;
    /**
     * 是否显示大格子里显示的贴图数量
     */
    showGridTextureCount: boolean = false;

    /**
     * 是否调整地块边缘消除缩放导致的缝隙
     */
    antiCrack: boolean = true;

    /**
     * 是否在加载完成之后cache所有大格子
     */
    cacheAllAfterInit: boolean = false;

    constructor() {

    }

    /**
     * 创建地图
     * @param	mapName 		JSON文件名字
     * @param	viewRect 		视口区域
     * @param	completeHandler 地图创建完成的回调函数
     * @param	viewRectPadding 视口扩充区域,把视口区域上、下、左、右扩充一下,防止视口移动时的穿帮
     * @param	gridSize 		grid大小
     * @param	enableLinear 	是否开启线性取样(为false时,可以解决地图黑线的问题,但画质会锐化)
     * @param	limitRange		把地图限制在显示区域
     */
    createMap(mapName: string, viewRect: Rectangle, completeHandler: Handler, viewRectPadding: Rectangle = null, gridSize: Point = null, enableLinear: boolean = true, limitRange: boolean = false): void {
        this._enableLinear = enableLinear;
        this._limitRange = limitRange;
        this._rect.x = viewRect.x;
        this._rect.y = viewRect.y;
        this._rect.width = viewRect.width;
        this._rect.height = viewRect.height;
        this._viewPortWidth = viewRect.width / this._scale;
        this._viewPortHeight = viewRect.height / this._scale;
        this._completeHandler = completeHandler;
        if (viewRectPadding) {
            this._paddingRect.copyFrom(viewRectPadding);
        }
        else {
            this._paddingRect.setTo(0, 0, 0, 0);
        }
        if (gridSize) {
            this._gridWidth = gridSize.x;
            this._gridHeight = gridSize.y;
        }
        var tIndex: number = mapName.lastIndexOf("/");
        if (tIndex > -1) {
            this._resPath = mapName.substr(0, tIndex);
            this._pathArray = this._resPath.split("/");
        }
        else {
            this._resPath = "";
            this._pathArray = [];
        }

        this._jsonLoader = new Loader();
        this._jsonLoader.once("complete", this, this.onJsonComplete);
        this._jsonLoader.load(mapName, Loader.JSON, false);
    }

    /**
     * json文件读取成功后,解析里面的纹理数据,进行加载
     * @param	e JSON数据
     */
    private onJsonComplete(e: any): void {
        this._mapSprite = new Sprite();
        ILaya.stage.addChild(this._mapSprite);
        var tJsonData: any = this._jsonData = e;

        this._properties = tJsonData.properties;
        this._orientation = tJsonData.orientation;
        this._renderOrder = tJsonData.renderorder;
        this._mapW = tJsonData.width;
        this._mapH = tJsonData.height;

        this._mapTileW = tJsonData.tilewidth;
        this._mapTileH = tJsonData.tileheight;

        this._width = this._mapTileW * this._mapW;
        this._height = this._mapTileH * this._mapH;

        if (this._orientation == TiledMap.ORIENTATION_STAGGERED) {
            this._height = (0.5 + this._mapH * 0.5) * this._mapTileH;
        }

        this._mapLastRect.top = this._mapLastRect.bottom = this._mapLastRect.left = this._mapLastRect.right = -1;

        var tArray: any[] = tJsonData.tilesets;
        var tileset: any;
        var tTileSet: TileSet;
        var i: number = 0;
        for (i = 0; i < tArray.length; i++) {
            tileset = tArray[i];
            tTileSet = new TileSet();
            tTileSet.init(tileset);
            if (tTileSet.properties && tTileSet.properties.ignore) continue;
            this._tileProperties[i] = tTileSet.tileproperties;
            this.addTileProperties(tTileSet.tileproperties);
            this._tileSetArray.push(tTileSet);
            //动画数据
            var tTiles: any = tileset.tiles;
            if (tTiles) {
                for (var p in tTiles) {
                    var tAnimation: any[] = tTiles[p].animation;
                    if (tAnimation) {
                        var tAniData: TileMapAniData = new TileMapAniData();
                        this._animationDic[p] = tAniData;
                        tAniData.image = tileset.image;
                        for (var j: number = 0; j < tAnimation.length; j++) {
                            var tAnimationItem: any = tAnimation[j];
                            tAniData.mAniIdArray.push(tAnimationItem.tileid);
                            tAniData.mDurationTimeArray.push(tAnimationItem.duration);
                        }
                    }
                }
            }
        }

        this._tileTexSetArr.push(null);
        if (this._tileSetArray.length > 0) {
            tTileSet = this._currTileSet = this._tileSetArray.shift();
            this._loader = new Loader();
            this._loader.once("complete", this, this.onTextureComplete);
            var tPath: string = this.mergePath(this._resPath, tTileSet.image);
            this._loader.load(tPath, Loader.IMAGE, false);
        }
    }

    /**
     * 合并路径
     * @param	resPath
     * @param	relativePath
     * @return
     */
    private mergePath(resPath: string, relativePath: string): string {
        var tResultPath: string = "";
        var tImageArray: any[] = relativePath.split("/");
        var tParentPathNum: number = 0;
        var i: number = 0;
        for (i = tImageArray.length - 1; i >= 0; i--) {
            if (tImageArray[i] == "..") {
                tParentPathNum++;
            }
        }
        if (tParentPathNum == 0) {
            if (this._pathArray.length > 0) {
                tResultPath = resPath + "/" + relativePath;
            }
            else {
                tResultPath = relativePath;
            }

            return tResultPath;
        }
        var tSrcNum: number = this._pathArray.length - tParentPathNum;
        if (tSrcNum < 0) {
            console.log("[error]path does not exist", this._pathArray, tImageArray, resPath, relativePath);
        }
        for (i = 0; i < tSrcNum; i++) {
            if (i == 0) {
                tResultPath += this._pathArray[i];
            }
            else {
                tResultPath = tResultPath + "/" + this._pathArray[i];
            }
        }
        for (i = tParentPathNum; i < tImageArray.length; i++) {
            tResultPath = tResultPath + "/" + tImageArray[i];
        }
        return tResultPath;
    }

    private _texutreStartDic: any = {};
    /**
     * 纹理加载完成,如果所有的纹理加载,开始初始化地图
     * @param	e 纹理数据
     */
    private onTextureComplete(e: any): void {
        var json: any = this._jsonData;
        var tTexture: Texture = e;
        if (!this._enableLinear) {
            (tTexture.bitmap as any).minFifter = 0x2600; //TODO any
            (tTexture.bitmap as any).magFifter = 0x2600; // TODO any
        }
        this._texArray.push(tTexture);
        var tSubTexture: Texture = null;

        //var tVersion:int = json.viersion;
        var tTileSet: TileSet = this._currTileSet;
        var tTileTextureW: number = tTileSet.tilewidth;
        var tTileTextureH: number = tTileSet.tileheight;
        var tImageWidth: number = tTileSet.imagewidth;
        var tImageHeight: number = tTileSet.imageheight;
        var tFirstgid: number = tTileSet.firstgid;

        var tTileWNum: number = Math.floor((tImageWidth - tTileSet.margin - tTileTextureW) / (tTileTextureW + tTileSet.spacing)) + 1;
        var tTileHNum: number = Math.floor((tImageHeight - tTileSet.margin - tTileTextureH) / (tTileTextureH + tTileSet.spacing)) + 1;

        var tTileTexSet: TileTexSet = null;
        this._texutreStartDic[tTileSet.image] = this._tileTexSetArr.length;
        for (var i: number = 0; i < tTileHNum; i++) {
            for (var j: number = 0; j < tTileWNum; j++) {
                tTileTexSet = new TileTexSet();
                tTileTexSet.offX = tTileSet.titleoffsetX;
                tTileTexSet.offY = tTileSet.titleoffsetY - (tTileTextureH - this._mapTileH);
                //tTileTexSet.texture = Texture.create(tTexture, tTileSet.margin + (tTileTextureW + tTileSet.spacing) * j, tTileSet.margin + (tTileTextureH + tTileSet.spacing) * i, tTileTextureW, tTileTextureH);
                tTileTexSet.texture = Texture.createFromTexture(tTexture, tTileSet.margin + (tTileTextureW + tTileSet.spacing) * j, tTileSet.margin + (tTileTextureH + tTileSet.spacing) * i, tTileTextureW, tTileTextureH);
                if (this.antiCrack)
                    this.adptTexture(tTileTexSet.texture);
                this._tileTexSetArr.push(tTileTexSet);
                tTileTexSet.gid = this._tileTexSetArr.length;
            }
        }

        if (this._tileSetArray.length > 0) {
            tTileSet = this._currTileSet = this._tileSetArray.shift();
            this._loader.once("complete", this, this.onTextureComplete);
            var tPath: string = this.mergePath(this._resPath, tTileSet.image);
            this._loader.load(tPath, Loader.IMAGE, false);
        }
        else {
            this._currTileSet = null;
            this.initMap();
        }
    }

    private adptTexture(tex: Texture): void {
        if (!tex) return;
        var pX: number = tex.uv[0];
        var pX1: number = tex.uv[2];
        var pY: number = tex.uv[1];
        var pY1: number = tex.uv[7];
        var dW: number = 1 / tex.bitmap.width;
        var dH: number = 1 / tex.bitmap.height;
        var Tex: any = tex;
        Tex.uv[0] = Tex.uv[6] = pX + dW;
        Tex.uv[2] = Tex.uv[4] = pX1 - dW;
        Tex.uv[1] = Tex.uv[3] = pY + dH;
        Tex.uv[5] = Tex.uv[7] = pY1 - dH;
    }

    /**
     * 初始化地图
     */
    private initMap(): void {
        var i: number, n: number;
        for (var p in this._animationDic) {
            var tAniData: TileMapAniData = this._animationDic[p];
            var gStart: number;
            gStart = this._texutreStartDic[tAniData.image];
            var tTileTexSet: TileTexSet = this.getTexture(parseInt(p) + gStart);
            if (tAniData.mAniIdArray.length > 0) {
                tTileTexSet.textureArray = [];
                tTileTexSet.durationTimeArray = tAniData.mDurationTimeArray;
                tTileTexSet.isAnimation = true;
                tTileTexSet.animationTotalTime = 0;
                for (i = 0, n = tTileTexSet.durationTimeArray.length; i < n; i++) {
                    tTileTexSet.animationTotalTime += tTileTexSet.durationTimeArray[i];
                }
                for (i = 0, n = tAniData.mAniIdArray.length; i < n; i++) {
                    var tTexture: TileTexSet = this.getTexture(tAniData.mAniIdArray[i] + gStart);
                    tTileTexSet.textureArray.push(tTexture);
                }
            }
        }

        this._gridWidth = Math.floor(this._gridWidth / this._mapTileW) * this._mapTileW;
        this._gridHeight = Math.floor(this._gridHeight / this._mapTileH) * this._mapTileH;
        if (this._gridWidth < this._mapTileW) {
            this._gridWidth = this._mapTileW;
        }
        if (this._gridHeight < this._mapTileH) {
            this._gridHeight = this._mapTileH;
        }

        this._gridW = Math.ceil(this._width / this._gridWidth);
        this._gridH = Math.ceil(this._height / this._gridHeight);
        this._totalGridNum = this._gridW * this._gridH;
        for (i = 0; i < this._gridH; i++) {
            var tGridArray: any[] = [];
            this._gridArray.push(tGridArray);
            for (var j: number = 0; j < this._gridW; j++) {
                tGridArray.push(null);
            }
        }

        var tLayerArray: any[] = this._jsonData.layers;
        var isFirst: boolean = true;
        var tTarLayerID: number = 1;
        var tLayerTarLayerName: string;
        var preLayerTarName: string;
        var preLayer: MapLayer;

        //创建地图层级
        for (var tLayerLoop: number = 0; tLayerLoop < tLayerArray.length; tLayerLoop++) {
            var tLayerData: any = tLayerArray[tLayerLoop];
            if (tLayerData.visible == true) //如果不显示,那么也没必要创建
            {
                var tMapLayer: MapLayer = new MapLayer();
                tMapLayer.init(tLayerData, this);
                if (!this.enableMergeLayer) {
                    this._mapSprite.addChild(tMapLayer);
                    this._renderLayerArray.push(tMapLayer);
                } else {
                    tLayerTarLayerName = tMapLayer.getLayerProperties("layer");
                    isFirst = isFirst || (!preLayer) || (tLayerTarLayerName != preLayerTarName);
                    if (isFirst) {
                        isFirst = false;
                        tMapLayer.tarLayer = tMapLayer;
                        preLayer = tMapLayer;
                        this._mapSprite.addChild(tMapLayer);
                        this._renderLayerArray.push(tMapLayer);
                    } else {
                        tMapLayer.tarLayer = preLayer;
                    }
                    preLayerTarName = tLayerTarLayerName;
                }

                this._layerArray.push(tMapLayer);
            }
        }
        if (this.removeCoveredTile) {
            this.adptTiledMapData();
        }
        if (this.cacheAllAfterInit) {
            this.cacheAllGrid();
        }
        this.moveViewPort(this._rect.x, this._rect.y);

        if (this._completeHandler != null) {
            this._completeHandler.run();
        }
        //这里应该发送消息,通知上层,地图创建完成
    }

    private addTileProperties(tileDataDic: any): void {
        var key: string;
        for (key in tileDataDic) {
            this._tileProperties2[key] = tileDataDic[key];
        }
    }

    getTileUserData(id: number, sign: string, defaultV: any = null): any {
        if (!this._tileProperties2 || !this._tileProperties2[id] || !(sign in this._tileProperties2[id])) return defaultV;
        return this._tileProperties2[id][sign];
    }

    private adptTiledMapData(): void {
        var i: number, len: number;
        len = this._layerArray.length;
        var tLayer: MapLayer;
        var noNeeds: any = {};
        var tDatas: any[];
        for (i = len - 1; i >= 0; i--) {
            tLayer = this._layerArray[i];
            tDatas = tLayer._mapData;
            if (!tDatas) continue;
            this.removeCoverd(tDatas, noNeeds);
            this.collectCovers(tDatas, noNeeds, i);
        }
    }

    private removeCoverd(datas: any[], noNeeds: any): void {
        var i: number, len: number;
        len = datas.length;
        for (i = 0; i < len; i++) {
            if (noNeeds[i]) {
                datas[i] = 0;
            }
        }
    }

    private collectCovers(datas: any[], noNeeds: any, layer: number): void {
        var i: number, len: number;
        len = datas.length;
        var tTileData: number;
        var isCover: number;
        for (i = 0; i < len; i++) {
            tTileData = datas[i];
            if (tTileData > 0) {
                isCover = this.getTileUserData(tTileData - 1, "type", 0);
                if (isCover > 0) {
                    noNeeds[i] = tTileData;
                }
            }
        }
    }
    /**
     * 得到一块指定的地图纹理
     * @param	index 纹理的索引值,默认从1开始
     * @return
     */
    getTexture(index: number): TileTexSet {
        if (index < this._tileTexSetArr.length) {
            return this._tileTexSetArr[index];
        }
        return null;
    }

    /**
     * 得到地图的自定义属性
     * @param	name		属性名称
     * @return
     */
    getMapProperties(name: string): any {
        if (this._properties) {
            return this._properties[name];
        }
        return null;
    }

    /**
     * 得到tile自定义属性
     * @param	index		地图块索引
     * @param	id			具体的TileSetID
     * @param	name		属性名称
     * @return
     */
    getTileProperties(index: number, id: number, name: string): any {
        if (this._tileProperties[index] && this._tileProperties[index][id]) {
            return this._tileProperties[index][id][name];
        }
        return null;
    }

    /**
     * 通过纹理索引,生成一个可控制物件
     * @param	index 纹理的索引值,默认从1开始
     * @return
     */
    getSprite(index: number, width: number, height: number): GridSprite {
        if (0 < this._tileTexSetArr.length) {
            var tGridSprite: GridSprite = new GridSprite();
            tGridSprite.initData(this, true);
            tGridSprite.size(width, height);
            var tTileTexSet: TileTexSet = this._tileTexSetArr[index];
            if (tTileTexSet != null && tTileTexSet.texture != null) {
                if (tTileTexSet.isAnimation) {
                    var tAnimationSprite: TileAniSprite = new TileAniSprite();
                    this._index++;
                    tAnimationSprite.setTileTextureSet(this._index.toString(), tTileTexSet);
                    tGridSprite.addAniSprite(tAnimationSprite);
                    tGridSprite.addChild(tAnimationSprite);
                }
                else {
                    tGridSprite.graphics.drawImage(tTileTexSet.texture, 0, 0, width, height);
                }
                tGridSprite.drawImageNum++;
            }
            return tGridSprite;
        }
        return null;
    }

    /**
     * 设置视口的缩放中心点(例如:scaleX= scaleY= 0.5,就是以视口中心缩放)
     * @param	scaleX
     * @param	scaleY
     */
    setViewPortPivotByScale(scaleX: number, scaleY: number): void {
        this._pivotScaleX = scaleX;
        this._pivotScaleY = scaleY;
    }

    /**
     * 设置地图缩放
     * @param	scale
     */
    set scale(scale: number) {
        if (scale <= 0)
            return;
        this._scale = scale;
        this._viewPortWidth = this._rect.width / scale;
        this._viewPortHeight = this._rect.height / scale;
        this._mapSprite.scale(this._scale, this._scale);
        this.updateViewPort();
    }

    /**
     * 得到当前地图的缩放
     */
    get scale(): number {
        return this._scale;
    }

    /**
     * 移动视口
     * @param	moveX 视口的坐标x
     * @param	moveY 视口的坐标y
     */
    moveViewPort(moveX: number, moveY: number): void {
        this._x = -moveX;
        this._y = -moveY;
        this._rect.x = moveX;
        this._rect.y = moveY;
        this.updateViewPort();
    }

    /**
     * 改变视口大小
     * @param	moveX	视口的坐标x
     * @param	moveY	视口的坐标y
     * @param	width	视口的宽
     * @param	height	视口的高
     */
    changeViewPort(moveX: number, moveY: number, width: number, height: number): void {
        if (moveX == this._rect.x && moveY == this._rect.y && width == this._rect.width && height == this._rect.height) return;
        this._x = -moveX;
        this._y = -moveY;
        this._rect.x = moveX;
        this._rect.y = moveY;
        this._rect.width = width;
        this._rect.height = height;
        this._viewPortWidth = width / this._scale;
        this._viewPortHeight = height / this._scale;
        this.updateViewPort();
    }

    /**
     * 在锚点的基础上计算,通过宽和高,重新计算视口
     * @param	width		新视口宽
     * @param	height		新视口高
     * @param	rect		返回的结果
     * @return
     */
    changeViewPortBySize(width: number, height: number, rect: Rectangle = null): Rectangle {
        if (rect == null) {
            rect = new Rectangle();
        }
        this._centerX = this._rect.x + this._rect.width * this._pivotScaleX;
        this._centerY = this._rect.y + this._rect.height * this._pivotScaleY;
        rect.x = this._centerX - width * this._pivotScaleX;
        rect.y = this._centerY - height * this._pivotScaleY;
        rect.width = width;
        rect.height = height;
        this.changeViewPort(rect.x, rect.y, rect.width, rect.height);
        return rect;
    }

    /**
     * 刷新视口
     */
    private updateViewPort(): void {
        //_rect.x和rect.y是内部坐标,会自动叠加缩放
        this._centerX = this._rect.x + this._rect.width * this._pivotScaleX;
        this._centerY = this._rect.y + this._rect.height * this._pivotScaleY;
        var posChanged: boolean = false;
        var preValue: number = this._viewPortX;
        this._viewPortX = this._centerX - this._rect.width * this._pivotScaleX / this._scale;
        if (preValue != this._viewPortX) {
            posChanged = true;
        } else {
            preValue = this._viewPortY;
        }
        this._viewPortY = this._centerY - this._rect.height * this._pivotScaleY / this._scale;
        if (!posChanged && preValue != this._viewPortY) {
            posChanged = true;
        }
        if (this._limitRange) {
            var tRight: number = this._viewPortX + this._viewPortWidth;
            if (tRight > this._width) {
                this._viewPortX = this._width - this._viewPortWidth;
            }
            var tBottom: number = this._viewPortY + this._viewPortHeight;
            if (tBottom > this._height) {
                this._viewPortY = this._height - this._viewPortHeight;
            }
            if (this._viewPortX < 0) {
                this._viewPortX = 0;
            }
            if (this._viewPortY < 0) {
                this._viewPortY = 0;
            }
        }
        var tPaddingRect: Rectangle = this._paddingRect;
        this._mapRect.top = Math.floor((this._viewPortY - tPaddingRect.y) / this._gridHeight);
        this._mapRect.bottom = Math.floor((this._viewPortY + this._viewPortHeight + tPaddingRect.height + tPaddingRect.y) / this._gridHeight);
        this._mapRect.left = Math.floor((this._viewPortX - tPaddingRect.x) / this._gridWidth);
        this._mapRect.right = Math.floor((this._viewPortX + this._viewPortWidth + tPaddingRect.width + tPaddingRect.x) / this._gridWidth);
        if (this._mapRect.top != this._mapLastRect.top || this._mapRect.bottom != this._mapLastRect.bottom || this._mapRect.left != this._mapLastRect.left || this._mapRect.right != this._mapLastRect.right) {
            this.clipViewPort();
            this._mapLastRect.top = this._mapRect.top;
            this._mapLastRect.bottom = this._mapRect.bottom;
            this._mapLastRect.left = this._mapRect.left;
            this._mapLastRect.right = this._mapRect.right;
            posChanged = true;
        }

        if (!posChanged) return;

        var tMapLayer: MapLayer;
        var len: number = this._renderLayerArray.length;
        for (var i: number = 0; i < len; i++) {
            tMapLayer = this._renderLayerArray[i];
            if (tMapLayer._gridSpriteArray.length > 0)
                tMapLayer.updateGridPos();
        }
    }

    /**
     * GRID裁剪
     */
    private clipViewPort(): void {
        var tSpriteNum: number = 0;
        var tSprite: Sprite;
        var tIndex: number = 0;
        var tSub: number = 0;
        var tAdd: number = 0;
        var i: number, j: number;
        if (this._mapRect.left > this._mapLastRect.left) {
            //裁剪
            tSub = this._mapRect.left - this._mapLastRect.left;
            if (tSub > 0) {
                for (j = this._mapLastRect.left; j < this._mapLastRect.left + tSub; j++) {
                    for (i = this._mapLastRect.top; i <= this._mapLastRect.bottom; i++) {
                        this.hideGrid(j, i);
                    }
                }
            }
        }
        else {
            //增加
            tAdd = Math.min(this._mapLastRect.left, this._mapRect.right + 1) - this._mapRect.left;
            if (tAdd > 0) {
                for (j = this._mapRect.left; j < this._mapRect.left + tAdd; j++) {
                    for (i = this._mapRect.top; i <= this._mapRect.bottom; i++) {
                        this.showGrid(j, i);
                    }
                }
            }
        }
        if (this._mapRect.right > this._mapLastRect.right) {
            //增加
            tAdd = this._mapRect.right - this._mapLastRect.right;
            if (tAdd > 0) {
                for (j = Math.max(this._mapLastRect.right + 1, this._mapRect.left); j <= this._mapLastRect.right + tAdd; j++) {
                    for (i = this._mapRect.top; i <= this._mapRect.bottom; i++) {
                        this.showGrid(j, i);
                    }
                }
            }
        }
        else {
            //裁剪
            tSub = this._mapLastRect.right - this._mapRect.right
            if (tSub > 0) {
                for (j = this._mapRect.right + 1; j <= this._mapRect.right + tSub; j++) {
                    for (i = this._mapLastRect.top; i <= this._mapLastRect.bottom; i++) {
                        this.hideGrid(j, i);
                    }
                }
            }
        }
        if (this._mapRect.top > this._mapLastRect.top) {
            //裁剪
            tSub = this._mapRect.top - this._mapLastRect.top;
            if (tSub > 0) {
                for (i = this._mapLastRect.top; i < this._mapLastRect.top + tSub; i++) {
                    for (j = this._mapLastRect.left; j <= this._mapLastRect.right; j++) {
                        this.hideGrid(j, i);
                    }
                }
            }

        }
        else {
            //增加
            tAdd = Math.min(this._mapLastRect.top, this._mapRect.bottom + 1) - this._mapRect.top;
            if (tAdd > 0) {
                for (i = this._mapRect.top; i < this._mapRect.top + tAdd; i++) {
                    for (j = this._mapRect.left; j <= this._mapRect.right; j++) {
                        this.showGrid(j, i);
                    }
                }
            }

        }
        if (this._mapRect.bottom > this._mapLastRect.bottom) {
            //增加
            tAdd = this._mapRect.bottom - this._mapLastRect.bottom;
            if (tAdd > 0) {
                for (i = Math.max(this._mapLastRect.bottom + 1, this._mapRect.top); i <= this._mapLastRect.bottom + tAdd; i++) {
                    for (j = this._mapRect.left; j <= this._mapRect.right; j++) {
                        this.showGrid(j, i);
                    }
                }
            }
        }
        else {
            //裁剪
            tSub = this._mapLastRect.bottom - this._mapRect.bottom
            if (tSub > 0) {
                for (i = this._mapRect.bottom + 1; i <= this._mapRect.bottom + tSub; i++) {
                    for (j = this._mapLastRect.left; j <= this._mapLastRect.right; j++) {
                        this.hideGrid(j, i);
                    }
                }
            }
        }
    }

    /**
     * 显示指定的GRID
     * @param	gridX
     * @param	gridY
     */
    private showGrid(gridX: number, gridY: number): void {
        if (gridX < 0 || gridX >= this._gridW || gridY < 0 || gridY >= this._gridH) {
            return;
        }
        var i: number, j: number;
        var tGridSprite: GridSprite
        var tTempArray: any[] = this._gridArray[gridY][gridX];
        if (tTempArray == null) {
            tTempArray = this.getGridArray(gridX, gridY);
        }
        else {
            for (i = 0; i < tTempArray.length && i < this._layerArray.length; i++) {
                var tLayerSprite: Sprite = this._layerArray[i];
                if (tLayerSprite && tTempArray[i]) {
                    tGridSprite = tTempArray[i];
                    if (tGridSprite.visible == false && tGridSprite.drawImageNum > 0) {
                        tGridSprite.show();
                    }
                }
            }
        }
    }

    private cacheAllGrid(): void {
        var i: number, j: number;
        var tempArr: any[];
        for (i = 0; i < this._gridW; i++) {
            for (j = 0; j < this._gridH; j++) {
                tempArr = this.getGridArray(i, j);
                this.cacheGridsArray(tempArr);
            }
        }

    }
    private static _tempCanvas: any;
    private cacheGridsArray(arr: any[]): void {
        var canvas: any;
        if (!TiledMap._tempCanvas) {
            TiledMap._tempCanvas = new HTMLCanvas();
            var tx: Context = TiledMap._tempCanvas.context;
            if (!tx) {
                tx = TiledMap._tempCanvas.getContext('2d');	//如果是webGL的话,这个会返回WebGLContext2D

                //tx.__tx = 0;
                //tx.__ty = 0;
            }
        }
        canvas = TiledMap._tempCanvas;
        canvas.context.asBitmap = false

        var i: number, len: number;
        len = arr.length;
        var tGrid: GridSprite;
        for (i = 0; i < len; i++) {
            tGrid = arr[i];
            canvas.clear();
            canvas.size(1, 1);
            tGrid.render(canvas.context, 0, 0);
            tGrid.hide();
        }
        canvas.clear();
        canvas.size(1, 1);
    }

    private getGridArray(gridX: number, gridY: number): any[] {
        var i: number, j: number;
        var tGridSprite: GridSprite
        var tTempArray: any[] = this._gridArray[gridY][gridX];
        if (tTempArray == null) {
            tTempArray = this._gridArray[gridY][gridX] = [];

            var tLeft: number = 0;
            var tRight: number = 0;
            var tTop: number = 0;
            var tBottom: number = 0;

            var tGridWidth: number = this._gridWidth
            var tGridHeight: number = this._gridHeight;
            switch (this.orientation) {
                case TiledMap.ORIENTATION_ISOMETRIC: //45度角
                    tLeft = Math.floor(gridX * tGridWidth);
                    tRight = Math.floor(gridX * tGridWidth + tGridWidth);
                    tTop = Math.floor(gridY * tGridHeight);
                    tBottom = Math.floor(gridY * tGridHeight + tGridHeight);
                    var tLeft1: number, tRight1: number, tTop1: number, tBottom1: number;
                    break;
                case TiledMap.ORIENTATION_STAGGERED: //45度交错地图
                    tLeft = Math.floor(gridX * tGridWidth / this._mapTileW);
                    tRight = Math.floor((gridX * tGridWidth + tGridWidth) / this._mapTileW);
                    tTop = Math.floor(gridY * tGridHeight / (this._mapTileH / 2));
                    tBottom = Math.floor((gridY * tGridHeight + tGridHeight) / (this._mapTileH / 2));
                    break;
                case TiledMap.ORIENTATION_ORTHOGONAL: //直角
                    tLeft = Math.floor(gridX * tGridWidth / this._mapTileW);
                    tRight = Math.floor((gridX * tGridWidth + tGridWidth) / this._mapTileW);
                    tTop = Math.floor(gridY * tGridHeight / this._mapTileH);
                    tBottom = Math.floor((gridY * tGridHeight + tGridHeight) / this._mapTileH);
                    break;
                case TiledMap.ORIENTATION_HEXAGONAL: //六边形
                    var tHeight: number = this._mapTileH * 2 / 3;
                    tLeft = Math.floor(gridX * tGridWidth / this._mapTileW);
                    tRight = Math.ceil((gridX * tGridWidth + tGridWidth) / this._mapTileW);
                    tTop = Math.floor(gridY * tGridHeight / tHeight);
                    tBottom = Math.ceil((gridY * tGridHeight + tGridHeight) / tHeight);
                    break;

            }

            var tLayer: MapLayer = null;
            var tTGridSprite: GridSprite;
            var tDrawMapLayer: MapLayer;
            for (var z: number = 0; z < this._layerArray.length; z++) {
                tLayer = this._layerArray[z];

                if (this.enableMergeLayer) {
                    if (tLayer.tarLayer != tDrawMapLayer) {
                        tTGridSprite = null;
                        tDrawMapLayer = tLayer.tarLayer;
                    }
                    if (!tTGridSprite) {
                        tTGridSprite = tDrawMapLayer.getDrawSprite(gridX, gridY);
                        tTempArray.push(tTGridSprite);
                        //tDrawMapLayer.addChild(tTGridSprite);
                    }
                    tGridSprite = tTGridSprite;
                }
                else {
                    tGridSprite = tLayer.getDrawSprite(gridX, gridY);
                    tTempArray.push(tGridSprite);
                }

                var tColorStr: string;
                if (this._showGridKey) {
                    tColorStr = "#";
                    tColorStr += this._colorArray[Math.floor(Math.random() * this._colorArray.length)];
                    tColorStr += this._colorArray[Math.floor(Math.random() * this._colorArray.length)];
                    tColorStr += this._colorArray[Math.floor(Math.random() * this._colorArray.length)];
                }
                switch (this.orientation) {
                    case TiledMap.ORIENTATION_ISOMETRIC: //45度角
                        var tHalfTileHeight: number = this.tileHeight / 2;
                        var tHalfTileWidth: number = this.tileWidth / 2;
                        var tHalfMapWidth: number = this._width / 2;
                        tTop1 = Math.floor(tTop / tHalfTileHeight);
                        tBottom1 = Math.floor(tBottom / tHalfTileHeight);
                        tLeft1 = this._mapW + Math.floor((tLeft - tHalfMapWidth) / tHalfTileWidth);
                        tRight1 = this._mapW + Math.floor((tRight - tHalfMapWidth) / tHalfTileWidth);

                        var tMapW: number = this._mapW * 2;
                        var tMapH: number = this._mapH * 2;

                        if (tTop1 < 0) {
                            tTop1 = 0;
                        }
                        if (tTop1 >= tMapH) {
                            tTop1 = tMapH - 1;
                        }
                        if (tBottom1 < 0) {
                            tBottom = 0;
                        }
                        if (tBottom1 >= tMapH) {
                            tBottom1 = tMapH - 1;
                        }
                        tGridSprite.zOrder = this._totalGridNum * z + gridY * this._gridW + gridX;
                        for (i = tTop1; i < tBottom1; i++) {
                            for (j = 0; j <= i; j++) {
                                var tIndexX: number = i - j;
                                var tIndexY: number = j;
                                var tIndexValue: number = (tIndexX - tIndexY) + this._mapW;
                                if (tIndexValue > tLeft1 && tIndexValue <= tRight1) {
                                    if (tLayer.drawTileTexture(tGridSprite, tIndexX, tIndexY)) {
                                        tGridSprite.drawImageNum++;
                                    }
                                }
                            }
                        }
                        break;
                    case TiledMap.ORIENTATION_STAGGERED: //45度交错地图
                        tGridSprite.zOrder = z * this._totalGridNum + gridY * this._gridW + gridX;
                        for (i = tTop; i < tBottom; i++) {
                            for (j = tLeft; j < tRight; j++) {
                                if (tLayer.drawTileTexture(tGridSprite, j, i)) {
                                    tGridSprite.drawImageNum++;
                                }
                            }
                        }
                        break;
                    case TiledMap.ORIENTATION_ORTHOGONAL: //直角
                    case TiledMap.ORIENTATION_HEXAGONAL: //六边形
                        switch (this._renderOrder) {
                            case TiledMap.RENDERORDER_RIGHTDOWN:
                                tGridSprite.zOrder = z * this._totalGridNum + gridY * this._gridW + gridX;
                                for (i = tTop; i < tBottom; i++) {
                                    for (j = tLeft; j < tRight; j++) {
                                        if (tLayer.drawTileTexture(tGridSprite, j, i)) {
                                            tGridSprite.drawImageNum++;
                                        }
                                    }
                                }
                                break;
                            case TiledMap.RENDERORDER_RIGHTUP:
                                tGridSprite.zOrder = z * this._totalGridNum + (this._gridH - 1 - gridY) * this._gridW + gridX;
                                for (i = tBottom - 1; i >= tTop; i--) {
                                    for (j = tLeft; j < tRight; j++) {
                                        if (tLayer.drawTileTexture(tGridSprite, j, i)) {
                                            tGridSprite.drawImageNum++;
                                        }
                                    }
                                }
                                break;
                            case TiledMap.RENDERORDER_LEFTDOWN:
                                tGridSprite.zOrder = z * this._totalGridNum + gridY * this._gridW + (this._gridW - 1 - gridX);
                                for (i = tTop; i < tBottom; i++) {
                                    for (j = tRight - 1; j >= tLeft; j--) {
                                        if (tLayer.drawTileTexture(tGridSprite, j, i)) {
                                            tGridSprite.drawImageNum++;
                                        }
                                    }
                                }
                                break;
                            case TiledMap.RENDERORDER_LEFTUP:
                                tGridSprite.zOrder = z * this._totalGridNum + (this._gridH - 1 - gridY) * this._gridW + (this._gridW - 1 - gridX);
                                for (i = tBottom - 1; i >= tTop; i--) {
                                    for (j = tRight - 1; j >= tLeft; j--) {
                                        if (tLayer.drawTileTexture(tGridSprite, j, i)) {
                                            tGridSprite.drawImageNum++;
                                        }
                                    }
                                }
                                break;
                        }
                        break;
                }
                //没动画了GRID,保存为图片
                if (!tGridSprite.isHaveAnimation) {
                    tGridSprite.autoSize = true;
                    if (this.autoCache)
                        tGridSprite.cacheAs = this.autoCacheType;
                    tGridSprite.autoSize = false;
                }

                if (!this.enableMergeLayer) {
                    if (tGridSprite.drawImageNum > 0) {
                        tLayer.addChild(tGridSprite);
                    }
                    if (this._showGridKey) {
                        tGridSprite.graphics.drawRect(0, 0, tGridWidth, tGridHeight, null, tColorStr);
                    }
                } else {
                    if (tTGridSprite && tTGridSprite.drawImageNum > 0 && tDrawMapLayer) {
                        tDrawMapLayer.addChild(tTGridSprite);
                    }
                }

            }
            if (this.enableMergeLayer && this.showGridTextureCount) {
                if (tTGridSprite) {
                    tTGridSprite.graphics.fillText(tTGridSprite.drawImageNum + "", 20, 20, null, "#ff0000", "left");
                }
            }
        }
        return tTempArray;
    }

    /**
     * 隐藏指定的GRID
     * @param	gridX
     * @param	gridY
     */
    private hideGrid(gridX: number, gridY: number): void {
        if (gridX < 0 || gridX >= this._gridW || gridY < 0 || gridY >= this._gridH) {
            return;
        }
        var tTempArray: any[] = this._gridArray[gridY][gridX];
        if (tTempArray) {
            var tGridSprite: GridSprite;
            for (var i: number = 0; i < tTempArray.length; i++) {
                tGridSprite = tTempArray[i];
                if (tGridSprite.drawImageNum > 0) {
                    if (tGridSprite != null) {
                        tGridSprite.hide();
                    }
                }
            }
        }
    }

    /**
     * 得到对象层上的某一个物品
     * @param	layerName   层的名称
     * @param	objectName	所找物品的名称
     * @return
     */
    getLayerObject(layerName: string, objectName: string): GridSprite {
        var tLayer: MapLayer = null;
        for (var i: number = 0; i < this._layerArray.length; i++) {
            tLayer = this._layerArray[i];
            if (tLayer.layerName == layerName) {
                break;
            }
        }
        if (tLayer) {
            return tLayer.getObjectByName(objectName);
        }
        return null;
    }

    /**
     * 销毁地图
     */
    destroy(): void {
        this._orientation = TiledMap.ORIENTATION_ORTHOGONAL;
        //json数据
        this._jsonData = null;

        var i: number = 0;
        var j: number = 0;
        var z: number = 0;

        this._gridArray = []; //??这里因为跟LAYER中的数据重复,所以不做处理
        //清除子纹理
        var tTileTexSet: TileTexSet;
        for (i = 0; i < this._tileTexSetArr.length; i++) {
            tTileTexSet = this._tileTexSetArr[i];
            if (tTileTexSet) {
                tTileTexSet.clearAll();
            }
        }
        this._tileTexSetArr = [];
        //清除主纹理
        var tTexture: Texture;
        for (i = 0; i < this._texArray.length; i++) {
            tTexture = this._texArray[i];
            tTexture.destroy();
        }
        this._texArray = [];

        //地图信息中的一些基本数据
        this._width = 0;
        this._height = 0;
        this._mapW = 0;
        this._mapH = 0;
        this._mapTileW = 0;
        this._mapTileH = 0;

        this._rect.setTo(0, 0, 0, 0);

        var tLayer: MapLayer;
        for (i = 0; i < this._layerArray.length; i++) {
            tLayer = this._layerArray[i];
            tLayer.clearAll();
        }

        this._layerArray = [];
        this._renderLayerArray = [];
        if (this._mapSprite) {
            this._mapSprite.destroy();
            this._mapSprite = null;
        }

        this._jsonLoader = null; //??
        this._loader = null; //??
        //
        var tDic: any = this._animationDic;
        for (var p in tDic) {
            delete tDic[p];
        }

        this._properties = null;
        tDic = this._tileProperties;
        for (p in tDic) {
            delete tDic[p];
        }

        this._currTileSet = null;
        this._completeHandler = null;

        this._mapRect.clearAll();
        this._mapLastRect.clearAll();

        this._tileSetArray = [];

        this._gridWidth = 450;
        this._gridHeight = 450;

        this._gridW = 0;
        this._gridH = 0;

        this._x = 0;
        this._y = 0;

        this._index = 0;

        this._enableLinear = true;
        //资源的相对路径
        this._resPath = null;
        this._pathArray = null;
    }

    /****************************地图的基本数据***************************/ /**
     * 格子的宽度
     */
    get tileWidth(): number {
        return this._mapTileW;
    }

    /**
     * 格子的高度
     */
    get tileHeight(): number {
        return this._mapTileH;
    }

    /**
     * 地图的宽度
     */
    get width(): number {
        return this._width;
    }

    /**
     * 地图的高度
     */
    get height(): number {
        return this._height;
    }

    /**
     * 地图横向的格子数
     */
    get numColumnsTile(): number {
        return this._mapW;
    }

    /**
     * 地图竖向的格子数
     */
    get numRowsTile(): number {
        return this._mapH;
    }

    /**
     * @private
     * 视口x坐标
     */
    get viewPortX(): number {
        return -this._viewPortX;
    }

    /**
     * @private
     * 视口的y坐标
     */
    get viewPortY(): number {
        return -this._viewPortY;
    }

    /**
     * @private
     * 视口的宽度
     */
    get viewPortWidth(): number {
        return this._viewPortWidth;
    }

    /**
     * @private
     * 视口的高度
     */
    get viewPortHeight(): number {
        return this._viewPortHeight;
    }

    /**
     * 地图的x坐标
     */
    get x(): number {
        return this._x;
    }

    /**
     * 地图的y坐标
     */
    get y(): number {
        return this._y;
    }

    /**
     * 块的宽度
     */
    get gridWidth(): number {
        return this._gridWidth;
    }

    /**
     * 块的高度
     */
    get gridHeight(): number {
        return this._gridHeight;
    }

    /**
     * 地图的横向块数
     */
    get numColumnsGrid(): number {
        return this._gridW;
    }

    /**
     * 地图的坚向块数
     */
    get numRowsGrid(): number {
        return this._gridH;
    }

    /**
     * 当前地图类型
     */
    get orientation(): string {
        return this._orientation;
    }

    /**
     * tile渲染顺序
     */
    get renderOrder(): string {
        return this._renderOrder;
    }

    /*****************************************对外接口**********************************************/

    /**
     * 整个地图的显示容器
     * @return 地图的显示容器
     */
    mapSprite(): Sprite {
        return this._mapSprite;
    }

    /**
     * 得到指定的MapLayer
     * @param layerName 要找的层名称
     * @return
     */
    getLayerByName(layerName: string): MapLayer {
        var tMapLayer: MapLayer;
        for (var i: number = 0; i < this._layerArray.length; i++) {
            tMapLayer = this._layerArray[i];
            if (layerName == tMapLayer.layerName) {
                return tMapLayer;
            }
        }
        return null;
    }

    /**
     * 通过索引得MapLayer
     * @param	index 要找的层索引
     * @return
     */
    getLayerByIndex(index: number): MapLayer {
        if (index < this._layerArray.length) {
            return this._layerArray[index];
        }
        return null;
    }

}

/**@internal */
class GRect {
    left: number;
    top: number;
    right: number;
    bottom: number;

    clearAll(): void {
        this.left = this.top = this.right = this.bottom = 0;
    }
}

/**@internal */
class TileMapAniData {
    mAniIdArray: any[] = [];
    mDurationTimeArray: any[] = [];
    mTileTexSetArr: any[] = [];
    image: any;
}

/**@internal */
class TileSet {

    firstgid: number = 0;
    image: string = "";
    imageheight: number = 0;
    imagewidth: number = 0;
    margin: number = 0;
    name: number = 0;
    properties: any;
    spacing: number = 0;
    tileheight: number = 0;
    tilewidth: number = 0;

    titleoffsetX: number = 0;
    titleoffsetY: number = 0;
    tileproperties: any;

    init(data: any): void {
        this.firstgid = data.firstgid;
        this.image = data.image;
        this.imageheight = data.imageheight;
        this.imagewidth = data.imagewidth;
        this.margin = data.margin;
        this.name = data.name;
        this.properties = data.properties;
        this.spacing = data.spacing;
        this.tileheight = data.tileheight;
        this.tilewidth = data.tilewidth;

        //自定义属性
        this.tileproperties = data.tileproperties;
        var tTileoffset: any = data.tileoffset;
        if (tTileoffset) {
            this.titleoffsetX = tTileoffset.x;
            this.titleoffsetY = tTileoffset.y;
        }
    }
}

IMap.TiledMap = TiledMap;


text: <!DOCTYPE html>

redpajama_set_name: RedPajamaGithub


text:
namespace Krkadoni.Enigma
{
    public interface IBouquetItemServiceE1 : IBouquetItemService
    {
        string VlcParms { get; set; }
    }
}


text:
package com.azure.data.cosmos.internal.routing;

import com.azure.data.cosmos.internal.Utils;
import com.fasterxml.jackson.core.JsonGenerator;

import java.io.IOException;
import java.io.OutputStream;

class MaxStringPartitionKeyComponent implements IPartitionKeyComponent {
    public static final MaxStringPartitionKeyComponent VALUE = new MaxStringPartitionKeyComponent();

    @Override
    public int CompareTo(IPartitionKeyComponent other) {
        MaxStringPartitionKeyComponent otherMaxString = Utils.as(other, MaxStringPartitionKeyComponent.class);
        if (otherMaxString == null) {
            throw new IllegalArgumentException("other");
        }

        return 0;
    }

    @Override
    public int GetTypeOrdinal() {
        return PartitionKeyComponentType.MAXSTRING.ordinal();
    }

    @Override
    public void JsonEncode(JsonGenerator writer) {
        PartitionKeyInternal.PartitionKeyInternalJsonSerializer.jsonEncode(this, writer);
    }

    @Override
    public void WriteForHashing(OutputStream outputStream) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void WriteForHashingV2(OutputStream outputStream) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void WriteForBinaryEncoding(OutputStream outputStream) {
        try {
            outputStream.write((byte) PartitionKeyComponentType.MAXSTRING.type);
        } catch (IOException e) {
            throw new IllegalStateException(e);
        }
    }

    @Override
    public IPartitionKeyComponent Truncate() {
        return this;
    }

}


text:
package com.google.cloud.tools.eclipse.appengine.localserver.server;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import com.google.cloud.tools.eclipse.test.util.ThreadDumpingWatchdog;
import com.google.cloud.tools.eclipse.test.util.project.ProjectUtils;
import com.google.common.base.Stopwatch;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.BooleanSupplier;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.wst.server.core.IModule;
import org.eclipse.wst.server.core.IServer;
import org.eclipse.wst.server.core.IServerType;
import org.eclipse.wst.server.core.IServerWorkingCopy;
import org.eclipse.wst.server.core.ServerCore;
import org.eclipse.wst.server.core.ServerUtil;
import org.eclipse.wst.server.core.internal.ModuleFactory;
import org.eclipse.wst.server.core.internal.ServerPlugin;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;

/** Verify that the server properly published submodule projects */
public class LocalAppEnginePublishOperationTest {
  @Rule
  public ThreadDumpingWatchdog timer = new ThreadDumpingWatchdog(2, TimeUnit.MINUTES);

  private final List<IProject> projects = new ArrayList<>();
  private IProject serverProject;
  private IProject sharedProject;
  private IModule serverModule;
  private IModule sharedModule;
  private IServer server;

  @Before
  public void setUp() throws Exception {
    sharedProject = importProject("sox-shared");
    serverProject = importProject("sox-server");
    assertEquals(2, projects.size());

    serverModule = ServerUtil.getModule(serverProject);
    sharedModule = ServerUtil.getModule(sharedProject);

    // https://github.com/GoogleCloudPlatform/google-cloud-eclipse/issues/1798
    waitUntilProjectsReady();

    // To diagnose https://github.com/GoogleCloudPlatform/google-cloud-eclipse/issues/1798.
    logModules(serverProject);
    logModules(sharedProject);
    assertTrue(serverProject.getFile("bin/sox/server/GreetingServiceImpl.class").exists());
    assertTrue(sharedProject.getFile("bin/sox/shared/GreetingService.class").exists());

    assertNotNull(serverModule);
    assertNotNull(sharedModule);
  }

  @After
  public void tearDown() throws CoreException {
    if (!projects.isEmpty()) {
      projects.get(0).getWorkspace().delete(projects.toArray(new IProject[0]), true, null);
    }
    if (server != null) {
      server.delete();
    }
  }

  private IProject importProject(String projectName) throws IOException, CoreException {
    Map<String, IProject> imported = ProjectUtils.importProjects(getClass(),
        "projects/" + projectName + ".zip", true /* checkBuildErrors */, null);
    assertEquals(1, imported.size());
    IProject project = imported.get(projectName);
    assertNotNull(project);
    projects.add(project);
    return project;
  }

  /**
   * Verify that multi-web-module works.
   */
  @Test
  public void testPublishingSubmodules() throws CoreException {
    IServerType serverType =
        ServerCore.findServerType("com.google.cloud.tools.eclipse.appengine.standard.server");
    IServerWorkingCopy serverWorkingCopy =
        serverType.createServer(getClass().getName(), null, null);
    serverWorkingCopy.modifyModules(new IModule[] {serverModule}, null, null);
    server = serverWorkingCopy.saveAll(true, null);
    assertTrue(server.canPublish().isOK());
    assertTrue("publish failed", server.publish(IServer.PUBLISH_CLEAN, null).isOK());

    LocalAppEngineServerBehaviour serverBehaviour =
        server.getAdapter(LocalAppEngineServerBehaviour.class);
    assertNotNull(serverBehaviour);

    // now verify the result
    IPath deployDirectory = serverBehaviour.getModuleDeployDirectory(serverModule);
    File publishedModule = deployDirectory.toFile();
    assertTrue(publishedModule.isDirectory());
    File webInf = new File(publishedModule, "WEB-INF");
    assertTrue(webInf.isDirectory());

    assertTrue(new File(webInf, "appengine-web.xml").isFile());
    assertTrue(new File(webInf, "web.xml").isFile());
    assertTrue(new File(webInf, "classes/sox/server/GreetingServiceImpl.class").isFile());
    assertTrue(new File(webInf, "lib/servlet-2.5.jar").isFile());
    assertTrue(new File(webInf, "lib/sox-shared.jar").isFile());
  }

  // Code taken from "ServerUtil.getModules()" (which "ServerUtil.getModule()" calls) to diagnose
  // one of the failures in https://github.com/GoogleCloudPlatform/google-cloud-eclipse/issues/1798.
  private static void logModules(IProject project) {
    System.out.println("  #### Testing getModules(" + project.getName() + ") ####");

    ModuleFactory[] factories = ServerPlugin.getModuleFactories();
    assertNotNull(factories);
    assertNotEquals(0, factories.length);

    for (ModuleFactory factory : factories) {
      boolean factoryEnabled = factory.isEnabled(project, null);
      System.out.println("    * " + factory + (!factoryEnabled? " (not enabled, skipping)" : ""));

      System.out.print("      - All factory modules:");
      printModules(factory.getDelegate(null).getModules());

      if (factoryEnabled) {
        System.out.print("      - Project modules:");
        printModules(factory.getModules(project, null));
      }
    }
  }

  private static void printModules(IModule[] modules) {
    if (modules == null) {
      System.out.println(" <null>");
    } else if (modules.length == 0) {
      System.out.println(" <empty>");
    } else {
      for (IModule module : modules) {
        System.out.println(" " + module.getName());
      }
    }
  }

  private void waitUntilProjectsReady() throws Exception {
    waitUntilCondition("Until fully built", this::classFilesExist, () -> Thread.sleep(100), 100);
    waitUntilCondition("Until modules fully ready", this::modulesReady, this::reopenProjects, 10);
  }

  private static void waitUntilCondition(String comment, BooleanSupplier condition,
      ThrowingRunnable interimAction, int tries) throws Exception {
    Stopwatch stopwatch = Stopwatch.createStarted();
    for (int i = 0; i < tries && !condition.getAsBoolean(); i++) {
      ThreadDumpingWatchdog.report(comment, stopwatch);
      interimAction.run();
    }
  }

  private boolean classFilesExist() {
    return serverProject.getFile("bin/sox/server/GreetingServiceImpl.class").exists()
        && sharedProject.getFile("bin/sox/shared/GreetingService.class").exists();
  }

  private boolean modulesReady() {
    return serverModule != null && sharedModule != null;
  }

  private void reopenProjects() throws CoreException {
    for (IProject project : projects) {
      project.close(null);
      project.open(null);
    }
    ProjectUtils.waitForProjects(projects);
    serverModule = ServerUtil.getModule(serverProject);
    sharedModule = ServerUtil.getModule(sharedProject);
  }

  private interface ThrowingRunnable {
    void run() throws Exception;
  };
}


text:
package edu.neu.ccs.pyramid.multilabel_classification;

import edu.neu.ccs.pyramid.calibration.*;
import edu.neu.ccs.pyramid.classification.logistic_regression.LogisticRegression;
import edu.neu.ccs.pyramid.dataset.IdTranslator;
import edu.neu.ccs.pyramid.dataset.LabelTranslator;
import edu.neu.ccs.pyramid.dataset.MultiLabel;
import edu.neu.ccs.pyramid.dataset.MultiLabelClfDataSet;
import edu.neu.ccs.pyramid.feature.Feature;
import edu.neu.ccs.pyramid.multilabel_classification.cbm.CBM;

import edu.neu.ccs.pyramid.multilabel_classification.predictor.SupportPredictor;
import edu.neu.ccs.pyramid.regression.*;
import edu.neu.ccs.pyramid.util.Pair;
import org.apache.mahout.math.Vector;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

public class BRLRInspector {

    public static  MultiLabelPredictionAnalysis analyzePrediction(CBM cbm,
                                                                  LabelCalibrator labelCalibrator,
                                                                  VectorCalibrator setCalibrator,
                                                                  MultiLabelClfDataSet dataSet,
                                                                  MultiLabelClassifier classifier,
                                                                  PredictionFeatureExtractor predictionFeatureExtractor,
                                                                  int dataPointIndex, int ruleLimit,
                                                                  int labelSetLimit, double classProbThreshold){
        MultiLabelPredictionAnalysis predictionAnalysis = new MultiLabelPredictionAnalysis();
        LabelTranslator labelTranslator = dataSet.getLabelTranslator();
        IdTranslator idTranslator = dataSet.getIdTranslator();
        predictionAnalysis.setInternalId(dataPointIndex);
        predictionAnalysis.setId(idTranslator.toExtId(dataPointIndex));
        predictionAnalysis.setInternalLabels(dataSet.getMultiLabels()[dataPointIndex].getMatchedLabelsOrdered());
        List<String> labels = dataSet.getMultiLabels()[dataPointIndex].getMatchedLabelsOrdered().stream()
                .map(labelTranslator::toExtLabel).collect(Collectors.toList());
        predictionAnalysis.setLabels(labels);

        double[] classProbs = cbm.predictClassProbs(dataSet.getRow(dataPointIndex));
        double[] calibratedClassProbs = labelCalibrator.calibratedClassProbs(classProbs);

        PredictionCandidate trueCandidate = new PredictionCandidate();
        trueCandidate.x = dataSet.getRow(dataPointIndex);
        trueCandidate.multiLabel = dataSet.getMultiLabels()[dataPointIndex];
        trueCandidate.labelProbs = calibratedClassProbs;
        predictionAnalysis.setProbForTrueLabels(setCalibrator.calibrate(predictionFeatureExtractor.extractFeatures(trueCandidate)));

        MultiLabel predictedLabels = classifier.predict(dataSet.getRow(dataPointIndex));
        List<Integer> internalPrediction = predictedLabels.getMatchedLabelsOrdered();
        predictionAnalysis.setInternalPrediction(internalPrediction);
        List<String> prediction = internalPrediction.stream().map(labelTranslator::toExtLabel).collect(Collectors.toList());
        predictionAnalysis.setPrediction(prediction);

        PredictionCandidate predictedCandidate = new PredictionCandidate();
        predictedCandidate.x = dataSet.getRow(dataPointIndex);
        predictedCandidate.multiLabel = predictedLabels;
        predictedCandidate.labelProbs = calibratedClassProbs;

        predictionAnalysis.setProbForPredictedLabels(setCalibrator.calibrate(predictionFeatureExtractor.extractFeatures(predictedCandidate)));

        List<Integer> classes = new ArrayList<Integer>();
        for (int k = 0; k < cbm.getNumClasses(); k++){
            if (calibratedClassProbs[k]>=classProbThreshold
                    ||dataSet.getMultiLabels()[dataPointIndex].matchClass(k)
                    ||predictedLabels.matchClass(k)){
                classes.add(k);
            }
        }

        //todo
        List<ClassScoreCalculation> classScoreCalculations = new ArrayList<>();
        for (int k: classes){
            ClassScoreCalculation classScoreCalculation = decisionProcess(cbm,labelTranslator,calibratedClassProbs[k],
                    dataSet.getRow(dataPointIndex),k,ruleLimit);
            classScoreCalculations.add(classScoreCalculation);
        }
        predictionAnalysis.setClassScoreCalculations(classScoreCalculations);

        List<MultiLabelPredictionAnalysis.ClassRankInfo> labelRanking = classes.stream().map(label -> {
                    MultiLabelPredictionAnalysis.ClassRankInfo rankInfo = new MultiLabelPredictionAnalysis.ClassRankInfo();
                    rankInfo.setClassIndex(label);
                    rankInfo.setClassName(labelTranslator.toExtLabel(label));
                    rankInfo.setProb(calibratedClassProbs[label]);
                    return rankInfo;
                }
        ).collect(Collectors.toList());
        predictionAnalysis.setPredictedRanking(labelRanking);

        List<Pair<MultiLabel,Double>> topK;
        if (classifier instanceof SupportPredictor){
            topK = TopKFinder.topKinSupport(dataSet.getRow(dataPointIndex),cbm,labelCalibrator,setCalibrator,
                    predictionFeatureExtractor,((SupportPredictor)classifier).getSupport(),labelSetLimit);
        } else {
            topK = TopKFinder.topK(dataSet.getRow(dataPointIndex),cbm,labelCalibrator,setCalibrator,
                    predictionFeatureExtractor,labelSetLimit);
        }

        List<MultiLabelPredictionAnalysis.LabelSetProbInfo> labelSetRanking = topK.stream()
                    .map(pair -> {
                    MultiLabel multiLabel = pair.getFirst();
                    double setProb = pair.getSecond();
                    MultiLabelPredictionAnalysis.LabelSetProbInfo labelSetProbInfo = new MultiLabelPredictionAnalysis.LabelSetProbInfo(multiLabel, setProb, labelTranslator);
                    return labelSetProbInfo;
                }).sorted(Comparator.comparing(MultiLabelPredictionAnalysis.LabelSetProbInfo::getProbability).reversed())
                .limit(labelSetLimit)
                .collect(Collectors.toList());

        predictionAnalysis.setPredictedLabelSetRanking(labelSetRanking);

        return predictionAnalysis;
    }

    //only show the positive class score calculation
    public static ClassScoreCalculation decisionProcess(CBM cbm, LabelTranslator labelTranslator, double prob,
                                                        Vector vector, int classIndex, int limit){
        LogisticRegression logisticRegression = (LogisticRegression)cbm.getBinaryClassifiers()[0][classIndex];
        ClassScoreCalculation classScoreCalculation = new ClassScoreCalculation(classIndex,labelTranslator.toExtLabel(classIndex),
                logisticRegression.predictClassScore(vector,1));
        classScoreCalculation.setClassProbability(prob);

        List<LinearRule> linearRules = new ArrayList<>();
        Rule bias = new ConstantRule(logisticRegression.getWeights().getBiasForClass(1));
        classScoreCalculation.addRule(bias);
        //todo speed up using sparsity
        for (int j=0;j<logisticRegression.getNumFeatures();j++){
            Feature feature = logisticRegression.getFeatureList().get(j);
            double weight = logisticRegression.getWeights().getWeightsWithoutBiasForClass(1).get(j);
            double featureValue = vector.get(j);
            double score = weight*featureValue;
            LinearRule rule = new LinearRule();
            rule.setFeature(feature);
            rule.setFeatureValue(featureValue);
            rule.setScore(score);
            rule.setWeight(weight);
            linearRules.add(rule);
        }

        Comparator<LinearRule> comparator = Comparator.comparing(decision -> Math.abs(decision.getScore()));
        List<LinearRule> sorted = linearRules.stream().sorted(comparator.reversed()).limit(limit).collect(Collectors.toList());

        for (LinearRule linearRule : sorted){
            classScoreCalculation.addRule(linearRule);
        }

        return classScoreCalculation;
    }
}


text:
'use strict';

var fs = require('fs');

// Temp store while I'm goofin' around
var store = {};
try {
    store = require('../.store');
} catch (e) {}

function exitHandler(options, err) {
    if (options.cleanup) {
        fs.writeFileSync('.store.json', JSON.stringify(store));
    }
    if (err) {
        console.log(err.stack);
    }
    if (options.exit) {
        process.exit();
    }
}
process.on('exit', exitHandler.bind(null, {
    cleanup: true
}));

process.on('SIGINT', exitHandler.bind(null, {
    exit: true
}));

process.on('SIGTERM', exitHandler.bind(null, {
    exit: true
}));

module.exports = store;


text:
module ActiveadminDraggable
  VERSION = "0.1.0"
end


text:
//	NavMenu is a hierarchical menu of volumes, folders, files and queries
//	displays icons, uses the SlowMenu API for full interruptability

#ifndef NAV_MENU_H
#define NAV_MENU_H

#include <Messenger.h>
#include <StorageDefs.h>
#include <Entry.h>

#include "SlowMenu.h"

template<class T> class BObjectList;
class BMenuItem;

namespace BPrivate {

class Model;
class BContainerWindow;
class ModelMenuItem;
class EntryListBase;

class TrackingHookData {
	public:
		TrackingHookData()
			:
			fTrackingHook(NULL),
			fDragMessage(NULL)
		{
		}

		bool (*fTrackingHook)(BMenu *, void *);
		BMessenger fTarget;
		const BMessage *fDragMessage;
};

class BNavMenu : public BSlowMenu {
	public:
		BNavMenu(const char* title, uint32 message, const BHandler *,
			BWindow *parentWindow = NULL, const BObjectList<BString> *list = NULL);
		BNavMenu(const char* title, uint32 message, const BMessenger &,
			BWindow *parentWindow = NULL, const BObjectList<BString> *list = NULL);
			// parentWindow, if specified, will be closed if nav menu item invoked
			// with option held down

		virtual ~BNavMenu();

		virtual	void AttachedToWindow();
		virtual	void DetachedFromWindow();

		void SetNavDir(const entry_ref *);
		void ForceRebuild();
		bool NeedsToRebuild() const;
			// will cause menu to get rebuilt next time it is shown

		virtual	void ResetTargets();
		void SetTarget(const BMessenger &);
		BMessenger Target();

		void SetTypesList(const BObjectList<BString> *list);
		const BObjectList<BString> *TypesList() const;

		void AddNavDir(const Model *model, uint32 what, BHandler *target,
			bool populateSubmenu);

		void AddNavParentDir(const char *name, const Model *model, uint32 what, BHandler *target);
		void AddNavParentDir(const Model *model, uint32 what, BHandler *target);
		void SetShowParent(bool show);

		static int32 GetMaxMenuWidth();

		static int CompareFolderNamesFirstOne(const BMenuItem *, const BMenuItem *);
		static int CompareOne(const BMenuItem *, const BMenuItem *);

		static ModelMenuItem *NewModelItem(Model *, const BMessage *, const BMessenger &,
			bool suppressFolderHierarchy=false, BContainerWindow * = NULL,
			const BObjectList<BString> *typeslist = NULL,
			TrackingHookData *hook = NULL);

		TrackingHookData *InitTrackingHook(bool (*hookfunction)(BMenu *, void *),
			const BMessenger *target, const BMessage *dragMessage);

	protected:
		virtual bool StartBuildingItemList();
		virtual bool AddNextItem();
		virtual void DoneBuildingItemList();
		virtual void  ClearMenuBuildingState();

		void BuildVolumeMenu();

		void AddOneItem(Model *);
		void AddRootItemsIfNeeded();
		static void SetTrackingHookDeep(BMenu *, bool (*)(BMenu *, void *), void *);

		entry_ref	fNavDir;
		BMessage	fMessage;
		BMessenger	fMessenger;
		BWindow		*fParentWindow;

		// menu building state
		uint8		fFlags;
		BObjectList<BMenuItem> *fItemList;
		EntryListBase *fContainer;
		bool		fIteratingDesktop;

		const BObjectList<BString> *fTypesList;

		TrackingHookData fTrackingHook;
};

//	Spring Loaded Folder convenience routines
//		used in both Tracker and Deskbar

bool SpringLoadedFolderCompareMessages(const BMessage *incoming,
	const BMessage *dragmessage);
void SpringLoadedFolderSetMenuStates(const BMenu *menu,
	const BObjectList<BString> *typeslist);
void SpringLoadedFolderAddUniqueTypeToList(entry_ref *ref,
	BObjectList<BString> *typeslist);
void SpringLoadedFolderCacheDragData(const BMessage *incoming,
	BMessage **, BObjectList<BString> **typeslist);

} // namespace BPrivate

using namespace BPrivate;

#endif


text:
static NSString* const kTagName = @"Hangup";

@implementation INDTwiMLHangupElement

- (instancetype)init
{
    return [super initWithTagName:kTagName];
}
@end


text:
<?xml version="1.0" encoding="UTF-8"?>
<Tokens version="1.0">
	<File path="Classes/CCActionEaseBackOut.html">

		<Token>
			<TokenIdentifier>//apple_ref/occ/cl/CCActionEaseBackOut</TokenIdentifier>
			<Abstract type="html">CCEaseBackOut action.</Abstract>
			<DeclaredIn>CCActionEase.h</DeclaredIn>
            <Availability type="html">(
    "v0.8.2"
)</Availability>

			<NodeRef refid="15"/>
		</Token>

	</File>
</Tokens>


text:
package org.apache.sis.measure;

import javax.measure.Unit;
import javax.measure.Quantity;
import javax.measure.quantity.Length;
import javax.measure.quantity.Temperature;
import org.apache.sis.test.DependsOn;
import org.apache.sis.test.TestCase;
import org.junit.Test;

import static org.opengis.test.Assert.*;

/**
 * Tests {@link Quantities}.
 *
 * @author  Martin Desruisseaux (Geomatys)
 * @version 1.1
 * @since   0.8
 * @module
 */
@DependsOn(ScalarTest.class)
public final strictfp class QuantitiesTest extends TestCase {
    /**
     * Tests {@link Quantities#create(double, String)}.
     */
    @Test
    public void testCreate() {
        final Quantity<?> q = Quantities.create(5, "km");
        assertEquals("value", 5, q.getValue().doubleValue(), STRICT);
        assertSame  ("unit", Units.KILOMETRE, q.getUnit());
    }

    /**
     * Tests {@link Quantities#castOrCopy(Quantity)}.
     */
    @Test
    public void testCastOrCopy() {
        Quantity<Length> q = Quantities.create(5, Units.KILOMETRE);
        assertSame(q, Quantities.castOrCopy(q));

        q = new Quantity<Length>() {
            @Override public Number           getValue()                         {return 8;}
            @Override public Unit<Length>     getUnit ()                         {return Units.CENTIMETRE;}
            @Override public Quantity<Length> add     (Quantity<Length> ignored) {return null;}
            @Override public Quantity<Length> subtract(Quantity<Length> ignored) {return null;}
            @Override public Quantity<?>      multiply(Quantity<?>      ignored) {return null;}
            @Override public Quantity<?>      divide  (Quantity<?>      ignored) {return null;}
            @Override public Quantity<Length> multiply(Number           ignored) {return null;}
            @Override public Quantity<Length> divide  (Number           ignored) {return null;}
            @Override public Quantity<?>      inverse ()                         {return null;}
            @Override public Quantity<Length> to      (Unit<Length>     ignored) {return null;}
            @Override public <T extends Quantity<T>> Quantity<T> asType(Class<T> ignored) {return null;}
        };
        final Length c = Quantities.castOrCopy(q);
        assertNotSame(q, c);
        assertEquals("value", 8, c.getValue().doubleValue(), STRICT);
        assertSame  ("unit", Units.CENTIMETRE, c.getUnit());
    }

    /**
     * Tests operations on temperature. The values shall be converted to Kelvin before any operation.
     * This produces counter-intuitive result, but is the only way to get results that are consistent
     * with arithmetic rules like commutativity and associativity.
     *
     * @since 1.0
     */
    @Test
    public void testTemperature() {
        final Quantity<Temperature> q1 = Quantities.create( 2, Units.CELSIUS);
        final Quantity<Temperature> q2 = Quantities.create( 3, Units.KELVIN);
        final Quantity<Temperature> q3 = Quantities.create(-8, Units.CELSIUS);

        assertInstanceOf( "2°C", DerivedScalar.TemperatureMeasurement.class, q1);
        assertInstanceOf( "3 K", DerivedScalar.Temperature.class,            q2);
        assertInstanceOf("-8°C", DerivedScalar.TemperatureMeasurement.class, q3);

        Quantity<Temperature> r = q1.add(q2);
        assertSame  ("unit",  Units.CELSIUS, r.getUnit());
        assertEquals("value", 5, r.getValue().doubleValue(), 1E-13);

        r = q2.add(q1);
        assertSame  ("unit",  Units.KELVIN, r.getUnit());
        assertEquals("value", 278.15, r.getValue().doubleValue(), 1E-13);

        r = q1.add(q3);
        assertSame  ("unit",  Units.CELSIUS, r.getUnit());
        assertEquals("value", 267.15, r.getValue().doubleValue(), 1E-13);

        r = q1.multiply(3);
        assertSame  ("unit",  Units.CELSIUS, r.getUnit());
        assertEquals("value", 552.3, r.getValue().doubleValue(), 1E-13);

        r = q1.multiply(1);
        assertSame(q1, r);
    }

    /**
     * Tests a multiply operation that result in a quantity for which we have no specialized sub-interface.
     *
     * @since 1.1
     */
    @Test
    public void testUnspecialized() {
        final Quantity<?> quantity = Quantities.create(3, Units.CENTIMETRE).multiply(Quantities.create(4, Units.SECOND));
        assertEquals("value", 12, quantity.getValue().doubleValue(), STRICT);
        assertEquals("unit", "cm⋅s", quantity.getUnit().toString());
    }

    /**
     * Tests {@link Scalar#equals(Object)} and {@link Scalar#hashCode()}.
     * This test uses a unit without specific {@link Scalar} subclass, in order to
     * verify that tested methods work even though the {@link ScalarFallback} proxy.
     */
    @Test
    public void testEqualsAndHashcode() {
        Quantity<?> q1 = Quantities.create(2, Units.VOLT);
        Quantity<?> q2 = Quantities.create(2, Units.VOLT);
        Quantity<?> q3 = Quantities.create(3, Units.VOLT);
        assertTrue (q1.hashCode() == q2.hashCode());
        assertFalse(q1.hashCode() == q3.hashCode());
        assertTrue (q1.hashCode() != 0);
        assertTrue (q1.equals(q2));
        assertFalse(q1.equals(q3));
    }

    /**
     * Tests {@link Quantities#min(Quantity, Quantity)} and {@link Quantities#max(Quantity, Quantity)}.
     *
     * @since 1.1
     */
    @Test
    public void testMinAndMax() {
        Quantity<Length> q1 = Quantities.create(5,      Units.KILOMETRE);
        Quantity<Length> q2 = Quantities.create(600,    Units.METRE);
        Quantity<Length> q3 = Quantities.create(700000, Units.CENTIMETRE);
        assertSame(q2, Quantities.min(q1, q2));
        assertSame(q1, Quantities.max(q1, q2));
        assertSame(q1, Quantities.min(q1, q3));
        assertSame(q3, Quantities.max(q1, q3));
    }
}


text:
local skynet = require "skynet"
local redis = require "skynet.db.redis"
local crc16 = require "skynet.db.redis.crc16"

local RedisClusterHashSlots = 16384
local RedisClusterRequestTTL = 16

local _M = {}

local rediscluster = {}
rediscluster.__index = rediscluster
_M.rediscluster = rediscluster

function _M.new(startup_nodes,opt)
	if #startup_nodes == 0 then
		startup_nodes = {startup_nodes,}
	end
	opt = opt or {}
	local self = {
		startup_nodes = startup_nodes,
		max_connections = opt.max_connections or 16,
		connections = setmetatable({},{__mode = "kv"}),
		opt = opt,
		refresh_table_asap = false,
	}
	setmetatable(self,rediscluster)
	self:initialize_slots_cache()
	return self
end

local function nodename(node)
	return string.format("%s:%s",node.host,node.port)
end

function rediscluster:get_redis_link(node)
	local conf = {
		host = node.host,
		port = node.port,
		auth = self.opt.auth,
		db = self.opt.db or 0,
	}
	return redis.connect(conf)
end

-- Given a node (that is just a Ruby hash) give it a name just
-- concatenating the host and port. We use the node name as a key
-- to cache connections to that node.
function rediscluster:set_node_name(node)
	if not node.name then
		node.name = nodename(node)
	end
	if not node.slaves then
		local oldnode = self.name_node[node.name]
		if oldnode then
			node.slaves = oldnode.slaves
		end
	end
	self.name_node[node.name] = node
end

-- Contact the startup nodes and try to fetch the hash slots -> instances
-- map in order to initialize the @slots hash.
function rediscluster:initialize_slots_cache()
	self.slots = {}
	self.nodes = {}
	self.name_node = {}
	for _,startup_node in ipairs(self.startup_nodes) do
		local ok = pcall(function ()
			local name = nodename(startup_node)
			local conn = self.connections[name] or self:get_redis_link(startup_node)
			local list = conn:cluster("slots")
			for _,result in ipairs(list) do
				local ip,port,runid = table.unpack(result[3])
				local master_node = {
					host = ip,
					port = port,
					runid = runid,
					slaves = {},
				}
				self:set_node_name(master_node)
				for i=4,#result do
					local ip,port,runid = table.unpack(result[i])
					local slave_node = {
						host = ip,
						port = port,
						runid = runid,
					}
					self:set_node_name(slave_node)
					table.insert(master_node.slaves,slave_node)
				end
				for slot=tonumber(result[1]),tonumber(result[2]) do
					table.insert(self.nodes,master_node)
					self.slots[slot] = master_node
				end
			end
			self.refresh_table_asap = false
			if not self.connections[name] then
				self.connections[name] = conn
			end
		end)
		-- Exit the loop as long as the first node replies
		if ok then
			break
		end
	end
end

-- Flush the cache, mostly useful for debugging when we want to force
-- redirection.
function rediscluster:flush_slots_cache()
	self.slots = {}
end

-- Return the hash slot from the key.
function rediscluster:keyslot(key)
	-- Only hash what is inside {...} if there is such a pattern in the key.
	-- Note that the specification requires the content that is between
	-- the first { and the first } after the first {. If we found {} without
	-- nothing in the middle, the whole key is hashed as usually.
	local startpos = string.find(key,"{",1,true)
	if startpos then
		local endpos = string.find(key,"}",startpos+1,true)
		if endpos and endpos ~= startpos + 1 then
			key = string.sub(key,startpos+1,endpos-1)
		end
	end
	return crc16(key) % RedisClusterHashSlots
end

-- Return the first key in the command arguments.
--
-- Currently we just return argv[1], that is, the first argument
-- after the command name.
--
-- This is indeed the key for most commands, and when it is not true
-- the cluster redirection will point us to the right node anyway.
--
-- For commands we want to explicitly bad as they don't make sense
-- in the context of cluster, nil is returned.
function rediscluster:get_key_from_command(argv)
	local cmd,key = table.unpack(argv)
	cmd = string.lower(cmd)
	if cmd == "info" or
		cmd == "multi" or
		cmd == "exec" or
		cmd == "slaveof" or
		cmd == "config" or
		cmd == "shutdown" then
		return nil
	end
	-- Unknown commands, and all the commands having the key
	-- as first argument are handled here:
	-- set, get, ...
	return key
end

-- If the current number of connections is already the maximum number
-- allowed, close a random connection. This should be called every time
-- we cache a new connection in the @connections hash.
function rediscluster:close_existing_connection()
	local length = 0
	for name,conn in pairs(self.connections) do
		length = length + 1
	end
	if length >= self.max_connections then
		pcall(function ()
			local name,conn = next(self.connections)
			self.connections[name] = nil
			conn:disconnect()
		end)
	end
end

function rediscluster:close_all_connection()
	local connections = self.connections
	self.connections = setmetatable({},{__mode = "kv"})
	for name,conn in pairs(connections) do
		pcall(conn.disconnect,conn)
	end
end

function rediscluster:get_connection(node)
	if type(node) == "string" then
		local ip,port = string.match(node,"^([^:]+):([^:]+)$")
		node = {host=ip,port=port}
	end
	local name = node.name or nodename(node)
	local conn = self.connections[name]
	if not conn then
		conn = self:get_redis_link(node)
		self.connections[name] = conn
	end
	return self.connections[name]
end

-- Return a link to a random node, or raise an error if no node can be
-- contacted. This function is only called when we can't reach the node
-- associated with a given hash slot, or when we don't know the right
-- mapping.
-- The function will try to get a successful reply to the PING command,
-- otherwise the next node is tried.
function rediscluster:get_random_connection()
	-- shuffle
	local shuffle_idx = {}
	local startpos = 1
	local endpos = #self.nodes
	for i=startpos,endpos do
		shuffle_idx[i] = i
	end
	for i=startpos,endpos do
		local idx = math.random(i,endpos)
		local tmp = shuffle_idx[i]
		shuffle_idx[i] = shuffle_idx[idx]
		shuffle_idx[idx] = tmp
	end
	for i,idx in ipairs(shuffle_idx) do
		local ok,conn = pcall(function ()
			local node = self.nodes[idx]
			local conn = self.connections[node.name]
			if not conn then
				-- Connect the node if it is not connected
				conn = self:get_redis_link(node)
				if conn:ping() == "PONG" then
					self:close_existing_connection()
					self.connections[node.name] = conn
					return conn
				else
					-- If the connection is not good close it ASAP in order
					-- to avoid waiting for the GC finalizer. File
					-- descriptors are a rare resource.
					conn:disconnect()
				end
			else
				-- The node was already connected, test the connection.
				if conn:ping() == "PONG" then
					return conn
				end
			end
		end)
		if ok and conn then
			return conn
		end
	end
	error("Can't reach a single startup node.")
end

-- Given a slot return the link (Redis instance) to the mapped node.
-- Make sure to create a connection with the node if we don't have
-- one.
function rediscluster:get_connection_by_slot(slot)
	local node = self.slots[slot]
	-- If we don't know what the mapping is, return a random node.
	if not node then
		return self:get_random_connection()
	end
	if not self.connections[node.name] then
		local ok = pcall(function ()
			self:close_existing_connection()
			self.connections[node.name] = self:get_redis_link(node)
		end)
		if not ok then
			if self.opt.read_slave and node.slaves and #node.slaves > 0 then
				local slave_node = node.slaves[math.random(1,#node.slaves)]
				local ok2,conn = pcall(self.get_connection,self,slave_node)
				if ok2 then
					conn:readonly()		-- allow this connection read-slave
					return conn
				end
			end
			-- This will probably never happen with recent redis-rb
			-- versions because the connection is enstablished in a lazy
			-- way only when a command is called. However it is wise to
			-- handle an instance creation error of some kind.
			return self:get_random_connection()
		end
	end
	return self.connections[node.name]
end

-- Dispatch commands.
function rediscluster:call(...)
	local argv = table.pack(...)
	if self.refresh_table_asap then
		self:initialize_slots_cache()
	end
	local ttl = RedisClusterRequestTTL	-- Max number of redirections
	local err
	local asking = false
	local try_random_node = false
	while ttl > 0 do
		ttl = ttl - 1
		local key = self:get_key_from_command(argv)
		if not key then
			error("No way to dispatch this command to Redis Cluster: " .. tostring(argv[1]))
		end
		local conn
		local slot = self:keyslot(key)
		if asking then
			conn = self:get_connection(asking)
		elseif try_random_node then
			conn = self:get_random_connection()
			try_random_node = false
		else
			conn = self:get_connection_by_slot(slot)
		end
		local result = {pcall(function ()
			-- TODO: use pipelining to send asking and save a rtt.
			if asking then
				conn:asking()
			end
			asking = false
			local cmd = argv[1]
			local func = conn[cmd]
			return func(conn,table.unpack(argv,2))
		end)}
		local ok = result[1]
		if not ok then
			err = table.unpack(result,2)
			err = tostring(err)
			if err == "[Error: socket]" then
				-- may be nerver come here?
				try_random_node = true
				if ttl < RedisClusterRequestTTL/2 then
					skynet.sleep(10)
				end
			else
				-- err: ./lualib/skynet/socketchannel.lua:371: xxx
				err = string.match(err,".+:%d+:%s(.*)$") or err
				local errlist = {}
				for e in string.gmatch(err,"([^%s]+)%s?") do
					table.insert(errlist,e)
				end
				if (errlist[1] ~= "MOVED" and errlist[1] ~= "ASK") then
					error(err)
				else
					if errlist[1] == "ASK" then
						asking = true
					else
						-- Serve replied with MOVED. It's better for us to
						-- ask for CLUSTER SLOTS the next time.
						self.refresh_table_asap = true
					end
					local newslot = tonumber(errlist[2])
					local node_ip,node_port = string.match(errlist[3],"^([^:]+):([^:]+)$")
					local node = {
						host = node_ip,
						port = tonumber(node_port),
					}
					if not asking then
						self:set_node_name(node)
						self.slots[newslot] = node
					else
						asking = node
					end
				end
			end
		else
			return table.unpack(result,2)
		end
	end
	error(string.format("Too many Cluster redirections?,maybe node is disconnected (last error: %q)",err))
end

-- Currently we handle all the commands using method_missing for
-- simplicity. For a Cluster client actually it will be better to have
-- every single command as a method with the right arity and possibly
-- additional checks (example: RPOPLPUSH with same src/dst key, SORT
-- without GET or BY, and so forth).
setmetatable(rediscluster,{
	__index = function (t,cmd)
		t[cmd] = function (self,...)
			return self:call(cmd,...)
		end
		return t[cmd]
	end,
})

return _M


text:
local M = {}
setfenv(1, M) -- Remove external access to contain everything in the module

environment_id = 42

tags = {
    environment_id=environment_id
}

return M


text:
using Newtonsoft.Json;

namespace Ptv.Timetable.Api.Responses
{
    public class HealthCheckResponse
    {
        [JsonProperty("securityTokenOK")]
        public bool IsSecurityTokenValid { get; set; }

        [JsonProperty("clientClockOK")]
        public bool IsClientClockInSync { get; set; }

        [JsonProperty("memcacheOK")]
        public bool IsApiMemoryCacheOk { get; set; }

        [JsonProperty("databaseOK")]
        public bool IsApiDatabaseOk { get; set; }

        [JsonIgnore]
        public bool IsHealthyEnoughToConnect
        {
            get { return IsSecurityTokenValid && IsApiDatabaseOk; }
        }
    }
}


text:
/**
 * @file lv_cont.h
 *
 */

#ifndef LV_CONT_H
#define LV_CONT_H

#ifdef __cplusplus
extern "C" {
#endif

/*********************
 *      INCLUDES
 *********************/
#include "../lv_conf_internal.h"

#if LV_USE_CONT != 0

#include "../lv_core/lv_obj.h"

/*********************
 *      DEFINES
 *********************/

/**********************
 *      TYPEDEFS
 **********************/

/** Container layout options*/
enum {
    LV_LAYOUT_OFF = 0, /**< No layout */
    LV_LAYOUT_CENTER, /**< Center objects */

    /**
     * COLUMN:
     * - Place the object below each other
     * - Keep `pad_top` space on the top
     * - Keep `pad_inner` space between the objects
     */
    LV_LAYOUT_COLUMN_LEFT,      /**< Column left align*/
    LV_LAYOUT_COLUMN_MID,       /**< Column middle align*/
    LV_LAYOUT_COLUMN_RIGHT,     /**< Column right align*/

    /**
     * ROW:
     * - Place the object next to each other
     * - Keep `pad_left` space on the left
     * - Keep `pad_inner` space between the objects
     * - If the object which applies the layout has `base_dir == LV_BIDI_DIR_RTL`
     *   the row will start from the right applying `pad.right` space
     */
    LV_LAYOUT_ROW_TOP,          /**< Row top align*/
    LV_LAYOUT_ROW_MID,          /**< Row middle align*/
    LV_LAYOUT_ROW_BOTTOM,       /**< Row bottom align*/

    /**
     * PRETTY:
     * - Place the object next to each other
     * - If there is no more space start a new row
     * - Respect `pad_left` and `pad_right` when determining the available space in a row
     * - Keep `pad_inner` space between the objects in the same row
     * - Keep `pad_inner` space between the objects in rows
     * - Divide the remaining horizontal space equally
     */
    LV_LAYOUT_PRETTY_TOP,       /**< Row top align*/
    LV_LAYOUT_PRETTY_MID,       /**< Row middle align*/
    LV_LAYOUT_PRETTY_BOTTOM,    /**< Row bottom align*/

    /**
     * GRID
     * - Place the object next to each other
     * - If there is no more space start a new row
     * - Respect `pad_left` and `pad_right` when determining the available space in a row
     * - Keep `pad_inner` space between the objects in the same row
     * - Keep `pad_inner` space between the objects in rows
     * - Unlike `PRETTY`, `GRID` always keep `pad_inner` space horizontally between objects
     *   so it doesn't divide the remaining horizontal space equally
     */
    LV_LAYOUT_GRID,   /**< Align same-sized object into a grid*/

    _LV_LAYOUT_LAST
};
typedef uint8_t lv_layout_t;

/**
 * How to resize the container around the children.
 */
enum {
    LV_FIT_NONE,  /**< Do not change the size automatically*/
    LV_FIT_TIGHT, /**< Shrink wrap around the children */
    LV_FIT_PARENT, /**< Align the size to the parent's edge*/
    LV_FIT_MAX,  /**< Align the size to the parent's edge first but if there is an object out of it
                     then get larger */
    _LV_FIT_LAST
};
typedef uint8_t lv_fit_t;

typedef struct {
    /*Inherited from 'base_obj' so no inherited ext. */ /*Ext. of ancestor*/
    /*New data for this type */
    lv_layout_t layout : 4;     /*A layout from 'lv_layout_t' enum*/
    lv_fit_t fit_left : 2;   /*A fit type from `lv_fit_t` enum */
    lv_fit_t fit_right : 2;  /*A fit type from `lv_fit_t` enum */
    lv_fit_t fit_top : 2;    /*A fit type from `lv_fit_t` enum */
    lv_fit_t fit_bottom : 2; /*A fit type from `lv_fit_t` enum */
} lv_cont_ext_t;

/*Part of the container*/
enum {
    LV_CONT_PART_MAIN = LV_OBJ_PART_MAIN,
    _LV_CONT_PART_VIRTUAL_LAST = _LV_OBJ_PART_VIRTUAL_LAST,
    _LV_CONT_PART_REAL_LAST = _LV_OBJ_PART_REAL_LAST,
};

/**********************
 * GLOBAL PROTOTYPES
 **********************/

/**
 * Create a container objects
 * @param par pointer to an object, it will be the parent of the new container
 * @param copy pointer to a container object, if not NULL then the new object will be copied from it
 * @return pointer to the created container
 */
lv_obj_t * lv_cont_create(lv_obj_t * par, const lv_obj_t * copy);

/*=====================
 * Setter functions
 *====================*/

/**
 * Set a layout on a container
 * @param cont pointer to a container object
 * @param layout a layout from 'lv_cont_layout_t'
 */
void lv_cont_set_layout(lv_obj_t * cont, lv_layout_t layout);

/**
 * Set the fit policy in all 4 directions separately.
 * It tell how to change the container's size automatically.
 * @param cont pointer to a container object
 * @param left left fit policy from `lv_fit_t`
 * @param right right fit policy from `lv_fit_t`
 * @param top top fit policy from `lv_fit_t`
 * @param bottom bottom fit policy from `lv_fit_t`
 */
void lv_cont_set_fit4(lv_obj_t * cont, lv_fit_t left, lv_fit_t right, lv_fit_t top, lv_fit_t bottom);

/**
 * Set the fit policy horizontally and vertically separately.
 * It tells how to change the container's size automatically.
 * @param cont pointer to a container object
 * @param hor horizontal fit policy from `lv_fit_t`
 * @param ver vertical fit policy from `lv_fit_t`
 */
static inline void lv_cont_set_fit2(lv_obj_t * cont, lv_fit_t hor, lv_fit_t ver)
{
    lv_cont_set_fit4(cont, hor, hor, ver, ver);
}

/**
 * Set the fit policy in all 4 direction at once.
 * It tells how to change the container's size automatically.
 * @param cont pointer to a container object
 * @param fit fit policy from `lv_fit_t`
 */
static inline void lv_cont_set_fit(lv_obj_t * cont, lv_fit_t fit)
{
    lv_cont_set_fit4(cont, fit, fit, fit, fit);
}

/*=====================
 * Getter functions
 *====================*/

/**
 * Get the layout of a container
 * @param cont pointer to container object
 * @return the layout from 'lv_cont_layout_t'
 */
lv_layout_t lv_cont_get_layout(const lv_obj_t * cont);

/**
 * Get left fit mode of a container
 * @param cont pointer to a container object
 * @return an element of `lv_fit_t`
 */
lv_fit_t lv_cont_get_fit_left(const lv_obj_t * cont);

/**
 * Get right fit mode of a container
 * @param cont pointer to a container object
 * @return an element of `lv_fit_t`
 */
lv_fit_t lv_cont_get_fit_right(const lv_obj_t * cont);

/**
 * Get top fit mode of a container
 * @param cont pointer to a container object
 * @return an element of `lv_fit_t`
 */
lv_fit_t lv_cont_get_fit_top(const lv_obj_t * cont);

/**
 * Get bottom fit mode of a container
 * @param cont pointer to a container object
 * @return an element of `lv_fit_t`
 */
lv_fit_t lv_cont_get_fit_bottom(const lv_obj_t * cont);

/**********************
 *      MACROS
 **********************/

#endif /*LV_USE_CONT*/

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif /*LV_CONT_H*/


text:
<!DOCTYPE html>

	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
	<?php include ('metas.php');?>
	<title>Recuperar Contraseña Ciudad Placer</title>
  	<?php include ('links.php');?>
	<link rel="stylesheet" href="<?php echo base_url('dist/css/bootstrap.css') ?>">
	<link rel="stylesheet" href="<?php echo base_url('dist/css/form_perfil.css') ?>">
	<link rel="stylesheet" href="<?php echo base_url('dist/css/header.css') ?>">
	<link rel="stylesheet" href="<?php echo base_url('dist/css/user-select.css') ?>">

				<a class="logo" href="<?php echo base_url(); ?>">

			    	Ciudad
			    	Placer
						<img src="<?php echo base_url('dist/img/logo/apple-logo.png'); ?>" class="letra-com" title="Logo Ciudad Placer">

Compañia Ciudad Placer

Recuperar contraseña

					<?php echo form_open('recuperar/clave', 'class="form-inline submit" id="contactar_form"') ?>

							Correo
							<input maxlength="92" type='email' name='correo_usuarios' id='email_o_p' autocomplete="off" required/>

             				Revise su correo, recibira un link para restablecer su contraseña

							<input class='input_submit block-button' type="submit" value='Enviar'/>

					<?php echo form_close(); ?>


text:
/*var contextDashboard = addClass.create( {
    initialize : function(container)
    {
      this.form = container;
      this.filter_project = this.container.down('#filter_project');
      this.filter_project.observe('change', this.changeFilterAndSubmit.bindAsEventListener(this));
    },
    changeFilterAndSubmit : function () {
      this.submit();
    }
});
*/


text:
+++
Title = "Miguel Angel García"
image = "miguel-angel-garcia.png"
type = "speaker"
linktitle = "miguel-angel-garcia"
twitter = "magmax9"
+++

Soy DevOps Lead en RFranco Technologies, y lidiamos diariamente con muchos proyectos. Actualmente nuestro Jenkins cuenta con más de 8000 proyectos, la mayoría de los cuales han sido autogenerados, y permitimos que los desarrolladores tomen la iniciativa con ellos.


text:
package basic.multi_inherit;

public class Mother {
    protected void calm(){
        System.out.println("Mother calm");
    }
}