text:
#pragma once
#include <algorithm>
#include <type_traits>
#include <numeric>
#include <iterator>
#include <stdexcept>
#include <functional>
#include <cmath>

#ifdef _MSC_VER
#define constexpr inline
#endif

#ifdef __cplusplus_winrt
#define OUTOFRANGEEX throw ref new ::Platform::OutOfBoundsException();
#else
#define OUTOFRANGEEX throw ::std::out_of_range( "Out of range exception." );
#endif

#define ARITHMETICABLECHECK static_assert( ::std::is_arithmetic<typename Details::Wrap<T>::type>::value, "T is arithmeticable only." );

namespace Linq {

#pragma region Detail

	namespace Details {

		template<typename T> struct Wrap { using type = T; };
		template<typename T> constexpr const T& MakeWrap( const T& t ) { return t; }
		template<typename T> constexpr const T& Unwrap( const T& t ) { return t; }

#ifdef __cplusplus_winrt
		template<typename T>
		struct Wrap<T^>
			: ::std::conditional<__is_winrt_agile( T ), T^, ::Platform::Agile<T^>>
		{ };

		template<typename T>
		constexpr ::std::enable_if_t<!__is_winrt_agile( T ), ::Platform::Agile<T^>> MakeWrap( T^ const& t )
		{
			return ::Platform::Agile<T^>( t );
		}

		template<typename T> constexpr T^ Unwrap( const ::Platform::Agile<T^>& a ) { return a.Get(); }
#endif

		template<typename T> constexpr T Power2( T value ) { return value * value; }

		template<typename T> constexpr T Sqrt( T value ) { return ::std::sqrt( value ); }
		template<> constexpr int Sqrt( int value ) { return static_cast<int>( Sqrt( static_cast<double>( value ) ) ); }
		template<> constexpr unsigned int Sqrt( unsigned int value ) { return static_cast<unsigned int>( Sqrt( static_cast<double>( value ) ) ); }
		template<> constexpr long long Sqrt( long long value ) { return static_cast<long long>( Sqrt( static_cast<double>( value ) ) ); }
		template<> constexpr unsigned long long Sqrt( unsigned long long value ) { return static_cast<unsigned long long>( Sqrt( static_cast<double>( value ) ) ); }

	}

#pragma endregion

	template<typename T>
	class Vectorable
	{
	public:
		using SizeType = typename ::std::vector<typename Details::Wrap<T>::type>::size_type;
		using ItrType = typename ::std::vector<typename Details::Wrap<T>::type>::iterator;

	public:

#pragma region Constructors

		constexpr Vectorable( SizeType size )
			: data_( size )
		{ }

		constexpr Vectorable( T element, SizeType size )
			: Vectorable( size )
		{
			::std::fill( ::std::begin( data_ ), ::std::end( data_ ), Details::MakeWrap( element ) );
		}

		template<typename FwdItr>
		constexpr Vectorable( FwdItr begin, FwdItr end )
			: Vectorable( ::std::distance( begin, end ) )
		{
			::std::transform(
				begin,
				end,
				::std::begin( data_ ),
				[]( T value ) { return Details::MakeWrap( value ); } );
		}

#pragma endregion

#pragma region Getter

		constexpr ItrType Begin() { return ::std::begin( data_ ); }
		constexpr ItrType End() { return ::std::end( data_ ); }

		constexpr T First() const { return *::std::begin( data_ ); }
		constexpr T Last() const { return *--::std::end( data_ ); }
		constexpr T At( SizeType index ) const
		{
			if( index > data_.size() )
			{
				OUTOFRANGEEX
			}

			auto itr = ::std::begin( data_ );
			::std::advance( itr, index );
			return *itr;
		}

		constexpr T First( ::std::function<bool( T )> predicate ) const { return Where( predicate ).First(); }
		constexpr T Last( ::std::function<bool( T )> predicate ) const { return Where( predicate ).Last(); }

#pragma endregion

#pragma region Conditional Judgement

		constexpr bool All( T element ) const
		{
			return ::std::all_of( ::std::cbegin( data_ ), ::std::cend( data_ ), ::std::bind( ::std::equal_to<T>(), ::std::placeholders::_1, element ) );
		}
		constexpr bool All( ::std::function<bool( T )> predicate ) const
		{
			return ::std::all_of( ::std::cbegin( data_ ), ::std::cend( data_ ), predicate );
		}

		constexpr bool Any( T element ) const
		{
			return ::std::any_of( ::std::cbegin( data_ ), ::std::cend( data_ ), ::std::bind( ::std::equal_to<T>(), ::std::placeholders::_1, element ) );
		}
		constexpr bool Any( ::std::function<bool( T )> predicate ) const
		{
			return ::std::any_of( ::std::cbegin( data_ ), ::std::cend( data_ ), predicate );
		}

		constexpr bool None( T element ) const
		{
			return ::std::none_of( ::std::cbegin( data_ ), ::std::cend( data_ ), ::std::bind( ::std::equal_to<T>(), ::std::placeholders::_1, element ) );
		}
		constexpr bool None( ::std::function<bool( T )> predicate ) const
		{
			return ::std::none_of( ::std::cbegin( data_ ), ::std::cend( data_ ), predicate );
		}

		constexpr bool Empty() const
		{
			return data_.empty();
		}

		constexpr bool SequenceEqual( Vectorable second ) const
		{
			return Count() == second.Count() && ::std::equal( ::std::cbegin( data_ ), ::std::cend( data_ ), ::std::cbegin( second.data_ ) );
		}

		constexpr bool Contain( T element ) const
		{
			return ::std::find( ::std::cbegin( data_ ), ::std::cend( data_ ), element ) != ::std::cend( data_ );
		}
		constexpr bool Contain( Vectorable second ) const
		{
			return second.All( [&]( T value )
			{
				return ::std::find( ::std::cbegin( data_ ), ::std::cend( data_ ), value ) != ::std::cend( data_ );
			} );
		}
		constexpr bool Include( T element ) const { return Contain( element ); }
		constexpr bool Include( Vectorable second ) const { return Contain( second ); }

#pragma endregion

#pragma region Basic Calc

		constexpr SizeType Count() const { return data_.size(); }
		constexpr SizeType Count( T element ) const
		{
			return ::std::count( ::std::cbegin( data_ ), ::std::cend( data_ ), element );
		}
		constexpr SizeType Count( ::std::function<bool( T )> predicate ) const
		{
			return ::std::count_if( ::std::cbegin( data_ ), ::std::cend( data_ ), predicate );
		}

		constexpr T Sum() const
		{
			ARITHMETICABLECHECK

			return ::std::accumulate( ::std::cbegin( data_ ), ::std::cend( data_ ), static_cast<T>( 0 ) );
		}

		constexpr T Average() const
		{
			ARITHMETICABLECHECK

			return Sum() / static_cast<T>( Count() );
		}
		template<typename S>
		constexpr S Average() const
		{
			ARITHMETICABLECHECK

			return Cast<S>().Average();
		}
		constexpr T Mean() const { return Average(); }
		template<typename S> constexpr S Mean() const { return Average<S>(); }

		constexpr T Minimum() const
		{
			ARITHMETICABLECHECK

			return *::std::min_element( ::std::cbegin( data_ ), ::std::cend( data_ ) );
		}

		constexpr T Maximum() const
		{
			ARITHMETICABLECHECK

			return *::std::max_element( ::std::cbegin( data_ ), ::std::cend( data_ ) );
		}

		constexpr T Median() const
		{
			ARITHMETICABLECHECK

			const auto s = OrderBy();
			const auto count = s.Count();
			auto halfCount = count / static_cast<SizeType>( 2 );
			return count % 2 == 0 ? ( s.At( halfCount - 1 ) + s.At( halfCount ) ) / 2 : s.At( halfCount );
		}

		constexpr T Variance() const
		{
			ARITHMETICABLECHECK

			const auto average = Average();
			const auto count = static_cast<T>( Count() );
			return Aggregate<T>(
				0,
				[average]( T value, T next ) { return value + Details::Power2( next - average ); },
				[count]( T value ) { return value / count; } );
		}
		constexpr T StandardDeviation() const { return static_cast<T>( Details::Sqrt( Variance() ) ); }

		constexpr T Aggregate( T seed, ::std::function<T( T, T )> func ) const
		{
			ARITHMETICABLECHECK

			return ::std::accumulate( ::std::cbegin( data_ ), ::std::cend( data_ ), seed, func );
		}

		template<typename S>
		constexpr S Aggregate( T seed, ::std::function<T( T, T )> func, ::std::function<S( T )> resultSelector ) const
		{
			ARITHMETICABLECHECK

			return resultSelector( ::std::accumulate( ::std::cbegin( data_ ), ::std::cend( data_ ), seed, func ) );
		}

#pragma endregion

#pragma region Filtering

#ifdef __cplusplus_winrt
		template<typename T>
		Vectorable OfType() const
		{
			return OfType( T::typeid );
		}

		Vectorable OfType( Windows::UI::Xaml::Interop::TypeName typeName ) const
		{
			static_assert( __is_valid_winrt_type( typename Details::Wrap<T>::type ), "T is winrt type only." );

			return Where( [typeName]( typename Details::Wrap<T>::type value )
			{
				return ::Windows::UI::Xaml::Interop::TypeName( Details::Unwrap( value )->GetType() ).Name == typeName.Name;
			} );
		}
#endif
		constexpr Vectorable EqualTo( T value ) const
		{
			return Where( ::std::bind( ::std::equal_to<>(), ::std::placeholders::_1, value ) );
		}

		constexpr Vectorable NotEqualTo( T value ) const
		{
			return Where( ::std::bind( ::std::not_equal_to<>(), ::std::placeholders::_1, value ) );
		}

		constexpr Vectorable LessThan( T value ) const
		{
			ARITHMETICABLECHECK

			return Where( ::std::bind( ::std::less<>(), ::std::placeholders::_1, value ) );
		}

