/*
 * Huffman encoder, part of New Generation Entropy library
 * Copyright (C) 2013-2016, Yann Collet.
 *
 * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *   * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License version 2 as published by the
 * Free Software Foundation. This program is dual-licensed; you may select
 * either version 2 of the GNU General Public License ("GPL") or BSD license
 * ("BSD").
 *
 * You can contact the author at :
 * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
 */

/* **************************************************************
*  Includes
****************************************************************/
#include "bitstream.h"
#include "fse.h" /* header compression */
#include "huf.h"
#include <linux/kernel.h>
#include <linux/string.h> /* memcpy, memset */

/* **************************************************************
*  Error Management
****************************************************************/
#define HUF_STATIC_ASSERT(c)                                   \
	{                                                      \
		enum { HUF_static_assert = 1 / (int)(!!(c)) }; \
	} /* use only *after* variable declarations */
#define CHECK_V_F(e, f)     \
	size_t const e = f; \
	if (ERR_isError(e)) \
	return f
#define CHECK_F(f)                        \
	{                                 \
		CHECK_V_F(_var_err__, f); \
	}

/* **************************************************************
*  Utils
****************************************************************/
unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue)
{
	return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 1);
}

/* *******************************************************
*  HUF : Huffman block compression
*********************************************************/
/* HUF_compressWeights() :
 * Same as FSE_compress(), but dedicated to huff0's weights compression.
 * The use case needs much less stack memory.
 * Note : all elements within weightTable are supposed to be <= HUF_TABLELOG_MAX.
 */
#define MAX_FSE_TABLELOG_FOR_HUFF_HEADER 6
size_t HUF_compressWeights_wksp(void *dst, size_t dstSize, const void *weightTable, size_t wtSize, void *workspace, size_t workspaceSize)
{
	BYTE *const ostart = (BYTE *)dst;
	BYTE *op = ostart;
	BYTE *const oend = ostart + dstSize;

	U32 maxSymbolValue = HUF_TABLELOG_MAX;
	U32 tableLog = MAX_FSE_TABLELOG_FOR_HUFF_HEADER;

	FSE_CTable *CTable;
	U32 *count;
	S16 *norm;
	size_t spaceUsed32 = 0;

	HUF_STATIC_ASSERT(sizeof(FSE_CTable) == sizeof(U32));

	CTable = (FSE_CTable *)((U32 *)workspace + spaceUsed32);
	spaceUsed32 += FSE_CTABLE_SIZE_U32(MAX_FSE_TABLELOG_FOR_HUFF_HEADER, HUF_TABLELOG_MAX);
	count = (U32 *)workspace + spaceUsed32;
	spaceUsed32 += HUF_TABLELOG_MAX + 1;
	norm = (S16 *)((U32 *)workspace + spaceUsed32);
	spaceUsed32 += ALIGN(sizeof(S16) * (HUF_TABLELOG_MAX + 1), sizeof(U32)) >> 2;

	if ((spaceUsed32 << 2) > workspaceSize)
		return ERROR(tableLog_tooLarge);
	workspace = (U32 *)workspace + spaceUsed32;
	workspaceSize -= (spaceUsed32 << 2);

	/* init conditions */
	if (wtSize <= 1)
		return 0; /* Not compressible */

	/* Scan input and build symbol stats */
	{
		CHECK_V_F(maxCount, FSE_count_simple(count, &maxSymbolValue, weightTable, wtSize));
		if (maxCount == wtSize)
			return 1; /* only a single symbol in src : rle */
		if (maxCount == 1)
			return 0; /* each symbol present maximum once => not compressible */
	}

	tableLog = FSE_optimalTableLog(tableLog, wtSize, maxSymbolValue);
	CHECK_F(FSE_normalizeCount(norm, tableLog, count, wtSize, maxSymbolValue));

	/* Write table description header */
	{
		CHECK_V_F(hSize, FSE_writeNCount(op, oend - op, norm, maxSymbolValue, tableLog));
		op += hSize;
	}

	/* Compress */
	CHECK_F(FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, workspace, workspaceSize));
	{
		CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, weightTable, wtSize, CTable));
		if (cSize == 0)
			return 0; /* not enough space for compressed data */
		op += cSize;
	}

	return op - ostart;
}

struct HUF_CElt_s {
	U16 val;
	BYTE nbBits;
}; /* typedef'd to HUF_CElt within "huf.h" */

/*! HUF_writeCTable_wksp() :
	`CTable` : Huffman tree to save, using huf representation.
	@return : size of saved CTable */
size_t HUF_writeCTable_wksp(void *dst, size_t maxDstSize, const HUF_CElt *CTable, U32 maxSymbolValue, U32 huffLog, void *workspace, size_t workspaceSize)
{
	BYTE *op = (BYTE *)dst;
	U32 n;

	BYTE *bitsToWeight;
	BYTE *huffWeight;
	size_t spaceUsed32 = 0;

	bitsToWeight = (BYTE *)((U32 *)workspace + spaceUsed32);
	spaceUsed32 += ALIGN(HUF_TABLELOG_MAX + 1, sizeof(U32)) >> 2;
	huffWeight = (BYTE *)((U32 *)workspace + spaceUsed32);
	spaceUsed32 += ALIGN(HUF_SYMBOLVALUE_MAX, sizeof(U32)) >> 2;

	if ((spaceUsed32 << 2) > workspaceSize)
		return ERROR(tableLog_tooLarge);
	workspace = (U32 *)workspace + spaceUsed32;
	workspaceSize -= (spaceUsed32 << 2);

	/* check conditions */
	if (maxSymbolValue > HUF_SYMBOLVALUE_MAX)
		return ERROR(maxSymbolValue_tooLarge);

	/* convert to weight */
	bitsToWeight[0] = 0;
	for (n = 1; n < huffLog + 1; n++)
		bitsToWeight[n] = (BYTE)(huffLog + 1 - n);
	for (n = 0; n < maxSymbolValue; n++)
		huffWeight[n] = bitsToWeight[CTable[n].nbBits];

	/* attempt weights compression by FSE */
	{
		CHECK_V_F(hSize, HUF_compressWeights_wksp(op + 1, maxDstSize - 1, huffWeight, maxSymbolValue, workspace, workspaceSize));
		if ((hSize > 1) & (hSize < maxSymbolValue / 2)) { /* FSE compressed */
			op[0] = (BYTE)hSize;
			return hSize + 1;
		}
	}

	/* write raw values as 4-bits (max : 15) */
	if (maxSymbolValue > (256 - 128))
		return ERROR(GENERIC); /* should not happen : likely means source cannot be compressed */
	if (((maxSymbolValue + 1) / 2) + 1 > maxDstSize)
		return ERROR(dstSize_tooSmall); /* not enough space within dst buffer */
	op[0] = (BYTE)(128 /*special case*/ + (maxSymbolValue - 1));
	huffWeight[maxSymbolValue] = 0; /* to be sure it doesn't cause msan issue in final combination */
	for (n = 0; n < maxSymbolValue; n += 2)
		op[(n / 2) + 1] = (BYTE)((huffWeight[n] << 4) + huffWeight[n + 1]);
	return ((maxSymbolValue + 1) / 2) + 1;
}

size_t HUF_readCTable_wksp(HUF_CElt *CTable, U32 maxSymbolValue, const void *src, size_t srcSize, void *workspace, size_t workspaceSize)
{
	U32 *rankVal;
	BYTE *huffWeight;
	U32 tableLog = 0;
	U32 nbSymbols = 0;
	size_t readSize;
	size_t spaceUsed32 = 0;

	rankVal = (U32 *)workspace + spaceUsed32;
	spaceUsed32 += HUF_TABLELOG_ABSOLUTEMAX + 1;
	huffWeight = (BYTE *)((U32 *)workspace + spaceUsed32);
	spaceUsed32 += ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2;

	if ((spaceUsed32 << 2) > workspaceSize)
		return ERROR(tableLog_tooLarge);
	workspace = (U32 *)workspace + spaceUsed32;
	workspaceSize -= (spaceUsed32 << 2);

	/* get symbol weights */
	readSize = HUF_readStats_wksp(huffWeight, HUF_SYMBOLVALUE_MAX + 1, rankVal, &nbSymbols, &tableLog, src, srcSize, workspace, workspaceSize);
	if (ERR_isError(readSize))
		return readSize;

	/* check result */
	if (tableLog > HUF_TABLELOG_MAX)
		return ERROR(tableLog_tooLarge);
	if (nbSymbols > maxSymbolValue + 1)
		return ERROR(maxSymbolValue_tooSmall);

	/* Prepare base value per rank */
	{
		U32 n, nextRankStart = 0;
		for (n = 1; n <= tableLog; n++) {
			U32 curr = nextRankStart;
			nextRankStart += (rankVal[n] << (n - 1));
			rankVal[n] = curr;
		}
	}

	/* fill nbBits */
	{
		U32 n;
		for (n = 0; n < nbSymbols; n++) {
			const U32 w = huffWeight[n];
			CTable[n].nbBits = (BYTE)(tableLog + 1 - w);
		}
	}

	/* fill val */
	{
		U16 nbPerRank[HUF_TABLELOG_MAX + 2] = {0}; /* support w=0=>n=tableLog+1 */
		U16 valPerRank[HUF_TABLELOG_MAX + 2] = {0};
		{
			U32 n;
			for (n = 0; n < nbSymbols; n++)
				nbPerRank[CTable[n].nbBits]++;
		}
		/* determine stating value per rank */
		valPerRank[tableLog + 1] = 0; /* for w==0 */
		{
			U16 min = 0;
			U32 n;
			for (n = tableLog; n > 0; n--) { /* start at n=tablelog <-> w=1 */
				valPerRank[n] = min;     /* get starting value within each rank */
				min += nbPerRank[n];
				min >>= 1;
			}
		}
		/* assign value within rank, symbol order */
		{
			U32 n;
			for (n = 0; n <= maxSymbolValue; n++)
				CTable[n].val = valPerRank[CTable[n].nbBits]++;
		}
	}

	return readSize;
}

typedef struct nodeElt_s {
	U32 count;
	U16 parent;
	BYTE byte;
	BYTE nbBits;
} nodeElt;

static U32 HUF_setMaxHeight(nodeElt *huffNode, U32 lastNonNull, U32 maxNbBits)
{
	const U32 largestBits = huffNode[lastNonNull].nbBits;
	if (largestBits <= maxNbBits)
		return largestBits; /* early exit : no elt > maxNbBits */

	/* there are several too large elements (at least >= 2) */
	{
		int totalCost = 0;
		const U32 baseCost = 1 << (largestBits - maxNbBits);
		U32 n = lastNonNull;

		while (huffNode[n].nbBits > maxNbBits) {
			totalCost += baseCost - (1 << (largestBits - huffNode[n].nbBits));
			huffNode[n].nbBits = (BYTE)maxNbBits;
			n--;
		} /* n stops at huffNode[n].nbBits <= maxNbBits */
		while (huffNode[n].nbBits == maxNbBits)
			n--; /* n end at index of smallest symbol using < maxNbBits */

		/* renorm totalCost */
		totalCost >>= (largestBits - maxNbBits); /* note : totalCost is necessarily a multiple of baseCost */

		/* repay normalized cost */
		{
			U32 const noSymbol = 0xF0F0F0F0;
			U32 rankLast[HUF_TABLELOG_MAX + 2];
			int pos;

			/* Get pos of last (smallest) symbol per rank */
			memset(rankLast, 0xF0, sizeof(rankLast));
			{
				U32 currNbBits = maxNbBits;
				for (pos = n; pos >= 0; pos--) {
					if (huffNode[pos].nbBits >= currNbBits)
						continue;
					currNbBits = huffNode[pos].nbBits; /* < maxNbBits */
					rankLast[maxNbBits - currNbBits] = pos;
				}
			}

			while (totalCost > 0) {
				U32 nBitsToDecrease = BIT_highbit32(totalCost) + 1;
				for (; nBitsToDecrease > 1; nBitsToDecrease--) {
					U32 highPos = rankLast[nBitsToDecrease];
					U32 lowPos = rankLast[nBitsToDecrease - 1];
					if (highPos == noSymbol)
						continue;
					if (lowPos == noSymbol)
						break;
					{
						U32 const highTotal = huffNode[highPos].count;
						U32 const lowTotal = 2 * huffNode[lowPos].count;
						if (highTotal <= lowTotal)
							break;
					}
				}
				/* only triggered when no more rank 1 symbol left => find closest one (note : there is necessarily at least one !) */
				/* HUF_MAX_TABLELOG test just to please gcc 5+; but it should not be necessary */
				while ((nBitsToDecrease <= HUF_TABLELOG_MAX) && (rankLast[nBitsToDecrease] == noSymbol))
					nBitsToDecrease++;
				totalCost -= 1 << (nBitsToDecrease - 1);
				if (rankLast[nBitsToDecrease - 1] == noSymbol)
					rankLast[nBitsToDecrease - 1] = rankLast[nBitsToDecrease]; /* this rank is no longer empty */
				huffNode[rankLast[nBitsToDecrease]].nbBits++;
				if (rankLast[nBitsToDecrease] == 0) /* special case, reached largest symbol */
					rankLast[nBitsToDecrease] = noSymbol;
				else {
					rankLast[nBitsToDecrease]--;
					if (huffNode[rankLast[nBitsToDecrease]].nbBits != maxNbBits - nBitsToDecrease)
						rankLast[nBitsToDecrease] = noSymbol; /* this rank is now empty */
				}
			} /* while (totalCost > 0) */

			while (totalCost < 0) {		       /* Sometimes, cost correction overshoot */
				if (rankLast[1] == noSymbol) { /* special case : no rank 1 symbol (using maxNbBits-1); let's create one from largest rank 0
								  (using maxNbBits) */
					while (huffNode[n].nbBits == maxNbBits)
						n--;
					huffNode[n + 1].nbBits--;
					rankLast[1] = n + 1;
					totalCost++;
					continue;
				}
				huffNode[rankLast[1] + 1].nbBits--;
				rankLast[1]++;
				totalCost++;
			}
		}
	} /* there are several too large elements (at least >= 2) */

	return maxNbBits;
}

