text:
/** \file unixstl/filesystem/glob_sequence.hpp
 *
 * \brief [C++ only] Definition of the unixstl::glob_sequence class
 *   (\ref group__library__filesystem "File System" Library).
 */

#ifndef UNIXSTL_INCL_UNIXSTL_FILESYSTEM_HPP_GLOB_SEQUENCE
#define UNIXSTL_INCL_UNIXSTL_FILESYSTEM_HPP_GLOB_SEQUENCE

#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_GLOB_SEQUENCE_MAJOR     5
# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_GLOB_SEQUENCE_MINOR     2
# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_GLOB_SEQUENCE_REVISION  6
# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_GLOB_SEQUENCE_EDIT      160
#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */

/* /////////////////////////////////////////////////////////////////////////
 * Includes
 */

#ifndef UNIXSTL_INCL_UNIXSTL_H_UNIXSTL
# include <unixstl/unixstl.h>
#endif /* !UNIXSTL_INCL_UNIXSTL_H_UNIXSTL */
#ifndef UNIXSTL_INCL_UNIXSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS
# include <unixstl/filesystem/filesystem_traits.hpp>
#endif /* !UNIXSTL_INCL_UNIXSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS */
#ifndef UNIXSTL_INCL_UNIXSTL_FILESYSTEM_HPP_FILE_PATH_BUFFER
# include <unixstl/filesystem/file_path_buffer.hpp>
#endif /* !UNIXSTL_INCL_UNIXSTL_FILESYSTEM_HPP_FILE_PATH_BUFFER */
#ifndef STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER
# include <stlsoft/util/std/iterator_helper.hpp>
#endif /* !STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER */
#ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_BUFFER
# include <stlsoft/memory/auto_buffer.hpp>
#endif /* !STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_BUFFER */
#ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_ALLOCATOR_SELECTOR
# include <stlsoft/memory/allocator_selector.hpp>
#endif /* !STLSOFT_INCL_STLSOFT_MEMORY_HPP_ALLOCATOR_SELECTOR */
#ifndef STLSOFT_INCL_STLSOFT_SMARTPTR_HPP_SCOPED_HANDLE
# include <stlsoft/smartptr/scoped_handle.hpp>
#endif /* !STLSOFT_INCL_STLSOFT_SMARTPTR_HPP_SCOPED_HANDLE */
#ifndef STLSOFT_INCL_STLSOFT_STRING_HPP_TOKENISER_FUNCTIONS
//# include <stlsoft/string/tokeniser_functions.hpp> // for find_next_token
#endif /* !STLSOFT_INCL_STLSOFT_STRING_HPP_TOKENISER_FUNCTIONS */
#ifndef STLSOFT_INCL_STLSOFT_COLLECTIONS_UTIL_HPP_COLLECTIONS
# include <stlsoft/collections/util/collections.hpp>
#endif /* !STLSOFT_INCL_STLSOFT_COLLECTIONS_UTIL_HPP_COLLECTIONS */
#ifndef STLSOFT_INCL_STLSOFT_UTIL_HPP_STD_SWAP
# include <stlsoft/util/std_swap.hpp>
#endif /* !STLSOFT_INCL_STLSOFT_UTIL_HPP_STD_SWAP */

#ifndef STLSOFT_INCL_SYS_H_TYPES
# define STLSOFT_INCL_SYS_H_TYPES
# include <sys/types.h>
#endif /* !STLSOFT_INCL_SYS_H_TYPES */
#ifndef STLSOFT_INCL_SYS_H_STAT
# define STLSOFT_INCL_SYS_H_STAT
# include <sys/stat.h>                      // for stat()
#endif /* !STLSOFT_INCL_SYS_H_STAT */
#ifndef STLSOFT_INCL_H_ERRNO
# define STLSOFT_INCL_H_ERRNO
# include <errno.h>
#endif /* !STLSOFT_INCL_H_ERRNO */
#ifndef STLSOFT_INCL_H_GLOB
# define STLSOFT_INCL_H_GLOB
# include <glob.h>                           // for glob(), globfree()
#endif /* !STLSOFT_INCL_H_GLOB */

#ifndef STLSOFT_INCL_ALGORITHM
# define STLSOFT_INCL_ALGORITHM
# include <algorithm>                        // for std::sort
#endif /* !STLSOFT_INCL_ALGORITHM */
#ifndef STLSOFT_INCL_EXCEPTION
# define STLSOFT_INCL_EXCEPTION
# include <exception>                        // for std::exception
#endif /* !STLSOFT_INCL_EXCEPTION */
#ifndef STLSOFT_INCL_STDEXCEPT
# define STLSOFT_INCL_STDEXCEPT
# include <stdexcept>                        // for std::runtime_error
#endif /* !STLSOFT_INCL_STDEXCEPT */

#ifdef STLSOFT_UNITTEST
# include <stlsoft/string/simple_string.hpp>
#endif /* STLSOFT_UNITTEST */

/* /////////////////////////////////////////////////////////////////////////
 * Library compatibility
 */

/* User may define UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYDIR to cause the
 * component to trust GLOB_ONLYDIR, if present. If GLOB_ONLYDIR is not
 * detected, UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYDIR is ignored.
 *
 * For any implementations that
 */

#ifndef GLOB_ONLYDIR
# ifdef UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYDIR
#  undef UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYDIR
# endif /* UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYDIR */
#endif /* GLOB_ONLYDIR */

/* User may define UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYREG to cause the
 * component to trust GLOB_ONLYREG, if present. If GLOB_ONLYREG is not
 * detected, UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYREG is ignored.
 */

#ifndef GLOB_ONLYREG
# ifdef UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYREG
#  undef UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYREG
# endif /* UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYREG */
#endif /* GLOB_ONLYREG */

/* User may define UNIXSTL_GLOB_SEQUENCE_TRUST_NODOTSDIRS to cause the
 * component to trust GLOB_NODOTSDIRS, if present. If GLOB_NODOTSDIRS is
 * not detected, UNIXSTL_GLOB_SEQUENCE_TRUST_NODOTSDIRS is ignored.
 */

#ifndef GLOB_NODOTSDIRS
# ifdef UNIXSTL_GLOB_SEQUENCE_TRUST_NODOTSDIRS
#  undef UNIXSTL_GLOB_SEQUENCE_TRUST_NODOTSDIRS
# endif /* UNIXSTL_GLOB_SEQUENCE_TRUST_NODOTSDIRS */
#endif /* GLOB_NODOTSDIRS */

/* User may define UNIXSTL_GLOB_SEQUENCE_DONT_TRUST_MARK do prevent the
 * component from trusting GLOB_MARK; this is meaningless on non-Windows
 * systems, since marking cannot be trusted to filter for files by eliding
 * directories because entries may also be sockets, etc.
 */
#ifndef _WIN32
# ifndef UNIXSTL_GLOB_SEQUENCE_DONT_TRUST_MARK
#  define UNIXSTL_GLOB_SEQUENCE_DONT_TRUST_MARK
# endif /* !UNIXSTL_GLOB_SEQUENCE_DONT_TRUST_MARK */
#endif /* !_WIN32 */

/* /////////////////////////////////////////////////////////////////////////
 * Compiler compatibility
 */

#ifdef STLSOFT_DOCUMENTATION_SKIP_SECTION
# define GLOB_SEQUENCE_CTOR_PRIMARY_FORM
#elif defined(STLSOFT_COMPILER_IS_CUSTOM)
# define GLOB_SEQUENCE_CTOR_PRIMARY_FORM
#elif defined(STLSOFT_COMPILER_IS_UNKNOWN)
# define GLOB_SEQUENCE_CTOR_PRIMARY_FORM
#elif defined(STLSOFT_COMPILER_IS_BORLAND)
# define GLOB_SEQUENCE_CTOR_OLD_FORM
#elif defined(STLSOFT_COMPILER_IS_COMO)
# define GLOB_SEQUENCE_CTOR_PRIMARY_FORM
#elif defined(STLSOFT_COMPILER_IS_DMC)
# define GLOB_SEQUENCE_CTOR_PRIMARY_FORM
#elif defined(STLSOFT_COMPILER_IS_GCC)
# define GLOB_SEQUENCE_CTOR_PRIMARY_FORM
#elif defined(STLSOFT_COMPILER_IS_INTEL)
# define GLOB_SEQUENCE_CTOR_PRIMARY_FORM
#elif defined(STLSOFT_COMPILER_IS_MSVC)
# if _MSC_VER >= 1310
#  define GLOB_SEQUENCE_CTOR_PRIMARY_FORM
# elif _MSC_VER >= 1020
#  define GLOB_SEQUENCE_CTOR_ALT_FORM
# else /* ? compiler */
#  define GLOB_SEQUENCE_CTOR_OLD_FORM
# endif /* compiler */
#elif defined(STLSOFT_COMPILER_IS_MWERKS)
# define GLOB_SEQUENCE_CTOR_ALT_FORM
#elif defined(STLSOFT_COMPILER_IS_VECTORC)
# define GLOB_SEQUENCE_CTOR_ALT_FORM
#elif defined(STLSOFT_COMPILER_IS_WATCOM)
# define GLOB_SEQUENCE_CTOR_OLD_FORM
#else /* ? compiler */
# error Unrecognised compiler
#endif /* compiler */

/* /////////////////////////////////////////////////////////////////////////
 * Namespace
 */

#ifndef _UNIXSTL_NO_NAMESPACE
# if defined(_STLSOFT_NO_NAMESPACE) || \
     defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