		constexpr Vectorable LessThanOrEqualTo( T value ) const
		{
			ARITHMETICABLECHECK

			return Where( ::std::bind( ::std::less_equal<>(), ::std::placeholders::_1, value ) );
		}

		constexpr Vectorable GreaterThan( T value ) const
		{
			ARITHMETICABLECHECK

			return Where( ::std::bind( ::std::greater<>(), ::std::placeholders::_1, value ) );
		}

		constexpr Vectorable GreaterThanOrEqualTo( T value ) const
		{
			ARITHMETICABLECHECK

			return Where( ::std::bind( ::std::greater_equal<>(), ::std::placeholders::_1, value ) );
		}

		constexpr Vectorable Where( ::std::function<bool( T )> predicate ) const
		{
			Vectorable ret( data_.size() );
			auto itr = ::std::copy_if( ::std::cbegin( data_ ), ::std::cend( data_ ), ::std::begin( ret.data_ ), predicate );
			ret.data_.resize( ::std::distance( ::std::begin( ret.data_ ), itr ) );
			return ::std::move( ret );
		}

#pragma endregion

#pragma region Basic Operation

		constexpr Vectorable Skip( SizeType count ) const
		{
			const auto size = data_.size();

			if( count > size )
			{
				OUTOFRANGEEX
			}

			Vectorable ret( size - count );
			auto begin = ::std::cbegin( data_ );
			::std::advance( begin, count );
			::std::copy( begin, ::std::cend( data_ ), ::std::begin( ret.data_ ) );
			return ::std::move( ret );
		}

		constexpr Vectorable SkipWhile( ::std::function<bool( T )> predicate ) const
		{
			SizeType i = 0;
			for( ; i < data_.size(); ++i )
			{
				const auto data = data_[i];
				if( !predicate( data ) )
				{
					break;
				}
			}

			return Skip( i );
		}

		constexpr Vectorable Take( SizeType count ) const
		{
			return TakeWhile( [&count]( T ) { return count-- != 0; } );
		}

		constexpr Vectorable TakeWhile( ::std::function<bool( T )> predicate ) const
		{
			const auto size = data_.size();

			Vectorable ret( size );

			SizeType i = 0;
			for( ; i < size; ++i )
			{
				const auto data = data_[i];
				if( !predicate( data ) )
				{
					break;
				}

				ret.data_[i] = data;
			}

			ret.data_.resize( i );
			return ::std::move( ret );
		}

		constexpr Vectorable Reverse() const
		{
			Vectorable ret( data_.size() );
			::std::reverse_copy( ::std::cbegin( data_ ), ::std::cend( data_ ), ::std::begin( ret.data_ ) );
			return ::std::move( ret );
		}

		constexpr Vectorable Rotate( SizeType advance ) const
		{
			Vectorable ret( data_.size() );
			auto itr = ::std::cbegin( data_ );
			::std::advance( itr, advance );
			::std::rotate_copy( ::std::cbegin( data_ ), itr, ::std::cend( data_ ), ::std::begin( ret.data_ ) );
			return ::std::move( ret );
		}

		constexpr Vectorable OrderBy() const
		{
			Vectorable ret( data_.size() );
			::std::copy( ::std::cbegin( data_ ), ::std::cend( data_ ), ::std::rbegin( ret.data_ ) );
			::std::sort( ::std::begin( ret.data_ ), ::std::end( ret.data_ ) );
			return ::std::move( ret );
		}
		constexpr Vectorable OrderBy( ::std::function<bool( T, T )> predicate ) const
		{
			Vectorable ret( data_.size() );
			::std::copy( ::std::cbegin( data_ ), ::std::cend( data_ ), ::std::rbegin( ret.data_ ) );
			::std::sort( ::std::begin( ret.data_ ), ::std::end( ret.data_ ), predicate );
			return ::std::move( ret );
		}

		constexpr Vectorable OrderByDescending() const
		{
			Vectorable ret( data_.size() );
			::std::copy( ::std::cbegin( data_ ), ::std::cend( data_ ), ::std::rbegin( ret.data_ ) );
			::std::sort( ::std::begin( ret.data_ ), ::std::end( ret.data_ ), ::std::greater<>() );
			return ::std::move( ret );
		}

#pragma endregion

#pragma region Set Calc

		constexpr Vectorable Distinct() const
		{
			Vectorable ret( data_.size() );
			auto itr = ::std::unique_copy( ::std::cbegin( data_ ), ::std::cend( data_ ), ::std::begin( ret.data_ ) );
			ret.data_.resize( ::std::distance( ::std::begin( ret.data_ ), itr ) );
			return ::std::move( ret );
		}
		constexpr Vectorable Distinct( ::std::function<bool( T )> predicate ) const
		{
			Vectorable ret( data_.size() );
			auto itr = ::std::unique_copy( ::std::cbegin( data_ ), ::std::cend( data_ ), ::std::begin( ret.data_ ), predicate );
			ret.data_.resize( ::std::distance( ::std::begin( ret.data_ ), itr ) );
			return ::std::move( ret );
		}

		constexpr Vectorable Concat( Vectorable second ) const
		{
			Vectorable ret( data_.size() + second.Count() );
			auto itr = ::std::copy( ::std::cbegin( data_ ), ::std::cend( data_ ), ::std::rbegin( ret.data_ ) );
			::std::copy( ::std::cbegin( second.data_ ), ::std::cend( second.data_ ), itr );
			return ::std::move( ret );
		}

		constexpr Vectorable Except( Vectorable second ) const
		{
			Vectorable ret( data_.size() );
			auto sortedFirst = OrderBy();
			auto sortedSecond = second.OrderBy();
			::std::set_difference(
				::std::cbegin( sortedFirst.data_ ),
				::std::cend( sortedFirst.data_ ),
				::std::cbegin( sortedSecond.data_ ),
				::std::cend( sortedSecond.data_ ),
				::std::inserter( ret.data_, ::std::begin( ret.data_ ) ) );
			return ::std::move( ret );
		}
		constexpr Vectorable Except( Vectorable second, ::std::function<bool( T, T )> predicate ) const
		{
			Vectorable ret( data_.size() );
			auto sortedFirst = OrderBy();
			auto sortedSecond = second.OrderBy();
			::std::set_difference(
				::std::cbegin( sortedFirst.data_ ),
				::std::cend( sortedFirst.data_ ),
				::std::cbegin( sortedSecond.data_ ),
				::std::cend( sortedSecond.data_ ),
				::std::inserter( ret.data_, ::std::begin( ret.data_ ) ),
				predicate );
			return ::std::move( ret );
		}
		constexpr Vectorable Differ( Vectorable second ) const { return Except( second ); }
		constexpr Vectorable Differ( Vectorable second, ::std::function<bool( T, T )> predicate ) const { return Except( second, predicate ); }

		constexpr Vectorable Union( Vectorable second ) const
		{
			Vectorable ret( data_.size() );
			auto sortedFirst = OrderBy();
			auto sortedSecond = second.OrderBy();
			::std::set_union(
				::std::cbegin( sortedFirst.data_ ),
				::std::cend( sortedFirst.data_ ),
				::std::cbegin( sortedSecond.data_ ),
				::std::cend( sortedSecond.data_ ),
				::std::back_inserter( ret.data_ ) );
			return ::std::move( ret );
		}
		constexpr Vectorable Union( Vectorable second, ::std::function<bool( T, T )> predicate ) const
		{
			Vectorable ret( data_.size() );
			auto sortedFirst = OrderBy();
			auto sortedSecond = second.OrderBy();
			::std::set_union(
				::std::cbegin( sortedFirst.data_ ),
				::std::cend( sortedFirst.data_ ),
				::std::cbegin( sortedSecond.data_ ),
				::std::cend( sortedSecond.data_ ),
				::std::back_inserter( ret.data_ ),
				predicate );
			return ::std::move( ret );
		}

		constexpr Vectorable Intersect( Vectorable second ) const
		{
			Vectorable ret( data_.size() );
			auto sortedFirst = OrderBy();
			auto sortedSecond = second.OrderBy();
			::std::set_difference(
				::std::cbegin( sortedFirst.data_ ),
				::std::cend( sortedFirst.data_ ),
				::std::cbegin( sortedSecond.data_ ),
				::std::cend( sortedSecond.data_ ),
				::std::inserter( ret.data_, ::std::begin( ret.data_ ) ) );
			return ::std::move( ret );
		}
		constexpr Vectorable Intersect( Vectorable second, ::std::function<bool( T, T )> predicate ) const
		{
			Vectorable ret( data_.size() );
			auto sortedFirst = OrderBy();
			auto sortedSecond = second.OrderBy();
			::std::set_intersection(
				::std::cbegin( sortedFirst.data_ ),
				::std::cend( sortedFirst.data_ ),
				::std::cbegin( sortedSecond.data_ ),
				::std::cend( sortedSecond.data_ ),
				::std::back_inserter( ret.data_ ),
				predicate );
			return ::std::move( ret );
		}

#pragma endregion

#pragma region Conversion

#ifdef __cplusplus_winrt
		template<typename S>
		constexpr Vectorable<S> Cast() const
		{
			return Cast<S>( ::std::integral_constant<bool, __is_valid_winrt_type( T ) && !::std::is_arithmetic<T>::value>() );
		}

		template<typename S>
		constexpr Vectorable<S> Cast( ::std::false_type ) const
		{
			return Select<S>( []( T value ) { return static_cast<S>( value ); } );
		}

		template<typename S>
		constexpr Vectorable<S> Cast( ::std::true_type ) const
		{
			static_assert( __is_valid_winrt_type( typename Details::Wrap<T>::type ), "T is winrt type only." );

			return Select<S>( []( T value ) { return dynamic_cast<S>( value ); } );
		}
#else
		template<typename S>
		constexpr Vectorable<S> Cast() const
		{
			return Select<S>( []( T value ) { return static_cast<S>( value ); } );
		}
#endif