typedef struct {
	U32 base;
	U32 curr;
} rankPos;

static void HUF_sort(nodeElt *huffNode, const U32 *count, U32 maxSymbolValue)
{
	rankPos rank[32];
	U32 n;

	memset(rank, 0, sizeof(rank));
	for (n = 0; n <= maxSymbolValue; n++) {
		U32 r = BIT_highbit32(count[n] + 1);
		rank[r].base++;
	}
	for (n = 30; n > 0; n--)
		rank[n - 1].base += rank[n].base;
	for (n = 0; n < 32; n++)
		rank[n].curr = rank[n].base;
	for (n = 0; n <= maxSymbolValue; n++) {
		U32 const c = count[n];
		U32 const r = BIT_highbit32(c + 1) + 1;
		U32 pos = rank[r].curr++;
		while ((pos > rank[r].base) && (c > huffNode[pos - 1].count))
			huffNode[pos] = huffNode[pos - 1], pos--;
		huffNode[pos].count = c;
		huffNode[pos].byte = (BYTE)n;
	}
}

/** HUF_buildCTable_wksp() :
 *  Same as HUF_buildCTable(), but using externally allocated scratch buffer.
 *  `workSpace` must be aligned on 4-bytes boundaries, and be at least as large as a table of 1024 unsigned.
 */
#define STARTNODE (HUF_SYMBOLVALUE_MAX + 1)
typedef nodeElt huffNodeTable[2 * HUF_SYMBOLVALUE_MAX + 1 + 1];
size_t HUF_buildCTable_wksp(HUF_CElt *tree, const U32 *count, U32 maxSymbolValue, U32 maxNbBits, void *workSpace, size_t wkspSize)
{
	nodeElt *const huffNode0 = (nodeElt *)workSpace;
	nodeElt *const huffNode = huffNode0 + 1;
	U32 n, nonNullRank;
	int lowS, lowN;
	U16 nodeNb = STARTNODE;
	U32 nodeRoot;

	/* safety checks */
	if (wkspSize < sizeof(huffNodeTable))
		return ERROR(GENERIC); /* workSpace is not large enough */
	if (maxNbBits == 0)
		maxNbBits = HUF_TABLELOG_DEFAULT;
	if (maxSymbolValue > HUF_SYMBOLVALUE_MAX)
		return ERROR(GENERIC);
	memset(huffNode0, 0, sizeof(huffNodeTable));

	/* sort, decreasing order */
	HUF_sort(huffNode, count, maxSymbolValue);

	/* init for parents */
	nonNullRank = maxSymbolValue;
	while (huffNode[nonNullRank].count == 0)
		nonNullRank--;
	lowS = nonNullRank;
	nodeRoot = nodeNb + lowS - 1;
	lowN = nodeNb;
	huffNode[nodeNb].count = huffNode[lowS].count + huffNode[lowS - 1].count;
	huffNode[lowS].parent = huffNode[lowS - 1].parent = nodeNb;
	nodeNb++;
	lowS -= 2;
	for (n = nodeNb; n <= nodeRoot; n++)
		huffNode[n].count = (U32)(1U << 30);
	huffNode0[0].count = (U32)(1U << 31); /* fake entry, strong barrier */

	/* create parents */
	while (nodeNb <= nodeRoot) {
		U32 n1 = (huffNode[lowS].count < huffNode[lowN].count) ? lowS-- : lowN++;
		U32 n2 = (huffNode[lowS].count < huffNode[lowN].count) ? lowS-- : lowN++;
		huffNode[nodeNb].count = huffNode[n1].count + huffNode[n2].count;
		huffNode[n1].parent = huffNode[n2].parent = nodeNb;
		nodeNb++;
	}

	/* distribute weights (unlimited tree height) */
	huffNode[nodeRoot].nbBits = 0;
	for (n = nodeRoot - 1; n >= STARTNODE; n--)
		huffNode[n].nbBits = huffNode[huffNode[n].parent].nbBits + 1;
	for (n = 0; n <= nonNullRank; n++)
		huffNode[n].nbBits = huffNode[huffNode[n].parent].nbBits + 1;

	/* enforce maxTableLog */
	maxNbBits = HUF_setMaxHeight(huffNode, nonNullRank, maxNbBits);

	/* fill result into tree (val, nbBits) */
	{
		U16 nbPerRank[HUF_TABLELOG_MAX + 1] = {0};
		U16 valPerRank[HUF_TABLELOG_MAX + 1] = {0};
		if (maxNbBits > HUF_TABLELOG_MAX)
			return ERROR(GENERIC); /* check fit into table */
		for (n = 0; n <= nonNullRank; n++)
			nbPerRank[huffNode[n].nbBits]++;
		/* determine stating value per rank */
		{
			U16 min = 0;
			for (n = maxNbBits; n > 0; n--) {
				valPerRank[n] = min; /* get starting value within each rank */
				min += nbPerRank[n];
				min >>= 1;
			}
		}
		for (n = 0; n <= maxSymbolValue; n++)
			tree[huffNode[n].byte].nbBits = huffNode[n].nbBits; /* push nbBits per symbol, symbol order */
		for (n = 0; n <= maxSymbolValue; n++)
			tree[n].val = valPerRank[tree[n].nbBits]++; /* assign value within rank, symbol order */
	}

	return maxNbBits;
}

static size_t HUF_estimateCompressedSize(HUF_CElt *CTable, const unsigned *count, unsigned maxSymbolValue)
{
	size_t nbBits = 0;
	int s;
	for (s = 0; s <= (int)maxSymbolValue; ++s) {
		nbBits += CTable[s].nbBits * count[s];
	}
	return nbBits >> 3;
}

static int HUF_validateCTable(const HUF_CElt *CTable, const unsigned *count, unsigned maxSymbolValue)
{
	int bad = 0;
	int s;
	for (s = 0; s <= (int)maxSymbolValue; ++s) {
		bad |= (count[s] != 0) & (CTable[s].nbBits == 0);
	}
	return !bad;
}

static void HUF_encodeSymbol(BIT_CStream_t *bitCPtr, U32 symbol, const HUF_CElt *CTable)
{
	BIT_addBitsFast(bitCPtr, CTable[symbol].val, CTable[symbol].nbBits);
}

size_t HUF_compressBound(size_t size) { return HUF_COMPRESSBOUND(size); }

#define HUF_FLUSHBITS(s)  BIT_flushBits(s)

#define HUF_FLUSHBITS_1(stream)                                            \
	if (sizeof((stream)->bitContainer) * 8 < HUF_TABLELOG_MAX * 2 + 7) \
	HUF_FLUSHBITS(stream)

#define HUF_FLUSHBITS_2(stream)                                            \
	if (sizeof((stream)->bitContainer) * 8 < HUF_TABLELOG_MAX * 4 + 7) \
	HUF_FLUSHBITS(stream)

size_t HUF_compress1X_usingCTable(void *dst, size_t dstSize, const void *src, size_t srcSize, const HUF_CElt *CTable)
{
	const BYTE *ip = (const BYTE *)src;
	BYTE *const ostart = (BYTE *)dst;
	BYTE *const oend = ostart + dstSize;
	BYTE *op = ostart;
	size_t n;
	BIT_CStream_t bitC;

	/* init */
	if (dstSize < 8)
		return 0; /* not enough space to compress */
	{
		size_t const initErr = BIT_initCStream(&bitC, op, oend - op);
		if (HUF_isError(initErr))
			return 0;
	}

	n = srcSize & ~3; /* join to mod 4 */
	switch (srcSize & 3) {
	case 3: HUF_encodeSymbol(&bitC, ip[n + 2], CTable); HUF_FLUSHBITS_2(&bitC);
	case 2: HUF_encodeSymbol(&bitC, ip[n + 1], CTable); HUF_FLUSHBITS_1(&bitC);
	case 1: HUF_encodeSymbol(&bitC, ip[n + 0], CTable); HUF_FLUSHBITS(&bitC);
	case 0:
	default:;
	}

	for (; n > 0; n -= 4) { /* note : n&3==0 at this stage */
		HUF_encodeSymbol(&bitC, ip[n - 1], CTable);
		HUF_FLUSHBITS_1(&bitC);
		HUF_encodeSymbol(&bitC, ip[n - 2], CTable);
		HUF_FLUSHBITS_2(&bitC);
		HUF_encodeSymbol(&bitC, ip[n - 3], CTable);
		HUF_FLUSHBITS_1(&bitC);
		HUF_encodeSymbol(&bitC, ip[n - 4], CTable);
		HUF_FLUSHBITS(&bitC);
	}

	return BIT_closeCStream(&bitC);
}

size_t HUF_compress4X_usingCTable(void *dst, size_t dstSize, const void *src, size_t srcSize, const HUF_CElt *CTable)
{
	size_t const segmentSize = (srcSize + 3) / 4; /* first 3 segments */
	const BYTE *ip = (const BYTE *)src;
	const BYTE *const iend = ip + srcSize;
	BYTE *const ostart = (BYTE *)dst;
	BYTE *const oend = ostart + dstSize;
	BYTE *op = ostart;

	if (dstSize < 6 + 1 + 1 + 1 + 8)
		return 0; /* minimum space to compress successfully */
	if (srcSize < 12)
		return 0; /* no saving possible : too small input */
	op += 6;	  /* jumpTable */

	{
		CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend - op, ip, segmentSize, CTable));
		if (cSize == 0)
			return 0;
		ZSTD_writeLE16(ostart, (U16)cSize);
		op += cSize;
	}

	ip += segmentSize;
	{
		CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend - op, ip, segmentSize, CTable));
		if (cSize == 0)
			return 0;
		ZSTD_writeLE16(ostart + 2, (U16)cSize);
		op += cSize;
	}

	ip += segmentSize;
	{
		CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend - op, ip, segmentSize, CTable));
		if (cSize == 0)
			return 0;
		ZSTD_writeLE16(ostart + 4, (U16)cSize);
		op += cSize;
	}

	ip += segmentSize;
	{
		CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend - op, ip, iend - ip, CTable));
		if (cSize == 0)
			return 0;
		op += cSize;
	}

	return op - ostart;
}

static size_t HUF_compressCTable_internal(BYTE *const ostart, BYTE *op, BYTE *const oend, const void *src, size_t srcSize, unsigned singleStream,
					  const HUF_CElt *CTable)
{
	size_t const cSize =
	    singleStream ? HUF_compress1X_usingCTable(op, oend - op, src, srcSize, CTable) : HUF_compress4X_usingCTable(op, oend - op, src, srcSize, CTable);
	if (HUF_isError(cSize)) {
		return cSize;
	}
	if (cSize == 0) {
		return 0;
	} /* uncompressible */
	op += cSize;
	/* check compressibility */
	if ((size_t)(op - ostart) >= srcSize - 1) {
		return 0;
	}
	return op - ostart;
}