/* There is no stlsoft namespace, so must define ::unixstl */
namespace unixstl
{
# else
/* Define stlsoft::unixstl_project */

namespace stlsoft
{

namespace unixstl_project
{

# endif /* _STLSOFT_NO_NAMESPACE */
#endif /* !_UNIXSTL_NO_NAMESPACE */

/* /////////////////////////////////////////////////////////////////////////
 * Classes
 */

#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
/** \brief The exception-type thrown by unixstl::glob_sequence
 *
 * \ingroup group__library__filesystem
 */
class glob_sequence_exception
#if defined(STLSOFT_COMPILER_IS_DMC)
    : public std::exception
#else /* ? compiler */
    : public unixstl_ns_qual_std(exception)
#endif /* compiler */
{
/// \name Types
/// @{
public:
#if defined(STLSOFT_COMPILER_IS_DMC)
    typedef std::exception                  parent_class_type;
#else /* ? compiler */
    typedef unixstl_ns_qual_std(exception)  parent_class_type;
#endif /* compiler */
    typedef glob_sequence_exception         class_type;
/// @}

/// \name Construction
/// @{
public:
    ss_explicit_k glob_sequence_exception(us_int_t globStatus, us_int_t errno_) stlsoft_throw_0()
        : m_globStatus(globStatus)
        , m_errno(errno_)
    {}
/// @}

/// \name Accessors
/// @{
public:
#if defined(STLSOFT_COMPILER_IS_DMC)
    char const* what() const throw()
#else /* ? compiler */
    char const* what() const stlsoft_throw_0()
#endif /* compiler */
    {
        return "glob_sequence failure";
    }

    us_int_t get_globstatus() const stlsoft_throw_0()
    {
        return m_globStatus;
    }
    us_int_t get_errno() const stlsoft_throw_0()
    {
        return m_errno;
    }
/// @}

/// \name Members
/// @{
private:
    us_int_t const  m_globStatus;
    us_int_t const  m_errno;
/// @}

/// \name Not to be implemented
/// @{
private:
    class_type& operator =(class_type const&);
/// @}
};

#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */

/** \brief STL-like readonly sequence based on the results of file-system wildcard matches
 *
 * \ingroup group__library__filesystem
 *
 * This class presents and STL-like readonly sequence interface to allow the
 * iteration over the results of file-system wildcard matches.
 */
class glob_sequence
    : public stlsoft_ns_qual(stl_collection_tag)
{
/// \name Types
/// @{
public:
    /// \brief This class
    typedef glob_sequence                                                   class_type;
    /// \brief The char type
    typedef us_char_a_t                                                     char_type;
    // The traits type
    typedef filesystem_traits<char_type>                                    traits_type;
    /// \brief The value type
    typedef char_type const*                                                value_type;
    /// \brief The non-mutating (const) reference type
    typedef value_type const&                                               const_reference;
    /// \brief The non-mutating (const) pointer type
    typedef value_type const*                                               const_pointer;
    /// \brief The size type
    typedef us_size_t                                                       size_type;
    /// \brief The difference type
    typedef us_ptrdiff_t                                                    difference_type;
    /// \brief The allocator type
    typedef stlsoft_ns_qual(allocator_selector)<value_type>::allocator_type allocator_type;

    /// \brief The non-mutating (const) iterator type
    typedef stlsoft_ns_qual(pointer_iterator)<   value_type const
                                             ,   const_pointer
                                             ,   const_reference
                                             >::type                        const_iterator;

#ifdef STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT
    /// \brief The type of the const (non-mutating) reverse iterator
    typedef stlsoft_ns_qual(reverse_iterator_base)  <   const_iterator
                                                    ,   value_type
                                                    ,   const_reference
                                                    ,   const_pointer
                                                    ,   difference_type
                                                    >                       const_reverse_iterator;
#endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
/// @}

/// \name Member Constants
/// @{
public:
    enum search_flags
    {
            includeDots     =   0x0008  /*!< \brief Requests that dots directories be included in the returned sequence for wildcard patterns, for which \c matchPeriod must also be specified (if GLOB_PERIOD is defined). Always ignored unless \c directories is specified. */
        ,   directories     =   0x0010  /*!< \brief Causes the search to include directories */
        ,   files           =   0x0020  /*!< \brief Causes the search to include files */
        ,   noSort          =   0x0100  /*!< \brief Does not sort entries. Corresponds to GLOB_NOSORT. */
        ,   markDirs        =   0x0200  /*!< \brief Mark directories with a trailing path name separator. Corresponds to GLOB_MARK. */
        ,   absolutePath    =   0x0400  /*!< \brief Return all entries in absolute format. Ignored when a dots directory is specified as the pattern. Note, absolute paths may not always be in canonical form, e.g. '/user/me/.' if specify ('/user/me', '.', absolutePath), in which case the caller is responsible for obtaining canonical form. */

        ,   breakOnError    =   0x0800  /*!< \brief Causes processing to stop on the first filesystem error. Corresponds to GLOB_ERR. */
        ,   noEscape        =   0x1000  /*!< \brief Treats backslashes literally. Corresponds to GLOB_NOESCAPE. */

#ifdef GLOB_PERIOD
        ,   matchPeriod     =   0x2000  /*!< \brief Leading '.' can be matched by metacharacters. Corresponds to GLOB_PERIOD. */
#endif /* GLOB_PERIOD */
#ifdef GLOB_BRACE
        ,   bracePatterns   =   0x4000  /*!< \brief Allow "{*.cpp;makefile*}" style multi-part patterns. Corresponds to GLOB_BRACE. */
#endif /* GLOB_BRACE */
#ifdef GLOB_TILDE
        ,   expandTilde     =   0x8000  /*!< \brief Expand ~ and ~<user> directories. Corresponds to GLOB_TILDE. */
#endif /* GLOB_TILDE */
    };
/// @}

/// \name Construction
/// @{
public:
#if defined(GLOB_SEQUENCE_CTOR_PRIMARY_FORM)
    /// \brief Constructs a sequence according to the given criteria
    ///
    /// The constructor initialises a glob_sequence instance on the given
    /// pattern with the given flags.
    ///
    /// \param pattern The pattern against which to match the file-system contents
    /// \param flags Flags to alter the behaviour of the search
    ///
    /// \note If exceptions are supported, then this will throw a glob_sequence_exception
    /// on failure of any underlying functions
    template<ss_typename_param_k S>
    ss_explicit_k glob_sequence(S const& pattern, us_int_t flags = files | directories)
        : m_flags(validate_flags_(flags))
        , m_buffer(1)
    {
        m_cItems = init_glob_(NULL, stlsoft_ns_qual(c_str_ptr)(pattern));

        UNIXSTL_ASSERT(is_valid());
    }

# ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
    template<ss_typename_param_k S>
    glob_sequence(S const& pattern, search_flags flag)
        : m_flags(validate_flags_(flag))
        , m_buffer(1)
    {
        m_cItems = init_glob_(NULL, stlsoft_ns_qual(c_str_ptr)(pattern));

        UNIXSTL_ASSERT(is_valid());
    }
# endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */

    /// \brief Constructs a sequence according to the given criteria
    ///
    /// The constructor initialises a glob_sequence instance on the given
    /// pattern with the given flags.
    ///
    /// \param directory The directory in which the pattern is located
    /// \param pattern The pattern against which to match the file-system contents
    /// \param flags Flags to alter the behaviour of the search
    ///
    /// \note If exceptions are supported, then this will throw a glob_sequence_exception
    /// on failure of any underlying functions
    template<   ss_typename_param_k S1
            ,   ss_typename_param_k S2
            >
    glob_sequence(S1 const& directory, S2 const& pattern, us_int_t flags = files | directories)
        : m_flags(validate_flags_(flags))
        , m_buffer(1)
    {
        m_cItems = init_glob_(stlsoft_ns_qual(c_str_ptr)(directory), stlsoft_ns_qual(c_str_ptr)(pattern));

        UNIXSTL_ASSERT(is_valid());
    }

# ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
    template<   ss_typename_param_k S1
            ,   ss_typename_param_k S2
            >
    glob_sequence(S1 const& directory, S2 const& pattern, search_flags flag)
        : m_flags(validate_flags_(flag))
        , m_buffer(1)
    {
        m_cItems = init_glob_(stlsoft_ns_qual(c_str_ptr)(directory), stlsoft_ns_qual(c_str_ptr)(pattern));

        UNIXSTL_ASSERT(is_valid());
    }
# endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */

#elif defined(GLOB_SEQUENCE_CTOR_ALT_FORM)

    template<ss_typename_param_k S>
    ss_explicit_k glob_sequence(S const& pattern)
        : m_flags(validate_flags_(files | directories))
        , m_buffer(1)
    {
        m_cItems = init_glob_(NULL, stlsoft_ns_qual(c_str_ptr)(pattern));

        UNIXSTL_ASSERT(is_valid());
    }

    template<ss_typename_param_k S>
    glob_sequence(S const& pattern, us_int_t flags)
        : m_flags(validate_flags_(flags))
        , m_buffer(1)
    {
        m_cItems = init_glob_(NULL, stlsoft_ns_qual(c_str_ptr)(pattern));

        UNIXSTL_ASSERT(is_valid());
    }

    glob_sequence(char_type const* directory, char_type const* pattern, us_int_t flags = files | directories);

    template<ss_typename_param_k S>
    glob_sequence(S const& directory, char const* pattern, us_int_t flags = files | directories)
        : m_flags(validate_flags_(flags))
        , m_buffer(1)
    {
        m_cItems = init_glob_(stlsoft_ns_qual(c_str_ptr)(directory), stlsoft_ns_qual(c_str_ptr)(pattern));

        UNIXSTL_ASSERT(is_valid());
    }

    template<ss_typename_param_k S>
    glob_sequence(S const& directory, S const& pattern, us_int_t flags = files | directories)
        : m_flags(validate_flags_(flags))
        , m_buffer(1)
    {
        m_cItems = init_glob_(stlsoft_ns_qual(c_str_ptr)(directory), stlsoft_ns_qual(c_str_ptr)(pattern));

        UNIXSTL_ASSERT(is_valid());
    }

#elif defined(GLOB_SEQUENCE_CTOR_OLD_FORM)

    ss_explicit_k glob_sequence(char_type const* pattern, us_int_t flags = files | directories);

    glob_sequence(char_type const* directory, char_type const* pattern, us_int_t flags = files | directories);

#else /* ? constructor form */
# error Constructor form not recognised
#endif /* constructor form */

#if 0
    /// \brief Constructs a sequence according to the given criteria
    ///
    /// The constructor initialises a glob_sequence instance on the given
    /// pattern with the given flags.
    ///
    /// \param directory The directory in which the pattern is located
    /// \param pattern The pattern against which to match the file-system contents
    /// \param flags Flags to alter the behaviour of the search
    ///
    /// \note If exceptions are supported, then this will throw a glob_sequence_exception
    /// on failure of any underlying functions
    glob_sequence(char_type const* directory, char_type const* pattern, char_type delim, us_int_t flags = files | directories);
#endif /* 0 */

    /// \brief Releases any acquired resources
    ~glob_sequence() stlsoft_throw_0();
/// @}

/// \name Attributes
/// @{
public:
    /// \brief Returns the number of elements in the sequence
    us_size_t size() const;

    /// \brief Indicates whether the search sequence is empty
    us_bool_t empty() const;
/// @}

/// \name Element Access
/// @{
public:
    /// \brief Returns the value corresponding to the given index
    ///
    /// \note In debug-mode a runtime assert is applied to enforce that the index is valid. There is <b>no</b> release-time checking on the index validity!
    const_reference operator [](size_type index) const;
/// @}

/// \name Iteration
/// @{
public:
    /// \brief Begins the iteration
    ///
    /// \return An iterator representing the start of the sequence
    const_iterator  begin() const;
    /// \brief Ends the iteration
    ///
    /// \return An iterator representing the end of the sequence
    const_iterator  end() const;

#ifdef STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT
    /// \brief Begins the reverse iteration
    ///
    /// \return An iterator representing the start of the reverse sequence
    const_reverse_iterator  rbegin() const;
    /// \brief Ends the reverse iteration
    ///
    /// \return An iterator representing the end of the reverse sequence
    const_reverse_iterator  rend() const;
#endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
/// @}

/// \name Implementation
/// @{
private:
    // Tests the class invariant
    us_bool_t           is_valid() const;

    // Validates the flags, and sets up defaults
    static us_int_t     validate_flags_(us_int_t flags);

    // Returns true if pch is a path separator "/" (or "\\"); false otherwise
    static us_bool_t    is_path_separator_(char_type ch);

    // Returns true if pch == "" or "/" (or "\\"); false otherwise
    static us_bool_t    is_end_of_path_elements_(char_type const* pch, difference_type index);

    // Returns true if s points to a path that is a dots directory; false otherwise
    static us_bool_t    is_dots_maybe_slashed_(char_type const* s, us_bool_t* bTwoDots);

    // Calls glob() and process the results
    //
    // init_glob_()   - handles any directory and/or pattern (where the pattern may contain rel/abs dir)
    // init_glob_1_() - splits combined path into directory+pattern (which are passed to init_glob_2_())
    // init_glob_2_() - handles receives properly split directory+pattern (and does test in order to call init_glob_3_())
    // init_glob_3_() - handles full pattern, with bool indicating whether pattern contains wildcard at leaf
    us_size_t           init_glob_(char_type const* directory, char_type const* pattern);
    us_size_t           init_glob_1_(size_type bufferSize, char_type* combinedPath);
    us_size_t           init_glob_2_(char_type const* patternDir, char_type const* pattern0);
    us_size_t           init_glob_3_(char_type const* pattern, bool isPattern0Wild);

/// @}

/// \name Members
/// @{
private:
    typedef stlsoft_ns_qual(auto_buffer_old)<   char_type const*
                                            ,   allocator_type
                                            ,   128
                                            >       buffer_type_;

    us_int_t const      m_flags;
    char_type const**   m_base;
    us_size_t           m_cItems;
    buffer_type_        m_buffer;
    glob_t              m_glob;
/// @}

/// \name Not to be implemented
/// @{
private:
    glob_sequence(class_type const&);
    class_type const& operator =(class_type const&);
/// @}
};

////////////////////////////////////////////////////////////////////////////
// Unit-testing

#ifdef STLSOFT_UNITTEST
# include "./unittest/glob_sequence_unittest_.h"
#endif /* STLSOFT_UNITTEST */

/* /////////////////////////////////////////////////////////////////////////
 * Implementation
 */

#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION

#if defined(GLOB_SEQUENCE_CTOR_OLD_FORM)
inline /* ss_explicit_k */ glob_sequence::glob_sequence(glob_sequence::char_type const* pattern, us_int_t flags)
    : m_flags(validate_flags_(flags))
    , m_buffer(1)
{
    m_cItems = init_glob_(NULL, pattern);

    UNIXSTL_ASSERT(is_valid());
}
#endif /* GLOB_SEQUENCE_CTOR_OLD_FORM */

#if defined(GLOB_SEQUENCE_CTOR_OLD_FORM) || \
    defined(GLOB_SEQUENCE_CTOR_ALT_FORM)
inline glob_sequence::glob_sequence(glob_sequence::char_type const* directory, glob_sequence::char_type const* pattern, us_int_t flags)
    : m_flags(validate_flags_(flags))
    , m_buffer(1)
{
    m_cItems = init_glob_(directory, pattern);

    UNIXSTL_ASSERT(is_valid());
}
#endif /* GLOB_SEQUENCE_CTOR_OLD_FORM || GLOB_SEQUENCE_CTOR_ALT_FORM */

#if 0
template<   ss_typename_param_k S1
        ,   ss_typename_param_k S2
        >
inline glob_sequence::glob_sequence(S1 const& directory, S2 const& pattern, us_int_t flags)
    : m_flags(validate_flags_(flags))
    , m_buffer(1)
{
    m_cItems = init_glob_(stlsoft_ns_qual(c_str_ptr)(directory), stlsoft_ns_qual(c_str_ptr)(pattern));

    UNIXSTL_ASSERT(is_valid());
}
#endif /* 0 */

#if 0
inline glob_sequence::glob_sequence(char_type const* directory, char_type const* pattern, char_type delim, us_int_t flags)
    : m_flags(validate_flags_(flags))
    , m_buffer(1)
{

    m_cItems = init_glob_(directory, pattern);

    UNIXSTL_ASSERT(is_valid());
}
#endif /* 0 */

inline glob_sequence::~glob_sequence() stlsoft_throw_0()
{
    UNIXSTL_ASSERT(is_valid());

    if(NULL != m_base)
    {
        ::globfree(&m_glob);
    }
}

inline us_size_t glob_sequence::size() const
{
    return m_cItems;
}

inline us_bool_t glob_sequence::empty() const
{
    return 0 == size();
}

inline glob_sequence::const_reference glob_sequence::operator [](glob_sequence::size_type index) const
{
    UNIXSTL_MESSAGE_ASSERT("index access out of range in glob_sequence", index < 1 + size());   // Has to be +1, since legitimate to take address of one-past-the-end

    return m_base[index];
}

inline glob_sequence::const_iterator glob_sequence::begin() const
{
    return m_base;
}

inline glob_sequence::const_iterator glob_sequence::end() const
{
    return m_base + m_cItems;
}

#ifdef STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT
inline glob_sequence::const_reverse_iterator glob_sequence::rbegin() const
{
    return const_reverse_iterator(end());
}

inline glob_sequence::const_reverse_iterator glob_sequence::rend() const
{
    return const_reverse_iterator(begin());
}
#endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */

inline us_bool_t glob_sequence::is_valid() const
{
    if((0 != m_cItems) && (NULL == m_base))
    {
        return false;
    }

    return true;
}

inline /* static */ us_int_t glob_sequence::validate_flags_(us_int_t flags)
{
    const us_int_t  validFlags  =   0
                                |   includeDots
                                |   directories
                                |   files
                                |   noSort
                                |   markDirs
                                |   absolutePath
                                |   breakOnError
                                |   noEscape
#ifdef GLOB_PERIOD
                                |   matchPeriod
#endif /* GLOB_PERIOD */
#ifdef GLOB_BRACE
                                |   bracePatterns
#endif /* GLOB_BRACE */
#ifdef GLOB_TILDE
                                |   expandTilde
#endif /* GLOB_TILDE */
                                |   0;

    UNIXSTL_MESSAGE_ASSERT("Specification of unrecognised/unsupported flags", flags == (flags & validFlags));
    STLSOFT_SUPPRESS_UNUSED(validFlags);

    if(0 == (flags & (directories | files)))
    {
        flags |= (directories | files);
    }

#ifndef UNIXSTL_GLOB_SEQUENCE_DONT_TRUST_MARK
    // If we're not searching for directories, then we can optimise the
    // subsequent filtering by asking for the dots directories (so we
    // skip that filtering) and asking for directories to be marked (so
    // we can detect the mark rather than making a system call (stat())
    if(0 == (flags & directories))
    {
        // It's more efficient to not bother doing a separate dots check if all
        // directories are being elided.
        flags |= includeDots;

        // Since we're not going to be returning directories to the caller, and
        // it's more efficient to believe the glob() directory marking rather
        // than calling stat, we add the markDirs flag here.
        flags |= markDirs;
    }
#endif /* !UNIXSTL_GLOB_SEQUENCE_DONT_TRUST_MARK */

    return flags;
}

inline /* static */ us_bool_t glob_sequence::is_path_separator_(glob_sequence::char_type ch)
{
    return  ch == '/'
#if defined(_UNIXSTL_COMPILER_IS_UNKNOWN) && \
    !defined(_UNIXSTL_GLOB_SEQUENCE_NO_BACK_SLASH_TERMINATOR)
            || ch == '\\' /* Allow for testing on Win32 systems */
#endif /* _UNIXSTL_COMPILER_IS_UNKNOWN && !_UNIXSTL_GLOB_SEQUENCE_NO_BACK_SLASH_TERMINATOR */
            ;
}

inline /* static */ us_bool_t glob_sequence::is_end_of_path_elements_(glob_sequence::char_type const* pch, glob_sequence::difference_type index)
{
    return  pch[index] == '\0' ||
            (   pch[index + 1] == '\0' &&
                is_path_separator_(pch[index]));
}

inline /* static */ us_bool_t glob_sequence::is_dots_maybe_slashed_(glob_sequence::char_type const* s, us_bool_t* bTwoDots)
{
    UNIXSTL_ASSERT(NULL != s);
    UNIXSTL_ASSERT(NULL != bTwoDots);

    // This must match all patterns like the following:
    //
    // "."          l=1, s[0] = .
    // ".."         l=2, s[0] = ., s[1] = .
    // "./"         l=2, s[0] = ., s[1] = sep
    // "../"        l=3, s[0] = ., s[1] = ., s[2] = sep
    // "abc/."
    // "abc/.."
    // "abc/./"
    // "abc/../"

    const us_size_t len             =   traits_type::str_len(s);
    us_size_t       lastNameChar    =   len -1;

    UNIXSTL_ASSERT(len > 0);

    if(is_path_separator_(s[lastNameChar]))
    {
        --lastNameChar;
    }
    if('.' == s[lastNameChar])
    {
        if(0 == lastNameChar)
        {
            return true;
        }
        else
        {
            --lastNameChar;

            if( 0 == lastNameChar ||
                is_path_separator_(s[lastNameChar]))
            {
                *bTwoDots = false;
                return true;
            }
            else if( 0 < lastNameChar &&
                    '.' == s[lastNameChar])
            {
                --lastNameChar;

                if( 0 == lastNameChar ||
                    is_path_separator_(s[lastNameChar]))
                {
                    *bTwoDots = true;
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }
    }

    return false;
}

inline
us_size_t
glob_sequence::init_glob_(
    glob_sequence::char_type const* directory
,   glob_sequence::char_type const* pattern
)
{
    UNIXSTL_MESSAGE_ASSERT("Null pattern given to glob_sequence", NULL != pattern);

    char_type const* lastSlash = traits_type::find_last_path_name_separator(pattern);

    if(NULL == lastSlash)
    {
        // already properly separated

        return init_glob_2_(directory, pattern);
    }
    else
    {
        if(traits_type::is_path_rooted(pattern))
        {
            directory = NULL;
        }

        basic_file_path_buffer<char_type>   scratch_;   // Scratch buffer for directory + pattern

        size_type                           dirLen  =   (NULL == directory) ? 0u : traits_type::str_len(directory);
        size_type                           patLen  =   traits_type::str_len(pattern);

        if(0 != dirLen)
        {
            traits_type::char_copy(&scratch_[0] + 0, directory, dirLen);
            scratch_[dirLen] = '\0';
            dirLen += traits_type::str_len(traits_type::ensure_dir_end(&scratch_[0] + (dirLen - 1))) - 1;
        }

        traits_type::char_copy(&scratch_[0] + dirLen, pattern, patLen);
        scratch_[dirLen + patLen] = '\0';

        return init_glob_1_(scratch_.size(), scratch_.data());
    }
}

inline
us_size_t
glob_sequence::init_glob_1_(
    size_type   /* bufferSize */
,   char_type*  combinedPath
)
{
    char_type const* const lastSlash = traits_type::find_last_path_name_separator(combinedPath);

    UNIXSTL_ASSERT(NULL != lastSlash);

    combinedPath[lastSlash - combinedPath] = '\0';

    char_type const*    directory   =   combinedPath;
    char_type const*    pattern     =   lastSlash + 1;

    return init_glob_2_(directory, pattern);
}

inline
us_size_t
glob_sequence::init_glob_2_(
    char_type const*    directory
,   char_type const*    pattern0
)
{
    // Preconditions:
    //
    // - pattern must not be NULL
    // - pattern must not contain a path-name separator
    UNIXSTL_ASSERT(NULL != pattern0);
    UNIXSTL_ASSERT(NULL == traits_type::str_chr(pattern0, '/'));
#ifdef _WIN32
    UNIXSTL_ASSERT(NULL == traits_type::str_chr(pattern0, '\\'));
#endif /* _WIN32 */

    static char_type const s_wildChars[] = { '?', '*', '\0' };

    us_bool_t const isPattern0Wild = (NULL != traits_type::str_pbrk(pattern0, s_wildChars));

    if( NULL != directory &&
        '\0' != directory[0])
    {
        if( absolutePath == (m_flags & absolutePath) &&
            !traits_type::is_path_rooted(directory))
        {
            us_bool_t const isPatternDirWild = (NULL != traits_type::str_pbrk(directory, s_wildChars));

            if(isPatternDirWild)
            {
                errno = EINVAL;

                m_base = NULL;

                return 0;
            }
            else
            {
                basic_file_path_buffer<char_type> scratch2_; // Scratch buffer for absolute path

                size_type absLen = traits_type::get_full_path_name(directory, scratch2_.size(), &scratch2_[0]);

                if(0 == absLen)
                {
                    m_base = NULL;

                    return 0;
                }
                else
                {
                    return init_glob_2_(scratch2_.data(), pattern0);
                }
            }
        }
        else
        {
            basic_file_path_buffer<char_type> scratch_;   // Scratch buffer for directory / pattern

#ifndef STLSOFT_CF_EXCEPTION_SUPPORT
            if(0 == scratch_.size())
            {
                m_base = NULL;

                return 0;
            }
            else
#endif /* !STLSOFT_CF_EXCEPTION_SUPPORT */
            {
                size_type dirLen = traits_type::str_len(directory);
                size_type patLen = traits_type::str_len(pattern0);

                traits_type::char_copy(&scratch_[0] + 0, directory, dirLen);
                scratch_[dirLen] = '\0';

                dirLen += traits_type::str_len(traits_type::ensure_dir_end(&scratch_[0] + (dirLen - 1))) - 1;

                traits_type::char_copy(&scratch_[0] + dirLen, pattern0, patLen);
                scratch_[dirLen + patLen] = '\0';

                return init_glob_3_(scratch_.c_str(), isPattern0Wild);
            }
        }
    }
    else
    {
        return init_glob_3_(pattern0, isPattern0Wild);
    }
}

inline
us_size_t
glob_sequence::init_glob_3_(
    char_type const*    pattern
,   bool                isPattern0Wild
)
{
    us_int_t glob_flags = 0;

    if(m_flags & noSort)
    {
        // Don't bother sorting
        glob_flags |= GLOB_NOSORT;
    }

    if(m_flags & markDirs)
    {
        // Ask for trailing slashes on directories
        glob_flags |= GLOB_MARK;
    }

#ifdef UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYDIR // If this is not defined, we rely on stat
    if(directories == (m_flags & (directories | files)))
    {
        // Ask for only directories
        glob_flags |= GLOB_ONLYDIR;
    }
#endif /* UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYDIR */

#ifdef UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYREG // If this is not defined, we rely on stat
    if(files == (m_flags & (directories | files)))
    {
        // Ask for only files
        glob_flags |= GLOB_ONLYREG;
    }
#endif /* UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYREG */

#ifdef GLOB_ERR
    if(m_flags & breakOnError)
    {
        glob_flags |= GLOB_ERR;
    }
#endif /* GLOB_ERR */

#ifdef GLOB_NOESCAPE
    if(m_flags & noEscape)
    {
        glob_flags |= GLOB_NOESCAPE;
    }
#endif /* GLOB_NOESCAPE */

#ifdef GLOB_PERIOD
    if(m_flags & matchPeriod)
    {
        glob_flags |= GLOB_PERIOD;
    }
#endif /* GLOB_PERIOD */

#ifdef GLOB_BRACE
    if(m_flags & bracePatterns)
    {
        glob_flags |= GLOB_BRACE;
    }
#endif /* GLOB_BRACE */

#ifdef GLOB_TILDE
    if(m_flags & expandTilde)
    {
        glob_flags |= GLOB_TILDE;
    }
#endif /* GLOB_TILDE */

#ifdef UNIXSTL_GLOB_SEQUENCE_TRUST_NODOTSDIRS
    if(0 == (m_flags & includeDots))
    {
        glob_flags |= GLOB_NODOTSDIRS;
    }
#endif /* UNIXSTL_GLOB_SEQUENCE_TRUST_NODOTSDIRS */

    int gr = ::glob(pattern, glob_flags, NULL, &m_glob);

    if(0 != gr)
    {
#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
# ifdef GLOB_NOMATCH
        // When GLOB_NOMATCH is not defined, we can reasonably infer that
        // there is no replacement value, so throwing on a non-zero
        // return from glob() is appropriate
        if(GLOB_NOMATCH != gr)
# endif /* GLOB_NOMATCH */
        {
            STLSOFT_THROW_X(glob_sequence_exception(gr, 0));
        }
#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */

        m_base = NULL;

        return 0;
    }
    else
    {
        // Sink the glob_t instance into a local scoped_handle, to invoke
        // ::globfree() automatically if we encounter any problems during
        // the processing. At the end we'll call detach(), to "give it"
        // to the glob_sequence instance.

        stlsoft_ns_qual(scoped_handle)<glob_t*> cleanup(&m_glob, ::globfree);

        char_type** base    =   m_glob.gl_pathv;
        us_size_t   cItems  =   static_cast<us_size_t>(m_glob.gl_pathc);

        // This section performs a COW on the entry pointers, into
        // the m_buffer member, if any of the following hold:
        //
        // 1. we're eliding dots
        // 2. we want directories only, and so will need to
        //     remove files, AND we do not trust GLOB_ONLYDIR
        // 3. we want files only, and so will need
        //     to remove directories
        //

        bool const elidingDots = isPattern0Wild && (0 == (m_flags & includeDots));

        if( elidingDots ||                                      // 1
#ifndef UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYDIR
            directories == (m_flags & (directories | files)) || // 2
#endif /* !UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYDIR */
            files == (m_flags & (directories | files)))         // 3
        {
            if(!m_buffer.resize(cItems))
            {
#ifndef STLSOFT_CF_EXCEPTION_SUPPORT
                m_base = NULL;

                return 0;
#endif /* !STLSOFT_CF_EXCEPTION_SUPPORT */
            }

            UNIXSTL_ASSERT(m_buffer.size() == cItems);

            base = static_cast<char_type**>(memcpy(&m_buffer[0], base, m_buffer.size() * sizeof(char_type*)));
        }

        // This section elides dots directories.
        if(elidingDots)
        {
#ifndef UNIXSTL_GLOB_SEQUENCE_TRUST_NODOTSDIRS
            // Now remove the dots. If located at the start of
            // the gl buffer, then simply increment m_base to
            // be above that. If not then rearrange the base
            // two pointers such that they are there.

            us_bool_t           bFoundDot1   =   false;
            us_bool_t           bFoundDot2   =   false;
            char_type**         begin        =   base;
            char_type** const   end          =   begin + cItems;

            for(; begin != end; ++begin)
            {
                us_bool_t bTwoDots = false;

                if(is_dots_maybe_slashed_(*begin, &bTwoDots))
                {
                    // Swap with whatever is at base[0]
                    if(begin != base)
                    {
                        stlsoft_ns_qual(std_swap)(*begin, *base);
                    }
                    ++base;
                    --cItems;

                     // We're only going to get one "." and one ".."
                    (bTwoDots ? bFoundDot2 : bFoundDot1) = true;

                    if( bFoundDot1 &&
                        bFoundDot2)
                    {
                        break;
                    }
                }
            }
#endif /* !UNIXSTL_GLOB_SEQUENCE_TRUST_NODOTSDIRS */
        }

        // This section performs the main filtering section, with
        // conditional shortcuts for if any of the following hold:
        //
        // 1. Looking for files only
        //  - and GLOB_ONLYREG is supported
        // 2. Looking for directories only
        //  - and GLOB_ONLYDIR is supported
        // 3. Looking for anything
        //

#ifdef UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYREG
        // 1. Looking for files only
        if(files == (m_flags & (directories | files)))
        {
            ; // Nothing to do
        }
        else
#endif /* UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYREG */
#ifdef UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYDIR
        // 2. Looking for directories only
        if(directories == (m_flags & (directories | files)))
        {
            ; // Nothing to do
        }
        else
#endif /* UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYDIR */
        // 3. Looking for anything
        if(0 == (m_flags & (directories | files)))
        {
            // NOTE: this conditional branch is a future-compatibility
            // feature, for when sockets and links are supported

            ; // Nothing to do
        }
        else
        {
            // Must filter based on type ascertained by call to stat()
            // (except if we trust MARKDIR

            char_type**         begin   =   base;
            char_type** const   end     =   begin + cItems;

            for(; begin != end; ++begin)
            {
                // Now need to process the file, by using stat
                traits_type::stat_data_type st;
                char_type const* const      entry = *begin;

                // Shortcut relying on mark, based on the assumption that
                // a strlen()-equiv. operation is faster than a call to
                // stat().
# ifndef UNIXSTL_GLOB_SEQUENCE_DONT_TRUST_MARK
                if(markDirs == (m_flags & markDirs))
                {
                    bool const isDirectory = traits_type::has_dir_end(entry);

                    if( isDirectory &&
                        directories == (m_flags & (directories)))
                    {
                        // It is a directory, and we want directories, so
                        // don't elide (by continue-ing)
                        continue;
                    }
                    else
                    if( !isDirectory &&
                        files == (m_flags & (directories | files)))
                    {
                        // It is not a directory, and we want files,
                        // so don't elide (by continue-ing)
                        continue;
                    }
                }
                else
# endif /* !UNIXSTL_GLOB_SEQUENCE_DONT_TRUST_MARK */
                if(!traits_type::stat(entry, &st))
                {
                    // We could throw an exception here, but it might just be
                    // the case that a file has been deleted subsequent to its
                    // having been included in the glob list. As such, it makes
                    // more sense to just kick it from the list

// TODO: Consider adding a callback function here, which can elect to throw, if the application requires that. Also, consider a throwOnStat flag
                }
                else
                { // stat() succeeded

                    if( files == (m_flags & (files)) &&
                        traits_type::is_file(&st))
                    {
                        continue; // A file, so accept it
                    }
                    else
                    if( directories == (m_flags & (directories)) &&
                        traits_type::is_directory(&st))
                    {
                        continue; // A directory, so accept it
                    }
                    else
                    {
                    }
                }

                // This section elides the entry from the list
                //
                // Note that there is no test here to determine whether or not
                // begin == base. It is assumed that most cases of file elision
                // will involve several files - how many directories have just
                // one file in them? - so the test would actually be a
                // pessimisation

                // Swap with whatever is at base[0]
                stlsoft_ns_qual(std_swap)(*begin, *base);
                ++base;
                --cItems;
            }
        }

        // Ensure we've not corrupted the sort order
        if( 0 == (m_flags & noSort) &&
            cItems != static_cast<us_size_t>(m_glob.gl_pathc))
        {
            unixstl_ns_qual_std(sort)(base, base + cItems);
        }

        // Set m_base and m_cItems to the correct values, with
        // or without dots. m_base is cast here to remove the
        // need for const-casting throughout the rest of the
        // class
        m_base = const_cast<char_type const**>(base);

        // Everything has succeeded, so give ownership over to the
        // glob_sequence instance
        cleanup.detach();

        return cItems;
    }
}

#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */

/* ////////////////////////////////////////////////////////////////////// */

#ifndef _UNIXSTL_NO_NAMESPACE
# if defined(_STLSOFT_NO_NAMESPACE) || \
     defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
} // namespace unixstl
# else
} // namespace unixstl_project
} // namespace stlsoft
# endif /* _STLSOFT_NO_NAMESPACE */
#endif /* !_UNIXSTL_NO_NAMESPACE */

/* ////////////////////////////////////////////////////////////////////// */

#endif /* !UNIXSTL_INCL_UNIXSTL_FILESYSTEM_HPP_GLOB_SEQUENCE */

/* ///////////////////////////// end of file //////////////////////////// */


text:
let svgns = "http://www.w3.org/2000/svg";

var sensitivity, iWithS;
var iGraph, sGraph, iwsGraph;
var submarine;
var activeThruster = 0;
var editor;

var data;

let names = [
    "Horizontal Left",
    "Vertical Left",
    "Vertical Center",
    "Vertical Right",
    "Horizontal Right",
];
let assignedJoystick = [
    0,
    1,
    1,
    1,
    0
];

function go() {
    document.onkeydown = handleKey;
    createCharts();

    // NOTE: need to call this last since it is async
    Data.getData(processNewData);
}

function processNewData(error, newData) {
    if (newData.version !== 1) {
        console.error(`Unsupported data version number '${newData.version}'`);
        return;
    }

    data = newData;

    // create sensitivity data provider
    sensitivity = new Sensitivity(data.sensitivity.strength, data.sensitivity.power);

    // convert thruster data providers
    data.thrusters = data.thrusters.map(values => {
        let interpolator = new Interpolator();

        for (var i = 0; i < values.length; i += 2) {
            interpolator.addIndexValue(values[i], values[i+1]);
        }

        return interpolator;
    });

    // draw charts
    updateCharts();

    // update range elements
    document.getElementById("t").value = data.sensitivity.strength;
    document.getElementById("tLabel").innerHTML = data.sensitivity.strength;
    document.getElementById("power").value = data.sensitivity.power;
    document.getElementById("powerLabel").innerHTML = data.sensitivity.power;
}

function loadSettings() {
    let name = document.getElementById("filename").value;

    Data.getNamedData(name, processNewData);
}

function saveSettings() {
    var filename = document.getElementById("filename").value;

    Data.sendData({
        version: 1,
        name: filename,
        sensitivity: {
            strength: sensitivity.t - 0,
            power: sensitivity.power - 0
        },
        thrusters: [
            data.thrusters[0].to_array(),
            data.thrusters[1].to_array(),
            data.thrusters[2].to_array(),
            data.thrusters[3].to_array(),
            data.thrusters[4].to_array()
        ]
    }, function(error) {
        if (error) {
            console.error(error);
        }
    })
}

function createCharts() {
    let margin        = 50;
    let padding       = 15;
    let width         = 600;
    let height        = 300;
    let joyStickSize  = 22;
    let submarineSize = Math.min(width, height) - joyStickSize;

    let chart = document.getElementById("chart");
    chart.setAttributeNS(null, "width", margin + submarineSize + padding + width + + joyStickSize + margin);
    chart.setAttributeNS(null, "height", margin + height + padding + height + margin);

    // top-left
    submarine = new Submarine(
        margin,
        margin,
        submarineSize,
        submarineSize
    );
    submarine.onchange = updateActiveThruster;

    // top-right
    iGraph = new Graph(
        margin + submarineSize + 2 * padding,   // x
        margin + 0 * (height + padding),        // y
        width,                                  // width
        height,                                 // height
        0, 360,                                 // xMin, xMax
        -1, 1,                                  // yMin, yMax
        4,                                      // xMajorSubdivisions
        20,                                     // yMajorSubdivisions
        360,                                    // xMinorSubdivisions
        10                                      // yMinorSubdivisions
    );

    // bottom-left
    sGraph = new Graph(
        margin,
        margin + 1 * (height + padding),
        submarineSize,
        submarineSize,
        -1, 1,
        -1, 1,
        4,
        4,
        360,
        10
    );
    sGraph.showJoysticks = false;

    // bottom-right
    iwsGraph = new Graph(
        margin + submarineSize + 2 * padding,
        margin + 1 * (height + padding),
        width,
        height,
        0, 360,
        -1, 1,
        4,
        20,
        360,
        10
    );

    // interpolator editor
    editor = new InterpolatorEditor(
        iGraph.xMin,
        iGraph.xMax,
        iGraph.yMin,
        iGraph.yMax,
        iGraph.graphBoundingBox
    );
    editor.onchange = () => {
        iGraph.drawData();
        iwsGraph.drawData();
    }

    // initial render
    submarine.attach(chart);
    iGraph.attach(chart);
    sGraph.attach(chart);
    iwsGraph.attach(chart);
    editor.attach(iGraph.rootNode);
}

function handleKey(e) {
    let lastIndex = data.thrusters.length - 1;

    switch (e.keyCode) {
        case 38:
            // up arrow
            break;

        case 40:
            // down arrow
            break;

        case 37:
            // left arrow
            if (activeThruster > 0) {
                activeThruster--;
            }
            else {
                activeThruster = lastIndex;
            }
            updateCharts();
            break;

        case 39:
            // right arrow
            if (activeThruster < lastIndex) {
                activeThruster++;
            }
            else {
                activeThruster = 0;
            }
            updateCharts();
            break;
    }
}

function updateCharts() {
    // create thruster with sensitivity provider
    iWithS = new InterpolatorWithSensitivity(data.thrusters[activeThruster], sensitivity);

    // apply data providers to graphs
    iGraph.dataProvider = data.thrusters[activeThruster];
    sGraph.dataProvider = sensitivity;
    iwsGraph.dataProvider = iWithS;

    // update editor provider
    editor.interpolator = iGraph.dataProvider;

    // update active joysticks
    var activeJoystick = assignedJoystick[activeThruster];

    iGraph.joysticks.forEach((pair) => {
        pair[0].showPosition = activeJoystick === 0;
        pair[1].showPosition = activeJoystick === 1;
    });
    iwsGraph.joysticks.forEach((pair) => {
        pair[0].showPosition = activeJoystick === 0;
        pair[1].showPosition = activeJoystick === 1;
    });

    // update all graphs
    iGraph.drawData();
    sGraph.drawData();
    iwsGraph.drawData();

    // update submarine graphic
    submarine.activeThruster = activeThruster;

    document.getElementById("thruster").innerHTML = names[activeThruster];
}

function updateT(value) {
    sensitivity.t = value;

    document.getElementById("tLabel").innerHTML = value;

    sGraph.drawData();
    iwsGraph.drawData();
}

function updatePower(value) {
    sensitivity.power = value;

    document.getElementById("powerLabel").innerHTML = value;

    sGraph.drawData();
    iwsGraph.drawData();
}

function updateActiveThruster(submarine) {
    activeThruster = submarine.activeThruster;
    updateCharts();
}

redpajama_set_name: RedPajamaGithub


text:
<?php

/**
 * Squiz_Sniffs_CSS_DuplicateClassDefinitionSniff.
 *
 * Check for duplicate class definitions that can be merged into one.
 *
 * @category  PHP
 * @package   PHP_CodeSniffer
 * @author    Greg Sherwood <gsherwood@squiz.net>
 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
 * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
 * @version   Release: @package_version@
 * @link      http://pear.php.net/package/PHP_CodeSniffer
 */
class Squiz_Sniffs_CSS_DuplicateClassDefinitionSniff implements PHP_CodeSniffer_Sniff
{