		constexpr Vectorable Square() const
		{
			ARITHMETICABLECHECK

			return Select( Details::Power2<T> );
		}

		constexpr Vectorable Select( ::std::function<T( T )> selector ) const
		{
			Vectorable ret( data_.size() );
			::std::transform(
				::std::cbegin( data_ ),
				::std::cend( data_ ),
				ret.Begin(),
				[selector]( typename Details::Wrap<T>::type value ) { return Details::MakeWrap( selector( Details::Unwrap( value ) ) ); } );
			return ::std::move( ret );
		}
		template<typename S>
		constexpr Vectorable<S> Select( ::std::function<S( T )> selector ) const
		{
			Vectorable<S> ret( data_.size() );
			::std::transform(
				::std::cbegin( data_ ),
				::std::cend( data_ ),
				ret.Begin(),
				[selector]( typename Details::Wrap<T>::type value ) { return Details::MakeWrap( selector( Details::Unwrap( value ) ) ); } );
			return ::std::move( ret );
		}

#pragma endregion

#pragma region Vectorlize/Maplize

#if defined( _VECTOR_ ) || defined( _LIBCPP_VECTOR ) || defined( _STLP_VECTOR ) || defined( _GLIBCXX_VECTOR )
		constexpr ::std::vector<T> to_vector() const
		{
			::std::vector<T> ret( data_.size() );
			::std::transform(
				::std::cbegin( data_ ),
				::std::cend( data_ ),
				::std::begin( ret ),
				[]( typename Details::Wrap<T>::type value ) { return Details::Unwrap( value ); } );
			return ::std::move( ret );
		}
		template<typename S> constexpr ::std::vector<T> to_vector( ::std::function<S( T )> selector ) const { return Select<S>( selector ).to_vector(); }
#endif

#if defined( _DEQUE_ ) || defined( _LIBCPP_DEQUE ) || defined( _STLP_DEQUE ) || defined( _GLIBCXX_DEQUE )
		constexpr ::std::deque<T> to_deque() const
		{
			::std::deque<T> ret( data_.size() );
			::std::transform(
				::std::cbegin( data_ ),
				::std::cend( data_ ),
				::std::begin( ret ),
				[]( typename Details::Wrap<T>::type value ) { return Details::Unwrap( value ); } );
			return ::std::move( ret );
		}
		template<typename S> constexpr ::std::deque<T> to_deque( ::std::function<S( T )> selector ) const { return Select<S>( selector ).to_deque(); }
#endif

#if defined( _LIST_ ) || defined( _LIBCPP_LIST ) || defined( _STLP_LIST ) || defined( _GLIBCXX_LIST )
		constexpr ::std::list<T> to_list() const
		{
			::std::list<T> ret( data_.size() );
			::std::transform(
				::std::cbegin( data_ ),
				::std::cend( data_ ),
				::std::begin( ret ),
				[]( typename Details::Wrap<T>::type value ) { return Details::Unwrap( value ); } );
			return ::std::move( ret );
		}
		template<typename S> constexpr ::std::list<T> to_list( ::std::function<S( T )> selector ) const { return Select<S>( selector ).to_list(); }
#endif

#if defined( _FORWARD_LIST_ ) || defined( _LIBCPP_FORWARD_LIST ) || defined( _STLP_FORWARD_LIST ) || defined( _GLIBCXX_FORWARD_LIST )
		constexpr ::std::forward_list<T> to_forward_list() const
		{
			::std::forward_list<T> ret( data_.size() );
			::std::transform(
				::std::cbegin( data_ ),
				::std::cend( data_ ),
				::std::begin( ret ),
				[]( typename Details::Wrap<T>::type value ) { return Details::Unwrap( value ); } );
			return ::std::move( ret );
		}
		template<typename S> constexpr ::std::forward_list<T> to_forward_list( ::std::function<S( T )> selector ) const { return Select<S>( selector ).to_forward_list(); }
#endif

#if defined( _MAP_ ) || defined( _LIBCPP_MAP ) || defined( _STLP_MAP ) || defined( _GLIBCXX_MAP )
		template<typename SKey>
		inline ::std::map<SKey, T> to_map( ::std::function<SKey( T )> selector ) const
		{
			::std::map<SKey, T> ret;
			::std::for_each(
				::std::cbegin( data_ ),
				::std::cend( data_ ),
				[&ret, selector]( typename Details::Wrap<T>::type value )
				{
					auto unwarppedValue = Details::Unwrap( value );
					ret.emplace( selector( unwarppedValue ), unwarppedValue );
				} );
			return ::std::move( ret );
		}
		template<typename SKey, typename SValue>
		inline ::std::map<SKey, SValue> to_map( ::std::function<SKey( T )> keySelector, ::std::function<SValue( T )> valueSelector ) const
		{
			::std::map<SKey, SValue> ret;
			::std::for_each(
				::std::cbegin( data_ ),
				::std::cend( data_ ),
				[&ret, keySelector, valueSelector]( typename Details::Wrap<T>::type value )
				{
					auto unwarppedValue = Details::Unwrap( value );
					ret.emplace( keySelector( unwarppedValue ), valueSelector( unwarppedValue ) );
				} );
			return ::std::move( ret );
		}

		template<typename SKey>
		inline ::std::multimap<SKey, T> to_multimap( ::std::function<SKey( T )> selector ) const
		{
			::std::multimap<SKey, T> ret;
			::std::for_each(
				::std::cbegin( data_ ),
				::std::cend( data_ ),
				[&ret, selector]( typename Details::Wrap<T>::type value )
				{
					auto unwarppedValue = Details::Unwrap( value );
					ret.emplace( selector( unwarppedValue ), unwarppedValue );
				} );
			return ::std::move( ret );
		}
		template<typename SKey, typename SValue>
		inline ::std::multimap<SKey, SValue> to_multimap( ::std::function<SKey( T )> keySelector, ::std::function<SValue( T )> valueSelector ) const
		{
			::std::multimap<SKey, SValue> ret;
			::std::for_each(
				::std::cbegin( data_ ),
				::std::cend( data_ ),
				[&ret, keySelector, valueSelector]( typename Details::Wrap<T>::type value )
				{
					auto unwarppedValue = Details::Unwrap( value );
					ret.emplace( keySelector( unwarppedValue ), valueSelector( unwarppedValue ) );
				} );
			return ::std::move( ret );
		}
#endif

#if defined( _UNORDERED_MAP_ ) || defined(  _LIBCPP_UNORDERED_MAP ) || defined( _STLP_UNORDERED_MAP ) || defined( _GLIBCXX_UNORDERED_MAP )
		template<typename SKey>
		constexpr ::std::unordered_map<SKey, T> to_unordered_map( ::std::function<SKey( T )> selector ) const
		{
			::std::unordered_map<SKey, T> ret;
			::std::for_each(
				::std::cbegin( data_ ),
				::std::cend( data_ ),
				[&ret, selector]( typename Details::Wrap<T>::type value )
				{
					auto unwarppedValue = Details::Unwrap( value );
					ret.emplace( selector( unwarppedValue ), unwarppedValue );
				} );
			return ::std::move( ret );
		}
		template<typename SKey, typename SValue>
		constexpr::std::unordered_map<SKey, SValue> to_unordered_map( ::std::function<SKey( T )> keySelector, ::std::function<SValue( T )> valueSelector ) const
		{
			::std::unordered_map<SKey, SValue> ret;
			::std::for_each(
				::std::cbegin( data_ ),
				::std::cend( data_ ),
				[&ret, keySelector, valueSelector]( typename Details::Wrap<T>::type value )
				{
					auto unwarppedValue = Details::Unwrap( value );
					ret.emplace( keySelector( unwarppedValue ), valueSelector( unwarppedValue ) );
				} );
			return ::std::move( ret );
		}

		template<typename SKey>
		constexpr ::std::unordered_multimap<SKey, T> to_unordered_multimap( ::std::function<SKey( T )> selector ) const
		{
			::std::unordered_multimap<SKey, T> ret;
			::std::for_each(
				::std::cbegin( data_ ),
				::std::cend( data_ ),
				[&ret, selector]( typename Details::Wrap<T>::type value )
				{
					auto unwarppedValue = Details::Unwrap( value );
					ret.emplace( selector( unwarppedValue ), unwarppedValue );
				} );
			return ::std::move( ret );
		}
		template<typename SKey, typename SValue>
		constexpr::std::unordered_multimap<SKey, SValue> to_unordered_multimap( ::std::function<SKey( T )> keySelector, ::std::function<SValue( T )> valueSelector ) const
		{
			::std::unordered_multimap<SKey, SValue> ret;
			::std::for_each(
				::std::cbegin( data_ ),
				::std::cend( data_ ),
				[&ret, keySelector, valueSelector]( typename Details::Wrap<T>::type value )
				{
					auto unwarppedValue = Details::Unwrap( value );
					ret.emplace( keySelector( unwarppedValue ), valueSelector( unwarppedValue ) );
				} );
			return ::std::move( ret );
		}
#endif

#ifdef _COLLECTION_H_
		constexpr ::Windows::Foundation::Collections::IVector<T>^ ToVector() const
		{
			return ref new ::Platform::Collections::Vector<T>( ::std::move( to_vector() ) );
		}
		template<typename S> constexpr ::Windows::Foundation::Collections::IVector<S>^ ToVector( ::std::function<S( T )> selector ) const { return Select<S>( selector ).ToVector(); }

		constexpr ::Windows::Foundation::Collections::IVectorView<T>^ ToVectorView() const
		{
			return ref new ::Platform::Collections::VectorView<T>( ::std::move( to_vector() ) );
		}
		template<typename S> constexpr ::Windows::Foundation::Collections::IVectorView<S>^ ToVectorView( ::std::function<S( T )> selector ) const { return Select<S>( selector ).ToVectorView(); }

#ifdef VECTOR_EXTENSION
		constexpr::Windows::Foundation::Collections::IVector<T>^ ToDeque() const
		{
			return ref new ::Platform::Collections::Vector<T>( ::std::move( to_deque() ) );
		}
		template<typename S> constexpr::Windows::Foundation::Collections::IVector<S>^ ToDeque( ::std::function<S( T )> selector ) const { return Select<S>( selector ).ToDeque(); }