/* `workSpace` must a table of at least 1024 unsigned */
static size_t HUF_compress_internal(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned huffLog,
				    unsigned singleStream, void *workSpace, size_t wkspSize, HUF_CElt *oldHufTable, HUF_repeat *repeat, int preferRepeat)
{
	BYTE *const ostart = (BYTE *)dst;
	BYTE *const oend = ostart + dstSize;
	BYTE *op = ostart;

	U32 *count;
	size_t const countSize = sizeof(U32) * (HUF_SYMBOLVALUE_MAX + 1);
	HUF_CElt *CTable;
	size_t const CTableSize = sizeof(HUF_CElt) * (HUF_SYMBOLVALUE_MAX + 1);

	/* checks & inits */
	if (wkspSize < sizeof(huffNodeTable) + countSize + CTableSize)
		return ERROR(GENERIC);
	if (!srcSize)
		return 0; /* Uncompressed (note : 1 means rle, so first byte must be correct) */
	if (!dstSize)
		return 0; /* cannot fit within dst budget */
	if (srcSize > HUF_BLOCKSIZE_MAX)
		return ERROR(srcSize_wrong); /* curr block size limit */
	if (huffLog > HUF_TABLELOG_MAX)
		return ERROR(tableLog_tooLarge);
	if (!maxSymbolValue)
		maxSymbolValue = HUF_SYMBOLVALUE_MAX;
	if (!huffLog)
		huffLog = HUF_TABLELOG_DEFAULT;

	count = (U32 *)workSpace;
	workSpace = (BYTE *)workSpace + countSize;
	wkspSize -= countSize;
	CTable = (HUF_CElt *)workSpace;
	workSpace = (BYTE *)workSpace + CTableSize;
	wkspSize -= CTableSize;

	/* Heuristic : If we don't need to check the validity of the old table use the old table for small inputs */
	if (preferRepeat && repeat && *repeat == HUF_repeat_valid) {
		return HUF_compressCTable_internal(ostart, op, oend, src, srcSize, singleStream, oldHufTable);
	}

	/* Scan input and build symbol stats */
	{
		CHECK_V_F(largest, FSE_count_wksp(count, &maxSymbolValue, (const BYTE *)src, srcSize, (U32 *)workSpace));
		if (largest == srcSize) {
			*ostart = ((const BYTE *)src)[0];
			return 1;
		} /* single symbol, rle */
		if (largest <= (srcSize >> 7) + 1)
			return 0; /* Fast heuristic : not compressible enough */
	}

	/* Check validity of previous table */
	if (repeat && *repeat == HUF_repeat_check && !HUF_validateCTable(oldHufTable, count, maxSymbolValue)) {
		*repeat = HUF_repeat_none;
	}
	/* Heuristic : use existing table for small inputs */
	if (preferRepeat && repeat && *repeat != HUF_repeat_none) {
		return HUF_compressCTable_internal(ostart, op, oend, src, srcSize, singleStream, oldHufTable);
	}

	/* Build Huffman Tree */
	huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue);
	{
		CHECK_V_F(maxBits, HUF_buildCTable_wksp(CTable, count, maxSymbolValue, huffLog, workSpace, wkspSize));
		huffLog = (U32)maxBits;
		/* Zero the unused symbols so we can check it for validity */
		memset(CTable + maxSymbolValue + 1, 0, CTableSize - (maxSymbolValue + 1) * sizeof(HUF_CElt));
	}

	/* Write table description header */
	{
		CHECK_V_F(hSize, HUF_writeCTable_wksp(op, dstSize, CTable, maxSymbolValue, huffLog, workSpace, wkspSize));
		/* Check if using the previous table will be beneficial */
		if (repeat && *repeat != HUF_repeat_none) {
			size_t const oldSize = HUF_estimateCompressedSize(oldHufTable, count, maxSymbolValue);
			size_t const newSize = HUF_estimateCompressedSize(CTable, count, maxSymbolValue);
			if (oldSize <= hSize + newSize || hSize + 12 >= srcSize) {
				return HUF_compressCTable_internal(ostart, op, oend, src, srcSize, singleStream, oldHufTable);
			}
		}
		/* Use the new table */
		if (hSize + 12ul >= srcSize) {
			return 0;
		}
		op += hSize;
		if (repeat) {
			*repeat = HUF_repeat_none;
		}
		if (oldHufTable) {
			memcpy(oldHufTable, CTable, CTableSize);
		} /* Save the new table */
	}
	return HUF_compressCTable_internal(ostart, op, oend, src, srcSize, singleStream, CTable);
}

size_t HUF_compress1X_wksp(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned huffLog, void *workSpace,
			   size_t wkspSize)
{
	return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 1 /* single stream */, workSpace, wkspSize, NULL, NULL, 0);
}

size_t HUF_compress1X_repeat(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned huffLog, void *workSpace,
			     size_t wkspSize, HUF_CElt *hufTable, HUF_repeat *repeat, int preferRepeat)
{
	return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 1 /* single stream */, workSpace, wkspSize, hufTable, repeat,
				     preferRepeat);
}

size_t HUF_compress4X_wksp(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned huffLog, void *workSpace,
			   size_t wkspSize)
{
	return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 0 /* 4 streams */, workSpace, wkspSize, NULL, NULL, 0);
}

size_t HUF_compress4X_repeat(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned huffLog, void *workSpace,
			     size_t wkspSize, HUF_CElt *hufTable, HUF_repeat *repeat, int preferRepeat)
{
	return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 0 /* 4 streams */, workSpace, wkspSize, hufTable, repeat,
				     preferRepeat);
}


Advanced usage instructions for the Independent JPEG Group's JPEG software
==========================================================================

This file describes cjpeg's "switches for wizards".

The "wizard" switches are intended for experimentation with JPEG by persons
who are reasonably knowledgeable about the JPEG standard.  If you don't know
what you are doing, DON'T USE THESE SWITCHES.  You'll likely produce files
with worse image quality and/or poorer compression than you'd get from the
default settings.  Furthermore, these switches must be used with caution
when making files intended for general use, because not all JPEG decoders
will support unusual JPEG parameter settings.

Quantization Table Adjustment
-----------------------------

Ordinarily, cjpeg starts with a default set of tables (the same ones given
as examples in the JPEG standard) and scales them up or down according to
the -quality setting.  The details of the scaling algorithm can be found in
jcparam.c.  At very low quality settings, some quantization table entries
can get scaled up to values exceeding 255.  Although 2-byte quantization
values are supported by the IJG software, this feature is not in baseline
JPEG and is not supported by all implementations.  If you need to ensure
wide compatibility of low-quality files, you can constrain the scaled
quantization values to no more than 255 by giving the -baseline switch.
Note that use of -baseline will result in poorer quality for the same file
size, since more bits than necessary are expended on higher AC coefficients.

You can substitute a different set of quantization values by using the
-qtables switch:

	-qtables file	Use the quantization tables given in the named file.

The specified file should be a text file containing decimal quantization
values.  The file should contain one to four tables, each of 64 elements.
The tables are implicitly numbered 0,1,etc. in order of appearance.  Table
entries appear in normal array order (NOT in the zigzag order in which they
will be stored in the JPEG file).

Quantization table files are free format, in that arbitrary whitespace can
appear between numbers.  Also, comments can be included: a comment starts
with '#' and extends to the end of the line.  Here is an example file that
duplicates the default quantization tables:

	# Quantization tables given in JPEG spec, section K.1

	# This is table 0 (the luminance table):
	  16  11  10  16  24  40  51  61
	  12  12  14  19  26  58  60  55
	  14  13  16  24  40  57  69  56
	  14  17  22  29  51  87  80  62
	  18  22  37  56  68 109 103  77
	  24  35  55  64  81 104 113  92
	  49  64  78  87 103 121 120 101
	  72  92  95  98 112 100 103  99

	# This is table 1 (the chrominance table):
	  17  18  24  47  99  99  99  99
	  18  21  26  66  99  99  99  99
	  24  26  56  99  99  99  99  99
	  47  66  99  99  99  99  99  99
	  99  99  99  99  99  99  99  99
	  99  99  99  99  99  99  99  99
	  99  99  99  99  99  99  99  99
	  99  99  99  99  99  99  99  99

If the -qtables switch is used without -quality, then the specified tables
are used exactly as-is.  If both -qtables and -quality are used, then the
tables taken from the file are scaled in the same fashion that the default
tables would be scaled for that quality setting.  If -baseline appears, then
the quantization values are constrained to the range 1-255.

By default, cjpeg will use quantization table 0 for luminance components and
table 1 for chrominance components.  To override this choice, use the -qslots
switch:

	-qslots N[,...]		Select which quantization table to use for
				each color component.

The -qslots switch specifies a quantization table number for each color
component, in the order in which the components appear in the JPEG SOF marker.
For example, to create a separate table for each of Y,Cb,Cr, you could
provide a -qtables file that defines three quantization tables and say
"-qslots 0,1,2".  If -qslots gives fewer table numbers than there are color
components, then the last table number is repeated as necessary.

Sampling Factor Adjustment
--------------------------

By default, cjpeg uses 2:1 horizontal and vertical downsampling when
compressing YCbCr data, and no downsampling for all other color spaces.
You can override this default with the -sample switch:

	-sample HxV[,...]	Set JPEG sampling factors for each color
				component.

The -sample switch specifies the JPEG sampling factors for each color
component, in the order in which they appear in the JPEG SOF marker.
If you specify fewer HxV pairs than there are components, the remaining
components are set to 1x1 sampling.  For example, the default YCbCr setting
is equivalent to "-sample 2x2,1x1,1x1", which can be abbreviated to
"-sample 2x2".

There are still some JPEG decoders in existence that support only 2x1
sampling (also called 4:2:2 sampling).  Compatibility with such decoders can
be achieved by specifying "-sample 2x1".  This is not recommended unless
really necessary, since it increases file size and encoding/decoding time
with very little quality gain.

Multiple Scan / Progression Control
-----------------------------------

By default, cjpeg emits a single-scan sequential JPEG file.  The
-progressive switch generates a progressive JPEG file using a default series
of progression parameters.  You can create multiple-scan sequential JPEG
files or progressive JPEG files with custom progression parameters by using
the -scans switch:

	-scans file	Use the scan sequence given in the named file.

The specified file should be a text file containing a "scan script".
The script specifies the contents and ordering of the scans to be emitted.
Each entry in the script defines one scan.  A scan definition specifies
the components to be included in the scan, and for progressive JPEG it also
specifies the progression parameters Ss,Se,Ah,Al for the scan.  Scan
definitions are separated by semicolons (';').  A semicolon after the last
scan definition is optional.

Each scan definition contains one to four component indexes, optionally
followed by a colon (':') and the four progressive-JPEG parameters.  The
component indexes denote which color component(s) are to be transmitted in
the scan.  Components are numbered in the order in which they appear in the
JPEG SOF marker, with the first component being numbered 0.  (Note that these
indexes are not the "component ID" codes assigned to the components, just
positional indexes.)

The progression parameters for each scan are:
	Ss	Zigzag index of first coefficient included in scan
	Se	Zigzag index of last coefficient included in scan
	Ah	Zero for first scan of a coefficient, else Al of prior scan
	Al	Successive approximation low bit position for scan
If the progression parameters are omitted, the values 0,63,0,0 are used,
producing a sequential JPEG file.  cjpeg automatically determines whether
the script represents a progressive or sequential file, by observing whether
Ss and Se values other than 0 and 63 appear.  (The -progressive switch is
not needed to specify this; in fact, it is ignored when -scans appears.)
The scan script must meet the JPEG restrictions on progression sequences.
(cjpeg checks that the spec's requirements are obeyed.)

Scan script files are free format, in that arbitrary whitespace can appear
between numbers and around punctuation.  Also, comments can be included: a
comment starts with '#' and extends to the end of the line.  For additional
legibility, commas or dashes can be placed between values.  (Actually, any
single punctuation character other than ':' or ';' can be inserted.)  For
example, the following two scan definitions are equivalent:
	0 1 2: 0 63 0 0;
	0,1,2 : 0-63, 0,0 ;

Here is an example of a scan script that generates a partially interleaved
sequential JPEG file:

	0;			# Y only in first scan
	1 2;			# Cb and Cr in second scan

Here is an example of a progressive scan script using only spectral selection
(no successive approximation):

	# Interleaved DC scan for Y,Cb,Cr:
	0,1,2: 0-0,   0, 0 ;
	# AC scans:
	0:     1-2,   0, 0 ;	# First two Y AC coefficients
	0:     3-5,   0, 0 ;	# Three more
	1:     1-63,  0, 0 ;	# All AC coefficients for Cb
	2:     1-63,  0, 0 ;	# All AC coefficients for Cr
	0:     6-9,   0, 0 ;	# More Y coefficients
	0:     10-63, 0, 0 ;	# Remaining Y coefficients

Here is an example of a successive-approximation script.  This is equivalent
to the default script used by "cjpeg -progressive" for YCbCr images:

	# Initial DC scan for Y,Cb,Cr (lowest bit not sent)
	0,1,2: 0-0,   0, 1 ;
	# First AC scan: send first 5 Y AC coefficients, minus 2 lowest bits:
	0:     1-5,   0, 2 ;
	# Send all Cr,Cb AC coefficients, minus lowest bit:
	# (chroma data is usually too small to be worth subdividing further;
	#  but note we send Cr first since eye is least sensitive to Cb)
	2:     1-63,  0, 1 ;
	1:     1-63,  0, 1 ;
	# Send remaining Y AC coefficients, minus 2 lowest bits:
	0:     6-63,  0, 2 ;
	# Send next-to-lowest bit of all Y AC coefficients:
	0:     1-63,  2, 1 ;
	# At this point we've sent all but the lowest bit of all coefficients.
	# Send lowest bit of DC coefficients
	0,1,2: 0-0,   1, 0 ;
	# Send lowest bit of AC coefficients
	2:     1-63,  1, 0 ;
	1:     1-63,  1, 0 ;
	# Y AC lowest bit scan is last; it's usually the largest scan
	0:     1-63,  1, 0 ;

It may be worth pointing out that this script is tuned for quality settings
of around 50 to 75.  For lower quality settings, you'd probably want to use
a script with fewer stages of successive approximation (otherwise the
initial scans will be really bad).  For higher quality settings, you might
want to use more stages of successive approximation (so that the initial
scans are not too large).


class AddSubmissionLimitToChallengeRounds < ActiveRecord::Migration[5.1]
  def change
    add_column :challenge_rounds, :submission_limit, :integer
    add_column :challenge_rounds, :submission_limit_period_cd, :string
  end
end


module.exports = require('../../../lint-staged.config.base');


#include "types.h"

#include <SDL_ttf.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

#include "helper.h"
#include "render.h"

#ifdef DBG
#include <assert.h>
#endif

extern LinkList animationsList[];
extern TTF_Font* font;
extern SDL_Renderer* renderer;
SDL_Color BLACK = {0, 0, 0, 255};
SDL_Color WHITE = {255, 255, 255, 255};
void initTexture(Texture* self, SDL_Texture* origin, int width, int height,
                 int frames) {
  self->origin = origin;
  self->width = width;
  self->height = height;
  self->frames = frames;
  self->crops = malloc(sizeof(SDL_Rect) * frames);
  // self->crops = malloc(sizeof(SDL_Rect) * frames);
}
void destroyTexture(Texture* self) {
#ifdef DBG
  assert(self);
#endif
  free(self->crops);
  free(self);
}
bool initText(Text* self, const char* str, SDL_Color color) {
  self->color = color;
  strcpy(self->text, str);
  // Render text surface
  SDL_Surface* textSurface = TTF_RenderText_Solid(font, str, color);
  if (textSurface == NULL) {
    printf("Unable to render text surface! SDL_ttf Error: %s\n",
           TTF_GetError());
  } else {
    // Create texture from surface pixels
    SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, textSurface);
    self->width = textSurface->w;
    self->height = textSurface->h;
    SDL_FreeSurface(textSurface);
    if (texture == NULL) {
      printf("Unable to create texture from rendered text! SDL Error: %s\n",
             SDL_GetError());
    } else {
      self->origin = texture;
      return true;
    }
  }
  return false;
}
Text* createText(const char* str, SDL_Color color) {
  Text* self = malloc(sizeof(Text));
  initText(self, str, color);
  return self;
}
void setText(Text* self, const char* str) {
  if (!strcmp(str, self->text)) return;
  SDL_DestroyTexture(self->origin);
  initText(self, str, self->color);
}
void destroyText(Text* self) {
  SDL_DestroyTexture(self->origin);
  free(self);
}
void initEffect(Effect* self, int duration, int length, SDL_BlendMode mode) {
  self->keys = malloc(sizeof(SDL_Color) * length);
  self->duration = duration;
  self->length = length;
  self->currentFrame = 0;
  self->mode = mode;
}
// deep copy
void copyEffect(const Effect* src, Effect* dest) {
  memcpy(dest, src, sizeof(Effect));
  dest->keys = malloc(sizeof(SDL_Color) * src->length);
  memcpy(dest->keys, src->keys, sizeof(SDL_Color) * src->length);
}
void destroyEffect(Effect* self) {
  if (self) {
    free(self->keys);
    free(self);
  }
}

