begin correctly implementing styles and formats

This commit is contained in:
Thomas Fussell 2016-08-16 00:23:49 -04:00
parent a7067db2ba
commit 94881ce660
50 changed files with 1893 additions and 2496 deletions

View File

@ -172,7 +172,48 @@ public:
/// </summary>
bool has_hyperlink() const;
// style
// computed format
/// <summary>
/// For each of alignment, border, fill, font, number format, and protection,
/// returns a format using the value from the cell format if that value is
/// applied, or else the value from the named style if that value is applied,
/// or else the default value. This is used to retreive the formatting of the cell
/// as it will be displayed in an editing application.
/// </summary>
format get_computed_format() const;
/// <summary>
/// Returns the result of get_computed_format().get_alignment().
/// </summary>
alignment get_computed_alignment() const;
/// <summary>
/// Returns the result of get_computed_format().get_border().
/// </summary>
border get_computed_border() const;
/// <summary>
/// Returns the result of get_computed_format().get_fill().
/// </summary>
fill get_computed_fill() const;
/// <summary>
/// Returns the result of get_computed_format().get_font().
/// </summary>
font get_computed_font() const;
/// <summary>
/// Returns the result of get_computed_format().get_number_format().
/// </summary>
number_format get_computed_number_format() const;
/// <summary>
/// Returns the result of get_computed_format().get_protection().
/// </summary>
protection get_computed_protection() const;
// format
/// <summary>
/// Return true if this cell has had a format applied to it.
@ -181,100 +222,145 @@ public:
/// <summary>
/// Return a reference to the format applied to this cell.
/// If this cell has no format, an invalid_attribute exception will be thrown.
/// </summary>
format &get_format();
/// <summary>
/// Return a reference to the format applied to this cell.
/// </summary>
const format &get_format() const;
format get_format() const;
/// <summary>
/// Applies the cell-level formatting of new_format to this cell.
/// </summary>
void set_format(const format &new_format);
void set_format_id(std::size_t format_id);
/// <summary>
/// Remove the cell-level formatting from this cell.
/// This doesn't affect the style that may also be applied to the cell.
/// Throws an invalid_attribute exception if no format is applied.
/// </summary>
void clear_format();
// style
/// <summary>
/// Return true if this cell has had a format applied to it.
/// </summary>
bool has_style() const;
/// <summary>
/// Return a reference to the format applied to this cell.
/// </summary>
const style &get_style() const;
void set_style(const style &new_style);
void set_style(const std::string &style_name);
void clear_style();
/// <summary>
/// Return the number format of this cell.
/// Returns the number format of this cell.
/// </summary>
const number_format &get_number_format() const;
/// <summary>
/// Creates a new format in the workbook, sets its number_format
/// to the given format, and applies the format to this cell.
/// </summary>
void set_number_format(const number_format &format);
/// <summary>
/// Return the font applied to the text in this cell.
/// Returns the font applied to the text in this cell.
/// </summary>
const font &get_font() const;
/// <summary>
/// Creates a new format in the workbook, sets its font
/// to the given font, and applies the format to this cell.
/// </summary>
void set_font(const font &font_);
/// <summary>
/// Return the fill applied to this cell.
/// Returns the fill applied to this cell.
/// </summary>
const fill &get_fill() const;
/// <summary>
/// Creates a new format in the workbook, sets its fill
/// to the given fill, and applies the format to this cell.
/// </summary>
void set_fill(const fill &fill_);
/// <summary>
/// Return the border of this cell.
/// Returns the border of this cell.
/// </summary>
const border &get_border() const;
/// <summary>
/// Creates a new format in the workbook, sets its border
/// to the given border, and applies the format to this cell.
/// </summary>
void set_border(const border &border_);
/// <summary>
/// Return the alignment of the text in this cell.
/// Returns the alignment of the text in this cell.
/// </summary>
const alignment &get_alignment() const;
/// <summary>
/// Creates a new format in the workbook, sets its alignment
/// to the given alignment, and applies the format to this cell.
/// </summary>
void set_alignment(const alignment &alignment_);
/// <summary>
/// Return the protection of this cell.
/// Returns the protection of this cell.
/// </summary>
const protection &get_protection() const;
/// <summary>
/// Creates a new format in the workbook, sets its protection
/// to the given protection, and applies the format to this cell.
/// </summary>
void set_protection(const protection &protection_);
// comment
// style
/// <summary>
/// Return the comment of this cell.
/// </summary>
comment get_comment();
/// <summary>
/// Returns true if this cell has had a style applied to it.
/// </summary>
bool has_style() const;
/// <summary>
/// Return the comment of this cell.
/// </summary>
const comment get_comment() const;
/// <summary>
/// Returns a reference to the named style applied to this cell.
/// </summary>
style get_style() const;
void set_comment(const comment &comment);
void clear_comment();
bool has_comment() const;
/// <summary>
/// Returns the name of the style applied to this cell.
/// </summary>
std::string get_style_name() const;
/// <summary>
/// Equivalent to set_style(new_style.name())
/// </summary>
void set_style(const style &new_style);
/// <summary>
/// Sets the named style applied to this cell to a style named style_name.
/// If this style has not been previously created in the workbook, a
/// key_not_found exception will be thrown.
/// </summary>
void set_style(const std::string &style_name);
/// <summary>
/// Removes the named style from this cell.
/// An invalid_attribute exception will be thrown if this cell has no style.
/// This will not affect the cell format of the cell.
/// </summary>
void clear_style();
// formula
/// <summary>
/// Returns the string representation of the formula applied to this cell.
/// </summary>
std::string get_formula() const;
/// <summary>
/// Sets the formula of this cell to the given value.
/// This formula string should begin with '='.
/// </summary>
void set_formula(const std::string &formula);
/// <summary>
/// Removes the formula from this cell. After this is called, has_formula() will return false.
/// </summary>
void clear_formula();
/// <summary>
/// Returns true if this cell has had a formula applied to it.
/// </summary>
bool has_formula() const;
// printing
@ -384,8 +470,6 @@ public:
friend XLNT_FUNCTION std::ostream &operator<<(std::ostream &stream, const xlnt::cell &cell);
private:
std::size_t get_format_id() const;
// make these friends so they can use the private constructor
friend class style;
friend class worksheet;
@ -393,8 +477,18 @@ private:
friend class detail::xlsx_producer;
friend struct detail::cell_impl;
/// <summary>
/// Helper function to guess the type of a string, convert it,
/// and then use the correct cell::get_value according to the type.
/// </summary>
void guess_type_and_set_value(const std::string &value);
/// <summary>
/// Returns a non-const reference to the format of this cell.
/// This is for internal use only.
/// </summary>
format &get_format();
/// <summary>
/// Private constructor to create a cell from its implementation.
/// </summary>

View File

@ -54,7 +54,7 @@ public:
/// <remarks>
/// Excel only supports 1 - 3 letter column names from A->ZZZ, so we
/// restrict our column names to 1 - 3 characters, each in the range A - Z.
/// Strings outside this range and malformed strings will throw xlnt::column_string_index_exception.
/// Strings outside this range and malformed strings will throw column_string_index_exception.
/// </remarks>
static index_t column_index_from_string(const std::string &column_string);

View File

@ -63,11 +63,11 @@ public:
private:
std::string string_;
std::experimental::optional<std::size_t> size_;
std::experimental::optional<std::string> color_;
std::experimental::optional<std::string> font_;
std::experimental::optional<std::size_t> family_;
std::experimental::optional<std::string> scheme_;
optional<std::size_t> size_;
optional<std::string> color_;
optional<std::string> font_;
optional<std::size_t> family_;
optional<std::string> scheme_;
};
} // namespace xlnt

View File