		constexpr::Windows::Foundation::Collections::IVectorView<T>^ ToDequeView() const
		{
			return ref new ::Platform::Collections::VectorView<T>( ::std::move( to_deque() ) );
		}
		template<typename S> constexpr::Windows::Foundation::Collections::IVectorView<S>^ ToDequeView( ::std::function<S( T )> selector ) const { return Select<S>( selector ).ToDequeView(); }
#endif

		template<typename SKey>
		constexpr ::Windows::Foundation::Collections::IMap<SKey, T>^ ToMap( ::std::function<SKey( T )> selector ) const
		{
			return ref new ::Platform::Collections::Map<SKey, T>( ::std::move( to_map( selector ) ) );
		}

		template<typename SKey, typename SValue>
		constexpr ::Windows::Foundation::Collections::IMap<SKey, SValue>^ ToMap( ::std::function<SKey( T )> keySelector, ::std::function<SValue( T )> valueSelector ) const
		{
			return ref new ::Platform::Collections::Map<SKey, SValue>( ::std::move( to_map( keySelector, valueSelector ) ) );
		}

		template<typename SKey>
		constexpr ::Windows::Foundation::Collections::IMapView<SKey, T>^ ToMapView( ::std::function<SKey( T )> selector ) const
		{
			return ref new ::Platform::Collections::MapView<SKey, T>( ::std::move( to_map( selector ) ) );
		}

		template<typename SKey, typename SValue>
		constexpr ::Windows::Foundation::Collections::IMapView<SKey, SValue>^ ToMapView( ::std::function<SKey( T )> keySelector, ::std::function<SValue( T )> valueSelector ) const
		{
			return ref new ::Platform::Collections::MapView<SKey, SValue>( ::std::move( to_map( keySelector, valueSelector ) ) );
		}

		template<typename SKey>
		constexpr ::Windows::Foundation::Collections::IMap<SKey, T>^ ToUnorderedMap( ::std::function<SKey( T )> selector ) const
		{
			return ref new ::Platform::Collections::UnorderedMap<SKey, T>( ::std::move( to_unordered_map( selector ) ) );
		}

		template<typename SKey, typename SValue>
		constexpr ::Windows::Foundation::Collections::IMap<SKey, SValue>^ ToUnorderedMap( ::std::function<SKey( T )> keySelector, ::std::function<SValue( T )> valueSelector ) const
		{
			return ref new ::Platform::Collections::UnorderedMap<SKey, SValue>( ::std::move( to_unordered_map( keySelector, valueSelector ) ) );
		}

		template<typename SKey>
		constexpr ::Windows::Foundation::Collections::IMapView<SKey, T>^ ToUnorderedMapView( ::std::function<SKey( T )> selector ) const
		{
			return ref new ::Platform::Collections::UnorderedMapView<SKey, T>( ::std::move( to_unordered_map( selector ) ) );
		}

		template<typename SKey, typename SValue>
		constexpr ::Windows::Foundation::Collections::IMapView<SKey, SValue>^ ToUnorderedMapView( ::std::function<SKey( T )> keySelector, ::std::function<SValue( T )> valueSelector ) const
		{
			return ref new ::Platform::Collections::UnorderedMapView<SKey, SValue>( ::std::move( to_unordered_map( keySelector, valueSelector ) ) );
		}
#endif

#pragma endregion

	private:
		::std::vector<typename Details::Wrap<T>::type> data_;
	};

	template<typename T>
	using RemoveIteratorT = ::std::remove_const_t<::std::remove_reference_t<::std::remove_const_t<T>>>;

	template<class Container>
	constexpr auto From( const Container& container ) -> Vectorable<RemoveIteratorT<decltype( *::std::begin( container ) )>>
	{
		return Vectorable<RemoveIteratorT<decltype( *::std::begin( container ) )>>( ::std::cbegin( container ), ::std::cend( container ) );
	}

	template<class Integer>
	constexpr Vectorable<Integer> Range( Integer from, Integer to )
	{
		static_assert( ::std::is_integral<Integer>::value, "T is integer only." );

		Vectorable<Integer> ret( to - from + 1 );
		::std::generate( ret.Begin(), ret.End(), [&from] { return from++; } );
		return ret;
	}

	template<typename T>
	constexpr Vectorable<T> Repeat( T element, typename Vectorable<T>::SizeType count )
	{
		return Vectorable<T>( element, count );
	}

}

#ifdef _MSC_VER
#undef constexpr
#endif

#undef OUTOFRANGEEX
#undef ARITHMETICABLECHECK


text:
package com.landian.sql.jpa.criterion;

import com.landian.sql.jpa.annotation.DateRangeTypePolicy;
import org.apache.commons.lang.StringUtils;

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

/**
 * 日期查询
 */
public class CriterionDateBetween implements Criterion {

	private static final long serialVersionUID = 1L;

	public CriterionDateBetween(String column, String beginTime, String endTime,DateRangeTypePolicy type) {
		this.column = column;
		this.beginTime = beginTime;
		this.endTime = endTime;
		this.type = type;
	}
	/**
	 * 字段
	 */
	private String column;
	/**
	 * 时间类型
	 */
	private DateRangeTypePolicy type;
	/**
	 * 开始时间
	 */
	private String beginTime;
	/**
	 * 结束时间
	 */
	private String endTime;

	/**
	 * SQL片段
	 */
	public String SQL(){
		List<String> sqlList = new ArrayList<String>();
		StringBuffer sb = new StringBuffer();
		if(StringUtils.isNotBlank(beginTime) || StringUtils.isNotBlank(endTime)){
			if(DateRangeTypePolicy.DATE == type){
				if(StringUtils.isNotBlank(beginTime)){
					sqlList.add(column + " >= '" + beginTime + "'");
				}
				if(StringUtils.isNotBlank(endTime)){
					sqlList.add(column +" <= '" + endTime + " 23:59:59'");
				}
			}
			if(sqlList.size()>1){
				sb.append("(");
				sb.append("(" + sqlList.get(0) + ")");
				sb.append(" and (" + sqlList.get(1) + ")");
				sb.append(")");
			}else{
				sb.append("(" + sqlList.get(0) + ")");
			}
		}
		return sb.toString();
	}
}

redpajama_set_name: RedPajamaGithub


text:
package engine

import (
	"context"
	"fmt"
	"io"

	"vitess.io/vitess/go/vt/vtgate/evalengine"

	"vitess.io/vitess/go/sqltypes"

	querypb "vitess.io/vitess/go/vt/proto/query"
)

var _ Primitive = (*Limit)(nil)

// Limit is a primitive that performs the LIMIT operation.
type Limit struct {
	Count  evalengine.Expr
	Offset evalengine.Expr
	Input  Primitive
}

// RouteType returns a description of the query routing type used by the primitive
func (l *Limit) RouteType() string {
	return l.Input.RouteType()
}

// GetKeyspaceName specifies the Keyspace that this primitive routes to.
func (l *Limit) GetKeyspaceName() string {
	return l.Input.GetKeyspaceName()
}

// GetTableName specifies the table that this primitive routes to.
func (l *Limit) GetTableName() string {
	return l.Input.GetTableName()
}

// TryExecute satisfies the Primitive interface.
func (l *Limit) TryExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool) (*sqltypes.Result, error) {
	count, offset, err := l.getCountAndOffset(vcursor, bindVars)
	if err != nil {
		return nil, err
	}
	// When offset is present, we hijack the limit value so we can calculate
	// the offset in memory from the result of the scatter query with count + offset.
	bindVars["__upper_limit"] = sqltypes.Int64BindVariable(int64(count + offset))

	result, err := vcursor.ExecutePrimitive(ctx, l.Input, bindVars, wantfields)
	if err != nil {
		return nil, err
	}

	// There are more rows in the response than limit + offset
	if count+offset <= len(result.Rows) {
		result.Rows = result.Rows[offset : count+offset]
		return result, nil
	}
	// Remove extra rows from response
	if offset <= len(result.Rows) {
		result.Rows = result.Rows[offset:]
		return result, nil
	}
	// offset is beyond the result set
	result.Rows = nil
	return result, nil
}

// TryStreamExecute satisfies the Primitive interface.
func (l *Limit) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error {
	count, offset, err := l.getCountAndOffset(vcursor, bindVars)
	if err != nil {
		return err
	}

	bindVars = copyBindVars(bindVars)

	// When offset is present, we hijack the limit value so we can calculate
	// the offset in memory from the result of the scatter query with count + offset.
	bindVars["__upper_limit"] = sqltypes.Int64BindVariable(int64(count + offset))

	err = vcursor.StreamExecutePrimitive(ctx, l.Input, bindVars, wantfields, func(qr *sqltypes.Result) error {
		if len(qr.Fields) != 0 {
			if err := callback(&sqltypes.Result{Fields: qr.Fields}); err != nil {
				return err
			}
		}
		inputSize := len(qr.Rows)
		if inputSize == 0 {
			return nil
		}

		// we've still not seen all rows we need to see before we can return anything to the client
		if offset > 0 {
			if inputSize <= offset {
				// not enough to return anything yet
				offset -= inputSize
				return nil
			}
			qr.Rows = qr.Rows[offset:]
			offset = 0
		}

		if count == 0 {
			return io.EOF
		}

		// reduce count till 0.
		result := &sqltypes.Result{Rows: qr.Rows}
		resultSize := len(result.Rows)
		if count > resultSize {
			count -= resultSize
			return callback(result)
		}
		result.Rows = result.Rows[:count]
		count = 0
		if err := callback(result); err != nil {
			return err
		}
		return io.EOF
	})

	if err == io.EOF {
		// We may get back the EOF we returned in the callback.
		// If so, suppress it.
		return nil
	}
	if err != nil {
		return err
	}
	return nil
}

// GetFields implements the Primitive interface.
func (l *Limit) GetFields(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable) (*sqltypes.Result, error) {
	return l.Input.GetFields(ctx, vcursor, bindVars)
}

// Inputs returns the input to limit
func (l *Limit) Inputs() []Primitive {
	return []Primitive{l.Input}
}

// NeedsTransaction implements the Primitive interface.
func (l *Limit) NeedsTransaction() bool {
	return l.Input.NeedsTransaction()
}

func (l *Limit) getCountAndOffset(vcursor VCursor, bindVars map[string]*querypb.BindVariable) (count int, offset int, err error) {
	env := evalengine.EnvWithBindVars(bindVars, vcursor.ConnCollation())
	count, err = getIntFrom(env, l.Count)
	if err != nil {
		return
	}
	offset, err = getIntFrom(env, l.Offset)
	if err != nil {
		return
	}
	return
}

func getIntFrom(env *evalengine.ExpressionEnv, expr evalengine.Expr) (int, error) {
	if expr == nil {
		return 0, nil
	}
	evalResult, err := env.Evaluate(expr)
	if err != nil {
		return 0, err
	}
	value := evalResult.Value()
	if value.IsNull() {
		return 0, nil
	}

	num, err := value.ToUint64()
	if err != nil {
		return 0, err
	}
	count := int(num)
	if count < 0 {
		return 0, fmt.Errorf("requested limit is out of range: %v", num)
	}
	return count, nil
}

func (l *Limit) description() PrimitiveDescription {
	other := map[string]any{}

	if l.Count != nil {
		other["Count"] = evalengine.FormatExpr(l.Count)
	}
	if l.Offset != nil {
		other["Offset"] = evalengine.FormatExpr(l.Offset)
	}

	return PrimitiveDescription{
		OperatorType: "Limit",
		Other:        other,
	}
}


text:
package com.bingoogol.mymoment.test;

import junit.framework.Assert;
import android.test.AndroidTestCase;

import com.bingoogol.mymoment.domain.Moment;
import com.bingoogol.mymoment.service.MomentService;
import com.bingoogol.mymoment.util.DateUtil;

public class MomentServiceTest extends AndroidTestCase {
	public void testAddMoment() {
		MomentService momentService = new MomentService(getContext());
		Moment moment = new Moment();
		moment.setContent("测试内容斯蒂芬所的");
		moment.setImgPath("测试图片路径");
		moment.setPublishTime(DateUtil.getPublishTime());
		Assert.assertTrue(momentService.addMoment(moment));
	}
}


text:
#ifndef TENSORFLOW_CORE_KERNELS_SPACETOBATCH_FUNCTOR_H_
#define TENSORFLOW_CORE_KERNELS_SPACETOBATCH_FUNCTOR_H_

#include <type_traits>

#include "third_party/eigen3/unsupported/Eigen/CXX11/Tensor"
#include "tensorflow/core/framework/tensor.h"
#include "tensorflow/core/framework/tensor_types.h"
#include "tensorflow/core/kernels/bounds_check.h"
#include "tensorflow/core/platform/types.h"