void initAnimation(Animation* self, Texture* origin, const Effect* effect,
                   LoopType lp, int duration, int x, int y,
                   SDL_RendererFlip flip, double angle, At at) {
  // will deep copy effect
  self->origin = origin;
  if (effect) {
    self->effect = malloc(sizeof(Effect));
    copyEffect(effect, self->effect);
  } else {
    self->effect = NULL;
  }
  self->lp = lp;
  self->duration = duration;
  self->currentFrame = 0;
  self->x = x;
  self->y = y;
  self->flip = flip;
  self->angle = angle;
  self->at = at;
  self->bind = NULL;
  self->strongBind = false;
  self->scaled = true;
  self->lifeSpan = duration;
}
Animation* createAnimation(Texture* origin, const Effect* effect, LoopType lp,
                           int duration, int x, int y, SDL_RendererFlip flip,
                           double angle, At at) {
  Animation* self = malloc(sizeof(Animation));
  initAnimation(self, origin, effect, lp, duration, x, y, flip, angle, at);
  return self;
}
void destroyAnimation(Animation* self) {
  destroyEffect(self->effect);
  free(self);
}
void copyAnimation(Animation* src, Animation* dest) {
  memcpy(dest, src, sizeof(Animation));
  if (src->effect) {
    dest->effect = malloc(sizeof(Effect));
    copyEffect(src->effect, dest->effect);
  }
}

void initLinkNode(LinkNode* self) {
  self->nxt = self->pre = self->element = NULL;
}
LinkNode* createLinkNode(void* element) {
  LinkNode* self = malloc(sizeof(LinkNode));
  initLinkNode(self);
  self->element = element;
  return self;
}
void initLinkList(LinkList* self) { self->head = self->tail = NULL; }
LinkList* createLinkList() {
  LinkList* self = malloc(sizeof(LinkList));
  initLinkList(self);
  return self;
}
void pushLinkNodeAtHead(LinkList* list, LinkNode* node) {
  if (list->head == NULL) {
    list->head = list->tail = node;
  } else {
    node->nxt = list->head;
    list->head->pre = node;
    list->head = node;
  }
}
void pushLinkNode(LinkList* list, LinkNode* node) {
  if (list->head == NULL) {
    list->head = list->tail = node;
  } else {
    list->tail->nxt = node;
    node->pre = list->tail;

    list->tail = node;
  }
}
void removeLinkNode(LinkList* list, LinkNode* node) {
  if (node->pre) {
    node->pre->nxt = node->nxt;
  } else {
    list->head = node->nxt;
  }
  if (node->nxt) {
    node->nxt->pre = node->pre;
  } else {
    list->tail = node->pre;
  }
  free(node);
}
void destroyLinkList(LinkList* self) {
  for (LinkNode *p = self->head, *nxt; p; p = nxt) {
    nxt = p->nxt;
    free(p);
  }
  free(self);
}
void destroyAnimationsByLinkList(LinkList* list) {
  for (LinkNode *p = list->head, *nxt; p; p = nxt) {
    nxt = p->nxt;
    destroyAnimation(p->element);
    removeLinkNode(list, p);
  }
}
void removeAnimationFromLinkList(LinkList* self, Animation* ani) {
  for (LinkNode* p = self->head; p; p = p->nxt)
    if (p->element == ani) {
      removeLinkNode(self, p);
      destroyAnimation(ani);
      break;
    }
}
void changeSpriteDirection(LinkNode* self, Direction newDirection) {
  Sprite* sprite = self->element;
  if (sprite->direction == (1 ^ newDirection)) return;
  sprite->direction = newDirection;
  if (newDirection == LEFT || newDirection == RIGHT)
    sprite->face = newDirection;
  if (self->nxt) {
    Sprite* nextSprite = self->nxt->element;
    nextSprite->buffer[nextSprite->bufferSize++] =
        (PositionBuffer){sprite->x, sprite->y, sprite->direction};
  }
}
void initScore(Score* score) { memset(score, 0, sizeof(Score)); }
Score* createScore() {
  Score* score = malloc(sizeof(Score));
  initScore(score);
  return score;
}
void destroyScore(Score* self) { free(self); }
void calcScore(Score* self) {
  if (!self->got) {
    self->rank = 0;
    return;
  }
  extern int gameLevel;
  self->rank = (double)self->damage / self->got +
               (double)self->stand / self->got + self->got * 50 +
               self->killed * 100;
  self->rank *= gameLevel + 1;
}
void addScore(Score* a, Score* b) {
  a->got += b->got;
  a->damage += b->damage;
  a->killed += b->killed;
  a->stand += b->stand;
  calcScore(a);
}


/*
Copyright IBM Corp. 2016 All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

		 http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package clilogging

import (
	"fmt"

	"github.com/inklabsfoundation/inkchain/common/flogging"

	"github.com/spf13/cobra"
)

const (
	loggingFuncName = "logging"
	shortDes        = "Log levels: getlevel|setlevel|revertlevels."
	longDes         = "Log levels: getlevel|setlevel|revertlevels."
)

var logger = flogging.MustGetLogger("cli/logging")

// Cmd returns the cobra command for Logging
func Cmd(cf *LoggingCmdFactory) *cobra.Command {
	loggingCmd.AddCommand(getLevelCmd(cf))
	loggingCmd.AddCommand(setLevelCmd(cf))
	loggingCmd.AddCommand(revertLevelsCmd(cf))

	return loggingCmd
}

var loggingCmd = &cobra.Command{
	Use:   loggingFuncName,
	Short: fmt.Sprint(shortDes),
	Long:  fmt.Sprint(longDes),
}


From: Maarten ter Huurne <maarten@treewalker.org>
Date: Sun, 14 Sep 2014 23:58:34 +0200
Subject: Do not create backup of old installed binary

This is a rather unusual feature that packagers will not expect.

Signed-off-by: Maarten ter Huurne <maarten@treewalker.org>
[baruch: update for 4.6.2]
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
---
 Makefile.in | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/Makefile.in b/Makefile.in
index 187a69b..65549e9 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -83,12 +83,9 @@ screen: $(OFILES)
 	    $(OPTIONS) $(CFLAGS) $<

 install_bin: .version screen installdirs
-	-if [ -f $(DESTDIR)$(bindir)/$(SCREEN) ] && [ ! -f $(DESTDIR)$(bindir)/$(SCREEN).old ]; \
-		then mv $(DESTDIR)$(bindir)/$(SCREEN) $(DESTDIR)$(bindir)/$(SCREEN).old; fi
 	$(INSTALL_PROGRAM) screen $(DESTDIR)$(bindir)/$(SCREEN)
 	-chown root $(DESTDIR)$(bindir)/$(SCREEN) && chmod 4755 $(DESTDIR)$(bindir)/$(SCREEN)
 # This doesn't work if $(bindir)/screen is a symlink
-	-if [ -f $(DESTDIR)$(bindir)/screen ] && [ ! -f $(DESTDIR)$(bindir)/screen.old ]; then mv $(DESTDIR)$(bindir)/screen $(DESTDIR)$(bindir)/screen.old; fi
 	rm -f $(DESTDIR)$(bindir)/screen
 	(cd $(DESTDIR)$(bindir) && ln -f -s $(SCREEN) screen)
 	cp $(srcdir)/utf8encodings/?? $(DESTDIR)$(SCREENENCODINGS)
@@ -113,7 +110,6 @@ installdirs:
 uninstall: .version
 	rm -f $(DESTDIR)$(bindir)/$(SCREEN)
 	rm -f $(DESTDIR)$(bindir)/screen
-	-mv $(DESTDIR)$(bindir)/screen.old $(DESTDIR)$(bindir)/screen
 	rm -f $(DESTDIR)$(ETCSCREENRC)
 	cd doc; $(MAKE) uninstall

--
1.8.4.5


<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
  <PropertyGroup>
    <TargetFrameworks>netstandard1.5</TargetFrameworks>
	<Product>SharpRepository for AzureDocumentDb</Product>
	<Authors>Ben Griswold, Jeff Treuting</Authors>
    <Description>SharpRepository generic repository Azure DocumentDb implementation</Description>
    <Summary>Written in C#, includes support for various relational, document and object databases including Entity Framework, RavenDB, MongoDB, CouchDB and Db4o. SharpRepository includes Xml and InMemory repository implementations as well. SharpRepository offers built-in caching options for AppFabric, memcached and the standard System.Runtime.Caching. SharpRepository also supports Specifications, FetchStrategies, Batches and Traits!</Summary>
	<PackageId>SharpRepository.AzureDocumentDbRepository</PackageId>
    <PackageVersion>2.0.2-alpha4</PackageVersion>
	<PackageReleaseNotes>2.0.2-alpha4: configurable via appsettings.json</PackageReleaseNotes>
	<PackageTags>SharpRepository Repository Azure DocumentDb</PackageTags>
	<PackageIconUrl>https://user-images.githubusercontent.com/6349515/28491142-7b6350c4-6eeb-11e7-9c5b-e3b8ef1e73b8.png</PackageIconUrl>
	<PackageProjectUrl>https://github.com/SharpRepository/SharpRepository</PackageProjectUrl>
	<PackageLicenseUrl>https://raw.githubusercontent.com/SharpRepository/SharpRepository/master/license.txt</PackageLicenseUrl>
	<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
    <RepositoryUrl>https://github.com/SharpRepository/SharpRepository.git</RepositoryUrl>
	<RepositoryType>git</RepositoryType>
	<Version>2.0.2-alpha4</Version>
  </PropertyGroup>
  <ItemGroup>
    <Content Include="repository.azureDocumentDb.json">
      <Pack>true</Pack>
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="..\SharpRepository.Repository\SharpRepository.Repository.csproj" />
  </ItemGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.Azure.DocumentDB.Core" Version="2.1.3" />
    <PackageReference Include="Nito.AsyncEx.Tasks" Version="1.1.0" />
  </ItemGroup>
</Project>


// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef EIGEN_SPARSE_BLOCKFORDYNAMICMATRIX_H
#define EIGEN_SPARSE_BLOCKFORDYNAMICMATRIX_H

namespace Eigen {

#if 0

// NOTE Have to be reimplemented as a specialization of BlockImpl< DynamicSparseMatrix<_Scalar, _Options, _Index>, ... >
// See SparseBlock.h for an example

/***************************************************************************
* specialisation for DynamicSparseMatrix
***************************************************************************/