    /**
     * A list of tokenizers this sniff supports.
     *
     * @var array
     */
    public $supportedTokenizers = array('CSS');

    /**
     * Returns the token types that this sniff is interested in.
     *
     * @return int[]
     */
    public function register()
    {
        return array(T_OPEN_TAG);

    }//end register()

    /**
     * Processes the tokens that this sniff is interested in.
     *
     * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found.
     * @param int                  $stackPtr  The position in the stack where
     *                                        the token was found.
     *
     * @return void
     */
    public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
    {
        $tokens = $phpcsFile->getTokens();

        // Find the content of each class definition name.
        $classNames = array();
        $next       = $phpcsFile->findNext(T_OPEN_CURLY_BRACKET, ($stackPtr + 1));
        if ($next === false) {
            // No class definitions in the file.
            return;
        }

        // Save the class names in a "scope",
        // to prevent false positives with @media blocks.
        $scope = 'main';

        $find = array(
                 T_CLOSE_CURLY_BRACKET,
                 T_OPEN_CURLY_BRACKET,
                 T_COMMENT,
                 T_OPEN_TAG,
                );

        while ($next !== false) {
            $prev = $phpcsFile->findPrevious($find, ($next - 1));

            // Check if an inner block was closed.
            $beforePrev = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, ($prev - 1), null, true);
            if ($beforePrev !== false
                && $tokens[$beforePrev]['code'] === T_CLOSE_CURLY_BRACKET
            ) {
                $scope = 'main';
            }

            // Create a sorted name for the class so we can compare classes
            // even when the individual names are all over the place.
            $name = '';
            for ($i = ($prev + 1); $i < $next; $i++) {
                $name .= $tokens[$i]['content'];
            }

            $name = trim($name);
            $name = str_replace("\n", ' ', $name);
            $name = preg_replace('|[\s]+|', ' ', $name);
            $name = str_replace(', ', ',', $name);

            $names = explode(',', $name);
            sort($names);
            $name = implode(',', $names);

            if ($name{0} === '@') {
                // Media block has its own "scope".
                $scope = $name;
            } else if (isset($classNames[$scope][$name]) === true) {
                $first = $classNames[$scope][$name];
                $error = 'Duplicate class definition found; first defined on line %s';
                $data  = array($tokens[$first]['line']);
                $phpcsFile->addError($error, $next, 'Found', $data);
            } else {
                $classNames[$scope][$name] = $next;
            }

            $next = $phpcsFile->findNext(T_OPEN_CURLY_BRACKET, ($next + 1));
        }//end while

    }//end process()

}//end class


text:
from django.utils.translation import ugettext_lazy as _
from django.views.generic.base import TemplateResponseMixin
from django.views.generic.list import BaseListView

from wagtail.admin.auth import permission_denied
from wagtail.core.models import UserPagePermissionsProxy

class ReportView(TemplateResponseMixin, BaseListView):
    header_icon = ''
    page_kwarg = 'p'
    template_name = None
    title = ''
    paginate_by = 10