namespace tensorflow {

// Maximum number of non-collapsible blocked dimensions supported by the
// {SpaceToBatch,BatchToSpace}ND operation.  To change the limit, modify this
// constant and the TF_SPACETOBATCH_FOR_EACH_NUM_BLOCK_DIMS macro definition
// below.
constexpr int kMaxSpaceToBatchBlockDims = 4;

// Expands to:
//   MACRO(1, ## __VA_ARGS__)
//   ...
//   MACRO(kMaxSpaceToBatchBlockDims, ## __VA_ARGS__)
//
// Note: The space between the number and the comma is necessary for proper GCC
// comma handling: https://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html
#define TF_SPACETOBATCH_FOR_EACH_NUM_BLOCK_DIMS(MACRO, ...) \
  MACRO(1 /**/, ##__VA_ARGS__)                              \
  MACRO(2 /**/, ##__VA_ARGS__)                              \
  MACRO(3 /**/, ##__VA_ARGS__)                              \
  MACRO(4 /**/, ##__VA_ARGS__)                              \
/**/

namespace internal {
namespace spacetobatch {

template <typename InputType, typename OutputType>
void SubtleMustCopyFlatHelper(const Tensor& t, OutputType* output) {
  const int64 num_elements = t.shape().num_elements();
  output->resize(num_elements);
  auto eigen_vec = t.flat<InputType>();
  for (int64 i = 0; i < num_elements; ++i) {
    (*output)[i] = SubtleMustCopy(eigen_vec(i));
  }
}

// Copies flat contents of `t` to std::vector-like `*output`, which is resized
// as needed.  `OutputType` may be either `std::vector<int64>` or
// `gtl::InlinedVector<int64>`.
//
// Precondition: t.dtype() must be either DT_INT32 or DT_INT64.
template <typename OutputType>
void SubtleMustCopyFlat(const Tensor& t, OutputType* output) {
  if (t.dtype() == DT_INT32) {
    SubtleMustCopyFlatHelper<int32, OutputType>(t, output);
  } else {
    SubtleMustCopyFlatHelper<int64, OutputType>(t, output);
  }
}

}  // namespace spacetobatch
}  // namespace internal

namespace functor {

// Functor used by {SpaceToBatch,BatchToSpace}{ND,}Op to do the conversion.
//
// If B2S is false, then this performs the space-to-batch conversion.  If S2B is
// true, then this performs the inverse batch-to-space conversion.
template <typename Device, typename T, int NUM_BLOCK_DIMS, bool B2S = false>
struct SpaceToBatchFunctor {
  using InputT = typename std::conditional<B2S, T, const T>::type;
  using OutputT = typename std::conditional<B2S, const T, T>::type;
  // Implements the space to batch conversion.
  //
  // space_tensor: input tensor of space-to-batch operation.  If B2S = false,
  //     then this is the input to the conversion.  If B2S = true, then this
  //     is the output of the conversion.
  // block_size: array of shape [NUM_BLOCK_DIMS] specifying the block sizes for
  //     dimensions 1 through NUM_BLOCK_DIMS.
  // paddings: row-major array of shape [NUM_BLOCK_DIMS, 2] specifying the
  //     start and end padding for dimensions 1 through NUM_BLOCK_DIMS.
  // batch_tensor: output tensor of the space-to-batch operation.  If
  //     B2S = false, then this is the output of the conversion.  If B2S = true,
  //     then this is the input to the conversion.
  //
  // The caller must ensure that the dimensions of the tensors are correct.
  Status operator()(
      const Device& d,
      typename TTypes<InputT, NUM_BLOCK_DIMS + 2>::Tensor space_tensor,
      const int64 block_shape[NUM_BLOCK_DIMS],
      const int64 paddings[NUM_BLOCK_DIMS * 2],
      typename TTypes<OutputT, NUM_BLOCK_DIMS + 2>::Tensor batch_tensor);
};

}  // namespace functor
}  // namespace tensorflow

#endif  // TENSORFLOW_CORE_KERNELS_SPACETOBATCH_FUNCTOR_H_


text:
1. If the Google Cloud SDK is not already installed, download a tarball for
the latest version from
<https://cloud.google.com/sdk/docs/downloads-versioned-archives>
and extract it to somewhere on your filesystem, e.g:

    ```bash
    wget https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-sdk-180.0.1-linux-x86_64.tar.gz

    tar zxf google-cloud-sdk-180.0.1-linux-x86_64.tar.gz -C "${HOME}"
    ```

    Alternatively, you can install the SDK using `apt-get` as described in
    <https://cloud.google.com/sdk/docs/downloads-apt-get>.

2. Use `gsutil` to copy the server deb from its GCS bucket to your local
machine:

    ```bash
    $HOME/google-cloud-sdk/bin/gsutil cp gs://autobuilds.grr-response.com/_latest_server_deb/*.deb .
    ```

3. Install the server deb the same way you would a
[release deb](from-release-deb.md).


text:
import * as type from './type';
function getBlobBuilder() {
    if (typeof BlobBuilder !== 'undefined') {
        return BlobBuilder;
    }
    else if (typeof WebKitBlobBuilder !== 'undefined') {
        return WebKitBlobBuilder;
    }
    else {
        return undefined;
    }
}
/**
 * Concatenates one or more values together and converts them to a Blob.
 *
 * @param var_args The values that will make up the resulting blob.
 * @return The blob.
 */
export function getBlob() {
    var var_args = [];
    for (var _i = 0; _i < arguments.length; _i++) {
        var_args[_i] = arguments[_i];
    }
    var BlobBuilder = getBlobBuilder();
    if (BlobBuilder !== undefined) {
        var bb = new BlobBuilder();
        for (var i = 0; i < var_args.length; i++) {
            bb.append(var_args[i]);
        }
        return bb.getBlob();
    }
    else {
        if (type.isNativeBlobDefined()) {
            return new Blob(var_args);
        }
        else {
            throw Error("This browser doesn't seem to support creating Blobs");
        }
    }
}
/**
 * Slices the blob. The returned blob contains data from the start byte
 * (inclusive) till the end byte (exclusive). Negative indices cannot be used.
 *
 * @param blob The blob to be sliced.
 * @param start Index of the starting byte.
 * @param end Index of the ending byte.
 * @return The blob slice or null if not supported.
 */
export function sliceBlob(blob, start, end) {
    if (blob.webkitSlice) {
        return blob.webkitSlice(start, end);
    }
    else if (blob.mozSlice) {
        return blob.mozSlice(start, end);
    }
    else if (blob.slice) {
        return blob.slice(start, end);
    }
    return null;
}

//# sourceMappingURL=fs.js.map


text:
using System;
using System.Collections.Generic;

namespace Carbon.Json.Converters
{
    public sealed class JsonConverterFactory
    {
        private static readonly Dictionary<Type, IJsonConverter> converters = new Dictionary<Type, IJsonConverter>();

        static JsonConverterFactory()
        {
            AddInternal<Boolean>(new BooleanConverter());
            AddInternal<DateTime>(new DateTimeConverter());
            AddInternal<DateTimeOffset>(new DateTimeOffsetConverter());
            AddInternal<Byte[]>(new BinaryConverter());
            AddInternal<Decimal>(new DecimalConverter());
            AddInternal<Double>(new DoubleConverter());
            AddInternal<Guid>(new GuidConverter());
            AddInternal<Int16>(new Int16Converter());
            AddInternal<Int32>(new Int32Converter());
            AddInternal<Int64>(new Int64Converter());
            AddInternal<Single>(new SingleConverter());
            AddInternal<String>(new StringConverter());
            AddInternal<TimeSpan>(new TimeSpanConverter());
            AddInternal<UInt16>(new UInt16Converter());
            AddInternal<UInt32>(new UInt32Converter());
            AddInternal<UInt64>(new UInt64Converter());
            AddInternal<Uri>(new UriConverter());

            // Hash sets
            AddInternal(new HashSetConverter<string>());
            AddInternal(new HashSetConverter<short>());
            AddInternal(new HashSetConverter<int>());
            AddInternal(new HashSetConverter<long>());
            AddInternal(new HashSetConverter<float>());
            AddInternal(new HashSetConverter<double>());

            // JSON

            AddInternal(new JsonObjectConverter());
            AddInternal(new JsonArrayConverter());
        }

        internal static Dictionary<Type, IJsonConverter> Instances => converters;

        public static IJsonConverter Get(Type type)
        {
            var details = TypeDetails.Get(type);

            if (details.JsonConverter is null)
            {
                throw new ConversionException($"No converter found for '{type.Name}'.");
            }

            return details.JsonConverter;
        }

        public static bool TryGet(Type type, out IJsonConverter converter)
        {
            var typeDetails = TypeDetails.Get(type);

            converter = typeDetails.JsonConverter;

            return converter != null;
        }

        private static void AddInternal<T>(JsonConverter<T> converter)
            => converters.Add(typeof(T), converter);

        private static void AddInternal<T>(IJsonConverter converter)
            => converters.Add(typeof(T), converter);

        public static void Add<T>(JsonConverter<T> converter)
        {
            if (converter is null)
            {
                throw new ArgumentNullException(nameof(converter));
            }

            AddInternal(converter);

            var type = TypeDetails.Get<T>();

            type.JsonConverter = converter;
        }
    }
}


text:
using Microsoft.VisualBasic.FileIO;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ML_3
{
    internal static class Helper
    {
        public static IEnumerable<InEntry> ReadFile(string inPath)
        {
            using (TextFieldParser parser = new TextFieldParser(inPath))
            {
                parser.CommentTokens = new string[] { "#" };
                parser.SetDelimiters(new string[] { "," });
                parser.HasFieldsEnclosedInQuotes = true;

                // Skip over header line.
                // parser.ReadLine();

                while (!parser.EndOfData)
                {
                    string[] fields = parser.ReadFields();
                    if (fields.Length == 1)
                    {
                        yield return new InEntry() { Text = ConvertField0(fields[0]) };
                    }
                    else
                    {
                        yield return new InEntry()
                        {
                            Text = ConvertField0(fields[0]),
                            Plz = int.Parse(fields[1]),
                            Country = int.Parse(fields[2]),
                        };
                    }
                }
            }
        }

        private static string ConvertField0(string field)
        {
            return field.Split(' ').Select(x => x).Aggregate((x, y) => x + " " + y).ToLower().Replace("\"", "$");
        }

        public static void WriteYMatix(IEnumerable<InEntry> data, string outPath)
        {
            File.WriteAllLines(outPath, data.Select(x => x.Plz.ToString() + "," + x.Country.ToString()));
        }

        public static void WriteClassesMatix(IEnumerable<InEntry> data, string outPath)
        {
            var cities = data.GroupBy(x => x.Plz);
            var cityCountries = cities.Select(c => c.Key.ToString() + "," + c.GroupBy(e => e.Country).OrderByDescending(g => g.Count()).First().Key.ToString());
            File.WriteAllLines(outPath, cityCountries);
        }

        public static void WriteXMatrix(IEnumerable<InEntry> data, IEnumerable<String> words, string outPath)
        {
            var wordList = words.ToList();
            var assignedData = data.Select(x => MapSentenceToWords(x.Text.ToLower().Split(' '), wordList));
            var strTab = assignedData.Select(x => x.Select(x2 => x2.ToString()).Aggregate((z, y) => z + ", " + y));
            File.WriteAllLines(outPath, strTab);
        }

        private static int[] MapSentenceToWords(String[] sentence, List<String> wordList)
        {
            int[] result = new int[wordList.Count];
            foreach (var word in sentence)
            {
                int index = wordList.FindIndex(w => w == word);
                if (index >= 0)
                    result[index] = 1;
            }
            return result;
        }

        internal static void WriteOverride(IEnumerable<InEntry> data, string outPath)
        {
            List<int> overrides = new List<int>();
            foreach (var item in data)
            {
                //if (item.Text.Contains("rhfcyjzhcrf hfqjyf"))
                //{
                //    overrides.Add(105089);
                //   // if (item.Plz != 105089) throw new Exception("rule is broken");
                //}
                //else
                {
                    overrides.Add(0);
                }
            }
            File.WriteAllLines(outPath, overrides.Select(x => x.ToString()));
        }
    }
}


text:
var fs = require('fs')
var {exec, execSync} = require('child_process')

var source = `${__dirname}/../../source`
var public = `${__dirname}/../../public`
if (!fs.existsSync(public)) fs.mkdirSync(public)

function rsyncSource(){
  exec(`rsync -a --exclude _posts --exclude _templates ${source}/ ${public}/`)
}
rsyncSource()

// var hljs = require('highlight.js')
var marked = require('marked')
marked.setOptions({
  // highlight: (code, lang) => hljs.highlight(lang || 'html', code).value,
  smartypants: true
})

var templates = {}
readdirAbs(`${source}/_templates`).forEach(path => {
  var str = fs.readFileSync(path, 'utf8')
  var templateName = path.split('_templates/')[1]
  templates[templateName] = d => eval('`' + str + '`')
})

function readdirAbs(dir){ return fs.readdirSync(dir).map(d => dir + '/' + d) }

var posts = readdirAbs(`${source}/_posts`)
  .filter(d => !d.includes('.DS_Store'))
  .map(parsePost)

fs.writeFileSync(public + '/rss.xml',  templates['rss.xml'](posts))
fs.writeFileSync(public + '/sitemap.xml', templates['sitemap.xml'](posts))

function parsePost(path){
  var str = fs.readFileSync(path, 'utf8')
  if (str[0] == '<') str = str.split('License.\n-->')[1]
  var [top, body] = str
    .replace('---\n', '')
    .split('\n---\n')

  console.log(path)

  var post = {html: path.includes('.html') ? body : marked(body)}
  top.split('\n').forEach(line => {
    var [key, val] = line.split(/: (.+)/)
    post[key] = val
  })

  return post
}

function writePost(post){
  var dir = public + post.permalink
  if (!fs.existsSync(dir)) execSync(`mkdir -p ${dir}`)
  fs.writeFileSync(`${dir}/index.html`, templates[post.template](post))

  var outposts = JSON.parse(JSON.stringify(posts))
  outposts.forEach(d => delete d.html)
  fs.writeFileSync(public + '/posts.json', JSON.stringify(outposts, null, 2))

}
posts.forEach(writePost)

if (process.argv.includes('--watch')){
  require('chokidar').watch(source).on('change', path => {
    rsyncSource()
    if (path.includes('_posts/')) writePost(parsePost(path))
  })
}


text:
using Ayu.Discord.Voice;
using WizBot.Services.Database.Models;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Wiz.Common;

namespace WizBot.Modules.Music;

public sealed class MusicPlayer : IMusicPlayer
{
    public event Func<IMusicPlayer, IQueuedTrackInfo, Task>? OnCompleted;
    public event Func<IMusicPlayer, IQueuedTrackInfo, int, Task>? OnStarted;
    public event Func<IMusicPlayer, Task>? OnQueueStopped;
    public bool IsKilled { get; private set; }
    public bool IsStopped { get; private set; }
    public bool IsPaused { get; private set; }
    public PlayerRepeatType Repeat { get; private set; }

    public int CurrentIndex
        => _queue.Index;

    public float Volume { get; private set; } = 1.0f;

    private readonly AdjustVolumeDelegate _adjustVolume;
    private readonly VoiceClient _vc;

    private readonly IMusicQueue _queue;
    private readonly ITrackResolveProvider _trackResolveProvider;
    private readonly IVoiceProxy _proxy;
    private readonly IGoogleApiService _googleApiService;
    private readonly ISongBuffer _songBuffer;

    private bool skipped;
    private int? forceIndex;
    private readonly Thread _thread;
    private readonly Random _rng;

    public bool AutoPlay { get; set; }

    public MusicPlayer(
        IMusicQueue queue,
        ITrackResolveProvider trackResolveProvider,
        IVoiceProxy proxy,
        IGoogleApiService googleApiService,
        QualityPreset qualityPreset,
        bool autoPlay)
    {
        _queue = queue;
        _trackResolveProvider = trackResolveProvider;
        _proxy = proxy;
        _googleApiService = googleApiService;
        AutoPlay = autoPlay;
        _rng = new WizBotRandom();

        _vc = GetVoiceClient(qualityPreset);
        if (_vc.BitDepth == 16)
            _adjustVolume = AdjustVolumeInt16;
        else
            _adjustVolume = AdjustVolumeFloat32;

        _songBuffer = new PoopyBufferImmortalized(_vc.InputLength);

        _thread = new(async () =>
        {
            await PlayLoop();
        });
        _thread.Start();
    }

    private static VoiceClient GetVoiceClient(QualityPreset qualityPreset)
        => qualityPreset switch
        {
            QualityPreset.Highest => new(),
            QualityPreset.High => new(SampleRate._48k, Bitrate._128k, Channels.Two, FrameDelay.Delay40),
            QualityPreset.Medium => new(SampleRate._48k,
                Bitrate._96k,
                Channels.Two,
                FrameDelay.Delay40,
                BitDepthEnum.UInt16),
            QualityPreset.Low => new(SampleRate._48k,
                Bitrate._64k,
                Channels.Two,
                FrameDelay.Delay40,
                BitDepthEnum.UInt16),
            _ => throw new ArgumentOutOfRangeException(nameof(qualityPreset), qualityPreset, null)
        };

    private async Task PlayLoop()
    {
        var sw = new Stopwatch();

        while (!IsKilled)
        {
            // wait until a song is available in the queue
            // or until the queue is resumed
            var track = _queue.GetCurrent(out var index);

            if (track is null || IsStopped)
            {
                await Task.Delay(500);
                continue;
            }

            if (skipped)
            {
                skipped = false;
                _queue.Advance();
                continue;
            }

            using var cancellationTokenSource = new CancellationTokenSource();
            var token = cancellationTokenSource.Token;
            try
            {
                // light up green in vc
                _ = _proxy.StartSpeakingAsync();

                _ = OnStarted?.Invoke(this, track, index);

                // make sure song buffer is ready to be (re)used
                _songBuffer.Reset();

                var streamUrl = await track.GetStreamUrl();
                // start up the data source
                using var source = FfmpegTrackDataSource.CreateAsync(
                    _vc.BitDepth,
                    streamUrl,
                    track.Platform == MusicPlatform.Local);

                // start moving data from the source into the buffer
                // this method will return once the sufficient prebuffering is done
                await _songBuffer.BufferAsync(source, token);

                // // Implemenation with multimedia timer. Works but a hassle because no support for switching
                // // vcs, as any error in copying will cancel the song. Also no idea how to use this as an option
                // // for selfhosters.
                // if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                // {
                //     var cancelSource = new CancellationTokenSource();
                //     var cancelToken = cancelSource.Token;
                //     using var timer = new MultimediaTimer(_ =>
                //     {
                //         if (IsStopped || IsKilled)
                //         {
                //             cancelSource.Cancel();
                //             return;
                //         }
                //
                //         if (_skipped)
                //         {
                //             _skipped = false;
                //             cancelSource.Cancel();
                //             return;
                //         }
                //
                //         if (IsPaused)
                //             return;
                //
                //         try
                //         {
                //             // this should tolerate certain number of errors
                //             var result = CopyChunkToOutput(_songBuffer, _vc);
                //             if (!result)
                //                 cancelSource.Cancel();
                //
                //         }
                //         catch (Exception ex)
                //         {
                //             Log.Warning(ex, "Something went wrong sending voice data: {ErrorMessage}", ex.Message);
                //             cancelSource.Cancel();
                //         }
                //
                //     }, null, 20);
                //
                //     while(true)
                //         await Task.Delay(1000, cancelToken);
                // }

                // start sending data
                var ticksPerMs = 1000f / Stopwatch.Frequency;
                sw.Start();
                Thread.Sleep(2);

                var delay = sw.ElapsedTicks * ticksPerMs > 3f ? _vc.Delay - 16 : _vc.Delay - 3;

                var errorCount = 0;
                while (!IsStopped && !IsKilled)
                {
                    // doing the skip this way instead of in the condition
                    // ensures that a song will for sure be skipped
                    if (skipped)
                    {
                        skipped = false;
                        break;
                    }

                    if (IsPaused)
                    {
                        await Task.Delay(200);
                        continue;
                    }

                    sw.Restart();
                    var ticks = sw.ElapsedTicks;
                    try
                    {
                        var result = CopyChunkToOutput(_songBuffer, _vc);

                        // if song is finished
                        if (result is null)
                            break;

                        if (result is true)
                        {
                            if (errorCount > 0)
                            {
                                _ = _proxy.StartSpeakingAsync();
                                errorCount = 0;
                            }

                            // FUTURE windows multimedia api

                            // wait for slightly less than the latency
                            Thread.Sleep(delay);

                            // and then spin out the rest
                            while ((sw.ElapsedTicks - ticks) * ticksPerMs <= _vc.Delay - 0.1f)
                                Thread.SpinWait(100);
                        }
                        else
                        {
                            // result is false is either when the gateway is being swapped
                            // or if the bot is reconnecting, or just disconnected for whatever reason

                            // tolerate up to 15x200ms of failures (3 seconds)
                            if (++errorCount <= 15)
                            {
                                await Task.Delay(200);
                                continue;
                            }

                            Log.Warning("Can't send data to voice channel");

                            IsStopped = true;
                            // if errors are happening for more than 3 seconds
                            // Stop the player
                            break;
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Warning(ex, "Something went wrong sending voice data: {ErrorMessage}", ex.Message);
                    }
                }
            }
            catch (Win32Exception)
            {
                IsStopped = true;
                Log.Error("Please install ffmpeg and make sure it's added to your "
                          + "PATH environment variable before trying again");
            }
            catch (OperationCanceledException)
            {
                Log.Information("Song skipped");
            }
            catch (Exception ex)
            {
                Log.Error(ex, "Unknown error in music loop: {ErrorMessage}", ex.Message);
            }
            finally
            {
                cancellationTokenSource.Cancel();
                // turn off green in vc

                _ = OnCompleted?.Invoke(this, track);

                if (AutoPlay && track.Platform == MusicPlatform.Youtube)
                {
                    try
                    {
                        var relatedSongs = await _googleApiService.GetRelatedVideosAsync(track.TrackInfo.Id, 5);
                        var related = relatedSongs.Shuffle().FirstOrDefault();
                        if (related is not null)
                        {
                            var relatedTrack = await _trackResolveProvider.QuerySongAsync(related, MusicPlatform.Youtube);
                            if (relatedTrack is not null)
                                EnqueueTrack(relatedTrack, "Autoplay");
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Warning(ex, "Failed queueing a related song via autoplay");
                    }
                }

                HandleQueuePostTrack();
                skipped = false;

                _ = _proxy.StopSpeakingAsync();

                await Task.Delay(100);
            }
        }
    }

    private bool? CopyChunkToOutput(ISongBuffer sb, VoiceClient vc)
    {
        var data = sb.Read(vc.InputLength, out var length);

        // if nothing is read from the buffer, song is finished
        if (data.Length == 0)
            return null;

        _adjustVolume(data, Volume);
        return _proxy.SendPcmFrame(vc, data, length);
    }

    private void HandleQueuePostTrack()
    {
        if (forceIndex is { } index)
        {
            _queue.SetIndex(index);
            forceIndex = null;
            return;
        }

        var (repeat, isStopped) = (Repeat, IsStopped);

        if (repeat == PlayerRepeatType.Track || isStopped)
            return;

        // if queue is being repeated, advance no matter what
        if (repeat == PlayerRepeatType.None)
        {
            // if this is the last song,
            // stop the queue
            if (_queue.IsLast())
            {
                IsStopped = true;
                OnQueueStopped?.Invoke(this);
                return;
            }

            _queue.Advance();
            return;
        }

        _queue.Advance();
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    private static void AdjustVolumeInt16(Span<byte> audioSamples, float volume)
    {
        if (Math.Abs(volume - 1f) < 0.0001f)
            return;

        var samples = MemoryMarshal.Cast<byte, short>(audioSamples);

        for (var i = 0; i < samples.Length; i++)
        {
            ref var sample = ref samples[i];
            sample = (short)(sample * volume);
        }
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    private static void AdjustVolumeFloat32(Span<byte> audioSamples, float volume)
    {
        if (Math.Abs(volume - 1f) < 0.0001f)
            return;

        var samples = MemoryMarshal.Cast<byte, float>(audioSamples);

        for (var i = 0; i < samples.Length; i++)
        {
            ref var sample = ref samples[i];
            sample *= volume;
        }
    }

    public async Task<(IQueuedTrackInfo? QueuedTrack, int Index)> TryEnqueueTrackAsync(
        string query,
        string queuer,
        bool asNext,
        MusicPlatform? forcePlatform = null)
    {
        var song = await _trackResolveProvider.QuerySongAsync(query, forcePlatform);
        if (song is null)
            return default;

        int index;

        if (asNext)
            return (_queue.EnqueueNext(song, queuer, out index), index);

        return (_queue.Enqueue(song, queuer, out index), index);
    }

    public async Task EnqueueManyAsync(IEnumerable<(string Query, MusicPlatform Platform)> queries, string queuer)
    {
        var errorCount = 0;
        foreach (var chunk in queries.Chunk(5))
        {
            if (IsKilled)
                break;

            await chunk.Select(async data =>
                       {
                           var (query, platform) = data;
                           try
                           {
                               await TryEnqueueTrackAsync(query, queuer, false, platform);
                               errorCount = 0;
                           }
                           catch (Exception ex)
                           {
                               Log.Warning(ex, "Error resolving {MusicPlatform} Track {TrackQuery}", platform, query);
                               ++errorCount;
                           }
                       })
                       .WhenAll();

            await Task.Delay(1000);

            // > 10 errors in a row = kill
            if (errorCount > 10)
                break;
        }
    }

    public void EnqueueTrack(ITrackInfo track, string queuer)
        => _queue.Enqueue(track, queuer, out _);

    public void EnqueueTracks(IEnumerable<ITrackInfo> tracks, string queuer)
        => _queue.EnqueueMany(tracks, queuer);

    public void SetRepeat(PlayerRepeatType type)
        => Repeat = type;

    public void ShuffleQueue()
        => _queue.Shuffle(_rng);

    public void Stop()
        => IsStopped = true;

    public void Clear()
    {
        _queue.Clear();
        skipped = true;
    }

    public IReadOnlyCollection<IQueuedTrackInfo> GetQueuedTracks()
        => _queue.List();

    public IQueuedTrackInfo? GetCurrentTrack(out int index)
        => _queue.GetCurrent(out index);

    public void Next()
    {
        skipped = true;
        IsStopped = false;
        IsPaused = false;
    }

    public bool MoveTo(int index)
    {
        if (_queue.SetIndex(index))
        {
            forceIndex = index;
            skipped = true;
            IsStopped = false;
            IsPaused = false;
            return true;
        }

        return false;
    }

    public void SetVolume(int newVolume)
    {
        var normalizedVolume = newVolume / 100f;
        if (normalizedVolume is < 0f or > 1f)
            throw new ArgumentOutOfRangeException(nameof(newVolume), "Volume must be in range 0-100");

        Volume = normalizedVolume;
    }

    public void Kill()
    {
        IsKilled = true;
        IsStopped = true;
        IsPaused = false;
        skipped = true;
    }

    public bool TryRemoveTrackAt(int index, out IQueuedTrackInfo? trackInfo)
    {
        if (!_queue.TryRemoveAt(index, out trackInfo, out var isCurrent))
            return false;

        if (isCurrent)
            skipped = true;

        return true;
    }

    public bool TogglePause()
        => IsPaused = !IsPaused;

    public IQueuedTrackInfo? MoveTrack(int from, int to)
        => _queue.MoveTrack(from, to);

    public void Dispose()
    {
        IsKilled = true;
        OnCompleted = null;
        OnStarted = null;
        OnQueueStopped = null;
        _queue.Clear();
        _songBuffer.Dispose();
        _vc.Dispose();
    }

    private delegate void AdjustVolumeDelegate(Span<byte> data, float volume);
}


text:
using UnityEngine;
using UnityEditor;

namespace AssetBundles
{
    /// <summary>
    /// A postprocessor to call a callback when the AssetBundle an asset is associated with changes.
    /// </summary>
    public class BundleBuildPostprocessor : AssetPostprocessor
    {
        void OnPostprocessAssetbundleNameChanged(string path, string previous, string next)
        {
            Debug.Log("AssetBundles: " + path + " old: " + previous + " new: " + next);
        }
    }
}


text:
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Photo extends Model
{
    protected $fillable = [
    	'file','article_id'
    ];

    public function article()
    {
    	return $this->belongsTo('App\Article');
    }
}


text:
app.controller("TopController", function($scope) {
    $scope.result = "Hoge";

    $scope.action = function (){
      // Javascript Remotingの呼び出し
      Visualforce.remoting.Manager.invokeAction(
        'RemoteActionTestController.helloWorld',
        'World',
        (result, event) => {
          if (event.status) {
            $scope.result = result;
          } else if (event.type === 'exception') {
            $scope.result = event.message + " " + event.where + "";
          } else {
            $scope.result = event.message;
          }
          $scope.$apply();
        },
        {escape: true});
    }

    var data =[
      ['data1', 30, 200, 100, 400, 150, 250],
      ['data2', 50, 20, 10, 40, 15, 25]
    ];
    var chart = new MainChart("#chart");
    chart.show(data);
  })


text:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:p="http://www.springframework.org/schema/p" xmlns:cache="http://www.springframework.org/schema/cache"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-3.2.xsd
           http://www.springframework.org/schema/cache
           http://www.springframework.org/schema/cache/spring-cache-3.2.xsd">

	<context:annotation-config />
	<context:component-scan base-package="com.precognitiveresearch" />
	<cache:annotation-driven />

	<bean
		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="location">
			<value>application.properties</value>
		</property>
	</bean>

	<bean id="top" class="org.restlet.ext.spring.SpringComponent">
		<property name="server">
			<bean class="org.restlet.ext.spring.SpringServer">
				<constructor-arg value="http" />
				<constructor-arg value="${server.port}" />
			</bean>
		</property>
		<property name="defaultTarget" ref="default" />
	</bean>

	<bean id="default" class="org.restlet.ext.spring.SpringRouter">
		<property name="attachments">
			<map>
				<entry key="/elevation/{latitude}/{longitude}">
					<bean class="org.restlet.ext.spring.SpringFinder">
						<lookup-method name="create" bean="elevationResource" />
					</bean>
				</entry>
			</map>
		</property>
	</bean>

	<bean id="elevationResource" class="com.precognitiveresearch.elevation.restlet.ElevationResource"
		scope="prototype" />

	<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
		<property name="cacheManager" ref="ehcache" />
	</bean>

	<bean id="ehcache"
		class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
		p:config-location="ehcache.xml" />

</beans>


text:
package org.elasticsearch.script;

import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;

import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount;
import static org.hamcrest.Matchers.equalTo;

//Use Suite scope so that paths get set correctly
@ElasticsearchIntegrationTest.ClusterScope(scope = ElasticsearchIntegrationTest.Scope.SUITE)
public class OnDiskScriptTests extends ElasticsearchIntegrationTest {

    @Override
    public Settings nodeSettings(int nodeOrdinal) {
        //Set path so ScriptService will pick up the test scripts
        return settingsBuilder().put(super.nodeSettings(nodeOrdinal))
                .put("path.conf", this.getResource("config").getPath()).build();
    }

    @Test
    public void testFieldOnDiskScript()  throws ExecutionException, InterruptedException {

        List<IndexRequestBuilder> builders = new ArrayList<>();
        builders.add(client().prepareIndex("test", "scriptTest", "1").setSource("{\"theField\":\"foo\"}"));
        builders.add(client().prepareIndex("test", "scriptTest", "2").setSource("{\"theField\":\"foo 2\"}"));
        builders.add(client().prepareIndex("test", "scriptTest", "3").setSource("{\"theField\":\"foo 3\"}"));
        builders.add(client().prepareIndex("test", "scriptTest", "4").setSource("{\"theField\":\"foo 4\"}"));
        builders.add(client().prepareIndex("test", "scriptTest", "5").setSource("{\"theField\":\"bar\"}"));

        indexRandom(true, builders);

        String query = "{ \"query\" : { \"match_all\": {}} , \"script_fields\" : { \"test1\" : { \"file\" : \"script1\" }, \"test2\" : { \"file\" : \"script2\", \"params\":{\"factor\":3}  }}, size:1}";
        SearchResponse searchResponse = client().prepareSearch().setSource(query).setIndices("test").setTypes("scriptTest").get();
        assertHitCount(searchResponse, 5);
        assertTrue(searchResponse.getHits().hits().length == 1);
        SearchHit sh = searchResponse.getHits().getAt(0);
        assertThat((Integer)sh.field("test1").getValue(), equalTo(2));
        assertThat((Integer)sh.field("test2").getValue(), equalTo(6));

    }

    @Test
    public void testFieldOnDiskBackwardCompatScript()  throws ExecutionException, InterruptedException {

        List<IndexRequestBuilder> builders = new ArrayList<>();
        builders.add(client().prepareIndex("test", "scriptTest", "1").setSource("{\"theField\":\"foo\"}"));
        builders.add(client().prepareIndex("test", "scriptTest", "2").setSource("{\"theField\":\"foo 2\"}"));
        builders.add(client().prepareIndex("test", "scriptTest", "3").setSource("{\"theField\":\"foo 3\"}"));
        builders.add(client().prepareIndex("test", "scriptTest", "4").setSource("{\"theField\":\"foo 4\"}"));
        builders.add(client().prepareIndex("test", "scriptTest", "5").setSource("{\"theField\":\"bar\"}"));

        indexRandom(true, builders);

        String query = "{ \"query\" : { \"match_all\": {}} , \"script_fields\" : { \"test1\" : { \"script\" : \"script1\" }, \"test2\" : { \"script\" : \"script2\", \"params\":{\"factor\":3}  }}, size:1}";
        SearchResponse searchResponse = client().prepareSearch().setSource(query).setIndices("test").setTypes("scriptTest").get();
        assertHitCount(searchResponse, 5);
        assertThat(searchResponse.getHits().hits().length, equalTo(1));
        SearchHit sh = searchResponse.getHits().getAt(0);
        assertThat((Integer) sh.field("test1").getValue(), equalTo(2));
        assertThat((Integer) sh.field("test2").getValue(), equalTo(6));
    }

    @Test
    public void testOnDiskScriptsSameNameDifferentLang()  throws ExecutionException, InterruptedException {

        List<IndexRequestBuilder> builders = new ArrayList<>();
        builders.add(client().prepareIndex("test", "scriptTest", "1").setSource("{\"theField\":\"foo\"}"));
        builders.add(client().prepareIndex("test", "scriptTest", "2").setSource("{\"theField\":\"foo 2\"}"));
        builders.add(client().prepareIndex("test", "scriptTest", "3").setSource("{\"theField\":\"foo 3\"}"));
        builders.add(client().prepareIndex("test", "scriptTest", "4").setSource("{\"theField\":\"foo 4\"}"));
        builders.add(client().prepareIndex("test", "scriptTest", "5").setSource("{\"theField\":\"bar\"}"));

        indexRandom(true, builders);

        String query = "{ \"query\" : { \"match_all\": {}} , \"script_fields\" : { \"test1\" : { \"script_file\" : \"script1\" }, \"test2\" : { \"script_file\" : \"script1\", \"lang\":\"expression\"  }}, size:1}";
        SearchResponse searchResponse = client().prepareSearch().setSource(query).setIndices("test").setTypes("scriptTest").get();
        assertHitCount(searchResponse, 5);
        assertThat(searchResponse.getHits().hits().length, equalTo(1));
        SearchHit sh = searchResponse.getHits().getAt(0);
        assertThat((Integer)sh.field("test1").getValue(), equalTo(2));
        assertThat((Double)sh.field("test2").getValue(), equalTo(10d));
    }
}