template<typename _Scalar, int _Options, typename _Index, int Size>
class SparseInnerVectorSet<DynamicSparseMatrix<_Scalar, _Options, _Index>, Size>
  : public SparseMatrixBase<SparseInnerVectorSet<DynamicSparseMatrix<_Scalar, _Options, _Index>, Size> >
{
    typedef DynamicSparseMatrix<_Scalar, _Options, _Index> MatrixType;
  public:

    enum { IsRowMajor = internal::traits<SparseInnerVectorSet>::IsRowMajor };

    EIGEN_SPARSE_PUBLIC_INTERFACE(SparseInnerVectorSet)
    class InnerIterator: public MatrixType::InnerIterator
    {
      public:
        inline InnerIterator(const SparseInnerVectorSet& xpr, Index outer)
          : MatrixType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
        {}
        inline Index row() const { return IsRowMajor ? m_outer : this->index(); }
        inline Index col() const { return IsRowMajor ? this->index() : m_outer; }
      protected:
        Index m_outer;
    };

    inline SparseInnerVectorSet(const MatrixType& matrix, Index outerStart, Index outerSize)
      : m_matrix(matrix), m_outerStart(outerStart), m_outerSize(outerSize)
    {
      eigen_assert( (outerStart>=0) && ((outerStart+outerSize)<=matrix.outerSize()) );
    }

    inline SparseInnerVectorSet(const MatrixType& matrix, Index outer)
      : m_matrix(matrix), m_outerStart(outer), m_outerSize(Size)
    {
      eigen_assert(Size!=Dynamic);
      eigen_assert( (outer>=0) && (outer<matrix.outerSize()) );
    }

    template<typename OtherDerived>
    inline SparseInnerVectorSet& operator=(const SparseMatrixBase<OtherDerived>& other)
    {
      if (IsRowMajor != ((OtherDerived::Flags&RowMajorBit)==RowMajorBit))
      {
        // need to transpose => perform a block evaluation followed by a big swap
        DynamicSparseMatrix<Scalar,IsRowMajor?RowMajorBit:0> aux(other);
        *this = aux.markAsRValue();
      }
      else
      {
        // evaluate/copy vector per vector
        for (Index j=0; j<m_outerSize.value(); ++j)
        {
          SparseVector<Scalar,IsRowMajor ? RowMajorBit : 0> aux(other.innerVector(j));
          m_matrix.const_cast_derived()._data()[m_outerStart+j].swap(aux._data());
        }
      }
      return *this;
    }

    inline SparseInnerVectorSet& operator=(const SparseInnerVectorSet& other)
    {
      return operator=<SparseInnerVectorSet>(other);
    }

    Index nonZeros() const
    {
      Index count = 0;
      for (Index j=0; j<m_outerSize.value(); ++j)
        count += m_matrix._data()[m_outerStart+j].size();
      return count;
    }

    const Scalar& lastCoeff() const
    {
      EIGEN_STATIC_ASSERT_VECTOR_ONLY(SparseInnerVectorSet);
      eigen_assert(m_matrix.data()[m_outerStart].size()>0);
      return m_matrix.data()[m_outerStart].vale(m_matrix.data()[m_outerStart].size()-1);
    }

//     template<typename Sparse>
//     inline SparseInnerVectorSet& operator=(const SparseMatrixBase<OtherDerived>& other)
//     {
//       return *this;
//     }

    EIGEN_STRONG_INLINE Index rows() const { return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); }
    EIGEN_STRONG_INLINE Index cols() const { return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); }

  protected:

    const typename MatrixType::Nested m_matrix;
    Index m_outerStart;
    const internal::variable_if_dynamic<Index, Size> m_outerSize;

};

#endif

} // end namespace Eigen

#endif // EIGEN_SPARSE_BLOCKFORDYNAMICMATRIX_H


/* styles */
/* Template for items in the ListView */
.VisitBackgroundEventsListViewItemStyle {
    width: 500px;
    padding: 4px;
    white-space: nowrap;
    overflow: hidden;
    -ms-text-overflow: ellipsis;
}

/* CSS applied to the ListView */
#VisitBackgroundEventsListView {
    height: 240px;
    width: 500px;
    padding: 4px;
    border: solid 2px rgba(0, 0, 0, 0.13);
}


import sys
import json

import click
import django.apps
from django.db import connection

import rssant_common.django_setup  # noqa:F401
from rssant_common.helper import pretty_format_json

sql_count_limit = '''
SELECT count(*) as row_count
FROM (SELECT 1 FROM {table} LIMIT {limit}) t;
'''

sql_count_estimate = '''
SELECT relname as table_name, reltuples AS row_count
FROM pg_class WHERE relname=ANY(%s);
'''

story_volume_tables = [
    'story_volume_0',
]

def pg_count_limit(tables, limit):
    result = {}
    with connection.cursor() as cursor:
        for table in tables:
            sql = sql_count_limit.format(table=table, limit=limit)
            cursor.execute(sql)
            (row_count,) = cursor.fetchone()
            row_count = int(row_count)
            if row_count < limit:
                result[table] = row_count
    return result

def pg_count_estimate(tables):
    result = {}
    with connection.cursor() as cursor:
        cursor.execute(sql_count_estimate, [tables])
        for table, count in cursor.fetchall():
            result[table] = int(count)
    return result

def pg_count():
    """
    Problem:
        1. count(*) is slow for large table.
        2. estimate is not accuracy for small table.
    Solution:
        1. count(*) with limit, avoid slow for large tables
        2. query estimate from system table for large tables
    See also:
        https://stackoverflow.com/questions/7943233/fast-way-to-discover-the-row-count-of-a-table-in-postgresql
        https://wiki.postgresql.org/wiki/Count_estimate
    """
    models = django.apps.apps.get_models()
    tables = [m._meta.db_table for m in models]
    tables.extend(story_volume_tables)
    result = pg_count_limit(tables, limit=10000)
    large_tables = list(set(tables) - set(result))
    result.update(pg_count_estimate(large_tables))
    result = list(sorted(result.items()))
    return result

def pg_verify(result, expect_result, bias):
    result_map = {name: count for name, count in result}
    is_all_ok = True
    for name, expect_count in expect_result:
        count = result_map.get(name)
        if count is None:
            v_bias = 1.0
            is_ok = False
        else:
            v_bias = abs(expect_count - count) / (expect_count + 1)
            is_ok = v_bias < bias
        if not is_ok:
            is_all_ok = False
        count_text = str(count) if count is not None else '#'
        status = 'OK' if is_ok else 'ERROR'
        bias_text = '{}%'.format(round(v_bias * 100, 2))
        print(f'{status:<5s} {name:<35s} count={count_text:<7s} expect={str(expect_count):<7s} bias={bias_text}')
    return is_all_ok

@click.command()
@click.option('--verify', type=str, help='target filepath, or - to query database')
@click.option('--verify-bias', type=float, default=0.003)
@click.argument('filepath', type=str, default='-')
def main(verify, filepath, verify_bias):
    if verify:
        if verify != '-':
            with open(verify) as f:
                data = json.load(f)
            result = [(x['name'], x['count']) for x in data['tables']]
        else:
            result = pg_count()
        if filepath and filepath != '-':
            with open(filepath) as f:
                content = f.read()
        else:
            content = sys.stdin.read()
        expect_data = json.loads(content)
        expect_result = [(x['name'], x['count']) for x in expect_data['tables']]
        is_ok = pg_verify(result, expect_result, verify_bias)
        sys.exit(0 if is_ok else 1)
    else:
        result = pg_count()
        tables = [dict(name=name, count=count) for name, count in result]
        content = pretty_format_json(dict(tables=tables))
        if filepath and filepath != '-':
            with open(filepath, 'w') as f:
                f.write(content)
        else:
            print(content)

if __name__ == "__main__":
    main()


/*
 * reserved comment block
 * DO NOT REMOVE OR ALTER!
 */
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.sun.org.apache.xerces.internal.impl.dtd;

import com.sun.org.apache.xerces.internal.impl.dv.DatatypeValidator;

/**
 */
public class XMLSimpleType {

    //
    // Constants
    //

    /** TYPE_CDATA */
    public static final short TYPE_CDATA = 0;

    /** TYPE_ENTITY */
    public static final short TYPE_ENTITY = 1;

    /** TYPE_ENUMERATION */
    public static final short TYPE_ENUMERATION = 2;

    /** TYPE_ID */
    public static final short TYPE_ID = 3;

    /** TYPE_IDREF */
    public static final short TYPE_IDREF = 4;

    /** TYPE_NMTOKEN */
    public static final short TYPE_NMTOKEN = 5;

    /** TYPE_NOTATION */
    public static final short TYPE_NOTATION = 6;

    /** TYPE_NAMED */
    public static final short TYPE_NAMED = 7;

    /** DEFAULT_TYPE_DEFAULT */
    public static final short DEFAULT_TYPE_DEFAULT = 3;

    /** DEFAULT_TYPE_FIXED */
    public static final short DEFAULT_TYPE_FIXED = 1;

    /** DEFAULT_TYPE_IMPLIED */
    public static final short DEFAULT_TYPE_IMPLIED = 0;

    /** DEFAULT_TYPE_REQUIRED */
    public static final short DEFAULT_TYPE_REQUIRED = 2;

    //
    // Data
    //

    /** type */
    public short type;

    /** name */
    public String name;

    /** enumeration */
    public String[] enumeration;

    /** list */
    public boolean list;

    /** defaultType */
    public short defaultType;

    /** defaultValue */
    public String defaultValue;

    /** non-normalized defaultValue */
    public String nonNormalizedDefaultValue;

    /** datatypeValidator */
    public DatatypeValidator datatypeValidator;

    //
    // Methods
    //

    /**
     * setValues
     *
     * @param type
     * @param name
     * @param enumeration
     * @param list
     * @param defaultType
     * @param defaultValue
     * @param nonNormalizedDefaultValue
     * @param datatypeValidator
     */
    public void setValues(short type, String name, String[] enumeration,
                          boolean list, short defaultType,
                          String defaultValue, String nonNormalizedDefaultValue,
                          DatatypeValidator datatypeValidator) {

        this.type              = type;
        this.name              = name;
        // REVISIT: Should this be a copy? -Ac
        if (enumeration != null && enumeration.length > 0) {
            this.enumeration = new String[enumeration.length];
            System.arraycopy(enumeration, 0, this.enumeration, 0, this.enumeration.length);
        }
        else {
            this.enumeration = null;
        }
        this.list              = list;
        this.defaultType       = defaultType;
        this.defaultValue      = defaultValue;
        this.nonNormalizedDefaultValue      = nonNormalizedDefaultValue;
        this.datatypeValidator = datatypeValidator;

    } // setValues(short,String,String[],boolean,short,String,String,DatatypeValidator)

    /** Set values. */
    public void setValues(XMLSimpleType simpleType) {

        type = simpleType.type;
        name = simpleType.name;
        // REVISIT: Should this be a copy? -Ac
        if (simpleType.enumeration != null && simpleType.enumeration.length > 0) {
            enumeration = new String[simpleType.enumeration.length];
            System.arraycopy(simpleType.enumeration, 0, enumeration, 0, enumeration.length);
        }
        else {
            enumeration = null;
        }
        list = simpleType.list;
        defaultType = simpleType.defaultType;
        defaultValue = simpleType.defaultValue;
        nonNormalizedDefaultValue = simpleType.nonNormalizedDefaultValue;
        datatypeValidator = simpleType.datatypeValidator;

    } // setValues(XMLSimpleType)

    /**
     * clear
     */
    public void clear() {
        this.type              = -1;
        this.name              = null;
        this.enumeration       = null;
        this.list              = false;
        this.defaultType       = -1;
        this.defaultValue      = null;
        this.nonNormalizedDefaultValue      = null;
        this.datatypeValidator = null;
    } // clear

} // class XMLSimpleType


# Change Log

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

# [2.0.0](https://github.com/yargs/set-blocking/compare/v1.0.0...v2.0.0) (2016-05-17)

### Features