@ -28,6 +28,7 @@
#include <xlnt/styles/horizontal_alignment.hpp>
#include <xlnt/styles/vertical_alignment.hpp>
#include <xlnt/utils/hashable.hpp>
#include <xlnt/utils/optional.hpp>
namespace xlnt {
@ -37,36 +38,40 @@ namespace xlnt {
class XLNT_CLASS alignment : public hashable
{
public:
bool get_wrap_text() const;
optional<bool> shrink() const;
void set_wrap_text(bool wrap_text);
alignment &shrink(bool shrink_to_fit);
bool has_horizontal() const;
optional<bool> wrap() const;
horizontal_alignment get_horizontal() const;
alignment &wrap(bool wrap_text);
void set_horizontal(horizontal_alignment horizontal);
optional<int> indent() const;
bool has_vertical() const;
alignment &indent(int indent_size);
vertical_alignment get_vertical() const;
optional<int> rotation() const;
void set_vertical(vertical_alignment vertical);
void set_shrink_to_fit(bool shrink_to_fit);
bool get_shrink_to_fit() const;
alignment &rotation(bool text_rotation);
optional<horizontal_alignment> horizontal() const;
alignment &horizontal(horizontal_alignment horizontal);
optional<vertical_alignment> vertical() const;
alignment &vertical(vertical_alignment vertical);
protected:
std::string to_hash_string() const override;
private:
horizontal_alignment horizontal_ = horizontal_alignment::general;
vertical_alignment vertical_ = vertical_alignment::bottom;
int text_rotation_ = 0;
bool wrap_text_ = false;
bool shrink_to_fit_ = false;
int indent_ = 0;
optional<bool> shrink_to_fit_;
optional<bool> wrap_text_;
optional<int> indent_;
optional<int> text_rotation_;
optional<horizontal_alignment> horizontal_;
optional<vertical_alignment> vertical_;
};
} // namespace xlnt

View File

@ -33,8 +33,6 @@
namespace xlnt {
class cell;
/// <summary>
/// Describes the formatting of a particular cell.
/// </summary>

View File

@ -34,6 +34,7 @@
#include <xlnt/styles/diagonal_direction.hpp>
#include <xlnt/styles/side.hpp>
#include <xlnt/utils/hashable.hpp>
#include <xlnt/utils/optional.hpp>
namespace xlnt {
@ -50,19 +51,6 @@ enum class XLNT_CLASS border_side
} // namespace xlnt
namespace std {
template<>
struct hash<xlnt::border_side>
{
size_t operator()(const xlnt::border_side &k) const
{
return static_cast<std::size_t>(k);
}
};
} // namepsace std
namespace xlnt {
/// <summary>
@ -71,44 +59,44 @@ namespace xlnt {
class XLNT_CLASS border : public hashable
{
public:
using side = border_side;
class XLNT_CLASS border_property
{
public:
bool has_color() const;
const color &get_color() const;
void set_color(const color &c);
optional<color> color() const;
border_property &color(const xlnt::color &c);
bool has_style() const;
border_style get_style() const;
void set_style(border_style style);
optional<border_style> style() const;
border_property &style(border_style style);
private:
bool has_color_ = false;
color color_ = color::black();
bool has_style_ = false;
border_style style_;
optional<xlnt::color> color_;
optional<border_style> style_;
};
static const std::vector<std::pair<side, std::string>> &get_side_names();
static const std::vector<border_side> &all_sides();
border();
bool has_side(side s) const;
const border_property &get_side(side s) const;
void set_side(side s, const border_property &prop);
optional<border_property> side(border_side s) const;
border &side(border_side s, const border_property &prop);
optional<diagonal_direction> diagonal() const;
border &diagonal(diagonal_direction dir);
protected:
std::string to_hash_string() const override;
private:
std::unordered_map<side, border_property> sides_;
/*
bool outline_ = true;
diagonal_direction diagonal_direction_ = diagonal_direction::neither;
*/
optional<border_property> start_;
optional<border_property> end_;
optional<border_property> top_;
optional<border_property> bottom_;
optional<border_property> vertical_;
optional<border_property> horizontal_;
optional<border_property> diagonal_;
//bool outline_ = true;
optional<diagonal_direction> diagonal_direction_;
};
} // namespace xlnt

View File

@ -31,114 +31,115 @@
namespace xlnt {
enum class XLNT_CLASS pattern_fill_type
{
none,
solid,
mediumgray,
darkgray,
lightgray,
darkhorizontal,
darkvertical,
darkdown,
darkup,
darkgrid,
darktrellis,
lighthorizontal,
lightvertical,
lightdown,
lightup,
lightgrid,
lighttrellis,
gray125,
gray0625
};
class XLNT_CLASS pattern_fill : public hashable
{
public:
enum class type
{
none,
solid,
mediumgray,
darkgray,
lightgray,
darkhorizontal,
darkvertical,
darkdown,
darkup,
darkgrid,
darktrellis,
lighthorizontal,
lightvertical,
lightdown,
lightup,
lightgrid,
lighttrellis,
gray125,
gray0625
};
pattern_fill();
pattern_fill(type pattern_type);
pattern_fill_type type() const;
type get_type() const;
pattern_fill &type(pattern_fill_type new_type);
void set_type(type pattern_type);
optional<color> foreground() const;
void set_foreground_color(const color &c);
std::experimental::optional<color> &get_foreground_color();
const std::experimental::optional<color> &get_foreground_color() const;
pattern_fill &foreground(const color &foreground);
void set_background_color(const color &c);
optional<color> background() const;
std::experimental::optional<color> &get_background_color();
const std::experimental::optional<color> &get_background_color() const;
pattern_fill &background(const color &background);
protected:
std::string to_hash_string() const override;
private:
type type_ = type::none;
pattern_fill_type type_ = pattern_fill_type::none;
std::experimental::optional<color> foreground_color_;
std::experimental::optional<color> background_color_;
optional<color> foreground_;
optional<color> background_;
};
enum class XLNT_CLASS gradient_fill_type
{
linear,
path
};
class XLNT_CLASS gradient_fill : public hashable
{
public:
enum class type
{
linear,
path
};
gradient_fill();
gradient_fill(type gradient_type);
gradient_fill_type type() const;
type get_type() const;
// Type
gradient_fill &type(gradient_fill_type new_type);
void set_type(type gradient_type);
// Degree
void set_degree(double degree);
gradient_fill &degree(double degree);
double get_degree() const;
double degree() const;
double get_gradient_left() const;
// Left
void set_gradient_left(double value);
double left() const;
double get_gradient_right() const;
gradient_fill &left(double value);
void set_gradient_right(double value);
// Right
double get_gradient_top() const;
double right() const;
void set_gradient_top(double value);
gradient_fill &right(double value);
double get_gradient_bottom() const;
// Top
void set_gradient_bottom(double value);
double top() const;
void add_stop(double position, color stop_color);
gradient_fill &top(double value);
void delete_stop(double position);
// Bottom
void clear_stops();
double bottom() const;
gradient_fill &bottom(double value);
// Stops
gradient_fill &add_stop(double position, color stop_color);
gradient_fill &clear_stops();
const std::unordered_map<double, color> &get_stops() const;
std::unordered_map<double, color> stops() const;
protected:
std::string to_hash_string() const override;
private:
type type_ = type::linear;
std::unordered_map<double, color> stops_;
gradient_fill_type type_ = gradient_fill_type::linear;
double degree_ = 0;
@ -146,6 +147,14 @@ private:
double right_ = 0;
double top_ = 0;
double bottom_ = 0;
std::unordered_map<double, color> stops_;
};
enum class XLNT_CLASS fill_type
{
pattern,
gradient
};
/// <summary>
@ -154,33 +163,46 @@ private:
class XLNT_CLASS fill : public hashable
{
public:
enum class type
{
pattern,
gradient
};
/// <summary>
/// Constructs a fill initialized as a none-type pattern fill with no
/// foreground or background colors.
/// </summary>
fill();
static fill gradient(gradient_fill::type gradient_type);
/// <summary>
/// Constructs a fill initialized as a pattern fill based on the given pattern.
/// </summary>
fill(const pattern_fill &pattern);
static fill pattern(pattern_fill::type pattern_type);
/// <summary>
/// Constructs a fill initialized as a gradient fill based on the given gradient.
/// </summary>
fill(const gradient_fill &gradient);
type get_type() const;
/// <summary>
/// Returns the fill_type of this fill depending on how it was constructed.
/// </summary>
fill_type type() const;
gradient_fill &get_gradient_fill();
/// <summary>
/// Returns the gradient fill represented by this fill.
/// Throws an invalid_attribute exception if this is not a gradient fill.
/// </summary>
gradient_fill gradient_fill() const;
const gradient_fill &get_gradient_fill() const;
pattern_fill &get_pattern_fill();
const pattern_fill &get_pattern_fill() const;
/// <summary>
/// Returns the pattern fill represented by this fill.
/// Throws an invalid_attribute exception if this is not a pattern fill.
/// </summary>
pattern_fill pattern_fill() const;
protected:
std::string to_hash_string() const override;
private:
type type_ = type::pattern;
gradient_fill gradient_;
pattern_fill pattern_;
fill_type type_ = fill_type::pattern;
xlnt::gradient_fill gradient_;
xlnt::pattern_fill pattern_;
};
} // namespace xlnt

View File

@ -27,7 +27,7 @@
#include <xlnt/xlnt_config.hpp>
#include <xlnt/styles/color.hpp>
#include <xlnt/utils/hash_combine.hpp>
#include <xlnt/utils/optional.hpp>
namespace xlnt {
@ -50,47 +50,43 @@ public:
font();
void set_bold(bool bold);
font &bold(bool bold);
bool is_bold() const;
bool bold() const;
void set_italic(bool italic);
font &italic(bool italic);
bool is_italic() const;
bool italic() const;
void set_strikethrough(bool strikethrough);
font &strikethrough(bool strikethrough);
bool is_strikethrough() const;
bool strikethrough() const;
void set_underline(underline_style new_underline);
font &underline(underline_style new_underline);
bool is_underline() const;
bool underlined() const;
underline_style get_underline() const;
underline_style underline() const;
void set_size(std::size_t size);
font &size(std::size_t size);
std::size_t get_size() const;
std::size_t size() const;
void set_name(const std::string &name);
font &name(const std::string &name);
std::string get_name() const;
std::string name() const;
void set_color(color c);
font &color(const color &c);
void set_family(std::size_t family);
optional<xlnt::color> color() const;
bool has_scheme() const;
font &family(std::size_t family);
void set_scheme(const std::string &scheme);
optional<std::size_t> family() const;
std::string get_scheme() const;
font &scheme(const std::string &scheme);
color get_color() const;
bool has_family() const;
std::size_t get_family() const;
optional<std::string> scheme() const;
protected:
std::string to_hash_string() const override;
@ -104,13 +100,11 @@ private:
bool italic_ = false;
bool superscript_ = false;
bool subscript_ = false;
underline_style underline_ = underline_style::none;
bool strikethrough_ = false;
color color_ = theme_color(1);
bool has_family_ = true;
std::size_t family_ = 2;
bool has_scheme_ = true;
std::string scheme_ = "minor";
underline_style underline_ = underline_style::none;
optional<xlnt::color> color_;
optional<std::size_t> family_;
optional<std::string> scheme_;
};
} // namespace xlnt

View File

@ -1,5 +1,4 @@
// Copyright (c) 2014-2016 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@ -23,25 +22,58 @@
// @author: see AUTHORS file
#pragma once
#include <xlnt/styles/base_format.hpp>
#include <cstddef>
#include <string>
#include <xlnt/xlnt_config.hpp>
namespace xlnt {
class style;
namespace detail { struct workbook_impl; }
class alignment;
class border;
class fill;
class font;
class number_format;
class protection;
namespace detail {
struct format_impl;
struct stylesheet;
} // namespace detail
/// <summary>
/// Describes the formatting of a particular cell.
/// </summary>
class XLNT_CLASS format : public base_format
class XLNT_CLASS format
{
public:
format();
format(const format &other);
format &operator=(const format &other);
protected:
std::string to_hash_string() const override;
std::size_t get_id() const;
alignment get_alignment() const;
void set_alignment(const alignment &new_alignment);
border get_border() const;
void set_border(const border &new_border);
fill get_fill() const;
void set_fill(const fill &new_fill);
font get_font() const;
void set_font(const font &new_font);
number_format get_number_format() const;
void set_number_format(const number_format &new_number_format);
protection get_protection() const;
void set_protection(const protection &new_protection);
void set_style(const std::string &name);
std::string get_name() const;
private:
friend struct detail::stylesheet;
format(detail::format_impl *d);
detail::format_impl *d_;
};
} // namespace xlnt

View File

@ -27,6 +27,7 @@
#include <xlnt/xlnt_config.hpp>
#include <xlnt/utils/hashable.hpp>
#include <xlnt/utils/optional.hpp>
namespace xlnt {
@ -36,14 +37,18 @@ namespace xlnt {
class XLNT_CLASS protection : public hashable
{
public:
protection();
protection(bool locked, bool hidden);
static protection unlocked_and_visible();
static protection locked_and_visible();
static protection unlocked_and_hidden();
static protection locked_and_hidden();
bool get_locked() const;
void set_locked(bool locked);
protection();
bool locked() const;
protection &locked(bool locked);
bool get_hidden() const;
void set_hidden(bool hidden);
bool hidden() const;
protection &hidden(bool hidden);
protected:
std::string to_hash_string() const override;

View File

@ -30,35 +30,34 @@
namespace xlnt {
class workbook;
namespace detail {
struct style_impl;
struct stylesheet;
}
/// <summary>
/// Describes a style which has a name and can be applied to multiple individual
/// formats. In Excel this is a "Cell Style".
/// </summary>
class XLNT_CLASS style : public base_format
class XLNT_CLASS style
{
public:
style();
style(const style &other);
style &operator=(const style &other);
std::string get_name() const;
void set_name(const std::string &name);
std::string name() const;
style &name(const std::string &name);
bool get_hidden() const;
void set_hidden(bool value);
std::size_t get_builtin_id() const;
void set_builtin_id(std::size_t builtin_id);
bool hidden() const;
style &hidden(bool value);
protected:
std::string to_hash_string() const override;
bool custom() const;
style &custom(bool value);
std::size_t built_in_id() const;
style &built_in_id(std::size_t builtin_id);
private:
std::string name_;
bool hidden_;
std::size_t builtin_id_;
friend struct detail::stylesheet;
style(detail::style_impl *d);
detail::style_impl *d_;
};
} // namespace xlnt

View File

@ -29,6 +29,9 @@
namespace xlnt {
struct date;
struct time;
/// <summary>
/// A datetime is a combination of a date and a time.
/// </summary>
@ -52,6 +55,7 @@ struct XLNT_CLASS datetime
/// </summary>
static datetime from_number(long double number, calendar base_date);
datetime(const date &d, const time &t);
datetime(int year_, int month_, int day_, int hour_ = 0, int minute_ = 0, int second_ = 0, int microsecond_ = 0);
std::string to_string() const;

File diff suppressed because it is too large Load Diff

View File

@ -401,7 +401,7 @@ public:
format &get_format(std::size_t format_index);
const format &get_format(std::size_t format_index) const;
std::size_t add_format(const format &new_format);
format &create_format();
void clear_formats();
// styles
@ -409,11 +409,7 @@ public:
bool has_style(const std::string &name) const;
style &get_style(const std::string &name);
const style &get_style(const std::string &name) const;
style &get_style_by_id(std::size_t style_id);
const style &get_style_by_id(std::size_t style_id) const;
std::size_t get_style_id(const std::string &name) const;
style &create_style(const std::string &name);
std::size_t add_style(const style &new_style);
void clear_styles();
// manifest
@ -478,6 +474,16 @@ private:
/// Apply the function "f" to every cell in every worksheet in this workbook.
/// </summary>
void apply_to_cells(std::function<void(cell)> f);
void register_app_properties_in_manifest();
void register_core_properties_in_manifest();
void register_shared_string_table_in_manifest();
void register_stylesheet_in_manifest();
void register_theme_in_manifest();
/// <summary>
/// An opaque pointer to a structure that holds all of the data relating to this workbook.

View File

@ -169,7 +169,7 @@ std::string cell::check_string(const std::string &to_check)
{
if (c >= 0 && (c <= 8 || c == 11 || c == 12 || (c >= 14 && c <= 31)))
{
throw xlnt::illegal_character(c);
throw illegal_character(c);
}
}
@ -182,7 +182,7 @@ cell::cell(detail::cell_impl *d) : d_(d)
bool cell::garbage_collectible() const
{
return !(get_data_type() != type::null || is_merged() || has_comment() || has_formula() || has_format());
return !(get_data_type() != type::null || is_merged() || has_formula() || has_format());
}
template <>
@ -353,10 +353,8 @@ XLNT_FUNCTION void cell::set_value(cell c)
d_->value_numeric_ = c.d_->value_numeric_;
d_->value_text_ = c.d_->value_text_;
d_->hyperlink_ = c.d_->hyperlink_;
d_->has_hyperlink_ = c.d_->has_hyperlink_;
d_->formula_ = c.d_->formula_;
d_->format_id_ = c.d_->format_id_;
if (c.has_comment()) set_comment(c.get_comment());
}
template <>
@ -433,7 +431,18 @@ bool cell::operator==(const cell &comparand) const
cell &cell::operator=(const cell &rhs)
{
*d_ = *rhs.d_;
d_->column_ = rhs.d_->column_;
d_->format_id_ = rhs.d_->format_id_;
d_->formula_ = rhs.d_->formula_;
d_->hyperlink_ = rhs.d_->hyperlink_;
d_->is_merged_ = rhs.d_->is_merged_;
d_->parent_ = rhs.d_->parent_;
d_->row_ = rhs.d_->row_;
d_->style_name_ = rhs.d_->style_name_;
d_->type_ = rhs.d_->type_;
d_->value_numeric_ = rhs.d_->value_numeric_;
d_->value_text_ = rhs.d_->value_text_;
return *this;
}
@ -444,27 +453,16 @@ std::string cell::to_repr() const
std::string cell::get_hyperlink() const
{
if (!d_->has_hyperlink_)
{
throw std::runtime_error("no hyperlink set");
}
return d_->hyperlink_;
}
bool cell::has_hyperlink() const
{
return d_->has_hyperlink_;
return d_->hyperlink_.get();
}
void cell::set_hyperlink(const std::string &hyperlink)
{
if (hyperlink.length() == 0 || std::find(hyperlink.begin(), hyperlink.end(), ':') == hyperlink.end())
{
throw invalid_data_type();
throw invalid_parameter();
}
d_->has_hyperlink_ = true;
d_->hyperlink_ = hyperlink;
if (get_data_type() == type::null)
@ -492,17 +490,12 @@ void cell::set_formula(const std::string &formula)
bool cell::has_formula() const
{
return !d_->formula_.empty();
return d_->formula_;
}
std::string cell::get_formula() const
{
if (d_->formula_.empty())
{
throw invalid_attribute();
}
return d_->formula_;
return d_->formula_.get();
}
void cell::clear_formula()
@ -510,36 +503,6 @@ void cell::clear_formula()
d_->formula_.clear();
}
void cell::set_comment(const xlnt::comment &c)
{
if (c.d_ != d_->comment_.get())
{
throw xlnt::invalid_attribute();
}
if (!has_comment())
{
get_worksheet().increment_comments();
}
*get_comment().d_ = *c.d_;
}
void cell::clear_comment()
{
if (has_comment())
{
get_worksheet().decrement_comments();
}
d_->comment_ = nullptr;
}
bool cell::has_comment() const
{
return d_->comment_ != nullptr;
}
void cell::set_error(const std::string &error)
{
if (error.length() == 0 || error[0] != '#')
@ -575,18 +538,8 @@ const workbook &cell::get_workbook() const
{
return get_worksheet().get_workbook();
}
comment cell::get_comment()
{
if (d_->comment_ == nullptr)
{
d_->comment_.reset(new detail::comment_impl());
get_worksheet().increment_comments();
}
return comment(d_->comment_.get());
}
//TODO: this shares a lot of code with worksheet::get_point_pos, try to reduce repition
//TODO: this shares a lot of code with worksheet::get_point_pos, try to reduce repetion
std::pair<int, int> cell::get_anchor() const
{
static const double DefaultColumnWidth = 51.85;
@ -650,76 +603,34 @@ void cell::set_data_type(type t)
d_->type_ = t;
}
const number_format &cell::get_number_format() const
number_format cell::get_computed_number_format() const
{
if (d_->has_format_)
{
return get_workbook().get_format(d_->format_id_).get_number_format();
}
else
{
return get_workbook().get_format(0).get_number_format();
}
return get_computed_format().get_number_format();
}
const font &cell::get_font() const
font cell::get_computed_font() const
{
if (d_->has_format_)
{
return get_workbook().get_format(d_->format_id_).get_font();
}
else
{
return get_workbook().get_format(0).get_font();
}
return get_computed_format().get_font();
}
const fill &cell::get_fill() const
fill cell::get_computed_fill() const
{
if (d_->has_format_)
{
return get_workbook().get_format(d_->format_id_).get_fill();
}
else
{
return get_workbook().get_format(0).get_fill();
}
return get_computed_format().get_fill();
}
const border &cell::get_border() const
border cell::get_computed_border() const
{
if (d_->has_format_)
{
return get_workbook().get_format(d_->format_id_).get_border();
}
else
{
return get_workbook().get_format(0).get_border();
}
return get_computed_format().get_border();
}
const alignment &cell::get_alignment() const
alignment cell::get_computed_alignment() const
{
if (d_->has_format_)
{
return get_workbook().get_format(d_->format_id_).get_alignment();
}
else
{
return get_workbook().get_format(0).get_alignment();
}
return get_computed_format().get_alignment();
}
const protection &cell::get_protection() const
protection cell::get_computed_protection() const
{
if (d_->has_format_)
{
return get_workbook().get_format(d_->format_id_).get_protection();
}
else
{
return get_workbook().get_format(0).get_protection();
}
return get_computed_format().get_protection();
}
void cell::clear_value()
@ -842,64 +753,32 @@ XLNT_FUNCTION timedelta cell::get_value() const
void cell::set_border(const xlnt::border &border_)
{
d_->has_format_ = true;
auto format_copy = get_workbook().get_format(d_->format_id_);
format_copy.set_border(border_);
d_->format_id_ = get_workbook().add_format(format_copy);
get_format().set_border(border_);
}
void cell::set_fill(const xlnt::fill &fill_)
{
d_->has_format_ = true;
auto format_copy = get_workbook().get_format(d_->format_id_);
format_copy.set_fill(fill_);
d_->format_id_ = get_workbook().add_format(format_copy);
get_format().set_fill(fill_);
}
void cell::set_font(const font &font_)
{
d_->has_format_ = true;
auto format_copy = get_workbook().get_format(d_->format_id_);
format_copy.set_font(font_);
d_->format_id_ = get_workbook().add_format(format_copy);
get_format().set_font(font_);
}
void cell::set_number_format(const number_format &number_format_)
{
format new_format;
if (d_->has_format_)
{
new_format = get_workbook().get_format(d_->format_id_);
}
auto number_format_with_id = number_format_;
if (!number_format_with_id.has_id())
{
number_format_with_id.set_id(get_worksheet().next_custom_number_format_id());
}
new_format.set_number_format(number_format_with_id);
d_->has_format_ = true;
d_->format_id_ = get_workbook().add_format(new_format);
get_format().set_number_format(number_format_);
}
void cell::set_alignment(const xlnt::alignment &alignment_)
{
d_->has_format_ = true;
auto format_copy = get_workbook().get_format(d_->format_id_);
format_copy.set_alignment(alignment_);
d_->format_id_ = get_workbook().add_format(format_copy);
get_format().set_alignment(alignment_);
}
void cell::set_protection(const xlnt::protection &protection_)
{
d_->has_format_ = true;
auto format_copy = get_workbook().get_format(d_->format_id_);
format_copy.set_protection(protection_);
d_->format_id_ = get_workbook().add_format(format_copy);
get_format().set_protection(protection_);
}
template <>
@ -947,19 +826,12 @@ format &cell::get_format()
bool cell::has_format() const
{
return d_->has_format_;
return d_->format_id_.is_set();
}
void cell::set_format(const format &new_format)
{
d_->format_id_ = get_workbook().add_format(new_format);
d_->has_format_ = true;
}
void cell::set_format_id(std::size_t format_id)
{
d_->format_id_ = format_id;
d_->has_format_ = true;
d_->format_id_ = get_workbook().create_format().get_id();
}
calendar cell::get_base_date() const
@ -972,11 +844,6 @@ std::ostream &operator<<(std::ostream &stream, const xlnt::cell &cell)
return stream << cell.to_string();
}
std::size_t cell::get_format_id() const
{
return d_->format_id_;
}
void cell::guess_type_and_set_value(const std::string &value)
{
auto percentage = cast_percentage(value);
@ -1012,55 +879,37 @@ void cell::guess_type_and_set_value(const std::string &value)
void cell::clear_format()
{
d_->format_id_ = 0;
d_->has_format_ = false;
d_->format_id_.clear();
}
void cell::clear_style()
{
d_->style_id_ = 0;
d_->has_style_ = false;
d_->style_name_.clear();
}
void cell::set_style(const style &new_style)
{
d_->has_style_ = true;
if (get_workbook().has_style(new_style.get_name()))
{
d_->style_id_ = get_workbook().get_style_id(new_style.get_name());
}
else
{
d_->style_id_ = get_workbook().add_style(new_style);
}
d_->style_name_ = new_style.name();
}
void cell::set_style(const std::string &style_name)
{
d_->has_style_ = true;
if (!get_workbook().has_style(style_name))
{
throw std::runtime_error("style " + style_name + " doesn't exist in workbook");
}
d_->style_id_ = get_workbook().get_style_id(style_name);
d_->style_name_ = style_name;
}
const style &cell::get_style() const
style cell::get_style() const
{
if (!d_->has_style_)
if (!d_->style_name_)
{
throw std::runtime_error("cell has no style");
throw invalid_attribute();
}
return get_workbook().get_style_by_id(d_->style_id_);
return get_workbook().get_style(*d_->style_name_);
}
bool cell::has_style() const
{
return d_->has_style_;
return d_->style_name_;
}
} // namespace xlnt

View File

@ -34,7 +34,6 @@ comment::comment(detail::comment_impl *d) : d_(d)
comment::comment(cell parent, const std::string &text, const std::string &author) : d_(nullptr)
{
d_ = parent.get_comment().d_;
d_->text_ = text;
d_->author_ = author;
}

View File

@ -355,14 +355,14 @@ public:
auto ws = wb.create_sheet();
auto cell = ws.get_cell("A1");
xlnt::fill f = xlnt::fill::pattern(xlnt::pattern_fill::type::solid);
f.get_pattern_fill().set_foreground_color(xlnt::color::red());
cell.set_fill(f);
xlnt::fill fill(xlnt::pattern_fill()
.type(xlnt::pattern_fill_type::solid)
.foreground(xlnt::color::red()));
cell.set_fill(fill);
TS_ASSERT(cell.has_format());
TS_ASSERT(cell.get_format().fill_applied());
TS_ASSERT_EQUALS(cell.get_fill(), f);
TS_ASSERT_EQUALS(cell.get_fill(), fill);
}
void test_border()
@ -454,12 +454,12 @@ public:
TS_ASSERT_EQUALS(cell.get_style().get_number_format(), xlnt::number_format::percentage());
TS_ASSERT_EQUALS(cell.get_style(), last_style);
TS_ASSERT_THROWS(cell.set_style("doesn't exist"), std::runtime_error);
TS_ASSERT_THROWS(cell.set_style("doesn't exist"), xlnt::key_not_found);
cell.clear_style();
TS_ASSERT(!cell.has_style());
TS_ASSERT_THROWS(cell.get_style(), std::runtime_error);
TS_ASSERT_THROWS(cell.get_style(), xlnt::invalid_attribute);
}
void test_print()
@ -651,9 +651,9 @@ public:
xlnt::workbook wb;
auto cell = wb.get_active_sheet().get_cell("A1");
TS_ASSERT(!cell.has_hyperlink());
TS_ASSERT_THROWS(cell.get_hyperlink(), std::runtime_error);
TS_ASSERT_THROWS(cell.set_hyperlink("notaurl"), std::runtime_error);
TS_ASSERT_THROWS(cell.set_hyperlink(""), std::runtime_error);
TS_ASSERT_THROWS(cell.get_hyperlink(), xlnt::invalid_attribute);
TS_ASSERT_THROWS(cell.set_hyperlink("notaurl"), xlnt::invalid_parameter);
TS_ASSERT_THROWS(cell.set_hyperlink(""), xlnt::invalid_parameter);
cell.set_hyperlink("http://example.com");
TS_ASSERT(cell.has_hyperlink());
TS_ASSERT_EQUALS(cell.get_hyperlink(), "http://example.com");

View File

@ -29,64 +29,5 @@
namespace xlnt {
namespace detail {
cell_impl::cell_impl() : cell_impl(column_t(1), 1)
{
}
cell_impl::cell_impl(column_t column, row_t row) : cell_impl(nullptr, column, row)
{
}
cell_impl::cell_impl(worksheet_impl *parent, column_t column, row_t row)
: type_(cell::type::null),
parent_(parent),
column_(column),
row_(row),
value_numeric_(0),
has_hyperlink_(false),
is_merged_(false),
has_format_(false),
format_id_(0),
has_style_(false),
style_id_(0),
comment_(nullptr)
{
}
cell_impl::cell_impl(const cell_impl &rhs)
{
*this = rhs;
}
cell_impl &cell_impl::operator=(const cell_impl &rhs)
{
type_ = rhs.type_;
parent_ = rhs.parent_;
column_ = rhs.column_;
row_ = rhs.row_;
value_text_ = rhs.value_text_;
value_numeric_ = rhs.value_numeric_;
has_hyperlink_ = rhs.has_hyperlink_;
hyperlink_ = rhs.hyperlink_;
formula_ = rhs.formula_;
is_merged_ = rhs.is_merged_;
has_format_ = rhs.has_format_;
format_id_ = rhs.format_id_;
has_style_ = rhs.has_style_;
style_id_ = rhs.style_id_;
if (rhs.comment_ != nullptr)
{
comment_.reset(new comment_impl(*rhs.comment_));
}
return *this;
}
cell cell_impl::self()
{
return xlnt::cell(this);
}
} // namespace detail
} // namespace xlnt

View File

@ -22,61 +22,42 @@
// @author: see AUTHORS file
#pragma once
#include <cstdlib>
#include <cstddef>
#include <string>
#include <xlnt/cell/cell.hpp>
#include <xlnt/cell/text.hpp>
#include <xlnt/cell/comment.hpp>
#include <xlnt/cell/cell_type.hpp>
#include <xlnt/cell/index_types.hpp>
#include <xlnt/utils/exceptions.hpp>
#include <xlnt/utils/time.hpp>
#include <xlnt/packaging/relationship.hpp>
#include <xlnt/styles/number_format.hpp>
#include "comment_impl.hpp"
#include <xlnt/cell/text.hpp>
#include <xlnt/utils/optional.hpp>
namespace xlnt {
class style;
namespace detail {
struct comment_impl;
struct worksheet_impl;
struct cell_impl
{
cell_impl();
cell_impl(column_t column, row_t row);
cell_impl(worksheet_impl *parent, column_t column, row_t row);
cell_impl(const cell_impl &rhs);
cell_impl &operator=(const cell_impl &rhs);
cell self();
cell::type type_;
cell_type type_;
worksheet_impl *parent_;
column_t column_;
row_t row_;
bool is_merged_;
text value_text_;
long double value_numeric_;
std::string formula_;
optional<std::string> formula_;
bool has_hyperlink_;
std::string hyperlink_;
optional<std::string> hyperlink_;
bool is_merged_;
optional<std::size_t> format_id_;
bool has_format_;
std::size_t format_id_;
bool has_style_;
std::size_t style_id_;
std::unique_ptr<comment_impl> comment_;
optional<std::string> style_name_;
};
} // namespace detail

View File

@ -0,0 +1,430 @@
#pragma once
#include <cstddef>
#include <vector>
namespace xlnt {
const std::vector<std::uint8_t> &excel_thumbnail()
{
const auto *data = new std::vector<std::uint8_t>{
0xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x00,0x00,0x48,0x00,0x48,0x00,0x00,0xff,0xe1,0x00,0x80,0x45,0x78,0x69,0x66,0x00,0x00,0x4d,0x4d,0x00
,0x2a,0x00,0x00,0x00,0x08,0x00,0x04,0x01,0x1a,0x00,0x05,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x3e,0x01,0x1b,0x00,0x05,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x46,0x01
,0x28,0x00,0x03,0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x00,0x87,0x69,0x00,0x04,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x4e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00
,0x00,0x00,0x01,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x01,0x00,0x03,0xa0,0x01,0x00,0x03,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0xa0,0x02,0x00,0x04,0x00,0x00,0x00
,0x01,0x00,0x00,0x01,0x00,0xa0,0x03,0x00,0x04,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x9d,0x00,0x00,0x00,0x00,0xff,0xed,0x00,0x38,0x50,0x68,0x6f,0x74,0x6f,0x73,0x68
,0x6f,0x70,0x20,0x33,0x2e,0x30,0x00,0x38,0x42,0x49,0x4d,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x42,0x49,0x4d,0x04,0x25,0x00,0x00,0x00,0x00,0x00,0x10,0xd4
,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,0x7e,0xff,0xc0,0x00,0x11,0x08,0x00,0x9d,0x01,0x00,0x03,0x01,0x11,0x00,0x02,0x11,0x01,0x03
,0x11,0x01,0xff,0xc4,0x00,0x1f,0x00,0x00,0x01,0x05,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08
,0x09,0x0a,0x0b,0xff,0xc4,0x00,0xb5,0x10,0x00,0x02,0x01,0x03,0x03,0x02,0x04,0x03,0x05,0x05,0x04,0x04,0x00,0x00,0x01,0x7d,0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12
,0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,0x22,0x71,0x14,0x32,0x81,0x91,0xa1,0x08,0x23,0x42,0xb1,0xc1,0x15,0x52,0xd1,0xf0,0x24,0x33,0x62,0x72,0x82,0x09,0x0a,0x16
,0x17,0x18,0x19,0x1a,0x25,0x26,0x27,0x28,0x29,0x2a,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58,0x59
,0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98
,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4
,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xff,0xc4,0x00,0x1f,0x01,0x00
,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0xff,0xc4,0x00,0xb5,0x11
,0x00,0x02,0x01,0x02,0x04,0x04,0x03,0x04,0x07,0x05,0x04,0x04,0x00,0x01,0x02,0x77,0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71
,0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,0xa1,0xb1,0xc1,0x09,0x23,0x33,0x52,0xf0,0x15,0x62,0x72,0xd1,0x0a,0x16,0x24,0x34,0xe1,0x25,0xf1,0x17,0x18,0x19,0x1a,0x26
,0x27,0x28,0x29,0x2a,0x35,0x36,0x37,0x38,0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x63,0x64,0x65,0x66,0x67,0x68
,0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5
,0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda
,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xff,0xdb,0x00,0x43,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01
,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01
,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xff,0xdb,0x00,0x43,0x01,0x01,0x01,0x01,0x01
,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01
,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xff,0xdd,0x00,0x04
,0x00,0x20,0xff,0xda,0x00,0x0c,0x03,0x01,0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xfe,0xef,0x7c,0x33,0xe1,0x7f,0x0d,0x4f,0xe1,0xbf,0x0f,0xcf,0x3f,0x87,0xb4,0x39
,0xa6,0x9b,0x44,0xd2,0xa5,0x9a,0x69,0x74,0x8b,0x09,0x25,0x96,0x59,0x2c,0x2d,0xde,0x49,0x24,0x91,0xa1,0x2c,0xf2,0x3b,0x92,0xce,0xec,0x4b,0x33,0x12,0x49,0x24,0x93
,0x40,0x1b,0x7f,0xf0,0x89,0x78,0x57,0xfe,0x85,0xaf,0x0f,0xff,0x00,0xe0,0x9b,0x4e,0xff,0x00,0xe3,0x14,0x00,0x7f,0xc2,0x25,0xe1,0x5f,0xfa,0x16,0xbc,0x3f,0xff,0x00
,0x82,0x6d,0x3b,0xff,0x00,0x8c,0x50,0x01,0xff,0x00,0x08,0x97,0x85,0x7f,0xe8,0x5a,0xf0,0xff,0x00,0xfe,0x09,0xb4,0xef,0xfe,0x31,0x40,0x07,0xfc,0x22,0x5e,0x15,0xff
,0x00,0xa1,0x6b,0xc3,0xff,0x00,0xf8,0x26,0xd3,0xbf,0xf8,0xc5,0x00,0x1f,0xf0,0x89,0x78,0x57,0xfe,0x85,0xaf,0x0f,0xff,0x00,0xe0,0x9b,0x4e,0xff,0x00,0xe3,0x14,0x00
,0x7f,0xc2,0x25,0xe1,0x5f,0xfa,0x16,0xbc,0x3f,0xff,0x00,0x82,0x6d,0x3b,0xff,0x00,0x8c,0x50,0x01,0xff,0x00,0x08,0x97,0x85,0x7f,0xe8,0x5a,0xf0,0xff,0x00,0xfe,0x09
,0xb4,0xef,0xfe,0x31,0x40,0x07,0xfc,0x22,0x5e,0x15,0xff,0x00,0xa1,0x6b,0xc3,0xff,0x00,0xf8,0x26,0xd3,0xbf,0xf8,0xc5,0x00,0x1f,0xf0,0x89,0x78,0x57,0xfe,0x85,0xaf
,0x0f,0xff,0x00,0xe0,0x9b,0x4e,0xff,0x00,0xe3,0x14,0x00,0x7f,0xc2,0x25,0xe1,0x5f,0xfa,0x16,0xbc,0x3f,0xff,0x00,0x82,0x6d,0x3b,0xff,0x00,0x8c,0x50,0x01,0xff,0x00
,0x08,0x97,0x85,0x7f,0xe8,0x5a,0xf0,0xff,0x00,0xfe,0x09,0xb4,0xef,0xfe,0x31,0x40,0x07,0xfc,0x22,0x5e,0x15,0xff,0x00,0xa1,0x6b,0xc3,0xff,0x00,0xf8,0x26,0xd3,0xbf
,0xf8,0xc5,0x00,0x1f,0xf0,0x89,0x78,0x57,0xfe,0x85,0xaf,0x0f,0xff,0x00,0xe0,0x9b,0x4e,0xff,0x00,0xe3,0x14,0x00,0x7f,0xc2,0x25,0xe1,0x5f,0xfa,0x16,0xbc,0x3f,0xff
,0x00,0x82,0x6d,0x3b,0xff,0x00,0x8c,0x50,0x01,0xff,0x00,0x08,0x97,0x85,0x7f,0xe8,0x5a,0xf0,0xff,0x00,0xfe,0x09,0xb4,0xef,0xfe,0x31,0x40,0x07,0xfc,0x22,0x5e,0x15
,0xff,0x00,0xa1,0x6b,0xc3,0xff,0x00,0xf8,0x26,0xd3,0xbf,0xf8,0xc5,0x00,0x1f,0xf0,0x89,0x78,0x57,0xfe,0x85,0xaf,0x0f,0xff,0x00,0xe0,0x9b,0x4e,0xff,0x00,0xe3,0x14
,0x00,0x7f,0xc2,0x25,0xe1,0x5f,0xfa,0x16,0xbc,0x3f,0xff,0x00,0x82,0x6d,0x3b,0xff,0x00,0x8c,0x50,0x01,0xff,0x00,0x08,0x97,0x85,0x7f,0xe8,0x5a,0xf0,0xff,0x00,0xfe
,0x09,0xb4,0xef,0xfe,0x31,0x40,0x07,0xfc,0x22,0x5e,0x15,0xff,0x00,0xa1,0x6b,0xc3,0xff,0x00,0xf8,0x26,0xd3,0xbf,0xf8,0xc5,0x00,0x1f,0xf0,0x89,0x78,0x57,0xfe,0x85
,0xaf,0x0f,0xff,0x00,0xe0,0x9b,0x4e,0xff,0x00,0xe3,0x14,0x00,0x7f,0xc2,0x25,0xe1,0x5f,0xfa,0x16,0xbc,0x3f,0xff,0x00,0x82,0x6d,0x3b,0xff,0x00,0x8c,0x50,0x01,0xff
,0x00,0x08,0x97,0x85,0x7f,0xe8,0x5a,0xf0,0xff,0x00,0xfe,0x09,0xb4,0xef,0xfe,0x31,0x40,0x07,0xfc,0x22,0x5e,0x15,0xff,0x00,0xa1,0x6b,0xc3,0xff,0x00,0xf8,0x26,0xd3
,0xbf,0xf8,0xc5,0x00,0x1f,0xf0,0x89,0x78,0x57,0xfe,0x85,0xaf,0x0f,0xff,0x00,0xe0,0x9b,0x4e,0xff,0x00,0xe3,0x14,0x00,0x7f,0xc2,0x25,0xe1,0x5f,0xfa,0x16,0xbc,0x3f
,0xff,0x00,0x82,0x6d,0x3b,0xff,0x00,0x8c,0x50,0x01,0xff,0x00,0x08,0x97,0x85,0x7f,0xe8,0x5a,0xf0,0xff,0x00,0xfe,0x09,0xb4,0xef,0xfe,0x31,0x40,0x07,0xfc,0x22,0x5e
,0x15,0xff,0x00,0xa1,0x6b,0xc3,0xff,0x00,0xf8,0x26,0xd3,0xbf,0xf8,0xc5,0x00,0x1f,0xf0,0x89,0x78,0x57,0xfe,0x85,0xaf,0x0f,0xff,0x00,0xe0,0x9b,0x4e,0xff,0x00,0xe3
,0x14,0x00,0x7f,0xc2,0x25,0xe1,0x5f,0xfa,0x16,0xbc,0x3f,0xff,0x00,0x82,0x6d,0x3b,0xff,0x00,0x8c,0x50,0x01,0xff,0x00,0x08,0x97,0x85,0x7f,0xe8,0x5a,0xf0,0xff,0x00
,0xfe,0x09,0xb4,0xef,0xfe,0x31,0x40,0x1f,0xff,0xd0,0xfe,0xf6,0x7c,0x29,0xff,0x00,0x22,0xbf,0x86,0xff,0x00,0xec,0x01,0xa3,0xff,0x00,0xe9,0xba,0xda,0x80,0x37,0xe8
,0x00,0xa0,0x02,0x80,0x0a,0x00,0x28,0x00,0xa0,0x02,0x80,0x0a,0x00,0x28,0x00,0xa0,0x02,0x80,0x0a,0x00,0x28,0x00,0xa0,0x02,0x80,0x0a,0x00,0x28,0x00,0xa0,0x02,0x80
,0x0a,0x00,0x28,0x00,0xa0,0x02,0x80,0x0a,0x00,0x28,0x00,0xa0,0x02,0x80,0x0a,0x00,0x28,0x00,0xa0,0x02,0x80,0x3f,0xff,0xd1,0xfe,0xf6,0x7c,0x29,0xff,0x00,0x22,0xbf
,0x86,0xff,0x00,0xec,0x01,0xa3,0xff,0x00,0xe9,0xba,0xda,0x80,0x37,0xe8,0x03,0xc8,0xfc,0x25,0xe1,0x3f,0x0b,0x6a,0xcf,0xe2,0xeb,0xcd,0x57,0xc3,0x5e,0x1f,0xd4,0xee
,0xdb,0xc7,0x5e,0x28,0x46,0xba,0xd4,0x34,0x6d,0x3a,0xf2,0xe0,0xa2,0xde,0x82,0xa8,0x67,0xb8,0x82,0x49,0x0a,0xa9,0x24,0xaa,0x96,0xc0,0xc9,0xc0,0x19,0x6d,0xc0,0x1d
,0x7f,0xfc,0x20,0x1e,0x04,0xff,0x00,0xa1,0x2b,0xc2,0x5f,0xf8,0x4d,0xe8,0xff,0x00,0xfc,0x89,0x40,0x07,0xfc,0x20,0x1e,0x04,0xff,0x00,0xa1,0x2b,0xc2,0x5f,0xf8,0x4d
,0xe8,0xff,0x00,0xfc,0x89,0x40,0x07,0xfc,0x20,0x1e,0x04,0xff,0x00,0xa1,0x2b,0xc2,0x5f,0xf8,0x4d,0xe8,0xff,0x00,0xfc,0x89,0x40,0x07,0xfc,0x20,0x1e,0x04,0xff,0x00
,0xa1,0x2b,0xc2,0x5f,0xf8,0x4d,0xe8,0xff,0x00,0xfc,0x89,0x40,0x07,0xfc,0x20,0x1e,0x04,0xff,0x00,0xa1,0x2b,0xc2,0x5f,0xf8,0x4d,0xe8,0xff,0x00,0xfc,0x89,0x40,0x1c
,0xb7,0x83,0xfc,0x11,0xe0,0xbb,0x9d,0x26,0xee,0x4b,0x8f,0x08,0x78,0x5e,0x79,0x17,0xc5,0x3e,0x39,0x81,0x5e,0x6f,0x0f,0xe9,0x52,0xba,0xc1,0x6b,0xe3,0x5f,0x10,0x5b
,0x5a,0xc2,0x19,0xed,0x58,0x88,0xad,0xad,0xa1,0x8a,0xde,0x08,0xc1,0xd9,0x0c,0x11,0x47,0x14,0x61,0x51,0x11,0x54,0x03,0xa9,0xff,0x00,0x84,0x03,0xc0,0x9f,0xf4,0x25
,0x78,0x4b,0xff,0x00,0x09,0xbd,0x1f,0xff,0x00,0x91,0x28,0x00,0xff,0x00,0x84,0x03,0xc0,0x9f,0xf4,0x25,0x78,0x4b,0xff,0x00,0x09,0xbd,0x1f,0xff,0x00,0x91,0x28,0x00
,0xff,0x00,0x84,0x03,0xc0,0x9f,0xf4,0x25,0x78,0x4b,0xff,0x00,0x09,0xbd,0x1f,0xff,0x00,0x91,0x28,0x00,0xff,0x00,0x84,0x03,0xc0,0x9f,0xf4,0x25,0x78,0x4b,0xff,0x00
,0x09,0xbd,0x1f,0xff,0x00,0x91,0x28,0x00,0xff,0x00,0x84,0x03,0xc0,0x9f,0xf4,0x25,0x78,0x4b,0xff,0x00,0x09,0xbd,0x1f,0xff,0x00,0x91,0x28,0x03,0x8b,0xf8,0x79,0xe0
,0xaf,0x06,0xde,0x78,0x3f,0x48,0xb9,0xbc,0xf0,0x97,0x86,0x6e,0xae,0x24,0x3a,0x8f,0x99,0x3d,0xce,0x83,0xa5,0xcf,0x34,0x9b,0x35,0x5b,0xe8,0xd3,0x7c,0xb2,0xda,0xb3
,0xb6,0xc8,0xd1,0x51,0x77,0x13,0xb5,0x15,0x54,0x70,0xa2,0x80,0x3b,0x4f,0xf8,0x40,0x3c,0x09,0xff,0x00,0x42,0x57,0x84,0xbf,0xf0,0x9b,0xd1,0xff,0x00,0xf9,0x12,0x80
,0x0f,0xf8,0x40,0x3c,0x09,0xff,0x00,0x42,0x57,0x84,0xbf,0xf0,0x9b,0xd1,0xff,0x00,0xf9,0x12,0x80,0x0f,0xf8,0x40,0x3c,0x09,0xff,0x00,0x42,0x57,0x84,0xbf,0xf0,0x9b
,0xd1,0xff,0x00,0xf9,0x12,0x80,0x0f,0xf8,0x40,0x3c,0x09,0xff,0x00,0x42,0x57,0x84,0xbf,0xf0,0x9b,0xd1,0xff,0x00,0xf9,0x12,0x80,0x0f,0xf8,0x40,0x3c,0x09,0xff,0x00
,0x42,0x57,0x84,0xbf,0xf0,0x9b,0xd1,0xff,0x00,0xf9,0x12,0x80,0x39,0x6f,0x03,0x78,0x23,0xc1,0x77,0x5e,0x0a,0xf0,0x7d,0xd5,0xd7,0x84,0x3c,0x2f,0x73,0x73,0x73,0xe1
,0x6f,0x0f,0xcf,0x71,0x71,0x3f,0x87,0xf4,0xa9,0xa7,0x9e,0x79,0xb4,0x9b,0x49,0x25,0x9a,0x69,0x64,0xb5,0x69,0x25,0x96,0x59,0x19,0x9e,0x49,0x1d,0x99,0xdd,0xd8,0xb3
,0x12,0xc4,0x9a,0x00,0xea,0x7f,0xe1,0x00,0xf0,0x27,0xfd,0x09,0x5e,0x12,0xff,0x00,0xc2,0x6f,0x47,0xff,0x00,0xe4,0x4a,0x00,0x3f,0xe1,0x00,0xf0,0x27,0xfd,0x09,0x5e
,0x12,0xff,0x00,0xc2,0x6f,0x47,0xff,0x00,0xe4,0x4a,0x00,0x3f,0xe1,0x00,0xf0,0x27,0xfd,0x09,0x5e,0x12,0xff,0x00,0xc2,0x6f,0x47,0xff,0x00,0xe4,0x4a,0x00,0x3f,0xe1
,0x00,0xf0,0x27,0xfd,0x09,0x5e,0x12,0xff,0x00,0xc2,0x6f,0x47,0xff,0x00,0xe4,0x4a,0x00,0xcb,0xd7,0x3c,0x09,0xe0,0x88,0xb4,0x5d,0x62,0x58,0xbc,0x1b,0xe1,0x58,0xe5
,0x8b,0x4b,0xd4,0x24,0x8e,0x48,0xfc,0x3d,0xa4,0x24,0x91,0xc8,0x96,0x92,0xb2,0x3a,0x3a,0xda,0x86,0x47,0x46,0x01,0x95,0x94,0xe5,0x48,0xc8,0xc1,0x14,0x01,0x53,0xc2
,0x9e,0x06,0xf0,0x4d,0xc7,0x85,0xfc,0x37,0x3c,0xfe,0x0f,0xf0,0xb4,0xd3,0xcf,0xa0,0x68,0xf3,0x4d,0x34,0xde,0x1f,0xd2,0x64,0x96,0x69,0x64,0xd3,0xad,0x9e,0x49,0x65
,0x91,0xed,0x4b,0xc9,0x24,0x8e,0xc5,0xdd,0xd8,0x96,0x66,0x62,0xcc,0x49,0x39,0xa0,0x0d,0xff,0x00,0xf8,0x40,0x3c,0x09,0xff,0x00,0x42,0x57,0x84,0xbf,0xf0,0x9b,0xd1
,0xff,0x00,0xf9,0x12,0x80,0x0f,0xf8,0x40,0x3c,0x09,0xff,0x00,0x42,0x57,0x84,0xbf,0xf0,0x9b,0xd1,0xff,0x00,0xf9,0x12,0x80,0x0f,0xf8,0x40,0x3c,0x09,0xff,0x00,0x42
,0x57,0x84,0xbf,0xf0,0x9b,0xd1,0xff,0x00,0xf9,0x12,0x80,0x0f,0xf8,0x40,0x3c,0x09,0xff,0x00,0x42,0x57,0x84,0xbf,0xf0,0x9b,0xd1,0xff,0x00,0xf9,0x12,0x80,0x39,0x8f
,0x1b,0xf8,0x23,0xc1,0x76,0x9e,0x0b,0xf1,0x75,0xd5,0xaf,0x84,0x7c,0x31,0x6d,0x73,0x6d,0xe1,0x8d,0x7e,0xe2,0xde,0xe2,0xdf,0x40,0xd2,0xa1,0x9e,0xde,0x78,0x74,0xab
,0xb9,0x21,0x9a,0x19,0xa3,0xb5,0x59,0x22,0x9a,0x29,0x15,0x64,0x8e,0x48,0xd9,0x5d,0x1d,0x55,0x94,0x86,0x00,0xd0,0x07,0xff,0xd2,0xfe,0xf6,0x7c,0x29,0xff,0x00,0x22
,0xbf,0x86,0xff,0x00,0xec,0x01,0xa3,0xff,0x00,0xe9,0xba,0xda,0x80,0x37,0xe8,0x03,0xc6,0xbc,0x2e,0xfe,0x35,0x12,0xf8,0xb8,0x68,0x96,0xfe,0x16,0x92,0xc7,0xfe,0x13
,0x9f,0x13,0xed,0x6d,0x52,0xf3,0x56,0x8a,0xec,0xc9,0xf6,0xef,0x9f,0x72,0x5a,0x59,0x4d,0x08,0x4c,0x6d,0xdb,0x87,0x2d,0xd7,0x38,0xc0,0xa0,0x0e,0xaf,0xcc,0xf8,0x99
,0xff,0x00,0x3e,0x9e,0x05,0xff,0x00,0xc1,0x8e,0xbf,0xff,0x00,0xca,0xda,0x00,0x3c,0xcf,0x89,0x9f,0xf3,0xe9,0xe0,0x5f,0xfc,0x18,0xeb,0xff,0x00,0xfc,0xad,0xa0,0x03
,0xcc,0xf8,0x99,0xff,0x00,0x3e,0x9e,0x05,0xff,0x00,0xc1,0x8e,0xbf,0xff,0x00,0xca,0xda,0x00,0x3c,0xcf,0x89,0x9f,0xf3,0xe9,0xe0,0x5f,0xfc,0x18,0xeb,0xff,0x00,0xfc
,0xad,0xa0,0x03,0xcc,0xf8,0x99,0xff,0x00,0x3e,0x9e,0x05,0xff,0x00,0xc1,0x8e,0xbf,0xff,0x00,0xca,0xda,0x00,0xe6,0x3c,0x22,0xff,0x00,0x10,0xc6,0x95,0x77,0xf6,0x5b
,0x5f,0x06,0x34,0x5f,0xf0,0x93,0xf8,0xdb,0x71,0xb8,0xbe,0xd7,0x16,0x4f,0xb4,0x9f,0x19,0xeb,0xe6,0xf0,0x28,0x8f,0x4f,0x75,0x30,0x2d,0xdf,0x9e,0xb6,0xcc,0x48,0x91
,0xed,0x84,0x4f,0x2a,0xa4,0xac,0xe8,0xa0,0x1d,0x3f,0x99,0xf1,0x33,0xfe,0x7d,0x3c,0x0b,0xff,0x00,0x83,0x1d,0x7f,0xff,0x00,0x95,0xb4,0x00,0x79,0x9f,0x13,0x3f,0xe7
,0xd3,0xc0,0xbf,0xf8,0x31,0xd7,0xff,0x00,0xf9,0x5b,0x40,0x07,0x99,0xf1,0x33,0xfe,0x7d,0x3c,0x0b,0xff,0x00,0x83,0x1d,0x7f,0xff,0x00,0x95,0xb4,0x00,0x79,0x9f,0x13
,0x3f,0xe7,0xd3,0xc0,0xbf,0xf8,0x31,0xd7,0xff,0x00,0xf9,0x5b,0x40,0x07,0x99,0xf1,0x33,0xfe,0x7d,0x3c,0x0b,0xff,0x00,0x83,0x1d,0x7f,0xff,0x00,0x95,0xb4,0x01,0xc6
,0xfc,0x3f,0x7f,0x88,0x03,0xc2,0x3a,0x4f,0xd8,0x2d,0x7c,0x1c,0xd6,0x99,0xd4,0x3c,0xa3,0x77,0x7d,0xad,0xa5,0xc7,0xfc,0x85,0x2f,0xbc,0xcf,0x31,0x61,0xd3,0xde,0x31
,0x89,0x77,0x84,0xda,0xc7,0x29,0xb0,0xb6,0x18,0x95,0x50,0x0e,0xcb,0xcc,0xf8,0x99,0xff,0x00,0x3e,0x9e,0x05,0xff,0x00,0xc1,0x8e,0xbf,0xff,0x00,0xca,0xda,0x00,0x3c
,0xcf,0x89,0x9f,0xf3,0xe9,0xe0,0x5f,0xfc,0x18,0xeb,0xff,0x00,0xfc,0xad,0xa0,0x03,0xcc,0xf8,0x99,0xff,0x00,0x3e,0x9e,0x05,0xff,0x00,0xc1,0x8e,0xbf,0xff,0x00,0xca
,0xda,0x00,0x3c,0xcf,0x89,0x9f,0xf3,0xe9,0xe0,0x5f,0xfc,0x18,0xeb,0xff,0x00,0xfc,0xad,0xa0,0x03,0xcc,0xf8,0x99,0xff,0x00,0x3e,0x9e,0x05,0xff,0x00,0xc1,0x8e,0xbf
,0xff,0x00,0xca,0xda,0x00,0xe6,0x3c,0x12,0xff,0x00,0x10,0xc7,0x83,0x3c,0x22,0x2c,0xed,0x7c,0x18,0xd6,0x83,0xc3,0x1a,0x07,0xd9,0x5a,0xe6,0xfb,0x5c,0x4b,0x96,0xb6
,0xfe,0xca,0xb4,0xf2,0x0d,0xc2,0x45,0xa7,0xbc,0x4b,0x39,0x8b,0x69,0x95,0x63,0x77,0x8d,0x64,0xdc,0x11,0x99,0x40,0x34,0x01,0xd3,0xf9,0x9f,0x13,0x3f,0xe7,0xd3,0xc0
,0xbf,0xf8,0x31,0xd7,0xff,0x00,0xf9,0x5b,0x40,0x07,0x99,0xf1,0x33,0xfe,0x7d,0x3c,0x0b,0xff,0x00,0x83,0x1d,0x7f,0xff,0x00,0x95,0xb4,0x00,0x79,0x9f,0x13,0x3f,0xe7
,0xd3,0xc0,0xbf,0xf8,0x31,0xd7,0xff,0x00,0xf9,0x5b,0x40,0x07,0x99,0xf1,0x33,0xfe,0x7d,0x3c,0x0b,0xff,0x00,0x83,0x1d,0x7f,0xff,0x00,0x95,0xb4,0x01,0x97,0xad,0xbf
,0xc4,0x7f,0xec,0x5d,0x5f,0xce,0xb4,0xf0,0x40,0x87,0xfb,0x2e,0xff,0x00,0xcd,0x31,0x6a,0x1a,0xf1,0x90,0x47,0xf6,0x49,0x77,0x98,0xc3,0x69,0xc1,0x4b,0xed,0xce,0xc0
,0xc4,0x29,0x6c,0x64,0x81,0x93,0x40,0x15,0x7c,0x2c,0xff,0x00,0x11,0x7f,0xe1,0x18,0xf0,0xe7,0xd9,0x6d,0x7c,0x14,0x6d,0xbf,0xb0,0x74,0x8f,0xb3,0x99,0xef,0xf5,0xc5
,0x9c,0xc1,0xfd,0x9f,0x6f,0xe5,0x19,0x96,0x3d,0x39,0xa3,0x12,0x98,0xf6,0xf9,0x82,0x36,0x64,0x0f,0x90,0xa4,0xa8,0x06,0x80,0x37,0xbc,0xcf,0x89,0x9f,0xf3,0xe9,0xe0
,0x5f,0xfc,0x18,0xeb,0xff,0x00,0xfc,0xad,0xa0,0x03,0xcc,0xf8,0x99,0xff,0x00,0x3e,0x9e,0x05,0xff,0x00,0xc1,0x8e,0xbf,0xff,0x00,0xca,0xda,0x00,0x3c,0xcf,0x89,0x9f
,0xf3,0xe9,0xe0,0x5f,0xfc,0x18,0xeb,0xff,0x00,0xfc,0xad,0xa0,0x03,0xcc,0xf8,0x99,0xff,0x00,0x3e,0x9e,0x05,0xff,0x00,0xc1,0x8e,0xbf,0xff,0x00,0xca,0xda,0x00,0xe6
,0x7c,0x6a,0xff,0x00,0x10,0xcf,0x83,0x7c,0x5a,0x2f,0x2d,0x7c,0x18,0xb6,0x67,0xc3,0x3a,0xf7,0xda,0xda,0xd6,0xfb,0x5c,0x7b,0x95,0xb6,0xfe,0xca,0xbb,0xf3,0xcd,0xba
,0x4b,0xa7,0xa4,0x4f,0x38,0x8b,0x71,0x89,0x64,0x74,0x8d,0xa4,0xda,0x1d,0x95,0x49,0x34,0x01,0xff,0xd3,0xfe,0xf6,0x7c,0x29,0xff,0x00,0x22,0xbf,0x86,0xff,0x00,0xec
,0x01,0xa3,0xff,0x00,0xe9,0xba,0xda,0x80,0x37,0xe8,0x03,0xc9,0xfc,0x21,0xe2,0x7f,0x0d,0xe9,0x6d,0xe2,0xdb,0x5d,0x4b,0xc4,0x3a,0x1e,0x9d,0x74,0x3c,0x75,0xe2,0x87
,0x36,0xd7,0xda,0xb5,0x85,0xa4,0xe1,0x1a,0xf4,0x6d,0x63,0x0d,0xc4,0xf1,0xc8,0x14,0x95,0x21,0x58,0xae,0x0e,0x0e,0x09,0xc1,0xda,0x01,0xd8,0x7f,0xc2,0x71,0xe0,0xbf
,0xfa,0x1b,0xfc,0x2f,0xff,0x00,0x85,0x06,0x93,0xff,0x00,0xc9,0x74,0x00,0x7f,0xc2,0x71,0xe0,0xbf,0xfa,0x1b,0xfc,0x2f,0xff,0x00,0x85,0x06,0x93,0xff,0x00,0xc9,0x74
,0x00,0x7f,0xc2,0x71,0xe0,0xbf,0xfa,0x1b,0xfc,0x2f,0xff,0x00,0x85,0x06,0x93,0xff,0x00,0xc9,0x74,0x00,0x7f,0xc2,0x71,0xe0,0xbf,0xfa,0x1b,0xfc,0x2f,0xff,0x00,0x85
,0x06,0x93,0xff,0x00,0xc9,0x74,0x00,0x7f,0xc2,0x71,0xe0,0xbf,0xfa,0x1b,0xfc,0x2f,0xff,0x00,0x85,0x06,0x93,0xff,0x00,0xc9,0x74,0x01,0xcb,0x78,0x3b,0xc6,0x3e,0x11
,0xb7,0xd2,0x6e,0xe3,0x9f,0xc5,0x3e,0x1c,0x81,0xdb,0xc5,0x3e,0x39,0x9d,0x52,0x6d,0x73,0x4b,0x8d,0xda,0x1b,0x9f,0x1b,0x78,0x86,0xe6,0xda,0x60,0xaf,0x74,0xa4,0xc5
,0x71,0x6f,0x2c,0x53,0xc1,0x20,0x1b,0x25,0x86,0x48,0xe5,0x8c,0xb2,0x3a,0xb3,0x00,0x75,0x3f,0xf0,0x9c,0x78,0x2f,0xfe,0x86,0xff,0x00,0x0b,0xff,0x00,0xe1,0x41,0xa4
,0xff,0x00,0xf2,0x5d,0x00,0x1f,0xf0,0x9c,0x78,0x2f,0xfe,0x86,0xff,0x00,0x0b,0xff,0x00,0xe1,0x41,0xa4,0xff,0x00,0xf2,0x5d,0x00,0x1f,0xf0,0x9c,0x78,0x2f,0xfe,0x86
,0xff,0x00,0x0b,0xff,0x00,0xe1,0x41,0xa4,0xff,0x00,0xf2,0x5d,0x00,0x1f,0xf0,0x9c,0x78,0x2f,0xfe,0x86,0xff,0x00,0x0b,0xff,0x00,0xe1,0x41,0xa4,0xff,0x00,0xf2,0x5d
,0x00,0x1f,0xf0,0x9c,0x78,0x2f,0xfe,0x86,0xff,0x00,0x0b,0xff,0x00,0xe1,0x41,0xa4,0xff,0x00,0xf2,0x5d,0x00,0x71,0x5f,0x0e,0xfc,0x5f,0xe1,0x3b,0x4f,0x07,0xe9,0x16
,0xf7,0x5e,0x28,0xf0,0xed,0xb4,0xf1,0x9d,0x47,0x7c,0x17,0x1a,0xde,0x99,0x0c,0xc9,0xbf,0x55,0xbe,0x74,0xdf,0x14,0x97,0x2a,0xeb,0xb9,0x19,0x5d,0x72,0xa3,0x72,0x30
,0x61,0x95,0x60,0x68,0x03,0xb5,0xff,0x00,0x84,0xe3,0xc1,0x7f,0xf4,0x37,0xf8,0x5f,0xff,0x00,0x0a,0x0d,0x27,0xff,0x00,0x92,0xe8,0x00,0xff,0x00,0x84,0xe3,0xc1,0x7f
,0xf4,0x37,0xf8,0x5f,0xff,0x00,0x0a,0x0d,0x27,0xff,0x00,0x92,0xe8,0x00,0xff,0x00,0x84,0xe3,0xc1,0x7f,0xf4,0x37,0xf8,0x5f,0xff,0x00,0x0a,0x0d,0x27,0xff,0x00,0x92
,0xe8,0x00,0xff,0x00,0x84,0xe3,0xc1,0x7f,0xf4,0x37,0xf8,0x5f,0xff,0x00,0x0a,0x0d,0x27,0xff,0x00,0x92,0xe8,0x00,0xff,0x00,0x84,0xe3,0xc1,0x7f,0xf4,0x37,0xf8,0x5f
,0xff,0x00,0x0a,0x0d,0x27,0xff,0x00,0x92,0xe8,0x03,0x96,0xf0,0x37,0x8c,0x7c,0x23,0x6d,0xe0,0x9f,0x07,0xdb,0x5c,0xf8,0xa7,0xc3,0x96,0xf7,0x16,0xfe,0x16,0xf0,0xfc
,0x13,0xc1,0x3e,0xb9,0xa5,0xc5,0x34,0x13,0x45,0xa4,0xda,0x24,0xb0,0xcd,0x13,0xdd,0x2b,0xc7,0x2c,0x6e,0xac,0x92,0x46,0xea,0xae,0x8e,0xa5,0x58,0x02,0x08,0xa0,0x0e
,0xa7,0xfe,0x13,0x8f,0x05,0xff,0x00,0xd0,0xdf,0xe1,0x7f,0xfc,0x28,0x34,0x9f,0xfe,0x4b,0xa0,0x03,0xfe,0x13,0x8f,0x05,0xff,0x00,0xd0,0xdf,0xe1,0x7f,0xfc,0x28,0x34
,0x9f,0xfe,0x4b,0xa0,0x03,0xfe,0x13,0x8f,0x05,0xff,0x00,0xd0,0xdf,0xe1,0x7f,0xfc,0x28,0x34,0x9f,0xfe,0x4b,0xa0,0x03,0xfe,0x13,0x8f,0x05,0xff,0x00,0xd0,0xdf,0xe1
,0x7f,0xfc,0x28,0x34,0x9f,0xfe,0x4b,0xa0,0x0c,0xad,0x77,0xc6,0x9e,0x0e,0x93,0x44,0xd6,0x23,0x8f,0xc5,0x9e,0x19,0x92,0x49,0x34,0xad,0x41,0x11,0x13,0x5e,0xd2,0x99
,0xdd,0xda,0xd2,0x65,0x54,0x45,0x5b,0xa2,0xcc,0xcc,0xc4,0x05,0x55,0x04,0x92,0x70,0x01,0x27,0x14,0x01,0x57,0xc2,0x7e,0x32,0xf0,0x84,0x1e,0x16,0xf0,0xd4,0x13,0x78
,0xaf,0xc3,0x70,0xcd,0x0e,0x81,0xa3,0x45,0x34,0x32,0xeb,0xba,0x5c,0x72,0xc5,0x2c,0x7a,0x75,0xb2,0x49,0x1c,0x91,0xbd,0xd0,0x74,0x91,0x18,0x15,0x74,0x60,0x19,0x58
,0x10,0xc0,0x11,0x8a,0x00,0xdf,0xff,0x00,0x84,0xe3,0xc1,0x7f,0xf4,0x37,0xf8,0x5f,0xff,0x00,0x0a,0x0d,0x27,0xff,0x00,0x92,0xe8,0x00,0xff,0x00,0x84,0xe3,0xc1,0x7f
,0xf4,0x37,0xf8,0x5f,0xff,0x00,0x0a,0x0d,0x27,0xff,0x00,0x92,0xe8,0x00,0xff,0x00,0x84,0xe3,0xc1,0x7f,0xf4,0x37,0xf8,0x5f,0xff,0x00,0x0a,0x0d,0x27,0xff,0x00,0x92
,0xe8,0x00,0xff,0x00,0x84,0xe3,0xc1,0x7f,0xf4,0x37,0xf8,0x5f,0xff,0x00,0x0a,0x0d,0x27,0xff,0x00,0x92,0xe8,0x03,0x97,0xf1,0xc7,0x8c,0x7c,0x23,0x73,0xe0,0xbf,0x17
,0xdb,0x5b,0x78,0xa7,0xc3,0x97,0x17,0x17,0x1e,0x17,0xf1,0x04,0x10,0x41,0x06,0xb9,0xa6,0x4b,0x34,0xf3,0x4b,0xa4,0xdd,0xc7,0x14,0x30,0xc5,0x1d,0xd3,0x49,0x24,0xb2
,0x3b,0x2a,0x47,0x1a,0x2b,0x3b,0xbb,0x05,0x50,0x58,0x81,0x40,0x1f,0xff,0xd4,0xfe,0xf6,0x7c,0x29,0xff,0x00,0x22,0xbf,0x86,0xff,0x00,0xec,0x01,0xa3,0xff,0x00,0xe9
,0xba,0xda,0x80,0x37,0xe8,0x03,0xce,0x7c,0x11,0x63,0x65,0x70,0x9e,0x2c,0x92,0xe2,0xce,0xd6,0x79,0x3f,0xe1,0x3b,0xf1,0x4a,0xef,0x9a,0xde,0x29,0x1f,0x68,0xbd,0x18
,0x1b,0x9d,0x58,0xe0,0x64,0xe0,0x67,0x8f,0x7f,0xe1,0x00,0xed,0xff,0x00,0xb2,0xb4,0xbf,0xfa,0x06,0xd8,0x7f,0xe0,0x24,0x1f,0xfc,0x6e,0x80,0x0f,0xec,0xad,0x2f,0xfe
,0x81,0xb6,0x1f,0xf8,0x09,0x07,0xff,0x00,0x1b,0xa0,0x03,0xfb,0x2b,0x4b,0xff,0x00,0xa0,0x6d,0x87,0xfe,0x02,0x41,0xff,0x00,0xc6,0xe8,0x00,0xfe,0xca,0xd2,0xff,0x00
,0xe8,0x1b,0x61,0xff,0x00,0x80,0x90,0x7f,0xf1,0xba,0x00,0x3f,0xb2,0xb4,0xbf,0xfa,0x06,0xd8,0x7f,0xe0,0x24,0x1f,0xfc,0x6e,0x80,0x39,0x3f,0x05,0xe9,0xba,0x6b,0xe8
,0xf7,0x85,0xf4,0xfb,0x26,0x23,0xc5,0x9e,0x3d,0x50,0x5a,0xd6,0x12,0x42,0xa7,0x8e,0xbc,0x46,0x88,0xa0,0x94,0x27,0x6a,0x22,0xaa,0x28,0xe8,0xaa,0xa1,0x46,0x00,0xc5
,0x00,0x75,0x9f,0xd9,0x5a,0x5f,0xfd,0x03,0x6c,0x3f,0xf0,0x12,0x0f,0xfe,0x37,0x40,0x07,0xf6,0x56,0x97,0xff,0x00,0x40,0xdb,0x0f,0xfc,0x04,0x83,0xff,0x00,0x8d,0xd0
,0x01,0xfd,0x95,0xa5,0xff,0x00,0xd0,0x36,0xc3,0xff,0x00,0x01,0x20,0xff,0x00,0xe3,0x74,0x00,0x7f,0x65,0x69,0x7f,0xf4,0x0d,0xb0,0xff,0x00,0xc0,0x48,0x3f,0xf8,0xdd
,0x00,0x1f,0xd9,0x5a,0x5f,0xfd,0x03,0x6c,0x3f,0xf0,0x12,0x0f,0xfe,0x37,0x40,0x1c,0x37,0xc3,0x6d,0x37,0x4e,0x93,0xc1,0x7a,0x33,0xc9,0x61,0x65,0x23,0x93,0xa9,0x65
,0xde,0xd6,0x16,0x63,0x8d,0x5e,0xfc,0x0c,0x92,0x84,0x9c,0x00,0x00,0xc9,0xe0,0x00,0x38,0xa0,0x0e,0xe7,0xfb,0x2b,0x4b,0xff,0x00,0xa0,0x6d,0x87,0xfe,0x02,0x41,0xff
,0x00,0xc6,0xe8,0x00,0xfe,0xca,0xd2,0xff,0x00,0xe8,0x1b,0x61,0xff,0x00,0x80,0x90,0x7f,0xf1,0xba,0x00,0x3f,0xb2,0xb4,0xbf,0xfa,0x06,0xd8,0x7f,0xe0,0x24,0x1f,0xfc
,0x6e,0x80,0x0f,0xec,0xad,0x2f,0xfe,0x81,0xb6,0x1f,0xf8,0x09,0x07,0xff,0x00,0x1b,0xa0,0x03,0xfb,0x2b,0x4b,0xff,0x00,0xa0,0x6d,0x87,0xfe,0x02,0x41,0xff,0x00,0xc6
,0xe8,0x03,0x93,0xf0,0x16,0x9b,0xa6,0xbf,0x81,0x7c,0x16,0xef,0xa7,0xd9,0x3b,0xbf,0x84,0xfc,0x38,0xce,0xed,0x6b,0x0b,0x33,0xb3,0x68,0xf6,0x65,0x99,0x98,0xa1,0x25
,0x98,0x92,0x49,0x27,0x24,0x9c,0x9c,0xe4,0xd0,0x07,0x59,0xfd,0x95,0xa5,0xff,0x00,0xd0,0x36,0xc3,0xff,0x00,0x01,0x20,0xff,0x00,0xe3,0x74,0x00,0x7f,0x65,0x69,0x7f
,0xf4,0x0d,0xb0,0xff,0x00,0xc0,0x48,0x3f,0xf8,0xdd,0x00,0x1f,0xd9,0x5a,0x5f,0xfd,0x03,0x6c,0x3f,0xf0,0x12,0x0f,0xfe,0x37,0x40,0x07,0xf6,0x56,0x97,0xff,0x00,0x40
,0xdb,0x0f,0xfc,0x04,0x83,0xff,0x00,0x8d,0xd0,0x06,0x4e,0xbf,0xa6,0x69,0x8b,0xa1,0x6b,0x4c,0xba,0x75,0x8a,0xb2,0xe9,0x3a,0x89,0x56,0x16,0x90,0x02,0x08,0xb3,0x98
,0x82,0x08,0x8f,0x20,0x83,0xc8,0x23,0xa5,0x00,0x53,0xf0,0x86,0x99,0xa6,0xbf,0x84,0xfc,0x2e,0xef,0xa7,0xd8,0xb3,0x37,0x87,0x74,0x56,0x66,0x6b,0x58,0x0b,0x33,0x36
,0x9b,0x6a,0x4b,0x31,0x31,0xe4,0x92,0x79,0x24,0xf2,0x4f,0x27,0xad,0x00,0x74,0x5f,0xd9,0x5a,0x5f,0xfd,0x03,0x6c,0x3f,0xf0,0x12,0x0f,0xfe,0x37,0x40,0x07,0xf6,0x56
,0x97,0xff,0x00,0x40,0xdb,0x0f,0xfc,0x04,0x83,0xff,0x00,0x8d,0xd0,0x01,0xfd,0x95,0xa5,0xff,0x00,0xd0,0x36,0xc3,0xff,0x00,0x01,0x20,0xff,0x00,0xe3,0x74,0x00,0x7f
,0x65,0x69,0x7f,0xf4,0x0d,0xb0,0xff,0x00,0xc0,0x48,0x3f,0xf8,0xdd,0x00,0x72,0x9e,0x3c,0xd3,0x74,0xd4,0xf0,0x37,0x8c,0xdd,0x34,0xfb,0x24,0x74,0xf0,0xa7,0x88,0x99
,0x1d,0x6d,0x61,0x56,0x46,0x5d,0x22,0xf0,0xab,0x2b,0x04,0x04,0x32,0x90,0x08,0x20,0xe4,0x11,0x91,0x8c,0x0a,0x00,0xff,0xd5,0xfe,0xf6,0x7c,0x29,0xff,0x00,0x22,0xbf
,0x86,0xff,0x00,0xec,0x01,0xa3,0xff,0x00,0xe9,0xba,0xda,0x80,0x37,0xe8,0x03,0xc8,0xfc,0x25,0x6d,0xe2,0xa9,0x1f,0xc5,0xcd,0xa5,0x6b,0x3e,0x1f,0xb3,0xb4,0xff,0x00
,0x84,0xeb,0xc5,0x01,0x61,0xd4,0x3c,0x35,0xa8,0xea,0x57,0x01,0xfe,0xdc,0x37,0x13,0x75,0x6f,0xe2,0xbd,0x26,0x36,0x52,0x30,0x02,0x8b,0x45,0x2a,0x41,0x25,0xce,0xe5
,0x14,0x01,0xd7,0xfd,0x8f,0xc7,0x7f,0xf4,0x31,0xf8,0x4b,0xff,0x00,0x08,0xbd,0x63,0xff,0x00,0x9b,0xea,0x00,0x3e,0xc7,0xe3,0xbf,0xfa,0x18,0xfc,0x25,0xff,0x00,0x84
,0x5e,0xb1,0xff,0x00,0xcd,0xf5,0x00,0x1f,0x63,0xf1,0xdf,0xfd,0x0c,0x7e,0x12,0xff,0x00,0xc2,0x2f,0x58,0xff,0x00,0xe6,0xfa,0x80,0x0f,0xb1,0xf8,0xef,0xfe,0x86,0x3f
,0x09,0x7f,0xe1,0x17,0xac,0x7f,0xf3,0x7d,0x40,0x07,0xd8,0xfc,0x77,0xff,0x00,0x43,0x1f,0x84,0xbf,0xf0,0x8b,0xd6,0x3f,0xf9,0xbe,0xa0,0x0e,0x5b,0xc1,0xf6,0x9e,0x34
,0x6d,0x26,0xec,0xdb,0xeb,0xfe,0x17,0x8a,0x3f,0xf8,0x4a,0x7c,0x72,0x19,0x66,0xf0,0x8e,0xab,0x3b,0x99,0xd7,0xc6,0xbe,0x20,0x5b,0xa9,0x03,0xa7,0x8d,0xad,0xc2,0xc5
,0x35,0xc8,0x96,0x58,0x21,0x31,0xb3,0xdb,0x40,0xf1,0xdb,0xc9,0x3d,0xd3,0xc4,0xf7,0x33,0x80,0x75,0x3f,0x63,0xf1,0xdf,0xfd,0x0c,0x7e,0x12,0xff,0x00,0xc2,0x2f,0x58
,0xff,0x00,0xe6,0xfa,0x80,0x0f,0xb1,0xf8,0xef,0xfe,0x86,0x3f,0x09,0x7f,0xe1,0x17,0xac,0x7f,0xf3,0x7d,0x40,0x07,0xd8,0xfc,0x77,0xff,0x00,0x43,0x1f,0x84,0xbf,0xf0
,0x8b,0xd6,0x3f,0xf9,0xbe,0xa0,0x03,0xec,0x7e,0x3b,0xff,0x00,0xa1,0x8f,0xc2,0x5f,0xf8,0x45,0xeb,0x1f,0xfc,0xdf,0x50,0x01,0xf6,0x3f,0x1d,0xff,0x00,0xd0,0xc7,0xe1
,0x2f,0xfc,0x22,0xf5,0x8f,0xfe,0x6f,0xa8,0x03,0x8b,0xf8,0x79,0x6b,0xe3,0x26,0xf0,0x7e,0x90,0xd6,0x9a,0xf7,0x86,0x60,0xb7,0x27,0x51,0xf2,0xe2,0xb9,0xf0,0x96,0xa9
,0x75,0x32,0xe3,0x55,0xbe,0x0f,0xbe,0x78,0xbc,0x6b,0x68,0x8f,0x97,0xdc,0xcb,0xb6,0xde,0x3d,0xa8,0xca,0x87,0x79,0x52,0xec,0x01,0xda,0x7d,0x8f,0xc7,0x7f,0xf4,0x31
,0xf8,0x4b,0xff,0x00,0x08,0xbd,0x63,0xff,0x00,0x9b,0xea,0x00,0x3e,0xc7,0xe3,0xbf,0xfa,0x18,0xfc,0x25,0xff,0x00,0x84,0x5e,0xb1,0xff,0x00,0xcd,0xf5,0x00,0x1f,0x63
,0xf1,0xdf,0xfd,0x0c,0x7e,0x12,0xff,0x00,0xc2,0x2f,0x58,0xff,0x00,0xe6,0xfa,0x80,0x0f,0xb1,0xf8,0xef,0xfe,0x86,0x3f,0x09,0x7f,0xe1,0x17,0xac,0x7f,0xf3,0x7d,0x40
,0x07,0xd8,0xfc,0x77,0xff,0x00,0x43,0x1f,0x84,0xbf,0xf0,0x8b,0xd6,0x3f,0xf9,0xbe,0xa0,0x0e,0x5b,0xc0,0xd6,0x9e,0x34,0x6f,0x05,0x78,0x3d,0xad,0x75,0xff,0x00,0x0b
,0xc3,0x6c,0xde,0x16,0xf0,0xf9,0xb7,0x8a,0x7f,0x08,0xea,0xb7,0x13,0xc5,0x01,0xd2,0x6d,0x0c,0x51,0xcd,0x71,0x1f,0x8d,0xad,0x63,0x9e,0x54,0x8f,0x6a,0xc9,0x32,0x5b
,0x5b,0xa4,0xae,0x0b,0xac,0x10,0xab,0x08,0xd4,0x03,0xa9,0xfb,0x1f,0x8e,0xff,0x00,0xe8,0x63,0xf0,0x97,0xfe,0x11,0x7a,0xc7,0xff,0x00,0x37,0xd4,0x00,0x7d,0x8f,0xc7
,0x7f,0xf4,0x31,0xf8,0x4b,0xff,0x00,0x08,0xbd,0x63,0xff,0x00,0x9b,0xea,0x00,0x3e,0xc7,0xe3,0xbf,0xfa,0x18,0xfc,0x25,0xff,0x00,0x84,0x5e,0xb1,0xff,0x00,0xcd,0xf5
,0x00,0x1f,0x63,0xf1,0xdf,0xfd,0x0c,0x7e,0x12,0xff,0x00,0xc2,0x2f,0x58,0xff,0x00,0xe6,0xfa,0x80,0x32,0xf5,0xcb,0x3f,0x1b,0x8d,0x17,0x58,0x32,0xf8,0x87,0xc2,0xaf
,0x10,0xd2,0xf5,0x03,0x22,0x47,0xe0,0xed,0x5e,0x39,0x1e,0x31,0x69,0x2e,0xf5,0x49,0x1b,0xc7,0x52,0xac,0x6e,0xcb,0x90,0xae,0xd1,0x48,0x14,0x9d,0xc6,0x37,0x03,0x6b
,0x00,0x54,0xf0,0xa5,0xa7,0x8d,0x8f,0x85,0xfc,0x36,0x60,0xf1,0x07,0x85,0xa3,0x80,0xe8,0x1a,0x39,0x86,0x39,0xbc,0x1f,0xab,0x4d,0x2c,0x71,0x1d,0x3a,0xd8,0xc6,0x92
,0xcc,0x9e,0x38,0xb7,0x49,0x64,0x54,0xc2,0xbc,0xab,0x04,0x0b,0x23,0x02,0xcb,0x14,0x60,0xec,0x50,0x0d,0xff,0x00,0xb1,0xf8,0xef,0xfe,0x86,0x3f,0x09,0x7f,0xe1,0x17
,0xac,0x7f,0xf3,0x7d,0x40,0x07,0xd8,0xfc,0x77,0xff,0x00,0x43,0x1f,0x84,0xbf,0xf0,0x8b,0xd6,0x3f,0xf9,0xbe,0xa0,0x03,0xec,0x7e,0x3b,0xff,0x00,0xa1,0x8f,0xc2,0x5f
,0xf8,0x45,0xeb,0x1f,0xfc,0xdf,0x50,0x01,0xf6,0x3f,0x1d,0xff,0x00,0xd0,0xc7,0xe1,0x2f,0xfc,0x22,0xf5,0x8f,0xfe,0x6f,0xa8,0x03,0x97,0xf1,0xbd,0xa7,0x8d,0x17,0xc1
,0x7e,0x2f,0x6b,0xad,0x7f,0xc2,0xf3,0x5b,0x2f,0x85,0xf5,0xf3,0x71,0x14,0x1e,0x11,0xd5,0x6d,0xa7,0x96,0x01,0xa5,0x5d,0x99,0xa3,0x86,0xe2,0x4f,0x1b,0x5d,0x47,0x04
,0xaf,0x1e,0xe5,0x8e,0x67,0xb6,0xb8,0x48,0x9c,0x87,0x68,0x26,0x55,0x31,0xb0,0x07,0xff,0xd6,0xfe,0xf6,0x7c,0x29,0xff,0x00,0x22,0xbf,0x86,0xff,0x00,0xec,0x01,0xa3
,0xff,0x00,0xe9,0xba,0xda,0x80,0x37,0xe8,0x03,0xc7,0x7c,0x2d,0xe3,0x3f,0x0b,0x68,0xb2,0xf8,0xba,0xcb,0x55,0xd7,0x2c,0x2c,0x6e,0xd7,0xc7,0x3e,0x28,0x91,0xa0,0x9e
,0x52,0xb2,0x04,0x6b,0xec,0x2b,0x10,0x15,0xb8,0x25,0x58,0x0e,0x7f,0x87,0xbe,0x0e,0xd0,0x0e,0xaf,0xfe,0x16,0x4f,0x81,0x3f,0xe8,0x68,0xd2,0xbf,0xef,0xf3,0x7f,0xf1
,0xba,0x00,0x3f,0xe1,0x64,0xf8,0x13,0xfe,0x86,0x8d,0x2b,0xfe,0xff,0x00,0x37,0xff,0x00,0x1b,0xa0,0x03,0xfe,0x16,0x4f,0x81,0x3f,0xe8,0x68,0xd2,0xbf,0xef,0xf3,0x7f
,0xf1,0xba,0x00,0x3f,0xe1,0x64,0xf8,0x13,0xfe,0x86,0x8d,0x2b,0xfe,0xff,0x00,0x37,0xff,0x00,0x1b,0xa0,0x03,0xfe,0x16,0x4f,0x81,0x3f,0xe8,0x68,0xd2,0xbf,0xef,0xf3
,0x7f,0xf1,0xba,0x00,0xe5,0xfc,0x21,0xf1,0x03,0xc1,0x76,0xba,0x55,0xdc,0x57,0x1e,0x23,0xd3,0x22,0x91,0xbc,0x51,0xe3,0x7b,0x85,0x57,0x99,0x81,0x30,0x5e,0x78,0xd3
,0x5f,0xbb,0xb6,0x94,0x7c,0x87,0xe5,0x9a,0xda,0x78,0x66,0x43,0xdd,0x24,0x53,0x81,0x9c,0x28,0x07,0x51,0xff,0x00,0x0b,0x27,0xc0,0x9f,0xf4,0x34,0x69,0x5f,0xf7,0xf9
,0xbf,0xf8,0xdd,0x00,0x1f,0xf0,0xb2,0x7c,0x09,0xff,0x00,0x43,0x46,0x95,0xff,0x00,0x7f,0x9b,0xff,0x00,0x8d,0xd0,0x01,0xff,0x00,0x0b,0x27,0xc0,0x9f,0xf4,0x34,0x69
,0x5f,0xf7,0xf9,0xbf,0xf8,0xdd,0x00,0x1f,0xf0,0xb2,0x7c,0x09,0xff,0x00,0x43,0x46,0x95,0xff,0x00,0x7f,0x9b,0xff,0x00,0x8d,0xd0,0x01,0xff,0x00,0x0b,0x27,0xc0,0x9f
,0xf4,0x34,0x69,0x5f,0xf7,0xf9,0xbf,0xf8,0xdd,0x00,0x71,0x9f,0x0f,0xbc,0x7d,0xe0,0xdb,0x1f,0x08,0x69,0x36,0xb7,0x7e,0x22,0xd3,0x6d,0xee,0x22,0x3a,0x87,0x99,0x14
,0x92,0xb0,0x75,0xdf,0xaa,0x5f,0x48,0x99,0x1b,0x0f,0xde,0x47,0x57,0x1c,0xf4,0x61,0xd7,0x34,0x01,0xd9,0xff,0x00,0xc2,0xc9,0xf0,0x27,0xfd,0x0d,0x1a,0x57,0xfd,0xfe
,0x6f,0xfe,0x37,0x40,0x07,0xfc,0x2c,0x9f,0x02,0x7f,0xd0,0xd1,0xa5,0x7f,0xdf,0xe6,0xff,0x00,0xe3,0x74,0x00,0x7f,0xc2,0xc9,0xf0,0x27,0xfd,0x0d,0x1a,0x57,0xfd,0xfe
,0x6f,0xfe,0x37,0x40,0x07,0xfc,0x2c,0x9f,0x02,0x7f,0xd0,0xd1,0xa5,0x7f,0xdf,0xe6,0xff,0x00,0xe3,0x74,0x00,0x7f,0xc2,0xc9,0xf0,0x27,0xfd,0x0d,0x1a,0x57,0xfd,0xfe
,0x6f,0xfe,0x37,0x40,0x1c,0xbf,0x82,0x3e,0x20,0x78,0x2e,0xcf,0xc1,0x7e,0x10,0xb4,0xb9,0xf1,0x1e,0x99,0x0d,0xcd,0xaf,0x85,0xf4,0x0b,0x7b,0x88,0x5e,0x66,0x0f,0x14
,0xf0,0x69,0x56,0x91,0x4b,0x13,0x8d,0x87,0x0d,0x1c,0x8a,0xc8,0xc3,0x27,0x04,0x75,0x3d,0x68,0x03,0xa8,0xff,0x00,0x85,0x93,0xe0,0x4f,0xfa,0x1a,0x34,0xaf,0xfb,0xfc
,0xdf,0xfc,0x6e,0x80,0x0f,0xf8,0x59,0x3e,0x04,0xff,0x00,0xa1,0xa3,0x4a,0xff,0x00,0xbf,0xcd,0xff,0x00,0xc6,0xe8,0x00,0xff,0x00,0x85,0x93,0xe0,0x4f,0xfa,0x1a,0x34
,0xaf,0xfb,0xfc,0xdf,0xfc,0x6e,0x80,0x0f,0xf8,0x59,0x3e,0x04,0xff,0x00,0xa1,0xa3,0x4a,0xff,0x00,0xbf,0xcd,0xff,0x00,0xc6,0xe8,0x03,0x2f,0x5b,0xf8,0x8b,0xe0,0x89
,0xb4,0x5d,0x5e,0x18,0xbc,0x4d,0xa5,0xbc,0x92,0xe9,0x7a,0x84,0x71,0xa2,0xcc,0xdb,0x9d,0xde,0xd2,0x55,0x45,0x1f,0xbb,0xea,0xcc,0x40,0x1e,0xf4,0x01,0x57,0xc2,0xbf
,0x10,0xbc,0x13,0x6d,0xe1,0x8f,0x0e,0x5b,0x4f,0xe2,0x4d,0x32,0x29,0xed,0xf4,0x1d,0x1e,0x09,0xa2,0x69,0x98,0x34,0x72,0xc5,0xa7,0xdb,0xa4,0x91,0xb0,0xd8,0x70,0xc8
,0xea,0x54,0xf3,0xd4,0x77,0xa0,0x0d,0xef,0xf8,0x59,0x3e,0x04,0xff,0x00,0xa1,0xa3,0x4a,0xff,0x00,0xbf,0xcd,0xff,0x00,0xc6,0xe8,0x00,0xff,0x00,0x85,0x93,0xe0,0x4f
,0xfa,0x1a,0x34,0xaf,0xfb,0xfc,0xdf,0xfc,0x6e,0x80,0x0f,0xf8,0x59,0x3e,0x04,0xff,0x00,0xa1,0xa3,0x4a,0xff,0x00,0xbf,0xcd,0xff,0x00,0xc6,0xe8,0x00,0xff,0x00,0x85
,0x93,0xe0,0x4f,0xfa,0x1a,0x34,0xaf,0xfb,0xfc,0xdf,0xfc,0x6e,0x80,0x39,0x9f,0x1a,0xfc,0x40,0xf0,0x5d,0xe7,0x83,0x7c,0x5b,0x69,0x6b,0xe2,0x3d,0x36,0x7b,0x9b,0xaf
,0x0c,0xeb,0xd6,0xd6,0xf0,0xc7,0x2b,0x17,0x9a,0x79,0xf4,0xab,0xa8,0xa1,0x89,0x06,0xc1,0x97,0x92,0x46,0x54,0x51,0x9e,0x4b,0x01,0xc5,0x00,0x7f,0xff,0xd7,0xfe,0xf6
,0x7c,0x29,0xff,0x00,0x22,0xbf,0x86,0xff,0x00,0xec,0x01,0xa3,0xff,0x00,0xe9,0xba,0xda,0x80,0x37,0xe8,0x03,0x83,0xf0,0x17,0xfa,0xaf,0x16,0x7f,0xd8,0xf9,0xe2,0xaf
,0xfd,0x2d,0x5a,0x00,0xef,0x28,0x00,0xa0,0x02,0x80,0x0a,0x00,0x28,0x03,0x91,0xf0,0x4f,0xfc,0x81,0xaf,0x7f,0xec,0x6e,0xf8,0x81,0xff,0x00,0xa9,0xe7,0x89,0x28,0x03
,0xae,0xa0,0x02,0x80,0x0a,0x00,0x28,0x00,0xa0,0x0e,0x13,0xe1,0x9f,0xfc,0x89,0x3a,0x2f,0xd7,0x53,0xff,0x00,0xd3,0xc5,0xfd,0x00,0x77,0x74,0x00,0x50,0x01,0x40,0x05
,0x00,0x14,0x01,0xc8,0xfc,0x3f,0xff,0x00,0x91,0x0f,0xc1,0x3f,0xf6,0x28,0xf8,0x6f,0xff,0x00,0x4c,0xd6,0x54,0x01,0xd7,0x50,0x01,0x40,0x05,0x00,0x14,0x01,0x91,0xe2
,0x0f,0xf9,0x00,0xeb,0x7f,0xf6,0x08,0xd4,0xbf,0xf4,0x8e,0x6a,0x00,0xa7,0xe0,0xef,0xf9,0x14,0x7c,0x2d,0xff,0x00,0x62,0xe6,0x87,0xff,0x00,0xa6,0xcb,0x5a,0x00,0xe8
,0xe8,0x00,0xa0,0x02,0x80,0x0a,0x00,0xe4,0xbc,0x7d,0xff,0x00,0x22,0x27,0x8d,0x7f,0xec,0x52,0xf1,0x1f,0xfe,0x99,0xef,0x68,0x03,0xff,0xd0,0xfe,0xf6,0x7c,0x29,0xff
,0x00,0x22,0xbf,0x86,0xff,0x00,0xec,0x01,0xa3,0xff,0x00,0xe9,0xba,0xda,0x80,0x37,0xe8,0x03,0xc6,0xfc,0x2d,0xa3,0x6b,0xf7,0x92,0xf8,0xba,0x7d,0x3f,0xc6,0x17,0xda
,0x3d,0xb9,0xf1,0xcf,0x8a,0x14,0x59,0x43,0xa4,0x68,0x97,0x88,0xac,0x2f,0xbe,0x67,0x13,0x5e,0xd9,0x4d,0x39,0x2d,0x90,0x36,0x97,0x2a,0x02,0x8c,0x60,0x93,0x40,0x1d
,0x5f,0xfc,0x23,0x9e,0x2d,0xff,0x00,0xa2,0x89,0xa9,0xff,0x00,0xe1,0x3d,0xe1,0x8f,0xfe,0x56,0xd0,0x01,0xff,0x00,0x08,0xe7,0x8b,0x7f,0xe8,0xa2,0x6a,0x7f,0xf8,0x4f
,0x78,0x63,0xff,0x00,0x95,0xb4,0x00,0x7f,0xc2,0x39,0xe2,0xdf,0xfa,0x28,0x9a,0x9f,0xfe,0x13,0xde,0x18,0xff,0x00,0xe5,0x6d,0x00,0x1f,0xf0,0x8e,0x78,0xb7,0xfe,0x8a
,0x26,0xa7,0xff,0x00,0x84,0xf7,0x86,0x3f,0xf9,0x5b,0x40,0x07,0xfc,0x23,0x9e,0x2d,0xff,0x00,0xa2,0x89,0xa9,0xff,0x00,0xe1,0x3d,0xe1,0x8f,0xfe,0x56,0xd0,0x07,0x31
,0xe1,0x1d,0x03,0xc5,0x12,0xe9,0x57,0x6d,0x07,0x8f,0x35,0x1b,0x54,0x1e,0x27,0xf1,0xb4,0x6d,0x1a,0xe8,0x5e,0x1d,0x94,0x34,0xd0,0xf8,0xcf,0x5f,0x8a,0xe2,0xe0,0xb4
,0xba,0x7b,0xb0,0x6b,0xb9,0xd2,0x5b,0xb7,0x8c,0x11,0x14,0x2f,0x39,0x8a,0x15,0x48,0x51,0x11,0x40,0x3a,0x7f,0xf8,0x47,0x3c,0x5b,0xff,0x00,0x45,0x13,0x53,0xff,0x00
,0xc2,0x7b,0xc3,0x1f,0xfc,0xad,0xa0,0x03,0xfe,0x11,0xcf,0x16,0xff,0x00,0xd1,0x44,0xd4,0xff,0x00,0xf0,0x9e,0xf0,0xc7,0xff,0x00,0x2b,0x68,0x00,0xff,0x00,0x84,0x73
,0xc5,0xbf,0xf4,0x51,0x35,0x3f,0xfc,0x27,0xbc,0x31,0xff,0x00,0xca,0xda,0x00,0x3f,0xe1,0x1c,0xf1,0x6f,0xfd,0x14,0x4d,0x4f,0xff,0x00,0x09,0xef,0x0c,0x7f,0xf2,0xb6
,0x80,0x0f,0xf8,0x47,0x3c,0x5b,0xff,0x00,0x45,0x13,0x53,0xff,0x00,0xc2,0x7b,0xc3,0x1f,0xfc,0xad,0xa0,0x0e,0x37,0xe1,0xf6,0x83,0xe2,0x69,0xfc,0x23,0xa4,0xcb,0x6f
,0xe3,0xad,0x42,0xca,0x16,0x3a,0x86,0xcb,0x68,0xf4,0x3f,0x0f,0x4e,0x91,0xed,0xd5,0x2f,0x55,0xb1,0x2c,0xfa,0x7b,0xca,0xdb,0xdc,0x34,0x87,0x7b,0x36,0xd2,0xc5,0x47
,0xca,0xaa,0x14,0x03,0xb2,0xff,0x00,0x84,0x73,0xc5,0xbf,0xf4,0x51,0x35,0x3f,0xfc,0x27,0xbc,0x31,0xff,0x00,0xca,0xda,0x00,0x3f,0xe1,0x1c,0xf1,0x6f,0xfd,0x14,0x4d
,0x4f,0xff,0x00,0x09,0xef,0x0c,0x7f,0xf2,0xb6,0x80,0x0f,0xf8,0x47,0x3c,0x5b,0xff,0x00,0x45,0x13,0x53,0xff,0x00,0xc2,0x7b,0xc3,0x1f,0xfc,0xad,0xa0,0x03,0xfe,0x11
,0xcf,0x16,0xff,0x00,0xd1,0x44,0xd4,0xff,0x00,0xf0,0x9e,0xf0,0xc7,0xff,0x00,0x2b,0x68,0x00,0xff,0x00,0x84,0x73,0xc5,0xbf,0xf4,0x51,0x35,0x3f,0xfc,0x27,0xbc,0x31
,0xff,0x00,0xca,0xda,0x00,0xe6,0x3c,0x13,0xa0,0x78,0xa2,0x6f,0x06,0x78,0x46,0x6b,0x7f,0x1e,0x6a,0x36,0x90,0x4b,0xe1,0x8d,0x02,0x48,0x2d,0x13,0x42,0xf0,0xec,0xc9
,0x6b,0x0b,0xe9,0x56,0x8d,0x1d,0xba,0x4b,0x36,0x9e,0xf3,0x4a,0xb0,0xa1,0x11,0x2c,0x92,0xbb,0xca,0xe1,0x43,0x48,0xcc,0xe5,0x8d,0x00,0x74,0xff,0x00,0xf0,0x8e,0x78
,0xb7,0xfe,0x8a,0x26,0xa7,0xff,0x00,0x84,0xf7,0x86,0x3f,0xf9,0x5b,0x40,0x07,0xfc,0x23,0x9e,0x2d,0xff,0x00,0xa2,0x89,0xa9,0xff,0x00,0xe1,0x3d,0xe1,0x8f,0xfe,0x56
,0xd0,0x01,0xff,0x00,0x08,0xe7,0x8b,0x7f,0xe8,0xa2,0x6a,0x7f,0xf8,0x4f,0x78,0x63,0xff,0x00,0x95,0xb4,0x00,0x7f,0xc2,0x39,0xe2,0xdf,0xfa,0x28,0x9a,0x9f,0xfe,0x13
,0xde,0x18,0xff,0x00,0xe5,0x6d,0x00,0x65,0xeb,0x7e,0x1e,0xf1,0x5a,0x68,0xba,0xbb,0xc9,0xf1,0x03,0x52,0x95,0x17,0x4b,0xd4,0x19,0xe2,0x3a,0x07,0x86,0x90,0x4a,0x8b
,0x69,0x29,0x68,0xcb,0x26,0x9c,0x1d,0x43,0x8c,0xa9,0x65,0x21,0x86,0x72,0xa4,0x11,0x9a,0x00,0xab,0xe1,0x6f,0x0f,0xf8,0xa6,0x4f,0x0c,0x78,0x72,0x48,0x7c,0x7d,0xa8
,0xdb,0xc5,0x26,0x83,0xa3,0xbc,0x56,0xeb,0xa0,0xf8,0x72,0x45,0x82,0x37,0xd3,0xed,0xd9,0x21,0x59,0x25,0xd3,0x9a,0x59,0x16,0x25,0x21,0x03,0xc8,0xcc,0xec,0x17,0x73
,0x92,0xc4,0x9a,0x00,0xde,0xff,0x00,0x84,0x73,0xc5,0xbf,0xf4,0x51,0x35,0x3f,0xfc,0x27,0xbc,0x31,0xff,0x00,0xca,0xda,0x00,0x3f,0xe1,0x1c,0xf1,0x6f,0xfd,0x14,0x4d
,0x4f,0xff,0x00,0x09,0xef,0x0c,0x7f,0xf2,0xb6,0x80,0x0f,0xf8,0x47,0x3c,0x5b,0xff,0x00,0x45,0x13,0x53,0xff,0x00,0xc2,0x7b,0xc3,0x1f,0xfc,0xad,0xa0,0x03,0xfe,0x11
,0xcf,0x16,0xff,0x00,0xd1,0x44,0xd4,0xff,0x00,0xf0,0x9e,0xf0,0xc7,0xff,0x00,0x2b,0x68,0x03,0x99,0xf1,0xae,0x81,0xe2,0x88,0x7c,0x1b,0xe2,0xd9,0xa7,0xf1,0xe6,0xa3
,0x77,0x04,0x5e,0x19,0xd7,0xa4,0x9a,0xd1,0xf4,0x2f,0x0e,0xc4,0x97,0x31,0x26,0x95,0x74,0xd2,0x5b,0xbc,0xb0,0xe9,0xe9,0x34,0x6b,0x32,0x03,0x1b,0x49,0x13,0xa4,0xa8
,0x1b,0x74,0x6c,0xae,0x14,0xd0,0x07,0xff,0xd1,0xfe,0xf6,0x7c,0x29,0xff,0x00,0x22,0xbf,0x86,0xff,0x00,0xec,0x01,0xa3,0xff,0x00,0xe9,0xba,0xda,0x80,0x37,0xe8,0x03
,0xc8,0xfc,0x25,0xe2,0x6d,0x3b,0x4c,0x7f,0x17,0x5a,0xdc,0x5b,0x78,0x82,0x49,0x57,0xc7,0x5e,0x28,0x62,0xda,0x7f,0x84,0xfc,0x55,0xab,0x5b,0xe1,0xaf,0x86,0x00,0xbc
,0xd2,0xf4,0x6b,0xdb,0x46,0x6e,0x39,0x45,0x9c,0xba,0x8c,0x12,0xa0,0x30,0xa0,0x0e,0xbf,0xfe,0x13,0x5d,0x1f,0xfe,0x7c,0xbc,0x5b,0xff,0x00,0x84,0x0f,0x8e,0xff,0x00
,0xf9,0x9b,0xa0,0x03,0xfe,0x13,0x5d,0x1f,0xfe,0x7c,0xbc,0x5b,0xff,0x00,0x84,0x0f,0x8e,0xff,0x00,0xf9,0x9b,0xa0,0x03,0xfe,0x13,0x5d,0x1f,0xfe,0x7c,0xbc,0x5b,0xff
,0x00,0x84,0x0f,0x8e,0xff,0x00,0xf9,0x9b,0xa0,0x03,0xfe,0x13,0x5d,0x1f,0xfe,0x7c,0xbc,0x5b,0xff,0x00,0x84,0x0f,0x8e,0xff,0x00,0xf9,0x9b,0xa0,0x03,0xfe,0x13,0x5d
,0x1f,0xfe,0x7c,0xbc,0x5b,0xff,0x00,0x84,0x0f,0x8e,0xff,0x00,0xf9,0x9b,0xa0,0x0e,0x5b,0xc1,0xfe,0x2f,0xd2,0x60,0xd2,0x6e,0xd1,0xed,0x3c,0x50,0xcc,0xde,0x29,0xf1
,0xcc,0xc0,0xc3,0xe0,0x8f,0x1a,0x5c,0xa6,0xcb,0x9f,0x1a,0xf8,0x82,0xe2,0x30,0x64,0xb7,0xf0,0xfc,0xb1,0xac,0xab,0x1c,0xaa,0xb3,0xc0,0xcc,0x27,0xb5,0x9c,0x49,0x6b
,0x73,0x1c,0x57,0x31,0x4d,0x14,0x40,0x1d,0x4f,0xfc,0x26,0xba,0x3f,0xfc,0xf9,0x78,0xb7,0xff,0x00,0x08,0x1f,0x1d,0xff,0x00,0xf3,0x37,0x40,0x07,0xfc,0x26,0xba,0x3f
,0xfc,0xf9,0x78,0xb7,0xff,0x00,0x08,0x1f,0x1d,0xff,0x00,0xf3,0x37,0x40,0x07,0xfc,0x26,0xba,0x3f,0xfc,0xf9,0x78,0xb7,0xff,0x00,0x08,0x1f,0x1d,0xff,0x00,0xf3,0x37
,0x40,0x07,0xfc,0x26,0xba,0x3f,0xfc,0xf9,0x78,0xb7,0xff,0x00,0x08,0x1f,0x1d,0xff,0x00,0xf3,0x37,0x40,0x07,0xfc,0x26,0xba,0x3f,0xfc,0xf9,0x78,0xb7,0xff,0x00,0x08
,0x1f,0x1d,0xff,0x00,0xf3,0x37,0x40,0x1c,0x5f,0xc3,0xcf,0x16,0xe9,0x56,0xbe,0x0f,0xd2,0x20,0x96,0xd3,0xc4,0xcc,0xf1,0x9d,0x47,0x73,0x5b,0x78,0x2b,0xc6,0x57,0x90
,0x9d,0xda,0xad,0xf3,0x8d,0x97,0x36,0x9a,0x04,0xf6,0xf2,0x60,0x30,0x0d,0xe5,0xca,0xfb,0x1c,0x34,0x6f,0xb5,0xd5,0xd5,0x40,0x3b,0x4f,0xf8,0x4d,0x74,0x7f,0xf9,0xf2
,0xf1,0x6f,0xfe,0x10,0x3e,0x3b,0xff,0x00,0xe6,0x6e,0x80,0x0f,0xf8,0x4d,0x74,0x7f,0xf9,0xf2,0xf1,0x6f,0xfe,0x10,0x3e,0x3b,0xff,0x00,0xe6,0x6e,0x80,0x0f,0xf8,0x4d
,0x74,0x7f,0xf9,0xf2,0xf1,0x6f,0xfe,0x10,0x3e,0x3b,0xff,0x00,0xe6,0x6e,0x80,0x0f,0xf8,0x4d,0x74,0x7f,0xf9,0xf2,0xf1,0x6f,0xfe,0x10,0x3e,0x3b,0xff,0x00,0xe6,0x6e
,0x80,0x0f,0xf8,0x4d,0x74,0x7f,0xf9,0xf2,0xf1,0x6f,0xfe,0x10,0x3e,0x3b,0xff,0x00,0xe6,0x6e,0x80,0x39,0x6f,0x03,0x78,0xbf,0x49,0xb6,0xf0,0x57,0x83,0xed,0xe4,0xb4
,0xf1,0x43,0x49,0x07,0x85,0xbc,0x3f,0x0b,0xb4,0x1e,0x08,0xf1,0xa5,0xd4,0x0c,0xf1,0x69,0x36,0x88,0xc6,0x1b,0xab,0x5f,0x0f,0xcd,0x6d,0x73,0x11,0x65,0x26,0x39,0xed
,0xe5,0x96,0x09,0x93,0x12,0x43,0x23,0xc6,0xca,0xf4,0x01,0xd4,0xff,0x00,0xc2,0x6b,0xa3,0xff,0x00,0xcf,0x97,0x8b,0x7f,0xf0,0x81,0xf1,0xdf,0xff,0x00,0x33,0x74,0x00
,0x7f,0xc2,0x6b,0xa3,0xff,0x00,0xcf,0x97,0x8b,0x7f,0xf0,0x81,0xf1,0xdf,0xff,0x00,0x33,0x74,0x00,0x7f,0xc2,0x6b,0xa3,0xff,0x00,0xcf,0x97,0x8b,0x7f,0xf0,0x81,0xf1
,0xdf,0xff,0x00,0x33,0x74,0x00,0x7f,0xc2,0x6b,0xa3,0xff,0x00,0xcf,0x97,0x8b,0x7f,0xf0,0x81,0xf1,0xdf,0xff,0x00,0x33,0x74,0x01,0x97,0xae,0x78,0xcb,0x48,0x97,0x45
,0xd6,0x23,0x5b,0x3f,0x15,0x06,0x93,0x4b,0xd4,0x11,0x4c,0x9e,0x04,0xf1,0xbc,0x51,0x86,0x7b,0x49,0x54,0x17,0x96,0x5f,0x0e,0xa4,0x51,0xa0,0x27,0xe6,0x92,0x47,0x48
,0xd0,0x7c,0xce,0xca,0xa0,0x9a,0x00,0xa9,0xe1,0x4f,0x18,0xe9,0x30,0x78,0x5f,0xc3,0x70,0xbd,0x9f,0x8a,0x59,0xe1,0xd0,0x34,0x78,0x9d,0xa1,0xf0,0x37,0x8d,0xae,0x22
,0x2d,0x1e,0x9d,0x6c,0x8c,0x62,0x9e,0x0f,0x0f,0x49,0x04,0xd1,0x92,0x09,0x49,0xa1,0x92,0x48,0xa4,0x5c,0x3c,0x6e,0xc8,0x55,0x98,0x03,0x7f,0xfe,0x13,0x5d,0x1f,0xfe
,0x7c,0xbc,0x5b,0xff,0x00,0x84,0x0f,0x8e,0xff,0x00,0xf9,0x9b,0xa0,0x03,0xfe,0x13,0x5d,0x1f,0xfe,0x7c,0xbc,0x5b,0xff,0x00,0x84,0x0f,0x8e,0xff,0x00,0xf9,0x9b,0xa0
,0x03,0xfe,0x13,0x5d,0x1f,0xfe,0x7c,0xbc,0x5b,0xff,0x00,0x84,0x0f,0x8e,0xff,0x00,0xf9,0x9b,0xa0,0x03,0xfe,0x13,0x5d,0x1f,0xfe,0x7c,0xbc,0x5b,0xff,0x00,0x84,0x0f
,0x8e,0xff,0x00,0xf9,0x9b,0xa0,0x0e,0x5f,0xc6,0xfe,0x2f,0xd2,0x6e,0x7c,0x17,0xe2,0xfb,0x78,0xed,0x3c,0x50,0xb2,0x5c,0x78,0x5f,0x5f,0x85,0x1a,0x7f,0x04,0x78,0xd2
,0xd6,0x05,0x79,0x74,0xab,0xb4,0x56,0x9a,0xea,0xeb,0xc3,0xf0,0xdb,0x5b,0x44,0x19,0x81,0x92,0x7b,0x89,0x62,0x82,0x14,0xcc,0x93,0x48,0x91,0xab,0x3d,0x00,0x7f,0xff
,0xd2,0xfe,0xf6,0x7c,0x29,0xff,0x00,0x22,0xbf,0x86,0xff,0x00,0xec,0x01,0xa3,0xff,0x00,0xe9,0xba,0xda,0x80,0x37,0xe8,0x03,0x83,0xf0,0x17,0xfa,0xaf,0x16,0x7f,0xd8
,0xf9,0xe2,0xaf,0xfd,0x2d,0x5a,0x00,0xef,0x28,0x00,0xa0,0x02,0x80,0x0a,0x00,0x28,0x03,0x91,0xf0,0x4f,0xfc,0x81,0xaf,0x7f,0xec,0x6e,0xf8,0x81,0xff,0x00,0xa9,0xe7
,0x89,0x28,0x03,0xae,0xa0,0x02,0x80,0x0a,0x00,0x28,0x00,0xa0,0x0e,0x13,0xe1,0x9f,0xfc,0x89,0x3a,0x2f,0xd7,0x53,0xff,0x00,0xd3,0xc5,0xfd,0x00,0x77,0x74,0x00,0x50
,0x01,0x40,0x05,0x00,0x14,0x01,0xc8,0xfc,0x3f,0xff,0x00,0x91,0x0f,0xc1,0x3f,0xf6,0x28,0xf8,0x6f,0xff,0x00,0x4c,0xd6,0x54,0x01,0xd7,0x50,0x01,0x40,0x05,0x00,0x14
,0x01,0x91,0xe2,0x0f,0xf9,0x00,0xeb,0x7f,0xf6,0x08,0xd4,0xbf,0xf4,0x8e,0x6a,0x00,0xa7,0xe0,0xef,0xf9,0x14,0x7c,0x2d,0xff,0x00,0x62,0xe6,0x87,0xff,0x00,0xa6,0xcb
,0x5a,0x00,0xe8,0xe8,0x00,0xa0,0x02,0x80,0x0a,0x00,0xe4,0xbc,0x7d,0xff,0x00,0x22,0x27,0x8d,0x7f,0xec,0x52,0xf1,0x1f,0xfe,0x99,0xef,0x68,0x03,0xff,0xd3,0xfe,0xf6
,0x7c,0x29,0xff,0x00,0x22,0xbf,0x86,0xff,0x00,0xec,0x01,0xa3,0xff,0x00,0xe9,0xba,0xda,0x80,0x37,0xe8,0x03,0xc7,0x7c,0x2d,0xe1,0xdb,0xad,0x46,0x5f,0x17,0x5c,0xc5
,0xe2,0xaf,0x13,0xe9,0x48,0x7c,0x73,0xe2,0x84,0xfb,0x26,0x99,0x36,0x8d,0x1d,0xaa,0x95,0xbd,0x1f,0x3a,0xad,0xe6,0x87,0x7d,0x36,0xf6,0xc8,0xdc,0x4c,0xe4,0x1c,0x0c
,0x28,0x25,0x8b,0x00,0x75,0x7f,0xf0,0x87,0xdf,0xff,0x00,0xd0,0xf9,0xe3,0x7f,0xfc,0x09,0xf0,0xe7,0xff,0x00,0x32,0xf4,0x00,0x7f,0xc2,0x1f,0x7f,0xff,0x00,0x43,0xe7
,0x8d,0xff,0x00,0xf0,0x27,0xc3,0x9f,0xfc,0xcb,0xd0,0x01,0xff,0x00,0x08,0x7d,0xff,0x00,0xfd,0x0f,0x9e,0x37,0xff,0x00,0xc0,0x9f,0x0e,0x7f,0xf3,0x2f,0x40,0x07,0xfc
,0x21,0xf7,0xff,0x00,0xf4,0x3e,0x78,0xdf,0xff,0x00,0x02,0x7c,0x39,0xff,0x00,0xcc,0xbd,0x00,0x1f,0xf0,0x87,0xdf,0xff,0x00,0xd0,0xf9,0xe3,0x7f,0xfc,0x09,0xf0,0xe7
,0xff,0x00,0x32,0xf4,0x01,0xcc,0x78,0x47,0xc2,0x97,0xb3,0xe9,0x57,0x6e,0xbe,0x35,0xf1,0x8d,0xb0,0x5f,0x14,0x78,0xde,0x1f,0x2e,0xde,0xe3,0x40,0x11,0xb3,0x5b,0xf8
,0xd3,0x5f,0x81,0xa7,0x6f,0x37,0xc3,0x92,0xb7,0x9f,0x74,0xd1,0x1b,0x9b,0x92,0x18,0x46,0x6e,0x66,0x94,0xc3,0x14,0x30,0x94,0x85,0x00,0x3a,0x7f,0xf8,0x43,0xef,0xff
,0x00,0xe8,0x7c,0xf1,0xbf,0xfe,0x04,0xf8,0x73,0xff,0x00,0x99,0x7a,0x00,0x3f,0xe1,0x0f,0xbf,0xff,0x00,0xa1,0xf3,0xc6,0xff,0x00,0xf8,0x13,0xe1,0xcf,0xfe,0x65,0xe8
,0x00,0xff,0x00,0x84,0x3e,0xff,0x00,0xfe,0x87,0xcf,0x1b,0xff,0x00,0xe0,0x4f,0x87,0x3f,0xf9,0x97,0xa0,0x03,0xfe,0x10,0xfb,0xff,0x00,0xfa,0x1f,0x3c,0x6f,0xff,0x00
,0x81,0x3e,0x1c,0xff,0x00,0xe6,0x5e,0x80,0x0f,0xf8,0x43,0xef,0xff,0x00,0xe8,0x7c,0xf1,0xbf,0xfe,0x04,0xf8,0x73,0xff,0x00,0x99,0x7a,0x00,0xe3,0x3e,0x1f,0x78,0x5a
,0xf2,0xe7,0xc2,0x3a,0x4c,0xe9,0xe3,0x3f,0x17,0xda,0x2b,0x9d,0x43,0x16,0xf6,0x93,0xe8,0x2b,0x6f,0x1e,0xdd,0x52,0xf5,0x0f,0x96,0x27,0xf0,0xed,0xc4,0xa3,0x79,0x53
,0x23,0xee,0x99,0xf2,0xee,0xc4,0x6d,0x5d,0xa8,0xa0,0x1d,0x9f,0xfc,0x21,0xf7,0xff,0x00,0xf4,0x3e,0x78,0xdf,0xff,0x00,0x02,0x7c,0x39,0xff,0x00,0xcc,0xbd,0x00,0x1f
,0xf0,0x87,0xdf,0xff,0x00,0xd0,0xf9,0xe3,0x7f,0xfc,0x09,0xf0,0xe7,0xff,0x00,0x32,0xf4,0x00,0x7f,0xc2,0x1f,0x7f,0xff,0x00,0x43,0xe7,0x8d,0xff,0x00,0xf0,0x27,0xc3
,0x9f,0xfc,0xcb,0xd0,0x01,0xff,0x00,0x08,0x7d,0xff,0x00,0xfd,0x0f,0x9e,0x37,0xff,0x00,0xc0,0x9f,0x0e,0x7f,0xf3,0x2f,0x40,0x07,0xfc,0x21,0xf7,0xff,0x00,0xf4,0x3e
,0x78,0xdf,0xff,0x00,0x02,0x7c,0x39,0xff,0x00,0xcc,0xbd,0x00,0x73,0x1e,0x08,0xf0,0xa5,0xed,0xc7,0x82,0xfc,0x23,0x70,0xbe,0x35,0xf1,0x8d,0xaa,0xcf,0xe1,0x8d,0x02
,0x65,0xb6,0xb6,0xb8,0xd0,0x05,0xb5,0xba,0xcb,0xa5,0x5a,0x38,0x82,0xdc,0x4d,0xe1,0xc9,0xa5,0x10,0xc2,0x0f,0x97,0x10,0x96,0x69,0x64,0x08,0xaa,0x1e,0x57,0x6c,0xbb
,0x00,0x74,0xff,0x00,0xf0,0x87,0xdf,0xff,0x00,0xd0,0xf9,0xe3,0x7f,0xfc,0x09,0xf0,0xe7,0xff,0x00,0x32,0xf4,0x00,0x7f,0xc2,0x1f,0x7f,0xff,0x00,0x43,0xe7,0x8d,0xff
,0x00,0xf0,0x27,0xc3,0x9f,0xfc,0xcb,0xd0,0x01,0xff,0x00,0x08,0x7d,0xff,0x00,0xfd,0x0f,0x9e,0x37,0xff,0x00,0xc0,0x9f,0x0e,0x7f,0xf3,0x2f,0x40,0x07,0xfc,0x21,0xf7
,0xff,0x00,0xf4,0x3e,0x78,0xdf,0xff,0x00,0x02,0x7c,0x39,0xff,0x00,0xcc,0xbd,0x00,0x65,0xeb,0x9e,0x11,0xbe,0x8f,0x45,0xd5,0xe4,0x3e,0x39,0xf1,0xa4,0xa1,0x34,0xbd
,0x41,0xcc,0x52,0x5c,0x78,0x78,0xc7,0x20,0x5b,0x49,0x49,0x8e,0x40,0x9e,0x19,0x47,0x28,0xe0,0x6d,0x6d,0xae,0x8d,0xb4,0x9d,0xac,0xa7,0x9a,0x00,0xab,0xe1,0x5f,0x09
,0xde,0xcd,0xe1,0x8f,0x0e,0x4c,0xbe,0x37,0xf1,0x95,0xba,0xcb,0xa0,0xe8,0xf2,0x08,0x20,0xb8,0xf0,0xf8,0x82,0x10,0xfa,0x7d,0xbb,0x08,0xa1,0x12,0x78,0x6a,0x49,0x04
,0x51,0x83,0xb2,0x31,0x24,0x92,0x38,0x45,0x1b,0x9d,0x9b,0x2c,0xc0,0x1b,0xdf,0xf0,0x87,0xdf,0xff,0x00,0xd0,0xf9,0xe3,0x7f,0xfc,0x09,0xf0,0xe7,0xff,0x00,0x32,0xf4
,0x00,0x7f,0xc2,0x1f,0x7f,0xff,0x00,0x43,0xe7,0x8d,0xff,0x00,0xf0,0x27,0xc3,0x9f,0xfc,0xcb,0xd0,0x01,0xff,0x00,0x08,0x7d,0xff,0x00,0xfd,0x0f,0x9e,0x37,0xff,0x00
,0xc0,0x9f,0x0e,0x7f,0xf3,0x2f,0x40,0x07,0xfc,0x21,0xf7,0xff,0x00,0xf4,0x3e,0x78,0xdf,0xff,0x00,0x02,0x7c,0x39,0xff,0x00,0xcc,0xbd,0x00,0x73,0x3e,0x35,0xf0,0xad
,0xed,0xbf,0x83,0x7c,0x5b,0x70,0xfe,0x35,0xf1,0x85,0xd2,0xc1,0xe1,0x9d,0x7a,0x66,0xb5,0xb9,0xb8,0xd0,0x0d,0xb5,0xca,0xc5,0xa5,0x5d,0x39,0x82,0xe0,0x43,0xe1,0xc8
,0x26,0x30,0x4c,0x17,0xcb,0x94,0x45,0x3c,0x32,0x18,0xd9,0x84,0x72,0xc6,0xe4,0x3a,0x80,0x7f,0xff,0xd4,0xfe,0xf6,0x7c,0x29,0xff,0x00,0x22,0xbf,0x86,0xff,0x00,0xec
,0x01,0xa3,0xff,0x00,0xe9,0xba,0xda,0x80,0x37,0xe8,0x03,0xc6,0xfc,0x2f,0xe2,0x69,0x34,0xb9,0x7c,0x5d,0x6a,0xbe,0x18,0xf1,0x4e,0xa8,0x07,0x8e,0x7c,0x50,0xff,0x00
,0x6a,0xd2,0xac,0x2d,0x2e,0x2d,0x0e,0xeb,0xec,0x6c,0x12,0x4b,0x7f,0x6e,0xfb,0xd7,0x1f,0x30,0x31,0xf0,0x0a,0x90,0x4e,0x7e,0x50,0x0e,0xab,0xfe,0x13,0x79,0xbf,0xe8
,0x48,0xf1,0xd7,0xfe,0x0a,0x6c,0x3f,0xf9,0x6d,0x40,0x07,0xfc,0x26,0xf3,0x7f,0xd0,0x91,0xe3,0xaf,0xfc,0x14,0xd8,0x7f,0xf2,0xda,0x80,0x0f,0xf8,0x4d,0xe6,0xff,0x00
,0xa1,0x23,0xc7,0x5f,0xf8,0x29,0xb0,0xff,0x00,0xe5,0xb5,0x00,0x1f,0xf0,0x9b,0xcd,0xff,0x00,0x42,0x47,0x8e,0xbf,0xf0,0x53,0x61,0xff,0x00,0xcb,0x6a,0x00,0x3f,0xe1
,0x37,0x9b,0xfe,0x84,0x8f,0x1d,0x7f,0xe0,0xa6,0xc3,0xff,0x00,0x96,0xd4,0x01,0xcc,0x78,0x47,0xc6,0x12,0xdb,0xe9,0x57,0x71,0x8f,0x07,0x78,0xce,0xe3,0x77,0x89,0xfc
,0x6d,0x3f,0x99,0x6f,0xa6,0x59,0x3c,0x6a,0x6e,0x7c,0x67,0xaf,0xdc,0x98,0x18,0xb6,0xa6,0x84,0x4f,0x6c,0x65,0xfb,0x35,0xd2,0x60,0xaa,0x5c,0xc5,0x2a,0x2b,0x3a,0xa8
,0x76,0x00,0xe9,0xff,0x00,0xe1,0x37,0x9b,0xfe,0x84,0x8f,0x1d,0x7f,0xe0,0xa6,0xc3,0xff,0x00,0x96,0xd4,0x00,0x7f,0xc2,0x6f,0x37,0xfd,0x09,0x1e,0x3a,0xff,0x00,0xc1
,0x4d,0x87,0xff,0x00,0x2d,0xa8,0x00,0xff,0x00,0x84,0xde,0x6f,0xfa,0x12,0x3c,0x75,0xff,0x00,0x82,0x9b,0x0f,0xfe,0x5b,0x50,0x01,0xff,0x00,0x09,0xbc,0xdf,0xf4,0x24
,0x78,0xeb,0xff,0x00,0x05,0x36,0x1f,0xfc,0xb6,0xa0,0x03,0xfe,0x13,0x79,0xbf,0xe8,0x48,0xf1,0xd7,0xfe,0x0a,0x6c,0x3f,0xf9,0x6d,0x40,0x1c,0x6f,0xc3,0xff,0x00,0x17
,0xcb,0x69,0xe1,0x1d,0x26,0xdc,0x78,0x43,0xc6,0x37,0x61,0x0e,0xa1,0xfb,0xfb,0x4d,0x36,0xca,0x4b,0x79,0x37,0xea,0x97,0xaf,0xfb,0xb7,0x7d,0x4e,0x36,0x3b,0x37,0x6c
,0x7c,0xa2,0xe1,0xd5,0x86,0x06,0x06,0xe0,0x0e,0xcb,0xfe,0x13,0x79,0xbf,0xe8,0x48,0xf1,0xd7,0xfe,0x0a,0x6c,0x3f,0xf9,0x6d,0x40,0x07,0xfc,0x26,0xf3,0x7f,0xd0,0x91
,0xe3,0xaf,0xfc,0x14,0xd8,0x7f,0xf2,0xda,0x80,0x0f,0xf8,0x4d,0xe6,0xff,0x00,0xa1,0x23,0xc7,0x5f,0xf8,0x29,0xb0,0xff,0x00,0xe5,0xb5,0x00,0x1f,0xf0,0x9b,0xcd,0xff
,0x00,0x42,0x47,0x8e,0xbf,0xf0,0x53,0x61,0xff,0x00,0xcb,0x6a,0x00,0x3f,0xe1,0x37,0x9b,0xfe,0x84,0x8f,0x1d,0x7f,0xe0,0xa6,0xc3,0xff,0x00,0x96,0xd4,0x01,0xcc,0x78
,0x27,0xc6,0x12,0xdb,0x78,0x33,0xc2,0x36,0xc3,0xc1,0xde,0x33,0xb9,0x16,0xfe,0x18,0xd0,0x20,0x17,0x36,0xba,0x65,0x94,0x96,0xd7,0x02,0x2d,0x2a,0xd1,0x3c,0xfb,0x77
,0x6d,0x4d,0x19,0xe0,0x97,0x6f,0x99,0x13,0xb2,0x23,0x34,0x6c,0xa4,0xaa,0x92,0x45,0x00,0x74,0xff,0x00,0xf0,0x9b,0xcd,0xff,0x00,0x42,0x47,0x8e,0xbf,0xf0,0x53,0x61
,0xff,0x00,0xcb,0x6a,0x00,0x3f,0xe1,0x37,0x9b,0xfe,0x84,0x8f,0x1d,0x7f,0xe0,0xa6,0xc3,0xff,0x00,0x96,0xd4,0x00,0x7f,0xc2,0x6f,0x37,0xfd,0x09,0x1e,0x3a,0xff,0x00
,0xc1,0x4d,0x87,0xff,0x00,0x2d,0xa8,0x00,0xff,0x00,0x84,0xde,0x6f,0xfa,0x12,0x3c,0x75,0xff,0x00,0x82,0x9b,0x0f,0xfe,0x5b,0x50,0x06,0x5e,0xb7,0xe3,0x49,0xa4,0xd1
,0x75,0x78,0xff,0x00,0xe1,0x0b,0xf1,0xbc,0x7e,0x66,0x97,0x7e,0x9e,0x64,0xba,0x5d,0x8a,0xc7,0x1e,0xfb,0x49,0x57,0x7c,0x8c,0x35,0x46,0x21,0x13,0x3b,0x9c,0x85,0x62
,0x14,0x12,0x01,0xc6,0x28,0x02,0xaf,0x85,0xbc,0x65,0x34,0x1e,0x18,0xf0,0xe4,0x23,0xc1,0xbe,0x35,0x9c,0x43,0xa0,0xe9,0x11,0x09,0xe0,0xd2,0xec,0x5e,0x09,0xbc,0xbd
,0x3e,0xdd,0x3c,0xd8,0x5d,0xb5,0x34,0x66,0x8a,0x4c,0x6f,0x8d,0x8a,0x21,0x64,0x60,0x4a,0xae,0x71,0x40,0x1b,0xdf,0xf0,0x9b,0xcd,0xff,0x00,0x42,0x47,0x8e,0xbf,0xf0
,0x53,0x61,0xff,0x00,0xcb,0x6a,0x00,0x3f,0xe1,0x37,0x9b,0xfe,0x84,0x8f,0x1d,0x7f,0xe0,0xa6,0xc3,0xff,0x00,0x96,0xd4,0x00,0x7f,0xc2,0x6f,0x37,0xfd,0x09,0x1e,0x3a
,0xff,0x00,0xc1,0x4d,0x87,0xff,0x00,0x2d,0xa8,0x00,0xff,0x00,0x84,0xde,0x6f,0xfa,0x12,0x3c,0x75,0xff,0x00,0x82,0x9b,0x0f,0xfe,0x5b,0x50,0x07,0x33,0xe3,0x5f,0x18
,0x4b,0x73,0xe0,0xdf,0x16,0xdb,0x9f,0x07,0x78,0xce,0xd8,0x5c,0x78,0x67,0x5e,0x84,0xdc,0xdd,0x69,0x96,0x51,0xdb,0x5b,0x89,0x74,0xab,0xb4,0x33,0xdc,0x3a,0x6a,0x72
,0x3a,0x41,0x10,0x6f,0x32,0x57,0x58,0xe4,0x65,0x8d,0x58,0xaa,0x31,0x1b,0x58,0x03,0xff,0xd5,0xfe,0xf6,0x7c,0x29,0xff,0x00,0x22,0xbf,0x86,0xff,0x00,0xec,0x01,0xa3
,0xff,0x00,0xe9,0xba,0xda,0x80,0x37,0xe8,0x03,0x83,0xf0,0x17,0xfa,0xaf,0x16,0x7f,0xd8,0xf9,0xe2,0xaf,0xfd,0x2d,0x5a,0x00,0xef,0x28,0x00,0xa0,0x02,0x80,0x0a,0x00
,0x28,0x03,0x91,0xf0,0x4f,0xfc,0x81,0xaf,0x7f,0xec,0x6e,0xf8,0x81,0xff,0x00,0xa9,0xe7,0x89,0x28,0x03,0xae,0xa0,0x02,0x80,0x0a,0x00,0x28,0x00,0xa0,0x0e,0x13,0xe1
,0x9f,0xfc,0x89,0x3a,0x2f,0xd7,0x53,0xff,0x00,0xd3,0xc5,0xfd,0x00,0x77,0x74,0x00,0x50,0x01,0x40,0x05,0x00,0x14,0x01,0xc8,0xfc,0x3f,0xff,0x00,0x91,0x0f,0xc1,0x3f
,0xf6,0x28,0xf8,0x6f,0xff,0x00,0x4c,0xd6,0x54,0x01,0xd7,0x50,0x01,0x40,0x05,0x00,0x14,0x01,0x91,0xe2,0x0f,0xf9,0x00,0xeb,0x7f,0xf6,0x08,0xd4,0xbf,0xf4,0x8e,0x6a
,0x00,0xa7,0xe0,0xef,0xf9,0x14,0x7c,0x2d,0xff,0x00,0x62,0xe6,0x87,0xff,0x00,0xa6,0xcb,0x5a,0x00,0xe8,0xe8,0x00,0xa0,0x02,0x80,0x0a,0x00,0xe4,0xbc,0x7d,0xff,0x00
,0x22,0x27,0x8d,0x7f,0xec,0x52,0xf1,0x1f,0xfe,0x99,0xef,0x68,0x03,0xff,0xd6,0xfe,0xf6,0x7c,0x29,0xff,0x00,0x22,0xbf,0x86,0xff,0x00,0xec,0x01,0xa3,0xff,0x00,0xe9
,0xba,0xda,0x80,0x37,0xe8,0x03,0xc8,0xfc,0x25,0xe1,0x9d,0x3b,0x53,0x7f,0x17,0x5d,0x5c,0x5c,0xf8,0x82,0x39,0x5b,0xc7,0x5e,0x28,0x52,0xba,0x7f,0x8b,0x3c,0x55,0xa4
,0xdb,0xe1,0x6f,0x86,0x08,0xb3,0xd2,0xf5,0x9b,0x2b,0x45,0x6e,0x79,0x75,0x80,0x3b,0x0c,0x02,0xc4,0x28,0xa0,0x0e,0xbf,0xfe,0x10,0xad,0x1f,0xfe,0x7f,0x7c,0x5b,0xff
,0x00,0x85,0xf7,0x8e,0xff,0x00,0xf9,0xa4,0xa0,0x03,0xfe,0x10,0xad,0x1f,0xfe,0x7f,0x7c,0x5b,0xff,0x00,0x85,0xf7,0x8e,0xff,0x00,0xf9,0xa4,0xa0,0x03,0xfe,0x10,0xad
,0x1f,0xfe,0x7f,0x7c,0x5b,0xff,0x00,0x85,0xf7,0x8e,0xff,0x00,0xf9,0xa4,0xa0,0x03,0xfe,0x10,0xad,0x1f,0xfe,0x7f,0x7c,0x5b,0xff,0x00,0x85,0xf7,0x8e,0xff,0x00,0xf9
,0xa4,0xa0,0x03,0xfe,0x10,0xad,0x1f,0xfe,0x7f,0x7c,0x5b,0xff,0x00,0x85,0xf7,0x8e,0xff,0x00,0xf9,0xa4,0xa0,0x0e,0x5b,0xc1,0xfe,0x10,0xd2,0x67,0xd2,0x6e,0xdd,0xee
,0xfc,0x50,0xac,0xbe,0x29,0xf1,0xcc,0x20,0x43,0xe3,0x7f,0x1a,0x5b,0x26,0xcb,0x6f,0x1a,0xf8,0x82,0xde,0x32,0x63,0xb7,0xf1,0x04,0x51,0xb4,0xad,0x1c,0x4a,0xd3,0xce
,0xca,0x67,0xba,0x9c,0xc9,0x75,0x73,0x24,0xb7,0x32,0xcd,0x2c,0xa0,0x1d,0x4f,0xfc,0x21,0x5a,0x3f,0xfc,0xfe,0xf8,0xb7,0xff,0x00,0x0b,0xef,0x1d,0xff,0x00,0xf3,0x49
,0x40,0x07,0xfc,0x21,0x5a,0x3f,0xfc,0xfe,0xf8,0xb7,0xff,0x00,0x0b,0xef,0x1d,0xff,0x00,0xf3,0x49,0x40,0x07,0xfc,0x21,0x5a,0x3f,0xfc,0xfe,0xf8,0xb7,0xff,0x00,0x0b
,0xef,0x1d,0xff,0x00,0xf3,0x49,0x40,0x07,0xfc,0x21,0x5a,0x3f,0xfc,0xfe,0xf8,0xb7,0xff,0x00,0x0b,0xef,0x1d,0xff,0x00,0xf3,0x49,0x40,0x07,0xfc,0x21,0x5a,0x3f,0xfc
,0xfe,0xf8,0xb7,0xff,0x00,0x0b,0xef,0x1d,0xff,0x00,0xf3,0x49,0x40,0x1c,0x5f,0xc3,0xcf,0x09,0x69,0x57,0x5e,0x0f,0xd2,0x27,0x96,0xef,0xc4,0xca,0xf2,0x1d,0x47,0x72
,0xdb,0x78,0xd7,0xc6,0x56,0x70,0x8d,0xba,0xad,0xf2,0x0d,0x96,0xd6,0x9a,0xfc,0x16,0xf1,0xe4,0x28,0x2d,0xe5,0xc4,0x9b,0xdc,0xb4,0x8f,0xb9,0xd9,0xd9,0x80,0x3b,0x4f
,0xf8,0x42,0xb4,0x7f,0xf9,0xfd,0xf1,0x6f,0xfe,0x17,0xde,0x3b,0xff,0x00,0xe6,0x92,0x80,0x0f,0xf8,0x42,0xb4,0x7f,0xf9,0xfd,0xf1,0x6f,0xfe,0x17,0xde,0x3b,0xff,0x00
,0xe6,0x92,0x80,0x0f,0xf8,0x42,0xb4,0x7f,0xf9,0xfd,0xf1,0x6f,0xfe,0x17,0xde,0x3b,0xff,0x00,0xe6,0x92,0x80,0x0f,0xf8,0x42,0xb4,0x7f,0xf9,0xfd,0xf1,0x6f,0xfe,0x17
,0xde,0x3b,0xff,0x00,0xe6,0x92,0x80,0x0f,0xf8,0x42,0xb4,0x7f,0xf9,0xfd,0xf1,0x6f,0xfe,0x17,0xde,0x3b,0xff,0x00,0xe6,0x92,0x80,0x39,0x6f,0x03,0x78,0x43,0x49,0xb9
,0xf0,0x57,0x83,0xee,0x24,0xbb,0xf1,0x42,0xc9,0x3f,0x85,0xbc,0x3f,0x33,0xac,0x1e,0x37,0xf1,0xa5,0xac,0x0a,0xf2,0xe9,0x36,0x8e,0xc2,0x1b,0x5b,0x5f,0x10,0x43,0x6d
,0x6d,0x10,0x66,0x22,0x38,0x2d,0xe2,0x8a,0x08,0x53,0x11,0xc3,0x1a,0x46,0xaa,0x94,0x01,0xd4,0xff,0x00,0xc2,0x15,0xa3,0xff,0x00,0xcf,0xef,0x8b,0x7f,0xf0,0xbe,0xf1
,0xdf,0xff,0x00,0x34,0x94,0x00,0x7f,0xc2,0x15,0xa3,0xff,0x00,0xcf,0xef,0x8b,0x7f,0xf0,0xbe,0xf1,0xdf,0xff,0x00,0x34,0x94,0x00,0x7f,0xc2,0x15,0xa3,0xff,0x00,0xcf
,0xef,0x8b,0x7f,0xf0,0xbe,0xf1,0xdf,0xff,0x00,0x34,0x94,0x00,0x7f,0xc2,0x15,0xa3,0xff,0x00,0xcf,0xef,0x8b,0x7f,0xf0,0xbe,0xf1,0xdf,0xff,0x00,0x34,0x94,0x01,0x97
,0xae,0x78,0x37,0x48,0x8b,0x45,0xd6,0x24,0x5b,0xcf,0x15,0x16,0x8f,0x4b,0xd4,0x1d,0x44,0x9e,0x3b,0xf1,0xbc,0xb1,0x96,0x4b,0x49,0x58,0x07,0x8a,0x5f,0x11,0x3c,0x52
,0x21,0x23,0xe6,0x8e,0x44,0x78,0xdc,0x7c,0xae,0xac,0xa4,0x8a,0x00,0xa9,0xe1,0x4f,0x07,0x69,0x33,0xf8,0x5f,0xc3,0x73,0x3d,0xe7,0x8a,0x55,0xe6,0xd0,0x34,0x79,0x5d
,0x61,0xf1,0xcf,0x8d,0xad,0xe2,0x0d,0x26,0x9d,0x6c,0xec,0x22,0x82,0x0f,0x10,0xc7,0x04,0x31,0x82,0x48,0x48,0x61,0x8e,0x38,0xa3,0x5c,0x24,0x68,0xa8,0x15,0x54,0x03
,0x7f,0xfe,0x10,0xad,0x1f,0xfe,0x7f,0x7c,0x5b,0xff,0x00,0x85,0xf7,0x8e,0xff,0x00,0xf9,0xa4,0xa0,0x03,0xfe,0x10,0xad,0x1f,0xfe,0x7f,0x7c,0x5b,0xff,0x00,0x85,0xf7
,0x8e,0xff,0x00,0xf9,0xa4,0xa0,0x03,0xfe,0x10,0xad,0x1f,0xfe,0x7f,0x7c,0x5b,0xff,0x00,0x85,0xf7,0x8e,0xff,0x00,0xf9,0xa4,0xa0,0x03,0xfe,0x10,0xad,0x1f,0xfe,0x7f
,0x7c,0x5b,0xff,0x00,0x85,0xf7,0x8e,0xff,0x00,0xf9,0xa4,0xa0,0x0e,0x5f,0xc6,0xfe,0x10,0xd2,0x6d,0xbc,0x17,0xe2,0xfb,0x88,0xee,0xfc,0x50,0xd2,0x5b,0xf8,0x5f,0x5f
,0x99,0x16,0x7f,0x1b,0xf8,0xd2,0xea,0x06,0x78,0xb4,0xab,0xb7,0x55,0x9a,0xd6,0xeb,0xc4,0x13,0x5b,0x5c,0xc4,0x59,0x40,0x92,0x0b,0x88,0xa5,0x82,0x64,0xcc,0x73,0x46
,0xf1,0xb3,0x25,0x00,0x7f,0xff,0xd7,0xfe,0xf6,0x7c,0x29,0xff,0x00,0x22,0xbf,0x86,0xff,0x00,0xec,0x01,0xa3,0xff,0x00,0xe9,0xba,0xda,0x80,0x37,0xe8,0x03,0xc7,0xfc
,0x2b,0xad,0x6b,0x36,0x72,0x78,0xba,0x0b,0x2f,0x08,0x6b,0x1a,0xbc,0x03,0xc7,0x5e,0x28,0x61,0x79,0x67,0xa8,0x78,0x6a,0xde,0x16,0x63,0x7d,0xca,0x08,0xf5,0x2d,0x6a
,0xce,0xe8,0x15,0xc0,0x24,0xb4,0x01,0x48,0x61,0x82,0x48,0x22,0x80,0x3a,0xcf,0xf8,0x49,0x3c,0x47,0xff,0x00,0x44,0xf7,0xc4,0x5f,0xf8,0x37,0xf0,0x5f,0xff,0x00,0x34
,0x94,0x00,0x7f,0xc2,0x49,0xe2,0x3f,0xfa,0x27,0xbe,0x22,0xff,0x00,0xc1,0xbf,0x82,0xff,0x00,0xf9,0xa4,0xa0,0x03,0xfe,0x12,0x4f,0x11,0xff,0x00,0xd1,0x3d,0xf1,0x17
,0xfe,0x0d,0xfc,0x17,0xff,0x00,0xcd,0x25,0x00,0x1f,0xf0,0x92,0x78,0x8f,0xfe,0x89,0xef,0x88,0xbf,0xf0,0x6f,0xe0,0xbf,0xfe,0x69,0x28,0x00,0xff,0x00,0x84,0x93,0xc4
,0x7f,0xf4,0x4f,0x7c,0x45,0xff,0x00,0x83,0x7f,0x05,0xff,0x00,0xf3,0x49,0x40,0x1c,0xbf,0x84,0x3c,0x41,0xaf,0xc5,0xa4,0xdd,0xac,0x5e,0x04,0xd7,0xae,0x54,0xf8,0xa3
,0xc6,0xf2,0x19,0x22,0xd5,0x3c,0x22,0x8a,0xb2,0x4d,0xe3,0x4d,0x7e,0x59,0xad,0xc8,0x9f,0xc4,0x11,0x39,0x92,0xd2,0x57,0x7b,0x59,0x5d,0x54,0xc3,0x24,0xb0,0xbc,0x96
,0xf2,0x4b,0x6e,0xd1,0x4b,0x28,0x07,0x51,0xff,0x00,0x09,0x27,0x88,0xff,0x00,0xe8,0x9e,0xf8,0x8b,0xff,0x00,0x06,0xfe,0x0b,0xff,0x00,0xe6,0x92,0x80,0x0f,0xf8,0x49
,0x3c,0x47,0xff,0x00,0x44,0xf7,0xc4,0x5f,0xf8,0x37,0xf0,0x5f,0xff,0x00,0x34,0x94,0x00,0x7f,0xc2,0x49,0xe2,0x3f,0xfa,0x27,0xbe,0x22,0xff,0x00,0xc1,0xbf,0x82,0xff
,0x00,0xf9,0xa4,0xa0,0x03,0xfe,0x12,0x4f,0x11,0xff,0x00,0xd1,0x3d,0xf1,0x17,0xfe,0x0d,0xfc,0x17,0xff,0x00,0xcd,0x25,0x00,0x1f,0xf0,0x92,0x78,0x8f,0xfe,0x89,0xef
,0x88,0xbf,0xf0,0x6f,0xe0,0xbf,0xfe,0x69,0x28,0x03,0x8c,0xf8,0x7b,0xaf,0xeb,0xd0,0x78,0x43,0x49,0x8a,0x0f,0x03,0xeb,0xb7,0xb1,0x29,0xd4,0x76,0xdc,0xc3,0xa9,0xf8
,0x4e,0x28,0xe4,0xdd,0xaa,0xdf,0x31,0xda,0x97,0x5a,0xfc,0x33,0xae,0xc6,0x26,0x36,0xdf,0x12,0xe5,0x90,0x94,0xdc,0x85,0x5d,0x80,0x3b,0x3f,0xf8,0x49,0x3c,0x47,0xff
,0x00,0x44,0xf7,0xc4,0x5f,0xf8,0x37,0xf0,0x5f,0xff,0x00,0x34,0x94,0x00,0x7f,0xc2,0x49,0xe2,0x3f,0xfa,0x27,0xbe,0x22,0xff,0x00,0xc1,0xbf,0x82,0xff,0x00,0xf9,0xa4
,0xa0,0x03,0xfe,0x12,0x4f,0x11,0xff,0x00,0xd1,0x3d,0xf1,0x17,0xfe,0x0d,0xfc,0x17,0xff,0x00,0xcd,0x25,0x00,0x1f,0xf0,0x92,0x78,0x8f,0xfe,0x89,0xef,0x88,0xbf,0xf0
,0x6f,0xe0,0xbf,0xfe,0x69,0x28,0x00,0xff,0x00,0x84,0x93,0xc4,0x7f,0xf4,0x4f,0x7c,0x45,0xff,0x00,0x83,0x7f,0x05,0xff,0x00,0xf3,0x49,0x40,0x1c,0xbf,0x82,0x3c,0x41
,0xaf,0xc3,0xe0,0xbf,0x08,0x43,0x0f,0x81,0x35,0xeb,0xb8,0xa2,0xf0,0xbe,0x81,0x1c,0x57,0x51,0x6a,0x9e,0x11,0x8e,0x2b,0x98,0xd3,0x4a,0xb4,0x54,0xb8,0x8a,0x3b,0x8f
,0x10,0x43,0x70,0x91,0xcc,0xa0,0x48,0x89,0x3c,0x51,0x4c,0xaa,0xc0,0x4b,0x1a,0x38,0x64,0xa0,0x0e,0xa3,0xfe,0x12,0x4f,0x11,0xff,0x00,0xd1,0x3d,0xf1,0x17,0xfe,0x0d
,0xfc,0x17,0xff,0x00,0xcd,0x25,0x00,0x1f,0xf0,0x92,0x78,0x8f,0xfe,0x89,0xef,0x88,0xbf,0xf0,0x6f,0xe0,0xbf,0xfe,0x69,0x28,0x00,0xff,0x00,0x84,0x93,0xc4,0x7f,0xf4
,0x4f,0x7c,0x45,0xff,0x00,0x83,0x7f,0x05,0xff,0x00,0xf3,0x49,0x40,0x07,0xfc,0x24,0x9e,0x23,0xff,0x00,0xa2,0x7b,0xe2,0x2f,0xfc,0x1b,0xf8,0x2f,0xff,0x00,0x9a,0x4a
,0x00,0xcb,0xd7,0x3c,0x45,0xe2,0x17,0xd1,0x75,0x74,0x7f,0x00,0x78,0x82,0x24,0x6d,0x2f,0x50,0x56,0x95,0xf5,0x6f,0x07,0x32,0x44,0xad,0x69,0x28,0x69,0x19,0x63,0xf1
,0x13,0xc8,0x55,0x01,0x2c,0xc2,0x34,0x77,0x20,0x61,0x55,0x98,0x81,0x40,0x15,0x7c,0x2b,0xe2,0x1f,0x10,0x45,0xe1,0x7f,0x0d,0xc7,0x1f,0x80,0xf5,0xfb,0x88,0xe3,0xd0
,0x74,0x74,0x8e,0xe2,0x3d,0x57,0xc2,0x09,0x1c,0xe8,0x9a,0x7d,0xb2,0xa4,0xd1,0xa4,0xde,0x21,0x8e,0x65,0x49,0x54,0x07,0x55,0x96,0x38,0xe5,0x55,0x60,0x24,0x45,0x70
,0xca,0xa0,0x1b,0xdf,0xf0,0x92,0x78,0x8f,0xfe,0x89,0xef,0x88,0xbf,0xf0,0x6f,0xe0,0xbf,0xfe,0x69,0x28,0x00,0xff,0x00,0x84,0x93,0xc4,0x7f,0xf4,0x4f,0x7c,0x45,0xff
,0x00,0x83,0x7f,0x05,0xff,0x00,0xf3,0x49,0x40,0x07,0xfc,0x24,0x9e,0x23,0xff,0x00,0xa2,0x7b,0xe2,0x2f,0xfc,0x1b,0xf8,0x2f,0xff,0x00,0x9a,0x4a,0x00,0x3f,0xe1,0x24
,0xf1,0x1f,0xfd,0x13,0xdf,0x11,0x7f,0xe0,0xdf,0xc1,0x7f,0xfc,0xd2,0x50,0x07,0x31,0xe3,0x6f,0x10,0x6b,0xf3,0x78,0x33,0xc5,0xd0,0xcd,0xe0,0x5d,0x7a,0xd2,0x29,0x7c
,0x31,0xaf,0xc7,0x2d,0xd4,0xda,0xa7,0x84,0xa4,0x8a,0xda,0x37,0xd2,0xae,0xd5,0xee,0x25,0x4b,0x6f,0x10,0x4d,0x70,0xf1,0xc2,0xa4,0xc8,0xe9,0x04,0x32,0xcc,0xca,0xa4
,0x45,0x13,0xb9,0x54,0x60,0x0f,0xff,0xd0,0xfe,0xf6,0x7c,0x29,0xff,0x00,0x22,0xbf,0x86,0xff,0x00,0xec,0x01,0xa3,0xff,0x00,0xe9,0xba,0xda,0x80,0x37,0xe8,0x03,0x83
,0xf0,0x17,0xfa,0xaf,0x16,0x7f,0xd8,0xf9,0xe2,0xaf,0xfd,0x2d,0x5a,0x00,0xef,0x28,0x00,0xa0,0x02,0x80,0x0a,0x00,0x28,0x03,0x91,0xf0,0x4f,0xfc,0x81,0xaf,0x7f,0xec
,0x6e,0xf8,0x81,0xff,0x00,0xa9,0xe7,0x89,0x28,0x03,0xae,0xa0,0x02,0x80,0x0a,0x00,0x28,0x00,0xa0,0x0e,0x13,0xe1,0x9f,0xfc,0x89,0x3a,0x2f,0xd7,0x53,0xff,0x00,0xd3
,0xc5,0xfd,0x00,0x77,0x74,0x00,0x50,0x01,0x40,0x05,0x00,0x14,0x01,0xc8,0xfc,0x3f,0xff,0x00,0x91,0x0f,0xc1,0x3f,0xf6,0x28,0xf8,0x6f,0xff,0x00,0x4c,0xd6,0x54,0x01
,0xd7,0x50,0x01,0x40,0x05,0x00,0x14,0x01,0x91,0xe2,0x0f,0xf9,0x00,0xeb,0x7f,0xf6,0x08,0xd4,0xbf,0xf4,0x8e,0x6a,0x00,0xa7,0xe0,0xef,0xf9,0x14,0x7c,0x2d,0xff,0x00
,0x62,0xe6,0x87,0xff,0x00,0xa6,0xcb,0x5a,0x00,0xe8,0xe8,0x00,0xa0,0x02,0x80,0x0a,0x00,0xe4,0xbc,0x7d,0xff,0x00,0x22,0x27,0x8d,0x7f,0xec,0x52,0xf1,0x1f,0xfe,0x99
,0xef,0x68,0x03,0xff,0xd1,0xfe,0xf6,0x7c,0x29,0xff,0x00,0x22,0xbf,0x86,0xff,0x00,0xec,0x01,0xa3,0xff,0x00,0xe9,0xba,0xda,0x80,0x37,0xe8,0x03,0xc6,0xfc,0x2f,0xe0
,0xbf,0x0c,0x6b,0x72,0xf8,0xba,0xfb,0x54,0xd2,0xa3,0xbb,0xbb,0x6f,0x1c,0xf8,0x9e,0x33,0x33,0x4f,0x77,0x19,0x28,0x97,0xd9,0x55,0xdb,0x0d,0xd4,0x49,0xc6,0xe3,0xce
,0xdc,0xf3,0x82,0x7a,0x05,0x00,0xea,0xbf,0xe1,0x5a,0x78,0x1f,0xfe,0x80,0x10,0xff,0x00,0xe0,0x56,0xa3,0xff,0x00,0xc9,0xd4,0x00,0x7f,0xc2,0xb4,0xf0,0x3f,0xfd,0x00
,0x21,0xff,0x00,0xc0,0xad,0x47,0xff,0x00,0x93,0xa8,0x00,0xff,0x00,0x85,0x69,0xe0,0x7f,0xfa,0x00,0x43,0xff,0x00,0x81,0x5a,0x8f,0xff,0x00,0x27,0x50,0x01,0xff,0x00
,0x0a,0xd3,0xc0,0xff,0x00,0xf4,0x00,0x87,0xff,0x00,0x02,0xb5,0x1f,0xfe,0x4e,0xa0,0x03,0xfe,0x15,0xa7,0x81,0xff,0x00,0xe8,0x01,0x0f,0xfe,0x05,0x6a,0x3f,0xfc,0x9d
,0x40,0x1c,0xc7,0x84,0x7e,0x1e,0xf8,0x3a,0xef,0x4a,0xbb,0x96,0xe3,0x44,0x8a,0x49,0x13,0xc4,0xfe,0x36,0xb6,0x56,0x37,0x37,0xe3,0x10,0x59,0x78,0xcf,0x5f,0xb3,0xb6
,0x8f,0x0b,0x7a,0xa3,0x11,0x5b,0x41,0x0c,0x40,0x91,0xb9,0x82,0x02,0xec,0xee,0x5d,0xe8,0x03,0xa7,0xff,0x00,0x85,0x69,0xe0,0x7f,0xfa,0x00,0x43,0xff,0x00,0x81,0x5a
,0x8f,0xff,0x00,0x27,0x50,0x01,0xff,0x00,0x0a,0xd3,0xc0,0xff,0x00,0xf4,0x00,0x87,0xff,0x00,0x02,0xb5,0x1f,0xfe,0x4e,0xa0,0x03,0xfe,0x15,0xa7,0x81,0xff,0x00,0xe8
,0x01,0x0f,0xfe,0x05,0x6a,0x3f,0xfc,0x9d,0x40,0x07,0xfc,0x2b,0x4f,0x03,0xff,0x00,0xd0,0x02,0x1f,0xfc,0x0a,0xd4,0x7f,0xf9,0x3a,0x80,0x0f,0xf8,0x56,0x9e,0x07,0xff
,0x00,0xa0,0x04,0x3f,0xf8,0x15,0xa8,0xff,0x00,0xf2,0x75,0x00,0x71,0xbf,0x0f,0xbe,0x1f,0xf8,0x3e,0xfb,0xc2,0x3a,0x4d,0xd5,0xd6,0x8b,0x14,0xd3,0xca,0x75,0x0d,0xf2
,0x1b,0x9b,0xe5,0x2d,0xe5,0xea,0x97,0xd1,0x27,0x09,0x78,0x8b,0xf2,0xc6,0x8a,0xbc,0x2a,0xe7,0x6e,0x4f,0x27,0x2c,0x01,0xd9,0x7f,0xc2,0xb4,0xf0,0x3f,0xfd,0x00,0x21
,0xff,0x00,0xc0,0xad,0x47,0xff,0x00,0x93,0xa8,0x00,0xff,0x00,0x85,0x69,0xe0,0x7f,0xfa,0x00,0x43,0xff,0x00,0x81,0x5a,0x8f,0xff,0x00,0x27,0x50,0x01,0xff,0x00,0x0a
,0xd3,0xc0,0xff,0x00,0xf4,0x00,0x87,0xff,0x00,0x02,0xb5,0x1f,0xfe,0x4e,0xa0,0x03,0xfe,0x15,0xa7,0x81,0xff,0x00,0xe8,0x01,0x0f,0xfe,0x05,0x6a,0x3f,0xfc,0x9d,0x40
,0x07,0xfc,0x2b,0x4f,0x03,0xff,0x00,0xd0,0x02,0x1f,0xfc,0x0a,0xd4,0x7f,0xf9,0x3a,0x80,0x39,0x8f,0x04,0xfc,0x3d,0xf0,0x75,0xef,0x83,0x3c,0x23,0x79,0x73,0xa2,0x45
,0x2d,0xcd,0xdf,0x86,0x34,0x0b,0x9b,0x89,0x4d,0xcd,0xf8,0x32,0x4f,0x3e,0x95,0x6b,0x2c,0xb2,0x10,0x97,0xaa,0x80,0xbc,0x8c,0xcc,0x42,0xaa,0xa8,0xce,0x15,0x40,0x18
,0x50,0x0e,0x9f,0xfe,0x15,0xa7,0x81,0xff,0x00,0xe8,0x01,0x0f,0xfe,0x05,0x6a,0x3f,0xfc,0x9d,0x40,0x07,0xfc,0x2b,0x4f,0x03,0xff,0x00,0xd0,0x02,0x1f,0xfc,0x0a,0xd4
,0x7f,0xf9,0x3a,0x80,0x0f,0xf8,0x56,0x9e,0x07,0xff,0x00,0xa0,0x04,0x3f,0xf8,0x15,0xa8,0xff,0x00,0xf2,0x75,0x00,0x1f,0xf0,0xad,0x3c,0x0f,0xff,0x00,0x40,0x08,0x7f
,0xf0,0x2b,0x51,0xff,0x00,0xe4,0xea,0x00,0xcb,0xd6,0xfe,0x1c,0x78,0x2a,0x1d,0x17,0x57,0x96,0x3d,0x0a,0x24,0x92,0x2d,0x2f,0x50,0x92,0x37,0x17,0x5a,0x86,0x55,0xd2
,0xd2,0x56,0x56,0x19,0xbe,0x23,0x21,0x80,0x3c,0x82,0x3d,0x41,0xe9,0x40,0x15,0x7c,0x2d,0xf0,0xef,0xc1,0x97,0x3e,0x18,0xf0,0xe5,0xcc,0xfa,0x1c,0x52,0x4f,0x71,0xa0
,0xe8,0xf3,0xcd,0x21,0xba,0xbf,0x05,0xe5,0x97,0x4f,0xb7,0x92,0x47,0x21,0x6f,0x55,0x41,0x67,0x62,0xd8,0x55,0x51,0xcf,0x0a,0x00,0xc2,0x80,0x6f,0x7f,0xc2,0xb4,0xf0
,0x3f,0xfd,0x00,0x21,0xff,0x00,0xc0,0xad,0x47,0xff,0x00,0x93,0xa8,0x00,0xff,0x00,0x85,0x69,0xe0,0x7f,0xfa,0x00,0x43,0xff,0x00,0x81,0x5a,0x8f,0xff,0x00,0x27,0x50
,0x01,0xff,0x00,0x0a,0xd3,0xc0,0xff,0x00,0xf4,0x00,0x87,0xff,0x00,0x02,0xb5,0x1f,0xfe,0x4e,0xa0,0x03,0xfe,0x15,0xa7,0x81,0xff,0x00,0xe8,0x01,0x0f,0xfe,0x05,0x6a
,0x3f,0xfc,0x9d,0x40,0x1c,0xcf,0x8d,0x7e,0x1e,0xf8,0x3a,0xcb,0xc1,0xbe,0x2d,0xbc,0xb6,0xd1,0x22,0x8a,0xe6,0xd3,0xc3,0x3a,0xf5,0xcd,0xbc,0xa2,0xe6,0xfc,0x98,0xe7
,0x83,0x4a,0xba,0x96,0x29,0x00,0x7b,0xd6,0x42,0x52,0x45,0x56,0x01,0x95,0x94,0xe3,0x0c,0xa4,0x1c,0x30,0x07,0xff,0xd2,0xfe,0xf6,0x7c,0x29,0xff,0x00,0x22,0xbf,0x86
,0xff,0x00,0xec,0x01,0xa3,0xff,0x00,0xe9,0xba,0xda,0x80,0x37,0xe8,0x03,0xe4,0x17,0xf8,0xed,0xff,0x00,0x08,0x2e,0xbb,0xe3,0x2d,0x03,0xfe,0x11,0x5f,0xed,0x4f,0x2b
,0xc6,0x9e,0x24,0x9f,0xed,0x7f,0xdb,0x9f,0x61,0xdd,0xe6,0xdf,0xba,0xed,0xf2,0x3f,0xb2,0x2e,0xf1,0xb7,0xcb,0xce,0xef,0x38,0xe7,0x76,0x36,0x8d,0xb9,0x60,0x09,0xbf
,0xe1,0xa9,0xff,0x00,0xea,0x44,0xff,0x00,0xcb,0x9f,0xff,0x00,0xc1,0xea,0x00,0x3f,0xe1,0xa9,0xff,0x00,0xea,0x44,0xff,0x00,0xcb,0x9f,0xff,0x00,0xc1,0xea,0x00,0x3f
,0xe1,0xa9,0xff,0x00,0xea,0x44,0xff,0x00,0xcb,0x9f,0xff,0x00,0xc1,0xea,0x00,0x3f,0xe1,0xa9,0xff,0x00,0xea,0x44,0xff,0x00,0xcb,0x9f,0xff,0x00,0xc1,0xea,0x00,0x3f
,0xe1,0xa9,0xff,0x00,0xea,0x44,0xff,0x00,0xcb,0x9f,0xff,0x00,0xc1,0xea,0x00,0xc7,0xd0,0xbf,0x69,0x3f,0xec,0x8b,0x29,0xed,0x3f,0xe1,0x0b,0xfb,0x47,0x9b,0xac,0xf8
,0x8b,0x53,0xf3,0x3f,0xe1,0x23,0xf2,0x76,0xff,0x00,0x6d,0xf8,0x83,0x53,0xd6,0x7c,0x8d,0x9f,0xd8,0x52,0x67,0xec,0xbf,0x6f,0xfb,0x37,0x9b,0xb8,0x79,0xde,0x57,0x9d
,0xe5,0xc5,0xbf,0xca,0x50,0x0d,0x8f,0xf8,0x6a,0x7f,0xfa,0x91,0x3f,0xf2,0xe7,0xff,0x00,0xf0,0x7a,0x80,0x0f,0xf8,0x6a,0x7f,0xfa,0x91,0x3f,0xf2,0xe7,0xff,0x00,0xf0
,0x7a,0x80,0x0f,0xf8,0x6a,0x7f,0xfa,0x91,0x3f,0xf2,0xe7,0xff,0x00,0xf0,0x7a,0x80,0x0f,0xf8,0x6a,0x7f,0xfa,0x91,0x3f,0xf2,0xe7,0xff,0x00,0xf0,0x7a,0x80,0x0f,0xf8
,0x6a,0x7f,0xfa,0x91,0x3f,0xf2,0xe7,0xff,0x00,0xf0,0x7a,0x80,0x30,0x3c,0x2f,0xfb,0x47,0x7f,0xc2,0x3f,0xa1,0x58,0xe9,0x1f,0xf0,0x86,0xfd,0xaf,0xec,0x86,0xe8,0xfd
,0xa3,0xfe,0x12,0x2f,0x23,0xcc,0xfb,0x45,0xe5,0xc5,0xd7,0xfa,0xaf,0xec,0x39,0xb6,0x6c,0xf3,0xfc,0xbf,0xf5,0x8d,0xbb,0x6e,0xef,0x97,0x76,0xda,0x00,0xdf,0xff,0x00
,0x86,0xa7,0xff,0x00,0xa9,0x13,0xff,0x00,0x2e,0x7f,0xff,0x00,0x07,0xa8,0x00,0xff,0x00,0x86,0xa7,0xff,0x00,0xa9,0x13,0xff,0x00,0x2e,0x7f,0xff,0x00,0x07,0xa8,0x00
,0xff,0x00,0x86,0xa7,0xff,0x00,0xa9,0x13,0xff,0x00,0x2e,0x7f,0xff,0x00,0x07,0xa8,0x00,0xff,0x00,0x86,0xa7,0xff,0x00,0xa9,0x13,0xff,0x00,0x2e,0x7f,0xff,0x00,0x07
,0xa8,0x00,0xff,0x00,0x86,0xa7,0xff,0x00,0xa9,0x13,0xff,0x00,0x2e,0x7f,0xff,0x00,0x07,0xa8,0x03,0x1f,0xc3,0xbf,0xb4,0x9f,0xf6,0x27,0x87,0xf4,0x2d,0x1b,0xfe,0x10
,0xbf,0xb5,0x7f,0x64,0x68,0xfa,0x66,0x99,0xf6,0x9f,0xf8,0x48,0xfc,0x9f,0xb4,0x7d,0x82,0xca,0x0b,0x5f,0x3f,0xc9,0xfe,0xc2,0x97,0xca,0xf3,0x7c,0x9f,0x33,0xca,0xf3
,0x64,0xf2,0xf7,0x6d,0xf3,0x1f,0x1b,0x98,0x03,0x63,0xfe,0x1a,0x9f,0xfe,0xa4,0x4f,0xfc,0xb9,0xff,0x00,0xfc,0x1e,0xa0,0x03,0xfe,0x1a,0x9f,0xfe,0xa4,0x4f,0xfc,0xb9
,0xff,0x00,0xfc,0x1e,0xa0,0x03,0xfe,0x1a,0x9f,0xfe,0xa4,0x4f,0xfc,0xb9,0xff,0x00,0xfc,0x1e,0xa0,0x03,0xfe,0x1a,0x9f,0xfe,0xa4,0x4f,0xfc,0xb9,0xff,0x00,0xfc,0x1e
,0xa0,0x0a,0x7a,0x8f,0xed,0x3b,0xf6,0xed,0x3e,0xfa,0xcb,0xfe,0x10,0x8f,0x2b,0xed,0x96,0x77,0x36,0xbe,0x6f,0xfc,0x24,0xbb,0xfc,0xbf,0xb4,0x43,0x24,0x5e,0x66,0xcf
,0xec,0x05,0xdf,0xb3,0x7e,0xed,0xbb,0x97,0x76,0x31,0xb8,0x67,0x2a,0x01,0x0e,0x8b,0xfb,0x4c,0x7f,0x65,0x68,0xfa,0x4e,0x97,0xff,0x00,0x08,0x57,0x9f,0xfd,0x9b,0xa6
,0xd8,0xd8,0x79,0xff,0x00,0xf0,0x92,0x79,0x5e,0x77,0xd8,0xed,0x62,0xb7,0xf3,0x7c,0xaf,0xec,0x19,0x3c,0xbf,0x33,0xcb,0xdf,0xe5,0xef,0x7d,0x9b,0xb6,0xef,0x6c,0x6e
,0xa0,0x0d,0x2f,0xf8,0x6a,0x7f,0xfa,0x91,0x3f,0xf2,0xe7,0xff,0x00,0xf0,0x7a,0x80,0x0f,0xf8,0x6a,0x7f,0xfa,0x91,0x3f,0xf2,0xe7,0xff,0x00,0xf0,0x7a,0x80,0x0f,0xf8
,0x6a,0x7f,0xfa,0x91,0x3f,0xf2,0xe7,0xff,0x00,0xf0,0x7a,0x80,0x0f,0xf8,0x6a,0x7f,0xfa,0x91,0x3f,0xf2,0xe7,0xff,0x00,0xf0,0x7a,0x80,0x32,0x3c,0x41,0xfb,0x49,0xff
,0x00,0x6e,0x68,0x3a,0xde,0x8b,0xff,0x00,0x08,0x5f,0xd9,0x7f,0xb5,0xf4,0x8d,0x4b,0x4b,0xfb,0x4f,0xfc,0x24,0x7e,0x7f,0xd9,0xff,0x00,0xb4,0x2c,0xe6,0xb4,0xf3,0xfc
,0x9f,0xec,0x28,0x7c,0xef,0x27,0xce,0xf3,0x3c,0xaf,0x36,0x2f,0x33,0x6e,0xcf,0x31,0x33,0xbe,0x80,0x3f,0xff,0xd9,0x00
};
return *data;
};
} // namespace xlnt

View File

@ -0,0 +1,41 @@
#pragma once
#include <cstddef>
#include <xlnt/styles/alignment.hpp>
#include <xlnt/styles/border.hpp>
#include <xlnt/styles/fill.hpp>
#include <xlnt/styles/font.hpp>
#include <xlnt/styles/number_format.hpp>
#include <xlnt/styles/protection.hpp>
#include <xlnt/utils/optional.hpp>
namespace xlnt {
class alignment;
class border;
class fill;
class font;
class number_format;
class protection;
namespace detail {
struct stylesheet;
struct format_impl
{
stylesheet *parent;
std::size_t formatting_record_id;
optional<alignment> alignment;
optional<border> border;
optional<fill> fill;
optional<font> font;
optional<number_format> number_format;
optional<protection> protection;
};
} // namespace detail
} // namespace xlnt

View File

@ -0,0 +1,35 @@
#pragma once
#include <cstddef>
namespace xlnt {
namespace detail {
struct formatting_record
{
std::size_t index;
bool pivot_button;
bool quote_prefix;
bool apply_alignment;
std::size_t alignment_id;
bool apply_border;
std::size_t border_id;
bool apply_fill;
std::size_t fill_id;
bool apply_font;
std::size_t font_id;
bool apply_number_format;
std::size_t number_format_id;
bool apply_protection;
std::size_t protection_id;
};
} // namespace detail
} // namespace xlnt

View File

@ -0,0 +1,43 @@
#pragma once
#include <cstddef>
#include <string>
#include <xlnt/utils/optional.hpp>
namespace xlnt {
class alignment;
class border;
class fill;
class font;
class number_format;
class protection;
namespace detail {
struct stylesheet;
struct style_impl
{
stylesheet *parent;
std::string name;
std::size_t formatting_record_id;
bool custom_built_in;
bool hidden_style;
optional<std::size_t> built_in_style_id;
optional<std::size_t> outline_style;
optional<alignment> alignment;
optional<border> border;
optional<fill> fill;
optional<font> font;
optional<number_format> number_format;
optional<protection> protection;
};
} // namespace detail
} // namespace xlnt

View File

@ -24,129 +24,77 @@
#pragma once
#include <string>
#include <unordered_map>
#include <vector>
#include <xlnt/styles/border.hpp>
#include <xlnt/styles/fill.hpp>
#include <xlnt/styles/font.hpp>
#include <detail/format_impl.hpp>
#include <detail/style_impl.hpp>
#include <xlnt/styles/format.hpp>
#include <xlnt/styles/number_format.hpp>
#include <xlnt/styles/style.hpp>
namespace {
template<typename T>
std::size_t index(const std::vector<T> &items, const T &to_find)
{
auto match = std::find(items.begin(), items.end(), to_find);
if (match == items.end())
{
throw std::out_of_range("xlnt::stylesheet index lookup");
}
return std::distance(items.begin(), match);
}
template<typename T>
bool contains(const std::vector<T> &items, const T &to_find)
{
auto match = std::find(items.begin(), items.end(), to_find);
return match != items.end();
}
} // namespace
#include <xlnt/utils/exceptions.hpp>
namespace xlnt {
namespace detail {
struct stylesheet
{
~stylesheet() {}
std::size_t index(const std::string &style_name)
{
auto match = std::find_if(styles.begin(), styles.end(),
[&](const style &s) { return s.get_name() == style_name; });
if (match == styles.end())
{
throw std::out_of_range("xlnt::stylesheet style index lookup");
}
return std::distance(styles.begin(), match);
}
std::size_t add_format(const format &f)
{
auto match = std::find(formats.begin(), formats.end(), f);
if (match != formats.end())
{
return std::distance(formats.begin(), match);
}
auto number_format_match = std::find_if(number_formats.begin(), number_formats.end(), [&](const number_format &nf) { return nf.get_format_string() == f.get_number_format().get_format_string(); });
if (number_format_match == number_formats.end() && f.get_number_format().get_id() >= 164)
{
number_formats.push_back(f.get_number_format());
}
formats.push_back(f);
format_styles.push_back("Normal");
if (!contains(borders, f.get_border()))
{
borders.push_back(f.get_border());
}
~stylesheet()
{
}
if (!contains(fills, f.get_fill()))
format &create_format()
{
formats.push_back(format_impl());
return format(&formats.back());
}
format &get_format(std::size_t index)
{
return format(&formats.at(index));
}
style &create_style()
{
styles.push_back(style_impl());
return style(&styles.back());
}
style &get_style(const std::string &name)
{
for (auto &s : styles)
{
fills.push_back(f.get_fill());
if (s.name == name)
{
return style(&s);
}
}
if (!contains(fonts, f.get_font()))
throw key_not_found();
}
bool has_style(const std::string &name)
{
for (auto &s : styles)
{
fonts.push_back(f.get_font());
if (s.name == name)
{
return true;
}
}
if (f.get_number_format().get_id() >= 164 && !contains(number_formats, f.get_number_format()))
{
number_formats.push_back(f.get_number_format());
}
return formats.size() - 1;
}
std::size_t add_style(const style &s)
{
auto match = std::find(styles.begin(), styles.end(), s);
if (match != styles.end())
{
return std::distance(styles.begin(), match);
}
styles.push_back(s);
return styles.size() - 1;
}
std::vector<format> formats;
std::vector<std::string> format_styles;
std::vector<style> styles;
return false;
}
std::vector<format_impl> formats;
std::vector<style_impl> styles;
std::vector<alignment> alignments;
std::vector<border> borders;
std::vector<fill> fills;
std::vector<font> fonts;
std::vector<number_format> number_formats;
std::vector<protection> protections;
std::vector<color> colors;
std::unordered_map<std::size_t, std::string> style_name_map;
std::size_t next_custom_format_id = 164;
};
} // namespace detail

View File

@ -68,34 +68,34 @@ xlnt::font::underline_style from_string(const std::string &underline_string)
}
template<>
xlnt::pattern_fill::type from_string(const std::string &fill_type)
xlnt::pattern_fill_type from_string(const std::string &fill_type)
{
if (fill_type == "darkdown") return xlnt::pattern_fill::type::darkdown;
if (fill_type == "darkgray") return xlnt::pattern_fill::type::darkgray;
if (fill_type == "darkgrid") return xlnt::pattern_fill::type::darkgrid;
if (fill_type == "darkhorizontal") return xlnt::pattern_fill::type::darkhorizontal;
if (fill_type == "darktrellis") return xlnt::pattern_fill::type::darktrellis;
if (fill_type == "darkup") return xlnt::pattern_fill::type::darkup;
if (fill_type == "darkvertical") return xlnt::pattern_fill::type::darkvertical;
if (fill_type == "gray0625") return xlnt::pattern_fill::type::gray0625;
if (fill_type == "gray125") return xlnt::pattern_fill::type::gray125;
if (fill_type == "lightdown") return xlnt::pattern_fill::type::lightdown;
if (fill_type == "lightgray") return xlnt::pattern_fill::type::lightgray;
if (fill_type == "lighthorizontal") return xlnt::pattern_fill::type::lighthorizontal;
if (fill_type == "lighttrellis") return xlnt::pattern_fill::type::lighttrellis;
if (fill_type == "lightup") return xlnt::pattern_fill::type::lightup;
if (fill_type == "lightvertical") return xlnt::pattern_fill::type::lightvertical;
if (fill_type == "mediumgray") return xlnt::pattern_fill::type::mediumgray;
if (fill_type == "solid") return xlnt::pattern_fill::type::solid;
return xlnt::pattern_fill::type::none;
if (fill_type == "darkdown") return xlnt::pattern_fill_type::darkdown;
if (fill_type == "darkgray") return xlnt::pattern_fill_type::darkgray;
if (fill_type == "darkgrid") return xlnt::pattern_fill_type::darkgrid;
if (fill_type == "darkhorizontal") return xlnt::pattern_fill_type::darkhorizontal;
if (fill_type == "darktrellis") return xlnt::pattern_fill_type::darktrellis;
if (fill_type == "darkup") return xlnt::pattern_fill_type::darkup;
if (fill_type == "darkvertical") return xlnt::pattern_fill_type::darkvertical;
if (fill_type == "gray0625") return xlnt::pattern_fill_type::gray0625;
if (fill_type == "gray125") return xlnt::pattern_fill_type::gray125;
if (fill_type == "lightdown") return xlnt::pattern_fill_type::lightdown;
if (fill_type == "lightgray") return xlnt::pattern_fill_type::lightgray;
if (fill_type == "lighthorizontal") return xlnt::pattern_fill_type::lighthorizontal;
if (fill_type == "lighttrellis") return xlnt::pattern_fill_type::lighttrellis;
if (fill_type == "lightup") return xlnt::pattern_fill_type::lightup;
if (fill_type == "lightvertical") return xlnt::pattern_fill_type::lightvertical;
if (fill_type == "mediumgray") return xlnt::pattern_fill_type::mediumgray;
if (fill_type == "solid") return xlnt::pattern_fill_type::solid;
return xlnt::pattern_fill_type::none;
};
template<>
xlnt::gradient_fill::type from_string(const std::string &fill_type)
xlnt::gradient_fill_type from_string(const std::string &fill_type)
{
//TODO what's the default?
if (fill_type == "linear") return xlnt::gradient_fill::type::linear;
return xlnt::gradient_fill::type::path;
if (fill_type == "linear") return xlnt::gradient_fill_type::linear;
return xlnt::gradient_fill_type::path;
};
template<>
@ -206,12 +206,20 @@ xlnt::relationship::type from_string(const std::string &type_string)
return xlnt::relationship::type::unknown;
}
std::string to_string(xlnt::border_side side)
{
switch (side)
{
case xlnt::border_side::bottom: return "bottom";
}
}
xlnt::protection read_protection(const pugi::xml_node protection_node)
{
xlnt::protection prot;
prot.set_locked(is_true(protection_node.attribute("locked").value()));
prot.set_hidden(is_true(protection_node.attribute("hidden").value()));
prot.locked(is_true(protection_node.attribute("locked").value()));
prot.hidden(is_true(protection_node.attribute("hidden").value()));
return prot;
}
@ -220,19 +228,19 @@ xlnt::alignment read_alignment(const pugi::xml_node alignment_node)
{
xlnt::alignment align;
align.set_wrap_text(is_true(alignment_node.attribute("wrapText").value()));
align.set_shrink_to_fit(is_true(alignment_node.attribute("shrinkToFit").value()));
align.wrap(is_true(alignment_node.attribute("wrapText").value()));
align.shrink(is_true(alignment_node.attribute("shrinkToFit").value()));
if (alignment_node.attribute("vertical"))
{
std::string vertical = alignment_node.attribute("vertical").value();
align.set_vertical(from_string<xlnt::vertical_alignment>(vertical));
align.vertical(from_string<xlnt::vertical_alignment>(vertical));
}
if (alignment_node.attribute("horizontal"))
{
std::string horizontal = alignment_node.attribute("horizontal").value();
align.set_horizontal(from_string<xlnt::horizontal_alignment>(horizontal));
align.horizontal(from_string<xlnt::horizontal_alignment>(horizontal));
}
return align;
@ -294,33 +302,33 @@ xlnt::font read_font(const pugi::xml_node font_node)
{
xlnt::font new_font;
new_font.set_size(string_to_size_t(font_node.child("sz").attribute("val").value()));
new_font.set_name(font_node.child("name").attribute("val").value());
new_font.size(string_to_size_t(font_node.child("sz").attribute("val").value()));
new_font.name(font_node.child("name").attribute("val").value());
if (font_node.child("color"))
{
new_font.set_color(read_color(font_node.child("color")));
new_font.color(read_color(font_node.child("color")));
}
if (font_node.child("family"))
{
new_font.set_family(string_to_size_t(font_node.child("family").attribute("val").value()));
new_font.family(string_to_size_t(font_node.child("family").attribute("val").value()));
}
if (font_node.child("scheme"))
{
new_font.set_scheme(font_node.child("scheme").attribute("val").value());
new_font.scheme(font_node.child("scheme").attribute("val").value());
}
if (font_node.child("b"))
{
if (font_node.child("b").attribute("val"))
{
new_font.set_bold(is_true(font_node.child("b").attribute("val").value()));
new_font.bold(is_true(font_node.child("b").attribute("val").value()));
}
else
{
new_font.set_bold(true);
new_font.bold(true);
}
}
@ -328,11 +336,11 @@ xlnt::font read_font(const pugi::xml_node font_node)
{
if (font_node.child("strike").attribute("val"))
{
new_font.set_strikethrough(is_true(font_node.child("strike").attribute("val").value()));
new_font.strikethrough(is_true(font_node.child("strike").attribute("val").value()));
}
else
{
new_font.set_strikethrough(true);
new_font.strikethrough(true);
}
}
@ -340,11 +348,11 @@ xlnt::font read_font(const pugi::xml_node font_node)
{
if (font_node.child("i").attribute("val"))
{
new_font.set_italic(is_true(font_node.child("i").attribute("val").value()));
new_font.italic(is_true(font_node.child("i").attribute("val").value()));
}
else
{
new_font.set_italic(true);
new_font.italic(true);
}
}
@ -353,11 +361,11 @@ xlnt::font read_font(const pugi::xml_node font_node)
if (font_node.child("u").attribute("val"))
{
std::string underline_string = font_node.child("u").attribute("val").value();
new_font.set_underline(from_string<xlnt::font::underline_style>(underline_string));
new_font.underline(from_string<xlnt::font::underline_style>(underline_string));
}
else
{
new_font.set_underline(xlnt::font::underline_style::single);
new_font.underline(xlnt::font::underline_style::single);
}
}
@ -401,37 +409,39 @@ xlnt::fill read_fill(const pugi::xml_node &fill_node)
auto pattern_fill_node = fill_node.child("patternFill");
std::string pattern_fill_type_string = pattern_fill_node.attribute("patternType").value();
xlnt::pattern_fill pattern;
if (!pattern_fill_type_string.empty())
{
new_fill = xlnt::fill::pattern(from_string<xlnt::pattern_fill::type>(pattern_fill_type_string));
if (pattern_fill_node.child("bgColor"))
{
new_fill.get_pattern_fill().get_background_color() = read_color(pattern_fill_node.child("bgColor"));
}
pattern.type(from_string<xlnt::pattern_fill_type>(pattern_fill_type_string));
if (pattern_fill_node.child("fgColor"))
{
new_fill.get_pattern_fill().get_foreground_color() = read_color(pattern_fill_node.child("fgColor"));
pattern.foreground(read_color(pattern_fill_node.child("fgColor")));
}
if (pattern_fill_node.child("bgColor"))
{
pattern.background(read_color(pattern_fill_node.child("bgColor")));
}
}
else
{
new_fill = xlnt::fill::pattern(xlnt::pattern_fill::type::none);
}
new_fill = pattern;
}
else if (fill_node.child("gradientFill"))
{
auto gradient_fill_node = fill_node.child("gradientFill");
std::string gradient_fill_type_string = gradient_fill_node.attribute("type").value();
xlnt::gradient_fill gradient;
if (!gradient_fill_type_string.empty())
{
new_fill = xlnt::fill::gradient(from_string<xlnt::gradient_fill::type>(gradient_fill_type_string));
gradient.type(from_string<xlnt::gradient_fill_type>(gradient_fill_type_string));
}
else
{
new_fill = xlnt::fill::gradient(xlnt::gradient_fill::type::linear);
gradient.type(xlnt::gradient_fill_type::linear);
}
for (auto stop_node : gradient_fill_node.children("stop"))
@ -439,8 +449,10 @@ xlnt::fill read_fill(const pugi::xml_node &fill_node)
auto position = stop_node.attribute("position").as_double();
auto color = read_color(stop_node.child("color"));
new_fill.get_gradient_fill().add_stop(position, color);
gradient.add_stop(position, color);
}
new_fill = gradient;
}
return new_fill;
@ -463,12 +475,12 @@ xlnt::border::border_property read_side(const pugi::xml_node &side_node)
if (side_node.attribute("style"))
{
new_side.set_style(from_string<xlnt::border_style>(side_node.attribute("style").value()));
new_side.style(from_string<xlnt::border_style>(side_node.attribute("style").value()));
}
if (side_node.child("color"))
{
new_side.set_color(read_color(side_node.child("color")));
new_side.color(read_color(side_node.child("color")));
}
return new_side;
@ -478,12 +490,13 @@ xlnt::border read_border(const pugi::xml_node &border_node)
{
xlnt::border new_border;
for (const auto &side_name : xlnt::border::get_side_names())
for (const auto &side : xlnt::border::all_sides())
{
if (border_node.child(side_name.second.c_str()))
auto side_name = to_string(side);
if (border_node.child(side_name.c_str()))
{
auto side = read_side(border_node.child(side_name.second.c_str()));
new_border.set_side(side_name.first, side);
new_border.side(side, read_side(border_node.child(side_name.c_str())));
}
}
@ -591,9 +604,9 @@ xlnt::style read_style(const pugi::xml_node &style_node, const pugi::xml_node &s
read_base_format(style_format_node, stylesheet, s);
s.set_name(style_node.attribute("name").value());
s.set_hidden(style_node.attribute("hidden") && is_true(style_node.attribute("hidden").value()));
s.set_builtin_id(string_to_size_t(style_node.attribute("builtinId").value()));
s.name(style_node.attribute("name").value());
s.hidden(style_node.attribute("hidden") && is_true(style_node.attribute("hidden").value()));
s.built_in_id(string_to_size_t(style_node.attribute("builtinId").value()));
return s;
}
@ -1105,7 +1118,7 @@ void xlsx_consumer::read_shared_string_table(const pugi::xml_node root)
if (unique_count != strings.size())
{
throw std::runtime_error("counts don't match");
throw invalid_file("sizes don't match");
}
}
@ -1219,7 +1232,7 @@ void xlsx_consumer::read_worksheet(const pugi::xml_node root, const std::string
if (count != 0)
{
throw std::runtime_error("mismatch between count and actual number of merged cells");
throw invalid_file("sizes don't match");
}
}

View File

@ -96,38 +96,36 @@ std::string to_string(xlnt::font::underline_style underline_style)
}
}
std::string to_string(xlnt::pattern_fill::type fill_type)
std::string to_string(xlnt::pattern_fill_type fill_type)
{
switch (fill_type)
{
case xlnt::pattern_fill::type::darkdown: return "darkdown";
case xlnt::pattern_fill::type::darkgray: return "darkgray";
case xlnt::pattern_fill::type::darkgrid: return "darkgrid";
case xlnt::pattern_fill::type::darkhorizontal: return "darkhorizontal";
case xlnt::pattern_fill::type::darktrellis: return "darkhorizontal";
case xlnt::pattern_fill::type::darkup: return "darkup";
case xlnt::pattern_fill::type::darkvertical: return "darkvertical";
case xlnt::pattern_fill::type::gray0625: return "gray0625";
case xlnt::pattern_fill::type::gray125: return "gray125";
case xlnt::pattern_fill::type::lightdown: return "lightdown";
case xlnt::pattern_fill::type::lightgray: return "lightgray";
case xlnt::pattern_fill::type::lightgrid: return "lightgrid";
case xlnt::pattern_fill::type::lighthorizontal: return "lighthorizontal";
case xlnt::pattern_fill::type::lighttrellis: return "lighttrellis";
case xlnt::pattern_fill::type::lightup: return "lightup";
case xlnt::pattern_fill::type::lightvertical: return "lightvertical";
case xlnt::pattern_fill::type::mediumgray: return "mediumgray";
case xlnt::pattern_fill::type::solid: return "solid";
case xlnt::pattern_fill_type::darkdown: return "darkdown";
case xlnt::pattern_fill_type::darkgray: return "darkgray";
case xlnt::pattern_fill_type::darkgrid: return "darkgrid";
case xlnt::pattern_fill_type::darkhorizontal: return "darkhorizontal";
case xlnt::pattern_fill_type::darktrellis: return "darkhorizontal";
case xlnt::pattern_fill_type::darkup: return "darkup";
case xlnt::pattern_fill_type::darkvertical: return "darkvertical";
case xlnt::pattern_fill_type::gray0625: return "gray0625";
case xlnt::pattern_fill_type::gray125: return "gray125";
case xlnt::pattern_fill_type::lightdown: return "lightdown";
case xlnt::pattern_fill_type::lightgray: return "lightgray";
case xlnt::pattern_fill_type::lightgrid: return "lightgrid";
case xlnt::pattern_fill_type::lighthorizontal: return "lighthorizontal";
case xlnt::pattern_fill_type::lighttrellis: return "lighttrellis";
case xlnt::pattern_fill_type::lightup: return "lightup";
case xlnt::pattern_fill_type::lightvertical: return "lightvertical";
case xlnt::pattern_fill_type::mediumgray: return "mediumgray";
case xlnt::pattern_fill_type::solid: return "solid";
default:
case xlnt::pattern_fill::type::none: return "none";
case xlnt::pattern_fill_type::none: return "none";
}
}
std::string to_string(xlnt::gradient_fill::type fill_type)
std::string to_string(xlnt::gradient_fill_type fill_type)
{
return fill_type == xlnt::gradient_fill::type::linear ? "linear" : "path";
return fill_type == xlnt::gradient_fill_type::linear ? "linear" : "path";
}
std::string to_string(xlnt::border_style border_style)
@ -152,7 +150,6 @@ std::string to_string(xlnt::border_style border_style)
}
}
std::string to_string(xlnt::vertical_alignment vertical_alignment)
{
switch (vertical_alignment)
@ -181,6 +178,14 @@ std::string to_string(xlnt::horizontal_alignment horizontal_alignment)
}
}
std::string to_string(xlnt::border_side side)
{
switch (side)
{
case xlnt::border_side::bottom: return "bottom";
}
}
void write_relationships(const std::vector<xlnt::relationship> &relationships, pugi::xml_node root)
{
auto relationships_node = root.append_child("Relationships");
@ -235,50 +240,52 @@ bool write_fonts(const std::vector<xlnt::font> &fonts, pugi::xml_node &fonts_nod
{
auto font_node = fonts_node.append_child("font");
if (f.is_bold())
if (f.bold())
{
auto bold_node = font_node.append_child("b");
bold_node.append_attribute("val").set_value("1");
}
if (f.is_italic())
if (f.italic())
{
auto italic_node = font_node.append_child("i");
italic_node.append_attribute("val").set_value("1");
}
if (f.is_underline())
if (f.underlined())
{
auto underline_node = font_node.append_child("u");
underline_node.append_attribute("val").set_value(to_string(f.get_underline()).c_str());
underline_node.append_attribute("val").set_value(to_string(f.underline()).c_str());
}
if (f.is_strikethrough())
if (f.strikethrough())
{
auto strike_node = font_node.append_child("strike");
strike_node.append_attribute("val").set_value("1");
}
auto size_node = font_node.append_child("sz");
size_node.append_attribute("val").set_value(std::to_string(f.get_size()).c_str());
size_node.append_attribute("val").set_value(std::to_string(f.size()).c_str());
auto color_node = font_node.append_child("color");
write_color(f.get_color(), color_node);
auto name_node = font_node.append_child("name");
name_node.append_attribute("val").set_value(f.get_name().c_str());
if (f.has_family())
if (f.color())
{
auto family_node = font_node.append_child("family");
family_node.append_attribute("val").set_value(std::to_string(f.get_family()).c_str());
auto color_node = font_node.append_child("color");
write_color(*f.color(), color_node);
}
if (f.has_scheme())
auto name_node = font_node.append_child("name");
name_node.append_attribute("val").set_value(f.name().c_str());
if (f.family())
{
auto family_node = font_node.append_child("family");
family_node.append_attribute("val").set_value(std::to_string(*f.family()).c_str());
}
if (f.scheme())
{
auto scheme_node = font_node.append_child("scheme");
scheme_node.append_attribute("val").set_value(f.get_scheme().c_str());
scheme_node.append_attribute("val").set_value(f.scheme()->c_str());
}
}
@ -293,57 +300,57 @@ bool write_fills(const std::vector<xlnt::fill> &fills, pugi::xml_node &fills_nod
{
auto fill_node = fills_node.append_child("fill");
if (fill_.get_type() == xlnt::fill::type::pattern)
if (fill_.type() == xlnt::fill_type::pattern)
{
const auto &pattern = fill_.get_pattern_fill();
const auto &pattern = fill_.pattern_fill();
auto pattern_fill_node = fill_node.append_child("patternFill");
pattern_fill_node.append_attribute("patternType").set_value(to_string(pattern.get_type()).c_str());
pattern_fill_node.append_attribute("patternType").set_value(to_string(pattern.type()).c_str());
if (pattern.get_foreground_color())
if (pattern.foreground())
{
write_color(*pattern.get_foreground_color(), pattern_fill_node.append_child("fgColor"));
write_color(*pattern.foreground(), pattern_fill_node.append_child("fgColor"));
}
if (pattern.get_background_color())
if (pattern.background())
{
write_color(*pattern.get_background_color(), pattern_fill_node.append_child("bgColor"));
write_color(*pattern.background(), pattern_fill_node.append_child("bgColor"));
}
}
else if (fill_.get_type() == xlnt::fill::type::gradient)
else if (fill_.type() == xlnt::fill_type::gradient)
{
const auto &gradient = fill_.get_gradient_fill();
const auto &gradient = fill_.gradient_fill();
auto gradient_fill_node = fill_node.append_child("gradientFill");
auto gradient_fill_type_string = to_string(gradient.get_type());
auto gradient_fill_type_string = to_string(gradient.type());
gradient_fill_node.append_attribute("gradientType").set_value(gradient_fill_type_string.c_str());
if (gradient.get_degree() != 0)
if (gradient.degree() != 0)
{
gradient_fill_node.append_attribute("degree").set_value(gradient.get_degree());
gradient_fill_node.append_attribute("degree").set_value(gradient.degree());
}
if (gradient.get_gradient_left() != 0)
if (gradient.left() != 0)
{
gradient_fill_node.append_attribute("left").set_value(gradient.get_gradient_left());
gradient_fill_node.append_attribute("left").set_value(gradient.left());
}
if (gradient.get_gradient_right() != 0)
if (gradient.right() != 0)
{
gradient_fill_node.append_attribute("right").set_value(gradient.get_gradient_right());
gradient_fill_node.append_attribute("right").set_value(gradient.right());
}
if (gradient.get_gradient_top() != 0)
if (gradient.top() != 0)
{
gradient_fill_node.append_attribute("top").set_value(gradient.get_gradient_top());
gradient_fill_node.append_attribute("top").set_value(gradient.top());
}
if (gradient.get_gradient_bottom() != 0)
if (gradient.bottom() != 0)
{
gradient_fill_node.append_attribute("bottom").set_value(gradient.get_gradient_bottom());
gradient_fill_node.append_attribute("bottom").set_value(gradient.bottom());
}
for (const auto &stop : gradient.get_stops())
for (const auto &stop : gradient.stops())
{
auto stop_node = gradient_fill_node.append_child("stop");
stop_node.append_attribute("position").set_value(stop.first);
@ -363,26 +370,24 @@ bool write_borders(const std::vector<xlnt::border> &borders, pugi::xml_node &bor
{
auto border_node = borders_node.append_child("border");
for (const auto &side_name : xlnt::border::get_side_names())
for (const auto &side : xlnt::border::all_sides())
{
const auto &current_name = side_name.second;
const auto &current_side_type = side_name.first;
if (border_.has_side(current_side_type))
if (border_.side(side))
{
auto side_node = border_node.append_child(current_name.c_str());
const auto &current_side = border_.get_side(current_side_type);
auto side_name = to_string(side);
auto side_node = border_node.append_child(side_name.c_str());
const auto current_side = *border_.side(side);
if (current_side.has_style())
if (current_side.style())
{
auto style_string = to_string(current_side.get_style());
auto style_string = to_string(*current_side.style());
side_node.append_attribute("style").set_value(style_string.c_str());
}
if (current_side.has_color())
if (current_side.color())
{
auto color_node = side_node.append_child("color");
write_color(current_side.get_color(), color_node);
write_color(*current_side.color(), color_node);
}
}
}
@ -778,7 +783,7 @@ void xlsx_producer::write_workbook(const relationship &rel, pugi::xml_node root)
if (num_visible == 0)
{
throw xlnt::no_visible_worksheets();
throw no_visible_worksheets();
}
auto workbook_node = root.append_child("workbook");

View File

@ -216,7 +216,7 @@ public:
xlnt::zip_file f3;
std::vector<std::uint8_t> bytes { 1, 2, 3 };
TS_ASSERT_THROWS(f3.load(bytes), std::runtime_error);
TS_ASSERT_THROWS(f3.load(bytes), xlnt::invalid_file);
}
private:

View File

@ -295,7 +295,7 @@ void zip_file::remove_comment()
if (position <= 3)
{
throw std::runtime_error("didn't find end of central directory signature");
throw invalid_file("zip");
}
uint16_t length = static_cast<uint16_t>(buffer_[position + 1]);

View File

@ -26,52 +26,42 @@
namespace xlnt {
bool alignment::get_wrap_text() const
optional<bool> alignment::wrap() const
{
return wrap_text_;
}
void alignment::set_shrink_to_fit(bool shrink_to_fit)
alignment &alignment::wrap(bool wrap_text)
{
wrap_text_ = wrap_text;
}
optional<bool> alignment::shrink() const
{
return shrink_to_fit_;
}
alignment &alignment::shrink(bool shrink_to_fit)
{
shrink_to_fit_ = shrink_to_fit;
}
bool alignment::get_shrink_to_fit() const
{
return shrink_to_fit_;
}
void alignment::set_wrap_text(bool wrap_text)
{
wrap_text_ = wrap_text;
}
bool alignment::has_horizontal() const
{
return horizontal_ != horizontal_alignment::none;
}
horizontal_alignment alignment::get_horizontal() const
optional<horizontal_alignment> alignment::horizontal() const
{
return horizontal_;
}
void alignment::set_horizontal(horizontal_alignment horizontal)
alignment &alignment::horizontal(horizontal_alignment horizontal)
{
horizontal_ = horizontal;
}
bool alignment::has_vertical() const
{
return vertical_ != vertical_alignment::none;
}
vertical_alignment alignment::get_vertical() const
optional<vertical_alignment> alignment::vertical() const
{
return vertical_;
}
void alignment::set_vertical(vertical_alignment vertical)
alignment &alignment::vertical(vertical_alignment vertical)
{
vertical_ = vertical;
}

View File

@ -27,130 +27,97 @@
namespace xlnt {
bool border::border_property::has_color() const
optional<xlnt::color> border::border_property::color() const
{
return has_color_;
}
const color &border::border_property::get_color() const
{
if (!has_color_)
{
throw invalid_attribute();
}
return color_;
}
void border::border_property::set_color(const color &c)
border::border_property &border::border_property::color(const xlnt::color &c)
{
has_color_ = true;
color_ = c;
return *this;
}
bool border::border_property::has_style() const
optional<border_style> border::border_property::style() const
{
return has_style_;
}
border_style border::border_property::get_style() const
{
if (!has_style_)
{
throw invalid_attribute();
}
return style_;
}
void border::border_property::set_style(border_style s)
border::border_property &border::border_property::style(border_style s)
{
has_style_ = true;
style_ = s;
return *this;
}
border::border()
{
sides_ =
{
{ xlnt::border::side::start, border_property() },
{ xlnt::border::side::end, border_property() },
{ xlnt::border::side::top, border_property() },
{ xlnt::border::side::bottom, border_property() },
{ xlnt::border::side::diagonal, border_property() }
};
}
const std::vector<std::pair<xlnt::border::side, std::string>> &border::get_side_names()
const std::vector<xlnt::border_side> &border::all_sides()
{
static auto *sides =
new std::vector<std::pair<xlnt::border::side, std::string>>
{
{ xlnt::border::side::start, "left" },
{ xlnt::border::side::end, "right" },
{ xlnt::border::side::top, "top" },
{ xlnt::border::side::bottom, "bottom" },
{ xlnt::border::side::diagonal, "diagonal" },
{ xlnt::border::side::vertical, "vertical" },
{ xlnt::border::side::horizontal, "horizontal" }
};
static auto *sides = new std::vector<xlnt::border_side>
{
xlnt::border_side::start,
xlnt::border_side::end,
xlnt::border_side::top,
xlnt::border_side::bottom,
xlnt::border_side::diagonal,
xlnt::border_side::vertical,
xlnt::border_side::horizontal
};
return *sides;
}
bool border::has_side(side s) const
optional<border::border_property> border::side(border_side s) const
{
return sides_.find(s) != sides_.end();
}
const border::border_property &border::get_side(side s) const
{
if (has_side(s))
switch (s)
{
return sides_.at(s);
case border_side::bottom: return bottom_;
}
throw key_not_found();
}
void border::set_side(side s, const border_property &prop)
border &border::side(border_side s, const border_property &prop)
{
sides_[s] = prop;
switch (s)
{
case border_side::bottom: bottom_ = prop;
}
}
std::string border::to_hash_string() const
{
std::string hash_string;
for (const auto &side_name : get_side_names())
for (const auto &side_type : all_sides())
{
hash_string.append(side_name.second);
hash_string.append(std::to_string(static_cast<std::size_t>(side_type)));
if (has_side(side_name.first))
if (side(side_type))
{
const auto &side_properties = get_side(side_name.first);
const auto side_properties = *side(side_type);
if (side_properties.has_style())
if (side_properties.style())
{
hash_string.append(std::to_string(static_cast<std::size_t>(side_properties.get_style())));
hash_string.append(std::to_string(static_cast<std::size_t>(*side_properties.style())));
}
else
{
hash_string.push_back('=');
hash_string.push_back(' ');
}
if (side_properties.has_color())
if (side_properties.color())
{
hash_string.append(std::to_string(std::hash<xlnt::hashable>()(side_properties.get_color())));
hash_string.append(std::to_string(std::hash<xlnt::hashable>()(*side_properties.color())));
}
else
{
hash_string.push_back('=');
hash_string.push_back(' ');
}
}
else
{
hash_string.push_back('=');
hash_string.push_back(' ');
}
hash_string.push_back(' ');

View File

@ -26,264 +26,236 @@
namespace xlnt {
fill::type fill::get_type() const
// pattern_fill
pattern_fill::pattern_fill()
{
return type_;
}
pattern_fill::type pattern_fill::get_type() const
pattern_fill_type pattern_fill::type() const
{
return type_;
return type_;
}
void pattern_fill::set_type(pattern_fill::type t)
pattern_fill &pattern_fill::type(pattern_fill_type type)
{
type_ = t;
type_ = type;
return *this;
}
gradient_fill::type gradient_fill::get_type() const
optional<color> pattern_fill::foreground() const
{
return type_;
return foreground_;
}
void gradient_fill::set_type(gradient_fill::type t)
pattern_fill &pattern_fill::foreground(const color &new_foreground)
{
type_ = t;
foreground_ = new_foreground;
return *this;
}
void pattern_fill::set_foreground_color(const color &c)
optional<color> pattern_fill::background() const
{
foreground_color_ = c;
return background_;
}
std::experimental::optional<color> &pattern_fill::get_foreground_color()
pattern_fill &pattern_fill::background(const color &new_background)
{
return foreground_color_;
}
const std::experimental::optional<color> &pattern_fill::get_foreground_color() const
{
return foreground_color_;
}
void pattern_fill::set_background_color(const color &c)
{
background_color_ = c;
}
std::experimental::optional<color> &pattern_fill::get_background_color()
{
return background_color_;
}
const std::experimental::optional<color> &pattern_fill::get_background_color() const
{
return background_color_;
}
void gradient_fill::set_degree(double degree)
{
degree_ = degree;
}
double gradient_fill::get_degree() const
{
return degree_;
background_ = new_background;
return *this;
}
std::string pattern_fill::to_hash_string() const
{
std::string hash_string = "pattern_fill";
std::string hash_string = "pattern_fill";
hash_string.append(background_color_ ? "1" : "0");
hash_string.append(background_ ? "1" : "0");
if (background_color_)
{
hash_string.append(std::to_string(background_color_->hash()));
}
if (background_)
{
hash_string.append(std::to_string(background_->hash()));
}
hash_string.append(background_color_ ? "1" : "0");
hash_string.append(background_ ? "1" : "0");
if (background_color_)
{
hash_string.append(std::to_string(background_color_->hash()));
}
return hash_string;
if (background_)
{
hash_string.append(std::to_string(background_->hash()));
}
return hash_string;
}
// gradient_fill
gradient_fill::gradient_fill() : type_(gradient_fill_type::linear)
{
}
gradient_fill_type gradient_fill::type() const
{
return type_;
}
gradient_fill &gradient_fill::type(gradient_fill_type t)
{
type_ = t;
return *this;
}
gradient_fill &gradient_fill::degree(double degree)
{
degree_ = degree;
return *this;
}
double gradient_fill::degree() const
{
return degree_;
}
double gradient_fill::left() const
{
return left_;
}
gradient_fill &gradient_fill::left(double value)
{
left_ = value;
return *this;
}
double gradient_fill::right() const
{
return right_;
}
gradient_fill &gradient_fill::right(double value)
{
right_ = value;
return *this;
}
double gradient_fill::top() const
{
return top_;
}
gradient_fill &gradient_fill::top(double value)
{
top_ = value;
return *this;
}
double gradient_fill::bottom() const
{
return bottom_;
}
gradient_fill &gradient_fill::bottom(double value)
{
bottom_ = value;
return *this;
}
std::string gradient_fill::to_hash_string() const
{
std::string hash_string = "gradient_fill";
std::string hash_string = "gradient_fill";
hash_string.append(std::to_string(static_cast<std::size_t>(type_)));
hash_string.append(std::to_string(stops_.size()));
hash_string.append(std::to_string(degree_));
hash_string.append(std::to_string(left_));
hash_string.append(std::to_string(right_));
hash_string.append(std::to_string(top_));
hash_string.append(std::to_string(bottom_));
return hash_string;
hash_string.append(std::to_string(static_cast<std::size_t>(type_)));
hash_string.append(std::to_string(stops_.size()));
hash_string.append(std::to_string(degree_));
hash_string.append(std::to_string(left_));
hash_string.append(std::to_string(right_));
hash_string.append(std::to_string(top_));
hash_string.append(std::to_string(bottom_));
return hash_string;
}
gradient_fill &gradient_fill::add_stop(double position, color stop_color)
{
stops_[position] = stop_color;
return *this;
}
gradient_fill &gradient_fill::clear_stops()
{
stops_.clear();
return *this;
}
std::unordered_map<double, color> gradient_fill::stops() const
{
return stops_;
}
// fill
fill::fill() : type_(fill_type::pattern)
{
}
fill::fill(const xlnt::pattern_fill &pattern)
: type_(fill_type::pattern),
pattern_(pattern)
{
}
fill::fill(const xlnt::gradient_fill &gradient)
: type_(fill_type::gradient),
gradient_(gradient)
{
}
fill_type fill::type() const
{
return type_;
}
gradient_fill fill::gradient_fill() const
{
if (type_ != fill_type::gradient)
{
throw invalid_attribute();
}
return gradient_;
}
pattern_fill fill::pattern_fill() const
{
if (type_ != fill_type::pattern)
{
throw invalid_attribute();
}
return pattern_;
}
std::string fill::to_hash_string() const
{
std::string hash_string = "fill";
hash_string.append(std::to_string(static_cast<std::size_t>(type_)));
std::string hash_string = "fill";
switch (type_)
{
case type::pattern:
hash_string.append(std::to_string(pattern_.hash()));
break;
hash_string.append(std::to_string(static_cast<std::size_t>(type_)));
case type::gradient:
hash_string.append(std::to_string(gradient_.hash()));
break;
switch (type_)
{
case fill_type::pattern:
hash_string.append(std::to_string(pattern_.hash()));
break;
default:
break;
} // switch (type_)
case fill_type::gradient:
hash_string.append(std::to_string(gradient_.hash()));
break;
return hash_string;
}
default:
break;
} // switch (type_)
double gradient_fill::get_gradient_left() const
{
return left_;
}
void gradient_fill::set_gradient_left(double value)
{
left_ = value;
}
double gradient_fill::get_gradient_right() const
{
return right_;
}
void gradient_fill::set_gradient_right(double value)
{
right_ = value;
}
double gradient_fill::get_gradient_top() const
{
return top_;
}
void gradient_fill::set_gradient_top(double value)
{
top_ = value;
}
double gradient_fill::get_gradient_bottom() const
{
return bottom_;
}
void gradient_fill::set_gradient_bottom(double value)
{
bottom_ = value;
}
fill fill::pattern(pattern_fill::type pattern_type)
{
fill f;
f.type_ = type::pattern;
f.pattern_ = pattern_fill(pattern_type);
return f;
}
fill fill::gradient(gradient_fill::type gradient_type)
{
fill f;
f.type_ = type::gradient;
f.gradient_ = gradient_fill(gradient_type);
return f;
}
pattern_fill::pattern_fill(type pattern_type) : type_(pattern_type)
{
}
pattern_fill::pattern_fill() : pattern_fill(type::none)
{
}
gradient_fill::gradient_fill(type gradient_type) : type_(gradient_type)
{
}
gradient_fill::gradient_fill() : gradient_fill(type::linear)
{
}
gradient_fill &fill::get_gradient_fill()
{
if (type_ != fill::type::gradient)
{
throw std::runtime_error("not gradient");
}
return gradient_;
}
const gradient_fill &fill::get_gradient_fill() const
{
if (type_ != fill::type::gradient)
{
throw std::runtime_error("not gradient");
}
return gradient_;
}
pattern_fill &fill::get_pattern_fill()
{
if (type_ != fill::type::pattern)
{
throw std::runtime_error("not pattern");
}
return pattern_;
}
const pattern_fill &fill::get_pattern_fill() const
{
if (type_ != fill::type::pattern)
{
throw std::runtime_error("not pattern");
}
return pattern_;
}
void gradient_fill::add_stop(double position, color stop_color)
{
stops_[position] = stop_color;
}
void gradient_fill::delete_stop(double position)
{
stops_.erase(stops_.find(position));
}
void gradient_fill::clear_stops()
{
stops_.clear();
}
const std::unordered_map<double, color> &gradient_fill::get_stops() const
{
return stops_;
return hash_string;
}
} // namespace xlnt

View File

@ -35,117 +35,100 @@ font::font()
superscript_(false),
subscript_(false),
underline_(underline_style::none),
strikethrough_(false),
color_(theme_color(1)),
has_family_(true),
family_(2),
has_scheme_(true),
scheme_("minor")
strikethrough_(false)
{
}
void font::set_bold(bool bold)
font &font::bold(bool bold)
{
bold_ = bold;
}
bool font::is_bold() const
bool font::bold() const
{
return bold_;
}
void font::set_italic(bool italic)
font &font::italic(bool italic)
{
italic_ = italic;
}
bool font::is_italic() const
bool font::italic() const
{
return italic_;
}
void font::set_strikethrough(bool strikethrough)
font &font::strikethrough(bool strikethrough)
{
strikethrough_ = strikethrough;
}
bool font::is_strikethrough() const
bool font::strikethrough() const
{
return strikethrough_;
}
void font::set_underline(underline_style new_underline)
font &font::underline(underline_style new_underline)
{
underline_ = new_underline;
}
bool font::is_underline() const
bool font::underlined() const
{
return underline_ != underline_style::none;
}
font::underline_style font::get_underline() const
font::underline_style font::underline() const
{
return underline_;
}
void font::set_size(std::size_t size)
font &font::size(std::size_t size)
{
size_ = size;
}
std::size_t font::get_size() const
std::size_t font::size() const
{
return size_;
}
void font::set_name(const std::string &name)
font &font::name(const std::string &name)
{
name_ = name;
}
std::string font::get_name() const
std::string font::name() const
{
return name_;
}
void font::set_color(color c)
font &font::color(const xlnt::color &c)
{
color_ = c;
}
void font::set_family(std::size_t family)
font &font::family(std::size_t family)
{
has_family_ = true;
family_ = family;
}
void font::set_scheme(const std::string &scheme)
font &font::scheme(const std::string &scheme)
{
has_scheme_ = true;
scheme_ = scheme;
}
color font::get_color() const
optional<color> font::color() const
{
return color_;
}
bool font::has_family() const
{
return has_family_;
}
std::size_t font::get_family() const
optional<std::size_t> font::family() const
{
return family_;
}
bool font::has_scheme() const
{
return has_scheme_;
}
std::string font::get_scheme() const
optional<std::string> font::scheme() const
{
return scheme_;
}
@ -162,9 +145,8 @@ std::string font::to_hash_string() const
hash_string.append(name_);
hash_string.append(std::to_string(size_));
hash_string.append(std::to_string(static_cast<std::size_t>(underline_)));
hash_string.append(std::to_string(color_.hash()));
hash_string.append(std::to_string(family_));
hash_string.append(scheme_);
hash_string.append(family_ ? std::to_string(*family_) : "");
hash_string.append(scheme_ ? *scheme_ : "");
return hash_string;
}

View File

@ -22,36 +22,15 @@
// @license: http://www.opensource.org/licenses/mit-license.php
// @author: see AUTHORS file
#include <xlnt/cell/cell.hpp>
#include <xlnt/styles/font.hpp>
#include <xlnt/styles/format.hpp>
#include <xlnt/styles/alignment.hpp>
#include <xlnt/styles/border.hpp>
#include <xlnt/styles/fill.hpp>
#include <xlnt/styles/font.hpp>
#include <xlnt/styles/number_format.hpp>
#include <xlnt/styles/protection.hpp>
#include <xlnt/utils/hash_combine.hpp>
#include <detail/format_impl.hpp>
namespace xlnt {
format::format() : base_format()
{
}
format::format(const format &other) : base_format(other)
{
}
format &format::operator=(const format &other)
{
base_format::operator=(other);
return *this;
}
std::string format::to_hash_string() const
{
auto hash_string = base_format::to_hash_string();
hash_string.append(":format:");
return hash_string;
}
} // namespace xlnt

View File

@ -26,12 +26,12 @@
#include <unordered_map>
#include <vector>
#include <detail/number_formatter.hpp>
#include <xlnt/utils/datetime.hpp>
#include <xlnt/utils/exceptions.hpp>
#include <xlnt/utils/hash_combine.hpp>
#include <xlnt/styles/number_format.hpp>
#include <detail/number_formatter.hpp>
namespace {
const std::unordered_map<std::size_t, std::string> &builtin_formats()
@ -254,7 +254,7 @@ number_format number_format::from_builtin_id(std::size_t builtin_id)
{
if (builtin_formats().find(builtin_id) == builtin_formats().end())
{
throw std::runtime_error("unknown id: " + std::to_string(builtin_id));
throw invalid_parameter(); //("unknown id: " + std::to_string(builtin_id));
}
auto format_string = builtin_formats().at(builtin_id);
@ -316,7 +316,7 @@ std::size_t number_format::get_id() const
{
if(!id_set_)
{
throw std::runtime_error("number format doesn't have an id");
throw invalid_attribute();
}
return id_;

View File

@ -26,32 +26,22 @@
namespace xlnt {
protection::protection() : protection(true, false)
{
}
protection::protection(bool locked, bool hidden)
: locked_(locked),
hidden_(hidden)
{
}
bool protection::get_locked() const
bool protection::locked() const
{
return locked_;
}
void protection::set_locked(bool locked)
protection &protection::locked(bool locked)
{
locked_ = locked;
}
bool protection::get_hidden() const
bool protection::hidden() const
{
return hidden_;
}
void protection::set_hidden(bool hidden)
protection &protection::hidden(bool hidden)
{
hidden_ = hidden;
}

View File

@ -22,69 +22,45 @@
// @license: http://www.opensource.org/licenses/mit-license.php
// @author: see AUTHORS file
#include <xlnt/styles/alignment.hpp>
#include <xlnt/styles/border.hpp>
#include <xlnt/styles/fill.hpp>
#include <xlnt/styles/font.hpp>
#include <xlnt/styles/number_format.hpp>
#include <xlnt/styles/protection.hpp>
#include <detail/style_impl.hpp> // include order is important here
#include <xlnt/styles/style.hpp>
namespace xlnt {
style::style()
: base_format(),
hidden_(false),
builtin_id_(0)
bool style::hidden() const
{
return d_->hidden_style;
}
style::style(const style &other)
: base_format(other),
name_(other.name_),
hidden_(other.hidden_),
builtin_id_(other.builtin_id_)
style &style::hidden(bool value)
{
d_->hidden_style = value;
}
style &style::operator=(const style &other)
std::size_t style::built_in_id() const
{
base_format::operator=(other);
name_ = other.name_;
hidden_ = other.hidden_;
builtin_id_ = other.builtin_id_;
return *this;
return d_->built_in_style_id;
}
bool style::get_hidden() const
style &style::built_in_id(std::size_t builtin_id)
{
return hidden_;
d_->built_in_style_id = builtin_id;
}
void style::set_hidden(bool value)
std::string style::name() const
{
hidden_ = value;
return d_->name;
}
std::size_t style::get_builtin_id() const
style &style::name(const std::string &name)
{
return builtin_id_;
}
void style::set_builtin_id(std::size_t builtin_id)
{
builtin_id_ = builtin_id;
}
std::string style::get_name() const
{
return name_;
}
void style::set_name(const std::string &name)
{
name_ = name;
}
std::string style::to_hash_string() const
{
return base_format::to_hash_string() + name_;
d_->name = name;
}
} // namespace xlnt

View File

@ -34,20 +34,20 @@ public:
{
xlnt::color auto_;
TS_ASSERT(auto_.is_auto());
TS_ASSERT_THROWS(auto_.get_theme(), std::runtime_error);
TS_ASSERT_THROWS(auto_.get_indexed(), std::runtime_error);
TS_ASSERT_THROWS(auto_.get_rgb(), std::runtime_error);
TS_ASSERT_THROWS(auto_.get_theme(), xlnt::invalid_attribute);
TS_ASSERT_THROWS(auto_.get_indexed(), xlnt::invalid_attribute);
TS_ASSERT_THROWS(auto_.get_rgb(), xlnt::invalid_attribute);
xlnt::color indexed = xlnt::indexed_color(1);
TS_ASSERT(!indexed.is_auto());
TS_ASSERT_EQUALS(indexed.get_indexed().get_index(), 1);
TS_ASSERT_THROWS(indexed.get_theme(), std::runtime_error);
TS_ASSERT_THROWS(indexed.get_rgb(), std::runtime_error);
TS_ASSERT_THROWS(indexed.get_theme(), xlnt::invalid_attribute);
TS_ASSERT_THROWS(indexed.get_rgb(), xlnt::invalid_attribute);
xlnt::color theme = xlnt::theme_color(3);
TS_ASSERT(!theme.is_auto());
TS_ASSERT_EQUALS(theme.get_theme().get_index(), 3);
TS_ASSERT_THROWS(theme.get_indexed(), std::runtime_error);
TS_ASSERT_THROWS(theme.get_rgb(), std::runtime_error);
TS_ASSERT_THROWS(theme.get_indexed(), xlnt::invalid_attribute);
TS_ASSERT_THROWS(theme.get_rgb(), xlnt::invalid_attribute);
}
};

View File

@ -12,42 +12,42 @@ public:
{
xlnt::fill fill;
TS_ASSERT_EQUALS(fill.get_type(), xlnt::fill::type::pattern);
fill = xlnt::fill::gradient(xlnt::gradient_fill::type::linear);
TS_ASSERT_EQUALS(fill.get_type(), xlnt::fill::type::gradient);
TS_ASSERT_EQUALS(fill.get_gradient_fill().get_type(), xlnt::gradient_fill::type::linear);
TS_ASSERT_EQUALS(fill.type(), xlnt::fill_type::pattern);
fill = xlnt::fill(xlnt::gradient_fill());
TS_ASSERT_EQUALS(fill.type(), xlnt::fill_type::gradient);
TS_ASSERT_EQUALS(fill.gradient_fill().type(), xlnt::gradient_fill_type::linear);
TS_ASSERT_EQUALS(fill.get_gradient_fill().get_gradient_left(), 0);
TS_ASSERT_EQUALS(fill.get_gradient_fill().get_gradient_right(), 0);
TS_ASSERT_EQUALS(fill.get_gradient_fill().get_gradient_top(), 0);
TS_ASSERT_EQUALS(fill.get_gradient_fill().get_gradient_bottom(), 0);
TS_ASSERT_EQUALS(fill.gradient_fill().left(), 0);
TS_ASSERT_EQUALS(fill.gradient_fill().right(), 0);
TS_ASSERT_EQUALS(fill.gradient_fill().top(), 0);
TS_ASSERT_EQUALS(fill.gradient_fill().bottom(), 0);
TS_ASSERT_THROWS(fill.get_pattern_fill(), std::runtime_error);
TS_ASSERT_THROWS(fill.pattern_fill(), xlnt::invalid_attribute);
TS_ASSERT_EQUALS(fill.get_gradient_fill().get_degree(), 0);
fill.get_gradient_fill().set_degree(1);
TS_ASSERT_EQUALS(fill.get_gradient_fill().get_degree(), 1);
TS_ASSERT_EQUALS(fill.gradient_fill().degree(), 0);
fill = fill.gradient_fill().degree(1);
TS_ASSERT_EQUALS(fill.gradient_fill().degree(), 1);
fill = xlnt::fill::pattern(xlnt::pattern_fill::type::solid);
fill = xlnt::pattern_fill().type(xlnt::pattern_fill_type::solid);
fill.get_pattern_fill().set_foreground_color(xlnt::color::black());
TS_ASSERT(fill.get_pattern_fill().get_foreground_color());
TS_ASSERT_EQUALS((*fill.get_pattern_fill().get_foreground_color()).get_rgb().get_hex_string(), xlnt::color::black().get_rgb().get_hex_string());
fill = fill.pattern_fill().foreground(xlnt::color::black());
TS_ASSERT(fill.pattern_fill().foreground());
TS_ASSERT_EQUALS((*fill.pattern_fill().foreground()).get_rgb().get_hex_string(), xlnt::color::black().get_rgb().get_hex_string());
fill.get_pattern_fill().set_background_color(xlnt::color::green());
TS_ASSERT(fill.get_pattern_fill().get_background_color());
TS_ASSERT_EQUALS((*fill.get_pattern_fill().get_background_color()).get_rgb().get_hex_string(), xlnt::color::green().get_rgb().get_hex_string());
fill = fill.pattern_fill().background(xlnt::color::green());
TS_ASSERT(fill.pattern_fill().background());
TS_ASSERT_EQUALS((*fill.pattern_fill().background()).get_rgb().get_hex_string(), xlnt::color::green().get_rgb().get_hex_string());
const auto &const_fill = fill;
TS_ASSERT(const_fill.get_pattern_fill().get_foreground_color());
TS_ASSERT(const_fill.get_pattern_fill().get_background_color());
TS_ASSERT(const_fill.pattern_fill().foreground());
TS_ASSERT(const_fill.pattern_fill().background());
}
void test_hash()
{
xlnt::fill pattern_fill = xlnt::fill::pattern(xlnt::pattern_fill::type::solid);
xlnt::fill gradient_fill_linear = xlnt::fill::gradient(xlnt::gradient_fill::type::linear);
xlnt::fill gradient_fill_path = xlnt::fill::gradient(xlnt::gradient_fill::type::path);
xlnt::fill pattern_fill = xlnt::pattern_fill().type(xlnt::pattern_fill_type::solid);
xlnt::fill gradient_fill_linear = xlnt::gradient_fill().type(xlnt::gradient_fill_type::linear);
xlnt::fill gradient_fill_path = xlnt::gradient_fill().type(xlnt::gradient_fill_type::path);
TS_ASSERT_DIFFERS(pattern_fill.hash(), gradient_fill_linear.hash());
TS_ASSERT_DIFFERS(gradient_fill_linear.hash(), gradient_fill_path.hash());

View File

@ -115,7 +115,6 @@ int date::to_number(calendar base_date) const
date date::today()
{
std::tm now = safe_localtime(std::time(0));
return date(1900 + now.tm_year, now.tm_mon + 1, now.tm_mday);
}

View File

@ -27,22 +27,6 @@
#include <xlnt/utils/date.hpp>
#include <xlnt/utils/time.hpp>
namespace {
std::tm safe_localtime(std::time_t raw_time)
{
#ifdef _MSC_VER
std::tm result;
localtime_s(&result, &raw_time);
return result;
#else
return *localtime(&raw_time);
#endif
}
} // namespace
namespace xlnt {
datetime datetime::from_number(long double raw_time, calendar base_date)
@ -73,14 +57,12 @@ std::string datetime::to_string() const
datetime datetime::now()
{
std::tm now = safe_localtime(std::time(0));
return datetime(1900 + now.tm_year, now.tm_mon + 1, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec);
return datetime(date::today(), time::now());
}
datetime datetime::today()
{
return now();
return datetime(date::today(), time(0, 0, 0, 0));
}
datetime::datetime(int year_, int month_, int day_, int hour_, int minute_, int second_, int microsecond_)
@ -94,6 +76,17 @@ datetime::datetime(int year_, int month_, int day_, int hour_, int minute_, int
{
}
datetime::datetime(const date &d, const time &t)
: year(d.year),
month(d.month),
day(d.day),
hour(t.hour),
minute(t.minute),
second(t.second),
microsecond(t.microsecond)
{
}
int datetime::weekday() const
{
return date(year, month, day).weekday();

View File

@ -25,6 +25,22 @@
#include <xlnt/utils/time.hpp>
namespace {
std::tm safe_localtime(std::time_t raw_time)
{
#ifdef _MSC_VER
std::tm result;
localtime_s(&result, &raw_time);
return result;
#else
return *localtime(&raw_time);
#endif
}
} // namespace
namespace xlnt {
time time::from_number(long double raw_time)
@ -107,4 +123,10 @@ long double time::to_number() const
return number;
}
time time::now()
{
std::tm now = safe_localtime(std::time(0));
return time(now.tm_hour, now.tm_min, now.tm_sec);
}
} // namespace xlnt

View File

@ -24,15 +24,21 @@ public:
return xml_helper::archives_match(wb_archive, file_archive);
}
void test_minimal()
void test_produce_minimal()
{
xlnt::workbook wb = xlnt::workbook::minimal();
TS_ASSERT(workbook_matches_file(wb, path_helper::get_data_directory("10_minimal.xlsx")));
TS_ASSERT(workbook_matches_file(wb, path_helper::get_data_directory("8_minimal.xlsx")));
}
void test_empty_excel()
void test_produce_default_excel()
{
xlnt::workbook wb = xlnt::workbook::empty_excel();
TS_ASSERT(workbook_matches_file(wb, path_helper::get_data_directory("8_default-excel.xlsx")));
TS_ASSERT(workbook_matches_file(wb, path_helper::get_data_directory("9_default-excel.xlsx")));
}
void test_produce_default_libre_office()
{
xlnt::workbook wb = xlnt::workbook::empty_libre_office();
TS_ASSERT(workbook_matches_file(wb, path_helper::get_data_directory("10_default-libre-office.xlsx")));
}
};

View File

@ -66,14 +66,14 @@ public:
void test_round_trip_empty_excel_rw()
{
auto path = path_helper::get_data_directory("8_default-excel.xlsx");
auto path = path_helper::get_data_directory("9_default-excel.xlsx");
TS_ASSERT(round_trip_matches_rw(path));
}
void test_round_trip_empty_libre_rw()
{
TS_SKIP("");
auto path = path_helper::get_data_directory("9_default-libre-office.xlsx");
auto path = path_helper::get_data_directory("10_default-libre-office.xlsx");
TS_ASSERT(round_trip_matches_rw(path));
}
};

View File

@ -30,10 +30,12 @@
#include <detail/cell_impl.hpp>
#include <detail/constants.hpp>
#include <detail/excel_thumbnail.hpp>
#include <detail/xlsx_consumer.hpp>
#include <detail/xlsx_producer.hpp>
#include <detail/workbook_impl.hpp>
#include <detail/worksheet_impl.hpp>
#include <xlnt/cell/cell.hpp>
#include <xlnt/packaging/manifest.hpp>
#include <xlnt/packaging/relationship.hpp>
#include <xlnt/packaging/zip_file.hpp>
@ -86,7 +88,7 @@ workbook workbook::minimal()
workbook workbook::empty_excel()
{
auto impl = new detail::workbook_impl();
xlnt::workbook wb(impl);
workbook wb(impl);
wb.d_->manifest_.register_override_type(path("xl/workbook.xml"),
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml");
@ -97,33 +99,7 @@ workbook workbook::empty_excel()
"application/vnd.openxmlformats-package.relationships+xml");
wb.d_->manifest_.register_default_type("xml", "application/xml");
const std::vector<std::uint8_t> thumbnail = {
0xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x01,
0x00,0x60,0x00,0x60,0x00,0x00,0xff,0xe1,0x00,0x16,0x45,0x78,0x69,0x66,
0x00,0x00,0x49,0x49,0x2a,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0xff,0xdb,0x00,0x43,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x01,0xff,0xdb,0x00,0x43,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0xff,0xc0,0x00,0x11,0x08,0x00,0x01,0x00,0x01,0x03,0x01,0x22,0x00,0x02,
0x11,0x01,0x03,0x11,0x01,0xff,0xc4,0x00,0x15,0x00,0x01,0x01,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0a,
0xff,0xc4,0x00,0x14,0x10,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc4,0x00,0x14,0x01,0x01,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0xff,0xc4,0x00,0x14,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,
0x03,0x01,0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xbf,0x80,0x01,0xff,
0xd9
};
wb.set_thumbnail(thumbnail, "jpeg", "image/jpeg");
wb.set_thumbnail(excel_thumbnail(), "jpeg", "image/jpeg");
wb.d_->manifest_.register_override_type(path("docProps/core.xml"),
"application/vnd.openxmlformats-package.coreproperties+xml");
@ -163,14 +139,11 @@ workbook workbook::empty_excel()
ws.d_->has_format_properties_ = true;
ws.d_->has_view_ = true;
wb.add_format(format());
wb.create_format();
wb.create_style("Normal");
wb.set_theme(theme());
wb.d_->stylesheet_.format_styles.front() = "Normal";
xlnt::fill gray125 = xlnt::fill::pattern(xlnt::pattern_fill::type::gray125);
wb.d_->stylesheet_.fills.push_back(gray125);
wb.d_->stylesheet_.fills.push_back(pattern_fill().type(pattern_fill_type::gray125));
return wb;
}
@ -180,6 +153,90 @@ workbook workbook::empty_libre_office()
auto impl = new detail::workbook_impl();
workbook wb(impl);
wb.d_->manifest_.register_override_type(path("xl/workbook.xml"),
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml");
wb.d_->manifest_.register_relationship(uri("/"), relationship::type::office_document,
uri("xl/workbook.xml"), target_mode::internal);
wb.d_->manifest_.register_override_type(path("docProps/core.xml"),
"application/vnd.openxmlformats-package.coreproperties+xml");
wb.d_->manifest_.register_relationship(uri("/"), relationship::type::core_properties,
uri("docProps/core.xml"), target_mode::internal);
wb.d_->manifest_.register_override_type(path("docProps/app.xml"),
"application/vnd.openxmlformats-officedocument.extended-properties+xml");
wb.d_->manifest_.register_relationship(uri("/"), relationship::type::extended_properties,
uri("docProps/app.xml"), target_mode::internal);
wb.d_->manifest_.register_override_type(path("_rels/.rels"),
"application/vnd.openxmlformats-package.relationships+xml");
wb.d_->manifest_.register_override_type(path("xl/_rels/workbook.xml.rels"),
"application/vnd.openxmlformats-package.relationships+xml");
std::string title("Sheet1");
wb.d_->worksheets_.push_back(detail::worksheet_impl(&wb, 1, title));
wb.d_->manifest_.register_override_type(path("xl/worksheets/sheet1.xml"),
"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml");
auto ws_rel = wb.d_->manifest_.register_relationship(uri("xl/workbook.xml"),
relationship::type::worksheet, uri("worksheets/sheet1.xml"), target_mode::internal);
wb.d_->sheet_title_rel_id_map_[title] = ws_rel;
wb.d_->stylesheet_.number_formats.push_back(xlnt::number_format("General", 164));
wb.d_->stylesheet_.fonts.push_back(xlnt::font().size(10).name("Arial").family(2));
wb.d_->stylesheet_.fonts.push_back(xlnt::font().size(10).name("Arial").family(0));
wb.d_->stylesheet_.fills.push_back(xlnt::pattern_fill().type(pattern_fill_type::none));
wb.d_->stylesheet_.fills.push_back(xlnt::pattern_fill().type(pattern_fill_type::gray125));
wb.d_->stylesheet_.borders.push_back(xlnt::border().diagonal(xlnt::diagonal_direction::neither));
auto alignment = xlnt::alignment()
.horizontal(horizontal_alignment::general)
.vertical(vertical_alignment::bottom)
.rotation(0)
.wrap(false)
.indent(0)
.shrink(false);
auto protection = xlnt::protection()
.locked(true)
.hidden(false);
wb.create_style("Normal").built_in_id(0).custom(false);
wb.create_style("Comma").built_in_id(0).custom(false);
wb.create_style("Comma [0]").built_in_id(0).custom(false);
wb.create_style("Currency").built_in_id(0).custom(false);
wb.create_style("Currency [0]").built_in_id(0).custom(false);
wb.create_style("Percent").built_in_id(0).custom(false);
/*
wb.d_->stylesheet_.styles.push_back(xlnt::style().name("Normal")
.builtin_id(0).custom(false).number_format_id(164)
.font_id(0).fill_id(0).border_id(0).font_applied(true)
.border_applied(true).alignment(alignment).protection(protection));
wb.d_->stylesheet_.styles.push_back(xlnt::style().name("Comma")
.builtin_id(3).custom(false).number_format_id(164)
.number_format_id(43).font_id(1).fill_id(0).border_id(0).font_applied(true));
wb.d_->stylesheet_.styles.push_back(xlnt::style().name("Comma [0]")
.builtin_id(6).custom(false).number_format_id(164)
.number_format_id(41).font_id(1).fill_id(0).border_id(0).font_applied(true));
wb.d_->stylesheet_.styles.push_back(xlnt::style().name("Currency")
.builtin_id(4).custom(false).number_format_id(164)
.number_format_id(44).font_id(1).fill_id(0).border_id(0).font_applied(true));
wb.d_->stylesheet_.styles.push_back(xlnt::style().name("Currency[0]")
.builtin_id(7).custom(false).number_format_id(164)
.number_format_id(42).font_id(1).fill_id(0).border_id(0).font_applied(true));
wb.d_->stylesheet_.styles.push_back(xlnt::style().name("Percent")
.builtin_id(5).custom(false).number_format_id(164)
.number_format_id(9).font_id(1).fill_id(0).border_id(0).font_applied(true));
*/
auto &format = wb.create_format();
format.set_number_format(number_format("General", 164));
format.set_alignment(alignment);
format.set_protection(protection);
format.set_style("Normal");
return wb;
}
@ -201,6 +258,71 @@ workbook::workbook(detail::workbook_impl *impl) : d_(impl)
{
}
void workbook::register_app_properties_in_manifest()
{
auto wb_rel = get_manifest().get_relationship(path("/"), relationship_type::office_document);
if (!get_manifest().has_relationship(wb_rel.get_target().get_path(), relationship_type::extended_properties))
{
get_manifest().register_override_type(path("docProps/app.xml"),
"application/vnd.openxmlformats-officedocument.extended-properties+xml");
get_manifest().register_relationship(uri("/"), relationship::type::extended_properties,
uri("docProps/app.xml"), target_mode::internal);
}
}
void workbook::register_core_properties_in_manifest()
{
auto wb_rel = get_manifest().get_relationship(path("/"), relationship_type::office_document);
if (!get_manifest().has_relationship(wb_rel.get_target().get_path(), relationship_type::core_properties))
{
get_manifest().register_override_type(path("docProps/core.xml"),
"application/vnd.openxmlformats-package.coreproperties+xml");
get_manifest().register_relationship(uri("/"), relationship::type::core_properties,
uri("docProps/core.xml"), target_mode::internal);
}
}
void workbook::register_shared_string_table_in_manifest()
{
auto wb_rel = get_manifest().get_relationship(path("/"), relationship_type::office_document);
if (!get_manifest().has_relationship(wb_rel.get_target().get_path(), relationship_type::shared_string_table))
{
get_manifest().register_override_type(constants::part_shared_strings(),
"application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml");
get_manifest().register_relationship(wb_rel.get_target(),
relationship::type::shared_string_table, uri("styles.xml"), target_mode::internal);
}
}
void workbook::register_stylesheet_in_manifest()
{
auto wb_rel = get_manifest().get_relationship(path("/"), relationship_type::office_document);
if (!get_manifest().has_relationship(wb_rel.get_target().get_path(), relationship_type::styles))
{
get_manifest().register_override_type(constants::part_styles(),
"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml");
get_manifest().register_relationship(wb_rel.get_target(),
relationship::type::styles, uri("styles.xml"), target_mode::internal);
}
}
void workbook::register_theme_in_manifest()
{
auto wb_rel = get_manifest().get_relationship(path("/"), relationship_type::office_document);
if (!get_manifest().has_relationship(wb_rel.get_target().get_path(), relationship_type::theme))
{
get_manifest().register_override_type(constants::part_theme(),
"application/vnd.openxmlformats-officedocument.theme+xml");
get_manifest().register_relationship(wb_rel.get_target(),
relationship::type::theme, uri("theme/theme1.xml"), target_mode::internal);
}
}
const worksheet workbook::get_sheet_by_title(const std::string &title) const
{
for (auto &impl : d_->worksheets_)
@ -318,19 +440,19 @@ worksheet workbook::create_sheet()
return worksheet(&d_->worksheets_.back());
}
void workbook::copy_sheet(xlnt::worksheet worksheet)
void workbook::copy_sheet(worksheet to_copy)
{
if(worksheet.d_->parent_ != this) throw xlnt::invalid_parameter();
if(to_copy.d_->parent_ != this) throw invalid_parameter();
xlnt::detail::worksheet_impl impl(*worksheet.d_);
detail::worksheet_impl impl(*to_copy.d_);
auto new_sheet = create_sheet();
impl.title_ = new_sheet.get_title();
*new_sheet.d_ = impl;
}
void workbook::copy_sheet(xlnt::worksheet worksheet, std::size_t index)
void workbook::copy_sheet(worksheet to_copy, std::size_t index)
{
copy_sheet(worksheet);
copy_sheet(to_copy);
if (index != d_->worksheets_.size() - 1)
{
@ -345,13 +467,13 @@ void workbook::copy_sheet(xlnt::worksheet worksheet, std::size_t index)
}
}
std::size_t workbook::get_index(xlnt::worksheet worksheet)
std::size_t workbook::get_index(worksheet ws)
{
auto match = std::find(begin(), end(), worksheet);
auto match = std::find(begin(), end(), ws);
if (match == end())
{
throw std::runtime_error("worksheet isn't owned by this workbook");
throw invalid_parameter();
}
return std::distance(begin(), match);
@ -378,7 +500,7 @@ void workbook::remove_named_range(const std::string &name)
}
}
throw std::runtime_error("named range not found");
throw key_not_found();
}
range workbook::get_named_range(const std::string &name)
@ -391,7 +513,7 @@ range workbook::get_named_range(const std::string &name)
}
}
throw std::runtime_error("named range not found");
throw key_not_found();
}
void workbook::load(std::istream &stream)
@ -460,7 +582,7 @@ void workbook::remove_sheet(worksheet ws)
if (match_iter == d_->worksheets_.end())
{
throw std::runtime_error("worksheet not owned by this workbook");
throw invalid_parameter();
}
auto sheet_filename = path("worksheets/sheet" + std::to_string(d_->worksheets_.size()) + ".xml");
@ -636,16 +758,7 @@ const theme &workbook::get_theme() const
void workbook::set_theme(const theme &value)
{
auto workbook_rel = d_->manifest_.get_relationship(path("/"), relationship::type::office_document);
if (!d_->manifest_.has_relationship(workbook_rel.get_target().get_path(), relationship::type::theme))
{
d_->manifest_.register_override_type(constants::part_theme(),
"application/vnd.openxmlformats-officedocument.theme+xml");
d_->manifest_.register_relationship(workbook_rel.get_target(),
relationship::type::theme, uri("theme/theme1.xml"), target_mode::internal);
}
register_theme_in_manifest();
d_->has_theme_ = true;
d_->theme_ = value;
}
@ -665,47 +778,15 @@ std::vector<named_range> workbook::get_named_ranges() const
return named_ranges;
}
std::size_t workbook::add_format(const format &to_add)
format &workbook::create_format()
{
auto workbook_rel = d_->manifest_.get_relationship(path("/"), relationship::type::office_document);
if (!d_->manifest_.has_relationship(workbook_rel.get_target().get_path(), relationship::type::styles))
{
d_->manifest_.register_override_type(constants::part_styles(),
"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml");
d_->manifest_.register_relationship(workbook_rel.get_target(),
relationship::type::styles, uri("styles.xml"), target_mode::internal);
}
return d_->stylesheet_.add_format(to_add);
}
std::size_t workbook::add_style(const style &to_add)
{
auto workbook_rel = d_->manifest_.get_relationship(path("/"), relationship::type::office_document);
if (!d_->manifest_.has_relationship(workbook_rel.get_target().get_path(), relationship::type::styles))
{
d_->manifest_.register_override_type(constants::part_styles(),
"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml");
d_->manifest_.register_relationship(workbook_rel.get_target(),
relationship::type::styles, uri("styles.xml"), target_mode::internal);
}
return d_->stylesheet_.add_style(to_add);
register_stylesheet_in_manifest();
return d_->stylesheet_.create_format();
}
bool workbook::has_style(const std::string &name) const
{
return std::find_if(d_->stylesheet_.styles.begin(), d_->stylesheet_.styles.end(),
[&](const style &s) { return s.get_name() == name; }) != d_->stylesheet_.styles.end();
}
std::size_t workbook::get_style_id(const std::string &name) const
{
return std::distance(d_->stylesheet_.styles.begin(),
std::find_if(d_->stylesheet_.styles.begin(), d_->stylesheet_.styles.end(),
[&](const style &s) { return s.get_name() == name; }));
return d_->stylesheet_.has_style(name);
}
void workbook::clear_styles()
@ -736,12 +817,12 @@ void workbook::apply_to_cells(std::function<void(cell)> f)
format &workbook::get_format(std::size_t format_index)
{
return d_->stylesheet_.formats.at(format_index);
return d_->stylesheet_.get_format(format_index);
}
const format &workbook::get_format(std::size_t format_index) const
{
return d_->stylesheet_.formats.at(format_index);
return d_->stylesheet_.get_format(format_index);
}
manifest &workbook::get_manifest()
@ -766,15 +847,7 @@ const std::vector<text> &workbook::get_shared_strings() const
void workbook::add_shared_string(const text &shared, bool allow_duplicates)
{
auto workbook_rel = d_->manifest_.get_relationship(path("/"), relationship::type::office_document);
if (!d_->manifest_.has_relationship(workbook_rel.get_target().get_path(), relationship::type::styles))
{
d_->manifest_.register_override_type(constants::part_shared_strings(),
"application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml");
d_->manifest_.register_relationship(workbook_rel.get_target(),
relationship::type::shared_string_table, uri("styles.xml"), target_mode::internal);
}
register_shared_string_table_in_manifest();
if (!allow_duplicates)
{
@ -818,34 +891,17 @@ const std::vector<std::uint8_t> &workbook::get_thumbnail() const
style &workbook::create_style(const std::string &name)
{
style style;
style.set_name(name);
d_->stylesheet_.styles.push_back(style);
return d_->stylesheet_.styles.back();
return d_->stylesheet_.create_style().name(name);
}
style &workbook::get_style(const std::string &name)
{
return *std::find_if(d_->stylesheet_.styles.begin(), d_->stylesheet_.styles.end(),
[&name](const style &s) { return s.get_name() == name; });
return d_->stylesheet_.get_style(name);
}
const style &workbook::get_style(const std::string &name) const
{
return *std::find_if(d_->stylesheet_.styles.begin(), d_->stylesheet_.styles.end(),
[&name](const style &s) { return s.get_name() == name; });
}
style &workbook::get_style_by_id(std::size_t style_id)
{
return d_->stylesheet_.styles.at(style_id);
}
const style &workbook::get_style_by_id(std::size_t style_id) const
{
return d_->stylesheet_.styles.at(style_id);
return d_->stylesheet_.get_style(name);
}
std::string workbook::get_application() const

View File

@ -966,12 +966,6 @@ public:
TS_ASSERT_EQUALS(dimensions, xlnt::range_reference("B2", "B2"));
}
void test_get_title_bad()
{
xlnt::worksheet ws;
TS_ASSERT_THROWS(ws.get_title(), std::runtime_error);
}
void test_has_cell()
{
xlnt::workbook wb;
@ -1125,8 +1119,8 @@ public:
{
xlnt::workbook wb;
auto ws = wb.get_active_sheet();
TS_ASSERT_THROWS(ws.create_named_range("A1", "A2"), std::runtime_error);
TS_ASSERT_THROWS(ws.create_named_range("XFD1048576", "A2"), std::runtime_error);
TS_ASSERT_THROWS(ws.create_named_range("A1", "A2"), xlnt::invalid_parameter);
TS_ASSERT_THROWS(ws.create_named_range("XFD1048576", "A2"), xlnt::invalid_parameter);
TS_ASSERT_THROWS_NOTHING(ws.create_named_range("XFE1048576", "A2"));
TS_ASSERT_THROWS_NOTHING(ws.create_named_range("XFD1048577", "A2"));
}

View File

@ -90,24 +90,25 @@ void worksheet::create_named_range(const std::string &name, const std::string &r
void worksheet::create_named_range(const std::string &name, const range_reference &reference)
{
try
{
auto temp = cell_reference::split_reference(name);
// name is a valid reference, make sure it's outside the allowed range
if (column_t(temp.first).index <= column_t("XFD").index && temp.second <= 1048576)
{
throw invalid_parameter(); //("named range name must be outside the range A1-XFD1048576");
}
}
catch (xlnt::invalid_cell_reference)
{
// name is not a valid reference, that's good
}
std::vector<named_range::target> targets;
targets.push_back({ *this, reference });
targets.push_back({ *this, reference });
try
{
auto temp = cell_reference::split_reference(name);
if (column_t(temp.first).index <= column_t("XFD").index && temp.second <= 1048576)
{
throw std::runtime_error("named range name must be outside the range A1-XFD1048576");
}
}
catch(xlnt::exception)
{
// must not be a valid cell reference
}
d_->named_ranges_[name] = named_range(name, targets);
}
@ -251,11 +252,6 @@ std::size_t worksheet::get_id() const
std::string worksheet::get_title() const
{
if (d_ == nullptr)
{
throw std::runtime_error("null worksheet");
}
return d_->title_;
}
@ -350,7 +346,10 @@ cell worksheet::get_cell(const cell_reference &reference)
if (row.find(reference.get_column_index()) == row.end())
{
row[reference.get_column_index()] = detail::cell_impl(d_, reference.get_column_index(), reference.get_row());
auto impl = row[reference.get_column_index()] = detail::cell_impl();
impl.parent_ = d_;
impl.column_ = reference.get_column_index();
impl.row_ = reference.get_row();
}
return cell(&row[reference.get_column_index()]);
@ -548,7 +547,7 @@ void worksheet::unmerge_cells(const range_reference &reference)
if (match == d_->merged_cells_.end())
{
throw std::runtime_error("cells not merged");
throw invalid_parameter();
}
d_->merged_cells_.erase(match);
@ -692,8 +691,8 @@ bool worksheet::compare(const worksheet &other, bool reference) const
return false;
}
auto this_cell = cell.second.self();
auto other_cell = other.d_->cell_map_[row.first][cell.first].self();
xlnt::cell this_cell(&cell.second);
xlnt::cell other_cell(&other.d_->cell_map_[row.first][cell.first]);
if (this_cell.get_data_type() != other_cell.get_data_type())
{
@ -769,7 +768,7 @@ void worksheet::remove_named_range(const std::string &name)
{
if (!has_named_range(name))
{
throw std::runtime_error("worksheet doesn't have named range");
throw key_not_found();
}
d_->named_ranges_.erase(name);
@ -1046,11 +1045,6 @@ sheet_view worksheet::get_view() const
return d_->view_;
}
std::size_t worksheet::next_custom_number_format_id()
{
return get_workbook().impl().stylesheet_.next_custom_format_id;
}
bool worksheet::x14ac_enabled() const
{
return d_->x14ac_;

View File

@ -147,7 +147,7 @@ public:
std::cout << std::endl;
std::cout << "right has: ";
for (auto &info : left_info)
for (auto &info : right_info)
{
std::cout << info.filename.string() << ", ";
}