    def get_context_data(self, *args, object_list=None, **kwargs):
        context = super().get_context_data(*args, object_list=object_list, **kwargs)
        context['title'] = self.title
        context['header_icon'] = self.header_icon
        return context

class LockedPagesView(ReportView):
    template_name = 'wagtailadmin/reports/locked_pages.html'
    title = _('Locked Pages')
    header_icon = 'locked'

    def get_queryset(self):
        pages = UserPagePermissionsProxy(self.request.user).editable_pages().filter(locked=True)
        self.queryset = pages
        return super().get_queryset()

    def dispatch(self, request, *args, **kwargs):
        if not UserPagePermissionsProxy(request.user).can_remove_locks():
            return permission_denied(request)
        return super().dispatch(request, *args, **kwargs)


text:
.. _backend_twitch:

Twitch Store Backend
====================


text:
package com.dmdirc.commandparser.commands.server;

import com.dmdirc.commandparser.BaseCommandInfo;
import com.dmdirc.commandparser.CommandArguments;
import com.dmdirc.commandparser.CommandInfo;
import com.dmdirc.commandparser.CommandType;
import com.dmdirc.commandparser.commands.BaseCommand;
import com.dmdirc.commandparser.commands.IntelligentCommand;
import com.dmdirc.commandparser.commands.context.CommandContext;
import com.dmdirc.commandparser.commands.context.ServerCommandContext;
import com.dmdirc.interfaces.CommandController;
import com.dmdirc.interfaces.Connection;
import com.dmdirc.interfaces.GroupChat;
import com.dmdirc.interfaces.InputModel;
import com.dmdirc.interfaces.WindowModel;
import com.dmdirc.ui.input.AdditionalTabTargets;
import com.dmdirc.ui.input.TabCompleterUtils;

import javax.annotation.Nonnull;
import javax.inject.Inject;

/**
 * The AllChannels command allows the user to issue a command to all channels on a server.
 */
public class AllChannels extends BaseCommand implements IntelligentCommand {

    /** A command info object for this command. */
    public static final CommandInfo INFO = new BaseCommandInfo("allchannels",
            "allchannels <command> - executes the command as though it had"
            + " been entered on all channels", CommandType.TYPE_SERVER);
    /** Tab-completer utilities. */
    private final TabCompleterUtils tabCompleterUtils;

    /**
     * Creates a new instance of this command.
     *
     * @param controller The controller to use for command information.
     */
    @Inject
    public AllChannels(final CommandController controller,
            final TabCompleterUtils tabCompleterUtils) {
        super(controller);
        this.tabCompleterUtils = tabCompleterUtils;
    }

    @Override
    public void execute(@Nonnull final WindowModel origin,
            final CommandArguments args, final CommandContext context) {
        final Connection server = ((ServerCommandContext) context).getConnection();
        final String command = args.getArgumentsAsString();

        for (GroupChat channel : server.getGroupChatManager().getChannels()) {
            channel.getWindowModel().getInputModel().map(InputModel::getCommandParser)
                    .ifPresent(cp -> cp.parseCommand(channel.getWindowModel(), command));
        }
    }

    @Override
    public AdditionalTabTargets getSuggestions(final int arg,
            final IntelligentCommandContext context) {
        return tabCompleterUtils.getIntelligentResults(arg, context, 0);
    }

}


text:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools" tools:context="net.ossrs.yasea.demo.MainActivity">
    <item android:id="@+id/action_settings" android:title="action_settings"
        android:orderInCategory="100" app:showAsAction="never" />

    <item android:id="@+id/original_filter" android:title="Original" app:showAsAction="never"/>
    <item android:id="@+id/beauty_filter" android:title="Beauty" app:showAsAction="never"/>
    <item android:id="@+id/cool_filter" android:title="Cool" app:showAsAction="never"/>
    <item android:id="@+id/early_bird_filter" android:title="Early Bird" app:showAsAction="never"/>
    <item android:id="@+id/evergreen_filter" android:title="Evergreen" app:showAsAction="never"/>
    <item android:id="@+id/n1977_filter" android:title="N1977" app:showAsAction="never"/>
    <item android:id="@+id/nostalgia_filter" android:title="Nostalgia" app:showAsAction="never"/>
    <item android:id="@+id/romance_filter" android:title="Romance" app:showAsAction="never"/>
    <item android:id="@+id/sunrise_filter" android:title="Sunrise" app:showAsAction="never"/>
    <item android:id="@+id/sunset_filter" android:title="Sunset" app:showAsAction="never"/>
    <item android:id="@+id/warm_filter" android:title="Warm" app:showAsAction="never"/>
    <item android:id="@+id/tender_filter" android:title="Tender" app:showAsAction="never"/>
    <item android:id="@+id/toast_filter" android:title="Toast" app:showAsAction="never"/>
    <item android:id="@+id/valencia_filter" android:title="Valencia" app:showAsAction="never"/>
    <item android:id="@+id/walden_filter" android:title="Walden" app:showAsAction="never"/>

</menu>


text:
$packageName = 'crystaldiskmark'
$installerType = 'EXE'
$url = 'http://jaist.dl.sourceforge.jp/crystaldiskmark/46482/CrystalDiskMark3_0_3a-en.exe'
$silentArgs = '/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP-'
$validExitCodes = @(0) #please insert other valid exit codes here, exit codes for ms http://msdn.microsoft.com/en-us/library/aa368542(VS.85).aspx

Install-ChocolateyPackage "$packageName" "$installerType" "$silentArgs" "$url"  -validExitCodes $validExitCodes


text:
require_relative 'http_exception'

module Saklient
  module Errors

    # この操作は認証が必要です. IDまたはパスワードが誤っている可能性があります.
    class HttpUnauthorizedException < Saklient::Errors::HttpException

      # @param [Fixnum] status
      # @param [String] code
      # @param [String] message
      def initialize(status, code = nil, message = '')
        super(status, code, (message).nil? || message == '' ? 'この操作は認証が必要です。IDまたはパスワードが誤っている可能性があります。' : message)
      end

    end

  end
end


text:
A simple template for starting a Polymer app

## Run
```console
npm install
bower install
npm start
```


text:
cask "localxpose" do
  arch arm: "arm64", intel: "amd64"

  version "22.9.2"
  sha256 :no_check

  url "https://api.localxpose.io/api/v2/downloads/loclx-darwin-#{arch}.zip"
  name "LocalXpose"
  desc "Reverse proxy that enables you to expose your localhost to the internet"
  homepage "https://localxpose.io/"

  livecheck do
    url "https://api.localxpose.io/api/v2/downloads/darwin-#{arch}.json"
    strategy :page_match do |page|
      JSON.parse(page)["Version"]
    end
  end

  auto_updates true

  binary "loclx-darwin-#{arch}", target: "loclx"

  zap trash: "~/.localxpose"
end


text:
module ReposReport
  VERSION = "5.0.2"
end


text:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- From: file:/Users/caominhvu/AndroidStudioProjects/InteractiveJob/facebook/build/intermediates/bundles/debug/res/values-in/values-in.xml -->
    <eat-comment/>
    <string name="messenger_send_button_text">Kirim</string>
</resources>


text:
<?php
namespace Topxia\WebBundle\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Topxia\Service\Util\CloudClientFactory;
use Topxia\Common\StringToolkit;
use Topxia\Common\FileToolkit;
use Topxia\Service\User\CurrentUser;
use Topxia\Service\CloudPlatform\CloudAPIFactory;

class HLSController extends BaseController
{

    public function playlistAction(Request $request, $id, $token)
    {
        $line = $request->query->get('line', null);
        $hideBeginning = $request->query->get('hideBeginning', false);
        $returnJson = $request->query->get('returnJson', false);
        $token = $this->getTokenService()->verifyToken('hls.playlist', $token);

        $levelParam = $request->query->get('level', "");

        if (empty($token)) {
            throw $this->createNotFoundException();
        }

        $dataId = is_array($token['data']) ? $token['data']['id'] : $token['data'];

        if ($dataId != $id) {
            throw $this->createNotFoundException();
        }

        $file = $this->getUploadFileService()->getFile($id);
        if (empty($file)) {
            throw $this->createNotFoundException();
        }

        $streams = array();
        $mode = is_array($token['data']) ? $token['data']['mode'] : '';

        foreach (array('sd', 'hd', 'shd') as $level) {
            if (empty($file['metas2'][$level])) {
                continue;
            }

            if(empty($levelParam) || (!empty($levelParam) && strtolower($levelParam) == $level)) {
                $tokenFields = array(
                    'data' => array(
                        'id' => $file['id']. $level,
                        'mode' => $mode
                    ) ,
                    'times' => 1,
                    'duration' => 3600
                );

                if(!empty($token['userId'])) {
                    $tokenFields['userId'] = $token['userId'];
                }

                $token = $this->getTokenService()->makeToken('hls.stream', $tokenFields);
            } else {
                $token['token'] = $this->getTokenService()->makeFakeTokenString();
            }

            $params = array(
                'id' => $file['id'],
                'level' => $level,
                'token' => $token['token'],
            );

            if ($line) {
                $params['line'] = $line;
            }
            if (!$this->haveHeadLeader()) {
                $params['hideBeginning'] = 1;
            }
            $streams[$level] = $this->generateUrl('hls_stream', $params, true);
        }

        $qualities = array(
            'video' => $file['convertParams']['videoQuality'],
            'audio' => $file['convertParams']['audioQuality'],
        );

        $api = CloudAPIFactory::create('leaf');

        if($returnJson){
            $playlist = $api->get('/hls/playlist/json', array( 'streams' => $streams, 'qualities' => $qualities));
            return $this->createJsonResponse($playlist);
        } else {
            $playlist = $api->get('/hls/playlist', array( 'streams' => $streams, 'qualities' => $qualities));
            if (empty($playlist['playlist'])) {
                return $this->createMessageResponse('error', '生成视频播放列表失败!');
            }

            return new Response($playlist['playlist'], 200, array(
                'Content-Type' => 'application/vnd.apple.mpegurl',
                'Content-Disposition' => 'inline; filename="playlist.m3u8"',
            ));
        }
    }

    protected function haveHeadLeader()
    {
        $storage = $this->setting("storage");
        if(!empty($storage) && array_key_exists("video_header", $storage) && $storage["video_header"]){
            return true;
        }
        return false;
    }

    public function streamAction(Request $request, $id, $level, $token)
    {
        $token = $this->getTokenService()->verifyToken('hls.stream', $token);

        if (empty($token)) {
            throw $this->createNotFoundException();
        }

        $dataId = is_array($token['data']) ? $token['data']['id'] : $token['data'];
        if ($dataId != ($id.$level)) {
            throw $this->createNotFoundException();
        }

        $file = $this->getUploadFileService()->getFile($id);
        if (empty($file)) {
            throw $this->createNotFoundException();
        }

        if (empty($file['metas2'][$level]['key'])) {
            throw $this->createNotFoundException();
        }

        $params = array();
        $params['key'] = $file['metas2'][$level]['key'];

        $mode = is_array($token['data']) ? $token['data']['mode'] : '';
        $timelimit = $this->setting('magic.lesson_watch_time_limit');
        if ($mode == 'preview' && !empty($timelimit)) {
            $params['limitSecond'] = $timelimit;
        }

        $tokenFields = array(
            'data' => array(
                'id' => $file['id'],
                'mode' => $mode
            ),
            'times' => 1,
            'duration' => 3600
        );

        if(!empty($token['userId'])) {
            $tokenFields['userId'] = $token['userId'];
        }

        $token = $this->getTokenService()->makeToken('hls.clef', $tokenFields);

        $params['keyUrl'] = $this->generateUrl('hls_clef', array('id' =>  $file['id'], 'token' => $token['token']), true);

        $hideBeginning = $request->query->get('hideBeginning');
        if (empty($hideBeginning)) {
            $beginning = $this->getVideoBeginning($level, $token['userId']);
            if ($beginning['beginningKey']) {
                $params = array_merge($params, $beginning);
            }
        }

        $line = $request->query->get('line');
        if (!empty($line)) {
            $params['line'] = $line;
        }

        $api = CloudAPIFactory::create('leaf');

        $stream = $api->get('/hls/stream', $params);

        if (empty($stream['stream'])) {
            return $this->createMessageResponse('error', '生成视频播放地址失败!');
        }

        return new Response($stream['stream'], 200, array(
            'Content-Type' => 'application/vnd.apple.mpegurl',
            'Content-Disposition' => 'inline; filename="stream.m3u8"',
        ));

    }

    public function clefAction(Request $request, $id, $token)
    {
        $token = $this->getTokenService()->verifyToken('hls.clef', $token);
        $fakeKey = $this->getTokenService()->makeFakeTokenString(16);

        if (empty($token)) {
            return new Response($fakeKey);
        }

        if(!empty($token['userId'])) {
            if(!($this->getCurrentUser()->isLogin()
                && $this->getCurrentUser()->getId() == $token['userId'])) {
                return new Response($fakeKey);
            }
        }

        $dataId = is_array($token['data']) ? $token['data']['id'] : $token['data'];
        if ($dataId != $id) {
            return new Response($fakeKey);
        }

        $file = $this->getUploadFileService()->getFile($id);
        if (empty($file)) {
            return new Response($fakeKey);
        }

        if (empty($file['convertParams']['hlsKey'])) {
            return new Response($fakeKey);
        }

        return new Response($file['convertParams']['hlsKey']);
    }

    protected function getUploadFileService()
    {
        return $this->getServiceKernel()->createService('File.UploadFileService');
    }

    protected function getTokenService()
    {
        return $this->getServiceKernel()->createService('User.TokenService');
    }

    protected function getSettingService()
    {
        return $this->getServiceKernel()->createService('System.SettingService');
    }

    protected function getVideoBeginning($level, $userId = 0)
    {
        $beginning = array(
            'beginningKey' => null,
            'beginningKeyUrl' => null,
        );

        $storage = $this->getSettingService()->get("storage");
        if(!empty($storage['video_header'])) {

            $file = $this->getUploadFileService()->getFileByTargetType('headLeader');
            $beginnings = json_decode($file['metas2'], true);
            $levels = array($level);
            $levels = array_merge($levels, array_diff(array('shd', 'hd', 'sd'), $levels));

            foreach ($levels as $level) {
                if (empty($beginnings[$level])) {
                    continue;
                }

                $beginning['beginningKey'] = $beginnings[$level]['key'];
                $token = $this->getTokenService()->makeToken('hls.clef', array('data' => $file['id'], 'times' => 1, 'duration' => 3600, 'userId'=>$userId));
                $beginning['beginningKeyUrl'] = $this->generateUrl('hls_clef', array('id' => $file['id'], 'token' => $token['token']), true);
                break;
            }
        }

        return $beginning;
    }

}


text:
namespace gfx {
namespace {

// static
gfx::ImageSkiaRep& NullImageRep() {
  CR_DEFINE_STATIC_LOCAL(ImageSkiaRep, null_image_rep, ());
  return null_image_rep;
}

std::vector<float>* g_supported_scales = NULL;

// The difference to fall back to the smaller scale factor rather than the
// larger one. For example, assume 1.20 is requested but only 1.0 and 2.0 are
// supported. In that case, not fall back to 2.0 but 1.0, and then expand
// the image to 1.25.
const float kFallbackToSmallerScaleDiff = 0.20f;

}  // namespace

namespace internal {
namespace {

class Matcher {
 public:
  explicit Matcher(float scale) : scale_(scale) {
  }

  bool operator()(const ImageSkiaRep& rep) const {
    return rep.scale() == scale_;
  }

 private:
  float scale_;
};

ImageSkiaRep ScaleImageSkiaRep(const ImageSkiaRep& rep, float target_scale) {
  if (rep.is_null() || rep.scale() == target_scale)
    return rep;

  gfx::Size scaled_size =
      gfx::ScaleToCeiledSize(rep.pixel_size(), target_scale / rep.scale());
  return ImageSkiaRep(skia::ImageOperations::Resize(
      rep.sk_bitmap(),
      skia::ImageOperations::RESIZE_LANCZOS3,
      scaled_size.width(),
      scaled_size.height()), target_scale);
}

}  // namespace

// A helper class such that ImageSkia can be cheaply copied. ImageSkia holds a
// refptr instance of ImageSkiaStorage, which in turn holds all of ImageSkia's
// information. Having both |base::RefCountedThreadSafe| and
// |base::NonThreadSafe| may sounds strange but necessary to turn
// the 'thread-non-safe modifiable ImageSkiaStorage' into
// the 'thread-safe read-only ImageSkiaStorage'.
class ImageSkiaStorage : public base::RefCountedThreadSafe<ImageSkiaStorage>,
                         public base::NonThreadSafe {
 public:
  ImageSkiaStorage(ImageSkiaSource* source, const gfx::Size& size)
      : source_(source),
        size_(size),
        read_only_(false) {
  }

  ImageSkiaStorage(ImageSkiaSource* source, float scale)
      : source_(source),
        read_only_(false) {
    ImageSkia::ImageSkiaReps::iterator it = FindRepresentation(scale, true);
    if (it == image_reps_.end() || it->is_null())
      source_.reset();
    else
      size_.SetSize(it->GetWidth(), it->GetHeight());
  }

  bool has_source() const { return source_.get() != NULL; }

  std::vector<gfx::ImageSkiaRep>& image_reps() { return image_reps_; }

  const gfx::Size& size() const { return size_; }

  bool read_only() const { return read_only_; }

  void DeleteSource() {
    source_.reset();
  }

  void SetReadOnly() {
    read_only_ = true;
  }

  void DetachFromThread() {
    base::NonThreadSafe::DetachFromThread();
  }

  // Checks if the current thread can safely modify the storage.
  bool CanModify() const {
    return !read_only_ && CalledOnValidThread();
  }

  // Checks if the current thread can safely read the storage.
  bool CanRead() const {
    return (read_only_ && !source_.get()) || CalledOnValidThread();
  }

  // Add a new representation. This checks if the scale of the added image
  // is not 1.0f, and mark the existing rep as scaled to make
  // the image high DPI aware.
  void AddRepresentation(const ImageSkiaRep& image) {
    if (image.scale() != 1.0f) {
      for (ImageSkia::ImageSkiaReps::iterator it = image_reps_.begin();
           it < image_reps_.end();
           ++it) {
        if (it->unscaled()) {
          DCHECK_EQ(1.0f, it->scale());
          it->SetScaled();
          break;
        }
      }
    }
    image_reps_.push_back(image);
  }

  // Returns the iterator of the image rep whose density best matches
  // |scale|. If the image for the |scale| doesn't exist in the storage and
  // |storage| is set, it fetches new image by calling
  // |ImageSkiaSource::GetImageForScale|. There are two modes to deal with
  // arbitrary scale factors.
  // 1: Invoke GetImageForScale with requested scale and if the source
  //   returns the image with different scale (if the image doesn't exist in
  //   resource, for example), it will fallback to closest image rep.
  // 2: Invoke GetImageForScale with the closest known scale to the requested
  //   one and rescale the image.
  // Right now only Windows uses 2 and other platforms use 1 by default.
  // TODO(mukai, oshima): abandon 1 code path and use 2 for every platforms.
  std::vector<ImageSkiaRep>::iterator FindRepresentation(
      float scale, bool fetch_new_image) const {
    ImageSkiaStorage* non_const = const_cast<ImageSkiaStorage*>(this);

    ImageSkia::ImageSkiaReps::iterator closest_iter =
        non_const->image_reps().end();
    ImageSkia::ImageSkiaReps::iterator exact_iter =
        non_const->image_reps().end();
    float smallest_diff = std::numeric_limits<float>::max();
    for (ImageSkia::ImageSkiaReps::iterator it =
             non_const->image_reps().begin();
         it < image_reps_.end(); ++it) {
      if (it->scale() == scale) {
        // found exact match
        fetch_new_image = false;
        if (it->is_null())
          continue;
        exact_iter = it;
        break;
      }
      float diff = std::abs(it->scale() - scale);
      if (diff < smallest_diff && !it->is_null()) {
        closest_iter = it;
        smallest_diff = diff;
      }
    }

    if (fetch_new_image && source_.get()) {
      DCHECK(CalledOnValidThread()) <<
          "An ImageSkia with the source must be accessed by the same thread.";

      ImageSkiaRep image;
      float resource_scale = scale;
      if (g_supported_scales) {
        if (g_supported_scales->back() <= scale) {
          resource_scale = g_supported_scales->back();
        } else {
          for (size_t i = 0; i < g_supported_scales->size(); ++i) {
            if ((*g_supported_scales)[i] + kFallbackToSmallerScaleDiff >=
                scale) {
              resource_scale = (*g_supported_scales)[i];
              break;
            }
          }
        }
      }
      if (scale != resource_scale) {
        std::vector<ImageSkiaRep>::iterator iter = FindRepresentation(
            resource_scale, fetch_new_image);
        DCHECK(iter != image_reps_.end());
        image = iter->unscaled() ? (*iter) : ScaleImageSkiaRep(*iter, scale);
      } else {
        image = source_->GetImageForScale(scale);
        // Image may be missing for the specified scale in some cases, such like
        // looking up 2x resources but the 2x resource pack is missing. Falls
        // back to 1x and re-scale it.
        if (image.is_null() && scale != 1.0f)
          image = ScaleImageSkiaRep(source_->GetImageForScale(1.0f), scale);
      }

      // If the source returned the new image, store it.
      if (!image.is_null() &&
          std::find_if(image_reps_.begin(), image_reps_.end(),
                       Matcher(image.scale())) == image_reps_.end()) {
        non_const->image_reps().push_back(image);
      }

      // If the result image's scale isn't same as the expected scale, create
      // null ImageSkiaRep with the |scale| so that the next lookup will
      // fallback to the closest scale.
      if (image.is_null() || image.scale() != scale) {
        non_const->image_reps().push_back(ImageSkiaRep(SkBitmap(), scale));
      }

      // image_reps_ must have the exact much now, so find again.
      return FindRepresentation(scale, false);
    }
    return exact_iter != image_reps_.end() ? exact_iter : closest_iter;
  }

 private:
  virtual ~ImageSkiaStorage() {
    // We only care if the storage is modified by the same thread.
    // Don't blow up even if someone else deleted the ImageSkia.
    DetachFromThread();
  }

  // Vector of bitmaps and their associated scale.
  std::vector<gfx::ImageSkiaRep> image_reps_;

  scoped_ptr<ImageSkiaSource> source_;

  // Size of the image in DIP.
  gfx::Size size_;

  bool read_only_;

  friend class base::RefCountedThreadSafe<ImageSkiaStorage>;
};

}  // internal

ImageSkia::ImageSkia() : storage_(NULL) {
}

ImageSkia::ImageSkia(ImageSkiaSource* source, const gfx::Size& size)
    : storage_(new internal::ImageSkiaStorage(source, size)) {
  DCHECK(source);
  // No other thread has reference to this, so it's safe to detach the thread.
  DetachStorageFromThread();
}

ImageSkia::ImageSkia(ImageSkiaSource* source, float scale)
    : storage_(new internal::ImageSkiaStorage(source, scale)) {
  DCHECK(source);
  if (!storage_->has_source())
    storage_ = NULL;
  // No other thread has reference to this, so it's safe to detach the thread.
  DetachStorageFromThread();
}

ImageSkia::ImageSkia(const ImageSkiaRep& image_rep) {
  Init(image_rep);
  // No other thread has reference to this, so it's safe to detach the thread.
  DetachStorageFromThread();
}

ImageSkia::ImageSkia(const ImageSkia& other) : storage_(other.storage_) {
}

ImageSkia& ImageSkia::operator=(const ImageSkia& other) {
  storage_ = other.storage_;
  return *this;
}

ImageSkia::~ImageSkia() {
}

// static
void ImageSkia::SetSupportedScales(const std::vector<float>& supported_scales) {
  if (g_supported_scales != NULL)
    delete g_supported_scales;
  g_supported_scales = new std::vector<float>(supported_scales);
  std::sort(g_supported_scales->begin(), g_supported_scales->end());
}

// static
const std::vector<float>& ImageSkia::GetSupportedScales() {
  DCHECK(g_supported_scales != NULL);
  return *g_supported_scales;
}

// static
float ImageSkia::GetMaxSupportedScale() {
  return g_supported_scales->back();
}

// static
ImageSkia ImageSkia::CreateFrom1xBitmap(const SkBitmap& bitmap) {
  return ImageSkia(ImageSkiaRep(bitmap, 0.0f));
}

scoped_ptr<ImageSkia> ImageSkia::DeepCopy() const {
  ImageSkia* copy = new ImageSkia;
  if (isNull())
    return make_scoped_ptr(copy);

  CHECK(CanRead());

  std::vector<gfx::ImageSkiaRep>& reps = storage_->image_reps();
  for (std::vector<gfx::ImageSkiaRep>::iterator iter = reps.begin();
       iter != reps.end(); ++iter) {
    copy->AddRepresentation(*iter);
  }
  // The copy has its own storage. Detach the copy from the current
  // thread so that other thread can use this.
  if (!copy->isNull())
    copy->storage_->DetachFromThread();
  return make_scoped_ptr(copy);
}

bool ImageSkia::BackedBySameObjectAs(const gfx::ImageSkia& other) const {
  return storage_.get() == other.storage_.get();
}

void ImageSkia::AddRepresentation(const ImageSkiaRep& image_rep) {
  DCHECK(!image_rep.is_null());

  // TODO(oshima): This method should be called |SetRepresentation|
  // and replace the existing rep if there is already one with the
  // same scale so that we can guarantee that a ImageSkia instance contains only
  // one image rep per scale. This is not possible now as ImageLoader currently
  // stores need this feature, but this needs to be fixed.
  if (isNull()) {
    Init(image_rep);
  } else {
    CHECK(CanModify());
    // If someone is adding ImageSkia explicitly, check if we should
    // make the image high DPI aware.
    storage_->AddRepresentation(image_rep);
  }
}

void ImageSkia::RemoveRepresentation(float scale) {
  if (isNull())
    return;
  CHECK(CanModify());

  ImageSkiaReps& image_reps = storage_->image_reps();
  ImageSkiaReps::iterator it =
      storage_->FindRepresentation(scale, false);
  if (it != image_reps.end() && it->scale() == scale)
    image_reps.erase(it);
}

bool ImageSkia::HasRepresentation(float scale) const {
  if (isNull())
    return false;
  CHECK(CanRead());

  ImageSkiaReps::iterator it = storage_->FindRepresentation(scale, false);
  return (it != storage_->image_reps().end() && it->scale() == scale);
}

const ImageSkiaRep& ImageSkia::GetRepresentation(float scale) const {
  if (isNull())
    return NullImageRep();

  CHECK(CanRead());

  ImageSkiaReps::iterator it = storage_->FindRepresentation(scale, true);
  if (it == storage_->image_reps().end())
    return NullImageRep();

  return *it;
}

void ImageSkia::SetReadOnly() {
  CHECK(storage_.get());
  storage_->SetReadOnly();
  DetachStorageFromThread();
}

void ImageSkia::MakeThreadSafe() {
  CHECK(storage_.get());
  EnsureRepsForSupportedScales();
  // Delete source as we no longer needs it.
  if (storage_.get())
    storage_->DeleteSource();
  storage_->SetReadOnly();
  CHECK(IsThreadSafe());
}

bool ImageSkia::IsThreadSafe() const {
  return !storage_.get() || (storage_->read_only() && !storage_->has_source());
}

int ImageSkia::width() const {
  return isNull() ? 0 : storage_->size().width();
}

gfx::Size ImageSkia::size() const {
  return gfx::Size(width(), height());
}

int ImageSkia::height() const {
  return isNull() ? 0 : storage_->size().height();
}

std::vector<ImageSkiaRep> ImageSkia::image_reps() const {
  if (isNull())
    return std::vector<ImageSkiaRep>();

  CHECK(CanRead());

  ImageSkiaReps internal_image_reps = storage_->image_reps();
  // Create list of image reps to return, skipping null image reps which were
  // added for caching purposes only.
  ImageSkiaReps image_reps;
  for (ImageSkiaReps::iterator it = internal_image_reps.begin();
       it != internal_image_reps.end(); ++it) {
    if (!it->is_null())
      image_reps.push_back(*it);
  }

  return image_reps;
}

void ImageSkia::EnsureRepsForSupportedScales() const {
  DCHECK(g_supported_scales != NULL);
  // Don't check ReadOnly because the source may generate images
  // even for read only ImageSkia. Concurrent access will be protected
  // by |DCHECK(CalledOnValidThread())| in FindRepresentation.
  if (storage_.get() && storage_->has_source()) {
    for (std::vector<float>::const_iterator it = g_supported_scales->begin();
         it != g_supported_scales->end(); ++it)
      storage_->FindRepresentation(*it, true);
  }
}

void ImageSkia::Init(const ImageSkiaRep& image_rep) {
  // TODO(pkotwicz): The image should be null whenever image rep is null.
  if (image_rep.sk_bitmap().empty()) {
    storage_ = NULL;
    return;
  }
  storage_ = new internal::ImageSkiaStorage(
      NULL, gfx::Size(image_rep.GetWidth(), image_rep.GetHeight()));
  storage_->image_reps().push_back(image_rep);
}

const SkBitmap& ImageSkia::GetBitmap() const {
  if (isNull()) {
    // Callers expect a ImageSkiaRep even if it is |isNull()|.
    // TODO(pkotwicz): Fix this.
    return NullImageRep().sk_bitmap();
  }

  // TODO(oshima): This made a few tests flaky on Windows.
  // Fix the root cause and re-enable this. crbug.com/145623.
#if !defined(OS_WIN)
  CHECK(CanRead());
#endif

  ImageSkiaReps::iterator it = storage_->FindRepresentation(1.0f, true);
  if (it != storage_->image_reps().end())
    return it->sk_bitmap();
  return NullImageRep().sk_bitmap();
}

bool ImageSkia::CanRead() const {
  return !storage_.get() || storage_->CanRead();
}

bool ImageSkia::CanModify() const {
  return !storage_.get() || storage_->CanModify();
}

void ImageSkia::DetachStorageFromThread() {
  if (storage_.get())
    storage_->DetachFromThread();
}

}  // namespace gfx


text:
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.chrome.browser.suggestions;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.os.SystemClock;

import androidx.annotation.IntDef;

import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.base.metrics.RecordHistogram;
import org.chromium.chrome.R;
import org.chromium.ui.base.LocalizationUtils;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * When suggestions cards are displayed on a white background, thumbnails with white backgrounds
 * have a gradient overlaid to provide contrast at the edge of the cards.
 */
public class ThumbnailGradient {
    /** If all the RGB values of a pixel are greater than this value, it is counted as 'light'. */
    private static final int LIGHT_PIXEL_THRESHOLD = 0xcc;

    /** The percent of the border pictures that need to be 'light' for a Bitmap to be 'light'. */
    private static final float PIXEL_BORDER_RATIO = 0.4f;

    /** Where the image is located in the card. */
    @IntDef({ThumbnailLocation.START, ThumbnailLocation.END})
    @Retention(RetentionPolicy.SOURCE)
    public @interface ThumbnailLocation {
        int START = 0;
        int END = 1;
    }

    /** The corner of the thumbnail where the gradient is darkest. */
    @IntDef({GradientDirection.TOP_LEFT, GradientDirection.TOP_RIGHT})
    @Retention(RetentionPolicy.SOURCE)
    private @interface GradientDirection {
        int TOP_LEFT = 0;
        int TOP_RIGHT = 1;
    }

    /**
     * Calls {@link #createDrawableWithGradientIfNeeded(Bitmap, int, Resources)} with the default
     * {@link ThumbnailLocation#END}.
     */
    public static Drawable createDrawableWithGradientIfNeeded(Bitmap bitmap, Resources resources) {
        return createDrawableWithGradientIfNeeded(bitmap, ThumbnailLocation.END, resources);
    }

    /**
     * If the {@link Bitmap} should have a gradient applied this method returns a Drawable
     * containing the Bitmap and a gradient. Otherwise it returns a BitmapDrawable containing just
     * the Bitmap.
     * @param bitmap The {@link Bitmap} used to create the drawable.
     * @param thumbnailLocation Where the image is located in the card.
     * @param resources The {@link Resources} for the current activity.
     */
    public static Drawable createDrawableWithGradientIfNeeded(
            Bitmap bitmap, @ThumbnailLocation int thumbnailLocation, Resources resources) {
        int direction = getGradientDirection(thumbnailLocation);

        // We want to keep an eye on how long this takes.
        long time = SystemClock.elapsedRealtime();
        boolean lightImage = hasLightCorner(bitmap, direction);
        RecordHistogram.recordTimesHistogram(
                "Thumbnails.Gradient.ImageDetectionTime", SystemClock.elapsedRealtime() - time);

        RecordHistogram.recordBooleanHistogram(
                "Thumbnails.Gradient.ImageRequiresGradient", lightImage);

        if (lightImage) {
            Drawable gradient = ApiCompatibilityUtils.getDrawable(resources,
                    direction == GradientDirection.TOP_LEFT
                            ? R.drawable.thumbnail_gradient_top_left
                            : R.drawable.thumbnail_gradient_top_right);

            return new LayerDrawable(
                    new Drawable[] {new BitmapDrawable(resources, bitmap), gradient});
        }

        return new BitmapDrawable(resources, bitmap);
    }

    /**
     * Determines whether a Bitmap has a light corner.
     */
    private static boolean hasLightCorner(Bitmap bitmap, @GradientDirection int direction) {
        int lightPixels = 0;

        final int width = bitmap.getWidth();
        final int height = bitmap.getHeight();
        // We test all the pixels along the top and one side. The |-1| is so we don't count the
        // corner twice.
        final int threshold = (int) ((width + height - 1) * PIXEL_BORDER_RATIO);

        for (int x = 0; x < width; x++) {
            if (isPixelLight(bitmap.getPixel(x, 0))) lightPixels++;
        }

        // If we've already exceeded the threshold of light pixels, don't bother counting the rest.
        if (lightPixels > threshold) {
            return true;
        }

        final int x = direction == GradientDirection.TOP_LEFT ? 0 : width - 1;
        // Avoid counting the corner pixels twice.
        for (int y = 1; y < height - 1; y++) {
            if (isPixelLight(bitmap.getPixel(x, y))) lightPixels++;
        }

        return lightPixels > threshold;
    }

    /**
     * Whether a pixel counts as light.
     */
    private static boolean isPixelLight(int color) {
        return Color.red(color) > LIGHT_PIXEL_THRESHOLD && Color.blue(color) > LIGHT_PIXEL_THRESHOLD
                && Color.green(color) > LIGHT_PIXEL_THRESHOLD;
    }

    /**
     * The gradient should come from the upper corner of the thumbnail that is touching the side of
     * the card.
     */
    @GradientDirection
    private static int getGradientDirection(@ThumbnailLocation int thumbnailLocation) {
        // The drawable resource does not get flipped automatically if we are in RTL, so we must
        // flip it ourselves.
        boolean rtl = LocalizationUtils.isLayoutRtl();

        // If the thumbnail is on the left side of the card, the gradient should be applied
        // to the top left corner. If it is on the right side of the card, the gradient should be
        // applied to the top right corner.
        return thumbnailLocation == ThumbnailLocation.END == rtl ? GradientDirection.TOP_LEFT
                                                                 : GradientDirection.TOP_RIGHT;
    }
}


text:
package eu.derbed.openmu.gs.client;

import java.io.IOException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.notbed.muonline.util.DataDecrypter;
import com.notbed.muonline.util.Header;

import eu.derbed.openmu.gs.ClientThread;
import eu.derbed.openmu.gs.CommandHandler;
import eu.derbed.openmu.gs.serverPackets.SPublicMsg;

@Header (0x00)
class CPublicMsg extends SimpleClientPackage {

	private static final Logger log = LoggerFactory.getLogger(CPublicMsg.class);

	private static final byte[] _learnSkill = {(byte) 0xc1, 0x08, (byte) 0xf3, 0x11,
			(byte) 0xfe, 0x00, 0x11, 0x00};
	private static final byte[] _itemMove = {(byte) 0xC3, 0x0A, 0x24, 0x00, 0x0D,
			(byte) 0xB4, 0x10, 0x20, (byte) 0xC0, 0x00, 0x00};
	private static final byte[] _skilllist = {(byte) 0xc1, 0x08, (byte) 0xf3, 0x11,
			0x01, 0x00, 0x11, 0x01};
	private static final byte[] _itemPack = {(byte) 0xc4, 0x00, 0x06 + 6,
			(byte) 0xf3, 0x10, 0x01, 0x01, (byte) 0xC0, 0x00, 0x16, 0x00, 0x00};

	/* (non-Javadoc)
	 * @see eu.derbed.openmu.gs.clientPackage.SimpleClientPackage#process(com.notbed.muonline.util.DataDecrypter, eu.derbed.openmu.gs.ClientThread)
	 */
	@Override
	protected void process(DataDecrypter dataDecrypter, ClientThread client) throws IOException {

		final String _from = dataDecrypter.readS(1, 10).trim();
		final String _msg = dataDecrypter.readS(11, dataDecrypter.data.length - 12);
		log.debug("Public message from {}: {}.", _from, _msg);
		if (_msg.charAt(0) == '\\') {
			if (!CommandHandler.getInstancec().Execude(client,
					_msg.substring(1))) {
				client.getConnection().sendPacket(
						new SPublicMsg("System",
								"Wrong Command try again !"));
			}

			switch (_msg.charAt(1)) {
				case '1':
					client.getConnection().sendPacket(_learnSkill);
					break;
				case '2':
					client.getConnection().sendPacket(_itemMove);
					break;
				case '3':
					client.getConnection().sendPacket(_skilllist);
					break;
				case '4':
					client.getConnection().sendPacket(_itemPack);
					break;
			}

		} else {
			client.getActiveChar()
					.getCurrentWorldRegion()
					.broadcastPacketWideArea(client.getActiveChar(),
							client.getActiveChar().getX() / 3,
							client.getActiveChar().getY() / 3,
							new SPublicMsg(_from, _msg));
			client.getActiveChar().sendPacket(new SPublicMsg(_from, _msg));
		}
	}

}


text:
package com.quinn.githubknife.presenter;

import android.content.Context;

import com.quinn.githubknife.view.ListFragmentView;

/**
 * Created by Quinn on 7/20/15.
 */
public class FolloweringPresenterImpl extends PresenterAdapter{

    public FolloweringPresenterImpl(Context context, ListFragmentView view){
        super(context, view);
    }

    @Override
    public void onPageLoad(int page, String user){
        super.onPageLoad(page,user);
        interactor.loadFollowerings(user,page);
    }

}


text:
try:
    from pokeminer.landmarks import Landmarks
except ImportError:
    print('Copy this script to the pokeminer directory, not scripts/')
    raise

import pickle

LANDMARKS = Landmarks(query_suffix='Salt Lake City')

# replace the following with your own landmarks
LANDMARKS.add('Rice Eccles Stadium', hashtags={'Utes'})
LANDMARKS.add('the Salt Lake Temple', hashtags={'TempleSquare'})
LANDMARKS.add('City Creek Center', points=((40.769210, -111.893901), (40.767231, -111.888275)), hashtags={'CityCreek'})
LANDMARKS.add('the State Capitol', query='Utah State Capitol Building')
LANDMARKS.add('the University of Utah', hashtags={'Utes'}, phrase='at', is_area=True)
LANDMARKS.add('Yalecrest', points=((40.750263, -111.836502), (40.750377, -111.851108), (40.751515, -111.853833), (40.741212, -111.853909), (40.741188, -111.836519)), is_area=True)

with open('pickles/landmarks.pickle', 'wb') as f:
    pickle.dump(LANDMARKS, f, pickle.HIGHEST_PROTOCOL)

print('\033[94mDone. Now add the following to your config:\n\033[92m',
      'import pickle',
      "with open('pickles/landmarks.pickle', 'rb') as f:",
      '    LANDMARKS = pickle.load(f)',
      sep='\n')


text:
from django import forms
from plan.models import Plan, SpecialFeature, UserProfile
from django.contrib.auth.models import User
from django.forms import widgets
from registration.forms import RegistrationFormUniqueEmail, RegistrationFormTermsOfService
from django.utils.translation import ugettext_lazy as _

class PlanForm(forms.Form):
	number   = forms.CharField(label='Plan Number', required=False)
	min_area = forms.FloatField(label='Square Feet', required=False)
	max_area = forms.FloatField(label='Max Area', required=False)
	min_bed  = forms.FloatField(label='Bedrooms', required=False)
	max_bed  = forms.FloatField(label='Max Bedrooms', required=False)
	min_bath = forms.FloatField(label='Bathrooms', required=False)
	max_bath = forms.FloatField(label='Max Bathrooms', required=False)
	min_floor  = forms.FloatField(label='Floors', required=False)
	max_floor  = forms.FloatField(label='Max Floors', required=False)
	min_garage = forms.FloatField(label='Garages', required=False)
	max_garage = forms.FloatField(label='Max Garage', required=False)
	min_living = forms.FloatField(label='Living Areas', required=False)
	max_living = forms.FloatField(label='Max Living', required=False)
	min_width  = forms.CharField(label='House Width', required=False)
	max_width  = forms.CharField(label='', required=False)
	features = forms.ModelMultipleChoiceField(queryset=SpecialFeature.objects.all(), required=False, widget=widgets.CheckboxSelectMultiple)

class UserForm(forms.ModelForm):
	password = forms.CharField(widget=forms.PasswordInput())

	class Meta:
		model = User
		fields = ('username', 'email', 'password')

class UserProfileForm(forms.ModelForm):
	class Meta:
		model = UserProfile
		fields = ('fav_plans',)

class RegistrationFormDHHD(RegistrationFormUniqueEmail):
	"""
	Subclass of 'RegistrationFormUniqueEmail', which is a subclass of
	'RegistrationForm'. Adds fields for user's first and last names, not required.
	Overrides username, email, password1, and password2 to add a placeholder attribute
	in the HTML output.
	"""
	username = forms.RegexField(regex=r'^[\w.@+-]+$', max_length=30, label=_("Username"),
								error_messages={'invalid': _("This value may contain only letters, numbers and @/./+/-/_ characters.")},
								widget=forms.TextInput(attrs={'placeholder': 'Username'}))
	email = forms.EmailField(label=_("E-mail"), widget=forms.EmailInput(attrs={'placeholder': 'Email address'}))
	password1 = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder': 'Password'}), label=_("Password"))
	password2 = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder': 'Password (again)'}), label=_("Password (again)"))

	first_name = forms.CharField(label=_('First Name'), required=False, widget=forms.TextInput(attrs={'placeholder': 'Your first name'}))
	last_name = forms.CharField(label=_('Last Name'), required=False, widget=forms.TextInput(attrs={'placeholder': 'Your last name'}))