* add an isTTY check ([#3](https://github.com/yargs/set-blocking/issues/3)) ([66ce277](https://github.com/yargs/set-blocking/commit/66ce277))

### BREAKING CHANGES

* stdio/stderr will not be set to blocking if isTTY === false

# 1.0.0 (2016-05-14)

### Features

* implemented shim for stream._handle.setBlocking ([6bde0c0](https://github.com/yargs/set-blocking/commit/6bde0c0))


<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
    xmlns:owl="http://www.w3.org/2002/07/owl#"
    xml:base="http://www.w3.org/2002/03owlt/cardinality/premises001" >
    <owl:Class rdf:ID="c">
      <rdfs:subClassOf>
          <rdf:Description>
             <owl:intersectionOf rdf:parseType="Collection">
                <owl:Restriction>
                   <owl:onProperty rdf:resource="#p"/>
                   <owl:cardinality
 rdf:datatype="http://www.w3.org/2001/XMLSchema#nonNegativeInteger"
                   >1</owl:cardinality>
                </owl:Restriction>
              </owl:intersectionOf>
           </rdf:Description>
       </rdfs:subClassOf>
     </owl:Class>
    <owl:Class rdf:about="premises001#c1">
             <owl:intersectionOf rdf:parseType="Collection">
                <owl:Restriction>
                   <owl:onProperty rdf:resource="premises001#p"/>
                   <owl:maxCardinality
 rdf:datatype="http://www.w3.org/2001/XMLSchema#nonNegativeInteger"
                   >1</owl:maxCardinality>
                </owl:Restriction>
                <owl:Restriction>
                   <owl:onProperty rdf:resource="premises001#p"/>
                   <owl:minCardinality
 rdf:datatype="http://www.w3.org/2001/XMLSchema#nonNegativeInteger"
                   >1</owl:minCardinality>
                </owl:Restriction>
              </owl:intersectionOf>
     </owl:Class>
     <owl:ObjectProperty rdf:ID="p"/>
</rdf:RDF>


# Symbolic constants for Tk

# Booleans
NO=FALSE=OFF=0
YES=TRUE=ON=1

# -anchor and -sticky
N='n'
S='s'
W='w'
E='e'
NW='nw'
SW='sw'
NE='ne'
SE='se'
NS='ns'
EW='ew'
NSEW='nsew'
CENTER='center'

# -fill
NONE='none'
X='x'
Y='y'
BOTH='both'

# -side
LEFT='left'
TOP='top'
RIGHT='right'
BOTTOM='bottom'

# -relief
RAISED='raised'
SUNKEN='sunken'
FLAT='flat'
RIDGE='ridge'
GROOVE='groove'
SOLID = 'solid'

# -orient
HORIZONTAL='horizontal'
VERTICAL='vertical'

# -tabs
NUMERIC='numeric'

# -wrap
CHAR='char'
WORD='word'

# -align
BASELINE='baseline'

# -bordermode
INSIDE='inside'
OUTSIDE='outside'

# Special tags, marks and insert positions
SEL='sel'
SEL_FIRST='sel.first'
SEL_LAST='sel.last'
END='end'
INSERT='insert'
CURRENT='current'
ANCHOR='anchor'
ALL='all' # e.g. Canvas.delete(ALL)

# Text widget and button states
NORMAL='normal'
DISABLED='disabled'
ACTIVE='active'
# Canvas state
HIDDEN='hidden'

# Menu item types
CASCADE='cascade'
CHECKBUTTON='checkbutton'
COMMAND='command'
RADIOBUTTON='radiobutton'
SEPARATOR='separator'

# Selection modes for list boxes
SINGLE='single'
BROWSE='browse'
MULTIPLE='multiple'
EXTENDED='extended'

# Activestyle for list boxes
# NONE='none' is also valid
DOTBOX='dotbox'
UNDERLINE='underline'

# Various canvas styles
PIESLICE='pieslice'
CHORD='chord'
ARC='arc'
FIRST='first'
LAST='last'
BUTT='butt'
PROJECTING='projecting'
ROUND='round'
BEVEL='bevel'
MITER='miter'

# Arguments to xview/yview
MOVETO='moveto'
SCROLL='scroll'
UNITS='units'
PAGES='pages'


julia 0.3
BinDeps
Compat
Images
Colors
FactCheck
TestImages


// Copyright 2001-2019 Crytek GmbH / Crytek Group. All rights reserved.

/*=============================================================================
   D3DPostProcess : Direct3D specific post processing special effects

   Revision history:
* 23/02/2005: Re-factored/Converted to CryEngine 2.0 by Tiago Sousa
* Created by Tiago Sousa

   =============================================================================*/

#include "StdAfx.h"
#include <Cry3DEngine/I3DEngine.h>
#include "D3DPostProcess.h"

#if CRY_PLATFORM_WINDOWS
	#include <CryInput/IHardwareMouse.h>
#endif

SD3DPostEffectsUtils SD3DPostEffectsUtils::m_pInstance;

////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////

void SD3DPostEffectsUtils::ResolveRT(CTexture*& pDst, const RECT* pSrcRect)
{
	ASSERT_LEGACY_PIPELINE
	assert(pDst);
	if (!pDst)
		return;
	/*
	CRenderDisplayContext* pActiveContext = gcpRendD3D.GetActiveDisplayContext();
	CTexture* pSrc = pActiveContext->GetColorOutput();
	if (pSrc)
	{
		RECT defaultRect;
		if (!pSrcRect)
		{
			defaultRect.left = 0;
			defaultRect.top = 0;
			defaultRect.right = min(pDst->GetWidth(), pActiveContext->GetResolution().x);
			defaultRect.bottom = min(pDst->GetHeight(), pActiveContext->GetResolution().y);

			pSrcRect = &defaultRect;
		}

		const SResourceRegionMapping region =
		{
			{ 0, 0, 0, 0 },
			{ pSrcRect->left, pSrcRect->top, 0, 0 },
			{ pSrcRect->right - pSrcRect->left, pSrcRect->bottom - pSrcRect->top, 1, 1 }
		};

		HRESULT hr = 0;
		SRenderStatistics::Write().m_RTCopied++;
		SRenderStatistics::Write().m_RTCopiedSize += pDst->GetDeviceDataSize();

		GetDeviceObjectFactory().GetCoreCommandList().GetCopyInterface()->Copy(pSrc->GetDevTexture(), pDst->GetDevTexture(), region);
	}
	*/
}

void SD3DPostEffectsUtils::CopyTextureToScreen(CTexture*& pSrc, const RECT* pSrcRegion, const int filterMode)
{
	ASSERT_LEGACY_PIPELINE
/*
	static CCryNameTSCRC pRestoreTechName("TextureToTexture");
	PostProcessUtils().ShBeginPass(CShaderMan::s_shPostEffects, pRestoreTechName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES);
	gRenDev->FX_SetState(GS_NODEPTHTEST);
	PostProcessUtils().SetTexture(pSrc, 0, filterMode >= 0 ? filterMode : FILTER_POINT);
	PostProcessUtils().DrawFullScreenTri(pSrc->GetWidth(), pSrc->GetHeight(), 0, pSrcRegion);
	PostProcessUtils().ShEndPass();
*/
}

void SD3DPostEffectsUtils::CopyScreenToTexture(CTexture*& pDst, const RECT* pSrcRegion)
{
	ResolveRT(pDst, pSrcRegion);
}

////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////

void SD3DPostEffectsUtils::StretchRect(CTexture* pSrc, CTexture*& pDst, bool bClearAlpha, bool bDecodeSrcRGBK, bool bEncodeDstRGBK, bool bBigDownsample, EDepthDownsample depthDownsample, bool bBindMultisampled, const RECT* srcRegion)
{
	if (!pSrc || !pDst)
	{
		return;
	}

	PROFILE_LABEL_SCOPE("STRETCHRECT");

	// OLD PIPELINE
	ASSERT_LEGACY_PIPELINE
}
////////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////

void SD3DPostEffectsUtils::Downsample(CTexture* pSrc, CTexture* pDst, int nSrcW, int nSrcH, int nDstW, int nDstH, EFilterType eFilter /*= FilterType_Box*/, bool bSetTarget /*= true*/)
{
	ASSERT_LEGACY_PIPELINE
}

////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////

void CD3D9Renderer::GetReprojectionMatrix(Matrix44A& matReproj,
                                          const Matrix44A& matView,
                                          const Matrix44A& matProj,
                                          const Matrix44A& matPrevView,
                                          const Matrix44A& matPrevProj,
                                          float fFarPlane) const
{
	// Current camera screen-space to projection-space
	const Matrix44A matSc2Pc
	  (2.f, 0.f, -1.f, 0.f,
	  0.f, 2.f, -1.f, 0.f,
	  0.f, 0.f, 1.f, 0.f,
	  0.f, 0.f, 0.f, 1.f / fFarPlane);

	// Current camera view-space to projection-space
	const Matrix44A matVc2Pc
	  (matProj.m00, 0.f, 0.f, 0.f,
	  0.f, matProj.m11, 0.f, 0.f,
	  0.f, 0.f, 1.f, 0.f,
	  0.f, 0.f, 0.f, 1.f);

	// Current camera projection-space to world-space
	const Matrix44A matPc2Wc = (matVc2Pc * matView).GetInverted();

	// Previous camera view-space to projection-space
	const Matrix44A matVp2Pp
	  (matPrevProj.m00, 0.f, 0.f, 0.f,
	  0.f, matPrevProj.m11, 0.f, 0.f,
	  0.f, 0.f, 1.f, 0.f,
	  0.f, 0.f, 0.f, 1.f);

	// Previous camera world-space to projection-space
	const Matrix44A matWp2Pp = matVp2Pp * matPrevView;

	// Previous camera projection-space to texture-space
	const Matrix44A matPp2Tp
	  (0.5f, 0.f, 0.5f, 0.f,
	  0.f, 0.5f, 0.5f, 0.f,
	  0.f, 0.f, 1.f, 0.f,
	  0.f, 0.f, 0.f, 1.f);

	// Final reprojection matrix (from current camera screen-space to previous camera texture-space)
	matReproj = matPp2Tp * matWp2Pp * matPc2Wc * matSc2Pc;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////

void CPostEffectsMgr::Begin()
{
	PostProcessUtils().Log("### POST-PROCESSING BEGINS ### ");
	PostProcessUtils().m_pTimer = gEnv->pTimer;
	static EShaderQuality nPrevShaderQuality = eSQ_Low;
	static ERenderQuality nPrevRenderQuality = eRQ_Low;

	EShaderQuality nShaderQuality = (EShaderQuality) gcpRendD3D->EF_GetShaderQuality(eST_PostProcess);
	ERenderQuality nRenderQuality = gRenDev->EF_GetRenderQuality();
	if (nPrevShaderQuality != nShaderQuality || nPrevRenderQuality != nRenderQuality)
	{
		CPostEffectsMgr::Reset(true);
		nPrevShaderQuality = nShaderQuality;
		nPrevRenderQuality = nRenderQuality;
	}

	//gcpRendD3D->RT_SetViewport(0, 0, gcpRendD3D->GetWidth(), gcpRendD3D->GetHeight());

	auto threadID = gRenDev->GetRenderThreadID();
	SPostEffectsUtils::m_fWaterLevel = gRenDev->m_p3DEngineCommon[threadID].m_OceanInfo.m_fWaterLevel;

	PostProcessUtils().UpdateOverscanBorderAspectRatio();
}

void CPostEffectsMgr::End(CRenderView* pRenderView)
{
	//gcpRendD3D->RT_SetViewport(PostProcessUtils().m_pScreenRect.left, PostProcessUtils().m_pScreenRect.top, PostProcessUtils().m_pScreenRect.right, PostProcessUtils().m_pScreenRect.bottom);
	const int kFloatMaxContinuousInt = 0x1000000;  // 2^24
	const bool bStereo = gcpRendD3D->GetS3DRend().IsStereoEnabled();
	const bool bStereoSequentialSubmission = gcpRendD3D->GetS3DRend().GetStereoSubmissionMode() == EStereoSubmission::STEREO_SUBMISSION_SEQUENTIAL;

	if (!bStereo || (bStereo && (!bStereoSequentialSubmission || pRenderView->GetCurrentEye() == CCamera::eEye_Right)))
		SPostEffectsUtils::m_iFrameCounter = (SPostEffectsUtils::m_iFrameCounter + 1) % kFloatMaxContinuousInt;

	PostProcessUtils().Log("### POST-PROCESSING ENDS ### ");
}


//===--- CFGStmtMap.h - Map from Stmt* to CFGBlock* -----------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines the CFGStmtMap class, which defines a mapping from
//  Stmt* to CFGBlock*
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_ANALYSIS_CFGSTMTMAP_H
#define LLVM_CLANG_ANALYSIS_CFGSTMTMAP_H

#include "clang/Analysis/CFG.h"

namespace clang {

class CFG;
class CFGBlock;
class ParentMap;
class Stmt;

class CFGStmtMap {
  ParentMap *PM;
  void *M;

  CFGStmtMap(ParentMap *pm, void *m) : PM(pm), M(m) {}

public:
  ~CFGStmtMap();

  /// Returns a new CFGMap for the given CFG.  It is the caller's
  /// responsibility to 'delete' this object when done using it.
  static CFGStmtMap *Build(CFG* C, ParentMap *PM);

  /// Returns the CFGBlock the specified Stmt* appears in.  For Stmt* that
  /// are terminators, the CFGBlock is the block they appear as a terminator,
  /// and not the block they appear as a block-level expression (e.g, '&&').
  /// CaseStmts and LabelStmts map to the CFGBlock they label.
  CFGBlock *getBlock(Stmt * S);

  const CFGBlock *getBlock(const Stmt * S) const {
    return const_cast<CFGStmtMap*>(this)->getBlock(const_cast<Stmt*>(S));
  }
};

} // end clang namespace
#endif


/*
 * ct_actions_help.cc
 *
 * Copyright 2009-2020
 * Giuseppe Penone <giuspen@gmail.com>
 * Evgenii Gurianov <https://github.com/txe>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301, USA.
 */

#include "ct_actions.h"
#include <glib/gstdio.h>

void CtActions::online_help()
{
    fs::open_weblink("https://giuspen.com/cherrytreemanual/");
}

void CtActions::dialog_about()
{
    CtDialogs::dialog_about(*_pCtMainWin, _pCtMainWin->get_icon_theme()->load_icon(CtConst::APP_NAME, 128));
}

void CtActions::folder_cfg_open()
{
    fs::open_folderpath(Glib::get_user_config_dir() / fs::path(CtConst::APP_NAME), _pCtMainWin->get_ct_config());
}

void CtActions::check_for_newer_version()
{
    auto& statusbar = _pCtMainWin->get_status_bar();
    statusbar.update_status(_("Checking for Newer Version..."));
    while (gtk_events_pending()) gtk_main_iteration();

    std::string latest_version_from_server = str::trim(fs::download_file("https://www.giuspen.com/software/version_cherrytree"));
    //g_print("v='%s'\n", latest_version_from_server.c_str());
    if (latest_version_from_server.empty() or latest_version_from_server.size() > 10) {
        statusbar.update_status(_("Failed to Retrieve Latest Version Information - Try Again Later"));
    }
    else {
        std::vector<gint64> splitted_latest_v = CtStrUtil::gstring_split_to_int64(latest_version_from_server.c_str(), ".");
        std::vector<gint64> splitted_local_v = CtStrUtil::gstring_split_to_int64(PACKAGE_VERSION, ".");
        if (splitted_latest_v.size() != 3 or splitted_local_v.size() != 3) {
            g_critical("unexpected versions %s, %s", latest_version_from_server.c_str(), PACKAGE_VERSION);
        }
        else {
            gint64 weighted_latest_v = splitted_latest_v[0]*10000 + splitted_latest_v[1]*100 + splitted_latest_v[2];
            gint64 weighted_local_v = splitted_local_v[0]*10000 + splitted_local_v[1]*100 + splitted_local_v[2];
            if (weighted_latest_v > weighted_local_v) {
                CtDialogs::info_dialog(Glib::ustring{_("A Newer Version Is Available!")} + " (" + latest_version_from_server + ")", *_pCtMainWin);
                _pCtMainWin->update_selected_node_statusbar_info();
            }
            else {
                if (weighted_latest_v == weighted_local_v) {
                    statusbar.update_status(Glib::ustring{_("You Are Using the Latest Version Available")} + " (" + latest_version_from_server + ")");
                }
                else {
                    statusbar.update_status(_("You Are Using a Development Version"));
                }
            }
        }
    }
}


.class public final Lc/a/e/t;
.super Ljava/lang/Object;
.source ""

# annotations
.annotation system Ldalvik/annotation/MemberClasses;
    value = {
        Lc/a/e/t$c;,
        Lc/a/e/t$a;,
        Lc/a/e/t$b;
    }
.end annotation

# instance fields
.field a:J

.field b:J

.field final c:I

.field final d:Lc/a/e/n;

.field private final e:Ljava/util/List;
    .annotation system Ldalvik/annotation/Signature;
        value = {
            "Ljava/util/List<",
            "Lc/a/e/c;",
            ">;"
        }
    .end annotation
.end field

.field private f:Ljava/util/List;
    .annotation system Ldalvik/annotation/Signature;
        value = {
            "Ljava/util/List<",
            "Lc/a/e/c;",
            ">;"
        }
    .end annotation
.end field

.field private final g:Lc/a/e/t$b;

.field final h:Lc/a/e/t$a;

.field final i:Lc/a/e/t$c;

.field final j:Lc/a/e/t$c;

.field k:Lc/a/e/b;

# direct methods
.method constructor <init>(ILc/a/e/n;ZZLjava/util/List;)V
    .locals 2
    .annotation system Ldalvik/annotation/Signature;
        value = {
            "(I",
            "Lc/a/e/n;",
            "ZZ",
            "Ljava/util/List<",
            "Lc/a/e/c;",
            ">;)V"
        }
    .end annotation

    invoke-direct {p0}, Ljava/lang/Object;-><init>()V

    const-wide/16 v0, 0x0

    iput-wide v0, p0, Lc/a/e/t;->a:J

    new-instance v0, Lc/a/e/t$c;

    invoke-direct {v0, p0}, Lc/a/e/t$c;-><init>(Lc/a/e/t;)V

    iput-object v0, p0, Lc/a/e/t;->i:Lc/a/e/t$c;

    new-instance v0, Lc/a/e/t$c;

    invoke-direct {v0, p0}, Lc/a/e/t$c;-><init>(Lc/a/e/t;)V

    iput-object v0, p0, Lc/a/e/t;->j:Lc/a/e/t$c;

    const/4 v0, 0x0

    iput-object v0, p0, Lc/a/e/t;->k:Lc/a/e/b;

    if-eqz p2, :cond_1

    if-eqz p5, :cond_0

    iput p1, p0, Lc/a/e/t;->c:I

    iput-object p2, p0, Lc/a/e/t;->d:Lc/a/e/n;

    iget-object p1, p2, Lc/a/e/n;->p:Lc/a/e/z;

    invoke-virtual {p1}, Lc/a/e/z;->c()I

    move-result p1

    int-to-long v0, p1

    iput-wide v0, p0, Lc/a/e/t;->b:J

    new-instance p1, Lc/a/e/t$b;

    iget-object p2, p2, Lc/a/e/n;->o:Lc/a/e/z;

    invoke-virtual {p2}, Lc/a/e/z;->c()I

    move-result p2

    int-to-long v0, p2

    invoke-direct {p1, p0, v0, v1}, Lc/a/e/t$b;-><init>(Lc/a/e/t;J)V

    iput-object p1, p0, Lc/a/e/t;->g:Lc/a/e/t$b;

    new-instance p1, Lc/a/e/t$a;

    invoke-direct {p1, p0}, Lc/a/e/t$a;-><init>(Lc/a/e/t;)V

    iput-object p1, p0, Lc/a/e/t;->h:Lc/a/e/t$a;

    iget-object p1, p0, Lc/a/e/t;->g:Lc/a/e/t$b;

    iput-boolean p4, p1, Lc/a/e/t$b;->e:Z

    iget-object p1, p0, Lc/a/e/t;->h:Lc/a/e/t$a;

    iput-boolean p3, p1, Lc/a/e/t$a;->c:Z

    iput-object p5, p0, Lc/a/e/t;->e:Ljava/util/List;

    return-void

    :cond_0
    new-instance p1, Ljava/lang/NullPointerException;

    const-string p2, "requestHeaders == null"

    invoke-direct {p1, p2}, Ljava/lang/NullPointerException;-><init>(Ljava/lang/String;)V

    throw p1

    :cond_1
    new-instance p1, Ljava/lang/NullPointerException;

    const-string p2, "connection == null"

    invoke-direct {p1, p2}, Ljava/lang/NullPointerException;-><init>(Ljava/lang/String;)V

    throw p1
.end method

.method private d(Lc/a/e/b;)Z
    .locals 2

    monitor-enter p0

    :try_start_0
    iget-object v0, p0, Lc/a/e/t;->k:Lc/a/e/b;

    const/4 v1, 0x0

    if-eqz v0, :cond_0

    monitor-exit p0

    return v1

    :cond_0
    iget-object v0, p0, Lc/a/e/t;->g:Lc/a/e/t$b;

    iget-boolean v0, v0, Lc/a/e/t$b;->e:Z

    if-eqz v0, :cond_1

    iget-object v0, p0, Lc/a/e/t;->h:Lc/a/e/t$a;

    iget-boolean v0, v0, Lc/a/e/t$a;->c:Z

    if-eqz v0, :cond_1

    monitor-exit p0

    return v1

    :cond_1
    iput-object p1, p0, Lc/a/e/t;->k:Lc/a/e/b;

    invoke-virtual {p0}, Ljava/lang/Object;->notifyAll()V

    monitor-exit p0
    :try_end_0
    .catchall {:try_start_0 .. :try_end_0} :catchall_0

    iget-object p1, p0, Lc/a/e/t;->d:Lc/a/e/n;

    iget v0, p0, Lc/a/e/t;->c:I

    invoke-virtual {p1, v0}, Lc/a/e/n;->d(I)Lc/a/e/t;

    const/4 p1, 0x1

    return p1

    :catchall_0
    move-exception p1

    :try_start_1
    monitor-exit p0
    :try_end_1
    .catchall {:try_start_1 .. :try_end_1} :catchall_0

    throw p1
.end method

# virtual methods
.method a()V
    .locals 2

    monitor-enter p0

    :try_start_0
    iget-object v0, p0, Lc/a/e/t;->g:Lc/a/e/t$b;

    iget-boolean v0, v0, Lc/a/e/t$b;->e:Z

    if-nez v0, :cond_1

    iget-object v0, p0, Lc/a/e/t;->g:Lc/a/e/t$b;

    iget-boolean v0, v0, Lc/a/e/t$b;->d:Z

    if-eqz v0, :cond_1

    iget-object v0, p0, Lc/a/e/t;->h:Lc/a/e/t$a;

    iget-boolean v0, v0, Lc/a/e/t$a;->c:Z

    if-nez v0, :cond_0

    iget-object v0, p0, Lc/a/e/t;->h:Lc/a/e/t$a;

    iget-boolean v0, v0, Lc/a/e/t$a;->b:Z

    if-eqz v0, :cond_1

    :cond_0
    const/4 v0, 0x1

    goto :goto_0

    :cond_1
    const/4 v0, 0x0

    :goto_0
    invoke-virtual {p0}, Lc/a/e/t;->h()Z

    move-result v1

    monitor-exit p0
    :try_end_0
    .catchall {:try_start_0 .. :try_end_0} :catchall_0

    if-eqz v0, :cond_2

    sget-object v0, Lc/a/e/b;->f:Lc/a/e/b;

    invoke-virtual {p0, v0}, Lc/a/e/t;->a(Lc/a/e/b;)V

    goto :goto_1

    :cond_2
    if-nez v1, :cond_3

    iget-object v0, p0, Lc/a/e/t;->d:Lc/a/e/n;

    iget v1, p0, Lc/a/e/t;->c:I

    invoke-virtual {v0, v1}, Lc/a/e/n;->d(I)Lc/a/e/t;

    :cond_3
    :goto_1
    return-void

    :catchall_0
    move-exception v0

    :try_start_1
    monitor-exit p0
    :try_end_1
    .catchall {:try_start_1 .. :try_end_1} :catchall_0

    throw v0
.end method

.method a(J)V
    .locals 3

    iget-wide v0, p0, Lc/a/e/t;->b:J

    add-long/2addr v0, p1

    iput-wide v0, p0, Lc/a/e/t;->b:J

    const-wide/16 v0, 0x0

    cmp-long v2, p1, v0

    if-lez v2, :cond_0

    invoke-virtual {p0}, Ljava/lang/Object;->notifyAll()V

    :cond_0
    return-void
.end method

.method public a(Lc/a/e/b;)V
    .locals 2

    invoke-direct {p0, p1}, Lc/a/e/t;->d(Lc/a/e/b;)Z

    move-result v0

    if-nez v0, :cond_0

    return-void

    :cond_0
    iget-object v0, p0, Lc/a/e/t;->d:Lc/a/e/n;

    iget v1, p0, Lc/a/e/t;->c:I

    invoke-virtual {v0, v1, p1}, Lc/a/e/n;->b(ILc/a/e/b;)V

    return-void
.end method

.method a(Ld/g;I)V
    .locals 3

    iget-object v0, p0, Lc/a/e/t;->g:Lc/a/e/t$b;

    int-to-long v1, p2

    invoke-virtual {v0, p1, v1, v2}, Lc/a/e/t$b;->a(Ld/g;J)V

    return-void
.end method

.method a(Ljava/util/List;)V
    .locals 3
    .annotation system Ldalvik/annotation/Signature;
        value = {
            "(",
            "Ljava/util/List<",
            "Lc/a/e/c;",
            ">;)V"
        }
    .end annotation

    const/4 v0, 0x1

    monitor-enter p0

    :try_start_0
    iget-object v1, p0, Lc/a/e/t;->f:Ljava/util/List;

    if-nez v1, :cond_0

    iput-object p1, p0, Lc/a/e/t;->f:Ljava/util/List;

    invoke-virtual {p0}, Lc/a/e/t;->h()Z

    move-result v0

    invoke-virtual {p0}, Ljava/lang/Object;->notifyAll()V

    goto :goto_0

    :cond_0
    new-instance v1, Ljava/util/ArrayList;

    invoke-direct {v1}, Ljava/util/ArrayList;-><init>()V

    iget-object v2, p0, Lc/a/e/t;->f:Ljava/util/List;

    invoke-interface {v1, v2}, Ljava/util/List;->addAll(Ljava/util/Collection;)Z

    invoke-interface {v1, p1}, Ljava/util/List;->addAll(Ljava/util/Collection;)Z

    iput-object v1, p0, Lc/a/e/t;->f:Ljava/util/List;

    :goto_0
    monitor-exit p0
    :try_end_0
    .catchall {:try_start_0 .. :try_end_0} :catchall_0

    if-nez v0, :cond_1

    iget-object p1, p0, Lc/a/e/t;->d:Lc/a/e/n;

    iget v0, p0, Lc/a/e/t;->c:I

    invoke-virtual {p1, v0}, Lc/a/e/n;->d(I)Lc/a/e/t;

    :cond_1
    return-void

    :catchall_0
    move-exception p1

    :try_start_1
    monitor-exit p0
    :try_end_1
    .catchall {:try_start_1 .. :try_end_1} :catchall_0

    throw p1
.end method

.method b()V
    .locals 2

    iget-object v0, p0, Lc/a/e/t;->h:Lc/a/e/t$a;

    iget-boolean v1, v0, Lc/a/e/t$a;->b:Z

    if-nez v1, :cond_2

    iget-boolean v0, v0, Lc/a/e/t$a;->c:Z

    if-nez v0, :cond_1

    iget-object v0, p0, Lc/a/e/t;->k:Lc/a/e/b;

    if-nez v0, :cond_0

    return-void

    :cond_0
    new-instance v1, Lc/a/e/A;

    invoke-direct {v1, v0}, Lc/a/e/A;-><init>(Lc/a/e/b;)V

    throw v1

    :cond_1
    new-instance v0, Ljava/io/IOException;

    const-string v1, "stream finished"

    invoke-direct {v0, v1}, Ljava/io/IOException;-><init>(Ljava/lang/String;)V

    throw v0

    :cond_2
    new-instance v0, Ljava/io/IOException;

    const-string v1, "stream closed"

    invoke-direct {v0, v1}, Ljava/io/IOException;-><init>(Ljava/lang/String;)V

    throw v0
.end method

.method public b(Lc/a/e/b;)V
    .locals 2

    invoke-direct {p0, p1}, Lc/a/e/t;->d(Lc/a/e/b;)Z

    move-result v0

    if-nez v0, :cond_0

    return-void

    :cond_0
    iget-object v0, p0, Lc/a/e/t;->d:Lc/a/e/n;

    iget v1, p0, Lc/a/e/t;->c:I

    invoke-virtual {v0, v1, p1}, Lc/a/e/n;->c(ILc/a/e/b;)V

    return-void
.end method

.method public c()I
    .locals 1

    iget v0, p0, Lc/a/e/t;->c:I

    return v0
.end method

.method declared-synchronized c(Lc/a/e/b;)V
    .locals 1

    monitor-enter p0

    :try_start_0
    iget-object v0, p0, Lc/a/e/t;->k:Lc/a/e/b;

    if-nez v0, :cond_0

    iput-object p1, p0, Lc/a/e/t;->k:Lc/a/e/b;

    invoke-virtual {p0}, Ljava/lang/Object;->notifyAll()V
    :try_end_0
    .catchall {:try_start_0 .. :try_end_0} :catchall_0

    :cond_0
    monitor-exit p0

    return-void

    :catchall_0
    move-exception p1

    monitor-exit p0

    throw p1
.end method

.method public declared-synchronized d()Ljava/util/List;
    .locals 2
    .annotation system Ldalvik/annotation/Signature;
        value = {
            "()",
            "Ljava/util/List<",
            "Lc/a/e/c;",
            ">;"
        }
    .end annotation

    monitor-enter p0

    :try_start_0
    iget-object v0, p0, Lc/a/e/t;->i:Lc/a/e/t$c;

    invoke-virtual {v0}, Ld/c;->i()V
    :try_end_0
    .catchall {:try_start_0 .. :try_end_0} :catchall_1

    :goto_0
    :try_start_1
    iget-object v0, p0, Lc/a/e/t;->f:Ljava/util/List;

    if-nez v0, :cond_0

    iget-object v0, p0, Lc/a/e/t;->k:Lc/a/e/b;

    if-nez v0, :cond_0

    invoke-virtual {p0}, Lc/a/e/t;->k()V
    :try_end_1
    .catchall {:try_start_1 .. :try_end_1} :catchall_0

    goto :goto_0

    :cond_0
    :try_start_2
    iget-object v0, p0, Lc/a/e/t;->i:Lc/a/e/t$c;

    invoke-virtual {v0}, Lc/a/e/t$c;->l()V

    iget-object v0, p0, Lc/a/e/t;->f:Ljava/util/List;

    if-eqz v0, :cond_1

    iget-object v0, p0, Lc/a/e/t;->f:Ljava/util/List;
    :try_end_2
    .catchall {:try_start_2 .. :try_end_2} :catchall_1

    monitor-exit p0

    return-object v0

    :cond_1
    :try_start_3
    new-instance v0, Lc/a/e/A;

    iget-object v1, p0, Lc/a/e/t;->k:Lc/a/e/b;

    invoke-direct {v0, v1}, Lc/a/e/A;-><init>(Lc/a/e/b;)V

    throw v0

    :catchall_0
    move-exception v0

    iget-object v1, p0, Lc/a/e/t;->i:Lc/a/e/t$c;

    invoke-virtual {v1}, Lc/a/e/t$c;->l()V

    throw v0
    :try_end_3
    .catchall {:try_start_3 .. :try_end_3} :catchall_1

    :catchall_1
    move-exception v0

    monitor-exit p0

    goto :goto_2

    :goto_1
    throw v0

    :goto_2
    goto :goto_1
.end method

.method public e()Ld/v;
    .locals 2

    monitor-enter p0

    :try_start_0
    iget-object v0, p0, Lc/a/e/t;->f:Ljava/util/List;

    if-nez v0, :cond_1

    invoke-virtual {p0}, Lc/a/e/t;->g()Z

    move-result v0

    if-eqz v0, :cond_0

    goto :goto_0

    :cond_0
    new-instance v0, Ljava/lang/IllegalStateException;

    const-string v1, "reply before requesting the sink"

    invoke-direct {v0, v1}, Ljava/lang/IllegalStateException;-><init>(Ljava/lang/String;)V

    throw v0

    :cond_1
    :goto_0
    monitor-exit p0
    :try_end_0
    .catchall {:try_start_0 .. :try_end_0} :catchall_0

    iget-object v0, p0, Lc/a/e/t;->h:Lc/a/e/t$a;

    return-object v0

    :catchall_0
    move-exception v0

    :try_start_1
    monitor-exit p0
    :try_end_1
    .catchall {:try_start_1 .. :try_end_1} :catchall_0

    throw v0
.end method

.method public f()Ld/w;
    .locals 1

    iget-object v0, p0, Lc/a/e/t;->g:Lc/a/e/t$b;

    return-object v0
.end method

.method public g()Z
    .locals 4

    iget v0, p0, Lc/a/e/t;->c:I

    const/4 v1, 0x1

    and-int/2addr v0, v1

    const/4 v2, 0x0

    if-ne v0, v1, :cond_0

    const/4 v0, 0x1

    goto :goto_0

    :cond_0
    const/4 v0, 0x0

    :goto_0
    iget-object v3, p0, Lc/a/e/t;->d:Lc/a/e/n;

    iget-boolean v3, v3, Lc/a/e/n;->b:Z

    if-ne v3, v0, :cond_1

    goto :goto_1

    :cond_1
    const/4 v1, 0x0

    :goto_1
    return v1
.end method

.method public declared-synchronized h()Z
    .locals 2

    monitor-enter p0

    :try_start_0
    iget-object v0, p0, Lc/a/e/t;->k:Lc/a/e/b;
    :try_end_0
    .catchall {:try_start_0 .. :try_end_0} :catchall_0

    const/4 v1, 0x0

    if-eqz v0, :cond_0

    monitor-exit p0

    return v1

    :cond_0
    :try_start_1
    iget-object v0, p0, Lc/a/e/t;->g:Lc/a/e/t$b;

    iget-boolean v0, v0, Lc/a/e/t$b;->e:Z

    if-nez v0, :cond_1

    iget-object v0, p0, Lc/a/e/t;->g:Lc/a/e/t$b;

    iget-boolean v0, v0, Lc/a/e/t$b;->d:Z

    if-eqz v0, :cond_3

    :cond_1
    iget-object v0, p0, Lc/a/e/t;->h:Lc/a/e/t$a;

    iget-boolean v0, v0, Lc/a/e/t$a;->c:Z

    if-nez v0, :cond_2

    iget-object v0, p0, Lc/a/e/t;->h:Lc/a/e/t$a;

    iget-boolean v0, v0, Lc/a/e/t$a;->b:Z

    if-eqz v0, :cond_3

    :cond_2
    iget-object v0, p0, Lc/a/e/t;->f:Ljava/util/List;
    :try_end_1
    .catchall {:try_start_1 .. :try_end_1} :catchall_0

    if-eqz v0, :cond_3

    monitor-exit p0

    return v1

    :cond_3
    const/4 v0, 0x1

    monitor-exit p0

    return v0

    :catchall_0
    move-exception v0

    monitor-exit p0

    throw v0
.end method

.method public i()Ld/y;
    .locals 1

    iget-object v0, p0, Lc/a/e/t;->i:Lc/a/e/t$c;

    return-object v0
.end method

.method j()V
    .locals 2

    monitor-enter p0

    :try_start_0
    iget-object v0, p0, Lc/a/e/t;->g:Lc/a/e/t$b;

    const/4 v1, 0x1

    iput-boolean v1, v0, Lc/a/e/t$b;->e:Z

    invoke-virtual {p0}, Lc/a/e/t;->h()Z

    move-result v0

    invoke-virtual {p0}, Ljava/lang/Object;->notifyAll()V

    monitor-exit p0
    :try_end_0
    .catchall {:try_start_0 .. :try_end_0} :catchall_0

    if-nez v0, :cond_0

    iget-object v0, p0, Lc/a/e/t;->d:Lc/a/e/n;

    iget v1, p0, Lc/a/e/t;->c:I

    invoke-virtual {v0, v1}, Lc/a/e/n;->d(I)Lc/a/e/t;

    :cond_0
    return-void

    :catchall_0
    move-exception v0

    :try_start_1
    monitor-exit p0
    :try_end_1
    .catchall {:try_start_1 .. :try_end_1} :catchall_0

    throw v0
.end method

.method k()V
    .locals 1

    :try_start_0
    invoke-virtual {p0}, Ljava/lang/Object;->wait()V
    :try_end_0
    .catch Ljava/lang/InterruptedException; {:try_start_0 .. :try_end_0} :catch_0

    return-void

    :catch_0
    new-instance v0, Ljava/io/InterruptedIOException;

    invoke-direct {v0}, Ljava/io/InterruptedIOException;-><init>()V

    throw v0
.end method

.method public l()Ld/y;
    .locals 1

    iget-object v0, p0, Lc/a/e/t;->j:Lc/a/e/t$c;

    return-object v0
.end method


<?php

namespace Fixtures\Prophecy;

class SpecialMethods
{
    public function __construct()
    {
    }

    function __destruct()
    {
    }

    function __call($name, $arguments)
    {
    }

    function __sleep()
    {
    }

    function __wakeup()
    {
    }

    function __toString()
    {
        return '';
    }

    function __invoke()
    {
    }

}


package proxy

import (
	"context"

	"github.com/docker/distribution"
)

// proxyTagService supports local and remote lookup of tags.
type proxyTagService struct {
	localTags      distribution.TagService
	remoteTags     distribution.TagService
	authChallenger authChallenger
}

var _ distribution.TagService = proxyTagService{}

// Get attempts to get the most recent digest for the tag by checking the remote
// tag service first and then caching it locally.  If the remote is unavailable
// the local association is returned
func (pt proxyTagService) Get(ctx context.Context, tag string) (distribution.Descriptor, error) {
	err := pt.authChallenger.tryEstablishChallenges(ctx)
	if err == nil {
		desc, err := pt.remoteTags.Get(ctx, tag)
		if err == nil {
			err := pt.localTags.Tag(ctx, tag, desc)
			if err != nil {
				return distribution.Descriptor{}, err
			}
			return desc, nil
		}
	}

	desc, err := pt.localTags.Get(ctx, tag)
	if err != nil {
		return distribution.Descriptor{}, err
	}
	return desc, nil
}

func (pt proxyTagService) Tag(ctx context.Context, tag string, desc distribution.Descriptor) error {
	return distribution.ErrUnsupported
}

func (pt proxyTagService) Untag(ctx context.Context, tag string) error {
	err := pt.localTags.Untag(ctx, tag)
	if err != nil {
		return err
	}
	return nil
}

func (pt proxyTagService) All(ctx context.Context) ([]string, error) {
	err := pt.authChallenger.tryEstablishChallenges(ctx)
	if err == nil {
		tags, err := pt.remoteTags.All(ctx)
		if err == nil {
			return tags, err
		}
	}
	return pt.localTags.All(ctx)
}

func (pt proxyTagService) Lookup(ctx context.Context, digest distribution.Descriptor) ([]string, error) {
	return []string{}, distribution.ErrUnsupported
}


(*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *)

open! IStd

(** Module that contains constants and global state used in the frontend *)

type clang_lang = C | CPP | ObjC | ObjCPP [@@deriving compare]

val equal_clang_lang : clang_lang -> clang_lang -> bool

type translation_unit_context =
  { lang: clang_lang
  ; source_file: SourceFile.t
  ; integer_type_widths: Typ.IntegerWidths.t
  ; is_objc_arc_on: bool }

type decl_trans_context = [`DeclTraversal | `Translation | `CppLambdaExprTranslation]

(** Constants *)

val alloc : string

val arrayWithObjects_count : string

val dictionaryWithObjects_forKeys_count : string

val dealloc : string

val assert_fail : string

val assert_rtn : string

val biniou_buffer_size : int

val builtin_expect : string

val builtin_memset_chk : string

val builtin_object_size : string

val ckcomponent_cl : string

val ckcomponentcontroller_cl : string

val clang_bin : string -> string
(** Script to run our own clang. The argument is expected to be either "" or "++". *)

val class_method : string

val fbAssertWithSignalAndLogFunctionHelper : string

val google_LogMessageFatal : string

val google_MakeCheckOpString : string

val handleFailureInFunction : string

val handleFailureInMethod : string

val id_cl : string

val infer : string

val init : string

val is_kind_of_class : string

val malloc : string

val new_str : string

val next_object : string

val nsenumerator_cl : string

val nsproxy_cl : string

val nsobject_cl : string

val nsstring_cl : string

val objc_class : string

val objc_object : string

val object_enumerator : string

val return_param : string

val self : string

val std_addressof : QualifiedCppName.Match.quals_matcher

val string_with_utf8_m : string

val this : string

val replace_with_deref_first_arg_attr : string

val modeled_function_attributes : string list

(** Global state *)

val enum_map : (Clang_ast_t.pointer option * Exp.t option) ClangPointers.Map.t ref
(** Map from enum constants pointers to their predecesor and their sil value *)

val global_translation_unit_decls : Clang_ast_t.decl list ref

val sil_types_map : Typ.desc Clang_ast_extend.TypePointerMap.t ref
(** Map from type pointers (clang pointers and types created later by frontend) to sil types
    Populated during frontend execution when new type is found *)

val procedures_attempted : int ref

val procedures_failed : int ref

val get_fresh_block_index : unit -> int

val reset_block_counter : unit -> unit

val reset_global_state : unit -> unit


<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="Encoding">
    <file url="PROJECT" charset="UTF-8" />
  </component>
</project>


CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/React-Core
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/React-Core" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/DoubleConversion" "${PODS_ROOT}/Headers/Public/React-Core" "${PODS_ROOT}/Headers/Public/React-cxxreact" "${PODS_ROOT}/Headers/Public/React-jsi" "${PODS_ROOT}/Headers/Public/React-jsiexecutor" "${PODS_ROOT}/Headers/Public/React-jsinspector" "${PODS_ROOT}/Headers/Public/glog" "${PODS_ROOT}/Headers/Public/yoga" "$(PODS_TARGET_SRCROOT)/ReactCommon" "$(PODS_ROOT)/boost-for-react-native" "$(PODS_ROOT)/DoubleConversion" "$(PODS_ROOT)/Folly"
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/../../node_modules/react-native/React
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES