diff --git a/.gitignore b/.gitignore
index 084d94fe1ac592b7dea47fd9b22a5626a3203721..eff00ce6675b9eb7c0dae3c9f48ccb3dcd860134 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,9 +1,17 @@
-Source/bin/
-Source/obj/
-Source/Svg.csproj.user
-Source/Svg.suo
+Source/**/bin/
+Source/**/obj/
+Source/**/*.csproj.user
+Source/**/*.suo
Source/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache
Samples/SVGViewer/obj/
Samples/SVGViewer/bin/
Samples/SVGViewer/SVGViewer.OpenCover.Settings
+Source/**/*.dll
+Source/**/*.pdb
+Tests/**/bin/
+Tests/**/obj/
+Tests/**/*.csproj.user
+Tests/**/*.suo
+*.trx
+Source/TestResults/
\ No newline at end of file
diff --git a/Samples/SvgExamples/Workflow.svg b/Samples/SvgExamples/Workflow.svg
deleted file mode 100644
index 0ecd70c982fc88b54cdc58bd7a2b5332838f6d14..0000000000000000000000000000000000000000
--- a/Samples/SvgExamples/Workflow.svg
+++ /dev/null
@@ -1,181 +0,0 @@
-
diff --git a/Source/Basic Shapes/SvgCircle.cs b/Source/Basic Shapes/SvgCircle.cs
index 29979c47f98ef8dea147218e52666b3c1a751a00..93a4fcd989e174559ae5580a062fa6006fc4f334 100644
--- a/Source/Basic Shapes/SvgCircle.cs
+++ b/Source/Basic Shapes/SvgCircle.cs
@@ -81,7 +81,7 @@ namespace Svg
/// The rectangular bounds of the circle.
public override RectangleF Bounds
{
- get { return this.Path.GetBounds(); }
+ get { return this.Path(null).GetBounds(); }
}
///
@@ -98,24 +98,19 @@ namespace Svg
///
/// Gets the representing this element.
///
- public override GraphicsPath Path
+ public override GraphicsPath Path(SvgRenderer renderer)
{
- get
+ if (this._path == null || this.IsPathDirty)
{
- if (this._path == null || this.IsPathDirty)
- {
- _path = new GraphicsPath();
- _path.StartFigure();
- _path.AddEllipse(this.Center.ToDeviceValue().X - this.Radius.ToDeviceValue(), this.Center.ToDeviceValue().Y - this.Radius.ToDeviceValue(), 2 * this.Radius.ToDeviceValue(), 2 * this.Radius.ToDeviceValue());
- _path.CloseFigure();
- this.IsPathDirty = false;
- }
- return _path;
- }
- protected set
- {
- _path = value;
+ _path = new GraphicsPath();
+ _path.StartFigure();
+ var center = this.Center.ToDeviceValue(renderer, this);
+ var radius = this.Radius.ToDeviceValue(renderer, UnitRenderingType.Other, this);
+ _path.AddEllipse(center.X - radius, center.Y - radius, 2 * radius, 2 * radius);
+ _path.CloseFigure();
+ this.IsPathDirty = false;
}
+ return _path;
}
///
diff --git a/Source/Basic Shapes/SvgEllipse.cs b/Source/Basic Shapes/SvgEllipse.cs
index 90f364157ab8c7193b6359c9d39e09fba7a72c86..07f93ad223a317131915f98be9c40e55d1df5fb0 100644
--- a/Source/Basic Shapes/SvgEllipse.cs
+++ b/Source/Basic Shapes/SvgEllipse.cs
@@ -95,34 +95,27 @@ namespace Svg
/// The bounds.
public override RectangleF Bounds
{
- get { return this.Path.GetBounds(); }
+ get { return this.Path(null).GetBounds(); }
}
///
/// Gets the for this element.
///
///
- public override GraphicsPath Path
+ public override GraphicsPath Path(SvgRenderer renderer)
{
- get
+ if (this._path == null || this.IsPathDirty)
{
- if (this._path == null || this.IsPathDirty)
- {
- PointF center = new PointF(this._centerX.ToDeviceValue(this), this._centerY.ToDeviceValue(this, true));
- PointF radius = new PointF(this._radiusX.ToDeviceValue(this), this._radiusY.ToDeviceValue(this, true));
+ var center = SvgUnit.GetDevicePoint(this._centerX, this._centerY, renderer, this);
+ var radius = SvgUnit.GetDevicePoint(this._radiusX, this._radiusY, renderer, this);
- this._path = new GraphicsPath();
- _path.StartFigure();
- _path.AddEllipse(center.X - radius.X, center.Y - radius.Y, 2 * radius.X, 2 * radius.Y);
- _path.CloseFigure();
- this.IsPathDirty = false;
- }
- return _path;
- }
- protected set
- {
- _path = value;
+ this._path = new GraphicsPath();
+ _path.StartFigure();
+ _path.AddEllipse(center.X - radius.X, center.Y - radius.Y, 2 * radius.X, 2 * radius.Y);
+ _path.CloseFigure();
+ this.IsPathDirty = false;
}
+ return _path;
}
///
diff --git a/Source/Basic Shapes/SvgImage.cs b/Source/Basic Shapes/SvgImage.cs
index eeed03a6edd64081338ff11c84bbef32d31a6b19..a8762c9b7eb02567ab528a65c92573204582c82d 100644
--- a/Source/Basic Shapes/SvgImage.cs
+++ b/Source/Basic Shapes/SvgImage.cs
@@ -29,6 +29,17 @@ namespace Svg
public SvgPoint Location
{
get { return new SvgPoint(X, Y); }
+ }
+
+ ///
+ /// Gets or sets the aspect of the viewport.
+ ///
+ ///
+ [SvgAttribute("preserveAspectRatio")]
+ public SvgAspectRatio AspectRatio
+ {
+ get { return this.Attributes.GetAttribute("preserveAspectRatio"); }
+ set { this.Attributes["preserveAspectRatio"] = value; }
}
[SvgAttribute("x")]
@@ -75,21 +86,17 @@ namespace Svg
/// The bounds.
public override RectangleF Bounds
{
- get { return new RectangleF(this.Location.ToDeviceValue(), new SizeF(this.Width, this.Height)); }
+ get { return new RectangleF(this.Location.ToDeviceValue(null, this),
+ new SizeF(this.Width.ToDeviceValue(null, UnitRenderingType.Horizontal, this),
+ this.Height.ToDeviceValue(null, UnitRenderingType.Vertical, this))); }
}
///
/// Gets the for this element.
- ///
- public override GraphicsPath Path
+ ///
+ public override GraphicsPath Path(SvgRenderer renderer)
{
- get
- {
- return null;
- }
- protected set
- {
- }
+ return null;
}
///
@@ -106,13 +113,72 @@ namespace Svg
{
if (b != null)
{
+ var srcRect = new RectangleF(0, 0, b.Width, b.Height);
+ var destClip = new RectangleF(this.Location.ToDeviceValue(renderer, this),
+ new SizeF(Width.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this),
+ Height.ToDeviceValue(renderer, UnitRenderingType.Vertical, this)));
+ RectangleF destRect = destClip;
+
this.PushTransforms(renderer);
+ renderer.AddClip(new Region(destClip));
this.SetClip(renderer);
- RectangleF srcRect = new RectangleF(0, 0, b.Width, b.Height);
- var destRect = new RectangleF(this.Location.ToDeviceValue(),
- new SizeF(Width.ToDeviceValue(), Height.ToDeviceValue()));
+ if (AspectRatio != null && AspectRatio.Align != SvgPreserveAspectRatio.none)
+ {
+ var fScaleX = destClip.Width / srcRect.Width;
+ var fScaleY = destClip.Height / srcRect.Height;
+ var xOffset = 0.0f;
+ var yOffset = 0.0f;
+
+ if (AspectRatio.Slice)
+ {
+ fScaleX = Math.Max(fScaleX, fScaleY);
+ fScaleY = Math.Max(fScaleX, fScaleY);
+ }
+ else
+ {
+ fScaleX = Math.Min(fScaleX, fScaleY);
+ fScaleY = Math.Min(fScaleX, fScaleY);
+ }
+
+ switch (AspectRatio.Align)
+ {
+ case SvgPreserveAspectRatio.xMinYMin:
+ break;
+ case SvgPreserveAspectRatio.xMidYMin:
+ xOffset = (destClip.Width - srcRect.Width * fScaleX) / 2;
+ break;
+ case SvgPreserveAspectRatio.xMaxYMin:
+ xOffset = (destClip.Width - srcRect.Width * fScaleX);
+ break;
+ case SvgPreserveAspectRatio.xMinYMid:
+ yOffset = (destClip.Height - srcRect.Height * fScaleY) / 2;
+ break;
+ case SvgPreserveAspectRatio.xMidYMid:
+ xOffset = (destClip.Width - srcRect.Width * fScaleX) / 2;
+ yOffset = (destClip.Height - srcRect.Height * fScaleY) / 2;
+ break;
+ case SvgPreserveAspectRatio.xMaxYMid:
+ xOffset = (destClip.Width - srcRect.Width * fScaleX);
+ yOffset = (destClip.Height - srcRect.Height * fScaleY) / 2;
+ break;
+ case SvgPreserveAspectRatio.xMinYMax:
+ yOffset = (destClip.Height - srcRect.Height * fScaleY);
+ break;
+ case SvgPreserveAspectRatio.xMidYMax:
+ xOffset = (destClip.Width - srcRect.Width * fScaleX) / 2;
+ yOffset = (destClip.Height - srcRect.Height * fScaleY);
+ break;
+ case SvgPreserveAspectRatio.xMaxYMax:
+ xOffset = (destClip.Width - srcRect.Width * fScaleX);
+ yOffset = (destClip.Height - srcRect.Height * fScaleY);
+ break;
+ }
+ destRect = new RectangleF(destClip.X + xOffset, destClip.Y + yOffset,
+ srcRect.Width * fScaleX, srcRect.Height * fScaleY);
+ }
+
renderer.DrawImage(b, destRect, srcRect, GraphicsUnit.Pixel);
this.ResetClip(renderer);
@@ -129,7 +195,7 @@ namespace Svg
try
{
// handle data/uri embedded images (http://en.wikipedia.org/wiki/Data_URI_scheme)
- if (uri.Scheme == "data")
+ if (uri.IsAbsoluteUri && uri.Scheme == "data")
{
string uriString = uri.OriginalString;
int dataIdx = uriString.IndexOf(",") + 1;
@@ -143,14 +209,26 @@ namespace Svg
return image;
}
+ if (!uri.IsAbsoluteUri)
+ {
+ uri = new Uri(OwnerDocument.BaseUri, uri);
+ }
+
// should work with http: and file: protocol urls
var httpRequest = WebRequest.Create(uri);
using (WebResponse webResponse = httpRequest.GetResponse())
{
MemoryStream ms = BufferToMemoryStream(webResponse.GetResponseStream());
- Image image = Bitmap.FromStream(ms);
- return image;
+ if (uri.LocalPath.EndsWith(".svg", StringComparison.InvariantCultureIgnoreCase))
+ {
+ var doc = SvgDocument.Open(ms);
+ return doc.Draw();
+ }
+ else
+ {
+ return Bitmap.FromStream(ms);
+ }
}
}
catch (Exception ex)
diff --git a/Source/Basic Shapes/SvgLine.cs b/Source/Basic Shapes/SvgLine.cs
index bd24ad8b6ca9360dfa16bbc4dce05c5044f09e42..05c12a055f76d9abbd07767d2e0522f6823b057d 100644
--- a/Source/Basic Shapes/SvgLine.cs
+++ b/Source/Basic Shapes/SvgLine.cs
@@ -92,30 +92,25 @@ namespace Svg
{
}
- public override System.Drawing.Drawing2D.GraphicsPath Path
+ public override System.Drawing.Drawing2D.GraphicsPath Path(SvgRenderer renderer)
{
- get
+ if (this._path == null || this.IsPathDirty)
{
- if (this._path == null || this.IsPathDirty)
- {
- PointF start = new PointF(this.StartX.ToDeviceValue(this), this.StartY.ToDeviceValue(this, true));
- PointF end = new PointF(this.EndX.ToDeviceValue(this), this.EndY.ToDeviceValue(this, true));
+ PointF start = new PointF(this.StartX.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this),
+ this.StartY.ToDeviceValue(renderer, UnitRenderingType.Vertical, this));
+ PointF end = new PointF(this.EndX.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this),
+ this.EndY.ToDeviceValue(renderer, UnitRenderingType.Vertical, this));
- this._path = new GraphicsPath();
- this._path.AddLine(start, end);
- this.IsPathDirty = false;
- }
- return this._path;
- }
- protected set
- {
- _path = value;
+ this._path = new GraphicsPath();
+ this._path.AddLine(start, end);
+ this.IsPathDirty = false;
}
+ return this._path;
}
public override System.Drawing.RectangleF Bounds
{
- get { return this.Path.GetBounds(); }
+ get { return this.Path(null).GetBounds(); }
}
public override SvgElement DeepCopy()
diff --git a/Source/Basic Shapes/SvgPolygon.cs b/Source/Basic Shapes/SvgPolygon.cs
index 9773c6b12937a6da587ab56c18ae2502d1b9b3aa..5c6fc24cf18275b9ffa7943af9aa14c6afd34a60 100644
--- a/Source/Basic Shapes/SvgPolygon.cs
+++ b/Source/Basic Shapes/SvgPolygon.cs
@@ -32,51 +32,44 @@ namespace Svg
get { return true; }
}
- public override GraphicsPath Path
+ public override GraphicsPath Path(SvgRenderer renderer)
{
- get
+ if (this._path == null || this.IsPathDirty)
{
- if (this._path == null || this.IsPathDirty)
- {
- this._path = new GraphicsPath();
- this._path.StartFigure();
+ this._path = new GraphicsPath();
+ this._path.StartFigure();
- try
+ try
+ {
+ for (int i = 2; i < this._points.Count; i+=2)
{
- for (int i = 2; i < this._points.Count; i+=2)
- {
- PointF endPoint = new PointF(this._points[i].ToDeviceValue(this), this._points[i+1].ToDeviceValue(this));
+ var endPoint = SvgUnit.GetDevicePoint(this._points[i], this._points[i+1], renderer, this);
- //first line
- if (_path.PointCount == 0)
- {
- _path.AddLine(new PointF(this._points[i-2].ToDeviceValue(this), this._points[i-1].ToDeviceValue(this)), endPoint);
- }
- else
- {
- _path.AddLine(_path.GetLastPoint(), endPoint);
- }
+ //first line
+ if (_path.PointCount == 0)
+ {
+ _path.AddLine(SvgUnit.GetDevicePoint(this._points[i - 2], this._points[i - 1], renderer, this), endPoint);
+ }
+ else
+ {
+ _path.AddLine(_path.GetLastPoint(), endPoint);
}
}
- catch
- {
- Trace.TraceError("Error parsing points");
- }
-
- this._path.CloseFigure();
- this.IsPathDirty = false;
}
- return this._path;
- }
- protected set
- {
- _path = value;
+ catch
+ {
+ Trace.TraceError("Error parsing points");
+ }
+
+ this._path.CloseFigure();
+ this.IsPathDirty = false;
}
+ return this._path;
}
public override RectangleF Bounds
{
- get { return this.Path.GetBounds(); }
+ get { return this.Path(null).GetBounds(); }
}
diff --git a/Source/Basic Shapes/SvgPolyline.cs b/Source/Basic Shapes/SvgPolyline.cs
index dd9d7051a14acf6629c7e5ee2fc0fccc8ef56fa4..c499dd6c2987f8221ddd8d0579e417d368b3d9c7 100644
--- a/Source/Basic Shapes/SvgPolyline.cs
+++ b/Source/Basic Shapes/SvgPolyline.cs
@@ -14,39 +14,37 @@ namespace Svg
public class SvgPolyline : SvgPolygon
{
private GraphicsPath _Path;
- public override GraphicsPath Path
+ public override GraphicsPath Path(SvgRenderer renderer)
{
- get
+ if (_Path == null || this.IsPathDirty)
{
- if (_Path == null || this.IsPathDirty)
- {
- _Path = new GraphicsPath();
+ _Path = new GraphicsPath();
- try
+ try
+ {
+ for (int i = 0; i < Points.Count; i += 2)
{
- for (int i = 0; i < Points.Count; i += 2)
- {
- PointF endPoint = new PointF(Points[i].ToDeviceValue(this), Points[i + 1].ToDeviceValue(this));
+ PointF endPoint = new PointF(Points[i].ToDeviceValue(renderer, UnitRenderingType.Horizontal, this),
+ Points[i + 1].ToDeviceValue(renderer, UnitRenderingType.Vertical, this));
- // TODO: Remove unrequired first line
- if (_Path.PointCount == 0)
- {
- _Path.AddLine(endPoint, endPoint);
- }
- else
- {
- _Path.AddLine(_Path.GetLastPoint(), endPoint);
- }
+ // TODO: Remove unrequired first line
+ if (_Path.PointCount == 0)
+ {
+ _Path.AddLine(endPoint, endPoint);
+ }
+ else
+ {
+ _Path.AddLine(_Path.GetLastPoint(), endPoint);
}
}
- catch (Exception exc)
- {
- Trace.TraceError("Error rendering points: " + exc.Message);
- }
- this.IsPathDirty = false;
}
- return _Path;
+ catch (Exception exc)
+ {
+ Trace.TraceError("Error rendering points: " + exc.Message);
+ }
+ this.IsPathDirty = false;
}
+ return _Path;
}
}
}
\ No newline at end of file
diff --git a/Source/Basic Shapes/SvgRectangle.cs b/Source/Basic Shapes/SvgRectangle.cs
index a438817bb3b855097121facd99c3c5edc8fd8898..717e6c68897d6e8d2677ec94a98df96a338a44ba 100644
--- a/Source/Basic Shapes/SvgRectangle.cs
+++ b/Source/Basic Shapes/SvgRectangle.cs
@@ -168,101 +168,94 @@ namespace Svg
/// The bounds.
public override RectangleF Bounds
{
- get { return Path.GetBounds(); }
+ get { return Path(null).GetBounds(); }
}
///
/// Gets the for this element.
///
- public override GraphicsPath Path
+ public override GraphicsPath Path(SvgRenderer renderer)
{
- get
+ if (_path == null || IsPathDirty)
{
- if (_path == null || IsPathDirty)
+ // If the corners aren't to be rounded just create a rectangle
+ if (CornerRadiusX.Value == 0.0f && CornerRadiusY.Value == 0.0f)
{
- // If the corners aren't to be rounded just create a rectangle
- if (CornerRadiusX.Value == 0.0f && CornerRadiusY.Value == 0.0f)
- {
- var rectangle = new RectangleF(Location.ToDeviceValue(),
- new SizeF(Width.ToDeviceValue(), Height.ToDeviceValue()));
+ var rectangle = new RectangleF(Location.ToDeviceValue(renderer, this),
+ SvgUnit.GetDeviceSize(this.Width, this.Height, renderer, this));
- _path = new GraphicsPath();
- _path.StartFigure();
- _path.AddRectangle(rectangle);
- _path.CloseFigure();
- }
- else
- {
- _path = new GraphicsPath();
- var arcBounds = new RectangleF();
- var lineStart = new PointF();
- var lineEnd = new PointF();
- var width = Width.ToDeviceValue();
- var height = Height.ToDeviceValue();
- var rx = CornerRadiusX.ToDeviceValue() * 2;
- var ry = CornerRadiusY.ToDeviceValue() * 2;
- var location = Location.ToDeviceValue();
+ _path = new GraphicsPath();
+ _path.StartFigure();
+ _path.AddRectangle(rectangle);
+ _path.CloseFigure();
+ }
+ else
+ {
+ _path = new GraphicsPath();
+ var arcBounds = new RectangleF();
+ var lineStart = new PointF();
+ var lineEnd = new PointF();
+ var width = Width.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this);
+ var height = Height.ToDeviceValue(renderer, UnitRenderingType.Vertical, this);
+ var rx = CornerRadiusX.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this) * 2;
+ var ry = CornerRadiusY.ToDeviceValue(renderer, UnitRenderingType.Vertical, this) * 2;
+ var location = Location.ToDeviceValue(renderer, this);
- // Start
- _path.StartFigure();
+ // Start
+ _path.StartFigure();
- // Add first arc
- arcBounds.Location = location;
- arcBounds.Width = rx;
- arcBounds.Height = ry;
- _path.AddArc(arcBounds, 180, 90);
+ // Add first arc
+ arcBounds.Location = location;
+ arcBounds.Width = rx;
+ arcBounds.Height = ry;
+ _path.AddArc(arcBounds, 180, 90);
- // Add first line
- lineStart.X = Math.Min(location.X + rx, location.X + width * 0.5f);
- lineStart.Y = location.Y;
- lineEnd.X = Math.Max(location.X + width - rx, location.X + width * 0.5f);
- lineEnd.Y = lineStart.Y;
- _path.AddLine(lineStart, lineEnd);
+ // Add first line
+ lineStart.X = Math.Min(location.X + rx, location.X + width * 0.5f);
+ lineStart.Y = location.Y;
+ lineEnd.X = Math.Max(location.X + width - rx, location.X + width * 0.5f);
+ lineEnd.Y = lineStart.Y;
+ _path.AddLine(lineStart, lineEnd);
- // Add second arc
- arcBounds.Location = new PointF(location.X + width - rx, location.Y);
- _path.AddArc(arcBounds, 270, 90);
+ // Add second arc
+ arcBounds.Location = new PointF(location.X + width - rx, location.Y);
+ _path.AddArc(arcBounds, 270, 90);
- // Add second line
- lineStart.X = location.X + width;
- lineStart.Y = Math.Min(location.Y + ry, location.Y + height * 0.5f);
- lineEnd.X = lineStart.X;
- lineEnd.Y = Math.Max(location.Y + height - ry, location.Y + height * 0.5f);
- _path.AddLine(lineStart, lineEnd);
+ // Add second line
+ lineStart.X = location.X + width;
+ lineStart.Y = Math.Min(location.Y + ry, location.Y + height * 0.5f);
+ lineEnd.X = lineStart.X;
+ lineEnd.Y = Math.Max(location.Y + height - ry, location.Y + height * 0.5f);
+ _path.AddLine(lineStart, lineEnd);
- // Add third arc
- arcBounds.Location = new PointF(location.X + width - rx, location.Y + height - ry);
- _path.AddArc(arcBounds, 0, 90);
+ // Add third arc
+ arcBounds.Location = new PointF(location.X + width - rx, location.Y + height - ry);
+ _path.AddArc(arcBounds, 0, 90);
- // Add third line
- lineStart.X = Math.Max(location.X + width - rx, location.X + width * 0.5f);
- lineStart.Y = location.Y + height;
- lineEnd.X = Math.Min(location.X + rx, location.X + width * 0.5f);
- lineEnd.Y = lineStart.Y;
- _path.AddLine(lineStart, lineEnd);
+ // Add third line
+ lineStart.X = Math.Max(location.X + width - rx, location.X + width * 0.5f);
+ lineStart.Y = location.Y + height;
+ lineEnd.X = Math.Min(location.X + rx, location.X + width * 0.5f);
+ lineEnd.Y = lineStart.Y;
+ _path.AddLine(lineStart, lineEnd);
- // Add third arc
- arcBounds.Location = new PointF(location.X, location.Y + height - ry);
- _path.AddArc(arcBounds, 90, 90);
+ // Add third arc
+ arcBounds.Location = new PointF(location.X, location.Y + height - ry);
+ _path.AddArc(arcBounds, 90, 90);
- // Add fourth line
- lineStart.X = location.X;
- lineStart.Y = Math.Max(location.Y + height - ry, location.Y + height * 0.5f);
- lineEnd.X = lineStart.X;
- lineEnd.Y = Math.Min(location.Y + ry, location.Y + height * 0.5f);
- _path.AddLine(lineStart, lineEnd);
+ // Add fourth line
+ lineStart.X = location.X;
+ lineStart.Y = Math.Max(location.Y + height - ry, location.Y + height * 0.5f);
+ lineEnd.X = lineStart.X;
+ lineEnd.Y = Math.Min(location.Y + ry, location.Y + height * 0.5f);
+ _path.AddLine(lineStart, lineEnd);
- // Close
- _path.CloseFigure();
- }
- IsPathDirty = false;
+ // Close
+ _path.CloseFigure();
}
- return _path;
- }
- protected set
- {
- _path = value;
+ IsPathDirty = false;
}
+ return _path;
}
///
diff --git a/Source/Basic Shapes/SvgVisualElement.cs b/Source/Basic Shapes/SvgVisualElement.cs
index 0bebf2c74c8ac2e35b686bd0b59cc86a22f60bf8..96d19d4881a39c26a0ea83258c5b02547bbd3c75 100644
--- a/Source/Basic Shapes/SvgVisualElement.cs
+++ b/Source/Basic Shapes/SvgVisualElement.cs
@@ -16,7 +16,7 @@ namespace Svg
///
/// Gets the for this element.
///
- public abstract GraphicsPath Path { get; protected set; }
+ public abstract GraphicsPath Path(SvgRenderer renderer);
PointF ISvgBoundable.Location
{
@@ -105,7 +105,7 @@ namespace Svg
/// The object to render to.
protected override void Render(SvgRenderer renderer)
{
- if ((this.Path != null) && this.Visible && this.Displayable)
+ if ((this.Path(renderer) != null) && this.Visible && this.Displayable)
{
this.PushTransforms(renderer);
this.SetClip(renderer);
@@ -138,12 +138,12 @@ namespace Svg
{
if (this.Fill != null)
{
- using (Brush brush = this.Fill.GetBrush(this, this.FillOpacity))
+ using (Brush brush = this.Fill.GetBrush(this, renderer, Math.Min(Math.Max(this.FillOpacity * this.Opacity, 0), 1)))
{
if (brush != null)
{
- this.Path.FillMode = this.FillRule == SvgFillRule.NonZero ? FillMode.Winding : FillMode.Alternate;
- renderer.FillPath(brush, this.Path);
+ this.Path(renderer).FillMode = this.FillRule == SvgFillRule.NonZero ? FillMode.Winding : FillMode.Alternate;
+ renderer.FillPath(brush, this.Path(renderer));
}
}
}
@@ -157,8 +157,8 @@ namespace Svg
{
if (this.Stroke != null)
{
- float strokeWidth = this.StrokeWidth.ToDeviceValue(this);
- using (var pen = new Pen(this.Stroke.GetBrush(this, this.StrokeOpacity), strokeWidth))
+ float strokeWidth = this.StrokeWidth.ToDeviceValue(renderer, UnitRenderingType.Other, this);
+ using (var pen = new Pen(this.Stroke.GetBrush(this, renderer, Math.Min(Math.Max(this.StrokeOpacity * this.Opacity, 0), 1)), strokeWidth))
{
if (this.StrokeDashArray != null && this.StrokeDashArray.Count > 0)
{
@@ -166,7 +166,7 @@ namespace Svg
pen.DashPattern = this.StrokeDashArray.ConvertAll(u => ((u.Value <= 0) ? 1 : u.Value) / ((strokeWidth <= 0) ? 1 : strokeWidth)).ToArray();
}
- renderer.DrawPath(pen, this.Path);
+ renderer.DrawPath(pen, this.Path(renderer));
}
}
}
@@ -184,7 +184,7 @@ namespace Svg
if (clipPath != null)
{
- renderer.Clip = clipPath.GetClipRegion(this);
+ renderer.AddClip(clipPath.GetClipRegion(this));
}
}
}
diff --git a/Source/Basic Shapes/SvgVisualElementStyle.cs b/Source/Basic Shapes/SvgVisualElementStyle.cs
index b151aa0d86a451014dd50551a842905568338cf1..a09fa748f71a27d2fdd06a7e0ae94931ef32c5db 100644
--- a/Source/Basic Shapes/SvgVisualElementStyle.cs
+++ b/Source/Basic Shapes/SvgVisualElementStyle.cs
@@ -162,11 +162,7 @@ namespace Svg
public virtual string FontFamily
{
get { return this.Attributes["font-family"] as string; }
- set
- {
- this.Attributes["font-family"] = value;
- this.IsPathDirty = true;
- }
+ set { this.Attributes["font-family"] = value; this.IsPathDirty = true; }
}
///
@@ -179,15 +175,6 @@ namespace Svg
set { this.Attributes["font-size"] = value; this.IsPathDirty = true; }
}
- public SvgUnit GetInheritedFontSize()
- {
- var fontSizeElement = (from e in this.ParentsAndSelf.OfType()
- where e.FontSize != SvgUnit.Empty && e.FontSize != SvgUnit.None
- select e).FirstOrDefault();
- return (fontSizeElement == null ? SvgUnit.None : fontSizeElement.FontSize);
- }
-
-
///
/// Refers to the boldness of the font.
///
@@ -308,5 +295,71 @@ namespace Svg
this.IsPathDirty = true;
}
}
+
+ private const string DefaultFontFamily = "Times New Roman";
+
+ ///
+ /// Get the font information based on data stored with the text object or inherited from the parent.
+ ///
+ ///
+ internal System.Drawing.Font GetFont(SvgRenderer renderer)
+ {
+ // Get the font-size
+ float fontSize;
+ var fontSizeUnit = this.FontSize;
+ if (fontSizeUnit == SvgUnit.None)
+ {
+ fontSize = 1.0f;
+ }
+ else
+ {
+ fontSize = fontSizeUnit.ToDeviceValue(renderer, UnitRenderingType.Vertical, this);
+ }
+
+ var fontStyle = System.Drawing.FontStyle.Regular;
+
+ // Get the font-weight
+ switch (this.FontWeight)
+ {
+ case SvgFontWeight.bold:
+ case SvgFontWeight.bolder:
+ case SvgFontWeight.w700:
+ case SvgFontWeight.w800:
+ case SvgFontWeight.w900:
+ fontStyle |= System.Drawing.FontStyle.Bold;
+ break;
+ }
+
+ // Get the font-style
+ switch (this.FontStyle)
+ {
+ case SvgFontStyle.italic:
+ case SvgFontStyle.oblique:
+ fontStyle |= System.Drawing.FontStyle.Italic;
+ break;
+ }
+
+ // Get the font-family
+ string family = ValidateFontFamily(this.FontFamily) ?? DefaultFontFamily;
+ return new System.Drawing.Font(family, fontSize, fontStyle, System.Drawing.GraphicsUnit.Pixel);
+ }
+
+ private static string ValidateFontFamily(string fontFamilyList)
+ {
+ // Split font family list on "," and then trim start and end spaces and quotes.
+ var fontParts = (fontFamilyList ?? "").Split(new[] { ',' }).Select(fontName => fontName.Trim(new[] { '"', ' ', '\'' }));
+
+ var families = System.Drawing.FontFamily.Families;
+
+ // Find a the first font that exists in the list of installed font families.
+ //styles from IE get sent through as lowercase.
+ foreach (var f in fontParts.Where(f => families.Any(family => family.Name.ToLower() == f.ToLower())))
+ {
+ return f;
+ }
+ // No valid font family found from the list requested.
+ return null;
+ }
+
}
}
\ No newline at end of file
diff --git a/Source/Clipping and Masking/SvgClipPath.cs b/Source/Clipping and Masking/SvgClipPath.cs
index 331f07a1e12b94b66c1e2367f1fa80a710783bfd..72bc101dc0104a2025a2fb311d737082da09b2ba 100644
--- a/Source/Clipping and Masking/SvgClipPath.cs
+++ b/Source/Clipping and Masking/SvgClipPath.cs
@@ -61,11 +61,11 @@ namespace Svg
{
var graphicsElement = element as SvgVisualElement;
- if (graphicsElement != null && graphicsElement.Path != null)
+ if (graphicsElement != null && graphicsElement.Path(null) != null)
{
path.FillMode = (graphicsElement.ClipRule == SvgClipRule.NonZero) ? FillMode.Winding : FillMode.Alternate;
- GraphicsPath childPath = graphicsElement.Path;
+ GraphicsPath childPath = graphicsElement.Path(null);
if (graphicsElement.Transforms != null)
{
diff --git a/Source/Css/CssQuery.cs b/Source/Css/CssQuery.cs
new file mode 100644
index 0000000000000000000000000000000000000000..fcb2bc00525237ea837db25f8cd245b16e9c8683
--- /dev/null
+++ b/Source/Css/CssQuery.cs
@@ -0,0 +1,78 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Fizzler;
+using ExCSS;
+
+namespace Svg.Css
+{
+ internal static class CssQuery
+ {
+ public static IEnumerable QuerySelectorAll(this SvgElement elem, string selector)
+ {
+ var generator = new SelectorGenerator(new SvgElementOps());
+ Fizzler.Parser.Parse(selector, generator);
+ return generator.Selector(Enumerable.Repeat(elem, 1));
+ }
+
+ public static int GetSpecificity(this BaseSelector selector)
+ {
+ if (selector is SimpleSelector)
+ {
+ var simpleCode = selector.ToString().ToLowerInvariant();
+ if (simpleCode.StartsWith(":not("))
+ {
+ simpleCode = simpleCode.Substring(5, simpleCode.Length - 6);
+ return GetSpecificity(new SimpleSelector(simpleCode));
+ }
+ else if (simpleCode.StartsWith("#"))
+ {
+ // ID selector
+ return 1 << 12;
+ }
+ else if (simpleCode.StartsWith("::") || simpleCode == ":after" || simpleCode == ":before" ||
+ simpleCode == ":first-letter" || simpleCode == ":first-line" || simpleCode == ":selection")
+ {
+ // pseudo-element
+ return 1 << 4;
+ }
+ else if (simpleCode.StartsWith(".") || simpleCode.StartsWith(":") || simpleCode.StartsWith("["))
+ {
+ // class, pseudo-class, attribute
+ return 1 << 8;
+ }
+ else if (selector == SimpleSelector.All)
+ {
+ // all selector
+ return 0;
+ }
+ else
+ {
+ // element selector
+ return 1 << 4;
+ }
+ }
+ else
+ {
+ var list = selector as IEnumerable;
+ if (list != null)
+ {
+ return (from s in list select GetSpecificity(s)).Aggregate((p, c) => p + c);
+ }
+ else
+ {
+ var complex = selector as IEnumerable;
+ if (complex != null)
+ {
+ return (from s in complex select GetSpecificity(s.Selector)).Aggregate((p, c) => p + c);
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/Source/Css/SvgElementOps.cs b/Source/Css/SvgElementOps.cs
new file mode 100644
index 0000000000000000000000000000000000000000..8928d4be5610104f2fa19385199748ea82959817
--- /dev/null
+++ b/Source/Css/SvgElementOps.cs
@@ -0,0 +1,186 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Fizzler;
+
+namespace Svg.Css
+{
+ internal class SvgElementOps : IElementOps
+ {
+ public Selector Type(NamespacePrefix prefix, string name)
+ {
+ var type = SvgElementFactory.AvailableElements.SingleOrDefault(e => e.ElementName == name);
+ return nodes => nodes.Where(n => n.GetType() == type.ElementType);
+ }
+
+ public Selector Universal(NamespacePrefix prefix)
+ {
+ return nodes => nodes;
+ }
+
+ public Selector Id(string id)
+ {
+ return nodes => nodes.Where(n => n.ID == id);
+ }
+
+ public Selector Class(string clazz)
+ {
+ return AttributeIncludes(NamespacePrefix.None, "class", clazz);
+ }
+
+ public Selector AttributeExists(NamespacePrefix prefix, string name)
+ {
+ return nodes => nodes.Where(n => n.Attributes.ContainsKey(name) || n.CustomAttributes.ContainsKey(name));
+ }
+
+ public Selector AttributeExact(NamespacePrefix prefix, string name, string value)
+ {
+ return nodes => nodes.Where(n =>
+ {
+ string val = null;
+ object oval = null;
+ return (n.CustomAttributes.TryGetValue(name, out val) && val == value) ||
+ (n.Attributes.TryGetValue(name, out oval) && oval.ToString() == value);
+ });
+ }
+
+ public Selector AttributeIncludes(NamespacePrefix prefix, string name, string value)
+ {
+ return nodes => nodes.Where(n =>
+ {
+ string val = null;
+ object oval = null;
+ return (n.CustomAttributes.TryGetValue(name, out val) && val.Split(' ').Contains(value)) ||
+ (n.Attributes.TryGetValue(name, out oval) && oval.ToString().Split(' ').Contains(value));
+ });
+ }
+
+ public Selector AttributeDashMatch(NamespacePrefix prefix, string name, string value)
+ {
+ return string.IsNullOrEmpty(value)
+ ? (Selector)(nodes => Enumerable.Empty())
+ : (nodes => nodes.Where(n =>
+ {
+ string val = null;
+ object oval = null;
+ return (n.CustomAttributes.TryGetValue(name, out val) && val.Split('-').Contains(value)) ||
+ (n.Attributes.TryGetValue(name, out oval) && oval.ToString().Split('-').Contains(value));
+ }));
+ }
+
+ public Selector AttributePrefixMatch(NamespacePrefix prefix, string name, string value)
+ {
+ return string.IsNullOrEmpty(value)
+ ? (Selector)(nodes => Enumerable.Empty())
+ : (nodes => nodes.Where(n =>
+ {
+ string val = null;
+ object oval = null;
+ return (n.CustomAttributes.TryGetValue(name, out val) && val.StartsWith(value)) ||
+ (n.Attributes.TryGetValue(name, out oval) && oval.ToString().StartsWith(value));
+ }));
+ }
+
+ public Selector AttributeSuffixMatch(NamespacePrefix prefix, string name, string value)
+ {
+ return string.IsNullOrEmpty(value)
+ ? (Selector)(nodes => Enumerable.Empty())
+ : (nodes => nodes.Where(n =>
+ {
+ string val = null;
+ object oval = null;
+ return (n.CustomAttributes.TryGetValue(name, out val) && val.EndsWith(value)) ||
+ (n.Attributes.TryGetValue(name, out oval) && oval.ToString().EndsWith(value));
+ }));
+ }
+
+ public Selector AttributeSubstring(NamespacePrefix prefix, string name, string value)
+ {
+ return string.IsNullOrEmpty(value)
+ ? (Selector)(nodes => Enumerable.Empty())
+ : (nodes => nodes.Where(n =>
+ {
+ string val = null;
+ object oval = null;
+ return (n.CustomAttributes.TryGetValue(name, out val) && val.Contains(value)) ||
+ (n.Attributes.TryGetValue(name, out oval) && oval.ToString().Contains(value));
+ }));
+ }
+
+ public Selector FirstChild()
+ {
+ return nodes => nodes.Where(n => n.Parent == null || n.Parent.Children.First() == n);
+ }
+
+ public Selector LastChild()
+ {
+ return nodes => nodes.Where(n => n.Parent == null || n.Parent.Children.Last() == n);
+ }
+
+ private IEnumerable GetByIds(IList items, IEnumerable indices)
+ {
+ foreach (var i in indices)
+ {
+ if (i >= 0 && i < items.Count) yield return items[i];
+ }
+ }
+
+ public Selector NthChild(int a, int b)
+ {
+ return nodes => nodes.Where(n => n.Parent != null && GetByIds(n.Parent.Children, (from i in Enumerable.Range(0, n.Parent.Children.Count / a) select a * i + b)).Contains(n));
+ }
+
+ public Selector OnlyChild()
+ {
+ return nodes => nodes.Where(n => n.Parent == null || n.Parent.Children.Count == 1);
+ }
+
+ public Selector Empty()
+ {
+ return nodes => nodes.Where(n => n.Children.Count == 0);
+ }
+
+ public Selector Child()
+ {
+ return nodes => nodes.SelectMany(n => n.Children);
+ }
+
+ public Selector Descendant()
+ {
+ return nodes => nodes.SelectMany(n => Descendants(n));
+ }
+
+ private IEnumerable Descendants(SvgElement elem)
+ {
+ foreach (var child in elem.Children)
+ {
+ yield return child;
+ foreach (var descendant in child.Descendants())
+ {
+ yield return descendant;
+ }
+ }
+ }
+
+ public Selector Adjacent()
+ {
+ return nodes => nodes.SelectMany(n => ElementsAfterSelf(n).Take(1));
+ }
+
+ public Selector GeneralSibling()
+ {
+ return nodes => nodes.SelectMany(n => ElementsAfterSelf(n));
+ }
+
+ private IEnumerable ElementsAfterSelf(SvgElement self)
+ {
+ return (self.Parent == null ? Enumerable.Empty() : self.Parent.Children.Skip(self.Parent.Children.IndexOf(self) + 1));
+ }
+
+ public Selector NthLastChild(int a, int b)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/Source/DataTypes/ISvgSupportsCoordinateUnits.cs b/Source/DataTypes/ISvgSupportsCoordinateUnits.cs
new file mode 100644
index 0000000000000000000000000000000000000000..21a3cad19f9ab7f7e05fb980e3dc800f65e9a7e0
--- /dev/null
+++ b/Source/DataTypes/ISvgSupportsCoordinateUnits.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Svg
+{
+ internal interface ISvgSupportsCoordinateUnits
+ {
+ SvgCoordinateUnits GetUnits();
+ }
+}
diff --git a/Source/DataTypes/SvgCoordinateUnits.cs b/Source/DataTypes/SvgCoordinateUnits.cs
index 6db0ffa2643c43fc25239bc05045d2b51ad3423f..9fdafdbc05b85e0d80a29179f923a4a3ee623317 100644
--- a/Source/DataTypes/SvgCoordinateUnits.cs
+++ b/Source/DataTypes/SvgCoordinateUnits.cs
@@ -11,12 +11,12 @@ namespace Svg
public enum SvgCoordinateUnits
{
///
- /// Indicates that the coordinate system of the entire document is to be used.
+ /// Indicates that the coordinate system of the owner element is to be used.
///
- UserSpaceOnUse,
+ ObjectBoundingBox,
///
- /// Indicates that the coordinate system of the owner element is to be used.
+ /// Indicates that the coordinate system of the entire document is to be used.
///
- ObjectBoundingBox
+ UserSpaceOnUse
}
}
diff --git a/Source/DataTypes/SvgPoint.cs b/Source/DataTypes/SvgPoint.cs
index 5673ef7635e5191a541bafda653aa50e33406916..e15358d16aa19592f762d1f9e356a2d774bbe52b 100644
--- a/Source/DataTypes/SvgPoint.cs
+++ b/Source/DataTypes/SvgPoint.cs
@@ -23,9 +23,9 @@ namespace Svg
set { this.y = value; }
}
- public PointF ToDeviceValue()
+ public PointF ToDeviceValue(SvgRenderer renderer, SvgElement owner)
{
- return new PointF(this.X.ToDeviceValue(), this.Y.ToDeviceValue());
+ return SvgUnit.GetDevicePoint(this.X, this.Y, renderer, owner);
}
public bool IsEmpty()
diff --git a/Source/DataTypes/SvgUnit.cs b/Source/DataTypes/SvgUnit.cs
index 24266272b3a1956bfec0e2699ad8b633a9579420..30a7c5965ebe7967422332a766c8aed9d0b9cc4d 100644
--- a/Source/DataTypes/SvgUnit.cs
+++ b/Source/DataTypes/SvgUnit.cs
@@ -1,6 +1,8 @@
using System;
using System.ComponentModel;
using System.Globalization;
+using System.Linq;
+using System.Drawing;
namespace Svg
{
@@ -60,26 +62,9 @@ namespace Svg
///
/// Converts the current unit to one that can be used at render time.
///
+ /// The container element used as the basis for calculations
/// The representation of the current unit in a device value (usually pixels).
- public float ToDeviceValue()
- {
- return this.ToDeviceValue(null);
- }
-
- ///
- /// Converts the current unit to one that can be used at render time.
- ///
- /// The representation of the current unit in a device value (usually pixels).
- public float ToDeviceValue(ISvgBoundable boundable)
- {
- return this.ToDeviceValue(boundable, false);
- }
-
- ///
- /// Converts the current unit to one that can be used at render time.
- ///
- /// The representation of the current unit in a device value (usually pixels).
- public float ToDeviceValue(ISvgBoundable boundable, bool vertical)
+ public float ToDeviceValue(SvgRenderer renderer, UnitRenderingType renderType, SvgElement owner)
{
// If it's already been calculated
if (this._deviceValue.HasValue)
@@ -99,60 +84,135 @@ namespace Svg
const float cmInInch = 2.54f;
int ppi = SvgDocument.PointsPerInch;
- switch (this.Type)
+ var type = this.Type;
+ var value = this.Value;
+
+ // Deal with fractional pattern units
+ var coordElem = owner as ISvgSupportsCoordinateUnits;
+ if (coordElem != null && coordElem.GetUnits() == SvgCoordinateUnits.ObjectBoundingBox && type != SvgUnitType.Percentage)
+ {
+ type = SvgUnitType.Percentage;
+ value *= 100;
+ }
+
+ var element = owner as SvgElement;
+ if (element != null)
+ {
+ var pattern = element.Parents.OfType().FirstOrDefault();
+ if (pattern != null && pattern.PatternContentUnits == SvgCoordinateUnits.ObjectBoundingBox && type != SvgUnitType.Percentage)
+ {
+ type = SvgUnitType.Percentage;
+ value *= 100;
+ }
+ }
+
+ float points;
+ Font currFont;
+
+ switch (type)
{
case SvgUnitType.Em:
- var visualElem = boundable as SvgVisualElement;
- if (visualElem == null)
+ currFont = GetFont(renderer, owner);
+ if (currFont == null)
{
- float points = (float)(this.Value * 9);
+ points = (float)(value * 9);
_deviceValue = (points / 72) * ppi;
}
else
{
- _deviceValue = this.Value * visualElem.GetInheritedFontSize().ToDeviceValue(boundable);
+ _deviceValue = value * (currFont.SizeInPoints / 72) * ppi;
+ }
+ break;
+ case SvgUnitType.Ex:
+ currFont = GetFont(renderer, owner);
+ if (currFont == null)
+ {
+ points = (float)(value * 9);
+ _deviceValue = (points / 72) * ppi / 2;
+ }
+ else
+ {
+ _deviceValue = value * (currFont.SizeInPoints / 72) * ppi * RelativeXHeight(currFont);
}
break;
case SvgUnitType.Centimeter:
- _deviceValue = (float)((this.Value / cmInInch) * ppi);
+ _deviceValue = (float)((value / cmInInch) * ppi);
break;
case SvgUnitType.Inch:
- _deviceValue = this.Value * ppi;
+ _deviceValue = value * ppi;
break;
case SvgUnitType.Millimeter:
- _deviceValue = (float)((this.Value / 10) / cmInInch) * ppi;
+ _deviceValue = (float)((value / 10) / cmInInch) * ppi;
break;
case SvgUnitType.Pica:
- _deviceValue = ((this.Value * 12) / 72) * ppi;
+ _deviceValue = ((value * 12) / 72) * ppi;
break;
case SvgUnitType.Point:
- _deviceValue = (this.Value / 72) * ppi;
+ _deviceValue = (value / 72) * ppi;
break;
case SvgUnitType.Pixel:
- _deviceValue = this.Value;
+ _deviceValue = value;
break;
case SvgUnitType.User:
- _deviceValue = this.Value;
+ _deviceValue = value;
break;
case SvgUnitType.Percentage:
// Can't calculate if there is no style owner
+ var boundable = (renderer == null ? (owner == null ? null : owner.OwnerDocument) : renderer.Boundable());
if (boundable == null)
{
- _deviceValue = this.Value;
+ _deviceValue = value;
break;
}
- // TODO : Support height percentages
System.Drawing.SizeF size = boundable.Bounds.Size;
- _deviceValue = (((vertical) ? size.Height : size.Width) / 100) * this.Value;
+
+ switch (renderType)
+ {
+ case UnitRenderingType.Horizontal:
+ _deviceValue = (size.Width / 100) * value;
+ break;
+ case UnitRenderingType.HorizontalOffset:
+ _deviceValue = (size.Width / 100) * value + boundable.Location.X;
+ break;
+ case UnitRenderingType.Vertical:
+ _deviceValue = (size.Height / 100) * value;
+ break;
+ case UnitRenderingType.VerticalOffset:
+ _deviceValue = (size.Height / 100) * value + boundable.Location.Y;
+ break;
+ default:
+ _deviceValue = (float)(Math.Sqrt(Math.Pow(size.Width, 2) + Math.Pow(size.Height, 2)) / Math.Sqrt(2) * value / 100.0);
+ break;
+ }
break;
default:
- _deviceValue = this.Value;
+ _deviceValue = value;
break;
}
return this._deviceValue.Value;
}
+ private Font GetFont(SvgRenderer renderer, SvgElement owner)
+ {
+ if (owner == null) return null;
+
+ var visual = owner.ParentsAndSelf.OfType().FirstOrDefault();
+ return visual.GetFont(renderer);
+ }
+ private float RelativeXHeight(Font font)
+ {
+ var mediaFont = new System.Windows.Media.FontFamily(font.Name);
+ var sum = 0.0;
+ var cnt = 0;
+ foreach (var tf in mediaFont.FamilyTypefaces)
+ {
+ sum += tf.XHeight;
+ cnt += 1;
+ }
+ return (float)(sum / cnt);
+ }
+
///
/// Converts the current unit to a percentage, if applicable.
///
@@ -249,7 +309,7 @@ namespace Svg
/// The result of the conversion.
public static implicit operator float(SvgUnit value)
{
- return value.ToDeviceValue();
+ return value.ToDeviceValue(null, UnitRenderingType.Other, null);
}
///
@@ -286,6 +346,32 @@ namespace Svg
this._isEmpty = (this._value == 0.0f);
this._deviceValue = null;
}
+
+ public static System.Drawing.PointF GetDevicePoint(SvgUnit x, SvgUnit y, SvgRenderer renderer, SvgElement owner)
+ {
+ return new System.Drawing.PointF(x.ToDeviceValue(renderer, UnitRenderingType.Horizontal, owner),
+ y.ToDeviceValue(renderer, UnitRenderingType.Vertical, owner));
+ }
+ public static System.Drawing.PointF GetDevicePointOffset(SvgUnit x, SvgUnit y, SvgRenderer renderer, SvgElement owner)
+ {
+ return new System.Drawing.PointF(x.ToDeviceValue(renderer, UnitRenderingType.HorizontalOffset, owner),
+ y.ToDeviceValue(renderer, UnitRenderingType.VerticalOffset, owner));
+ }
+
+ public static System.Drawing.SizeF GetDeviceSize(SvgUnit width, SvgUnit height, SvgRenderer renderer, SvgElement owner)
+ {
+ return new System.Drawing.SizeF(width.ToDeviceValue(renderer, UnitRenderingType.HorizontalOffset, owner),
+ height.ToDeviceValue(renderer, UnitRenderingType.VerticalOffset, owner));
+ }
+ }
+
+ public enum UnitRenderingType
+ {
+ Other,
+ Horizontal,
+ HorizontalOffset,
+ Vertical,
+ VerticalOffset
}
///
@@ -306,6 +392,10 @@ namespace Svg
///
Em,
///
+ /// Indicates that the unit is equal to the x-height of the current font.
+ ///
+ Ex,
+ ///
/// Indicates that the unit is a percentage.
///
Percentage,
diff --git a/Source/DataTypes/SvgUnitConverter.cs b/Source/DataTypes/SvgUnitConverter.cs
index d1a80a0cb5b4355a8814017b2e07a6379522a978..4787fab54a65516e906d186c64239ce13f4a9899 100644
--- a/Source/DataTypes/SvgUnitConverter.cs
+++ b/Source/DataTypes/SvgUnitConverter.cs
@@ -68,6 +68,8 @@ namespace Svg
return new SvgUnit(SvgUnitType.Percentage, val);
case "em":
return new SvgUnit(SvgUnitType.Em, val);
+ case "ex":
+ return new SvgUnit(SvgUnitType.Ex, val);
default:
throw new FormatException("Unit is in an invalid format '" + unit + "'.");
}
diff --git a/Source/Document Structure/SvgFragment.cs b/Source/Document Structure/SvgFragment.cs
index 4799646679af4ba55713a4358f0270feea47d4a4..f23081f1a22960693540967e742d4ff4c8702ea7 100644
--- a/Source/Document Structure/SvgFragment.cs
+++ b/Source/Document Structure/SvgFragment.cs
@@ -127,20 +127,43 @@ namespace Svg
set { this.Attributes["preserveAspectRatio"] = value; }
}
+ ///
+ /// Refers to the size of the font from baseline to baseline when multiple lines of text are set solid in a multiline layout environment.
+ ///
+ [SvgAttribute("font-size")]
+ public virtual SvgUnit FontSize
+ {
+ get { return (this.Attributes["font-size"] == null) ? SvgUnit.Empty : (SvgUnit)this.Attributes["font-size"]; }
+ set { this.Attributes["font-size"] = value; }
+ }
+
+ ///
+ /// Indicates which font family is to be used to render the text.
+ ///
+ [SvgAttribute("font-family")]
+ public virtual string FontFamily
+ {
+ get { return this.Attributes["font-family"] as string; }
+ set { this.Attributes["font-family"] = value; }
+ }
+
///
/// Applies the required transforms to .
///
/// The to be transformed.
- protected internal override void PushTransforms(SvgRenderer renderer)
+ protected internal override bool PushTransforms(SvgRenderer renderer)
{
- base.PushTransforms(renderer);
+ if (!base.PushTransforms(renderer)) return false;
if (!this.ViewBox.Equals(SvgViewBox.Empty))
{
- float fScaleX = this.Width.ToDeviceValue(this, false) / this.ViewBox.Width;
- float fScaleY = this.Height.ToDeviceValue(this, true) / this.ViewBox.Height;
- float fMinX = -this.ViewBox.MinX;
- float fMinY = -this.ViewBox.MinY;
+ var width = this.Width.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this);
+ var height = this.Height.ToDeviceValue(renderer, UnitRenderingType.Vertical, this);
+
+ var fScaleX = width / this.ViewBox.Width;
+ var fScaleY = height / this.ViewBox.Height;
+ var fMinX = -this.ViewBox.MinX;
+ var fMinY = -this.ViewBox.MinY;
if (AspectRatio.Align != SvgPreserveAspectRatio.none)
{
@@ -156,50 +179,56 @@ namespace Svg
}
float fViewMidX = (this.ViewBox.Width / 2) * fScaleX;
float fViewMidY = (this.ViewBox.Height / 2) * fScaleY;
- float fMidX = this.Width.ToDeviceValue(this, false) / 2;
- float fMidY = this.Height.ToDeviceValue(this, true) / 2;
+ float fMidX = width / 2;
+ float fMidY = height / 2;
switch (AspectRatio.Align)
{
case SvgPreserveAspectRatio.xMinYMin:
break;
case SvgPreserveAspectRatio.xMidYMin:
- fMinX += (fMidX - fViewMidX) / fScaleX;
+ fMinX += fMidX - fViewMidX;
break;
case SvgPreserveAspectRatio.xMaxYMin:
- fMinX += (this.Width.ToDeviceValue(this, false) / fScaleX) - this.ViewBox.Width;
+ fMinX += width - this.ViewBox.Width * fScaleX;
break;
case SvgPreserveAspectRatio.xMinYMid:
- fMinY += (fMidY - fViewMidY) / fScaleY;
+ fMinY += fMidY - fViewMidY;
break;
case SvgPreserveAspectRatio.xMidYMid:
- fMinX += (fMidX - fViewMidX) / fScaleX;
- fMinY += (fMidY - fViewMidY) / fScaleY;
+ fMinX += fMidX - fViewMidX;
+ fMinY += fMidY - fViewMidY;
break;
case SvgPreserveAspectRatio.xMaxYMid:
- fMinX += (this.Width.ToDeviceValue(this, false) / fScaleX) - this.ViewBox.Width;
- fMinY += (fMidY - fViewMidY) / fScaleY;
+ fMinX += width - this.ViewBox.Width * fScaleX;
+ fMinY += fMidY - fViewMidY;
break;
case SvgPreserveAspectRatio.xMinYMax:
- fMinY += (this.Height.ToDeviceValue(this, true) / fScaleY) - this.ViewBox.Height;
+ fMinY += height - this.ViewBox.Height * fScaleY;
break;
case SvgPreserveAspectRatio.xMidYMax:
- fMinX += (fMidX - fViewMidX) / fScaleX;
- fMinY += (this.Height.ToDeviceValue(this, true) / fScaleY) - this.ViewBox.Height;
+ fMinX += fMidX - fViewMidX;
+ fMinY += height - this.ViewBox.Height * fScaleY;
break;
case SvgPreserveAspectRatio.xMaxYMax:
- fMinX += (this.Width.ToDeviceValue(this, false) / fScaleX) - this.ViewBox.Width;
- fMinY += (this.Height.ToDeviceValue(this, true) / fScaleY) - this.ViewBox.Height;
+ fMinX += width - this.ViewBox.Width * fScaleX;
+ fMinY += height - this.ViewBox.Height * fScaleY;
break;
default:
break;
}
}
- renderer.TranslateTransform(_x, _y);
+ var x = _x.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this);
+ var y = _y.ToDeviceValue(renderer, UnitRenderingType.Vertical, this);
+
+ renderer.AddClip(new Region(new RectangleF(x, y, width, height)));
+ renderer.ScaleTransform(fScaleX, fScaleY, MatrixOrder.Prepend);
+ renderer.TranslateTransform(x,y);
renderer.TranslateTransform(fMinX, fMinY);
- renderer.ScaleTransform(fScaleX, fScaleY);
}
+
+ return true;
}
///
@@ -245,18 +274,38 @@ namespace Svg
public SizeF GetDimensions()
{
- var w = Width.ToDeviceValue();
- var h = Height.ToDeviceValue();
-
- RectangleF bounds = new RectangleF();
+ float w, h;
var isWidthperc = Width.Type == SvgUnitType.Percentage;
var isHeightperc = Height.Type == SvgUnitType.Percentage;
+ RectangleF bounds = new RectangleF();
if (isWidthperc || isHeightperc)
{
- bounds = this.Bounds; //do just one call to the recursive bounds property
- if (isWidthperc) w = (bounds.Width + bounds.X) * (w * 0.01f);
- if (isHeightperc) h = (bounds.Height + bounds.Y) * (h * 0.01f);
+ if (ViewBox.Width > 0 && ViewBox.Height > 0)
+ {
+ bounds = new RectangleF(ViewBox.MinX, ViewBox.MinY, ViewBox.Width, ViewBox.Height);
+ }
+ else
+ {
+ bounds = this.Bounds; //do just one call to the recursive bounds property
+ }
+ }
+
+ if (isWidthperc)
+ {
+ w = (bounds.Width + bounds.X) * (Width.Value * 0.01f);
+ }
+ else
+ {
+ w = Width.ToDeviceValue(null, UnitRenderingType.Horizontal, this);
+ }
+ if (isHeightperc)
+ {
+ h = (bounds.Height + bounds.Y) * (Height.Value * 0.01f);
+ }
+ else
+ {
+ h = Height.ToDeviceValue(null, UnitRenderingType.Vertical, this);
}
return new SizeF(w, h);
diff --git a/Source/Document Structure/SvgGroup.cs b/Source/Document Structure/SvgGroup.cs
index ce52270ab6b31e35ceace3b0984bb92de70435d2..3dfc691f6f772c5a5e42f32deef0ce6316596390 100644
--- a/Source/Document Structure/SvgGroup.cs
+++ b/Source/Document Structure/SvgGroup.cs
@@ -17,17 +17,9 @@ namespace Svg
/// Gets the for this element.
///
///
- public override System.Drawing.Drawing2D.GraphicsPath Path
+ public override System.Drawing.Drawing2D.GraphicsPath Path(SvgRenderer renderer)
{
- get
- {
- //var path = new GraphicsPath();
- //AddPaths(this, path);
-
- return GetPaths(this);
- }
- protected set
- { }
+ return GetPaths(this, renderer);
}
///
@@ -73,11 +65,13 @@ namespace Svg
if (!Visible || !Displayable)
return;
- this.PushTransforms(renderer);
- this.SetClip(renderer);
- base.RenderChildren(renderer);
- this.ResetClip(renderer);
- this.PopTransforms(renderer);
+ if (this.PushTransforms(renderer))
+ {
+ this.SetClip(renderer);
+ base.RenderChildren(renderer);
+ this.ResetClip(renderer);
+ this.PopTransforms(renderer);
+ }
}
diff --git a/Source/Document Structure/SvgSwitch.cs b/Source/Document Structure/SvgSwitch.cs
index e9af587a868c788cb042c4a0bfc18ba04505167f..d3700306e19ce0de75605d3a590256f47cc50582 100644
--- a/Source/Document Structure/SvgSwitch.cs
+++ b/Source/Document Structure/SvgSwitch.cs
@@ -17,17 +17,9 @@ namespace Svg
/// Gets the for this element.
///
///
- public override System.Drawing.Drawing2D.GraphicsPath Path
+ public override System.Drawing.Drawing2D.GraphicsPath Path(SvgRenderer renderer)
{
- get
- {
- //var path = new GraphicsPath();
- //AddPaths(this, path);
-
- return GetPaths(this);
- }
- protected set
- { }
+ return GetPaths(this, renderer);
}
///
diff --git a/Source/Document Structure/SvgUse.cs b/Source/Document Structure/SvgUse.cs
index 6fe3d2e485f7ed0299b9e35e52b42aaed4eafc55..147d0b915adef2685cf6e7acf2ee01d6242cc252 100644
--- a/Source/Document Structure/SvgUse.cs
+++ b/Source/Document Structure/SvgUse.cs
@@ -38,10 +38,12 @@ namespace Svg
/// Applies the required transforms to .
///
/// The to be transformed.
- protected internal override void PushTransforms(SvgRenderer renderer)
+ protected internal override bool PushTransforms(SvgRenderer renderer)
{
- base.PushTransforms(renderer);
- renderer.TranslateTransform(this.X.ToDeviceValue(this), this.Y.ToDeviceValue(this, true));
+ if (!base.PushTransforms(renderer)) return false;
+ renderer.TranslateTransform(this.X.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this),
+ this.Y.ToDeviceValue(renderer, UnitRenderingType.Vertical, this));
+ return true;
}
///
@@ -53,15 +55,10 @@ namespace Svg
this.Y = 0;
}
- public override System.Drawing.Drawing2D.GraphicsPath Path
+ public override System.Drawing.Drawing2D.GraphicsPath Path(SvgRenderer renderer)
{
- get
- {
- SvgVisualElement element = (SvgVisualElement)this.OwnerDocument.IdManager.GetElementById(this.ReferencedElement);
- return (element != null) ? element.Path : null;
- }
- protected set
- { }
+ SvgVisualElement element = (SvgVisualElement)this.OwnerDocument.IdManager.GetElementById(this.ReferencedElement);
+ return (element != null) ? element.Path(renderer) : null;
}
public override System.Drawing.RectangleF Bounds
diff --git a/Source/Extensibility/SvgForeignObject.cs b/Source/Extensibility/SvgForeignObject.cs
index afe0ed0f8cbb223aca9e3b7f8235fe44a324f768..3fc4cdd485c95b3eb6950a98d0af67a3cc2fd134 100644
--- a/Source/Extensibility/SvgForeignObject.cs
+++ b/Source/Extensibility/SvgForeignObject.cs
@@ -17,17 +17,9 @@ namespace Svg
/// Gets the for this element.
///
///
- public override System.Drawing.Drawing2D.GraphicsPath Path
+ public override System.Drawing.Drawing2D.GraphicsPath Path(SvgRenderer renderer)
{
- get
- {
- //var path = new GraphicsPath();
- //AddPaths(this, path);
-
- return GetPaths(this);
- }
- protected set
- { }
+ return GetPaths(this, renderer);
}
///
diff --git a/Source/External/ExCSS/IToString.cs b/Source/External/ExCSS/IToString.cs
new file mode 100644
index 0000000000000000000000000000000000000000..778aea745f239238ad08c3e53afd8afdf3a16f99
--- /dev/null
+++ b/Source/External/ExCSS/IToString.cs
@@ -0,0 +1,7 @@
+namespace ExCSS
+{
+ public interface IToString
+ {
+ string ToString(bool friendlyFormat, int indentation = 0);
+ }
+}
\ No newline at end of file
diff --git a/Source/External/ExCSS/Lexer.cs b/Source/External/ExCSS/Lexer.cs
new file mode 100644
index 0000000000000000000000000000000000000000..6d81d2186e62171910143e3fe7156413171c4dde
--- /dev/null
+++ b/Source/External/ExCSS/Lexer.cs
@@ -0,0 +1,1223 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Text;
+using ExCSS.Model;
+using ExCSS.Model.TextBlocks;
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ sealed class Lexer
+ {
+ private readonly StringBuilder _buffer;
+ private readonly StylesheetReader _stylesheetReader;
+ private bool _ignoreWhitespace;
+ private bool _ignoreComments;
+ internal Action ErrorHandler { get; set; }
+
+ internal Lexer(StylesheetReader source)
+ {
+ _buffer = new StringBuilder();
+ _stylesheetReader = source;
+
+ ErrorHandler = (err, msg) => { };
+ }
+
+ private Block DataBlock(char current)
+ {
+ switch (current)
+ {
+ case Specification.LineFeed:
+ case Specification.CarriageReturn:
+ case Specification.Tab:
+ case Specification.Space:
+ do
+ {
+ current = _stylesheetReader.Next;
+ }
+ while (current.IsSpaceCharacter());
+
+ if (_ignoreWhitespace)
+ {
+ return DataBlock(current);
+ }
+
+ _stylesheetReader.Back();
+ return SpecialCharacter.Whitespace;
+
+ case Specification.DoubleQuote:
+ return DoubleQuoteString(_stylesheetReader.Next);
+
+ case Specification.Hash:
+ return HashStart(_stylesheetReader.Next);
+
+ case Specification.DollarSign:
+ current = _stylesheetReader.Next;
+
+ return current == Specification.EqualSign
+ ? MatchBlock.Suffix
+ : Block.Delim(_stylesheetReader.Previous);
+
+ case Specification.SingleQuote:
+ return SingleQuoteString(_stylesheetReader.Next);
+
+ case Specification.ParenOpen:
+ return BracketBlock.OpenRound;
+
+ case Specification.ParenClose:
+ return BracketBlock.CloseRound;
+
+ case Specification.Asterisk:
+ current = _stylesheetReader.Next;
+
+ return current == Specification.EqualSign
+ ? MatchBlock.Substring
+ : Block.Delim(_stylesheetReader.Previous);
+
+ case Specification.PlusSign:
+ {
+ var nextFirst = _stylesheetReader.Next;
+
+ if (nextFirst == Specification.EndOfFile)
+ {
+ _stylesheetReader.Back();
+ }
+ else
+ {
+ var nextSEcond = _stylesheetReader.Next;
+ _stylesheetReader.Back(2);
+
+ if (nextFirst.IsDigit() || (nextFirst == Specification.Period && nextSEcond.IsDigit()))
+ {
+ return NumberStart(current);
+ }
+ }
+
+ return Block.Delim(current);
+ }
+
+ case Specification.Comma:
+ return SpecialCharacter.Comma;
+
+ case Specification.Period:
+ {
+ var c = _stylesheetReader.Next;
+
+ return c.IsDigit()
+ ? NumberStart(_stylesheetReader.Previous)
+ : Block.Delim(_stylesheetReader.Previous);
+ }
+
+ case Specification.MinusSign:
+ {
+ var nextFirst = _stylesheetReader.Next;
+
+ if (nextFirst == Specification.EndOfFile)
+ {
+ _stylesheetReader.Back();
+ }
+ else
+ {
+ var nextSecond = _stylesheetReader.Next;
+ _stylesheetReader.Back(2);
+
+ if (nextFirst.IsDigit() || (nextFirst == Specification.Period && nextSecond.IsDigit()))
+ {
+ return NumberStart(current);
+ }
+ if (nextFirst.IsNameStart())
+ {
+ return IdentStart(current);
+ }
+ if (nextFirst == Specification.ReverseSolidus && !nextSecond.IsLineBreak() && nextSecond != Specification.EndOfFile)
+ {
+ return IdentStart(current);
+ }
+
+ if (nextFirst != Specification.MinusSign || nextSecond != Specification.GreaterThan)
+ {
+ return Block.Delim(current);
+ }
+ _stylesheetReader.Advance(2);
+
+ return _ignoreComments
+ ? DataBlock(_stylesheetReader.Next)
+ : CommentBlock.Close;
+ }
+
+ return Block.Delim(current);
+ }
+
+ case Specification.Solidus:
+
+ current = _stylesheetReader.Next;
+
+ return current == Specification.Asterisk
+ ? Comment(_stylesheetReader.Next)
+ : Block.Delim(_stylesheetReader.Previous);
+
+ case Specification.ReverseSolidus:
+ current = _stylesheetReader.Next;
+
+ if (current.IsLineBreak() || current == Specification.EndOfFile)
+ {
+ ErrorHandler(current == Specification.EndOfFile
+ ? ParserError.EndOfFile
+ : ParserError.UnexpectedLineBreak,
+ ErrorMessages.LineBreakEof);
+
+ return Block.Delim(_stylesheetReader.Previous);
+ }
+
+ return IdentStart(_stylesheetReader.Previous);
+
+ case Specification.Colon:
+ return SpecialCharacter.Colon;
+
+ case Specification.Simicolon:
+ return SpecialCharacter.Semicolon;
+
+ case Specification.LessThan:
+ current = _stylesheetReader.Next;
+
+ if (current == Specification.Em)
+ {
+ current = _stylesheetReader.Next;
+
+ if (current == Specification.MinusSign)
+ {
+ current = _stylesheetReader.Next;
+
+ if (current == Specification.MinusSign)
+ {
+ return _ignoreComments
+ ? DataBlock(_stylesheetReader.Next)
+ : CommentBlock.Open;
+ }
+
+ current = _stylesheetReader.Previous;
+ }
+
+ current = _stylesheetReader.Previous;
+ }
+
+ return Block.Delim(_stylesheetReader.Previous);
+
+ case Specification.At:
+ return AtKeywordStart(_stylesheetReader.Next);
+
+ case Specification.SquareBracketOpen:
+ return BracketBlock.OpenSquare;
+
+ case Specification.SquareBracketClose:
+ return BracketBlock.CloseSquare;
+
+ case Specification.Accent:
+ current = _stylesheetReader.Next;
+
+ return current == Specification.EqualSign
+ ? MatchBlock.Prefix
+ : Block.Delim(_stylesheetReader.Previous);
+
+ case Specification.CurlyBraceOpen:
+ return BracketBlock.OpenCurly;
+
+ case Specification.CurlyBraceClose:
+ return BracketBlock.CloseCurly;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ return NumberStart(current);
+
+ case 'U':
+ case 'u':
+ current = _stylesheetReader.Next;
+
+ if (current == Specification.PlusSign)
+ {
+ current = _stylesheetReader.Next;
+
+ if (current.IsHex() || current == Specification.QuestionMark)
+ return UnicodeRange(current);
+
+ current = _stylesheetReader.Previous;
+ }
+
+ return IdentStart(_stylesheetReader.Previous);
+
+ case Specification.Pipe:
+ current = _stylesheetReader.Next;
+
+ if (current == Specification.EqualSign)
+ {
+ return MatchBlock.Dash;
+ }
+ if (current == Specification.Pipe)
+ {
+ return Block.Column;
+ }
+
+ return Block.Delim(_stylesheetReader.Previous);
+
+ case Specification.Tilde:
+ current = _stylesheetReader.Next;
+
+ if (current == Specification.EqualSign)
+ {
+ return MatchBlock.Include;
+ }
+
+ return Block.Delim(_stylesheetReader.Previous);
+
+ case Specification.EndOfFile:
+ return null;
+
+ case Specification.Em:
+ current = _stylesheetReader.Next;
+
+ return current == Specification.EqualSign
+ ? MatchBlock.Not
+ : Block.Delim(_stylesheetReader.Previous);
+
+ default:
+ return current.IsNameStart()
+ ? IdentStart(current)
+ : Block.Delim(current);
+ }
+ }
+
+ private Block DoubleQuoteString(char current)
+ {
+ while (true)
+ {
+ switch (current)
+ {
+ case Specification.DoubleQuote:
+ case Specification.EndOfFile:
+ return StringBlock.Plain(FlushBuffer());
+
+ case Specification.FormFeed:
+ case Specification.LineFeed:
+ ErrorHandler(ParserError.UnexpectedLineBreak, ErrorMessages.DoubleQuotedString);
+ _stylesheetReader.Back();
+ return StringBlock.Plain(FlushBuffer(), true);
+
+ case Specification.ReverseSolidus:
+ current = _stylesheetReader.Next;
+
+ if (current.IsLineBreak())
+ {
+ _buffer.AppendLine();
+ }
+ else if (current != Specification.EndOfFile)
+ {
+ _buffer.Append(ConsumeEscape(current));
+ }
+ else
+ {
+ ErrorHandler(ParserError.EndOfFile, ErrorMessages.DoubleQuotedStringEof);
+ _stylesheetReader.Back();
+ return StringBlock.Plain(FlushBuffer(), true);
+ }
+
+ break;
+
+ default:
+ _buffer.Append(current);
+ break;
+ }
+
+ current = _stylesheetReader.Next;
+ }
+ }
+
+ private Block SingleQuoteString(char current)
+ {
+ while (true)
+ {
+ switch (current)
+ {
+ case Specification.SingleQuote:
+ case Specification.EndOfFile:
+ return StringBlock.Plain(FlushBuffer());
+
+ case Specification.FormFeed:
+ case Specification.LineFeed:
+ ErrorHandler(ParserError.UnexpectedLineBreak, ErrorMessages.SingleQuotedString);
+ _stylesheetReader.Back();
+ return (StringBlock.Plain(FlushBuffer(), true));
+
+ case Specification.ReverseSolidus:
+ current = _stylesheetReader.Next;
+
+ if (current.IsLineBreak())
+ {
+ _buffer.AppendLine();
+ }
+ else if (current != Specification.EndOfFile)
+ {
+ _buffer.Append(ConsumeEscape(current));
+ }
+ else
+ {
+ ErrorHandler(ParserError.EndOfFile, ErrorMessages.SingleQuotedStringEof);
+ _stylesheetReader.Back();
+ return (StringBlock.Plain(FlushBuffer(), true));
+ }
+
+ break;
+
+ default:
+ _buffer.Append(current);
+ break;
+ }
+
+ current = _stylesheetReader.Next;
+ }
+ }
+
+ private Block HashStart(char current)
+ {
+ if (current.IsNameStart())
+ {
+ _buffer.Append(current);
+ return HashRest(_stylesheetReader.Next);
+ }
+
+ if (IsValidEscape(current))
+ {
+ current = _stylesheetReader.Next;
+ _buffer.Append(ConsumeEscape(current));
+ return HashRest(_stylesheetReader.Next);
+ }
+
+ if (current != Specification.ReverseSolidus)
+ {
+ _stylesheetReader.Back();
+ return Block.Delim(Specification.Hash);
+ }
+
+ ErrorHandler(ParserError.InvalidCharacter, ErrorMessages.InvalidCharacterAfterHash);
+ return Block.Delim(Specification.Hash);
+ }
+
+ private Block HashRest(char current)
+ {
+ while (true)
+ {
+ if (current.IsName())
+ {
+ _buffer.Append(current);
+ }
+ else if (IsValidEscape(current))
+ {
+ current = _stylesheetReader.Next;
+ _buffer.Append(ConsumeEscape(current));
+ }
+ else if (current == Specification.ReverseSolidus)
+ {
+ ErrorHandler(ParserError.InvalidCharacter, ErrorMessages.InvalidCharacterAfterHash);
+
+ _stylesheetReader.Back();
+ return SymbolBlock.Hash(FlushBuffer());
+ }
+ else
+ {
+ _stylesheetReader.Back();
+ return SymbolBlock.Hash(FlushBuffer());
+ }
+
+ current = _stylesheetReader.Next;
+ }
+ }
+
+ private Block Comment(char current)
+ {
+ while (true)
+ {
+ switch (current)
+ {
+ case Specification.Asterisk:
+ current = _stylesheetReader.Next;
+ if (current == Specification.Solidus)
+ {
+ return DataBlock(_stylesheetReader.Next);
+ }
+ break;
+ case Specification.Solidus:
+ {
+ if (_stylesheetReader.Previous == Specification.Asterisk)
+ {
+ return DataBlock(_stylesheetReader.Next);
+ }
+ current = _stylesheetReader.Next;
+ break;
+ }
+ case Specification.EndOfFile:
+
+ ErrorHandler(ParserError.EndOfFile, ErrorMessages.ExpectedCommentEnd);
+
+ return DataBlock(current);
+ }
+
+ current = _stylesheetReader.Next;
+ }
+ }
+
+ private Block AtKeywordStart(char current)
+ {
+ if (current == Specification.MinusSign)
+ {
+ current = _stylesheetReader.Next;
+
+ if (current.IsNameStart() || IsValidEscape(current))
+ {
+ _buffer.Append(Specification.MinusSign);
+ return AtKeywordRest(current);
+ }
+
+ _stylesheetReader.Back(2);
+
+ return Block.Delim(Specification.At);
+ }
+
+ if (current.IsNameStart())
+ {
+ _buffer.Append(current);
+ return AtKeywordRest(_stylesheetReader.Next);
+ }
+
+ if (IsValidEscape(current))
+ {
+ current = _stylesheetReader.Next;
+ _buffer.Append(ConsumeEscape(current));
+ return AtKeywordRest(_stylesheetReader.Next);
+ }
+
+ _stylesheetReader.Back();
+ return Block.Delim(Specification.At);
+
+ }
+
+ private Block AtKeywordRest(char current)
+ {
+ while (true)
+ {
+ if (current.IsName())
+ {
+ _buffer.Append(current);
+ }
+ else if (IsValidEscape(current))
+ {
+ current = _stylesheetReader.Next;
+ _buffer.Append(ConsumeEscape(current));
+ }
+ else
+ {
+ _stylesheetReader.Back();
+ return SymbolBlock.At(FlushBuffer());
+ }
+
+ current = _stylesheetReader.Next;
+ }
+ }
+
+ private Block IdentStart(char current)
+ {
+ if (current == Specification.MinusSign)
+ {
+ current = _stylesheetReader.Next;
+
+ if (current.IsNameStart() || IsValidEscape(current))
+ {
+ _buffer.Append(Specification.MinusSign);
+ return IdentRest(current);
+ }
+
+ _stylesheetReader.Back();
+ return Block.Delim(Specification.MinusSign);
+ }
+
+ if (current.IsNameStart())
+ {
+ _buffer.Append(current);
+ return IdentRest(_stylesheetReader.Next);
+ }
+
+ if (current != Specification.ReverseSolidus)
+ {
+ return DataBlock(current);
+ }
+
+ if (!IsValidEscape(current))
+ {
+ return DataBlock(current);
+ }
+
+ current = _stylesheetReader.Next;
+ _buffer.Append(ConsumeEscape(current));
+ return IdentRest(_stylesheetReader.Next);
+ }
+
+ private Block IdentRest(char current)
+ {
+ while (true)
+ {
+ if (current.IsName())
+ {
+ _buffer.Append(current);
+ }
+ else if (IsValidEscape(current))
+ {
+ current = _stylesheetReader.Next;
+ _buffer.Append(ConsumeEscape(current));
+ }
+ else if (current == Specification.ParenOpen)
+ {
+ switch (_buffer.ToString().ToLower())
+ {
+ case "url":
+ _buffer.Length = 0;
+ return UrlStart(_stylesheetReader.Next);//, GrammarSegment.Url);
+
+ case "domain":
+ _buffer.Length = 0;
+ return UrlStart(_stylesheetReader.Next);//, GrammarSegment.Domain);
+
+ case "url-prefix":
+ _buffer.Length = 0;
+ return UrlStart(_stylesheetReader.Next);//, GrammarSegment.UrlPrefix);
+
+ default:
+ return SymbolBlock.Function(FlushBuffer());
+ }
+
+ }
+ else
+ {
+ _stylesheetReader.Back();
+ return SymbolBlock.Ident(FlushBuffer());
+ }
+
+ current = _stylesheetReader.Next;
+ }
+ }
+
+ private Block NumberStart(char current)
+ {
+ while (true)
+ {
+ switch (current)
+ {
+ case Specification.MinusSign:
+ case Specification.PlusSign:
+ _buffer.Append(current);
+ current = _stylesheetReader.Next;
+ if (current == Specification.Period)
+ {
+ _buffer.Append(current);
+ _buffer.Append(_stylesheetReader.Next);
+
+ return NumberFraction(_stylesheetReader.Next);
+ }
+ _buffer.Append(current);
+ return NumberRest(_stylesheetReader.Next);
+
+ case Specification.Period:
+ _buffer.Append(current);
+ _buffer.Append(_stylesheetReader.Next);
+ return NumberFraction(_stylesheetReader.Next);
+
+ default:
+ if (current.IsDigit())
+ {
+ _buffer.Append(current);
+ return NumberRest(_stylesheetReader.Next);
+ }
+ break;
+ }
+
+ current = _stylesheetReader.Next;
+ }
+ }
+
+ private Block NumberRest(char current)
+ {
+ while (true)
+ {
+ if (current.IsDigit())
+ {
+ _buffer.Append(current);
+ }
+ else if (current.IsNameStart())
+ {
+ var number = FlushBuffer();
+ _buffer.Append(current);
+ return Dimension(_stylesheetReader.Next, number);
+ }
+ else if (IsValidEscape(current))
+ {
+ current = _stylesheetReader.Next;
+ var number = FlushBuffer();
+ _buffer.Append(ConsumeEscape(current));
+ return Dimension(_stylesheetReader.Next, number);
+ }
+ else
+ {
+ break;
+ }
+
+ current = _stylesheetReader.Next;
+ }
+
+ switch (current)
+ {
+ case Specification.Period:
+ current = _stylesheetReader.Next;
+
+ if (current.IsDigit())
+ {
+ _buffer.Append(Specification.Period).Append(current);
+ return NumberFraction(_stylesheetReader.Next);
+ }
+
+ _stylesheetReader.Back();
+ return Block.Number(FlushBuffer());
+
+ case '%':
+ return UnitBlock.Percentage(FlushBuffer());
+
+ case 'e':
+ case 'E':
+ return NumberExponential(current);
+
+ case Specification.MinusSign:
+ return NumberDash(current);
+
+ default:
+ _stylesheetReader.Back();
+ return Block.Number(FlushBuffer());
+ }
+ }
+
+ private Block NumberFraction(char current)
+ {
+ while (true)
+ {
+ if (current.IsDigit())
+ {
+ _buffer.Append(current);
+ }
+ else if (current.IsNameStart())
+ {
+ var number = FlushBuffer();
+ _buffer.Append(current);
+
+ return Dimension(_stylesheetReader.Next, number);
+ }
+ else if (IsValidEscape(current))
+ {
+ current = _stylesheetReader.Next;
+ var number = FlushBuffer();
+ _buffer.Append(ConsumeEscape(current));
+
+ return Dimension(_stylesheetReader.Next, number);
+ }
+ else
+ {
+ break;
+ }
+
+ current = _stylesheetReader.Next;
+ }
+
+ switch (current)
+ {
+ case 'e':
+ case 'E':
+ return NumberExponential(current);
+
+ case '%':
+ return UnitBlock.Percentage(FlushBuffer());
+
+ case Specification.MinusSign:
+ return NumberDash(current);
+
+ default:
+ _stylesheetReader.Back();
+ return Block.Number(FlushBuffer());
+ }
+ }
+
+ private Block Dimension(char current, string number)
+ {
+ while (true)
+ {
+ if (current.IsName())
+ {
+ _buffer.Append(current);
+ }
+ else if (IsValidEscape(current))
+ {
+ current = _stylesheetReader.Next;
+ _buffer.Append(ConsumeEscape(current));
+ }
+ else
+ {
+ _stylesheetReader.Back();
+ return UnitBlock.Dimension(number, FlushBuffer());
+ }
+
+ current = _stylesheetReader.Next;
+ }
+ }
+
+ private Block SciNotation(char current)
+ {
+ while (true)
+ {
+ if (current.IsDigit())
+ {
+ _buffer.Append(current);
+ }
+ else
+ {
+ _stylesheetReader.Back();
+ return Block.Number(FlushBuffer());
+ }
+
+ current = _stylesheetReader.Next;
+ }
+ }
+
+ private Block UrlStart(char current)
+ {
+ while (current.IsSpaceCharacter())
+ {
+ current = _stylesheetReader.Next;
+ }
+
+ switch (current)
+ {
+ case Specification.EndOfFile:
+ ErrorHandler(ParserError.EndOfFile, ErrorMessages.InvalidUrlEnd);
+ return StringBlock.Url(string.Empty, true);
+
+ case Specification.DoubleQuote:
+ return DoubleQuotedUrl(_stylesheetReader.Next);
+
+ case Specification.SingleQuote:
+ return SingleQuoteUrl(_stylesheetReader.Next);
+
+ case ')':
+ return StringBlock.Url(string.Empty);
+
+ default:
+ return UnquotedUrl(current);
+ }
+ }
+
+ private Block DoubleQuotedUrl(char current)
+ {
+ while (true)
+ {
+ if (current.IsLineBreak())
+ {
+ ErrorHandler(ParserError.UnexpectedLineBreak, ErrorMessages.InvalidUrlEnd);
+ return BadUrl(_stylesheetReader.Next);
+ }
+
+ if (Specification.EndOfFile == current)
+ {
+ return StringBlock.Url(FlushBuffer());
+ }
+
+ if (current == Specification.DoubleQuote)
+ {
+ return UrlEnd(_stylesheetReader.Next);
+ }
+
+ if (current == Specification.ReverseSolidus)
+ {
+ current = _stylesheetReader.Next;
+
+ if (current == Specification.EndOfFile)
+ {
+ _stylesheetReader.Back(2);
+ ErrorHandler(ParserError.EndOfFile, ErrorMessages.InvalidUrlEnd);
+ return StringBlock.Url(FlushBuffer(), true);
+ }
+
+ if (current.IsLineBreak())
+ {
+ _buffer.AppendLine();
+ }
+ else
+ {
+ _buffer.Append(ConsumeEscape(current));
+ }
+ }
+ else
+ {
+ _buffer.Append(current);
+ }
+
+ current = _stylesheetReader.Next;
+ }
+ }
+
+ private Block SingleQuoteUrl(char current)
+ {
+ while (true)
+ {
+ if (current.IsLineBreak())
+ {
+ ErrorHandler(ParserError.UnexpectedLineBreak, ErrorMessages.SingleQuotedString);
+ return BadUrl(_stylesheetReader.Next);
+ }
+
+ if (Specification.EndOfFile == current)
+ {
+ return StringBlock.Url(FlushBuffer());
+ }
+
+ if (current == Specification.SingleQuote)
+ {
+ return UrlEnd(_stylesheetReader.Next);
+ }
+
+ if (current == Specification.ReverseSolidus)
+ {
+ current = _stylesheetReader.Next;
+
+ if (current == Specification.EndOfFile)
+ {
+ _stylesheetReader.Back(2);
+ ErrorHandler(ParserError.EndOfFile, ErrorMessages.SingleQuotedString);
+ return StringBlock.Url(FlushBuffer(), true);
+ }
+
+ if (current.IsLineBreak())
+ {
+ _buffer.AppendLine();
+ }
+ else
+ {
+ _buffer.Append(ConsumeEscape(current));
+ }
+ }
+ else
+ {
+ _buffer.Append(current);
+ }
+
+ current = _stylesheetReader.Next;
+ }
+ }
+
+ private Block UnquotedUrl(char current)
+ {
+ while (true)
+ {
+ if (current.IsSpaceCharacter())
+ {
+ return UrlEnd(_stylesheetReader.Next);
+ }
+
+ if (current == Specification.ParenClose || current == Specification.EndOfFile)
+ {
+ return StringBlock.Url(FlushBuffer());
+ }
+
+ if (current == Specification.DoubleQuote || current == Specification.SingleQuote ||
+ current == Specification.ParenOpen || current.IsNonPrintable())
+ {
+ ErrorHandler(ParserError.InvalidCharacter, ErrorMessages.InvalidUrlQuote);
+ return BadUrl(_stylesheetReader.Next);
+ }
+
+ if (current == Specification.ReverseSolidus)
+ {
+ if (IsValidEscape(current))
+ {
+ current = _stylesheetReader.Next;
+ _buffer.Append(ConsumeEscape(current));
+ }
+ else
+ {
+ ErrorHandler(ParserError.InvalidCharacter, ErrorMessages.InvalidUrlCharacter);
+ return BadUrl(_stylesheetReader.Next);
+ }
+ }
+ else
+ {
+ _buffer.Append(current);
+ }
+
+ current = _stylesheetReader.Next;
+ }
+ }
+
+ private Block UrlEnd(char current)
+ {
+ while (true)
+ {
+ if (current == Specification.ParenClose)
+ {
+ return StringBlock.Url(FlushBuffer());
+ }
+
+ if (!current.IsSpaceCharacter())
+ {
+ ErrorHandler(ParserError.InvalidCharacter, ErrorMessages.InvalidUrlCharacter);
+ return BadUrl(current);
+ }
+
+ current = _stylesheetReader.Next;
+ }
+ }
+
+ private Block BadUrl(char current)
+ {
+ while (true)
+ {
+ if (current == Specification.EndOfFile)
+ {
+ ErrorHandler(ParserError.EndOfFile, ErrorMessages.InvalidUrlEnd);
+
+ return StringBlock.Url(FlushBuffer(), true);
+ }
+
+ if (current == Specification.ParenClose)
+ {
+ return StringBlock.Url(FlushBuffer(), true);
+ }
+
+ if (IsValidEscape(current))
+ {
+ current = _stylesheetReader.Next;
+ _buffer.Append(ConsumeEscape(current));
+ }
+
+ current = _stylesheetReader.Next;
+ }
+ }
+
+ private Block UnicodeRange(char current)
+ {
+ for (var i = 0; i < 6; i++)
+ {
+ if (!current.IsHex())
+ {
+ break;
+ }
+
+ _buffer.Append(current);
+ current = _stylesheetReader.Next;
+ }
+
+ if (_buffer.Length != 6)
+ {
+ for (var i = 0; i < 6 - _buffer.Length; i++)
+ {
+ if (current != Specification.QuestionMark)
+ {
+ current = _stylesheetReader.Previous;
+ break;
+ }
+
+ _buffer.Append(current);
+ current = _stylesheetReader.Next;
+ }
+
+ var range = FlushBuffer();
+ var start = range.Replace(Specification.QuestionMark, '0');
+ var end = range.Replace(Specification.QuestionMark, 'F');
+ return Block.Range(start, end);
+ }
+
+ if (current == Specification.MinusSign)
+ {
+ current = _stylesheetReader.Next;
+
+ if (current.IsHex())
+ {
+ var start = _buffer.ToString();
+ _buffer.Length = 0;
+
+ for (var i = 0; i < 6; i++)
+ {
+ if (!current.IsHex())
+ {
+ current = _stylesheetReader.Previous;
+ break;
+ }
+
+ _buffer.Append(current);
+ current = _stylesheetReader.Next;
+ }
+
+ var end = FlushBuffer();
+ return Block.Range(start, end);
+ }
+
+ _stylesheetReader.Back(2);
+ return Block.Range(FlushBuffer(), null);
+
+ }
+
+ _stylesheetReader.Back();
+ return Block.Range(FlushBuffer(), null);
+ }
+
+ private string FlushBuffer()
+ {
+ var value = _buffer.ToString();
+ _buffer.Length = 0;
+ return value;
+ }
+
+ private Block NumberExponential(char current)
+ {
+ current = _stylesheetReader.Next;
+
+ if (current.IsDigit())
+ {
+ _buffer.Append('e').Append(current);
+ return SciNotation(_stylesheetReader.Next);
+ }
+
+ if (current == Specification.PlusSign || current == Specification.MinusSign)
+ {
+ var op = current;
+ current = _stylesheetReader.Next;
+
+ if (current.IsDigit())
+ {
+ _buffer.Append('e').Append(op).Append(current);
+ return SciNotation(_stylesheetReader.Next);
+ }
+
+ _stylesheetReader.Back();
+ }
+
+ current = _stylesheetReader.Previous;
+ var number = FlushBuffer();
+ _buffer.Append(current);
+
+ return Dimension(_stylesheetReader.Next, number);
+ }
+
+ private Block NumberDash(char current)
+ {
+ current = _stylesheetReader.Next;
+
+ if (current.IsNameStart())
+ {
+ var number = FlushBuffer();
+ _buffer.Append(Specification.MinusSign).Append(current);
+ return Dimension(_stylesheetReader.Next, number);
+ }
+
+ if (IsValidEscape(current))
+ {
+ current = _stylesheetReader.Next;
+ var number = FlushBuffer();
+ _buffer.Append(Specification.MinusSign).Append(ConsumeEscape(current));
+ return Dimension(_stylesheetReader.Next, number);
+ }
+
+ _stylesheetReader.Back(2);
+ return Block.Number(FlushBuffer());
+ }
+
+ private string ConsumeEscape(char current)
+ {
+ if (!current.IsHex())
+ {
+ return current.ToString(CultureInfo.InvariantCulture);
+ }
+
+ var escape = new List();
+
+ for (var i = 0; i < 6; i++)
+ {
+ escape.Add(current);
+ current = _stylesheetReader.Next;
+
+ if (!current.IsHex())
+ {
+ break;
+ }
+ }
+
+ current = _stylesheetReader.Previous;
+ var code = int.Parse(new string(escape.ToArray()), NumberStyles.HexNumber);
+ return Char.ConvertFromUtf32(code);
+ }
+
+ private bool IsValidEscape(char current)
+ {
+ if (current != Specification.ReverseSolidus)
+ {
+ return false;
+ }
+
+ current = _stylesheetReader.Next;
+ _stylesheetReader.Back();
+
+ if (current == Specification.EndOfFile)
+ {
+ return false;
+ }
+
+ return !current.IsLineBreak();
+ }
+
+ internal bool IgnoreWhitespace
+ {
+ get { return _ignoreWhitespace; }
+ set { _ignoreWhitespace = value; }
+ }
+
+ internal bool IgnoreComments
+ {
+ get { return _ignoreComments; }
+ set { _ignoreComments = value; }
+ }
+
+ internal StylesheetReader Stream
+ {
+ get { return _stylesheetReader; }
+ }
+
+ internal IEnumerable Tokens
+ {
+ get
+ {
+ while (true)
+ {
+ var token = DataBlock(_stylesheetReader.Current);
+
+ if (token == null)
+ {
+ yield break;
+ }
+
+ _stylesheetReader.Advance();
+
+ yield return token;
+ }
+ }
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Model/Enumerations.cs b/Source/External/ExCSS/Model/Enumerations.cs
new file mode 100644
index 0000000000000000000000000000000000000000..347565fe92db6d9cb23e26a80a0c6e77fa2ed72b
--- /dev/null
+++ b/Source/External/ExCSS/Model/Enumerations.cs
@@ -0,0 +1,257 @@
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ internal static class RuleTypes
+ {
+ internal const string CharacterSet = "charset";
+ internal const string Keyframes = "keyframes";
+ internal const string Media = "media";
+ internal const string Page = "page";
+ internal const string Import = "import";
+ internal const string FontFace = "font-face";
+ internal const string Namespace = "namespace";
+ internal const string Supports = "supports";
+ internal const string Document = "document";
+ }
+
+ internal static class PseudoSelectorPrefix
+ {
+ internal const string NthChildOdd = "odd";
+ internal const string NthChildEven = "even";
+ internal const string NthChildN = "n";
+ internal const string PseudoFunctionNthchild = "nth-child";
+ internal const string PseudoFunctionNthlastchild = "nth-last-child";
+ internal const string PseudoFunctionNthOfType = "nth-of-type";
+ internal const string PseudoFunctionNthLastOfType = "nth-last-of-type";
+ internal const string PseudoRoot = "root";
+ internal const string PseudoFirstOfType = "first-of-type";
+ internal const string PseudoLastoftype = "last-of-type";
+ internal const string PseudoOnlychild = "only-child";
+ internal const string PseudoOnlyOfType = "only-of-type";
+ internal const string PseudoFirstchild = "first-child";
+ internal const string PseudoLastchild = "last-child";
+ internal const string PseudoEmpty = "empty";
+ internal const string PseudoLink = "link";
+ internal const string PseudoVisited = "visited";
+ internal const string PseudoActive = "active";
+ internal const string PseudoHover = "hover";
+ internal const string PseudoFocus = "focus";
+ internal const string PseudoTarget = "target";
+ internal const string PseudoEnabled = "enabled";
+ internal const string PseudoDisabled = "disabled";
+ internal const string PseudoChecked = "checked";
+ internal const string PseudoUnchecked = "unchecked";
+ internal const string PseudoIndeterminate = "indeterminate";
+ internal const string PseudoDefault = "default";
+ internal const string PseudoValid = "valid";
+ internal const string PseudoInvalid = "invalid";
+ internal const string PseudoRequired = "required";
+ internal const string PseudoInrange = "in-range";
+ internal const string PseudoOutofrange = "out-of-range";
+ internal const string PseudoOptional = "optional";
+ internal const string PseudoReadonly = "read-only";
+ internal const string PseudoReadwrite = "read-write";
+ internal const string PseudoFunctionDir = "dir";
+
+ internal const string PseudoFunctionNot = "not";
+ internal const string PseudoFunctionLang = "lang";
+ internal const string PseudoFunctionContains = "contains";
+ internal const string PseudoElementBefore = "before";
+ internal const string PseudoElementAfter = "after";
+ internal const string PseudoElementSelection = "selection";
+ internal const string PseudoElementFirstline = "first-line";
+ internal const string PseudoElementFirstletter = "first-letter";
+ }
+
+ internal static class ErrorMessages
+ {
+ internal const string InvalidCharacter = "Invalid character detected.";
+ internal const string LineBreakEof = "Unexpected line break or EOF.";
+ internal const string UnexpectedCommentToken = "The input element is unexpected and has been ignored.";
+ internal const string DoubleQuotedString = "Expected double quoted string to terminate before form feed or line feed.";
+ internal const string DoubleQuotedStringEof = "Expected double quoted string to terminate before end of file.";
+ internal const string SingleQuotedString = "Expected single quoted string to terminate before form feed or line feed.";
+ internal const string SingleQuotedStringEof = "Expected single quoted string to terminate before end of file.";
+ internal const string InvalidCharacterAfterHash = "Invalid character after #.";
+ internal const string InvalidIdentAfterHash = "Invalid character after #.";
+ internal const string InvalidUrlEnd = "Expected URL to terminate before line break or end of file.";
+ internal const string InvalidUrlQuote = "Expected quotation or open paren in URL.";
+ internal const string InvalidUrlCharacter = "Invalid character in URL.";
+ internal const string ExpectedCommentEnd = "Expected comment to close before end of file.";
+ internal const string Default = "An unexpected error occurred.";
+ }
+
+ public enum Combinator
+ {
+ Child,
+ Descendent,
+ AdjacentSibling,
+ Sibling,
+ Namespace
+ }
+
+ internal enum GrammarSegment
+ {
+ String,
+ Url,
+ UrlPrefix,
+ Domain,
+ Hash, //#
+ AtRule, //@
+ Ident,
+ Function,
+ Number,
+ Percentage,
+ Dimension,
+ Range,
+ CommentOpen,
+ CommentClose,
+ Column,
+ Delimiter,
+ IncludeMatch, //~=
+ DashMatch, // |=
+ PrefixMatch, // ^=
+ SuffixMatch, // $=
+ SubstringMatch, // *=
+ NegationMatch, // !=
+ ParenOpen,
+ ParenClose,
+ CurlyBraceOpen,
+ CurlyBracketClose,
+ SquareBraceOpen,
+ SquareBracketClose,
+ Colon,
+ Comma,
+ Semicolon,
+ Whitespace
+ }
+
+ public enum RuleType
+ {
+ Unknown = 0,
+ Style = 1,
+ Charset = 2,
+ Import = 3,
+ Media = 4,
+ FontFace = 5,
+ Page = 6,
+ Keyframes = 7,
+ Keyframe = 8,
+ Namespace = 10,
+ CounterStyle = 11,
+ Supports = 12,
+ Document = 13,
+ FontFeatureValues = 14,
+ Viewport = 15,
+ RegionStyle = 16
+ }
+
+ public enum UnitType
+ {
+ Unknown = 0,
+ Number = 1,
+ Percentage = 2,
+ Ems = 3,
+ Exs = 4,
+ Pixel = 5,
+ Centimeter = 6,
+ Millimeter = 7,
+ Inch = 8,
+ Point = 9,
+ Percent = 10,
+ Degree = 11,
+ Radian = 12,
+ Grad = 13,
+ Millisecond = 14,
+ Second = 15,
+ Hertz = 16,
+ KiloHertz = 17,
+ Dimension = 18,
+ String = 19,
+ Uri = 20,
+ Ident = 21,
+ Attribute = 22,
+ Counter = 23,
+ Rect = 24,
+ RGB = 25,
+ ViewportWidth = 26,
+ ViewportHeight = 28,
+ ViewportMin = 29,
+ ViewportMax = 30,
+ Turn = 31,
+ }
+
+ public enum DocumentFunction
+ {
+ Url,
+ UrlPrefix,
+ Domain,
+ RegExp
+ }
+
+ public enum DirectionMode
+ {
+ LeftToRight,
+ RightToLeft
+ }
+
+ public enum ParserError
+ {
+ EndOfFile,
+ UnexpectedLineBreak,
+ InvalidCharacter,
+ UnexpectedCommentToken
+ }
+
+ internal enum SelectorOperation
+ {
+ Data,
+ Attribute,
+ AttributeOperator,
+ AttributeValue,
+ AttributeEnd,
+ Class,
+ PseudoClass,
+ PseudoClassFunction,
+ PseudoClassFunctionEnd,
+ PseudoElement
+ }
+
+ internal enum ParsingContext
+ {
+ DataBlock,
+ InSelector,
+ InDeclaration,
+ AfterProperty,
+ BeforeValue,
+ InValuePool,
+ InValueList,
+ InSingleValue,
+ InMediaList,
+ InMediaValue,
+ BeforeImport,
+ BeforeCharset,
+ BeforeNamespacePrefix,
+ AfterNamespacePrefix,
+ BeforeFontFace,
+ FontfaceData,
+ FontfaceProperty,
+ AfterInstruction,
+ InCondition,
+ BeforeKeyframesName,
+ BeforeKeyframesData,
+ KeyframesData,
+ InKeyframeText,
+ BeforePageSelector,
+ BeforeDocumentFunction,
+ InDocumentFunction,
+ AfterDocumentFunction,
+ BetweenDocumentFunctions,
+ InUnknown,
+ ValueImportant,
+ AfterValue,
+ InHexValue,
+ InFunction
+ }
+}
diff --git a/Source/External/ExCSS/Model/Extensions/CharacterExtensions.cs b/Source/External/ExCSS/Model/Extensions/CharacterExtensions.cs
new file mode 100644
index 0000000000000000000000000000000000000000..dba314f3546906954e2e8c8cb072065900da4b6f
--- /dev/null
+++ b/Source/External/ExCSS/Model/Extensions/CharacterExtensions.cs
@@ -0,0 +1,80 @@
+using System.Collections.Generic;
+
+namespace ExCSS.Model.Extensions
+{
+ static class CharacterExtensions
+ {
+ public static int FromHex(this char character)
+ {
+ return character.IsDigit() ? character - 0x30 : character - (character.IsLowercaseAscii() ? 0x57 : 0x37);
+ }
+
+ public static string TrimArray(this char[] array)
+ {
+ var start = 0;
+ var end = array.Length - 1;
+
+ while (start < array.Length && array[start].IsSpaceCharacter())
+ {
+ start++;
+ }
+
+ while (end > start && array[end].IsSpaceCharacter())
+ {
+ end--;
+ }
+
+ return new string(array, start, 1 + end - start);
+ }
+
+ public static string[] SplitOnCommas(this string value)
+ {
+ var list = new List();
+ var buffer = new List();
+ var chars = value.ToCharArray();
+
+ for (var i = 0; i <= chars.Length; i++)
+ {
+ if (i == chars.Length || chars[i] == ',')
+ {
+ if (buffer.Count <= 0)
+ {
+ continue;
+ }
+ var token = buffer.ToArray().TrimArray();
+
+ if (token.Length != 0)
+ {
+ list.Add(token);
+ }
+
+ buffer.Clear();
+ }
+ else
+ {
+ buffer.Add(chars[i]);
+ }
+ }
+
+ return list.ToArray();
+ }
+
+ public static string ToHex(this byte num)
+ {
+ var characters = new char[2];
+ var rem = num >> 4;
+
+ characters[0] = (char)(rem + (rem < 10 ? 48 : 55));
+ rem = num - 16 * rem;
+ characters[1] = (char)(rem + (rem < 10 ? 48 : 55));
+
+ return new string(characters);
+ }
+
+ public static char ToHexChar(this byte num)
+ {
+ var rem = num & 0x0F;
+ return (char)(rem + (rem < 10 ? 48 : 55));
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/External/ExCSS/Model/Extensions/StringExtensions.cs b/Source/External/ExCSS/Model/Extensions/StringExtensions.cs
new file mode 100644
index 0000000000000000000000000000000000000000..76eb2eecc2869bc90b9a614ea5b6dfd769e6e454
--- /dev/null
+++ b/Source/External/ExCSS/Model/Extensions/StringExtensions.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Text;
+
+namespace ExCSS.Model.Extensions
+{
+ public static class StringExtensions
+ {
+ public static string Indent(this string value, bool friendlyForamt, int indentation)
+ {
+ if (!friendlyForamt)
+ {
+ return value;
+ }
+
+ var tabs = new StringBuilder();
+ for (var i = 0; i < indentation; i++)
+ {
+ tabs.Append("\t");
+ }
+
+ return string.Format("{0}{1}", tabs, value);
+ }
+
+ public static string NewLineIndent(this string value, bool friendlyFormat, int indentation)
+ {
+ if (!friendlyFormat)
+ {
+ return value;
+ }
+
+ return Environment.NewLine + value.Indent(true, indentation);
+ }
+
+ public static string TrimFirstLine(this string value)
+ {
+ return new StringBuilder(value).TrimFirstLine().ToString();
+ }
+
+ public static StringBuilder TrimLastLine(this StringBuilder builder)
+ {
+ while (builder[builder.Length-1] == '\r' || builder[builder.Length-1] == '\n' || builder[builder.Length-1] == '\t')
+ {
+ builder.Remove(builder.Length - 1, 1);
+ }
+
+ return builder;
+ }
+
+ public static StringBuilder TrimFirstLine(this StringBuilder builder)
+ {
+ while (builder[0] == '\r' || builder[0] == '\n' || builder[0] == '\t')
+ {
+ builder.Remove(0, 1);
+ }
+
+ return builder;
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Model/FunctionBuffer.cs b/Source/External/ExCSS/Model/FunctionBuffer.cs
new file mode 100644
index 0000000000000000000000000000000000000000..cdc9f070a4b03488ae3a36fec7490ad3f03ba6b5
--- /dev/null
+++ b/Source/External/ExCSS/Model/FunctionBuffer.cs
@@ -0,0 +1,137 @@
+using System;
+using System.Collections.Generic;
+
+namespace ExCSS.Model
+{
+ internal class FunctionBuffer
+ {
+ private readonly string _function;
+ private readonly List _termList;
+ private Term _term;
+
+ internal FunctionBuffer(string function)
+ {
+ _termList = new List();
+ _function = function;
+ }
+
+ public List TermList
+ {
+ get { return _termList; }
+ }
+
+ public Term Term
+ {
+ get { return _term; }
+ set { _term = value; }
+ }
+
+ public void Include()
+ {
+ if (_term != null)
+ {
+ _termList.Add(_term);
+ }
+
+ _term = null;
+ }
+
+ public Term Done()
+ {
+ Include();
+ return BuildFunctionTerm(_function, _termList);
+ }
+
+ private Term BuildFunctionTerm(string name, List terms)
+ {
+ switch (name)
+ {
+ case "rgb":
+ {
+ if (terms.Count == 3)
+ {
+ if (CheckNumber(terms[0]) &&
+ CheckNumber(terms[1]) &&
+ CheckNumber(terms[2]))
+ {
+ return HtmlColor.FromRgb(
+ ToByte(terms[0]),
+ ToByte(terms[1]),
+ ToByte(terms[2]));
+ }
+ }
+
+ break;
+ }
+ case "rgba":
+ {
+ if (terms.Count == 4)
+ {
+ if (CheckNumber(terms[0]) &&
+ CheckNumber(terms[1]) &&
+ CheckNumber(terms[2]) &&
+ CheckNumber(terms[3]))
+ {
+ return HtmlColor.FromRgba(
+ ToByte(terms[0]),
+ ToByte(terms[1]),
+ ToByte(terms[2]),
+ ToSingle(terms[3]));
+ }
+ }
+
+ break;
+ }
+ case "hsl":
+ {
+ if (_termList.Count == 3)
+ {
+ if (CheckNumber(terms[0]) &&
+ CheckNumber(terms[1]) &&
+ CheckNumber(terms[2]))
+ {
+ return HtmlColor.FromHsl(
+ ToSingle(terms[0]),
+ ToSingle(terms[1]),
+ ToSingle(terms[2]));
+ }
+ }
+
+ break;
+ }
+ }
+
+ return new GenericFunction(name, terms);
+ }
+
+ private static bool CheckNumber(Term cssValue)
+ {
+ return (cssValue is PrimitiveTerm &&
+ ((PrimitiveTerm)cssValue).PrimitiveType == UnitType.Number);
+ }
+
+ private static Single ToSingle(Term cssValue)
+ {
+ var value = ((PrimitiveTerm)cssValue).GetFloatValue(UnitType.Number);
+
+ return value.HasValue
+ ? value.Value
+ : 0f;
+ }
+
+ private static byte ToByte(Single? value)
+ {
+ if (value.HasValue)
+ {
+ return (byte)Math.Min(Math.Max(value.Value, 0), 255);
+ }
+
+ return 0;
+ }
+
+ private static byte ToByte(Term cssValue)
+ {
+ return ToByte(((PrimitiveTerm)cssValue).GetFloatValue(UnitType.Number));
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/External/ExCSS/Model/HtmlEncoding.cs b/Source/External/ExCSS/Model/HtmlEncoding.cs
new file mode 100644
index 0000000000000000000000000000000000000000..bf04f2bd0cd346c661f7dba161d244746525ce95
--- /dev/null
+++ b/Source/External/ExCSS/Model/HtmlEncoding.cs
@@ -0,0 +1,459 @@
+using System;
+using System.Text;
+
+namespace ExCSS.Model
+{
+ internal static class HtmlEncoding
+ {
+ internal static string Extract(string content)
+ {
+ var position = 0;
+ content = content.ToLower();
+
+ for (var i = position; i < content.Length - 7; i++)
+ {
+ if (!content.Substring(i).StartsWith("charset"))
+ {
+ continue;
+ }
+
+ position = i + 7;
+ break;
+ }
+
+ if (position <= 0 || position >= content.Length)
+ {
+ return string.Empty;
+ }
+
+ for (var i = position; i < content.Length - 1; i++)
+ {
+ if (content[i].IsSpaceCharacter())
+ {
+ position++;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if (content[position] != Specification.EqualSign)
+ {
+ return Extract(content.Substring(position));
+ }
+
+ position++;
+
+ for (var i = position; i < content.Length; i++)
+ {
+ if (content[i].IsSpaceCharacter())
+ {
+ position++;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if (position >= content.Length)
+ {
+ return string.Empty;
+ }
+
+ switch (content[position])
+ {
+ case Specification.DoubleQuote:
+ {
+ content = content.Substring(position + 1);
+ var index = content.IndexOf(Specification.DoubleQuote);
+
+ if (index != -1)
+ {
+ return content.Substring(0, index);
+ }
+ }
+ break;
+
+ case Specification.SingleQuote:
+ {
+ content = content.Substring(position + 1);
+ var index = content.IndexOf(Specification.SingleQuote);
+
+ if (index != -1)
+ {
+ return content.Substring(0, index);
+ }
+ }
+ break;
+
+ default:
+ {
+ content = content.Substring(position);
+ var index = 0;
+
+ for (var i = 0; i < content.Length; i++)
+ {
+ if (content[i].IsSpaceCharacter())
+ {
+ break;
+ }
+
+ if (content[i] == ';')
+ {
+ break;
+ }
+
+ index++;
+ }
+
+ return content.Substring(0, index);
+ }
+ }
+
+ return string.Empty;
+ }
+
+ internal static bool IsSupported(string charset)
+ {
+ return Resolve(charset) != null;
+ }
+
+ internal static Encoding Resolve(string charset)
+ {
+ charset = charset.ToLower();
+
+ switch (charset)
+ {
+ case "unicode-1-1-utf-8":
+ case "utf-8":
+ case "utf8":
+ return Encoding.UTF8;
+
+ case "utf-16be":
+ return Encoding.BigEndianUnicode;
+
+ case "utf-16":
+ case "utf-16le":
+ return Encoding.Unicode;
+
+ case "dos-874":
+ case "iso-8859-11":
+ case "iso8859-11":
+ case "iso885911":
+ case "tis-620":
+ case "windows-874":
+ return Encoding.GetEncoding("windows-874");
+
+ case "cp1250":
+ case "windows-1250":
+ case "x-cp1250":
+ return Encoding.GetEncoding("windows-1250");
+
+ case "cp1251":
+ case "windows-1251":
+ case "x-cp1251":
+ return Encoding.GetEncoding("windows-1251");
+
+ case "ansi_x3.4-1968":
+ case "ascii":
+ case "cp1252":
+ case "cp819":
+ case "csisolatin1":
+ case "ibm819":
+ case "iso-8859-1":
+ case "iso-ir-100":
+ case "iso8859-1":
+ case "iso88591":
+ case "iso_8859-1":
+ case "iso_8859-1:1987":
+ case "l1":
+ case "latin1":
+ case "us-ascii":
+ case "windows-1252":
+ case "x-cp1252":
+ return Encoding.GetEncoding("windows-1252");
+
+ case "cp1253":
+ case "windows-1253":
+ case "x-cp1253":
+ return Encoding.GetEncoding("windows-1253");
+
+ case "cp1254":
+ case "csisolatin5":
+ case "iso-8859-9":
+ case "iso-ir-148":
+ case "iso8859-9":
+ case "iso88599":
+ case "iso_8859-9":
+ case "iso_8859-9:1989":
+ case "l5":
+ case "latin5":
+ case "windows-1254":
+ case "x-cp1254":
+ return Encoding.GetEncoding("windows-1254");
+
+ case "cp1255":
+ case "windows-1255":
+ case "x-cp1255":
+ return Encoding.GetEncoding("windows-1255");
+
+ case "cp1256":
+ case "windows-1256":
+ case "x-cp1256":
+ return Encoding.GetEncoding("windows-1256");
+
+ case "cp1257":
+ case "windows-1257":
+ case "x-cp1257":
+ return Encoding.GetEncoding("windows-1257");
+
+ case "cp1258":
+ case "windows-1258":
+ case "x-cp1258":
+ return Encoding.GetEncoding("windows-1258");
+
+ case "csmacintosh":
+ case "mac":
+ case "macintosh":
+ case "x-mac-roman":
+ return Encoding.GetEncoding("macintosh");
+
+ case "x-mac-cyrillic":
+ case "x-mac-ukrainian":
+ return Encoding.GetEncoding("x-mac-cyrillic");
+
+ case "866":
+ case "cp866":
+ case "csibm866":
+ case "ibm866":
+ return Encoding.GetEncoding("cp866");
+
+ case "csisolatin2":
+ case "iso-8859-2":
+ case "iso-ir-101":
+ case "iso8859-2":
+ case "iso88592":
+ case "iso_8859-2":
+ case "iso_8859-2:1987":
+ case "l2":
+ case "latin2":
+ return Encoding.GetEncoding("iso-8859-2");
+
+ case "csisolatin3":
+ case "iso-8859-3":
+ case "iso-ir-109":
+ case "iso8859-3":
+ case "iso88593":
+ case "iso_8859-3":
+ case "iso_8859-3:1988":
+ case "l3":
+ case "latin3":
+ return Encoding.GetEncoding("iso-8859-3");
+
+ case "csisolatin4":
+ case "iso-8859-4":
+ case "iso-ir-110":
+ case "iso8859-4":
+ case "iso88594":
+ case "iso_8859-4":
+ case "iso_8859-4:1988":
+ case "l4":
+ case "latin4":
+ return Encoding.GetEncoding("iso-8859-4");
+
+ case "csisolatincyrillic":
+ case "cyrillic":
+ case "iso-8859-5":
+ case "iso-ir-144":
+ case "iso8859-5":
+ case "iso88595":
+ case "iso_8859-5":
+ case "iso_8859-5:1988":
+ return Encoding.GetEncoding("iso-8859-5");
+
+ case "arabic":
+ case "asmo-708":
+ case "csiso88596e":
+ case "csiso88596i":
+ case "csisolatinarabic":
+ case "ecma-114":
+ case "iso-8859-6":
+ case "iso-8859-6-e":
+ case "iso-8859-6-i":
+ case "iso-ir-127":
+ case "iso8859-6":
+ case "iso88596":
+ case "iso_8859-6":
+ case "iso_8859-6:1987":
+ return Encoding.GetEncoding("iso-8859-6");
+
+ case "csisolatingreek":
+ case "ecma-118":
+ case "elot_928":
+ case "greek":
+ case "greek8":
+ case "iso-8859-7":
+ case "iso-ir-126":
+ case "iso8859-7":
+ case "iso88597":
+ case "iso_8859-7":
+ case "iso_8859-7:1987":
+ case "sun_eu_greek":
+ return Encoding.GetEncoding("iso-8859-7");
+
+ case "csiso88598e":
+ case "csisolatinhebrew":
+ case "hebrew":
+ case "iso-8859-8":
+ case "iso-8859-8-e":
+ case "iso-ir-138":
+ case "iso8859-8":
+ case "iso88598":
+ case "iso_8859-8":
+ case "iso_8859-8:1988":
+ case "visual":
+ return Encoding.GetEncoding("iso-8859-8");
+
+ case "csiso88598i":
+ case "iso-8859-8-i":
+ case "logical":
+ return Encoding.GetEncoding("iso-8859-8-i");
+
+ case "iso-8859-13":
+ case "iso8859-13":
+ case "iso885913":
+ return Encoding.GetEncoding("iso-8859-13");
+
+ case "csisolatin9":
+ case "iso-8859-15":
+ case "iso8859-15":
+ case "iso885915":
+ case "iso_8859-15":
+ case "l9":
+ return Encoding.GetEncoding("iso-8859-15");
+
+ case "cskoi8r":
+ case "koi":
+ case "koi8":
+ case "koi8-r":
+ case "koi8_r":
+ return Encoding.GetEncoding("koi8-r");
+
+ case "koi8-u":
+ return Encoding.GetEncoding("koi8-u");
+
+ case "chinese":
+ case "csgb2312":
+ case "csiso58gb231280":
+ case "gb2312":
+ case "gb_2312":
+ case "gb_2312-80":
+ case "gbk":
+ case "iso-ir-58":
+ case "x-gbk":
+ return Encoding.GetEncoding("x-cp20936");
+
+ case "hz-gb-2312":
+ return Encoding.GetEncoding("hz-gb-2312");
+
+ case "gb18030":
+ return Encoding.GetEncoding("GB18030");
+
+ case "big5":
+ case "big5-hkscs":
+ case "cn-big5":
+ case "csbig5":
+ case "x-x-big5":
+ return Encoding.GetEncoding("big5");
+
+ case "csiso2022jp":
+ case "iso-2022-jp":
+ return Encoding.GetEncoding("iso-2022-jp");
+
+ case "csiso2022kr":
+ case "iso-2022-kr":
+ return Encoding.GetEncoding("iso-2022-kr");
+
+ case "iso-2022-cn":
+ case "iso-2022-cn-ext":
+ return Encoding.GetEncoding("iso-2022-jp");
+
+ default:
+ return null;
+ }
+ }
+
+ internal static Encoding Suggest(string local)
+ {
+ if (local.Length < 2)
+ return Encoding.UTF8;
+
+ var firstTwo = local.Substring(0, 2).ToLower();
+
+ switch (firstTwo)
+ {
+ case "ar":
+ case "cy":
+ case "fa":
+ case "hr":
+ case "kk":
+ case "mk":
+ case "or":
+ case "ro":
+ case "sr":
+ case "vi":
+ return Encoding.UTF8;
+
+ case "be":
+ return Encoding.GetEncoding("iso-8859-5");
+
+ case "bg":
+ case "ru":
+ case "uk":
+ return Encoding.GetEncoding("windows-1251");
+
+ case "cs":
+ case "hu":
+ case "pl":
+ case "sl":
+ return Encoding.GetEncoding("iso-8859-2");
+
+ case "tr":
+ case "ku":
+ return Encoding.GetEncoding("windows-1254");
+
+ case "he":
+ return Encoding.GetEncoding("windows-1255");
+
+ case "lv":
+ return Encoding.GetEncoding("iso-8859-13");
+
+ case "ja":// Windows-31J ???? Replaced by something better anyway
+ return Encoding.UTF8;
+
+ case "ko":
+ return Encoding.GetEncoding("ks_c_5601-1987");
+
+ case "lt":
+ return Encoding.GetEncoding("windows-1257");
+
+ case "sk":
+ return Encoding.GetEncoding("windows-1250");
+
+ case "th":
+ return Encoding.GetEncoding("windows-874");
+ }
+
+ if (local.Equals("zh-CN", StringComparison.OrdinalIgnoreCase))
+ {
+ return Encoding.GetEncoding("GB18030");
+ }
+
+ return Encoding.GetEncoding(local.Equals("zh-TW", StringComparison.OrdinalIgnoreCase)
+ ? "big5"
+ : "windows-1252");
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/External/ExCSS/Model/ICssRules.cs b/Source/External/ExCSS/Model/ICssRules.cs
new file mode 100644
index 0000000000000000000000000000000000000000..9c303c2f860f33f0022efa99441cb42ae7d37146
--- /dev/null
+++ b/Source/External/ExCSS/Model/ICssRules.cs
@@ -0,0 +1,9 @@
+using System.Collections.Generic;
+
+namespace ExCSS.Model
+{
+ interface ISupportsRuleSets
+ {
+ List RuleSets { get; }
+ }
+}
\ No newline at end of file
diff --git a/Source/External/ExCSS/Model/ICssSelector.cs b/Source/External/ExCSS/Model/ICssSelector.cs
new file mode 100644
index 0000000000000000000000000000000000000000..62d57a4e425deee978f035ff46afdffc51a2c790
--- /dev/null
+++ b/Source/External/ExCSS/Model/ICssSelector.cs
@@ -0,0 +1,7 @@
+namespace ExCSS.Model
+{
+ interface ISupportsSelector
+ {
+ BaseSelector Selector { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/Source/External/ExCSS/Model/IStyleDeclaration.cs b/Source/External/ExCSS/Model/IStyleDeclaration.cs
new file mode 100644
index 0000000000000000000000000000000000000000..38f0d690cc17ed241529c8088e6778abb737f32d
--- /dev/null
+++ b/Source/External/ExCSS/Model/IStyleDeclaration.cs
@@ -0,0 +1,7 @@
+namespace ExCSS.Model
+{
+ interface ISupportsDeclarations
+ {
+ StyleDeclaration Declarations { get; }
+ }
+}
\ No newline at end of file
diff --git a/Source/External/ExCSS/Model/ISupportsMedia.cs b/Source/External/ExCSS/Model/ISupportsMedia.cs
new file mode 100644
index 0000000000000000000000000000000000000000..fa81faf84921e192f15129785eb602ba8a340488
--- /dev/null
+++ b/Source/External/ExCSS/Model/ISupportsMedia.cs
@@ -0,0 +1,7 @@
+namespace ExCSS.Model
+{
+ interface ISupportsMedia
+ {
+ MediaTypeList Media { get; }
+ }
+}
\ No newline at end of file
diff --git a/Source/External/ExCSS/Model/MediaTypeList.cs b/Source/External/ExCSS/Model/MediaTypeList.cs
new file mode 100644
index 0000000000000000000000000000000000000000..f8f8cd3ac603a60bb9fac834e7a81d94ce1f886e
--- /dev/null
+++ b/Source/External/ExCSS/Model/MediaTypeList.cs
@@ -0,0 +1,98 @@
+using System.Collections;
+using System.Collections.Generic;
+using ExCSS.Model.Extensions;
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ public class MediaTypeList : IEnumerable
+ {
+ private readonly List _media;
+ private string _buffer;
+
+ internal MediaTypeList()
+ {
+ _buffer = string.Empty;
+ _media = new List();
+ }
+
+ public string this[int index]
+ {
+ get
+ {
+ if (index < 0 || index >= _media.Count)
+ {
+ return null;
+ }
+
+ return _media[index];
+ }
+ set
+ {
+ _media[index] = value;
+ }
+ }
+
+ public int Count
+ {
+ get { return _media.Count; }
+ }
+
+ public string MediaType
+ {
+ get { return _buffer; }
+ set
+ {
+ _buffer = string.Empty;
+ _media.Clear();
+
+ if (string.IsNullOrEmpty(value))
+ {
+ return;
+ }
+
+ var entries = value.SplitOnCommas();
+
+ foreach (var t in entries)
+ {
+ AppendMedium(t);
+ }
+ }
+ }
+
+ internal MediaTypeList AppendMedium(string newMedium)
+ {
+ if (_media.Contains(newMedium))
+ {
+ return this;
+ }
+
+ _media.Add(newMedium);
+ _buffer += (string.IsNullOrEmpty(_buffer) ? string.Empty : ",") + newMedium;
+
+ return this;
+ }
+
+ public override string ToString()
+ {
+ return ToString(false);
+ }
+
+ public string ToString(bool friendlyFormat, int indentation = 0)
+ {
+ return friendlyFormat
+ ? string.Join(", ", _media.ToArray())
+ : string.Join(",", _media.ToArray());
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ return ((IEnumerable) _media).GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/External/ExCSS/Model/Rules/AggregateRule.cs b/Source/External/ExCSS/Model/Rules/AggregateRule.cs
new file mode 100644
index 0000000000000000000000000000000000000000..c70d60c68915284774e5f9f1fcb4bd6029b827a1
--- /dev/null
+++ b/Source/External/ExCSS/Model/Rules/AggregateRule.cs
@@ -0,0 +1,16 @@
+using System.Collections.Generic;
+using ExCSS.Model;
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ public abstract class AggregateRule : RuleSet, ISupportsRuleSets
+ {
+ protected AggregateRule()
+ {
+ RuleSets = new List();
+ }
+
+ public List RuleSets { get; private set; }
+ }
+}
diff --git a/Source/External/ExCSS/Model/Rules/CharacterSetRule.cs b/Source/External/ExCSS/Model/Rules/CharacterSetRule.cs
new file mode 100644
index 0000000000000000000000000000000000000000..a12e3b3298c393cf68067981b7c24404a68c0441
--- /dev/null
+++ b/Source/External/ExCSS/Model/Rules/CharacterSetRule.cs
@@ -0,0 +1,25 @@
+using ExCSS.Model.Extensions;
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ public class CharacterSetRule : RuleSet
+ {
+ public CharacterSetRule()
+ {
+ RuleType = RuleType.Charset;
+ }
+
+ public string Encoding { get; internal set; }
+
+ public override string ToString()
+ {
+ return ToString(false);
+ }
+
+ public override string ToString(bool friendlyFormat, int indentation = 0)
+ {
+ return string.Format("@charset '{0}';", Encoding).NewLineIndent(friendlyFormat, indentation);
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Model/Rules/ConditionalRule.cs b/Source/External/ExCSS/Model/Rules/ConditionalRule.cs
new file mode 100644
index 0000000000000000000000000000000000000000..f51c38d500ad733d610f3b4ec19ef9385dd44102
--- /dev/null
+++ b/Source/External/ExCSS/Model/Rules/ConditionalRule.cs
@@ -0,0 +1,13 @@
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ public abstract class ConditionalRule : AggregateRule
+ {
+ public virtual string Condition
+ {
+ get { return string.Empty; }
+ set { }
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Model/Rules/DocumentRule.cs b/Source/External/ExCSS/Model/Rules/DocumentRule.cs
new file mode 100644
index 0000000000000000000000000000000000000000..b9853730e2fcda1bfb3eb7511f84e00cdeef459d
--- /dev/null
+++ b/Source/External/ExCSS/Model/Rules/DocumentRule.cs
@@ -0,0 +1,82 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using ExCSS.Model;
+using ExCSS.Model.Extensions;
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ public sealed class DocumentRule : AggregateRule
+ {
+ readonly List> _conditions;
+
+ internal DocumentRule()
+ {
+ RuleType = RuleType.Document;
+ _conditions = new List>();
+ }
+
+ public string ConditionText
+ {
+ get
+ {
+ var builder = new StringBuilder();
+ var concat = false;
+
+ foreach (var condition in _conditions)
+ {
+ if (concat)
+ {
+ builder.Append(',');
+ }
+
+ switch (condition.Key)
+ {
+ case DocumentFunction.Url:
+ builder.Append("url");
+ break;
+
+ case DocumentFunction.UrlPrefix:
+ builder.Append("url-prefix");
+ break;
+
+ case DocumentFunction.Domain:
+ builder.Append("domain");
+ break;
+
+ case DocumentFunction.RegExp:
+ builder.Append("regexp");
+ break;
+ }
+
+ builder.Append(Specification.ParenOpen);
+ builder.Append(Specification.DoubleQuote);
+ builder.Append(condition.Value);
+ builder.Append(Specification.DoubleQuote);
+ builder.Append(Specification.ParenClose);
+ concat = true;
+ }
+
+ return builder.ToString();
+ }
+ }
+
+ internal List> Conditions
+ {
+ get { return _conditions; }
+ }
+
+ public override string ToString()
+ {
+ return ToString(false);
+ }
+
+ public override string ToString(bool friendlyFormat, int indentation = 0)
+ {
+ return "@document " + ConditionText + " {" +
+ RuleSets +
+ "}".NewLineIndent(friendlyFormat, indentation);
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Model/Rules/FontFaceRule.cs b/Source/External/ExCSS/Model/Rules/FontFaceRule.cs
new file mode 100644
index 0000000000000000000000000000000000000000..0d933d065a7efa9d150954fd899c9999404df343
--- /dev/null
+++ b/Source/External/ExCSS/Model/Rules/FontFaceRule.cs
@@ -0,0 +1,88 @@
+using ExCSS.Model;
+using ExCSS.Model.Extensions;
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ public class FontFaceRule : RuleSet, ISupportsDeclarations
+ {
+ private readonly StyleDeclaration _declarations;
+
+ public FontFaceRule()
+ {
+ _declarations = new StyleDeclaration();
+ RuleType = RuleType.FontFace;
+ }
+
+ internal FontFaceRule AppendRule(Property rule)
+ {
+ _declarations.Properties.Add(rule);
+ return this;
+ }
+
+ public StyleDeclaration Declarations
+ {
+ get { return _declarations; }
+ }
+
+ public string FontFamily
+ {
+ get { return _declarations.GetPropertyValue("font-family"); }
+ set { _declarations.SetProperty("font-family", value); }
+ }
+
+ public string Src
+ {
+ get { return _declarations.GetPropertyValue("src"); }
+ set { _declarations.SetProperty("src", value); }
+ }
+
+ public string FontStyle
+ {
+ get { return _declarations.GetPropertyValue("font-style"); }
+ set { _declarations.SetProperty("font-style", value); }
+ }
+
+ public string FontWeight
+ {
+ get { return _declarations.GetPropertyValue("font-weight"); }
+ set { _declarations.SetProperty("font-weight", value); }
+ }
+
+ public string Stretch
+ {
+ get { return _declarations.GetPropertyValue("stretch"); }
+ set { _declarations.SetProperty("stretch", value); }
+ }
+
+ public string UnicodeRange
+ {
+ get { return _declarations.GetPropertyValue("unicode-range"); }
+ set { _declarations.SetProperty("unicode-range", value); }
+ }
+
+ public string FontVariant
+ {
+ get { return _declarations.GetPropertyValue("font-variant"); }
+ set { _declarations.SetProperty("font-variant", value); }
+ }
+
+ public string FeatureSettings
+ {
+ get { return _declarations.GetPropertyValue("font-feature-settings"); }
+ set { _declarations.SetProperty("font-feature-settings", value); }
+ }
+
+ public override string ToString()
+ {
+ return ToString(false);
+ }
+
+ public override string ToString(bool friendlyFormat, int indentation = 0)
+ {
+ return "@font-face{".NewLineIndent(friendlyFormat, indentation) +
+ _declarations.ToString(friendlyFormat, indentation) +
+ "}".NewLineIndent(friendlyFormat, indentation);
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Model/Rules/GenericRule.cs b/Source/External/ExCSS/Model/Rules/GenericRule.cs
new file mode 100644
index 0000000000000000000000000000000000000000..a1d85d9e7116ed750700e0ebb3527583fd28e749
--- /dev/null
+++ b/Source/External/ExCSS/Model/Rules/GenericRule.cs
@@ -0,0 +1,36 @@
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ public class GenericRule : AggregateRule
+ {
+ private string _text;
+ private bool _stopped;
+
+ internal void SetInstruction(string text)
+ {
+ _text = text;
+ _stopped = true;
+ }
+
+ internal void SetCondition(string text)
+ {
+ _text = text;
+ _stopped = false;
+ }
+
+ public override string ToString()
+ {
+ return ToString(false);
+ }
+
+ public override string ToString(bool friendlyFormat, int indentation = 0)
+ {
+ if (_stopped)
+ {
+ return _text + ";";
+ }
+
+ return _text + "{" + RuleSets + "}";
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Model/Rules/IRuleContainer.cs b/Source/External/ExCSS/Model/Rules/IRuleContainer.cs
new file mode 100644
index 0000000000000000000000000000000000000000..13ec5a967beafcfe590fcb295671706eba9bb4b3
--- /dev/null
+++ b/Source/External/ExCSS/Model/Rules/IRuleContainer.cs
@@ -0,0 +1,10 @@
+using System.Collections.Generic;
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ public interface IRuleContainer
+ {
+ List Declarations { get; }
+ }
+}
\ No newline at end of file
diff --git a/Source/External/ExCSS/Model/Rules/ImportRule.cs b/Source/External/ExCSS/Model/Rules/ImportRule.cs
new file mode 100644
index 0000000000000000000000000000000000000000..8ef67b26bb078605b2a030e81d0a945bf5efb87e
--- /dev/null
+++ b/Source/External/ExCSS/Model/Rules/ImportRule.cs
@@ -0,0 +1,41 @@
+using ExCSS.Model;
+using ExCSS.Model.Extensions;
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ public class ImportRule : RuleSet, ISupportsMedia
+ {
+ private string _href;
+ private readonly MediaTypeList _media;
+
+ public ImportRule()
+ {
+ _media = new MediaTypeList();
+ RuleType = RuleType.Import;
+ }
+
+ public string Href
+ {
+ get { return _href; }
+ set { _href = value; }
+ }
+
+ public MediaTypeList Media
+ {
+ get { return _media; }
+ }
+
+ public override string ToString()
+ {
+ return ToString(false);
+ }
+
+ public override string ToString(bool friendlyFormat, int indentation = 0)
+ {
+ return _media.Count > 0
+ ? string.Format("@import url({0}) {1};", _href, _media).NewLineIndent(friendlyFormat, indentation)
+ : string.Format("@import url({0});", _href).NewLineIndent(friendlyFormat, indentation);
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Model/Rules/KeyframeRule.cs b/Source/External/ExCSS/Model/Rules/KeyframeRule.cs
new file mode 100644
index 0000000000000000000000000000000000000000..159314dbcd845e81cc77ffed2124e1a62a0a2f0b
--- /dev/null
+++ b/Source/External/ExCSS/Model/Rules/KeyframeRule.cs
@@ -0,0 +1,39 @@
+using ExCSS.Model;
+using ExCSS.Model.Extensions;
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ public class KeyframeRule : RuleSet, ISupportsDeclarations
+ {
+ private string _value;
+
+ public KeyframeRule()
+ {
+ Declarations = new StyleDeclaration();
+ RuleType = RuleType.Keyframe;
+ }
+
+ public string Value
+ {
+ get { return _value; }
+ set { _value = value; }
+ }
+
+ public StyleDeclaration Declarations { get; private set; }
+
+ public override string ToString()
+ {
+ return ToString(false);
+ }
+
+ public override string ToString(bool friendlyFormat, int indentation = 0)
+ {
+ return string.Empty.Indent(friendlyFormat, indentation) +
+ _value +
+ "{" +
+ Declarations.ToString(friendlyFormat, indentation) +
+ "}".NewLineIndent(friendlyFormat, indentation);
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Model/Rules/KeyframesRule.cs b/Source/External/ExCSS/Model/Rules/KeyframesRule.cs
new file mode 100644
index 0000000000000000000000000000000000000000..d4e4e0687c78fd699befba216a4ef8458edf0e5d
--- /dev/null
+++ b/Source/External/ExCSS/Model/Rules/KeyframesRule.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using ExCSS.Model.Extensions;
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ public class KeyframesRule : RuleSet, IRuleContainer
+ {
+ private readonly List _ruleSets;
+ private string _identifier;
+
+ public KeyframesRule()
+ {
+ _ruleSets = new List();
+ RuleType = RuleType.Keyframes;
+ }
+
+ public string Identifier
+ {
+ get { return _identifier; }
+ set { _identifier = value; }
+ }
+
+ //TODO change to "keyframes"
+ public List Declarations
+ {
+ get { return _ruleSets; }
+ }
+
+ public override string ToString()
+ {
+ return ToString(false);
+ }
+
+ public override string ToString(bool friendlyFormat, int indentation = 0)
+ {
+ var join = friendlyFormat ? "".NewLineIndent(true, indentation) : "";
+
+ var declarationList = _ruleSets.Select(d => d.ToString(friendlyFormat, indentation + 1));
+ var declarations = string.Join(join, declarationList.ToArray());
+
+ return ("@keyframes " + _identifier + "{").NewLineIndent(friendlyFormat, indentation) +
+ declarations.NewLineIndent(friendlyFormat, indentation) +
+ "}".NewLineIndent(friendlyFormat, indentation);
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Model/Rules/MediaRule.cs b/Source/External/ExCSS/Model/Rules/MediaRule.cs
new file mode 100644
index 0000000000000000000000000000000000000000..89727debe322be99bac8229c6ca58d5e9f80953e
--- /dev/null
+++ b/Source/External/ExCSS/Model/Rules/MediaRule.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Linq;
+using ExCSS.Model;
+using ExCSS.Model.Extensions;
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ public class MediaRule : ConditionalRule, ISupportsMedia
+ {
+ private readonly MediaTypeList _media;
+
+ public MediaRule()
+ {
+ _media = new MediaTypeList();
+ RuleType = RuleType.Media;
+ }
+
+ public override string Condition
+ {
+ get { return _media.MediaType; }
+ set { _media.MediaType = value; }
+ }
+
+ public MediaTypeList Media
+ {
+ get { return _media; }
+ }
+
+ public override string ToString()
+ {
+ return ToString(false);
+ }
+
+ public override string ToString(bool friendlyFormat, int indentation = 0)
+ {
+ var join = friendlyFormat ? "".NewLineIndent(true, indentation + 1) : "";
+
+ var declarationList = RuleSets.Select(d => d.ToString(friendlyFormat, indentation + 1).TrimFirstLine());
+ var declarations = string.Join(join, declarationList.ToArray());
+
+ return ("@media " + _media.MediaType + "{").NewLineIndent(friendlyFormat, indentation) +
+ declarations.TrimFirstLine().NewLineIndent(friendlyFormat, indentation + 1) +
+ "}".NewLineIndent(friendlyFormat, indentation);
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Model/Rules/NamespaceRule.cs b/Source/External/ExCSS/Model/Rules/NamespaceRule.cs
new file mode 100644
index 0000000000000000000000000000000000000000..0981f4688d00a378eb36f03aea4d744457c39f96
--- /dev/null
+++ b/Source/External/ExCSS/Model/Rules/NamespaceRule.cs
@@ -0,0 +1,30 @@
+using ExCSS.Model.Extensions;
+// ReSharper disable once CheckNamespace
+
+
+namespace ExCSS
+{
+ public class NamespaceRule : RuleSet
+ {
+ public NamespaceRule()
+ {
+ RuleType = RuleType.Namespace;
+ }
+
+ public string Uri { get; set; }
+
+ public string Prefix { get; set; }
+
+ public override string ToString()
+ {
+ return ToString(false);
+ }
+
+ public override string ToString(bool friendlyFormat, int indentation = 0)
+ {
+ return string.IsNullOrEmpty(Prefix)
+ ? string.Format("@namespace '{0}';", Uri).NewLineIndent(friendlyFormat, indentation)
+ : string.Format("@namespace {0} '{1}';", Prefix, Uri).NewLineIndent(friendlyFormat, indentation);
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Model/Rules/PageRule.cs b/Source/External/ExCSS/Model/Rules/PageRule.cs
new file mode 100644
index 0000000000000000000000000000000000000000..43bb0d3db2e62fb68ae12d060c0cf9470b3a6039
--- /dev/null
+++ b/Source/External/ExCSS/Model/Rules/PageRule.cs
@@ -0,0 +1,58 @@
+using ExCSS.Model;
+using ExCSS.Model.Extensions;
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ public class PageRule : RuleSet, ISupportsSelector, ISupportsDeclarations
+ {
+ private readonly StyleDeclaration _declarations;
+ private BaseSelector _selector;
+ private string _selectorText;
+
+ public PageRule()
+ {
+ _declarations = new StyleDeclaration();
+ RuleType = RuleType.Page;
+ }
+
+ internal PageRule AppendRule(Property rule)
+ {
+ _declarations.Properties.Add(rule);
+ return this;
+ }
+
+ public BaseSelector Selector
+ {
+ get { return _selector; }
+ set
+ {
+ _selector = value;
+ _selectorText = value.ToString();
+ }
+ }
+
+ public StyleDeclaration Declarations
+ {
+ get { return _declarations; }
+ }
+
+ public override string ToString()
+ {
+ return ToString(false);
+ }
+
+ public override string ToString(bool friendlyFormat, int indentation = 0)
+ {
+ var pseudo = string.IsNullOrEmpty(_selectorText)
+ ? ""
+ : ":" + _selectorText;
+
+ var declarations = _declarations.ToString(friendlyFormat, indentation);//.TrimFirstLine();
+
+ return ("@page " + pseudo + "{").NewLineIndent(friendlyFormat, indentation) +
+ declarations +
+ "}".NewLineIndent(friendlyFormat, indentation);
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Model/Rules/RuleSet.cs b/Source/External/ExCSS/Model/Rules/RuleSet.cs
new file mode 100644
index 0000000000000000000000000000000000000000..ec811e0b957e7ae2e0672c64d14ad6b37e6fec12
--- /dev/null
+++ b/Source/External/ExCSS/Model/Rules/RuleSet.cs
@@ -0,0 +1,16 @@
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ public abstract class RuleSet
+ {
+ internal RuleSet()
+ {
+ RuleType = RuleType.Unknown;
+ }
+
+ public RuleType RuleType { get; set; }
+
+ public abstract string ToString(bool friendlyFormat, int indentation = 0);
+ }
+}
diff --git a/Source/External/ExCSS/Model/Rules/StyleDeclaration.cs b/Source/External/ExCSS/Model/Rules/StyleDeclaration.cs
new file mode 100644
index 0000000000000000000000000000000000000000..2d66277f3dfc4239c168c40a1f70b61539ec4979
--- /dev/null
+++ b/Source/External/ExCSS/Model/Rules/StyleDeclaration.cs
@@ -0,0 +1,184 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ public class StyleDeclaration : IList
+ {
+ private readonly List _properties;
+ private readonly Func _getter;
+ private readonly Action _setter;
+ private bool _blocking;
+
+ public StyleDeclaration()
+ {
+ var text = string.Empty;
+ _getter = () => text;
+ _setter = value => text = value;
+ _properties = new List();
+ }
+
+ public string Value
+ {
+ get { return _getter(); }
+ set
+ {
+ Update(value);
+ _setter(value);
+ }
+ }
+
+ public RuleSet ParentRule { get; set; }
+
+ public void Add(Property item)
+ {
+ _properties.Add(item);
+ }
+
+ public void Clear()
+ {
+ _properties.Clear();
+ }
+
+ public bool Contains(Property item)
+ {
+ return _properties.Contains(item);
+ }
+
+ public void CopyTo(Property[] array, int arrayIndex)
+ {
+ _properties.CopyTo(array, arrayIndex);
+ }
+
+ public bool Remove(Property item)
+ {
+ return _properties.Remove(item);
+ }
+
+ public int IndexOf(Property item)
+ {
+ return _properties.IndexOf(item);
+ }
+
+ public void Insert(int index, Property item)
+ {
+ _properties.Insert(index, item);
+ }
+
+ public void RemoveAt(int index)
+ {
+ _properties.RemoveAt(index);
+ }
+
+ public override string ToString()
+ {
+ return ToString(false);
+ }
+
+ public string ToString(bool friendlyFormat, int indentation = 0)
+ {
+ var builder = new StringBuilder();
+
+ foreach (var property in _properties)
+ {
+ if (friendlyFormat)
+ {
+ builder.Append(Environment.NewLine);
+ }
+
+ builder.Append(property.ToString(friendlyFormat, indentation+1)).Append(';');
+ }
+
+ return builder.ToString();
+ }
+
+ internal string RemoveProperty(string propertyName)
+ {
+ for (var i = 0; i < _properties.Count; i++)
+ {
+ if (!_properties[i].Name.Equals(propertyName))
+ {
+ continue;
+ }
+
+ var value = _properties[i].Term;
+
+ _properties.RemoveAt(i);
+ Propagate();
+
+ return value.ToString();
+ }
+
+ return null;
+ }
+
+ internal string GetPropertyValue(string propertyName)
+ {
+ for (var i = 0; i < _properties.Count; i++)
+ {
+ if (_properties[i].Name.Equals(propertyName))
+ {
+ return _properties[i].Term.ToString();
+ }
+ }
+
+ return null;
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ return _properties.GetEnumerator();
+ }
+
+ public Property this[int index]
+ {
+ get { return _properties[index]; }
+ set { _properties[index] = value; }
+ }
+
+ public List Properties
+ {
+ get { return _properties; }
+ }
+
+ public int Count { get { return _properties.Count; } }
+
+ public bool IsReadOnly { get { return false; } }
+
+ internal StyleDeclaration SetProperty(string propertyName, string propertyValue)
+ {
+ //_properties.Add(Parser.ParseDeclaration(propertyName + ":" + propertyValue));
+ //TODO
+ Propagate();
+ return this;
+ }
+
+ internal void Update(string value)
+ {
+ if (_blocking)
+ {
+ return;
+ }
+
+ var rules = Parser.ParseDeclarations(value ?? string.Empty).Properties;
+
+ _properties.Clear();
+ _properties.AddRange(rules);
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return ((IEnumerable)_properties).GetEnumerator();
+ }
+
+ private void Propagate()
+ {
+ _blocking = true;
+ _setter(ToString());
+ _blocking = false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/External/ExCSS/Model/Rules/StyleRule.cs b/Source/External/ExCSS/Model/Rules/StyleRule.cs
new file mode 100644
index 0000000000000000000000000000000000000000..1b6780de1a3bedd2a06c37a873084efabc7fd785
--- /dev/null
+++ b/Source/External/ExCSS/Model/Rules/StyleRule.cs
@@ -0,0 +1,61 @@
+using System;
+using ExCSS.Model;
+using ExCSS.Model.Extensions;
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ public class StyleRule : RuleSet, ISupportsSelector, ISupportsDeclarations
+ {
+ private string _value;
+ private BaseSelector _selector;
+ private readonly StyleDeclaration _declarations;
+
+ public StyleRule() : this( new StyleDeclaration())
+ {}
+
+ public StyleRule(StyleDeclaration declarations)
+ {
+ RuleType = RuleType.Style;
+ _declarations = declarations;
+ }
+
+ public BaseSelector Selector
+ {
+ get { return _selector; }
+ set
+ {
+ _selector = value;
+ _value = value.ToString();
+ }
+ }
+
+ public string Value
+ {
+ get { return _value; }
+ set
+ {
+ _selector = Parser.ParseSelector(value);
+ _value = value;
+ }
+ }
+
+ public StyleDeclaration Declarations
+ {
+ get { return _declarations; }
+ }
+
+ public override string ToString()
+ {
+ return ToString(false);
+ }
+
+ public override string ToString(bool friendlyFormat, int indentation = 0)
+ {
+ return _value.NewLineIndent(friendlyFormat, indentation) +
+ "{" +
+ _declarations.ToString(friendlyFormat, indentation) +
+ "}".NewLineIndent(friendlyFormat, indentation);
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Model/Rules/SupportsRule.cs b/Source/External/ExCSS/Model/Rules/SupportsRule.cs
new file mode 100644
index 0000000000000000000000000000000000000000..b4349c3c0b796f6ecfb5734dcdd638d4e084c3b4
--- /dev/null
+++ b/Source/External/ExCSS/Model/Rules/SupportsRule.cs
@@ -0,0 +1,42 @@
+using System.Linq;
+using ExCSS.Model.Extensions;
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ public class SupportsRule : ConditionalRule
+ {
+ private string _condition;
+
+ public SupportsRule()
+ {
+ RuleType = RuleType.Supports;
+ _condition = string.Empty;
+ }
+
+ public override string Condition
+ {
+ get { return _condition; }
+ set { _condition = value; }
+ }
+
+ public bool IsSupported{ get; set; }
+
+ public override string ToString()
+ {
+ return ToString(false);
+ }
+
+ public override string ToString(bool friendlyFormat, int indentation = 0)
+ {
+ var join = friendlyFormat ? "".NewLineIndent(true, indentation + 1) : "";
+
+ var declarationList = RuleSets.Select(d => d.ToString(friendlyFormat, indentation + 1).TrimFirstLine());
+ var declarations = string.Join(join, declarationList.ToArray());
+
+ return ("@supports" + _condition + "{").NewLineIndent(friendlyFormat, indentation) +
+ declarations.TrimFirstLine().NewLineIndent(friendlyFormat, indentation + 1) +
+ "}".NewLineIndent(friendlyFormat, indentation);
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Model/Selector/AggregateSelectorList.cs b/Source/External/ExCSS/Model/Selector/AggregateSelectorList.cs
new file mode 100644
index 0000000000000000000000000000000000000000..f93de033db66b9ba338081e0388335315223da82
--- /dev/null
+++ b/Source/External/ExCSS/Model/Selector/AggregateSelectorList.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Text;
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ public class AggregateSelectorList : SelectorList
+ {
+ public readonly string Delimiter;
+
+ public AggregateSelectorList(string delimiter)
+ {
+ if (delimiter.Length > 1)
+ {
+ throw new ArgumentException("Expected single character delimiter or empty string", "delimiter");
+ }
+
+ Delimiter = delimiter;
+ }
+
+ public override string ToString(bool friendlyFormat, int indentation = 0)
+ {
+ var builder = new StringBuilder();
+
+ foreach (var selector in Selectors)
+ {
+ builder.Append(selector.ToString(friendlyFormat, indentation + 1));
+ builder.Append(Delimiter);
+ }
+
+ if (Delimiter.Length <= 0)
+ {
+ return builder.ToString();
+ }
+
+ if (builder.Length > 0)
+ {
+ builder.Remove(builder.Length - 1, 1);
+ }
+
+ return builder.ToString();
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Model/Selector/BaseSelector.cs b/Source/External/ExCSS/Model/Selector/BaseSelector.cs
new file mode 100644
index 0000000000000000000000000000000000000000..c718b5686fb527763575e1c7b0f22d434aa51f1e
--- /dev/null
+++ b/Source/External/ExCSS/Model/Selector/BaseSelector.cs
@@ -0,0 +1,15 @@
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ public abstract class BaseSelector
+ {
+ public sealed override string ToString()
+ {
+ return ToString(false);
+ }
+
+ public abstract string ToString(bool friendlyFormat, int indentation = 0);
+ }
+}
+
diff --git a/Source/External/ExCSS/Model/Selector/CombinatorSelector.cs b/Source/External/ExCSS/Model/Selector/CombinatorSelector.cs
new file mode 100644
index 0000000000000000000000000000000000000000..f8be92c6e25811d06dd38d65d45e8f1adc1b63cc
--- /dev/null
+++ b/Source/External/ExCSS/Model/Selector/CombinatorSelector.cs
@@ -0,0 +1,45 @@
+using System;
+using ExCSS.Model;
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ public struct CombinatorSelector
+ {
+ public BaseSelector Selector;
+ public Combinator Delimiter;
+
+ public CombinatorSelector(BaseSelector selector, Combinator delimiter)
+ {
+ Selector = selector;
+ Delimiter = delimiter;
+ }
+
+ public char Character
+ {
+ get{
+ switch (Delimiter)
+ {
+ case Combinator.Child:
+ return Specification.GreaterThan;
+
+ case Combinator.AdjacentSibling:
+ return Specification.PlusSign;
+
+ case Combinator.Descendent:
+ return Specification.Space;
+
+ case Combinator.Sibling:
+ return Specification.Tilde;
+
+ case Combinator.Namespace:
+ return Specification.Pipe;
+
+ default:
+ throw new NotImplementedException("Unknown combinator: " + Delimiter);
+ }
+ }
+ }
+ }
+}
+
diff --git a/Source/External/ExCSS/Model/Selector/ComplexSelector.cs b/Source/External/ExCSS/Model/Selector/ComplexSelector.cs
new file mode 100644
index 0000000000000000000000000000000000000000..e39969875faf92fa2b00894e53beaffe66e158f8
--- /dev/null
+++ b/Source/External/ExCSS/Model/Selector/ComplexSelector.cs
@@ -0,0 +1,66 @@
+using System;
+using System.Text;
+using System.Collections.Generic;
+using System.Collections;
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ public class ComplexSelector : BaseSelector, IEnumerable
+ {
+ private readonly List _selectors;
+
+ public ComplexSelector()
+ {
+ _selectors = new List();
+ }
+
+ public ComplexSelector AppendSelector(BaseSelector selector, Combinator combinator)
+ {
+ _selectors.Add(new CombinatorSelector(selector, combinator));
+ return this;
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ return _selectors.GetEnumerator();
+ }
+
+ internal void ConcludeSelector(BaseSelector selector)
+ {
+ _selectors.Add(new CombinatorSelector { Selector = selector });
+ }
+
+ public int Length
+ {
+ get { return _selectors.Count; }
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return ((IEnumerable)_selectors).GetEnumerator();
+ }
+
+ public override string ToString(bool friendlyFormat, int indentation = 0)
+ {
+ var builder = new StringBuilder();
+
+ if (_selectors.Count <= 0)
+ {
+ return builder.ToString();
+ }
+
+ var n = _selectors.Count - 1;
+
+ for (var i = 0; i < n; i++)
+ {
+ builder.Append(_selectors[i].Selector);
+ builder.Append(_selectors[i].Character);
+ }
+
+ builder.Append(_selectors[n].Selector);
+
+ return builder.ToString();
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Model/Selector/FirstChildSelector.cs b/Source/External/ExCSS/Model/Selector/FirstChildSelector.cs
new file mode 100644
index 0000000000000000000000000000000000000000..569bbac788af20f1038281476be9650a96cb6813
--- /dev/null
+++ b/Source/External/ExCSS/Model/Selector/FirstChildSelector.cs
@@ -0,0 +1,21 @@
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ internal sealed class FirstChildSelector : BaseSelector, IToString
+ {
+ FirstChildSelector()
+ { }
+
+ static FirstChildSelector _instance;
+
+ public static FirstChildSelector Instance
+ {
+ get { return _instance ?? (_instance = new FirstChildSelector()); }
+ }
+
+ public override string ToString(bool friendlyFormat, int indentation = 0)
+ {
+ return ":" + PseudoSelectorPrefix.PseudoFirstchild;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/External/ExCSS/Model/Selector/LastChildSelector.cs b/Source/External/ExCSS/Model/Selector/LastChildSelector.cs
new file mode 100644
index 0000000000000000000000000000000000000000..f0d1bfbdc4c180ceff34d8f06745740db2a058f0
--- /dev/null
+++ b/Source/External/ExCSS/Model/Selector/LastChildSelector.cs
@@ -0,0 +1,21 @@
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ internal sealed class LastChildSelector : BaseSelector, IToString
+ {
+ LastChildSelector()
+ { }
+
+ static LastChildSelector _instance;
+
+ public static LastChildSelector Instance
+ {
+ get { return _instance ?? (_instance = new LastChildSelector()); }
+ }
+
+ public override string ToString(bool friendlyFormat, int indentation = 0)
+ {
+ return ":" + PseudoSelectorPrefix.PseudoLastchild;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/External/ExCSS/Model/Selector/MultipleSelectorList.cs b/Source/External/ExCSS/Model/Selector/MultipleSelectorList.cs
new file mode 100644
index 0000000000000000000000000000000000000000..57e1e70ca7284a02c871d5577aab61419980ee48
--- /dev/null
+++ b/Source/External/ExCSS/Model/Selector/MultipleSelectorList.cs
@@ -0,0 +1,41 @@
+using System.Text;
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ public class MultipleSelectorList : SelectorList, IToString
+ {
+ internal static MultipleSelectorList Create(params SimpleSelector[] selectors)
+ {
+ var multiple = new MultipleSelectorList();
+
+ foreach (var selector in selectors)
+ {
+ multiple.Selectors.Add(selector);
+ }
+
+ return multiple;
+ }
+
+ internal bool IsInvalid { get; set; }
+
+ public override string ToString(bool friendlyFormat, int indentation = 0)
+ {
+ var builder = new StringBuilder();
+
+ if (Selectors.Count <= 0)
+ {
+ return builder.ToString();
+ }
+
+ builder.Append(Selectors[0]);
+
+ for (var i = 1; i < Selectors.Count; i++)
+ {
+ builder.Append(',').Append(Selectors[i]);
+ }
+
+ return builder.ToString();
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Model/Selector/NthChildSelector.cs b/Source/External/ExCSS/Model/Selector/NthChildSelector.cs
new file mode 100644
index 0000000000000000000000000000000000000000..77fc7425e2cbbefb634200ac3aa881315a3e21fe
--- /dev/null
+++ b/Source/External/ExCSS/Model/Selector/NthChildSelector.cs
@@ -0,0 +1,24 @@
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ internal abstract class NthChildSelector : BaseSelector, IToString
+ {
+ public int Step;
+ public int Offset;
+ internal string FunctionText { get; set; }
+
+ internal string FormatSelector(string functionName)
+ {
+ var format = Offset < 0
+ ? ":{0}({1}n{2})"
+ : ":{0}({1}n+{2})";
+
+ return string.IsNullOrEmpty(FunctionText)
+ ? string.Format(format, functionName, Step, Offset)
+ : string.Format(":{0}({1})", functionName, FunctionText);
+ }
+
+ public abstract override string ToString(bool friendlyFormat, int indentation = 0);
+ }
+}
\ No newline at end of file
diff --git a/Source/External/ExCSS/Model/Selector/NthFirstChildSelector.cs b/Source/External/ExCSS/Model/Selector/NthFirstChildSelector.cs
new file mode 100644
index 0000000000000000000000000000000000000000..154f66292c46f8c1c5f3cd636630e2d159c291c1
--- /dev/null
+++ b/Source/External/ExCSS/Model/Selector/NthFirstChildSelector.cs
@@ -0,0 +1,12 @@
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ internal sealed class NthFirstChildSelector : NthChildSelector, IToString
+ {
+ public override string ToString(bool friendlyFormat, int indentation = 0)
+ {
+ return FormatSelector(PseudoSelectorPrefix.PseudoFunctionNthchild);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/External/ExCSS/Model/Selector/NthLastChildSelector.cs b/Source/External/ExCSS/Model/Selector/NthLastChildSelector.cs
new file mode 100644
index 0000000000000000000000000000000000000000..797b627578aed515eba0980143d2638c818e8666
--- /dev/null
+++ b/Source/External/ExCSS/Model/Selector/NthLastChildSelector.cs
@@ -0,0 +1,13 @@
+using System;
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ internal sealed class NthLastChildSelector : NthChildSelector, IToString
+ {
+ public override string ToString(bool friendlyFormat, int indentation = 0)
+ {
+ return FormatSelector(PseudoSelectorPrefix.PseudoFunctionNthlastchild);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/External/ExCSS/Model/Selector/NthLastOfTypeSelector.cs b/Source/External/ExCSS/Model/Selector/NthLastOfTypeSelector.cs
new file mode 100644
index 0000000000000000000000000000000000000000..b1bbf9182672c3ffc5987ae67a60dbd29d02009c
--- /dev/null
+++ b/Source/External/ExCSS/Model/Selector/NthLastOfTypeSelector.cs
@@ -0,0 +1,12 @@
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ internal sealed class NthLastOfTypeSelector : NthChildSelector, IToString
+ {
+ public override string ToString(bool friendlyFormat, int indentation = 0)
+ {
+ return FormatSelector(PseudoSelectorPrefix.PseudoFunctionNthLastOfType);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/External/ExCSS/Model/Selector/NthOfTypeSelector.cs b/Source/External/ExCSS/Model/Selector/NthOfTypeSelector.cs
new file mode 100644
index 0000000000000000000000000000000000000000..66a704cbb8f78f465948f8fb2b5d8f9386a9f839
--- /dev/null
+++ b/Source/External/ExCSS/Model/Selector/NthOfTypeSelector.cs
@@ -0,0 +1,12 @@
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ internal sealed class NthOfTypeSelector : NthChildSelector, IToString
+ {
+ public override string ToString(bool friendlyFormat, int indentation = 0)
+ {
+ return FormatSelector(PseudoSelectorPrefix.PseudoFunctionNthOfType);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/External/ExCSS/Model/Selector/SelectorFactory.cs b/Source/External/ExCSS/Model/Selector/SelectorFactory.cs
new file mode 100644
index 0000000000000000000000000000000000000000..127b2ab1969980de4fd3cae20b8b17bb5161ef21
--- /dev/null
+++ b/Source/External/ExCSS/Model/Selector/SelectorFactory.cs
@@ -0,0 +1,802 @@
+using System;
+using System.Globalization;
+using ExCSS.Model;
+using ExCSS.Model.TextBlocks;
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ internal sealed class SelectorFactory
+ {
+ private SelectorOperation _selectorOperation;
+ private BaseSelector _currentSelector;
+ private AggregateSelectorList _aggregateSelectorList;
+ private ComplexSelector _complexSelector;
+ private bool _hasCombinator;
+ private Combinator _combinator;
+ private SelectorFactory _nestedSelectorFactory;
+ private string _attributeName;
+ private string _attributeValue;
+ private string _attributeOperator;
+
+ internal SelectorFactory()
+ {
+ ResetFactory();
+ }
+
+ internal BaseSelector GetSelector()
+ {
+ if (_complexSelector != null)
+ {
+ _complexSelector.ConcludeSelector(_currentSelector);
+ _currentSelector = _complexSelector;
+ }
+
+ if (_aggregateSelectorList == null || _aggregateSelectorList.Length == 0)
+ {
+ return _currentSelector ?? SimpleSelector.All;
+ }
+
+ if (_currentSelector == null && _aggregateSelectorList.Length == 1)
+ {
+ return _aggregateSelectorList[0];
+ }
+
+ if (_currentSelector == null)
+ {
+ return _aggregateSelectorList;
+ }
+
+ _aggregateSelectorList.AppendSelector(_currentSelector);
+ _currentSelector = null;
+
+ return _aggregateSelectorList;
+ }
+
+ internal void Apply(Block token)
+ {
+ switch (_selectorOperation)
+ {
+ case SelectorOperation.Data:
+ ParseSymbol(token);
+ break;
+
+ case SelectorOperation.Class:
+ PraseClass(token);
+ break;
+
+ case SelectorOperation.Attribute:
+ ParseAttribute(token);
+ break;
+
+ case SelectorOperation.AttributeOperator:
+ ParseAttributeOperator(token);
+ break;
+
+ case SelectorOperation.AttributeValue:
+ ParseAttributeValue(token);
+ break;
+
+ case SelectorOperation.AttributeEnd:
+ ParseAttributeEnd(token);
+ break;
+
+ case SelectorOperation.PseudoClass:
+ ParsePseudoClass(token);
+ break;
+
+ case SelectorOperation.PseudoClassFunction:
+ ParsePseudoClassFunction(token);
+ break;
+
+ case SelectorOperation.PseudoClassFunctionEnd:
+ PrasePseudoClassFunctionEnd(token);
+ break;
+
+ case SelectorOperation.PseudoElement:
+ ParsePseudoElement(token);
+ break;
+ }
+ }
+
+ internal SelectorFactory ResetFactory()
+ {
+ _attributeName = null;
+ _attributeValue = null;
+ _attributeOperator = string.Empty;
+ _selectorOperation = SelectorOperation.Data;
+ _combinator = Combinator.Descendent;
+ _hasCombinator = false;
+ _currentSelector = null;
+ _aggregateSelectorList = null;
+ _complexSelector = null;
+
+ return this;
+ }
+
+ private void ParseSymbol(Block token)
+ {
+ switch (token.GrammarSegment)
+ {
+ // Attribute [A]
+ case GrammarSegment.SquareBraceOpen:
+ _attributeName = null;
+ _attributeValue = null;
+ _attributeOperator = string.Empty;
+ _selectorOperation = SelectorOperation.Attribute;
+ return;
+
+ // Pseudo :P
+ case GrammarSegment.Colon:
+ _selectorOperation = SelectorOperation.PseudoClass;
+ return;
+
+ // ID #I
+ case GrammarSegment.Hash:
+ Insert(SimpleSelector.Id(((SymbolBlock)token).Value));
+ return;
+
+ // Type E
+ case GrammarSegment.Ident:
+ Insert(SimpleSelector.Type(((SymbolBlock)token).Value));
+ return;
+
+ // Whitespace
+ case GrammarSegment.Whitespace:
+ Insert(Combinator.Descendent);
+ return;
+
+ case GrammarSegment.Delimiter:
+ ParseDelimiter(token);
+ return;
+
+ case GrammarSegment.Comma:
+ InsertCommaDelimited();
+ return;
+ }
+ }
+
+ private void ParseAttribute(Block token)
+ {
+ if (token.GrammarSegment == GrammarSegment.Whitespace)
+ {
+ return;
+ }
+
+ _selectorOperation = SelectorOperation.AttributeOperator;
+
+ switch (token.GrammarSegment)
+ {
+ case GrammarSegment.Ident:
+ _attributeName = ((SymbolBlock)token).Value;
+ break;
+
+ case GrammarSegment.String:
+ _attributeName = ((StringBlock)token).Value;
+ break;
+
+ default:
+ _selectorOperation = SelectorOperation.Data;
+ break;
+ }
+ }
+
+ private void ParseAttributeOperator(Block token)
+ {
+ if (token.GrammarSegment == GrammarSegment.Whitespace)
+ {
+ return;
+ }
+
+ _selectorOperation = SelectorOperation.AttributeValue;
+
+ if (token.GrammarSegment == GrammarSegment.SquareBracketClose)
+ {
+ ParseAttributeEnd(token);
+ }
+ else if (token is MatchBlock || token.GrammarSegment == GrammarSegment.Delimiter)
+ {
+ _attributeOperator = token.ToString();
+ }
+ else
+ {
+ _selectorOperation = SelectorOperation.AttributeEnd;
+ }
+ }
+
+ private void ParseAttributeValue(Block token)
+ {
+ if (token.GrammarSegment == GrammarSegment.Whitespace)
+ {
+ return;
+ }
+
+ _selectorOperation = SelectorOperation.AttributeEnd;
+
+ switch (token.GrammarSegment)
+ {
+ case GrammarSegment.Ident:
+ _attributeValue = ((SymbolBlock)token).Value;
+ break;
+
+ case GrammarSegment.String:
+ _attributeValue = ((StringBlock)token).Value;
+ break;
+
+ case GrammarSegment.Number:
+ _attributeValue = ((NumericBlock)token).Value.ToString(CultureInfo.InvariantCulture);
+ break;
+
+ default:
+ _selectorOperation = SelectorOperation.Data;
+ break;
+ }
+ }
+
+ private void ParseAttributeEnd(Block token)
+ {
+ if (token.GrammarSegment == GrammarSegment.Whitespace)
+ {
+ return;
+ }
+
+ _selectorOperation = SelectorOperation.Data;
+
+ if (token.GrammarSegment != GrammarSegment.SquareBracketClose)
+ {
+ return;
+ }
+
+ switch (_attributeOperator)
+ {
+ case "=":
+ Insert(SimpleSelector.AttributeMatch(_attributeName, _attributeValue));
+ break;
+
+ case "~=":
+ Insert(SimpleSelector.AttributeSpaceSeparated(_attributeName, _attributeValue));
+ break;
+
+ case "|=":
+ Insert(SimpleSelector.AttributeDashSeparated(_attributeName, _attributeValue));
+ break;
+
+ case "^=":
+ Insert(SimpleSelector.AttributeStartsWith(_attributeName, _attributeValue));
+ break;
+
+ case "$=":
+ Insert(SimpleSelector.AttributeEndsWith(_attributeName, _attributeValue));
+ break;
+
+ case "*=":
+ Insert(SimpleSelector.AttributeContains(_attributeName, _attributeValue));
+ break;
+
+ case "!=":
+ Insert(SimpleSelector.AttributeNegatedMatch(_attributeName, _attributeValue));
+ break;
+
+ default:
+ Insert(SimpleSelector.AttributeUnmatched(_attributeName));
+ break;
+ }
+ }
+
+ private void ParsePseudoClass(Block token)
+ {
+ _selectorOperation = SelectorOperation.Data;
+
+ switch (token.GrammarSegment)
+ {
+ case GrammarSegment.Colon:
+ _selectorOperation = SelectorOperation.PseudoElement;
+ break;
+
+ case GrammarSegment.Function:
+ _attributeName = ((SymbolBlock)token).Value;
+ _attributeValue = string.Empty;
+ _selectorOperation = SelectorOperation.PseudoClassFunction;
+
+ if (_nestedSelectorFactory != null)
+ {
+ _nestedSelectorFactory.ResetFactory();
+ }
+
+ break;
+
+ case GrammarSegment.Ident:
+ var pseudoSelector = GetPseudoSelector(token);
+
+ if (pseudoSelector != null)
+ {
+ Insert(pseudoSelector);
+ }
+ break;
+ }
+ }
+
+ private void ParsePseudoElement(Block token)
+ {
+ if (token.GrammarSegment != GrammarSegment.Ident)
+ {
+ return;
+ }
+ var data = ((SymbolBlock)token).Value;
+
+ switch (data)
+ {
+ case PseudoSelectorPrefix.PseudoElementBefore:
+ Insert(SimpleSelector.PseudoElement(PseudoSelectorPrefix.PseudoElementBefore));
+ break;
+
+ case PseudoSelectorPrefix.PseudoElementAfter:
+ Insert(SimpleSelector.PseudoElement(PseudoSelectorPrefix.PseudoElementAfter));
+ break;
+
+ case PseudoSelectorPrefix.PseudoElementSelection:
+ Insert(SimpleSelector.PseudoElement(PseudoSelectorPrefix.PseudoElementSelection));
+ break;
+
+ case PseudoSelectorPrefix.PseudoElementFirstline:
+ Insert(SimpleSelector.PseudoElement(PseudoSelectorPrefix.PseudoElementFirstline));
+ break;
+
+ case PseudoSelectorPrefix.PseudoElementFirstletter:
+ Insert(SimpleSelector.PseudoElement(PseudoSelectorPrefix.PseudoElementFirstletter));
+ break;
+
+ default:
+ Insert(SimpleSelector.PseudoElement(data));
+ break;
+ }
+ }
+
+ private void PraseClass(Block token)
+ {
+ _selectorOperation = SelectorOperation.Data;
+
+ if (token.GrammarSegment == GrammarSegment.Ident)
+ {
+ Insert(SimpleSelector.Class(((SymbolBlock)token).Value));
+ }
+ }
+
+ private void ParsePseudoClassFunction(Block token)
+ {
+ if (token.GrammarSegment == GrammarSegment.Whitespace)
+ {
+ return;
+ }
+
+ switch (_attributeName)
+ {
+ case PseudoSelectorPrefix.PseudoFunctionNthchild:
+ case PseudoSelectorPrefix.PseudoFunctionNthlastchild:
+ case PseudoSelectorPrefix.PseudoFunctionNthOfType:
+ case PseudoSelectorPrefix.PseudoFunctionNthLastOfType:
+ {
+ switch (token.GrammarSegment)
+ {
+ case GrammarSegment.Ident:
+ case GrammarSegment.Number:
+ case GrammarSegment.Dimension:
+ _attributeValue += token.ToString();
+ return;
+
+ case GrammarSegment.Delimiter:
+ var chr = ((DelimiterBlock)token).Value;
+
+ if (chr == Specification.PlusSign || chr == Specification.MinusSign)
+ {
+ _attributeValue += chr;
+ return;
+ }
+
+ break;
+ }
+
+ break;
+ }
+ case PseudoSelectorPrefix.PseudoFunctionNot:
+ {
+ if (_nestedSelectorFactory == null)
+ {
+ _nestedSelectorFactory = new SelectorFactory();
+ }
+
+ if (token.GrammarSegment != GrammarSegment.ParenClose || _nestedSelectorFactory._selectorOperation != SelectorOperation.Data)
+ {
+ _nestedSelectorFactory.Apply(token);
+ return;
+ }
+
+ break;
+ }
+ case PseudoSelectorPrefix.PseudoFunctionDir:
+ {
+ if (token.GrammarSegment == GrammarSegment.Ident)
+ {
+ _attributeValue = ((SymbolBlock)token).Value;
+ }
+
+ _selectorOperation = SelectorOperation.PseudoClassFunctionEnd;
+ return;
+ }
+ case PseudoSelectorPrefix.PseudoFunctionLang:
+ {
+ if (token.GrammarSegment == GrammarSegment.Ident)
+ {
+ _attributeValue = ((SymbolBlock)token).Value;
+ }
+
+ _selectorOperation = SelectorOperation.PseudoClassFunctionEnd;
+ return;
+ }
+ case PseudoSelectorPrefix.PseudoFunctionContains:
+ {
+ switch (token.GrammarSegment)
+ {
+ case GrammarSegment.String:
+ _attributeValue = ((StringBlock)token).Value;
+ break;
+
+ case GrammarSegment.Ident:
+ _attributeValue = ((SymbolBlock)token).Value;
+ break;
+ }
+
+ _selectorOperation = SelectorOperation.PseudoClassFunctionEnd;
+ return;
+ }
+ }
+
+ PrasePseudoClassFunctionEnd(token);
+ }
+
+ private void PrasePseudoClassFunctionEnd(Block token)
+ {
+ _selectorOperation = SelectorOperation.Data;
+
+ if (token.GrammarSegment != GrammarSegment.ParenClose)
+ {
+ return;
+ }
+
+ switch (_attributeName)
+ {
+ case PseudoSelectorPrefix.PseudoFunctionNthchild:
+ Insert(GetChildSelector());
+ break;
+
+ case PseudoSelectorPrefix.PseudoFunctionNthlastchild:
+ Insert(GetChildSelector());
+ break;
+
+ case PseudoSelectorPrefix.PseudoFunctionNthOfType:
+ Insert(GetChildSelector());
+ break;
+
+ case PseudoSelectorPrefix.PseudoFunctionNthLastOfType:
+ Insert(GetChildSelector());
+ break;
+
+ case PseudoSelectorPrefix.PseudoFunctionNot:
+ {
+ var selector = _nestedSelectorFactory.GetSelector();
+ var code = string.Format("{0}({1})", PseudoSelectorPrefix.PseudoFunctionNot, selector);
+ Insert(SimpleSelector.PseudoClass(code));
+ break;
+ }
+ case PseudoSelectorPrefix.PseudoFunctionDir:
+ {
+ var code = string.Format("{0}({1})", PseudoSelectorPrefix.PseudoFunctionDir, _attributeValue);
+ Insert(SimpleSelector.PseudoClass(code));
+ break;
+ }
+ case PseudoSelectorPrefix.PseudoFunctionLang:
+ {
+ var code = string.Format("{0}({1})", PseudoSelectorPrefix.PseudoFunctionLang, _attributeValue);
+ Insert(SimpleSelector.PseudoClass(code));
+ break;
+ }
+ case PseudoSelectorPrefix.PseudoFunctionContains:
+ {
+ var code = string.Format("{0}({1})", PseudoSelectorPrefix.PseudoFunctionContains, _attributeValue);
+ Insert(SimpleSelector.PseudoClass(code));
+ break;
+ }
+ }
+ }
+
+ private void InsertCommaDelimited()
+ {
+ if (_currentSelector == null)
+ {
+ return;
+ }
+
+ if (_aggregateSelectorList == null)
+ {
+ _aggregateSelectorList = new AggregateSelectorList(",");
+ }
+
+ if (_complexSelector != null)
+ {
+ _complexSelector.ConcludeSelector(_currentSelector);
+ _aggregateSelectorList.AppendSelector(_complexSelector);
+ _complexSelector = null;
+ }
+ else
+ {
+ _aggregateSelectorList.AppendSelector(_currentSelector);
+ }
+
+ _currentSelector = null;
+ }
+
+ private void Insert(BaseSelector selector)
+ {
+ if (_currentSelector != null)
+ {
+ if (!_hasCombinator)
+ {
+ var compound = _currentSelector as AggregateSelectorList;
+
+ if (compound == null)
+ {
+ compound = new AggregateSelectorList("");
+ compound.AppendSelector(_currentSelector);
+ }
+
+ compound.AppendSelector(selector);
+ _currentSelector = compound;
+ }
+ else
+ {
+ if (_complexSelector == null)
+ {
+ _complexSelector = new ComplexSelector();
+ }
+
+ _complexSelector.AppendSelector(_currentSelector, _combinator);
+ _combinator = Combinator.Descendent;
+ _hasCombinator = false;
+ _currentSelector = selector;
+ }
+ }
+ else
+ {
+ if (_currentSelector == null && _complexSelector == null && _combinator == Combinator.Namespace)
+ {
+ _complexSelector = new ComplexSelector();
+ _complexSelector.AppendSelector(SimpleSelector.Type(""), _combinator);
+ _currentSelector = selector;
+ }
+ else
+ {
+ _combinator = Combinator.Descendent;
+ _hasCombinator = false;
+ _currentSelector = selector;
+ }
+ }
+ }
+
+ private void Insert(Combinator combinator)
+ {
+ _hasCombinator = true;
+
+ if (combinator != Combinator.Descendent)
+ {
+ _combinator = combinator;
+ }
+ }
+
+ private void ParseDelimiter(Block token)
+ {
+ switch (((DelimiterBlock)token).Value)
+ {
+ case Specification.Comma:
+ InsertCommaDelimited();
+ return;
+
+ case Specification.GreaterThan:
+ Insert(Combinator.Child);
+ return;
+
+ case Specification.PlusSign:
+ Insert(Combinator.AdjacentSibling);
+ return;
+
+ case Specification.Tilde:
+ Insert(Combinator.Sibling);
+ return;
+
+ case Specification.Asterisk:
+ Insert(SimpleSelector.All);
+ return;
+
+ case Specification.Period:
+ _selectorOperation = SelectorOperation.Class;
+ return;
+
+ case Specification.Pipe:
+ Insert(Combinator.Namespace);
+ return;
+ }
+ }
+
+ private BaseSelector GetChildSelector() where T : NthChildSelector, new()
+ {
+ var selector = new T();
+
+ if (_attributeValue.Equals(PseudoSelectorPrefix.NthChildOdd, StringComparison.OrdinalIgnoreCase))
+ {
+ selector.Step = 2;
+ selector.Offset = 1;
+ selector.FunctionText = PseudoSelectorPrefix.NthChildOdd;
+ }
+ else if (_attributeValue.Equals(PseudoSelectorPrefix.NthChildEven, StringComparison.OrdinalIgnoreCase))
+ {
+ selector.Step = 2;
+ selector.Offset = 0;
+ selector.FunctionText = PseudoSelectorPrefix.NthChildEven;
+ }
+ else if (!int.TryParse(_attributeValue, out selector.Offset))
+ {
+ var index = _attributeValue.IndexOf(PseudoSelectorPrefix.NthChildN, StringComparison.OrdinalIgnoreCase);
+
+ if (_attributeValue.Length <= 0 || index == -1)
+ {
+ return selector;
+ }
+
+ var first = _attributeValue.Substring(0, index).Replace(" ", "");
+
+ var second = "";
+
+ if (_attributeValue.Length > index + 1)
+ {
+ second = _attributeValue.Substring(index + 1).Replace(" ", "");
+ }
+
+ if (first == string.Empty || (first.Length == 1 && first[0] == Specification.PlusSign))
+ {
+ selector.Step = 1;
+ }
+ else if (first.Length == 1 && first[0] == Specification.MinusSign)
+ {
+ selector.Step = -1;
+ }
+ else
+ {
+ int step;
+ if (int.TryParse(first, out step))
+ {
+ selector.Step = step;
+ }
+ }
+
+ if (second == string.Empty)
+ {
+ selector.Offset = 0;
+ }
+ else
+ {
+ int offset;
+ if (int.TryParse(second, out offset))
+ {
+ selector.Offset = offset;
+ }
+ }
+ }
+
+ return selector;
+ }
+
+ private static BaseSelector GetPseudoSelector(Block token)
+ {
+ switch (((SymbolBlock)token).Value)
+ {
+ case PseudoSelectorPrefix.PseudoRoot:
+ return SimpleSelector.PseudoClass(PseudoSelectorPrefix.PseudoRoot);
+
+ case PseudoSelectorPrefix.PseudoFirstOfType:
+ return SimpleSelector.PseudoClass(PseudoSelectorPrefix.PseudoFirstOfType);
+
+ case PseudoSelectorPrefix.PseudoLastoftype:
+ return SimpleSelector.PseudoClass(PseudoSelectorPrefix.PseudoLastoftype);
+
+ case PseudoSelectorPrefix.PseudoOnlychild:
+ return SimpleSelector.PseudoClass(PseudoSelectorPrefix.PseudoOnlychild);
+
+ case PseudoSelectorPrefix.PseudoOnlyOfType:
+ return SimpleSelector.PseudoClass(PseudoSelectorPrefix.PseudoOnlyOfType);
+
+ case PseudoSelectorPrefix.PseudoFirstchild:
+ return FirstChildSelector.Instance;
+
+ case PseudoSelectorPrefix.PseudoLastchild:
+ return LastChildSelector.Instance;
+
+ case PseudoSelectorPrefix.PseudoEmpty:
+ return SimpleSelector.PseudoClass(PseudoSelectorPrefix.PseudoEmpty);
+
+ case PseudoSelectorPrefix.PseudoLink:
+ return SimpleSelector.PseudoClass(PseudoSelectorPrefix.PseudoLink);
+
+ case PseudoSelectorPrefix.PseudoVisited:
+ return SimpleSelector.PseudoClass(PseudoSelectorPrefix.PseudoVisited);
+
+ case PseudoSelectorPrefix.PseudoActive:
+ return SimpleSelector.PseudoClass(PseudoSelectorPrefix.PseudoActive);
+
+ case PseudoSelectorPrefix.PseudoHover:
+ return SimpleSelector.PseudoClass(PseudoSelectorPrefix.PseudoHover);
+
+ case PseudoSelectorPrefix.PseudoFocus:
+ return SimpleSelector.PseudoClass(PseudoSelectorPrefix.PseudoFocus);
+
+ case PseudoSelectorPrefix.PseudoTarget:
+ return SimpleSelector.PseudoClass(PseudoSelectorPrefix.PseudoTarget);
+
+ case PseudoSelectorPrefix.PseudoEnabled:
+ return SimpleSelector.PseudoClass(PseudoSelectorPrefix.PseudoEnabled);
+
+ case PseudoSelectorPrefix.PseudoDisabled:
+ return SimpleSelector.PseudoClass(PseudoSelectorPrefix.PseudoDisabled);
+
+ case PseudoSelectorPrefix.PseudoDefault:
+ return SimpleSelector.PseudoClass(PseudoSelectorPrefix.PseudoDefault);
+
+ case PseudoSelectorPrefix.PseudoChecked:
+ return SimpleSelector.PseudoClass(PseudoSelectorPrefix.PseudoChecked);
+
+ case PseudoSelectorPrefix.PseudoIndeterminate:
+ return SimpleSelector.PseudoClass(PseudoSelectorPrefix.PseudoIndeterminate);
+
+ case PseudoSelectorPrefix.PseudoUnchecked:
+ return SimpleSelector.PseudoClass(PseudoSelectorPrefix.PseudoUnchecked);
+
+ case PseudoSelectorPrefix.PseudoValid:
+ return SimpleSelector.PseudoClass(PseudoSelectorPrefix.PseudoValid);
+
+ case PseudoSelectorPrefix.PseudoInvalid:
+ return SimpleSelector.PseudoClass(PseudoSelectorPrefix.PseudoInvalid);
+
+ case PseudoSelectorPrefix.PseudoRequired:
+ return SimpleSelector.PseudoClass(PseudoSelectorPrefix.PseudoRequired);
+
+ case PseudoSelectorPrefix.PseudoReadonly:
+ return SimpleSelector.PseudoClass(PseudoSelectorPrefix.PseudoReadonly);
+
+ case PseudoSelectorPrefix.PseudoReadwrite:
+ return SimpleSelector.PseudoClass(PseudoSelectorPrefix.PseudoReadwrite);
+
+ case PseudoSelectorPrefix.PseudoInrange:
+ return SimpleSelector.PseudoClass(PseudoSelectorPrefix.PseudoInrange);
+
+ case PseudoSelectorPrefix.PseudoOutofrange:
+ return SimpleSelector.PseudoClass(PseudoSelectorPrefix.PseudoOutofrange);
+
+ case PseudoSelectorPrefix.PseudoOptional:
+ return SimpleSelector.PseudoClass(PseudoSelectorPrefix.PseudoOptional);
+
+ case PseudoSelectorPrefix.PseudoElementBefore:
+ return SimpleSelector.PseudoClass(PseudoSelectorPrefix.PseudoElementBefore);
+
+ case PseudoSelectorPrefix.PseudoElementAfter:
+ return SimpleSelector.PseudoClass(PseudoSelectorPrefix.PseudoElementAfter);
+
+ case PseudoSelectorPrefix.PseudoElementFirstline:
+ return SimpleSelector.PseudoClass(PseudoSelectorPrefix.PseudoElementFirstline);
+
+ case PseudoSelectorPrefix.PseudoElementFirstletter:
+ return SimpleSelector.PseudoClass(PseudoSelectorPrefix.PseudoElementFirstletter);
+
+ default:
+ return SimpleSelector.PseudoClass(token.ToString());
+ }
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Model/Selector/SelectorList.cs b/Source/External/ExCSS/Model/Selector/SelectorList.cs
new file mode 100644
index 0000000000000000000000000000000000000000..dc9b7f204ba8d06a495f3d556357d95745ca8ce0
--- /dev/null
+++ b/Source/External/ExCSS/Model/Selector/SelectorList.cs
@@ -0,0 +1,57 @@
+using System.Collections;
+using System.Collections.Generic;
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ public abstract class SelectorList : BaseSelector, IEnumerable
+ {
+ protected List Selectors;
+
+ protected SelectorList()
+ {
+ Selectors = new List();
+ }
+
+ public int Length
+ {
+ get { return Selectors.Count; }
+ }
+
+ public BaseSelector this[int index]
+ {
+ get { return Selectors[index]; }
+ set { Selectors[index] = value; }
+ }
+
+ public SelectorList AppendSelector(BaseSelector selector)
+ {
+ Selectors.Add(selector);
+ return this;
+ }
+
+ public SelectorList RemoveSelector(SimpleSelector selector)
+ {
+ Selectors.Remove(selector);
+ return this;
+ }
+
+ public SelectorList ClearSelectors()
+ {
+ Selectors.Clear();
+ return this;
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ return Selectors.GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return ((IEnumerable)Selectors).GetEnumerator();
+ }
+
+ public override abstract string ToString(bool friendlyFormat, int indentation = 0);
+ }
+}
diff --git a/Source/External/ExCSS/Model/Selector/SimpleSelector.cs b/Source/External/ExCSS/Model/Selector/SimpleSelector.cs
new file mode 100644
index 0000000000000000000000000000000000000000..0fc2f29d3c27a5079189b516956ff290cdc7767f
--- /dev/null
+++ b/Source/External/ExCSS/Model/Selector/SimpleSelector.cs
@@ -0,0 +1,126 @@
+using System;
+using ExCSS.Model;
+// ReSharper disable once CheckNamespace
+
+namespace ExCSS
+{
+ public sealed class SimpleSelector : BaseSelector
+ {
+ private readonly string _code;
+ internal static readonly SimpleSelector All = new SimpleSelector("*");
+
+ public SimpleSelector(string selectorText)
+ {
+ _code = selectorText;
+ }
+
+ internal static SimpleSelector PseudoElement(string pseudoElement)
+ {
+ return new SimpleSelector("::" + pseudoElement);
+ }
+
+ internal static SimpleSelector PseudoClass(string pseudoClass)
+ {
+ return new SimpleSelector(":" + pseudoClass);
+ }
+
+ internal static SimpleSelector Class(string match)
+ {
+ return new SimpleSelector("." + match);
+ }
+
+ internal static SimpleSelector Id(string match)
+ {
+ return new SimpleSelector("#" + match);
+ }
+
+ internal static SimpleSelector AttributeUnmatched(string match)
+ {
+ return new SimpleSelector("[" + match + "]");
+ }
+
+ internal static SimpleSelector AttributeMatch(string match, string value)
+ {
+ var code = string.Format("[{0}=\"{1}\"]", match, GetValueAsString(value));
+ return new SimpleSelector(code);
+ }
+
+ internal static SimpleSelector AttributeNegatedMatch(string match, string value)
+ {
+ var code = string.Format("[{0}!=\"{1}\"]", match, GetValueAsString(value));
+ return new SimpleSelector(code);
+ }
+
+ internal static SimpleSelector AttributeSpaceSeparated(string match, string value)
+ {
+ var code = string.Format("[{0}~=\"{1}\"]", match, GetValueAsString(value));
+
+ return new SimpleSelector(code);
+ }
+
+ internal static SimpleSelector AttributeStartsWith(string match, string value)
+ {
+ var code = string.Format("[{0}^=\"{1}\"]", match, GetValueAsString(value));
+
+ return new SimpleSelector(code);
+ }
+
+ internal static SimpleSelector AttributeEndsWith(string match, string value)
+ {
+ var code = string.Format("[{0}$=\"{1}\"]", match, GetValueAsString(value));
+
+ return new SimpleSelector(code);
+ }
+
+ internal static SimpleSelector AttributeContains(string match, string value)
+ {
+ var code = string.Format("[{0}*=\"{1}\"]", match, GetValueAsString(value));
+
+ return new SimpleSelector(code);
+ }
+
+ internal static SimpleSelector AttributeDashSeparated(string match, string value)
+ {
+ var code = string.Format("[{0}|=\"{1}\"]", match, GetValueAsString(value));
+
+ return new SimpleSelector(code);
+ }
+
+ internal static SimpleSelector Type(string match)
+ {
+ return new SimpleSelector(match);
+ }
+
+ private static string GetValueAsString(string value)
+ {
+ var containsSpace = false;
+
+ for (var i = 0; i < value.Length; i++)
+ {
+ if (!value[i].IsSpaceCharacter())
+ {
+ continue;
+ }
+ containsSpace = true;
+ break;
+ }
+
+ if (!containsSpace)
+ {
+ return value;
+ }
+
+ if (value.IndexOf(Specification.SingleQuote) != -1)
+ {
+ return '"' + value + '"';
+ }
+
+ return "'" + value + "'";
+ }
+
+ public override string ToString(bool friendlyFormat, int indentation = 0)
+ {
+ return _code;
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Model/Specification.cs b/Source/External/ExCSS/Model/Specification.cs
new file mode 100644
index 0000000000000000000000000000000000000000..2da18d370ddaa2c3b2fbc6cf5027357dd9acaffb
--- /dev/null
+++ b/Source/External/ExCSS/Model/Specification.cs
@@ -0,0 +1,98 @@
+namespace ExCSS.Model
+{
+ internal static class Specification
+ {
+ internal const char EndOfFile = (char)0x1a;
+ internal const char Tilde = (char)0x7e;
+ internal const char Pipe = (char)0x7c;
+ internal const char Null = (char)0x0;
+ internal const char Ampersand = (char)0x26;
+ internal const char Hash = (char)0x23;
+ internal const char DollarSign = (char)0x24;
+ internal const char Simicolon = (char)0x3b;
+ internal const char Asterisk = (char)0x2a;
+ internal const char EqualSign = (char)0x3d;
+ internal const char PlusSign = (char)0x2b;
+ internal const char Comma = (char)0x2c;
+ internal const char Period = (char)0x2e;
+ internal const char Accent = (char)0x5e;
+ internal const char At = (char)0x40;
+ internal const char LessThan = (char)0x3c;
+ internal const char GreaterThan = (char)0x3e;
+ internal const char SingleQuote = (char)0x27;
+ internal const char DoubleQuote = (char)0x22;
+ internal const char QuestionMark = (char)0x3f;
+ internal const char Tab = (char)0x09;
+ internal const char LineFeed = (char)0x0a;
+ internal const char CarriageReturn = (char)0x0d;
+ internal const char FormFeed = (char)0x0c;
+ internal const char Space = (char)0x20;
+ internal const char Solidus = (char)0x2f;
+ internal const char ReverseSolidus = (char)0x5c;
+ internal const char Colon = (char)0x3a;
+ internal const char Em = (char)0x21;
+ internal const char MinusSign = (char)0x2d;
+ internal const char Replacement = (char)0xfffd;
+ internal const char Underscore = (char)0x5f;
+ internal const char ParenOpen = (char)0x28;
+ internal const char ParenClose = (char)0x29;
+ internal const char Percent = (char)0x25;
+ internal const char SquareBracketOpen =(char)0x5b;
+ internal const char SquareBracketClose = (char)0x5d;
+ internal const char CurlyBraceOpen = (char)0x7b;
+ internal const char CurlyBraceClose = (char)0x7d;
+ internal const int MaxPoint = 0x10FFFF;/// The maximum allowed codepoint (defined in Unicode).
+
+ internal static bool IsNonPrintable(this char c)
+ {
+ return (c >= 0x0 && c <= 0x8) || (c >= 0xe && c <= 0x1f) || (c >= 0x7f && c <= 0x9f);
+ }
+
+ internal static bool IsLetter(this char c)
+ {
+ return IsUppercaseAscii(c) || IsLowercaseAscii(c);
+ }
+
+ internal static bool IsName(this char c)
+ {
+ return c >= 0x80 || c.IsLetter() || c == Underscore || c == MinusSign || IsDigit(c);
+ }
+
+ internal static bool IsNameStart(this char c)
+ {
+ return c >= 0x80 || IsUppercaseAscii(c) || IsLowercaseAscii(c) || c == Underscore;
+ }
+
+ internal static bool IsLineBreak(this char c)
+ {
+ //line feed, carriage return
+ return c == LineFeed || c == CarriageReturn;
+ }
+
+ internal static bool IsSpaceCharacter(this char c)
+ {
+ //white space, tab, line feed, form feed, carriage return
+ return c == Space || c == Tab || c == LineFeed || c == FormFeed || c == CarriageReturn;
+ }
+
+ internal static bool IsDigit(this char c)
+ {
+ return c >= 0x30 && c <= 0x39;
+ }
+
+ internal static bool IsUppercaseAscii(this char c)
+ {
+ return c >= 0x41 && c <= 0x5a;
+ }
+
+ internal static bool IsLowercaseAscii(this char c)
+ {
+ return c >= 0x61 && c <= 0x7a;
+ }
+
+ internal static bool IsHex(this char c)
+ {
+ return IsDigit(c) || (c >= 0x41 && c <= 0x46) || (c >= 0x61 && c <= 0x66);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/External/ExCSS/Model/TextBlocks/Block.cs b/Source/External/ExCSS/Model/TextBlocks/Block.cs
new file mode 100644
index 0000000000000000000000000000000000000000..16f02dc80eb98ec759b3f1c70203c022366b4581
--- /dev/null
+++ b/Source/External/ExCSS/Model/TextBlocks/Block.cs
@@ -0,0 +1,28 @@
+
+namespace ExCSS.Model.TextBlocks
+{
+ internal abstract class Block
+ {
+ internal GrammarSegment GrammarSegment { get;set; }
+
+ internal static PipeBlock Column
+ {
+ get { return PipeBlock.Token; }
+ }
+
+ internal static DelimiterBlock Delim(char value)
+ {
+ return new DelimiterBlock(value);
+ }
+
+ internal static NumericBlock Number(string value)
+ {
+ return new NumericBlock(value);
+ }
+
+ internal static RangeBlock Range(string start, string end)
+ {
+ return new RangeBlock().SetRange(start, end);
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Model/TextBlocks/BracketBlock.cs b/Source/External/ExCSS/Model/TextBlocks/BracketBlock.cs
new file mode 100644
index 0000000000000000000000000000000000000000..5de795bd3fdada2390fee7511f0879b6973ff5a3
--- /dev/null
+++ b/Source/External/ExCSS/Model/TextBlocks/BracketBlock.cs
@@ -0,0 +1,123 @@
+
+namespace ExCSS.Model.TextBlocks
+{
+ internal class BracketBlock : Block
+ {
+ private readonly static BracketBlock RoundOpen= new BracketBlock { GrammarSegment = GrammarSegment.ParenOpen, _mirror = GrammarSegment.ParenClose };
+ private readonly static BracketBlock RoundClose = new BracketBlock { GrammarSegment = GrammarSegment.ParenClose, _mirror = GrammarSegment.ParenOpen };
+ private readonly static BracketBlock CurlyOpen = new BracketBlock { GrammarSegment = GrammarSegment.CurlyBraceOpen, _mirror = GrammarSegment.CurlyBracketClose };
+ private readonly static BracketBlock CurlyClose = new BracketBlock { GrammarSegment = GrammarSegment.CurlyBracketClose, _mirror = GrammarSegment.CurlyBraceOpen };
+ private readonly static BracketBlock SquareOpen = new BracketBlock { GrammarSegment = GrammarSegment.SquareBraceOpen, _mirror = GrammarSegment.SquareBracketClose };
+ private readonly static BracketBlock SquareClose = new BracketBlock { GrammarSegment = GrammarSegment.SquareBracketClose, _mirror = GrammarSegment.SquareBraceOpen };
+
+ private GrammarSegment _mirror;
+
+ BracketBlock()
+ {
+ }
+
+ internal char Open
+ {
+ get
+ {
+ switch (GrammarSegment)
+ {
+ case GrammarSegment.ParenOpen:
+ return '(';
+
+ case GrammarSegment.SquareBraceOpen:
+ return '[';
+
+ default:
+ return '{';
+
+ }
+ }
+ }
+
+ internal char Close
+ {
+ get
+ {
+ switch (GrammarSegment)
+ {
+ case GrammarSegment.ParenOpen:
+ return ')';
+
+ case GrammarSegment.SquareBraceOpen:
+ return ']';
+
+ default:
+ return '}';
+
+ }
+ }
+ }
+
+ internal GrammarSegment Mirror
+ {
+ get { return _mirror; }
+ }
+
+ internal static BracketBlock OpenRound
+ {
+ get { return RoundOpen; }
+ }
+
+ internal static BracketBlock CloseRound
+ {
+ get { return RoundClose; }
+ }
+
+ internal static BracketBlock OpenCurly
+ {
+ get { return CurlyOpen; }
+ }
+
+ internal static BracketBlock CloseCurly
+ {
+ get { return CurlyClose; }
+ }
+
+ internal static BracketBlock OpenSquare
+ {
+ get { return SquareOpen; }
+ }
+
+ internal static BracketBlock CloseSquare
+ {
+ get { return SquareClose; }
+ }
+
+ public override string ToString()
+ {
+ return ToString(false);
+ }
+
+ public string ToString(bool friendlyFormat, int indentation = 0)
+ {
+ switch (GrammarSegment)
+ {
+ case GrammarSegment.CurlyBraceOpen:
+ return "{";
+
+ case GrammarSegment.CurlyBracketClose:
+ return "}";
+
+ case GrammarSegment.ParenClose:
+ return ")";
+
+ case GrammarSegment.ParenOpen:
+ return "(";
+
+ case GrammarSegment.SquareBracketClose:
+ return "]";
+
+ case GrammarSegment.SquareBraceOpen:
+ return "[";
+ }
+
+ return string.Empty;
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Model/TextBlocks/CharacterBlock.cs b/Source/External/ExCSS/Model/TextBlocks/CharacterBlock.cs
new file mode 100644
index 0000000000000000000000000000000000000000..f5c44731402053688a41771144b036f32484d814
--- /dev/null
+++ b/Source/External/ExCSS/Model/TextBlocks/CharacterBlock.cs
@@ -0,0 +1,23 @@
+
+namespace ExCSS.Model.TextBlocks
+{
+ internal abstract class CharacterBlock : Block
+ {
+ private readonly char _value;
+
+ protected CharacterBlock()
+ {
+ _value = Specification.Null;
+ }
+
+ protected CharacterBlock(char value)
+ {
+ _value = value;
+ }
+
+ internal char Value
+ {
+ get { return _value; }
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Model/TextBlocks/CommentBlock.cs b/Source/External/ExCSS/Model/TextBlocks/CommentBlock.cs
new file mode 100644
index 0000000000000000000000000000000000000000..a9fe661622bb65940d7218d5c81bcbdff94a0fc0
--- /dev/null
+++ b/Source/External/ExCSS/Model/TextBlocks/CommentBlock.cs
@@ -0,0 +1,35 @@
+
+namespace ExCSS.Model.TextBlocks
+{
+ internal class CommentBlock : Block
+ {
+ private readonly static CommentBlock OpenBlock;
+ private readonly static CommentBlock CloseBlock;
+
+ static CommentBlock()
+ {
+ OpenBlock = new CommentBlock { GrammarSegment = GrammarSegment.CommentOpen };
+ CloseBlock = new CommentBlock { GrammarSegment = GrammarSegment.CommentClose };
+ }
+
+ CommentBlock()
+ {
+ }
+
+
+ internal static CommentBlock Open
+ {
+ get { return OpenBlock; }
+ }
+
+ internal static CommentBlock Close
+ {
+ get { return CloseBlock; }
+ }
+
+ public override string ToString()
+ {
+ return GrammarSegment == GrammarSegment.CommentOpen ? "";
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Model/TextBlocks/DelimiterBlock.cs b/Source/External/ExCSS/Model/TextBlocks/DelimiterBlock.cs
new file mode 100644
index 0000000000000000000000000000000000000000..6e14f444ee2a42349ba8c8ad6c0829d12ad4d5a1
--- /dev/null
+++ b/Source/External/ExCSS/Model/TextBlocks/DelimiterBlock.cs
@@ -0,0 +1,23 @@
+
+using System.Globalization;
+
+namespace ExCSS.Model.TextBlocks
+{
+ internal class DelimiterBlock : CharacterBlock
+ {
+ internal DelimiterBlock()
+ {
+ GrammarSegment = GrammarSegment.Delimiter;
+ }
+
+ internal DelimiterBlock(char value) : base(value)
+ {
+ GrammarSegment = GrammarSegment.Delimiter;
+ }
+
+ public override string ToString()
+ {
+ return Value.ToString(CultureInfo.InvariantCulture);
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Model/TextBlocks/MatchBlock.cs b/Source/External/ExCSS/Model/TextBlocks/MatchBlock.cs
new file mode 100644
index 0000000000000000000000000000000000000000..eb334c067a31fe01f28bcf9d40affd63d5a44599
--- /dev/null
+++ b/Source/External/ExCSS/Model/TextBlocks/MatchBlock.cs
@@ -0,0 +1,39 @@
+
+namespace ExCSS.Model.TextBlocks
+{
+ internal class MatchBlock : Block
+ {
+ internal readonly static MatchBlock Include = new MatchBlock { GrammarSegment = GrammarSegment.IncludeMatch };
+ internal readonly static MatchBlock Dash = new MatchBlock { GrammarSegment = GrammarSegment.DashMatch };
+ internal readonly static Block Prefix = new MatchBlock { GrammarSegment = GrammarSegment.PrefixMatch };
+ internal readonly static Block Substring = new MatchBlock { GrammarSegment = GrammarSegment.SubstringMatch };
+ internal readonly static Block Suffix = new MatchBlock { GrammarSegment = GrammarSegment.SuffixMatch };
+ internal readonly static Block Not = new MatchBlock { GrammarSegment = GrammarSegment.NegationMatch };
+
+ public override string ToString()
+ {
+ switch (GrammarSegment)
+ {
+ case GrammarSegment.SubstringMatch:
+ return "*=";
+
+ case GrammarSegment.SuffixMatch:
+ return "$=";
+
+ case GrammarSegment.PrefixMatch:
+ return "^=";
+
+ case GrammarSegment.IncludeMatch:
+ return "~=";
+
+ case GrammarSegment.DashMatch:
+ return "|=";
+
+ case GrammarSegment.NegationMatch:
+ return "!=";
+ }
+
+ return string.Empty;
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Model/TextBlocks/NumericBlock.cs b/Source/External/ExCSS/Model/TextBlocks/NumericBlock.cs
new file mode 100644
index 0000000000000000000000000000000000000000..facab18ea5e2c17aaa203085b37aa891a6509981
--- /dev/null
+++ b/Source/External/ExCSS/Model/TextBlocks/NumericBlock.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Globalization;
+
+namespace ExCSS.Model.TextBlocks
+{
+ internal class NumericBlock : Block
+ {
+ private readonly string _data;
+
+ internal NumericBlock(string number)
+ {
+ _data = number;
+ GrammarSegment = GrammarSegment.Number;
+ }
+
+ public Single Value
+ {
+ get { return Single.Parse(_data, CultureInfo.InvariantCulture); }
+ }
+
+ public override string ToString()
+ {
+ return _data;
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Model/TextBlocks/PipeBlock.cs b/Source/External/ExCSS/Model/TextBlocks/PipeBlock.cs
new file mode 100644
index 0000000000000000000000000000000000000000..8beefed39e73a190eb6829e39817e783598e1ffc
--- /dev/null
+++ b/Source/External/ExCSS/Model/TextBlocks/PipeBlock.cs
@@ -0,0 +1,28 @@
+
+namespace ExCSS.Model.TextBlocks
+{
+ internal class PipeBlock : Block
+ {
+ private readonly static PipeBlock TokenBlock;
+
+ static PipeBlock()
+ {
+ TokenBlock = new PipeBlock();
+ }
+
+ PipeBlock()
+ {
+ GrammarSegment = GrammarSegment.Column;
+ }
+
+ internal static PipeBlock Token
+ {
+ get { return TokenBlock; }
+ }
+
+ public override string ToString()
+ {
+ return "||";
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Model/TextBlocks/RangeBlock.cs b/Source/External/ExCSS/Model/TextBlocks/RangeBlock.cs
new file mode 100644
index 0000000000000000000000000000000000000000..56471cb18f6f58ccfe9d5bb47b728224348b8efb
--- /dev/null
+++ b/Source/External/ExCSS/Model/TextBlocks/RangeBlock.cs
@@ -0,0 +1,69 @@
+using System.Collections.Generic;
+
+namespace ExCSS.Model.TextBlocks
+{
+ internal class RangeBlock : Block
+ {
+ public RangeBlock()
+ {
+ GrammarSegment = GrammarSegment.Range;
+ }
+
+ internal bool IsEmpty
+ {
+ get { return SelectedRange == null || SelectedRange.Length == 0; }
+ }
+
+ internal string[] SelectedRange { get; private set; }
+
+ internal RangeBlock SetRange(string start, string end)
+ {
+ var startValue = int.Parse(start, System.Globalization.NumberStyles.HexNumber);
+
+ if (startValue > Specification.MaxPoint)
+ {
+ return this;
+ }
+
+ if (end == null)
+ {
+ SelectedRange = new [] { char.ConvertFromUtf32(startValue) };
+ }
+ else
+ {
+ var list = new List();
+ var endValue = int.Parse(end, System.Globalization.NumberStyles.HexNumber);
+
+ if (endValue > Specification.MaxPoint)
+ {
+ endValue = Specification.MaxPoint;
+ }
+
+ for (; startValue <= endValue; startValue++)
+ {
+ list.Add(char.ConvertFromUtf32(startValue));
+ }
+
+ SelectedRange = list.ToArray();
+ }
+
+ return this;
+ }
+
+ public override string ToString()
+ {
+ if (IsEmpty)
+ {
+ return string.Empty;
+ }
+
+ if (SelectedRange.Length == 1)
+ {
+ return "#" + char.ConvertToUtf32(SelectedRange[0], 0).ToString("x");
+ }
+
+ return "#" + char.ConvertToUtf32(SelectedRange[0], 0).ToString("x") + "-#" +
+ char.ConvertToUtf32(SelectedRange[SelectedRange.Length - 1], 0).ToString("x");
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Model/TextBlocks/SpecialCharacter.cs b/Source/External/ExCSS/Model/TextBlocks/SpecialCharacter.cs
new file mode 100644
index 0000000000000000000000000000000000000000..48fd9a2edeabb463a2614c37a39f4978336bba00
--- /dev/null
+++ b/Source/External/ExCSS/Model/TextBlocks/SpecialCharacter.cs
@@ -0,0 +1,21 @@
+
+namespace ExCSS.Model.TextBlocks
+{
+ internal class SpecialCharacter : CharacterBlock
+ {
+ internal static readonly SpecialCharacter Colon = new SpecialCharacter(Specification.Colon, GrammarSegment.Colon);
+ internal static readonly SpecialCharacter Comma = new SpecialCharacter(Specification.Comma, GrammarSegment.Comma);
+ internal static readonly SpecialCharacter Semicolon = new SpecialCharacter(Specification.Simicolon, GrammarSegment.Semicolon);
+ internal static readonly SpecialCharacter Whitespace = new SpecialCharacter(Specification.Space, GrammarSegment.Whitespace);
+
+ SpecialCharacter(char specialCharacter, GrammarSegment type) : base(specialCharacter)
+ {
+ GrammarSegment = type;
+ }
+
+ public override string ToString()
+ {
+ return Value.ToString();
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Model/TextBlocks/StringBlock.cs b/Source/External/ExCSS/Model/TextBlocks/StringBlock.cs
new file mode 100644
index 0000000000000000000000000000000000000000..cce8390b64d345431ac7c38d2401f41d227c8362
--- /dev/null
+++ b/Source/External/ExCSS/Model/TextBlocks/StringBlock.cs
@@ -0,0 +1,35 @@
+
+namespace ExCSS.Model.TextBlocks
+{
+ internal class StringBlock : Block
+ {
+ StringBlock(GrammarSegment type)
+ {
+ GrammarSegment = type;
+ }
+
+ internal static StringBlock Plain(string data, bool bad = false)
+ {
+ return new StringBlock(GrammarSegment.String) { Value = data, IsBad = bad };
+ }
+
+ internal static StringBlock Url(string data, bool bad = false)
+ {
+ return new StringBlock(GrammarSegment.Url) { Value = data, IsBad = bad };
+ }
+
+ internal string Value { get; private set; }
+
+ internal bool IsBad { get; private set; }
+
+ public override string ToString()
+ {
+ if (GrammarSegment == GrammarSegment.Url)
+ {
+ return "url(" + Value + ")";
+ }
+
+ return "'" + Value + "'";
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Model/TextBlocks/SymbolBlock.cs b/Source/External/ExCSS/Model/TextBlocks/SymbolBlock.cs
new file mode 100644
index 0000000000000000000000000000000000000000..f2c9024756adcffa2aaf12321d21440d18d1e28f
--- /dev/null
+++ b/Source/External/ExCSS/Model/TextBlocks/SymbolBlock.cs
@@ -0,0 +1,47 @@
+
+namespace ExCSS.Model.TextBlocks
+{
+ internal class SymbolBlock : Block
+ {
+ SymbolBlock(GrammarSegment type)
+ {
+ GrammarSegment = type;
+ }
+
+ internal static SymbolBlock Function(string name)
+ {
+ return new SymbolBlock(GrammarSegment.Function) { Value = name };
+ }
+
+ internal static SymbolBlock Ident(string identifier)
+ {
+ return new SymbolBlock(GrammarSegment.Ident) { Value = identifier };
+ }
+
+ internal static SymbolBlock At(string name)
+ {
+ return new SymbolBlock(GrammarSegment.AtRule) { Value = name };
+ }
+
+ internal static SymbolBlock Hash(string characters)
+ {
+ return new SymbolBlock(GrammarSegment.Hash) { Value = characters };
+ }
+
+ internal string Value { get; private set; }
+
+ public override string ToString()
+ {
+ switch (GrammarSegment)
+ {
+ case GrammarSegment.Hash:
+ return "#" + Value;
+
+ case GrammarSegment.AtRule:
+ return "@" + Value;
+ }
+
+ return Value;
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Model/TextBlocks/UnitBlock.cs b/Source/External/ExCSS/Model/TextBlocks/UnitBlock.cs
new file mode 100644
index 0000000000000000000000000000000000000000..2a21858c4edf1680a1df22190bee8b285fbd53b9
--- /dev/null
+++ b/Source/External/ExCSS/Model/TextBlocks/UnitBlock.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Globalization;
+
+namespace ExCSS.Model.TextBlocks
+{
+ internal class UnitBlock : Block
+ {
+ private string _value;
+
+ UnitBlock(GrammarSegment type)
+ {
+ GrammarSegment = type;
+ }
+
+ internal Single Value
+ {
+ get { return Single.Parse(_value, CultureInfo.InvariantCulture); }
+ }
+
+ internal string Unit { get; private set; }
+
+ internal static UnitBlock Percentage(string value)
+ {
+ return new UnitBlock(GrammarSegment.Percentage) { _value = value, Unit = "%" };
+ }
+
+ internal static UnitBlock Dimension(string value, string dimension)
+ {
+ return new UnitBlock(GrammarSegment.Dimension) { _value = value, Unit = dimension };
+ }
+
+ public override string ToString()
+ {
+ return _value + Unit;
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Model/Values/GenericFunction.cs b/Source/External/ExCSS/Model/Values/GenericFunction.cs
new file mode 100644
index 0000000000000000000000000000000000000000..6f5ce1a4c46c3e8469161c1b4943f05f6a2d53d5
--- /dev/null
+++ b/Source/External/ExCSS/Model/Values/GenericFunction.cs
@@ -0,0 +1,33 @@
+using System.Collections.Generic;
+using System.Text;
+using ExCSS.Model;
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ public class GenericFunction : Term
+ {
+ public string Name { get; set; }
+ public TermList Arguments { get; set; }
+
+ public GenericFunction(string name, List arguments)
+ {
+ this.Name = name;
+
+ var list = new TermList();
+ for (int n = 0; n < arguments.Count; n++)
+ {
+ list.AddTerm(arguments[n]);
+ if (n == arguments.Count - 1)
+ break;
+ list.AddSeparator(GrammarSegment.Comma);
+ }
+ this.Arguments = list;
+ }
+
+ public override string ToString()
+ {
+ return Name + "(" + Arguments + ")";
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/External/ExCSS/Model/Values/HtmlColor.cs b/Source/External/ExCSS/Model/Values/HtmlColor.cs
new file mode 100644
index 0000000000000000000000000000000000000000..32d50df1e7426bde0e1bb5d93ce3d7298e8d3049
--- /dev/null
+++ b/Source/External/ExCSS/Model/Values/HtmlColor.cs
@@ -0,0 +1,252 @@
+using System;
+using System.Runtime.InteropServices;
+using ExCSS.Model;
+using ExCSS.Model.Extensions;
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ public class HtmlColor : Term, IEquatable
+ {
+ public byte A;
+ public byte R;
+ public byte G;
+ public byte B;
+
+ public HtmlColor(byte r, byte g, byte b)
+ {
+ A = 255;
+ R = r;
+ B = b;
+ G = g;
+ }
+
+ public HtmlColor(byte a, byte r, byte g, byte b)
+ {
+ A = a;
+ R = r;
+ B = b;
+ G = g;
+ }
+
+ public HtmlColor(Double a, byte r, byte g, byte b)
+ {
+ A = (byte)Math.Max(Math.Min(Math.Ceiling(255 * a), 255), 0);
+ R = r;
+ B = b;
+ G = g;
+ }
+
+ public static HtmlColor FromRgba(byte r, byte g, byte b, Single a)
+ {
+ return new HtmlColor(a, r, g, b);
+ }
+
+ public static HtmlColor FromRgba(byte r, byte g, byte b, Double a)
+ {
+ return new HtmlColor(a, r, g, b);
+ }
+
+ public static HtmlColor FromRgb(byte r, byte g, byte b)
+ {
+ return new HtmlColor(r, g, b);
+ }
+
+ public static HtmlColor FromHsl(Single h, Single s, Single l)
+ {
+ const Single third = 1f / 3f;
+
+ var m2 = l <= 0.5f ? (l * (s + 1f)) : (l + s - l * s);
+ var m1 = 2f * l - m2;
+ var r = (Byte)Math.Round(255 * HueToRgb(m1, m2, h + third));
+ var g = (Byte)Math.Round(255 * HueToRgb(m1, m2, h));
+ var b = (Byte)Math.Round(255 * HueToRgb(m1, m2, h - third));
+ return new HtmlColor(r, g, b);
+ }
+
+ public static HtmlColor FromHex(string color)
+ {
+ if (color.Length == 3)
+ {
+ var r = color[0].FromHex();
+ r += r * 16;
+
+ var g = color[1].FromHex();
+ g += g * 16;
+
+ var b = color[2].FromHex();
+ b += b * 16;
+
+ return new HtmlColor((byte)r, (byte)g, (byte)b);
+ }
+
+ if (color.Length == 6)
+ {
+ var r = 16 * color[0].FromHex();
+ var g = 16 * color[2].FromHex();
+ var b = 16 * color[4].FromHex();
+
+ r += color[1].FromHex();
+ g += color[3].FromHex();
+ b += color[5].FromHex();
+
+ return new HtmlColor((byte)r, (byte)g, (byte)b);
+ }
+
+ throw new ArgumentException("Invalid color code length: " + color, "color");
+ }
+
+ public static bool TryFromHex(string color, out HtmlColor htmlColor)
+ {
+ htmlColor = new HtmlColor(255, 0, 0, 0);
+
+ if (color.Length == 3)
+ {
+ if (!color[0].IsHex() || !color[1].IsHex() || !color[2].IsHex())
+ {
+ return false;
+ }
+
+ var r = color[0].FromHex();
+ r += r * 16;
+
+ var g = color[1].FromHex();
+ g += g * 16;
+
+ var b = color[2].FromHex();
+ b += b * 16;
+
+ htmlColor.R = (byte)r;
+ htmlColor.G = (byte)g;
+ htmlColor.B = (byte)b;
+
+ return true;
+ }
+
+ if (color.Length == 6)
+ {
+ if (!color[0].IsHex() || !color[1].IsHex() || !color[2].IsHex() ||
+ !color[3].IsHex() || !color[4].IsHex() || !color[5].IsHex())
+ {
+ return false;
+ }
+
+ var r = 16 * color[0].FromHex();
+ var g = 16 * color[2].FromHex();
+ var b = 16 * color[4].FromHex();
+
+ r += color[1].FromHex();
+ g += color[3].FromHex();
+ b += color[5].FromHex();
+
+ htmlColor.R = (byte)r;
+ htmlColor.G = (byte)g;
+ htmlColor.B = (byte)b;
+
+ return true;
+ }
+
+ return false;
+ }
+
+ public double Alpha
+ {
+ get { return A / 255.0; }
+ }
+
+ public static bool operator ==(HtmlColor a, HtmlColor b)
+ {
+ return a.GetHashCode() == b.GetHashCode();
+ }
+
+ public static bool operator !=(HtmlColor a, HtmlColor b)
+ {
+ return a.GetHashCode() != b.GetHashCode();
+ }
+
+ public override bool Equals(Object obj)
+ {
+ if (obj is HtmlColor)
+ {
+ return Equals((HtmlColor)obj);
+ }
+
+ return false;
+ }
+
+ public override int GetHashCode()
+ {
+ return unchecked(A + (R << 8) + (G << 16) + (B << 24));
+ }
+
+ public override string ToString()
+ {
+ return ToString(false);
+ }
+
+ public string ToString(bool friendlyFormat, int indentation = 0)
+ {
+ return ToCss().Indent(friendlyFormat, indentation);
+ }
+
+ public string ToString(bool forceLong, bool friendlyFormat, int indentation = 0)
+ {
+ return ToCss(forceLong).Indent(friendlyFormat, indentation);
+ }
+
+ ///
+ /// Return the shortest form possible
+ ///
+ string ToCss(bool forceLong = false)
+ {
+ if (A == 255 && !forceLong && ((R >> 4) == (R & 0x0F)) && ((G >> 4) == (G & 0x0F)) && ((B >> 4) == (B & 0x0F)))
+ return "#" + R.ToHexChar() + G.ToHexChar() + B.ToHexChar();
+
+ if (A == 255)
+ {
+ return "#" + R.ToHex() + G.ToHex() + B.ToHex();
+ //return "rgb(" + R + ", " + G + ", " + B + ")";
+ }
+
+ return "rgba(" + R + ", " + G + ", " + B + ", " + Alpha.ToString("0.##") + ")";
+ }
+
+ public bool Equals(HtmlColor other)
+ {
+ HtmlColor o = other as HtmlColor;
+ if (o == null)
+ return false;
+ return GetHashCode() == other.GetHashCode();
+ }
+
+ private static Single HueToRgb(Single m1, Single m2, Single h)
+ {
+ const Single sixth = 1f / 6f;
+ const Single third2 = 2f / 3f;
+
+ if (h < 0f)
+ {
+ h += 1f;
+ }
+ else if (h > 1f)
+ {
+ h -= 1f;
+ }
+
+ if (h < sixth)
+ {
+ return m1 + (m2 - m1) * h * 6f;
+ }
+ if (h < 0.5)
+ {
+ return m2;
+ }
+ if (h < third2)
+ {
+ return m1 + (m2 - m1) * (third2 - h) * 6f;
+ }
+
+ return m1;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/External/ExCSS/Model/Values/InheritTerm.cs b/Source/External/ExCSS/Model/Values/InheritTerm.cs
new file mode 100644
index 0000000000000000000000000000000000000000..c39c02334d47c0c33c35c206256560d413250f99
--- /dev/null
+++ b/Source/External/ExCSS/Model/Values/InheritTerm.cs
@@ -0,0 +1,17 @@
+using System;
+
+namespace ExCSS
+{
+ public class InheritTerm : Term
+ {
+ internal InheritTerm()
+ {
+ }
+
+ public override string ToString()
+ {
+ return "inherit";
+ }
+ }
+}
+
diff --git a/Source/External/ExCSS/Model/Values/PrimitiveTerm.cs b/Source/External/ExCSS/Model/Values/PrimitiveTerm.cs
new file mode 100644
index 0000000000000000000000000000000000000000..332e57b8ddc0a2af49aef9d46ad69471c22810d6
--- /dev/null
+++ b/Source/External/ExCSS/Model/Values/PrimitiveTerm.cs
@@ -0,0 +1,169 @@
+using System;
+using System.Globalization;
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ public class PrimitiveTerm : Term
+ {
+ public object Value { get; set; }
+ public UnitType PrimitiveType { get; set; }
+
+ public PrimitiveTerm(UnitType unitType, string value)
+ {
+ PrimitiveType = unitType;
+ Value = value;
+ }
+
+ public PrimitiveTerm(UnitType unitType, Single value)
+ {
+ PrimitiveType = unitType;
+ Value = value;
+ }
+
+ public PrimitiveTerm(string unit, Single value)
+ {
+ PrimitiveType = ConvertStringToUnitType(unit);;
+ Value = value;
+ }
+
+ public Single? GetFloatValue(UnitType unit)
+ {
+ if (!(Value is Single))
+ {
+ return null;
+ }
+
+ var quantity = (Single)Value;
+
+ switch (unit)
+ {
+ case UnitType.Percentage:
+ quantity = quantity / 100f;
+ break;
+ }
+
+ return quantity;
+ }
+
+ public override string ToString()
+ {
+ switch (PrimitiveType)
+ {
+ case UnitType.String:
+ return "'" + Value + "'";
+
+ case UnitType.Uri:
+ return "url(" + Value + ")";
+
+ default:
+ if (Value is Single)
+ return ((Single)Value).ToString(CultureInfo.InvariantCulture) + ConvertUnitTypeToString(PrimitiveType);
+
+ return Value.ToString();
+ }
+ }
+
+ internal static UnitType ConvertStringToUnitType(string unit)
+ {
+ switch (unit)
+ {
+ case "%":
+ return UnitType.Percentage;
+ case "em":
+ return UnitType.Ems;
+ case "cm":
+ return UnitType.Centimeter;
+ case "deg":
+ return UnitType.Degree;
+ case "grad":
+ return UnitType.Grad;
+ case "rad":
+ return UnitType.Radian;
+ case "turn":
+ return UnitType.Turn;
+ case "ex":
+ return UnitType.Exs;
+ case "hz":
+ return UnitType.Hertz;
+ case "in":
+ return UnitType.Inch;
+ case "khz":
+ return UnitType.KiloHertz;
+ case "mm":
+ return UnitType.Millimeter;
+ case "ms":
+ return UnitType.Millisecond;
+ case "s":
+ return UnitType.Second;
+ case "pc":
+ return UnitType.Percent;
+ case "pt":
+ return UnitType.Point;
+ case "px":
+ return UnitType.Pixel;
+ case "vw":
+ return UnitType.ViewportWidth;
+ case "vh":
+ return UnitType.ViewportHeight;
+ case "vmin":
+ return UnitType.ViewportMin;
+ case "vmax":
+ return UnitType.ViewportMax;
+ }
+
+ return UnitType.Unknown;
+ }
+
+ internal static string ConvertUnitTypeToString(UnitType unit)
+ {
+ switch (unit)
+ {
+ case UnitType.Percentage:
+ return "%";
+ case UnitType.Ems:
+ return "em";
+ case UnitType.Centimeter:
+ return "cm";
+ case UnitType.Degree:
+ return "deg";
+ case UnitType.Grad:
+ return "grad";
+ case UnitType.Radian:
+ return "rad";
+ case UnitType.Turn:
+ return "turn";
+ case UnitType.Exs:
+ return "ex";
+ case UnitType.Hertz:
+ return "hz";
+ case UnitType.Inch:
+ return "in";
+ case UnitType.KiloHertz:
+ return "khz";
+ case UnitType.Millimeter:
+ return "mm";
+ case UnitType.Millisecond:
+ return "ms";
+ case UnitType.Second:
+ return "s";
+ case UnitType.Percent:
+ return "pc";
+ case UnitType.Point:
+ return "pt";
+ case UnitType.Pixel:
+ return "px";
+ case UnitType.ViewportWidth:
+ return "vw";
+ case UnitType.ViewportHeight:
+ return "vh";
+ case UnitType.ViewportMin:
+ return "vmin";
+ case UnitType.ViewportMax:
+ return "vmax";
+ }
+
+ return string.Empty;
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Model/Values/Property.cs b/Source/External/ExCSS/Model/Values/Property.cs
new file mode 100644
index 0000000000000000000000000000000000000000..ebc7a0893ef25cfb1575696e3147c949262b469c
--- /dev/null
+++ b/Source/External/ExCSS/Model/Values/Property.cs
@@ -0,0 +1,47 @@
+using ExCSS.Model.Extensions;
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ public class Property
+ {
+ private Term _term;
+ private bool _important;
+
+ public Property(string name)
+ {
+ Name = name;
+ }
+
+ public string Name { get; private set; }
+
+ public Term Term
+ {
+ get { return _term; }
+ set { _term = value; }
+ }
+
+ public bool Important
+ {
+ get { return _important; }
+ set { _important = value; }
+ }
+
+ public override string ToString()
+ {
+ return ToString(false);
+ }
+
+ public string ToString(bool friendlyFormat, int indentation = 0)
+ {
+ var value = Name + ":" + _term;
+
+ if (_important)
+ {
+ value += " !important";
+ }
+
+ return value.Indent(friendlyFormat, indentation);
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Model/Values/Term.cs b/Source/External/ExCSS/Model/Values/Term.cs
new file mode 100644
index 0000000000000000000000000000000000000000..25f695e48592bd199059746200c62f83db2fa339
--- /dev/null
+++ b/Source/External/ExCSS/Model/Values/Term.cs
@@ -0,0 +1,9 @@
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ public abstract class Term
+ {
+ public static readonly InheritTerm Inherit = new InheritTerm();
+ }
+}
diff --git a/Source/External/ExCSS/Model/Values/TermList.cs b/Source/External/ExCSS/Model/Values/TermList.cs
new file mode 100644
index 0000000000000000000000000000000000000000..51bb3c2fa9c0eab9fc566720fa5c218e6ee5e0ca
--- /dev/null
+++ b/Source/External/ExCSS/Model/Values/TermList.cs
@@ -0,0 +1,123 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.CompilerServices;
+using System.Text;
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ public class TermList : Term
+ {
+ private readonly List _separator = new List();
+ private readonly List _items = new List();
+ private const GrammarSegment DefaultSeparator = GrammarSegment.Comma;
+
+ public TermList()
+ {
+ }
+
+ public TermList(params Term[] terms)
+ {
+ for(var i = 0; i < terms.Length; ++i)
+ {
+ AddTerm(terms[i]);
+ if(i != terms.Length-1)
+ {
+ AddSeparator(DefaultSeparator);
+ }
+ }
+ }
+
+ public void AddTerm(Term term)
+ {
+ if (_items.Count != _separator.Count)
+ {
+ throw new NotSupportedException("Must call AddTerm AddSeparator in that order");
+ }
+
+ _items.Add(term);
+ }
+
+ public void AddSeparator(TermSeparator termSeparator)
+ {
+ switch(termSeparator)
+ {
+ case(TermSeparator.Comma):
+ {
+ AddSeparator(GrammarSegment.Comma);
+ break;
+ }
+ case(TermSeparator.Space):
+ {
+ AddSeparator(GrammarSegment.Whitespace);
+ break;
+ }
+ }
+ }
+
+ internal void AddSeparator(GrammarSegment termSepertor)
+ {
+ if (_items.Count != _separator.Count + 1)
+ {
+ throw new NotSupportedException("Must call AddTerm AddSeparator in that order");
+ }
+
+ _separator.Add(termSepertor);
+ }
+
+ public int Length
+ {
+ get { return _items.Count; }
+ }
+
+ [IndexerName("ListItems")]
+ public Term this [int index]
+ {
+ //return index >= 0 && index < _items.Count ? _items[index] : null;
+ get { return _items[index]; }
+ }
+
+ public Term Item(int index)
+ {
+ return this[index];
+ }
+
+ public override string ToString()
+ {
+ var builder = new StringBuilder();
+
+ for (var i = 0; i < _items.Count; i++)
+ {
+ builder.Append(_items[i]);
+
+ if (i == _separator.Count)
+ break;
+
+ switch (_separator[i])
+ {
+ case GrammarSegment.Whitespace:
+ builder.Append(" ");
+ break;
+
+ case GrammarSegment.Comma:
+ builder.Append(",");
+ break;
+
+ default:
+ throw new NotImplementedException();
+ }
+ }
+
+ return builder.ToString();
+ }
+
+ ///
+ /// exposed enumeration for the adding of separators into term lists
+ ///
+ public enum TermSeparator
+ {
+ Comma,
+ Space
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Parser.Blocks.cs b/Source/External/ExCSS/Parser.Blocks.cs
new file mode 100644
index 0000000000000000000000000000000000000000..9406aecec20db4adbdbf0f2a3edc3ef59e206044
--- /dev/null
+++ b/Source/External/ExCSS/Parser.Blocks.cs
@@ -0,0 +1,853 @@
+using System;
+using System.Text;
+using System.Collections.Generic;
+using ExCSS.Model;
+using ExCSS.Model.TextBlocks;
+
+namespace ExCSS
+{
+ public partial class Parser
+ {
+ private bool ParseTokenBlock(Block token)
+ {
+ switch (_parsingContext)
+ {
+ case ParsingContext.DataBlock:
+ return ParseSymbol(token);
+
+ case ParsingContext.InSelector:
+ return ParseSelector(token);
+
+ case ParsingContext.InDeclaration:
+ return ParseDeclaration(token);
+
+ case ParsingContext.AfterProperty:
+ return ParsePostProperty(token);
+
+ case ParsingContext.BeforeValue:
+ return ParseValue(token);
+
+ case ParsingContext.InValuePool:
+ return ParseValuePool(token);
+
+ case ParsingContext.InValueList:
+ return ParseValueList(token);
+
+ case ParsingContext.InSingleValue:
+ return ParseSingleValue(token);
+
+ case ParsingContext.ValueImportant:
+ return ParseImportant(token);
+
+ case ParsingContext.AfterValue:
+ return ParsePostValue(token);
+
+ case ParsingContext.InMediaList:
+ return ParseMediaList(token);
+
+ case ParsingContext.InMediaValue:
+ return ParseMediaValue(token);
+
+ case ParsingContext.BeforeImport:
+ return ParseImport(token);
+
+ case ParsingContext.AfterInstruction:
+ return ParsePostInstruction(token);
+
+ case ParsingContext.BeforeCharset:
+ return ParseCharacterSet(token);
+
+ case ParsingContext.BeforeNamespacePrefix:
+ return ParseLeadingPrefix(token);
+
+ case ParsingContext.AfterNamespacePrefix:
+ return ParseNamespace(token);
+
+ case ParsingContext.InCondition:
+ return ParseCondition(token);
+
+ case ParsingContext.InUnknown:
+ return ParseUnknown(token);
+
+ case ParsingContext.InKeyframeText:
+ return ParseKeyframeText(token);
+
+ case ParsingContext.BeforePageSelector:
+ return ParsePageSelector(token);
+
+ case ParsingContext.BeforeDocumentFunction:
+ return ParsePreDocumentFunction(token);
+
+ case ParsingContext.InDocumentFunction:
+ return ParseDocumentFunction(token);
+
+ case ParsingContext.AfterDocumentFunction:
+ return ParsePostDocumentFunction(token);
+
+ case ParsingContext.BetweenDocumentFunctions:
+ return ParseDocumentFunctions(token);
+
+ case ParsingContext.BeforeKeyframesName:
+ return ParseKeyframesName(token);
+
+ case ParsingContext.BeforeKeyframesData:
+ return ParsePreKeyframesData(token);
+
+ case ParsingContext.KeyframesData:
+ return ParseKeyframesData(token);
+
+ case ParsingContext.BeforeFontFace:
+ return ParseFontface(token);
+
+ case ParsingContext.InHexValue:
+ return ParseHexValue(token);
+
+ case ParsingContext.InFunction:
+
+ return ParseValueFunction(token);
+ default:
+ return false;
+ }
+ }
+
+ private bool ParseSymbol(Block token)
+ {
+ if (token.GrammarSegment == GrammarSegment.AtRule)
+ {
+ switch (((SymbolBlock)token).Value)
+ {
+ case RuleTypes.Media:
+ {
+ AddRuleSet(new MediaRule());
+ SetParsingContext(ParsingContext.InMediaList);
+ break;
+ }
+ case RuleTypes.Page:
+ {
+ AddRuleSet(new PageRule());
+ //SetParsingContext(ParsingContext.InSelector);
+ SetParsingContext(ParsingContext.BeforePageSelector);
+ break;
+ }
+ case RuleTypes.Import:
+ {
+ AddRuleSet(new ImportRule());
+ SetParsingContext(ParsingContext.BeforeImport);
+ break;
+ }
+ case RuleTypes.FontFace:
+ {
+ AddRuleSet(new FontFaceRule());
+ //SetParsingContext(ParsingContext.InDeclaration);
+ SetParsingContext(ParsingContext.BeforeFontFace);
+ break;
+ }
+ case RuleTypes.CharacterSet:
+ {
+ AddRuleSet(new CharacterSetRule());
+ SetParsingContext(ParsingContext.BeforeCharset);
+ break;
+ }
+ case RuleTypes.Namespace:
+ {
+ AddRuleSet(new NamespaceRule());
+ SetParsingContext(ParsingContext.BeforeNamespacePrefix);
+ break;
+ }
+ case RuleTypes.Supports:
+ {
+ _buffer = new StringBuilder();
+ AddRuleSet(new SupportsRule());
+ SetParsingContext(ParsingContext.InCondition);
+ break;
+ }
+ case RuleTypes.Keyframes:
+ {
+ AddRuleSet(new KeyframesRule());
+ SetParsingContext(ParsingContext.BeforeKeyframesName);
+ break;
+ }
+ case RuleTypes.Document:
+ {
+ AddRuleSet(new DocumentRule());
+ SetParsingContext(ParsingContext.BeforeDocumentFunction);
+ break;
+ }
+ default:
+ {
+ _buffer = new StringBuilder();
+ AddRuleSet(new GenericRule());
+ SetParsingContext(ParsingContext.InUnknown);
+ ParseUnknown(token);
+ break;
+ }
+ }
+
+ return true;
+ }
+
+ if (token.GrammarSegment == GrammarSegment.CurlyBracketClose)
+ {
+ return FinalizeRule();
+ }
+
+ AddRuleSet(new StyleRule());
+ SetParsingContext(ParsingContext.InSelector);
+ ParseSelector(token);
+ return true;
+
+ }
+
+ private bool ParseUnknown(Block token)
+ {
+ switch (token.GrammarSegment)
+ {
+ case GrammarSegment.Semicolon:
+ CastRuleSet().SetInstruction(_buffer.ToString());
+ SetParsingContext(ParsingContext.DataBlock);
+
+ return FinalizeRule();
+
+ case GrammarSegment.CurlyBraceOpen:
+ CastRuleSet().SetCondition(_buffer.ToString());
+ SetParsingContext(ParsingContext.DataBlock);
+ break;
+
+ default:
+ _buffer.Append(token);
+ break;
+ }
+
+ return true;
+ }
+
+ private bool ParseSelector(Block token)
+ {
+ switch (token.GrammarSegment)
+ {
+ case GrammarSegment.CurlyBraceOpen:
+ {
+ var rule = CurrentRule as ISupportsSelector;
+
+ if (rule != null)
+ {
+ rule.Selector = _selectorFactory.GetSelector();
+ }
+
+ SetParsingContext(CurrentRule is StyleRule
+ ? ParsingContext.InDeclaration
+ : ParsingContext.DataBlock);
+ }
+ break;
+
+ case GrammarSegment.CurlyBracketClose:
+ return false;
+
+ default:
+ _selectorFactory.Apply(token);
+ break;
+ }
+
+ return true;
+ }
+
+ private bool ParseDeclaration(Block token)
+ {
+ if (token.GrammarSegment == GrammarSegment.CurlyBracketClose)
+ {
+ FinalizeProperty();
+ SetParsingContext(CurrentRule is KeyframeRule ? ParsingContext.KeyframesData : ParsingContext.DataBlock);
+ return FinalizeRule();
+ }
+
+ if (token.GrammarSegment != GrammarSegment.Ident)
+ {
+ return false;
+ }
+
+ AddProperty(new Property(((SymbolBlock)token).Value));
+ SetParsingContext(ParsingContext.AfterProperty);
+ return true;
+ }
+
+ private bool ParsePostInstruction(Block token)
+ {
+ if (token.GrammarSegment != GrammarSegment.Semicolon)
+ {
+ return false;
+ }
+
+ SetParsingContext(ParsingContext.DataBlock);
+
+ return FinalizeRule();
+ }
+
+ private bool ParseCondition(Block token)
+ {
+ switch (token.GrammarSegment)
+ {
+ case GrammarSegment.CurlyBraceOpen:
+ CastRuleSet().Condition = _buffer.ToString();
+ SetParsingContext(ParsingContext.DataBlock);
+ break;
+
+ default:
+ _buffer.Append(token);
+ break;
+ }
+
+ return true;
+ }
+
+ private bool ParseLeadingPrefix(Block token)
+ {
+ if (token.GrammarSegment == GrammarSegment.Ident)
+ {
+ CastRuleSet().Prefix = ((SymbolBlock)token).Value;
+ SetParsingContext(ParsingContext.AfterNamespacePrefix);
+
+ return true;
+ }
+
+ if (token.GrammarSegment == GrammarSegment.String || token.GrammarSegment == GrammarSegment.Url)
+ {
+ CastRuleSet().Uri = ((StringBlock)token).Value;
+ return true;
+ }
+
+ SetParsingContext(ParsingContext.AfterInstruction);
+
+ return ParsePostInstruction(token);
+ }
+
+ private bool ParsePostProperty(Block token)
+ {
+ if (token.GrammarSegment == GrammarSegment.Colon)
+ {
+ _isFraction = false;
+ SetParsingContext(ParsingContext.BeforeValue);
+ return true;
+ }
+
+ if (token.GrammarSegment == GrammarSegment.Semicolon || token.GrammarSegment == GrammarSegment.CurlyBracketClose)
+ {
+ ParsePostValue(token);
+ }
+
+ return false;
+ }
+
+ private bool ParseValue(Block token)
+ {
+ switch (token.GrammarSegment)
+ {
+ case GrammarSegment.Semicolon:
+ SetParsingContext(ParsingContext.InDeclaration);
+ break;
+
+ case GrammarSegment.CurlyBracketClose:
+ ParseDeclaration(token);
+ break;
+
+ default:
+ SetParsingContext(ParsingContext.InSingleValue);
+ return ParseSingleValue(token);
+ }
+
+ return false;
+ }
+
+ private bool ParseSingleValue(Block token)
+ {
+ switch (token.GrammarSegment)
+ {
+ case GrammarSegment.Dimension: // "3px"
+ return AddTerm(new PrimitiveTerm(((UnitBlock)token).Unit, ((UnitBlock)token).Value));
+
+ case GrammarSegment.Hash:// "#ffffff"
+ return ParseSingleValueHexColor(((SymbolBlock)token).Value);
+
+ case GrammarSegment.Delimiter: // "#"
+ return ParseValueDelimiter((DelimiterBlock)token);
+
+ case GrammarSegment.Ident: // "auto"
+ return ParseSingleValueIdent((SymbolBlock)token);
+
+ case GrammarSegment.String:// "'some value'"
+ return AddTerm(new PrimitiveTerm(UnitType.String, ((StringBlock)token).Value));
+
+ case GrammarSegment.Url:// "url('http://....')"
+ return AddTerm(new PrimitiveTerm(UnitType.Uri, ((StringBlock)token).Value));
+
+ case GrammarSegment.Percentage: // "10%"
+ return AddTerm(new PrimitiveTerm(UnitType.Percentage, ((UnitBlock)token).Value));
+
+ case GrammarSegment.Number: // "123"
+ return AddTerm(new PrimitiveTerm(UnitType.Number, ((NumericBlock)token).Value));
+
+ case GrammarSegment.Whitespace: // " "
+ _terms.AddSeparator(GrammarSegment.Whitespace);
+ SetParsingContext(ParsingContext.InValueList);
+ return true;
+
+ case GrammarSegment.Function: // rgba(...)
+ _functionBuffers.Push(new FunctionBuffer(((SymbolBlock)token).Value));
+ SetParsingContext(ParsingContext.InFunction);
+ return true;
+
+ case GrammarSegment.Comma: // ","
+ _terms.AddSeparator(GrammarSegment.Comma);
+ SetParsingContext(ParsingContext.InValuePool);
+ return true;
+
+ case GrammarSegment.Semicolon: // ";"
+ case GrammarSegment.CurlyBracketClose: // "}"
+ return ParsePostValue(token);
+
+ default:
+ return false;
+ }
+ }
+
+ private bool ParseValueFunction(Block token)
+ {
+ switch (token.GrammarSegment)
+ {
+ case GrammarSegment.ParenClose:
+ SetParsingContext(ParsingContext.InSingleValue);
+ return AddTerm(_functionBuffers.Pop().Done());
+
+ case GrammarSegment.Comma:
+ _functionBuffers.Peek().Include();
+ return true;
+
+ default:
+ return ParseSingleValue(token);
+ }
+ }
+
+ private bool ParseValueList(Block token)
+ {
+ switch (token.GrammarSegment)
+ {
+ case GrammarSegment.CurlyBracketClose:
+ case GrammarSegment.Semicolon:
+ ParsePostValue(token);
+ break;
+
+ case GrammarSegment.Comma:
+ SetParsingContext(ParsingContext.InValuePool);
+ break;
+
+ default:
+ SetParsingContext(ParsingContext.InSingleValue);
+ return ParseSingleValue(token);
+ }
+
+ return true;
+ }
+
+ private bool ParseValuePool(Block token)
+ {
+ if (token.GrammarSegment == GrammarSegment.Semicolon || token.GrammarSegment == GrammarSegment.CurlyBracketClose)
+ {
+ ParsePostValue(token);
+ }
+ else
+ {
+ SetParsingContext(ParsingContext.InSingleValue);
+ return ParseSingleValue(token);
+ }
+
+ return false;
+ }
+
+ private bool ParseHexValue(Block token)
+ {
+ switch (token.GrammarSegment)
+ {
+ case GrammarSegment.Number:
+ case GrammarSegment.Dimension:
+ case GrammarSegment.Ident:
+ var rest = token.ToString();
+
+ if (_buffer.Length + rest.Length <= 6)
+ {
+ _buffer.Append(rest);
+ return true;
+ }
+
+ break;
+ }
+
+ ParseSingleValueHexColor(_buffer.ToString());
+ SetParsingContext(ParsingContext.InSingleValue);
+ return ParseSingleValue(token);
+ }
+
+ private bool ParsePostValue(Block token)
+ {
+ if (token.GrammarSegment == GrammarSegment.Semicolon)
+ {
+ FinalizeProperty();
+ SetParsingContext(ParsingContext.InDeclaration);
+ return true;
+ }
+
+ if (token.GrammarSegment == GrammarSegment.CurlyBracketClose)
+ {
+ return ParseDeclaration(token);
+ }
+
+ return false;
+ }
+
+ private bool ParseImportant(Block token)
+ {
+ if (token.GrammarSegment != GrammarSegment.Ident || ((SymbolBlock)token).Value != "important")
+ {
+ return ParsePostValue(token);
+ }
+
+ SetParsingContext(ParsingContext.AfterValue);
+ _property.Important = true;
+
+ return true;
+ }
+
+ private bool ParseValueDelimiter(DelimiterBlock token)
+ {
+ switch (token.Value)
+ {
+ case Specification.Em:
+ SetParsingContext(ParsingContext.ValueImportant);
+ return true;
+
+ case Specification.Hash:
+ _buffer = new StringBuilder();
+ SetParsingContext(ParsingContext.InHexValue);
+ return true;
+
+ case Specification.Solidus:
+ _isFraction = true;
+ return true;
+
+ default:
+ return false;
+ }
+ }
+
+ private bool ParseSingleValueIdent(SymbolBlock token)
+ {
+ if (token.Value != "inherit")
+ {
+ return AddTerm(new PrimitiveTerm(UnitType.Ident, token.Value));
+ }
+ _terms.AddTerm(Term.Inherit);
+ SetParsingContext(ParsingContext.AfterValue);
+ return true;
+ }
+
+ private bool ParseSingleValueHexColor(string color)
+ {
+ HtmlColor htmlColor;
+
+ if(HtmlColor.TryFromHex(color, out htmlColor))
+ return AddTerm(htmlColor);
+ return false;
+ }
+
+ #region Namespace
+ private bool ParseNamespace(Block token)
+ {
+ SetParsingContext(ParsingContext.AfterInstruction);
+
+ if (token.GrammarSegment != GrammarSegment.String)
+ {
+ return ParsePostInstruction(token);
+ }
+
+ CastRuleSet().Uri = ((StringBlock)token).Value;
+
+ return true;
+ }
+ #endregion
+
+ #region Charset
+ private bool ParseCharacterSet(Block token)
+ {
+ SetParsingContext(ParsingContext.AfterInstruction);
+
+ if (token.GrammarSegment != GrammarSegment.String)
+ {
+ return ParsePostInstruction(token);
+ }
+
+ CastRuleSet().Encoding = ((StringBlock)token).Value;
+
+ return true;
+ }
+ #endregion
+
+ #region Import
+ private bool ParseImport(Block token)
+ {
+ if (token.GrammarSegment == GrammarSegment.String || token.GrammarSegment == GrammarSegment.Url)
+ {
+ CastRuleSet().Href = ((StringBlock)token).Value;
+ SetParsingContext(ParsingContext.InMediaList);
+ return true;
+ }
+
+ SetParsingContext(ParsingContext.AfterInstruction);
+
+ return false;
+ }
+ #endregion
+
+ #region Font Face
+
+ private bool ParseFontface(Block token)
+ {
+ if (token.GrammarSegment == GrammarSegment.CurlyBraceOpen)
+ {
+ SetParsingContext(ParsingContext.InDeclaration);
+ return true;
+ }
+
+ return false;
+ }
+ #endregion
+
+ #region Keyframes
+ private bool ParseKeyframesName(Block token)
+ {
+ //SetParsingContext(ParsingContext.BeforeKeyframesData);
+
+ if (token.GrammarSegment == GrammarSegment.Ident)
+ {
+ CastRuleSet().Identifier = ((SymbolBlock)token).Value;
+ return true;
+ }
+
+ if (token.GrammarSegment == GrammarSegment.CurlyBraceOpen)
+ {
+ SetParsingContext(ParsingContext.KeyframesData);
+ return true;
+ }
+
+ return false;
+ }
+
+ private bool ParsePreKeyframesData(Block token)
+ {
+ if (token.GrammarSegment != GrammarSegment.CurlyBraceOpen)
+ {
+ return false;
+ }
+
+ SetParsingContext(ParsingContext.BeforeKeyframesData);
+ return true;
+ }
+
+ private bool ParseKeyframesData(Block token)
+ {
+ if (token.GrammarSegment == GrammarSegment.CurlyBracketClose)
+ {
+ SetParsingContext(ParsingContext.DataBlock);
+ return FinalizeRule();
+ }
+
+ _buffer = new StringBuilder();
+
+ return ParseKeyframeText(token);
+ }
+
+ private bool ParseKeyframeText(Block token)
+ {
+ if (token.GrammarSegment == GrammarSegment.CurlyBraceOpen)
+ {
+ SetParsingContext(ParsingContext.InDeclaration);
+ return true;
+ }
+
+ if (token.GrammarSegment == GrammarSegment.CurlyBracketClose)
+ {
+ ParseKeyframesData(token);
+
+ return false;
+ }
+
+ var frame = new KeyframeRule
+ {
+ Value = token.ToString()
+ };
+
+
+ CastRuleSet().Declarations.Add(frame);
+ _activeRuleSets.Push(frame);
+
+ return true;
+ }
+ #endregion
+
+ #region Page
+
+ private bool ParsePageSelector(Block token)
+ {
+ if (token.GrammarSegment == GrammarSegment.Colon || token.GrammarSegment == GrammarSegment.Whitespace)
+ {
+ return true;
+ }
+
+ if (token.GrammarSegment == GrammarSegment.Ident)
+ {
+ CastRuleSet().Selector = new SimpleSelector(token.ToString());
+ return true;
+ }
+
+ if (token.GrammarSegment == GrammarSegment.CurlyBraceOpen)
+ {
+ SetParsingContext(ParsingContext.InDeclaration);
+ return true;
+ }
+
+ return false;
+ }
+
+ #endregion
+
+ #region Document
+ private bool ParsePreDocumentFunction(Block token)
+ {
+ switch (token.GrammarSegment)
+ {
+ case GrammarSegment.Url:
+ CastRuleSet().Conditions.Add(new KeyValuePair(DocumentFunction.Url, ((StringBlock)token).Value));
+ break;
+
+ case GrammarSegment.UrlPrefix:
+ CastRuleSet().Conditions.Add(new KeyValuePair(DocumentFunction.UrlPrefix, ((StringBlock)token).Value));
+ break;
+
+ case GrammarSegment.Domain:
+ CastRuleSet().Conditions.Add(new KeyValuePair(DocumentFunction.Domain, ((StringBlock)token).Value));
+ break;
+
+ case GrammarSegment.Function:
+ if (string.Compare(((SymbolBlock)token).Value, "regexp", StringComparison.OrdinalIgnoreCase) == 0)
+ {
+ SetParsingContext(ParsingContext.InDocumentFunction);
+ return true;
+ }
+ SetParsingContext(ParsingContext.AfterDocumentFunction);
+ return false;
+
+ default:
+ SetParsingContext(ParsingContext.DataBlock);
+ return false;
+ }
+
+ SetParsingContext(ParsingContext.BetweenDocumentFunctions);
+ return true;
+ }
+
+ private bool ParseDocumentFunction(Block token)
+ {
+ SetParsingContext(ParsingContext.AfterDocumentFunction);
+
+ if (token.GrammarSegment != GrammarSegment.String) return false;
+ CastRuleSet().Conditions.Add(new KeyValuePair(DocumentFunction.RegExp, ((StringBlock)token).Value));
+ return true;
+ }
+
+ private bool ParsePostDocumentFunction(Block token)
+ {
+ SetParsingContext(ParsingContext.BetweenDocumentFunctions);
+ return token.GrammarSegment == GrammarSegment.ParenClose;
+ }
+
+ private bool ParseDocumentFunctions(Block token)
+ {
+ if (token.GrammarSegment == GrammarSegment.Comma)
+ {
+ SetParsingContext(ParsingContext.BeforeDocumentFunction);
+ return true;
+ }
+
+ if (token.GrammarSegment == GrammarSegment.CurlyBraceOpen)
+ {
+ SetParsingContext(ParsingContext.DataBlock);
+ return true;
+ }
+
+ SetParsingContext(ParsingContext.DataBlock);
+ return false;
+ }
+ #endregion
+
+ #region Media
+ private bool ParseMediaList(Block token)
+ {
+ if (token.GrammarSegment == GrammarSegment.Semicolon)
+ {
+ FinalizeRule();
+ SetParsingContext(ParsingContext.DataBlock);
+ return true;
+ }
+
+ _buffer = new StringBuilder();
+ SetParsingContext(ParsingContext.InMediaValue);
+ return ParseMediaValue(token);
+ }
+
+ private bool ParseMediaValue(Block token)
+ {
+ switch (token.GrammarSegment)
+ {
+ case GrammarSegment.CurlyBraceOpen:
+ case GrammarSegment.Semicolon:
+ {
+ var container = CurrentRule as ISupportsMedia;
+ var medium = _buffer.ToString();
+
+ if (container != null)
+ {
+ container.Media.AppendMedium(medium);
+ }
+
+ if (CurrentRule is ImportRule)
+ {
+ return ParsePostInstruction(token);
+ }
+
+ SetParsingContext(ParsingContext.DataBlock);
+ return token.GrammarSegment == GrammarSegment.CurlyBraceOpen;
+ }
+ case GrammarSegment.Comma:
+ {
+ var container = CurrentRule as ISupportsMedia;
+
+ if (container != null)
+ {
+ container.Media.AppendMedium(_buffer.ToString());
+ }
+
+ _buffer.Length = 0;
+ return true;
+ }
+ case GrammarSegment.Whitespace:
+ {
+ _buffer.Append(' ');
+ return true;
+ }
+ default:
+ {
+ _buffer.Append(token);
+ return true;
+ }
+ }
+ }
+ #endregion
+ }
+}
diff --git a/Source/External/ExCSS/Parser.cs b/Source/External/ExCSS/Parser.cs
new file mode 100644
index 0000000000000000000000000000000000000000..b44db37cfb249ff5a992016d8a76d1406b811804
--- /dev/null
+++ b/Source/External/ExCSS/Parser.cs
@@ -0,0 +1,252 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using ExCSS.Model;
+using ExCSS.Model.TextBlocks;
+
+// ReSharper disable once CheckNamespace
+using System;
+
+
+namespace ExCSS
+{
+ internal delegate void ParseErrorEventHandler(StylesheetParseError e);
+
+ public sealed partial class Parser
+ {
+ private SelectorFactory _selectorFactory;
+ private Stack _functionBuffers;
+ private Lexer _lexer;
+ private bool _isFraction;
+ private Property _property;
+ private TermList _terms = new TermList();
+ private StyleSheet _styleSheet;
+ private Stack _activeRuleSets;
+ private StringBuilder _buffer;
+ private ParsingContext _parsingContext;
+
+ public StyleSheet Parse(string css)
+ {
+ _selectorFactory = new SelectorFactory();
+ _functionBuffers = new Stack();
+ _styleSheet = new StyleSheet();
+ _activeRuleSets = new Stack();
+ _lexer = new Lexer(new StylesheetReader(css)) { ErrorHandler = HandleLexerError };
+
+ SetParsingContext(ParsingContext.DataBlock);
+
+ var tokens = _lexer.Tokens;
+
+ foreach (var token in tokens)
+ {
+ if (ParseTokenBlock(token))
+ {
+ continue;
+ }
+
+ HandleLexerError(ParserError.UnexpectedLineBreak, ErrorMessages.Default);
+ }
+
+ if (_property != null)
+ {
+ ParseTokenBlock(SpecialCharacter.Semicolon);
+ }
+
+ return _styleSheet;
+ }
+
+ internal static BaseSelector ParseSelector(string selector)
+ {
+ var tokenizer = new Lexer(new StylesheetReader(selector));
+ var tokens = tokenizer.Tokens;
+ var selctor = new SelectorFactory();
+
+ foreach (var token in tokens)
+ {
+ selctor.Apply(token);
+ }
+
+ var result = selctor.GetSelector();
+
+ return result;
+ }
+
+ internal static RuleSet ParseRule(string css)
+ {
+ var parser = new Parser();
+
+
+ var styleSheet = parser.Parse(css);
+
+ return styleSheet.Rules.Count > 0
+ ? styleSheet.Rules[0]
+ : null;
+ }
+
+ internal static StyleDeclaration ParseDeclarations(string declarations, bool quirksMode = false)
+ {
+ var decl = new StyleDeclaration();
+ AppendDeclarations(decl, declarations, quirksMode);
+
+ return decl;
+ }
+
+ internal static void AppendDeclarations(StyleDeclaration list, string css, bool quirksMode = false)
+ {
+ var parser = new Parser();//(new StyleSheet(), new StylesheetReader(declarations))
+
+
+ parser.AddRuleSet(list.ParentRule ?? new StyleRule(list));
+
+ parser._parsingContext = ParsingContext.InDeclaration;
+ parser.Parse(css);
+ }
+
+ internal void HandleLexerError(ParserError error, string message)
+ {
+ _styleSheet.Errors.Add(new StylesheetParseError(error, message, _lexer.Stream.Line, _lexer.Stream.Column));
+ }
+
+ private bool AddTerm(Term value)
+ {
+ if (_isFraction)
+ {
+ if (_terms.Length > 0)
+ {
+ value = new PrimitiveTerm(UnitType.Unknown, _terms[0] + "/" + value);
+ _terms = new TermList();
+ }
+
+ _isFraction = false;
+ }
+
+ if (_functionBuffers.Count > 0)
+ {
+ _functionBuffers.Peek().TermList.Add(value);
+ }
+ else if (_terms.Length == 0)
+ {
+ _terms.AddTerm(value);
+ }
+ else if (_parsingContext == ParsingContext.InSingleValue)
+ {
+ _terms.AddTerm(value);
+ }
+ else
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ private void FinalizeProperty()
+ {
+ if (_property != null)
+ {
+ if (_terms.Length > 1)
+ {
+ _property.Term = _terms;
+ }
+ else
+ {
+ _property.Term = _terms[0];
+ }
+ }
+
+ _terms = new TermList();
+ _property = null;
+ }
+
+ private bool FinalizeRule()
+ {
+ if (_activeRuleSets.Count <= 0)
+ {
+ return false;
+ }
+
+ _activeRuleSets.Pop();
+ return true;
+ }
+
+ private void AddRuleSet(RuleSet rule)
+ {
+ //rule.ParentStyleSheet = _styleSheet;
+
+ if (_activeRuleSets.Count > 0)
+ {
+ var container = _activeRuleSets.Peek() as ISupportsRuleSets;
+
+ if (container != null)
+ {
+ container.RuleSets.Add(rule);
+ }
+ }
+ else
+ {
+ _styleSheet.Rules.Add(rule);
+ }
+
+ _activeRuleSets.Push(rule);
+ }
+
+ private void AddProperty(Property property)
+ {
+ _property = property;
+ var rule = CurrentRule as ISupportsDeclarations;
+
+ if (rule != null)
+ {
+ rule.Declarations.Add(property);
+ }
+ }
+
+ private T CastRuleSet() where T : RuleSet
+ {
+ if (_activeRuleSets.Count > 0)
+ {
+ return _activeRuleSets.Peek() as T;
+ }
+
+ return default(T);
+ }
+
+ private void SetParsingContext(ParsingContext newState)
+ {
+ switch (newState)
+ {
+ case ParsingContext.InSelector:
+ _lexer.IgnoreComments = true;
+ _lexer.IgnoreWhitespace = false;
+ _selectorFactory.ResetFactory();
+ break;
+
+ case ParsingContext.InHexValue:
+ case ParsingContext.InUnknown:
+ case ParsingContext.InCondition:
+ case ParsingContext.InSingleValue:
+ case ParsingContext.InMediaValue:
+ _lexer.IgnoreComments = true;
+ _lexer.IgnoreWhitespace = false;
+ break;
+
+ default:
+ _lexer.IgnoreComments = true;
+ _lexer.IgnoreWhitespace = true;
+ break;
+ }
+
+ _parsingContext = newState;
+ }
+
+ internal RuleSet CurrentRule
+ {
+ get
+ {
+ return _activeRuleSets.Count > 0
+ ? _activeRuleSets.Peek()
+ : null;
+ }
+ }
+ }
+}
diff --git a/Source/External/ExCSS/Parser.generated.cs b/Source/External/ExCSS/Parser.generated.cs
new file mode 100644
index 0000000000000000000000000000000000000000..df0667b241e458e59eac77c7dfdcd136cd96a7a5
--- /dev/null
+++ b/Source/External/ExCSS/Parser.generated.cs
@@ -0,0 +1,2791 @@
+
+/* #line 1 "Parser.rl" */
+using System;
+using ExCSS.Model;
+
+namespace ExCSS
+{
+ public class Parser
+ {
+ private string _css;
+ private int _currentPosition;
+ private int p = 0;
+ private StylesheetContext _context;
+
+
+/* #line 17 "Parser.rl" */
+
+
+ private string GetCssFragment() {
+ return _css.Substring(_currentPosition, p - _currentPosition);
+ }
+
+ private void BeginToken(TokenType tokenType){
+ _currentPosition = p;
+ _context.BeginToken(tokenType);
+ }
+
+ private void EndToken(TokenType tokenType){
+ _context.EndToken(tokenType, GetCssFragment());
+ }
+
+ #region Generated Scanner + Parser
+ public void Parse(string value, StylesheetContext context)
+ {
+ _css = value;
+ _context = context;
+
+ char[] data = value.ToCharArray();
+ int cs;
+ int eof = data.Length;
+
+ int pe = eof;
+
+
+/* #line 2 "../ExCSS/Parser.generated.cs" */
+ {
+ cs = selector_start;
+ }
+
+/* #line 45 "Parser.rl" */
+
+/* #line 5 "../ExCSS/Parser.generated.cs" */
+ {
+ sbyte _klen;
+ short _trans;
+ short _keys;
+
+ if ( p == pe )
+ goto _test_eof;
+ if ( cs == 0 )
+ goto _out;
+_resume:
+ _keys = _selector_key_offsets[cs];
+ _trans = (short)_selector_index_offsets[cs];
+
+ _klen = _selector_single_lengths[cs];
+ if ( _klen > 0 ) {
+ short _lower = _keys;
+ short _mid;
+ short _upper = (short) (_keys + _klen - 1);
+ while (true) {
+ if ( _upper < _lower )
+ break;
+
+ _mid = (short) (_lower + ((_upper-_lower) >> 1));
+ if ( data[p] < _selector_trans_keys[_mid] )
+ _upper = (short) (_mid - 1);
+ else if ( data[p] > _selector_trans_keys[_mid] )
+ _lower = (short) (_mid + 1);
+ else {
+ _trans += (short) (_mid - _keys);
+ goto _match;
+ }
+ }
+ _keys += (short) _klen;
+ _trans += (short) _klen;
+ }
+
+ _klen = _selector_range_lengths[cs];
+ if ( _klen > 0 ) {
+ short _lower = _keys;
+ short _mid;
+ short _upper = (short) (_keys + (_klen<<1) - 2);
+ while (true) {
+ if ( _upper < _lower )
+ break;
+
+ _mid = (short) (_lower + (((_upper-_lower) >> 1) & ~1));
+ if ( data[p] < _selector_trans_keys[_mid] )
+ _upper = (short) (_mid - 2);
+ else if ( data[p] > _selector_trans_keys[_mid+1] )
+ _lower = (short) (_mid + 2);
+ else {
+ _trans += (short)((_mid - _keys)>>1);
+ goto _match;
+ }
+ }
+ _trans += (short) _klen;
+ }
+
+_match:
+ cs = _selector_trans_targs[_trans];
+
+ if ( cs == 0 )
+ goto _out;
+ if ( ++p != pe )
+ goto _resume;
+ _test_eof: {}
+ _out: {}
+ }
+
+/* #line 46 "Parser.rl" */
+ }
+
+
+/* #line 73 "../ExCSS/Parser.generated.cs" */
+static readonly short[] _selector_key_offsets = new short [] {
+ 0, 0, 12, 16, 27, 31, 49, 50,
+ 72, 74, 76, 78, 80, 82, 84, 86,
+ 88, 90, 95, 96, 97, 98, 99, 100,
+ 101, 103, 127, 135, 156, 160, 180, 195,
+ 215, 237, 240, 243, 246, 249, 252, 255,
+ 258, 261, 264, 270, 283, 288, 300, 305,
+ 323, 325, 347, 350, 353, 356, 359, 362,
+ 365, 368, 371, 374, 380, 393, 398, 410,
+ 415, 433, 436, 460, 469, 490, 495, 515,
+ 529, 549, 571, 575, 579, 583, 587, 591,
+ 595, 599, 603, 607, 614, 628, 634, 647,
+ 653, 671, 675, 699, 709, 730, 736, 740,
+ 763, 776, 797, 820, 841, 862, 882, 894,
+ 906, 924, 937, 950, 963, 976, 989, 1001,
+ 1004, 1007, 1010, 1017, 1020, 1023, 1045, 1047,
+ 1069, 1070, 1073, 1076, 1079, 1082, 1085, 1088,
+ 1091, 1094, 1097, 1103, 1116, 1121, 1133, 1138,
+ 1156, 1161, 1164, 1188, 1197, 1218, 1223, 1243,
+ 1258, 1279, 1302, 1305, 1329, 1338, 1359, 1362,
+ 1385, 1399, 1421, 1442, 1463, 1483, 1495, 1507,
+ 1525, 1538, 1551, 1564, 1577, 1590, 1602, 1604,
+ 1606, 1608, 1614, 1616, 1618, 1620, 1642, 1643,
+ 1646, 1649, 1652, 1655, 1658, 1661, 1664, 1667,
+ 1670, 1676, 1689, 1694, 1706, 1711, 1729, 1732,
+ 1756, 1765, 1786, 1791, 1811, 1826, 1846, 1868,
+ 1872, 1876, 1880, 1884, 1888, 1892, 1896, 1900,
+ 1904, 1911, 1925, 1931, 1944, 1950, 1968, 1972,
+ 1996, 2006, 2027, 2033, 2037, 2060, 2074, 2095,
+ 2118, 2139, 2160, 2180, 2192, 2204, 2222, 2235,
+ 2248, 2261, 2274, 2287, 2299, 2302, 2305, 2308,
+ 2315, 2318, 2321, 2343, 2345, 2349, 2353, 2357,
+ 2361, 2365, 2369, 2373, 2377, 2381, 2388, 2402,
+ 2408, 2421, 2427, 2445, 2451, 2455, 2479, 2489,
+ 2510, 2516, 2536, 2551, 2572, 2595, 2599, 2603,
+ 2607, 2611, 2615, 2619, 2623, 2627, 2631, 2638,
+ 2652, 2658, 2671, 2677, 2695, 2699, 2723, 2733,
+ 2754, 2774, 2788, 2810, 2814, 2837, 2858, 2879,
+ 2899, 2911, 2923, 2941, 2954, 2967, 2980, 2993,
+ 3006, 3018, 3021, 3024, 3027, 3034, 3037, 3040,
+ 3051, 3054, 3057, 3060, 3063, 3066, 3086, 3091,
+ 3111, 3132, 3153, 3174, 3193, 3214, 3221, 3228,
+ 3235, 3242, 3245, 3248, 3269, 3287, 3303, 3327,
+ 3340, 3353, 3359, 3377, 3392, 3416, 3419, 3442,
+ 3463, 3484, 3504, 3516, 3528, 3546, 3559, 3572,
+ 3585, 3598, 3611, 3623, 3625, 3627, 3629, 3635,
+ 3637, 3639, 3649, 3651, 3653, 3655, 3657, 3659,
+ 3679, 3683, 3703, 3724, 3736, 3758, 3772, 3796,
+ 3798, 3821, 3842, 3863, 3883, 3895, 3907, 3925,
+ 3938, 3951, 3964, 3977, 3990, 4002, 4003, 4004,
+ 4005, 4010, 4011, 4012, 4021, 4041, 4044, 4064,
+ 4085, 4098, 4111, 4124, 4126, 4128, 4130, 4132,
+ 4134, 4136, 4142, 4144, 4146, 4168, 4183, 4207,
+ 4210, 4233, 4254, 4275, 4295, 4307, 4319, 4337,
+ 4350, 4363, 4376, 4389, 4402, 4414, 4416, 4418,
+ 4420, 4426, 4428, 4430, 4440, 4442, 4444, 4446,
+ 4448, 4450, 4470, 4474, 4494, 4515, 4529, 4543,
+ 4557, 4560, 4563, 4566, 4569, 4572, 4575, 4582,
+ 4585, 4588, 4603, 4618, 4630, 4644, 4658, 4679,
+ 4702, 4723, 4744, 4764, 4776, 4788, 4806, 4819,
+ 4832, 4845, 4858, 4871, 4883, 4886, 4889, 4892,
+ 4899, 4902, 4905, 4916, 4919, 4922, 4925, 4928,
+ 4931, 4951, 4956, 4976, 4997, 5019, 5023, 5046,
+ 5067, 5088, 5107, 5128, 5135, 5142, 5149, 5156,
+ 5159, 5162, 5183, 5201, 5217, 5241, 5254, 5267,
+ 5273, 5291, 5306, 5330, 5333, 5356, 5377, 5398,
+ 5418, 5430, 5442, 5460, 5473, 5486, 5499, 5512,
+ 5525, 5537, 5539, 5541, 5543, 5549, 5551, 5553,
+ 5563, 5565, 5567, 5569, 5571, 5573, 5593, 5597,
+ 5617, 5638, 5650, 5662, 5667, 5685, 5696, 5708,
+ 5720, 5732, 5733, 5734, 5735, 5736, 5737, 5738,
+ 5743, 5744, 5745, 5758, 5771, 5784, 5786, 5788,
+ 5790, 5792, 5794, 5796, 5802, 5804, 5806, 5819,
+ 5825, 5843, 5855, 5868, 5881, 5894, 5896, 5898,
+ 5900, 5902, 5904, 5906, 5912, 5914, 5916, 5930,
+ 5944, 5958, 5961, 5964, 5967, 5970, 5973, 5976,
+ 5983, 5986, 5989, 6004, 6019, 6031, 6045, 6059,
+ 6070, 6073, 6076, 6079, 6082, 6085, 6105, 6110,
+ 6130, 6151, 6173, 6194, 6215, 6234, 6255, 6262,
+ 6269, 6276, 6283, 6286, 6289, 6310, 6328, 6344,
+ 6368, 6381, 6403, 6416, 6422, 6440, 6455, 6479,
+ 6489, 6491, 6493, 6495, 6497, 6499, 6519, 6523,
+ 6543, 6564, 6576, 6589, 6602, 6615, 6617, 6619,
+ 6621, 6623, 6625, 6627, 6633, 6635, 6637, 6651,
+ 6665, 6679, 6682, 6685, 6688, 6691, 6694, 6697,
+ 6704, 6707, 6710, 6725, 6740, 6752, 6766, 6780,
+ 6801, 6824, 6845, 6868, 6890, 6911, 6932, 6951,
+ 6972, 6978, 6984, 6990, 6996, 6998, 7000, 7021,
+ 7035, 7049, 7060, 7073, 7086, 7107, 7128, 7147,
+ 7168, 7174, 7180, 7186, 7192, 7194, 7196, 7217,
+ 7238, 7261, 7283, 7304, 7325, 7344, 7365, 7371,
+ 7377, 7383, 7389, 7391, 7393, 7414, 7428, 7442,
+ 7453, 7466, 7479, 7490, 7493, 7496, 7499, 7502,
+ 7505, 7525, 7530, 7550, 7571, 7593, 7614, 7635,
+ 7654, 7675, 7682, 7689, 7696, 7703, 7706, 7709,
+ 7730, 7748, 7764, 7788, 7801, 7823, 7845, 7859,
+ 7873, 7887, 7890, 7893, 7896, 7899, 7902, 7905,
+ 7912, 7915, 7918, 7933, 7948, 7960, 7974, 7988,
+ 8010, 8031, 8052, 8071, 8092, 8098, 8104, 8110,
+ 8116, 8118, 8120, 8141, 8155, 8169, 8180, 8193,
+ 8206, 8220, 8234, 8245, 8258, 8271, 8292, 8315,
+ 8337, 8358, 8379, 8398, 8419, 8424, 8429, 8434,
+ 8439, 8440, 8441, 8462, 8475, 8488, 8498, 8510,
+ 8522, 8523, 8529, 8550, 8573, 8581, 8602, 8623,
+ 8646, 8653, 8674, 8697, 8718, 8741, 8748, 8762,
+ 8771, 8792, 8815, 8823, 8844, 8865, 8888, 8895,
+ 8909, 8918, 8939, 8962, 8970, 8991, 9012, 9035,
+ 9042, 9056, 9065, 9086, 9099, 9107, 9128, 9149,
+ 9162, 9170, 9191, 9214, 9222, 9243, 9257, 9266,
+ 9287, 9300, 9308, 9321, 9329, 9350, 9362
+};
+
+static readonly char[] _selector_trans_keys = new char [] {
+ '\u0020', '\u002d', '\u0037', '\u003b', '\u005c', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u0031', '\u0037', '\u005c', '\u0000', '\u0031',
+ '\u0020', '\u003a', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002c', '\u002e', '\u002f', '\u0020', '\u003a', '\u0009', '\u000d', '\u0020',
+ '\u0022', '\u0027', '\u002b', '\u002d', '\u0037', '\u005c', '\u0075', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002f', '\u0030', '\u0031', '\u0032',
+ '\u0039', '\u0022', '\u0020', '\u0021', '\u0022', '\u0027', '\u002b', '\u002c',
+ '\u002d', '\u002f', '\u0037', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002e', '\u0030', '\u0031', '\u0032', '\u0039',
+ '\u0049', '\u0069', '\u004d', '\u006d', '\u0050', '\u0070', '\u004f', '\u006f',
+ '\u0052', '\u0072', '\u0054', '\u0074', '\u0041', '\u0061', '\u004e', '\u006e',
+ '\u0054', '\u0074', '\u0020', '\u003b', '\u007d', '\u0009', '\u000d', '\u002d',
+ '\u003e', '\u0021', '\u002d', '\u002d', '\u0027', '\u0030', '\u0039', '\u0020',
+ '\u0021', '\u0022', '\u0025', '\u0027', '\u002b', '\u002d', '\u002e', '\u0037',
+ '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002a', '\u002c', '\u002f', '\u0030', '\u0031', '\u0032', '\u0039', '\u0037',
+ '\u005c', '\u0000', '\u002f', '\u0030', '\u0031', '\u0032', '\u0039', '\u0020',
+ '\u0021', '\u0022', '\u0025', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e',
+ '\u002f', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002a', '\u0030', '\u0039', '\u0020', '\u0029', '\u0009', '\u000d',
+ '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e',
+ '\u002f', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002a', '\u0030', '\u0039', '\u000a', '\u0022', '\u0027', '\u0028',
+ '\u005c', '\u0075', '\u007d', '\u000c', '\u000d', '\u0030', '\u0039', '\u0041',
+ '\u0046', '\u0061', '\u0066', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028',
+ '\u002b', '\u002c', '\u002e', '\u002f', '\u005c', '\u0075', '\u007d', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020',
+ '\u0021', '\u0022', '\u0027', '\u002b', '\u002c', '\u002d', '\u002f', '\u0037',
+ '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002e', '\u0030', '\u0031', '\u0032', '\u0039', '\u0022', '\u0049', '\u0069',
+ '\u0022', '\u004d', '\u006d', '\u0022', '\u0050', '\u0070', '\u0022', '\u004f',
+ '\u006f', '\u0022', '\u0052', '\u0072', '\u0022', '\u0054', '\u0074', '\u0022',
+ '\u0041', '\u0061', '\u0022', '\u004e', '\u006e', '\u0022', '\u0054', '\u0074',
+ '\u0020', '\u0022', '\u003b', '\u007d', '\u0009', '\u000d', '\u0020', '\u0022',
+ '\u002d', '\u0037', '\u003b', '\u005c', '\u007d', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u0031', '\u0022', '\u0037', '\u005c', '\u0000', '\u0031',
+ '\u0020', '\u0022', '\u003a', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002c', '\u002e', '\u002f', '\u0020', '\u0022', '\u003a', '\u0009',
+ '\u000d', '\u0020', '\u0022', '\u0027', '\u002b', '\u002d', '\u0037', '\u005c',
+ '\u0075', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002f', '\u0030',
+ '\u0031', '\u0032', '\u0039', '\u0022', '\u0027', '\u0020', '\u0021', '\u0022',
+ '\u0027', '\u002b', '\u002c', '\u002d', '\u002f', '\u0037', '\u005c', '\u0075',
+ '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002e', '\u0030',
+ '\u0031', '\u0032', '\u0039', '\u0027', '\u0049', '\u0069', '\u0027', '\u004d',
+ '\u006d', '\u0027', '\u0050', '\u0070', '\u0027', '\u004f', '\u006f', '\u0027',
+ '\u0052', '\u0072', '\u0027', '\u0054', '\u0074', '\u0027', '\u0041', '\u0061',
+ '\u0027', '\u004e', '\u006e', '\u0027', '\u0054', '\u0074', '\u0020', '\u0027',
+ '\u003b', '\u007d', '\u0009', '\u000d', '\u0020', '\u0027', '\u002d', '\u0037',
+ '\u003b', '\u005c', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u0031', '\u0027', '\u0037', '\u005c', '\u0000', '\u0031', '\u0020', '\u0027',
+ '\u003a', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002c',
+ '\u002e', '\u002f', '\u0020', '\u0027', '\u003a', '\u0009', '\u000d', '\u0020',
+ '\u0022', '\u0027', '\u002b', '\u002d', '\u0037', '\u005c', '\u0075', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002f', '\u0030', '\u0031', '\u0032',
+ '\u0039', '\u0027', '\u0030', '\u0039', '\u0020', '\u0021', '\u0022', '\u0025',
+ '\u0027', '\u002b', '\u002d', '\u002e', '\u0037', '\u005c', '\u0075', '\u007d',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u002c', '\u002f',
+ '\u0030', '\u0031', '\u0032', '\u0039', '\u0027', '\u0037', '\u005c', '\u0000',
+ '\u002f', '\u0030', '\u0031', '\u0032', '\u0039', '\u0020', '\u0021', '\u0022',
+ '\u0025', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u005c',
+ '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a',
+ '\u0030', '\u0039', '\u0020', '\u0027', '\u0029', '\u0009', '\u000d', '\u0020',
+ '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f',
+ '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002a', '\u0030', '\u0039', '\u000a', '\u0022', '\u0028', '\u005c', '\u0075',
+ '\u007d', '\u000c', '\u000d', '\u0030', '\u0039', '\u0041', '\u0046', '\u0061',
+ '\u0066', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c',
+ '\u002e', '\u002f', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020', '\u0021', '\u0022',
+ '\u0027', '\u002b', '\u002c', '\u002d', '\u002f', '\u0037', '\u005c', '\u0075',
+ '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002e', '\u0030',
+ '\u0031', '\u0032', '\u0039', '\u0022', '\u0027', '\u0049', '\u0069', '\u0022',
+ '\u0027', '\u004d', '\u006d', '\u0022', '\u0027', '\u0050', '\u0070', '\u0022',
+ '\u0027', '\u004f', '\u006f', '\u0022', '\u0027', '\u0052', '\u0072', '\u0022',
+ '\u0027', '\u0054', '\u0074', '\u0022', '\u0027', '\u0041', '\u0061', '\u0022',
+ '\u0027', '\u004e', '\u006e', '\u0022', '\u0027', '\u0054', '\u0074', '\u0020',
+ '\u0022', '\u0027', '\u003b', '\u007d', '\u0009', '\u000d', '\u0020', '\u0022',
+ '\u0027', '\u002d', '\u0037', '\u003b', '\u005c', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u0031', '\u0022', '\u0027', '\u0037', '\u005c',
+ '\u0000', '\u0031', '\u0020', '\u0022', '\u0027', '\u003a', '\u005c', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002c', '\u002e', '\u002f', '\u0020',
+ '\u0022', '\u0027', '\u003a', '\u0009', '\u000d', '\u0020', '\u0022', '\u0027',
+ '\u002b', '\u002d', '\u0037', '\u005c', '\u0075', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u002f', '\u0030', '\u0031', '\u0032', '\u0039', '\u0022',
+ '\u0027', '\u0030', '\u0039', '\u0020', '\u0021', '\u0022', '\u0025', '\u0027',
+ '\u002b', '\u002d', '\u002e', '\u0037', '\u005c', '\u0075', '\u007d', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u002c', '\u002f', '\u0030',
+ '\u0031', '\u0032', '\u0039', '\u0022', '\u0027', '\u0037', '\u005c', '\u0000',
+ '\u002f', '\u0030', '\u0031', '\u0032', '\u0039', '\u0020', '\u0021', '\u0022',
+ '\u0025', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u005c',
+ '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a',
+ '\u0030', '\u0039', '\u0020', '\u0022', '\u0027', '\u0029', '\u0009', '\u000d',
+ '\u0022', '\u0027', '\u0030', '\u0039', '\u0020', '\u0021', '\u0022', '\u0025',
+ '\u0027', '\u002b', '\u002c', '\u002d', '\u002f', '\u0037', '\u005c', '\u0075',
+ '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002e', '\u0030',
+ '\u0031', '\u0032', '\u0039', '\u000a', '\u0028', '\u005c', '\u0075', '\u007d',
+ '\u000c', '\u000d', '\u0030', '\u0039', '\u0041', '\u0046', '\u0061', '\u0066',
+ '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u0029', '\u002b', '\u002c',
+ '\u002e', '\u002f', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020', '\u0021', '\u0022',
+ '\u0027', '\u0029', '\u002b', '\u002c', '\u002d', '\u002f', '\u0037', '\u005c',
+ '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002e',
+ '\u0030', '\u0031', '\u0032', '\u0039', '\u0020', '\u0021', '\u0022', '\u0027',
+ '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u005c', '\u0072', '\u0075',
+ '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030',
+ '\u0039', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c',
+ '\u002e', '\u002f', '\u005c', '\u006c', '\u0075', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020', '\u0021',
+ '\u0022', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u005c',
+ '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a',
+ '\u0030', '\u0039', '\u0020', '\u0022', '\u0027', '\u0028', '\u0029', '\u005c',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u001f', '\u0020', '\u0022',
+ '\u0027', '\u0028', '\u0029', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u001f', '\u0020', '\u0022', '\u0027', '\u0028', '\u0029', '\u005c',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u001f', '\u0030', '\u0039',
+ '\u0041', '\u0046', '\u0061', '\u0066', '\u0020', '\u0022', '\u0027', '\u0028',
+ '\u0029', '\u005c', '\u007b', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u001f', '\u0020', '\u0022', '\u0027', '\u0028', '\u0029', '\u0031', '\u005c',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u001f', '\u0020', '\u0022',
+ '\u0027', '\u0028', '\u0029', '\u002c', '\u005c', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u001f', '\u0020', '\u0022', '\u0027', '\u0028', '\u0029',
+ '\u0036', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u001f',
+ '\u0020', '\u0022', '\u0027', '\u0028', '\u0029', '\u005c', '\u007d', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u001f', '\u0020', '\u0022', '\u0027',
+ '\u0028', '\u0029', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u001f', '\u000d', '\u0022', '\u0027', '\u000a', '\u0022', '\u0027', '\u0022',
+ '\u0027', '\u007c', '\u0020', '\u0022', '\u0027', '\u0009', '\u000a', '\u000c',
+ '\u000d', '\u0022', '\u0027', '\u0029', '\u0022', '\u0027', '\u003f', '\u0020',
+ '\u0021', '\u0022', '\u0027', '\u002b', '\u002c', '\u002d', '\u002f', '\u0037',
+ '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002e', '\u0030', '\u0031', '\u0032', '\u0039', '\u0022', '\u0027', '\u0020',
+ '\u0021', '\u0022', '\u0027', '\u002b', '\u002c', '\u002d', '\u002f', '\u0037',
+ '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002e', '\u0030', '\u0031', '\u0032', '\u0039', '\u0022', '\u0022', '\u0049',
+ '\u0069', '\u0022', '\u004d', '\u006d', '\u0022', '\u0050', '\u0070', '\u0022',
+ '\u004f', '\u006f', '\u0022', '\u0052', '\u0072', '\u0022', '\u0054', '\u0074',
+ '\u0022', '\u0041', '\u0061', '\u0022', '\u004e', '\u006e', '\u0022', '\u0054',
+ '\u0074', '\u0020', '\u0022', '\u003b', '\u007d', '\u0009', '\u000d', '\u0020',
+ '\u0022', '\u002d', '\u0037', '\u003b', '\u005c', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u0031', '\u0022', '\u0037', '\u005c', '\u0000',
+ '\u0031', '\u0020', '\u0022', '\u003a', '\u005c', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u002c', '\u002e', '\u002f', '\u0020', '\u0022', '\u003a',
+ '\u0009', '\u000d', '\u0020', '\u0022', '\u0027', '\u002b', '\u002d', '\u0037',
+ '\u005c', '\u0075', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002f',
+ '\u0030', '\u0031', '\u0032', '\u0039', '\u0020', '\u0022', '\u0029', '\u0009',
+ '\u000d', '\u0022', '\u0030', '\u0039', '\u0020', '\u0021', '\u0022', '\u0025',
+ '\u0027', '\u002b', '\u002d', '\u002e', '\u0037', '\u005c', '\u0075', '\u007d',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u002c', '\u002f',
+ '\u0030', '\u0031', '\u0032', '\u0039', '\u0022', '\u0037', '\u005c', '\u0000',
+ '\u002f', '\u0030', '\u0031', '\u0032', '\u0039', '\u0020', '\u0021', '\u0022',
+ '\u0025', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u005c',
+ '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a',
+ '\u0030', '\u0039', '\u0020', '\u0022', '\u0029', '\u0009', '\u000d', '\u0020',
+ '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f',
+ '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002a', '\u0030', '\u0039', '\u000a', '\u0022', '\u0027', '\u0028', '\u005c',
+ '\u0075', '\u007d', '\u000c', '\u000d', '\u0030', '\u0039', '\u0041', '\u0046',
+ '\u0061', '\u0066', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u0029',
+ '\u002b', '\u002c', '\u002e', '\u002f', '\u005c', '\u0075', '\u007d', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020',
+ '\u0021', '\u0022', '\u0027', '\u0029', '\u002b', '\u002c', '\u002d', '\u002f',
+ '\u0037', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002e', '\u0030', '\u0031', '\u0032', '\u0039', '\u0022', '\u0030',
+ '\u0039', '\u0020', '\u0021', '\u0022', '\u0025', '\u0027', '\u002b', '\u002d',
+ '\u002e', '\u0037', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u002a', '\u002c', '\u002f', '\u0030', '\u0031', '\u0032',
+ '\u0039', '\u0022', '\u0037', '\u005c', '\u0000', '\u002f', '\u0030', '\u0031',
+ '\u0032', '\u0039', '\u0020', '\u0021', '\u0022', '\u0025', '\u0027', '\u0028',
+ '\u002b', '\u002c', '\u002e', '\u002f', '\u005c', '\u0075', '\u007d', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0022',
+ '\u0030', '\u0039', '\u0020', '\u0021', '\u0022', '\u0025', '\u0027', '\u002b',
+ '\u002c', '\u002d', '\u002f', '\u0037', '\u005c', '\u0075', '\u007d', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002e', '\u0030', '\u0031', '\u0032',
+ '\u0039', '\u000a', '\u0027', '\u0028', '\u005c', '\u0075', '\u007d', '\u000c',
+ '\u000d', '\u0030', '\u0039', '\u0041', '\u0046', '\u0061', '\u0066', '\u0020',
+ '\u0021', '\u0022', '\u0025', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e',
+ '\u002f', '\u005c', '\u0075', '\u007b', '\u007d', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020', '\u0021', '\u0022',
+ '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u005c', '\u0072',
+ '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a',
+ '\u0030', '\u0039', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b',
+ '\u002c', '\u002e', '\u002f', '\u005c', '\u006c', '\u0075', '\u007d', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020',
+ '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f',
+ '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002a', '\u0030', '\u0039', '\u0020', '\u0022', '\u0027', '\u0028', '\u0029',
+ '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u001f', '\u0020',
+ '\u0022', '\u0029', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u001f', '\u0027', '\u0028', '\u0020', '\u0022', '\u0029', '\u005c', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u001f', '\u0027', '\u0028', '\u0030',
+ '\u0039', '\u0041', '\u0046', '\u0061', '\u0066', '\u0020', '\u0022', '\u0029',
+ '\u005c', '\u007b', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u001f',
+ '\u0027', '\u0028', '\u0020', '\u0022', '\u0029', '\u0031', '\u005c', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u001f', '\u0027', '\u0028', '\u0020',
+ '\u0022', '\u0029', '\u002c', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u001f', '\u0027', '\u0028', '\u0020', '\u0022', '\u0029', '\u0036',
+ '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u001f', '\u0027',
+ '\u0028', '\u0020', '\u0022', '\u0029', '\u005c', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u001f', '\u0027', '\u0028', '\u0020', '\u0022',
+ '\u0027', '\u0028', '\u0029', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u001f', '\u000d', '\u0022', '\u000a', '\u0022', '\u0022', '\u007c',
+ '\u0020', '\u0022', '\u0009', '\u000a', '\u000c', '\u000d', '\u0022', '\u0029',
+ '\u0022', '\u003f', '\u0022', '\u0027', '\u0020', '\u0021', '\u0022', '\u0027',
+ '\u002b', '\u002c', '\u002d', '\u002f', '\u0037', '\u005c', '\u0075', '\u007d',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002e', '\u0030', '\u0031',
+ '\u0032', '\u0039', '\u0027', '\u0027', '\u0049', '\u0069', '\u0027', '\u004d',
+ '\u006d', '\u0027', '\u0050', '\u0070', '\u0027', '\u004f', '\u006f', '\u0027',
+ '\u0052', '\u0072', '\u0027', '\u0054', '\u0074', '\u0027', '\u0041', '\u0061',
+ '\u0027', '\u004e', '\u006e', '\u0027', '\u0054', '\u0074', '\u0020', '\u0027',
+ '\u003b', '\u007d', '\u0009', '\u000d', '\u0020', '\u0027', '\u002d', '\u0037',
+ '\u003b', '\u005c', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u0031', '\u0027', '\u0037', '\u005c', '\u0000', '\u0031', '\u0020', '\u0027',
+ '\u003a', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002c',
+ '\u002e', '\u002f', '\u0020', '\u0027', '\u003a', '\u0009', '\u000d', '\u0020',
+ '\u0022', '\u0027', '\u002b', '\u002d', '\u0037', '\u005c', '\u0075', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002f', '\u0030', '\u0031', '\u0032',
+ '\u0039', '\u0027', '\u0030', '\u0039', '\u0020', '\u0021', '\u0022', '\u0025',
+ '\u0027', '\u002b', '\u002d', '\u002e', '\u0037', '\u005c', '\u0075', '\u007d',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u002c', '\u002f',
+ '\u0030', '\u0031', '\u0032', '\u0039', '\u0027', '\u0037', '\u005c', '\u0000',
+ '\u002f', '\u0030', '\u0031', '\u0032', '\u0039', '\u0020', '\u0021', '\u0022',
+ '\u0025', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u005c',
+ '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a',
+ '\u0030', '\u0039', '\u0020', '\u0027', '\u0029', '\u0009', '\u000d', '\u0020',
+ '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f',
+ '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002a', '\u0030', '\u0039', '\u000a', '\u0022', '\u0027', '\u0028', '\u005c',
+ '\u0075', '\u007d', '\u000c', '\u000d', '\u0030', '\u0039', '\u0041', '\u0046',
+ '\u0061', '\u0066', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b',
+ '\u002c', '\u002e', '\u002f', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020', '\u0021',
+ '\u0022', '\u0027', '\u002b', '\u002c', '\u002d', '\u002f', '\u0037', '\u005c',
+ '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002e',
+ '\u0030', '\u0031', '\u0032', '\u0039', '\u0022', '\u0027', '\u0049', '\u0069',
+ '\u0022', '\u0027', '\u004d', '\u006d', '\u0022', '\u0027', '\u0050', '\u0070',
+ '\u0022', '\u0027', '\u004f', '\u006f', '\u0022', '\u0027', '\u0052', '\u0072',
+ '\u0022', '\u0027', '\u0054', '\u0074', '\u0022', '\u0027', '\u0041', '\u0061',
+ '\u0022', '\u0027', '\u004e', '\u006e', '\u0022', '\u0027', '\u0054', '\u0074',
+ '\u0020', '\u0022', '\u0027', '\u003b', '\u007d', '\u0009', '\u000d', '\u0020',
+ '\u0022', '\u0027', '\u002d', '\u0037', '\u003b', '\u005c', '\u007d', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u0031', '\u0022', '\u0027', '\u0037',
+ '\u005c', '\u0000', '\u0031', '\u0020', '\u0022', '\u0027', '\u003a', '\u005c',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002c', '\u002e', '\u002f',
+ '\u0020', '\u0022', '\u0027', '\u003a', '\u0009', '\u000d', '\u0020', '\u0022',
+ '\u0027', '\u002b', '\u002d', '\u0037', '\u005c', '\u0075', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002f', '\u0030', '\u0031', '\u0032', '\u0039',
+ '\u0022', '\u0027', '\u0030', '\u0039', '\u0020', '\u0021', '\u0022', '\u0025',
+ '\u0027', '\u002b', '\u002d', '\u002e', '\u0037', '\u005c', '\u0075', '\u007d',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u002c', '\u002f',
+ '\u0030', '\u0031', '\u0032', '\u0039', '\u0022', '\u0027', '\u0037', '\u005c',
+ '\u0000', '\u002f', '\u0030', '\u0031', '\u0032', '\u0039', '\u0020', '\u0021',
+ '\u0022', '\u0025', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f',
+ '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002a', '\u0030', '\u0039', '\u0020', '\u0022', '\u0027', '\u0029', '\u0009',
+ '\u000d', '\u0022', '\u0027', '\u0030', '\u0039', '\u0020', '\u0021', '\u0022',
+ '\u0025', '\u0027', '\u002b', '\u002c', '\u002d', '\u002f', '\u0037', '\u005c',
+ '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002e',
+ '\u0030', '\u0031', '\u0032', '\u0039', '\u000a', '\u0027', '\u0028', '\u005c',
+ '\u0075', '\u007d', '\u000c', '\u000d', '\u0030', '\u0039', '\u0041', '\u0046',
+ '\u0061', '\u0066', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u0029',
+ '\u002b', '\u002c', '\u002e', '\u002f', '\u005c', '\u0075', '\u007d', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020',
+ '\u0021', '\u0022', '\u0027', '\u0029', '\u002b', '\u002c', '\u002d', '\u002f',
+ '\u0037', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002e', '\u0030', '\u0031', '\u0032', '\u0039', '\u0020', '\u0021',
+ '\u0022', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u005c',
+ '\u0072', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002a', '\u0030', '\u0039', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028',
+ '\u002b', '\u002c', '\u002e', '\u002f', '\u005c', '\u006c', '\u0075', '\u007d',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039',
+ '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e',
+ '\u002f', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002a', '\u0030', '\u0039', '\u0020', '\u0022', '\u0027', '\u0028',
+ '\u0029', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u001f',
+ '\u0020', '\u0022', '\u0027', '\u0028', '\u0029', '\u005c', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u001f', '\u0020', '\u0022', '\u0027', '\u0028',
+ '\u0029', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u001f',
+ '\u0030', '\u0039', '\u0041', '\u0046', '\u0061', '\u0066', '\u0020', '\u0022',
+ '\u0027', '\u0028', '\u0029', '\u005c', '\u007b', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u001f', '\u0020', '\u0022', '\u0027', '\u0028', '\u0029',
+ '\u0031', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u001f',
+ '\u0020', '\u0022', '\u0027', '\u0028', '\u0029', '\u002c', '\u005c', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u001f', '\u0020', '\u0022', '\u0027',
+ '\u0028', '\u0029', '\u0036', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u001f', '\u0020', '\u0022', '\u0027', '\u0028', '\u0029', '\u005c',
+ '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u001f', '\u0020',
+ '\u0022', '\u0027', '\u0028', '\u0029', '\u005c', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u001f', '\u000d', '\u0022', '\u0027', '\u000a', '\u0022',
+ '\u0027', '\u0022', '\u0027', '\u007c', '\u0020', '\u0022', '\u0027', '\u0009',
+ '\u000a', '\u000c', '\u000d', '\u0022', '\u0027', '\u0029', '\u0022', '\u0027',
+ '\u003f', '\u0020', '\u0021', '\u0022', '\u0027', '\u002b', '\u002c', '\u002d',
+ '\u002f', '\u0037', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u002e', '\u0030', '\u0031', '\u0032', '\u0039', '\u0022',
+ '\u0027', '\u0022', '\u0027', '\u0049', '\u0069', '\u0022', '\u0027', '\u004d',
+ '\u006d', '\u0022', '\u0027', '\u0050', '\u0070', '\u0022', '\u0027', '\u004f',
+ '\u006f', '\u0022', '\u0027', '\u0052', '\u0072', '\u0022', '\u0027', '\u0054',
+ '\u0074', '\u0022', '\u0027', '\u0041', '\u0061', '\u0022', '\u0027', '\u004e',
+ '\u006e', '\u0022', '\u0027', '\u0054', '\u0074', '\u0020', '\u0022', '\u0027',
+ '\u003b', '\u007d', '\u0009', '\u000d', '\u0020', '\u0022', '\u0027', '\u002d',
+ '\u0037', '\u003b', '\u005c', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u0031', '\u0022', '\u0027', '\u0037', '\u005c', '\u0000', '\u0031',
+ '\u0020', '\u0022', '\u0027', '\u003a', '\u005c', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u002c', '\u002e', '\u002f', '\u0020', '\u0022', '\u0027',
+ '\u003a', '\u0009', '\u000d', '\u0020', '\u0022', '\u0027', '\u002b', '\u002d',
+ '\u0037', '\u005c', '\u0075', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002f', '\u0030', '\u0031', '\u0032', '\u0039', '\u0020', '\u0022', '\u0027',
+ '\u0029', '\u0009', '\u000d', '\u0022', '\u0027', '\u0030', '\u0039', '\u0020',
+ '\u0021', '\u0022', '\u0025', '\u0027', '\u002b', '\u002d', '\u002e', '\u0037',
+ '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002a', '\u002c', '\u002f', '\u0030', '\u0031', '\u0032', '\u0039', '\u0022',
+ '\u0027', '\u0037', '\u005c', '\u0000', '\u002f', '\u0030', '\u0031', '\u0032',
+ '\u0039', '\u0020', '\u0021', '\u0022', '\u0025', '\u0027', '\u0028', '\u002b',
+ '\u002c', '\u002e', '\u002f', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020', '\u0022',
+ '\u0027', '\u0029', '\u0009', '\u000d', '\u0020', '\u0021', '\u0022', '\u0027',
+ '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u005c', '\u0075', '\u007d',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039',
+ '\u000a', '\u0022', '\u0027', '\u0028', '\u005c', '\u0075', '\u007d', '\u000c',
+ '\u000d', '\u0030', '\u0039', '\u0041', '\u0046', '\u0061', '\u0066', '\u0020',
+ '\u0021', '\u0022', '\u0027', '\u0028', '\u0029', '\u002b', '\u002c', '\u002e',
+ '\u002f', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002a', '\u0030', '\u0039', '\u0020', '\u0021', '\u0022', '\u0027',
+ '\u0029', '\u002b', '\u002c', '\u002d', '\u002f', '\u0037', '\u005c', '\u0075',
+ '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002e', '\u0030',
+ '\u0031', '\u0032', '\u0039', '\u0022', '\u0027', '\u0049', '\u0069', '\u0022',
+ '\u0027', '\u004d', '\u006d', '\u0022', '\u0027', '\u0050', '\u0070', '\u0022',
+ '\u0027', '\u004f', '\u006f', '\u0022', '\u0027', '\u0052', '\u0072', '\u0022',
+ '\u0027', '\u0054', '\u0074', '\u0022', '\u0027', '\u0041', '\u0061', '\u0022',
+ '\u0027', '\u004e', '\u006e', '\u0022', '\u0027', '\u0054', '\u0074', '\u0020',
+ '\u0022', '\u0027', '\u003b', '\u007d', '\u0009', '\u000d', '\u0020', '\u0022',
+ '\u0027', '\u002d', '\u0037', '\u003b', '\u005c', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u0031', '\u0022', '\u0027', '\u0037', '\u005c',
+ '\u0000', '\u0031', '\u0020', '\u0022', '\u0027', '\u003a', '\u005c', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002c', '\u002e', '\u002f', '\u0020',
+ '\u0022', '\u0027', '\u003a', '\u0009', '\u000d', '\u0020', '\u0022', '\u0027',
+ '\u002b', '\u002d', '\u0037', '\u005c', '\u0075', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u002f', '\u0030', '\u0031', '\u0032', '\u0039', '\u0022',
+ '\u0027', '\u0030', '\u0039', '\u0020', '\u0021', '\u0022', '\u0025', '\u0027',
+ '\u002b', '\u002d', '\u002e', '\u0037', '\u005c', '\u0075', '\u007d', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u002c', '\u002f', '\u0030',
+ '\u0031', '\u0032', '\u0039', '\u0022', '\u0027', '\u0037', '\u005c', '\u0000',
+ '\u002f', '\u0030', '\u0031', '\u0032', '\u0039', '\u0020', '\u0021', '\u0022',
+ '\u0025', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u005c',
+ '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a',
+ '\u0030', '\u0039', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b',
+ '\u002c', '\u002e', '\u002f', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u000a', '\u0022',
+ '\u0028', '\u005c', '\u0075', '\u007d', '\u000c', '\u000d', '\u0030', '\u0039',
+ '\u0041', '\u0046', '\u0061', '\u0066', '\u0020', '\u0021', '\u0022', '\u0025',
+ '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u005c', '\u0075',
+ '\u007b', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a',
+ '\u0030', '\u0039', '\u0022', '\u0027', '\u0030', '\u0039', '\u0020', '\u0021',
+ '\u0022', '\u0025', '\u0027', '\u002b', '\u002c', '\u002d', '\u002f', '\u0037',
+ '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002e', '\u0030', '\u0031', '\u0032', '\u0039', '\u0020', '\u0021', '\u0022',
+ '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u005c', '\u0072',
+ '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a',
+ '\u0030', '\u0039', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b',
+ '\u002c', '\u002e', '\u002f', '\u005c', '\u006c', '\u0075', '\u007d', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020',
+ '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f',
+ '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002a', '\u0030', '\u0039', '\u0020', '\u0022', '\u0027', '\u0028', '\u0029',
+ '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u001f', '\u0020',
+ '\u0022', '\u0027', '\u0028', '\u0029', '\u005c', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u001f', '\u0020', '\u0022', '\u0027', '\u0028', '\u0029',
+ '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u001f', '\u0030',
+ '\u0039', '\u0041', '\u0046', '\u0061', '\u0066', '\u0020', '\u0022', '\u0027',
+ '\u0028', '\u0029', '\u005c', '\u007b', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u001f', '\u0020', '\u0022', '\u0027', '\u0028', '\u0029', '\u0031',
+ '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u001f', '\u0020',
+ '\u0022', '\u0027', '\u0028', '\u0029', '\u002c', '\u005c', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u001f', '\u0020', '\u0022', '\u0027', '\u0028',
+ '\u0029', '\u0036', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u001f', '\u0020', '\u0022', '\u0027', '\u0028', '\u0029', '\u005c', '\u007d',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u001f', '\u0020', '\u0022',
+ '\u0027', '\u0028', '\u0029', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u001f', '\u000d', '\u0022', '\u0027', '\u000a', '\u0022', '\u0027',
+ '\u0022', '\u0027', '\u007c', '\u0020', '\u0022', '\u0027', '\u0009', '\u000a',
+ '\u000c', '\u000d', '\u0022', '\u0027', '\u0029', '\u0022', '\u0027', '\u003f',
+ '\u0022', '\u0027', '\u002d', '\u0037', '\u005c', '\u0000', '\u002f', '\u0030',
+ '\u0031', '\u0032', '\u0039', '\u0022', '\u0027', '\u003e', '\u0022', '\u0027',
+ '\u002d', '\u0021', '\u0022', '\u0027', '\u0022', '\u0027', '\u002d', '\u0022',
+ '\u0027', '\u002d', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b',
+ '\u002c', '\u002e', '\u002f', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0022', '\u0027',
+ '\u002d', '\u0049', '\u0069', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028',
+ '\u002b', '\u002c', '\u002d', '\u002f', '\u005c', '\u0075', '\u007d', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002e', '\u0030', '\u0039', '\u0020',
+ '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f',
+ '\u003e', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002a', '\u0030', '\u0039', '\u0020', '\u0021', '\u0022', '\u0027',
+ '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u0031', '\u005c', '\u0075',
+ '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030',
+ '\u0039', '\u0020', '\u0021', '\u0022', '\u0025', '\u0027', '\u0028', '\u002b',
+ '\u002c', '\u002e', '\u002f', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020', '\u0022',
+ '\u0027', '\u002b', '\u002d', '\u0036', '\u0037', '\u005c', '\u0075', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002f', '\u0030', '\u0031', '\u0032',
+ '\u0039', '\u0020', '\u0021', '\u0022', '\u0025', '\u0027', '\u0028', '\u002b',
+ '\u002c', '\u002e', '\u002f', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u000d', '\u0020',
+ '\u0022', '\u0027', '\u0029', '\u0009', '\u000c', '\u000a', '\u0020', '\u0022',
+ '\u0027', '\u0029', '\u0009', '\u000d', '\u0020', '\u0022', '\u0027', '\u0029',
+ '\u007c', '\u0009', '\u000d', '\u0020', '\u0022', '\u0027', '\u0009', '\u000a',
+ '\u000c', '\u000d', '\u0022', '\u0027', '\u0029', '\u0022', '\u0027', '\u003f',
+ '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e',
+ '\u002f', '\u005c', '\u0075', '\u007b', '\u007d', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020', '\u0022', '\u0027',
+ '\u002b', '\u002d', '\u0037', '\u005c', '\u0075', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u002f', '\u0030', '\u0031', '\u0032', '\u0039', '\u0020',
+ '\u0022', '\u0027', '\u002d', '\u0037', '\u005c', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u002f', '\u0030', '\u0031', '\u0032', '\u0039', '\u0020',
+ '\u0021', '\u0022', '\u0025', '\u0027', '\u002b', '\u002d', '\u002e', '\u0037',
+ '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002a', '\u002c', '\u002f', '\u0030', '\u0031', '\u0032', '\u0039', '\u000a',
+ '\u0022', '\u0027', '\u003a', '\u005c', '\u000c', '\u000d', '\u0030', '\u0039',
+ '\u0041', '\u0046', '\u0061', '\u0066', '\u0020', '\u0027', '\u0029', '\u003a',
+ '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002c', '\u002e',
+ '\u002f', '\u0020', '\u0027', '\u0029', '\u003a', '\u0009', '\u000d', '\u0020',
+ '\u0022', '\u0027', '\u002b', '\u002d', '\u0037', '\u005c', '\u0075', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002f', '\u0030', '\u0031', '\u0032',
+ '\u0039', '\u0020', '\u0027', '\u002d', '\u0037', '\u005c', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002f', '\u0030', '\u0031', '\u0032', '\u0039',
+ '\u0020', '\u0021', '\u0022', '\u0025', '\u0027', '\u002b', '\u002d', '\u002e',
+ '\u0037', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002a', '\u002c', '\u002f', '\u0030', '\u0031', '\u0032', '\u0039',
+ '\u0027', '\u0030', '\u0039', '\u0020', '\u0021', '\u0022', '\u0025', '\u0027',
+ '\u002b', '\u002c', '\u002d', '\u002f', '\u0037', '\u005c', '\u0075', '\u007d',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002e', '\u0030', '\u0031',
+ '\u0032', '\u0039', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b',
+ '\u002c', '\u002e', '\u002f', '\u005c', '\u0072', '\u0075', '\u007d', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020',
+ '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f',
+ '\u005c', '\u006c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002a', '\u0030', '\u0039', '\u0020', '\u0021', '\u0022', '\u0027',
+ '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u005c', '\u0075', '\u007d',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039',
+ '\u0020', '\u0022', '\u0027', '\u0028', '\u0029', '\u005c', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u001f', '\u0020', '\u0022', '\u0027', '\u0028',
+ '\u0029', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u001f',
+ '\u0020', '\u0022', '\u0027', '\u0028', '\u0029', '\u005c', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u001f', '\u0030', '\u0039', '\u0041', '\u0046',
+ '\u0061', '\u0066', '\u0020', '\u0022', '\u0027', '\u0028', '\u0029', '\u005c',
+ '\u007b', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u001f', '\u0020',
+ '\u0022', '\u0027', '\u0028', '\u0029', '\u0031', '\u005c', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u001f', '\u0020', '\u0022', '\u0027', '\u0028',
+ '\u0029', '\u002c', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u001f', '\u0020', '\u0022', '\u0027', '\u0028', '\u0029', '\u0036', '\u005c',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u001f', '\u0020', '\u0022',
+ '\u0027', '\u0028', '\u0029', '\u005c', '\u007d', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u001f', '\u0020', '\u0022', '\u0027', '\u0028', '\u0029',
+ '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u001f', '\u000d',
+ '\u0027', '\u000a', '\u0027', '\u0027', '\u007c', '\u0020', '\u0027', '\u0009',
+ '\u000a', '\u000c', '\u000d', '\u0027', '\u0029', '\u0027', '\u003f', '\u0027',
+ '\u002d', '\u0037', '\u005c', '\u0000', '\u002f', '\u0030', '\u0031', '\u0032',
+ '\u0039', '\u0027', '\u003e', '\u0027', '\u002d', '\u0021', '\u0027', '\u0027',
+ '\u002d', '\u0027', '\u002d', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028',
+ '\u002b', '\u002c', '\u002e', '\u002f', '\u005c', '\u0075', '\u007d', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0027',
+ '\u002d', '\u0049', '\u0069', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028',
+ '\u002b', '\u002c', '\u002d', '\u002f', '\u005c', '\u0075', '\u007d', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002e', '\u0030', '\u0039', '\u0020',
+ '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f',
+ '\u003e', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002a', '\u0030', '\u0039', '\u000a', '\u0027', '\u003a', '\u005c',
+ '\u000c', '\u000d', '\u0030', '\u0039', '\u0041', '\u0046', '\u0061', '\u0066',
+ '\u0020', '\u0021', '\u0022', '\u0027', '\u002b', '\u002c', '\u002d', '\u002f',
+ '\u0037', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002e', '\u0030', '\u0031', '\u0032', '\u0039', '\u0020', '\u002d',
+ '\u0037', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002f',
+ '\u0030', '\u0031', '\u0032', '\u0039', '\u0020', '\u0021', '\u0022', '\u0025',
+ '\u0027', '\u002b', '\u002d', '\u002e', '\u0037', '\u005c', '\u0075', '\u007d',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u002c', '\u002f',
+ '\u0030', '\u0031', '\u0032', '\u0039', '\u0030', '\u0039', '\u0020', '\u0021',
+ '\u0022', '\u0025', '\u0027', '\u002b', '\u002c', '\u002d', '\u002f', '\u0037',
+ '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002e', '\u0030', '\u0031', '\u0032', '\u0039', '\u0020', '\u0021', '\u0022',
+ '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u005c', '\u0072',
+ '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a',
+ '\u0030', '\u0039', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b',
+ '\u002c', '\u002e', '\u002f', '\u005c', '\u006c', '\u0075', '\u007d', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020',
+ '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f',
+ '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002a', '\u0030', '\u0039', '\u0020', '\u0022', '\u0027', '\u0028', '\u0029',
+ '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u001f', '\u0020',
+ '\u0022', '\u0029', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u001f', '\u0027', '\u0028', '\u0020', '\u0022', '\u0029', '\u005c', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u001f', '\u0027', '\u0028', '\u0030',
+ '\u0039', '\u0041', '\u0046', '\u0061', '\u0066', '\u0020', '\u0022', '\u0029',
+ '\u005c', '\u007b', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u001f',
+ '\u0027', '\u0028', '\u0020', '\u0022', '\u0029', '\u0031', '\u005c', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u001f', '\u0027', '\u0028', '\u0020',
+ '\u0022', '\u0029', '\u002c', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u001f', '\u0027', '\u0028', '\u0020', '\u0022', '\u0029', '\u0036',
+ '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u001f', '\u0027',
+ '\u0028', '\u0020', '\u0022', '\u0029', '\u005c', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u001f', '\u0027', '\u0028', '\u0020', '\u0022',
+ '\u0027', '\u0028', '\u0029', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u001f', '\u000d', '\u000a', '\u007c', '\u0020', '\u0009', '\u000a',
+ '\u000c', '\u000d', '\u0029', '\u003f', '\u002d', '\u0037', '\u005c', '\u0000',
+ '\u002f', '\u0030', '\u0031', '\u0032', '\u0039', '\u0020', '\u0021', '\u0022',
+ '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u005c', '\u0075',
+ '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030',
+ '\u0039', '\u002d', '\u0049', '\u0069', '\u0020', '\u0021', '\u0022', '\u0027',
+ '\u0028', '\u002b', '\u002c', '\u002d', '\u002f', '\u005c', '\u0075', '\u007d',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002e', '\u0030', '\u0039',
+ '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e',
+ '\u002f', '\u003e', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020', '\u0027', '\u003a',
+ '\u005c', '\u007b', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002c',
+ '\u002e', '\u002f', '\u0020', '\u0027', '\u0031', '\u003a', '\u005c', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002c', '\u002e', '\u002f', '\u0020',
+ '\u0027', '\u002c', '\u003a', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002b', '\u002e', '\u002f', '\u0027', '\u0036', '\u0027', '\u007d',
+ '\u0027', '\u0028', '\u000d', '\u0027', '\u000a', '\u0027', '\u0027', '\u007c',
+ '\u0020', '\u0027', '\u0009', '\u000a', '\u000c', '\u000d', '\u0027', '\u0029',
+ '\u0027', '\u003f', '\u0020', '\u0021', '\u0022', '\u0027', '\u002b', '\u002c',
+ '\u002d', '\u002f', '\u0037', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002e', '\u0030', '\u0031', '\u0032', '\u0039',
+ '\u0020', '\u0022', '\u002d', '\u0037', '\u005c', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u002f', '\u0030', '\u0031', '\u0032', '\u0039', '\u0020',
+ '\u0021', '\u0022', '\u0025', '\u0027', '\u002b', '\u002d', '\u002e', '\u0037',
+ '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002a', '\u002c', '\u002f', '\u0030', '\u0031', '\u0032', '\u0039', '\u0022',
+ '\u0030', '\u0039', '\u0020', '\u0021', '\u0022', '\u0025', '\u0027', '\u002b',
+ '\u002c', '\u002d', '\u002f', '\u0037', '\u005c', '\u0075', '\u007d', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002e', '\u0030', '\u0031', '\u0032',
+ '\u0039', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c',
+ '\u002e', '\u002f', '\u005c', '\u0072', '\u0075', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020', '\u0021',
+ '\u0022', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u005c',
+ '\u006c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002a', '\u0030', '\u0039', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028',
+ '\u002b', '\u002c', '\u002e', '\u002f', '\u005c', '\u0075', '\u007d', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020',
+ '\u0022', '\u0027', '\u0028', '\u0029', '\u005c', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u001f', '\u0020', '\u0022', '\u0029', '\u005c', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u001f', '\u0027', '\u0028', '\u0020',
+ '\u0022', '\u0029', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u001f', '\u0027', '\u0028', '\u0030', '\u0039', '\u0041', '\u0046', '\u0061',
+ '\u0066', '\u0020', '\u0022', '\u0029', '\u005c', '\u007b', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u001f', '\u0027', '\u0028', '\u0020', '\u0022',
+ '\u0029', '\u0031', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u001f', '\u0027', '\u0028', '\u0020', '\u0022', '\u0029', '\u002c', '\u005c',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u001f', '\u0027', '\u0028',
+ '\u0020', '\u0022', '\u0029', '\u0036', '\u005c', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u001f', '\u0027', '\u0028', '\u0020', '\u0022', '\u0029',
+ '\u005c', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u001f',
+ '\u0027', '\u0028', '\u0020', '\u0022', '\u0027', '\u0028', '\u0029', '\u005c',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u001f', '\u000d', '\u0022',
+ '\u000a', '\u0022', '\u0022', '\u007c', '\u0020', '\u0022', '\u0009', '\u000a',
+ '\u000c', '\u000d', '\u0022', '\u0029', '\u0022', '\u003f', '\u0022', '\u002d',
+ '\u0037', '\u005c', '\u0000', '\u002f', '\u0030', '\u0031', '\u0032', '\u0039',
+ '\u0022', '\u003e', '\u0022', '\u002d', '\u0021', '\u0022', '\u0022', '\u002d',
+ '\u0022', '\u002d', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b',
+ '\u002c', '\u002e', '\u002f', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0022', '\u002d',
+ '\u0049', '\u0069', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b',
+ '\u002c', '\u002d', '\u002f', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002e', '\u0030', '\u0039', '\u0020', '\u0021',
+ '\u0022', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u003e',
+ '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002a', '\u0030', '\u0039', '\u0020', '\u0022', '\u0027', '\u003a', '\u005c',
+ '\u007b', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002c', '\u002e',
+ '\u002f', '\u0020', '\u0022', '\u0027', '\u0031', '\u003a', '\u005c', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002c', '\u002e', '\u002f', '\u0020',
+ '\u0022', '\u0027', '\u002c', '\u003a', '\u005c', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u002b', '\u002e', '\u002f', '\u0022', '\u0027', '\u0036',
+ '\u0022', '\u0027', '\u007d', '\u0022', '\u0027', '\u0028', '\u000d', '\u0022',
+ '\u0027', '\u000a', '\u0022', '\u0027', '\u0022', '\u0027', '\u007c', '\u0020',
+ '\u0022', '\u0027', '\u0009', '\u000a', '\u000c', '\u000d', '\u0022', '\u0027',
+ '\u0029', '\u0022', '\u0027', '\u003f', '\u0020', '\u0022', '\u0027', '\u003a',
+ '\u003b', '\u005c', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002c', '\u002e', '\u002f', '\u0020', '\u0022', '\u0027', '\u002d', '\u0037',
+ '\u003a', '\u003b', '\u005c', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u0031', '\u0020', '\u0022', '\u0027', '\u002d', '\u003a', '\u005c',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002f', '\u0020', '\u0022',
+ '\u0027', '\u003a', '\u003e', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002c', '\u002e', '\u002f', '\u0020', '\u0021', '\u0022', '\u0027',
+ '\u003a', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002c',
+ '\u002e', '\u002f', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u0029',
+ '\u002b', '\u002c', '\u002e', '\u002f', '\u005c', '\u0075', '\u007d', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020',
+ '\u0021', '\u0022', '\u0027', '\u0029', '\u002b', '\u002c', '\u002d', '\u002f',
+ '\u0037', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002e', '\u0030', '\u0031', '\u0032', '\u0039', '\u0020', '\u0021',
+ '\u0022', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u005c',
+ '\u0072', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002a', '\u0030', '\u0039', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028',
+ '\u002b', '\u002c', '\u002e', '\u002f', '\u005c', '\u006c', '\u0075', '\u007d',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039',
+ '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e',
+ '\u002f', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002a', '\u0030', '\u0039', '\u0020', '\u0022', '\u0027', '\u0028',
+ '\u0029', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u001f',
+ '\u0020', '\u0022', '\u0027', '\u0028', '\u0029', '\u005c', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u001f', '\u0020', '\u0022', '\u0027', '\u0028',
+ '\u0029', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u001f',
+ '\u0030', '\u0039', '\u0041', '\u0046', '\u0061', '\u0066', '\u0020', '\u0022',
+ '\u0027', '\u0028', '\u0029', '\u005c', '\u007b', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u001f', '\u0020', '\u0022', '\u0027', '\u0028', '\u0029',
+ '\u0031', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u001f',
+ '\u0020', '\u0022', '\u0027', '\u0028', '\u0029', '\u002c', '\u005c', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u001f', '\u0020', '\u0022', '\u0027',
+ '\u0028', '\u0029', '\u0036', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u001f', '\u0020', '\u0022', '\u0027', '\u0028', '\u0029', '\u005c',
+ '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u001f', '\u0020',
+ '\u0022', '\u0027', '\u0028', '\u0029', '\u005c', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u001f', '\u000d', '\u0022', '\u0027', '\u000a', '\u0022',
+ '\u0027', '\u0022', '\u0027', '\u007c', '\u0020', '\u0022', '\u0027', '\u0009',
+ '\u000a', '\u000c', '\u000d', '\u0022', '\u0027', '\u0029', '\u0022', '\u0027',
+ '\u003f', '\u0022', '\u0027', '\u002d', '\u0037', '\u005c', '\u0000', '\u002f',
+ '\u0030', '\u0031', '\u0032', '\u0039', '\u0022', '\u0027', '\u003e', '\u0022',
+ '\u0027', '\u002d', '\u0021', '\u0022', '\u0027', '\u0022', '\u0027', '\u002d',
+ '\u0022', '\u0027', '\u002d', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028',
+ '\u002b', '\u002c', '\u002e', '\u002f', '\u005c', '\u0075', '\u007d', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0022',
+ '\u0027', '\u002d', '\u0049', '\u0069', '\u0020', '\u0021', '\u0022', '\u0027',
+ '\u0028', '\u002b', '\u002c', '\u002d', '\u002f', '\u005c', '\u0075', '\u007d',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002e', '\u0030', '\u0039',
+ '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e',
+ '\u002f', '\u003e', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020', '\u0021', '\u0022',
+ '\u0025', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u005c',
+ '\u0075', '\u007b', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002a', '\u0030', '\u0039', '\u0022', '\u0027', '\u0030', '\u0039', '\u0020',
+ '\u0021', '\u0022', '\u0025', '\u0027', '\u002b', '\u002c', '\u002d', '\u002f',
+ '\u0037', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002e', '\u0030', '\u0031', '\u0032', '\u0039', '\u0020', '\u0021',
+ '\u0022', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u0031',
+ '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002a', '\u0030', '\u0039', '\u0020', '\u0021', '\u0022', '\u0025', '\u0027',
+ '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u005c', '\u0075', '\u007d',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039',
+ '\u0020', '\u0022', '\u0027', '\u002b', '\u002d', '\u0036', '\u0037', '\u005c',
+ '\u0075', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002f', '\u0030',
+ '\u0031', '\u0032', '\u0039', '\u0020', '\u0021', '\u0022', '\u0025', '\u0027',
+ '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u005c', '\u0075', '\u007d',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039',
+ '\u000d', '\u0020', '\u0022', '\u0027', '\u0029', '\u0009', '\u000c', '\u000a',
+ '\u0020', '\u0022', '\u0027', '\u0029', '\u0009', '\u000d', '\u0020', '\u0022',
+ '\u0027', '\u0029', '\u007c', '\u0009', '\u000d', '\u0020', '\u0022', '\u0027',
+ '\u0009', '\u000a', '\u000c', '\u000d', '\u0022', '\u0027', '\u0029', '\u0022',
+ '\u0027', '\u003f', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b',
+ '\u002c', '\u002e', '\u002f', '\u005c', '\u0075', '\u007b', '\u007d', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020',
+ '\u0022', '\u0027', '\u002b', '\u002d', '\u0037', '\u005c', '\u0075', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002f', '\u0030', '\u0031', '\u0032',
+ '\u0039', '\u0020', '\u0022', '\u0027', '\u002d', '\u0037', '\u005c', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002f', '\u0030', '\u0031', '\u0032',
+ '\u0039', '\u0020', '\u0021', '\u0022', '\u0025', '\u0027', '\u002b', '\u002d',
+ '\u002e', '\u0037', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u002a', '\u002c', '\u002f', '\u0030', '\u0031', '\u0032',
+ '\u0039', '\u000a', '\u0022', '\u0027', '\u003a', '\u005c', '\u000c', '\u000d',
+ '\u0030', '\u0039', '\u0041', '\u0046', '\u0061', '\u0066', '\u0020', '\u0027',
+ '\u0029', '\u003a', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002c', '\u002e', '\u002f', '\u0020', '\u0027', '\u0029', '\u003a', '\u0009',
+ '\u000d', '\u0020', '\u0022', '\u0027', '\u002b', '\u002d', '\u0037', '\u005c',
+ '\u0075', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002f', '\u0030',
+ '\u0031', '\u0032', '\u0039', '\u0020', '\u0027', '\u002d', '\u0037', '\u005c',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002f', '\u0030', '\u0031',
+ '\u0032', '\u0039', '\u0020', '\u0021', '\u0022', '\u0025', '\u0027', '\u002b',
+ '\u002d', '\u002e', '\u0037', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002a', '\u002c', '\u002f', '\u0030', '\u0031',
+ '\u0032', '\u0039', '\u0027', '\u0030', '\u0039', '\u0020', '\u0021', '\u0022',
+ '\u0025', '\u0027', '\u002b', '\u002c', '\u002d', '\u002f', '\u0037', '\u005c',
+ '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002e',
+ '\u0030', '\u0031', '\u0032', '\u0039', '\u0020', '\u0021', '\u0022', '\u0027',
+ '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u005c', '\u0072', '\u0075',
+ '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030',
+ '\u0039', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c',
+ '\u002e', '\u002f', '\u005c', '\u006c', '\u0075', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020', '\u0021',
+ '\u0022', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u005c',
+ '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a',
+ '\u0030', '\u0039', '\u0020', '\u0022', '\u0027', '\u0028', '\u0029', '\u005c',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u001f', '\u0020', '\u0022',
+ '\u0027', '\u0028', '\u0029', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u001f', '\u0020', '\u0022', '\u0027', '\u0028', '\u0029', '\u005c',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u001f', '\u0030', '\u0039',
+ '\u0041', '\u0046', '\u0061', '\u0066', '\u0020', '\u0022', '\u0027', '\u0028',
+ '\u0029', '\u005c', '\u007b', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u001f', '\u0020', '\u0022', '\u0027', '\u0028', '\u0029', '\u0031', '\u005c',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u001f', '\u0020', '\u0022',
+ '\u0027', '\u0028', '\u0029', '\u002c', '\u005c', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u001f', '\u0020', '\u0022', '\u0027', '\u0028', '\u0029',
+ '\u0036', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u001f',
+ '\u0020', '\u0022', '\u0027', '\u0028', '\u0029', '\u005c', '\u007d', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u001f', '\u0020', '\u0022', '\u0027',
+ '\u0028', '\u0029', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u001f', '\u000d', '\u0027', '\u000a', '\u0027', '\u0027', '\u007c', '\u0020',
+ '\u0027', '\u0009', '\u000a', '\u000c', '\u000d', '\u0027', '\u0029', '\u0027',
+ '\u003f', '\u0027', '\u002d', '\u0037', '\u005c', '\u0000', '\u002f', '\u0030',
+ '\u0031', '\u0032', '\u0039', '\u0027', '\u003e', '\u0027', '\u002d', '\u0021',
+ '\u0027', '\u0027', '\u002d', '\u0027', '\u002d', '\u0020', '\u0021', '\u0022',
+ '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u005c', '\u0075',
+ '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030',
+ '\u0039', '\u0027', '\u002d', '\u0049', '\u0069', '\u0020', '\u0021', '\u0022',
+ '\u0027', '\u0028', '\u002b', '\u002c', '\u002d', '\u002f', '\u005c', '\u0075',
+ '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002e', '\u0030',
+ '\u0039', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c',
+ '\u002e', '\u002f', '\u003e', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u000a', '\u0027',
+ '\u003a', '\u005c', '\u000c', '\u000d', '\u0030', '\u0039', '\u0041', '\u0046',
+ '\u0061', '\u0066', '\u0020', '\u0029', '\u003a', '\u005c', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002c', '\u002e', '\u002f', '\u0020', '\u0029',
+ '\u003a', '\u0009', '\u000d', '\u0020', '\u0022', '\u0027', '\u002b', '\u002d',
+ '\u0037', '\u005c', '\u0075', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002f', '\u0030', '\u0031', '\u0032', '\u0039', '\u000a', '\u003a', '\u005c',
+ '\u000c', '\u000d', '\u0030', '\u0039', '\u0041', '\u0046', '\u0061', '\u0066',
+ '\u0020', '\u003a', '\u005c', '\u007b', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002c', '\u002e', '\u002f', '\u0020', '\u0031', '\u003a', '\u005c',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002c', '\u002e', '\u002f',
+ '\u0020', '\u002c', '\u003a', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002b', '\u002e', '\u002f', '\u0036', '\u007d', '\u0028', '\u000d',
+ '\u000a', '\u007c', '\u0020', '\u0009', '\u000a', '\u000c', '\u000d', '\u0029',
+ '\u003f', '\u0020', '\u0027', '\u003a', '\u005c', '\u007b', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002c', '\u002e', '\u002f', '\u0020', '\u0027',
+ '\u0031', '\u003a', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002c', '\u002e', '\u002f', '\u0020', '\u0027', '\u002c', '\u003a', '\u005c',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002b', '\u002e', '\u002f',
+ '\u0027', '\u0036', '\u0027', '\u007d', '\u0027', '\u0028', '\u000d', '\u0027',
+ '\u000a', '\u0027', '\u0027', '\u007c', '\u0020', '\u0027', '\u0009', '\u000a',
+ '\u000c', '\u000d', '\u0027', '\u0029', '\u0027', '\u003f', '\u0020', '\u0022',
+ '\u0029', '\u003a', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002c', '\u002e', '\u002f', '\u0020', '\u0022', '\u0029', '\u003a', '\u0009',
+ '\u000d', '\u0020', '\u0022', '\u0027', '\u002b', '\u002d', '\u0037', '\u005c',
+ '\u0075', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002f', '\u0030',
+ '\u0031', '\u0032', '\u0039', '\u000a', '\u0022', '\u003a', '\u005c', '\u000c',
+ '\u000d', '\u0030', '\u0039', '\u0041', '\u0046', '\u0061', '\u0066', '\u0020',
+ '\u0022', '\u003a', '\u005c', '\u007b', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002c', '\u002e', '\u002f', '\u0020', '\u0022', '\u0031', '\u003a',
+ '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002c', '\u002e',
+ '\u002f', '\u0020', '\u0022', '\u002c', '\u003a', '\u005c', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002b', '\u002e', '\u002f', '\u0022', '\u0036',
+ '\u0022', '\u007d', '\u0022', '\u0028', '\u000d', '\u0022', '\u000a', '\u0022',
+ '\u0022', '\u007c', '\u0020', '\u0022', '\u0009', '\u000a', '\u000c', '\u000d',
+ '\u0022', '\u0029', '\u0022', '\u003f', '\u0020', '\u0022', '\u0027', '\u003a',
+ '\u005c', '\u007b', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002c',
+ '\u002e', '\u002f', '\u0020', '\u0022', '\u0027', '\u0031', '\u003a', '\u005c',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002c', '\u002e', '\u002f',
+ '\u0020', '\u0022', '\u0027', '\u002c', '\u003a', '\u005c', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002b', '\u002e', '\u002f', '\u0022', '\u0027',
+ '\u0036', '\u0022', '\u0027', '\u007d', '\u0022', '\u0027', '\u0028', '\u000d',
+ '\u0022', '\u0027', '\u000a', '\u0022', '\u0027', '\u0022', '\u0027', '\u007c',
+ '\u0020', '\u0022', '\u0027', '\u0009', '\u000a', '\u000c', '\u000d', '\u0022',
+ '\u0027', '\u0029', '\u0022', '\u0027', '\u003f', '\u0020', '\u0022', '\u0027',
+ '\u003a', '\u003b', '\u005c', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002c', '\u002e', '\u002f', '\u0020', '\u0022', '\u0027', '\u002d',
+ '\u0037', '\u003a', '\u003b', '\u005c', '\u007d', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u0031', '\u0020', '\u0022', '\u0027', '\u002d', '\u003a',
+ '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002f', '\u0020',
+ '\u0022', '\u0027', '\u003a', '\u003e', '\u005c', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u002c', '\u002e', '\u002f', '\u0020', '\u0021', '\u0022',
+ '\u0027', '\u003a', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002c', '\u002e', '\u002f', '\u0022', '\u0027', '\u002d', '\u0037', '\u005c',
+ '\u0000', '\u002f', '\u0030', '\u0031', '\u0032', '\u0039', '\u0022', '\u0027',
+ '\u003e', '\u0022', '\u0027', '\u002d', '\u0021', '\u0022', '\u0027', '\u0022',
+ '\u0027', '\u002d', '\u0022', '\u0027', '\u002d', '\u0020', '\u0021', '\u0022',
+ '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u005c', '\u0075',
+ '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030',
+ '\u0039', '\u0022', '\u0027', '\u002d', '\u0049', '\u0069', '\u0020', '\u0021',
+ '\u0022', '\u0027', '\u0028', '\u002b', '\u002c', '\u002d', '\u002f', '\u005c',
+ '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002e',
+ '\u0030', '\u0039', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b',
+ '\u002c', '\u002e', '\u002f', '\u003e', '\u005c', '\u0075', '\u007d', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020',
+ '\u0021', '\u0022', '\u0025', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e',
+ '\u002f', '\u005c', '\u0075', '\u007b', '\u007d', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020', '\u0021', '\u0022',
+ '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u0031', '\u005c',
+ '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a',
+ '\u0030', '\u0039', '\u0020', '\u0021', '\u0022', '\u0025', '\u0027', '\u0028',
+ '\u002b', '\u002c', '\u002e', '\u002f', '\u005c', '\u0075', '\u007d', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020',
+ '\u0022', '\u0027', '\u002b', '\u002d', '\u0036', '\u0037', '\u005c', '\u0075',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002f', '\u0030', '\u0031',
+ '\u0032', '\u0039', '\u0020', '\u0021', '\u0022', '\u0025', '\u0027', '\u0028',
+ '\u002b', '\u002c', '\u002e', '\u002f', '\u005c', '\u0075', '\u007d', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u000d',
+ '\u0020', '\u0022', '\u0027', '\u0029', '\u0009', '\u000c', '\u000a', '\u0020',
+ '\u0022', '\u0027', '\u0029', '\u0009', '\u000d', '\u0020', '\u0022', '\u0027',
+ '\u0029', '\u007c', '\u0009', '\u000d', '\u0020', '\u0022', '\u0027', '\u0009',
+ '\u000a', '\u000c', '\u000d', '\u0022', '\u0027', '\u0029', '\u0022', '\u0027',
+ '\u003f', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c',
+ '\u002e', '\u002f', '\u005c', '\u0075', '\u007b', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020', '\u0022',
+ '\u0027', '\u002b', '\u002d', '\u0037', '\u005c', '\u0075', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002f', '\u0030', '\u0031', '\u0032', '\u0039',
+ '\u0020', '\u0022', '\u0027', '\u002d', '\u0037', '\u005c', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002f', '\u0030', '\u0031', '\u0032', '\u0039',
+ '\u0020', '\u0021', '\u0022', '\u0025', '\u0027', '\u002b', '\u002d', '\u002e',
+ '\u0037', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002a', '\u002c', '\u002f', '\u0030', '\u0031', '\u0032', '\u0039',
+ '\u000a', '\u0022', '\u0027', '\u003a', '\u005c', '\u000c', '\u000d', '\u0030',
+ '\u0039', '\u0041', '\u0046', '\u0061', '\u0066', '\u0020', '\u0021', '\u0022',
+ '\u0027', '\u002b', '\u002c', '\u002d', '\u002f', '\u0037', '\u005c', '\u0075',
+ '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002e', '\u0030',
+ '\u0031', '\u0032', '\u0039', '\u0020', '\u0022', '\u0029', '\u003a', '\u005c',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002c', '\u002e', '\u002f',
+ '\u0020', '\u0022', '\u0029', '\u003a', '\u0009', '\u000d', '\u0020', '\u0022',
+ '\u0027', '\u002b', '\u002d', '\u0037', '\u005c', '\u0075', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002f', '\u0030', '\u0031', '\u0032', '\u0039',
+ '\u0020', '\u0022', '\u002d', '\u0037', '\u005c', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u002f', '\u0030', '\u0031', '\u0032', '\u0039', '\u0020',
+ '\u0021', '\u0022', '\u0025', '\u0027', '\u002b', '\u002d', '\u002e', '\u0037',
+ '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002a', '\u002c', '\u002f', '\u0030', '\u0031', '\u0032', '\u0039', '\u0022',
+ '\u002d', '\u0037', '\u005c', '\u0000', '\u002f', '\u0030', '\u0031', '\u0032',
+ '\u0039', '\u0022', '\u003e', '\u0022', '\u002d', '\u0021', '\u0022', '\u0022',
+ '\u002d', '\u0022', '\u002d', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028',
+ '\u002b', '\u002c', '\u002e', '\u002f', '\u005c', '\u0075', '\u007d', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0022',
+ '\u002d', '\u0049', '\u0069', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028',
+ '\u002b', '\u002c', '\u002d', '\u002f', '\u005c', '\u0075', '\u007d', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002e', '\u0030', '\u0039', '\u0020',
+ '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f',
+ '\u003e', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002a', '\u0030', '\u0039', '\u000a', '\u0022', '\u003a', '\u005c',
+ '\u000c', '\u000d', '\u0030', '\u0039', '\u0041', '\u0046', '\u0061', '\u0066',
+ '\u0020', '\u0022', '\u003a', '\u005c', '\u007b', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u002c', '\u002e', '\u002f', '\u0020', '\u0022', '\u0031',
+ '\u003a', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002c',
+ '\u002e', '\u002f', '\u0020', '\u0022', '\u002c', '\u003a', '\u005c', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002b', '\u002e', '\u002f', '\u0022',
+ '\u0036', '\u0022', '\u007d', '\u0022', '\u0028', '\u000d', '\u0022', '\u000a',
+ '\u0022', '\u0022', '\u007c', '\u0020', '\u0022', '\u0009', '\u000a', '\u000c',
+ '\u000d', '\u0022', '\u0029', '\u0022', '\u003f', '\u0020', '\u0022', '\u0027',
+ '\u003a', '\u005c', '\u007b', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002c', '\u002e', '\u002f', '\u0020', '\u0022', '\u0027', '\u0031', '\u003a',
+ '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002c', '\u002e',
+ '\u002f', '\u0020', '\u0022', '\u0027', '\u002c', '\u003a', '\u005c', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002b', '\u002e', '\u002f', '\u0022',
+ '\u0027', '\u0036', '\u0022', '\u0027', '\u007d', '\u0022', '\u0027', '\u0028',
+ '\u000d', '\u0022', '\u0027', '\u000a', '\u0022', '\u0027', '\u0022', '\u0027',
+ '\u007c', '\u0020', '\u0022', '\u0027', '\u0009', '\u000a', '\u000c', '\u000d',
+ '\u0022', '\u0027', '\u0029', '\u0022', '\u0027', '\u003f', '\u0020', '\u0022',
+ '\u0027', '\u003a', '\u003b', '\u005c', '\u007d', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u002c', '\u002e', '\u002f', '\u0020', '\u0022', '\u0027',
+ '\u002d', '\u0037', '\u003a', '\u003b', '\u005c', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u0031', '\u0020', '\u0022', '\u0027', '\u002d',
+ '\u003a', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002f',
+ '\u0020', '\u0022', '\u0027', '\u003a', '\u003e', '\u005c', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002c', '\u002e', '\u002f', '\u0020', '\u0021',
+ '\u0022', '\u0027', '\u003a', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002c', '\u002e', '\u002f', '\u0020', '\u0021', '\u0022', '\u0027',
+ '\u0028', '\u0029', '\u002b', '\u002c', '\u002e', '\u002f', '\u005c', '\u0075',
+ '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030',
+ '\u0039', '\u0020', '\u0021', '\u0022', '\u0027', '\u0029', '\u002b', '\u002c',
+ '\u002d', '\u002f', '\u0037', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002e', '\u0030', '\u0031', '\u0032', '\u0039',
+ '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u0029', '\u002b', '\u002c',
+ '\u002e', '\u002f', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020', '\u0021', '\u0022',
+ '\u0027', '\u0029', '\u002b', '\u002c', '\u002d', '\u002f', '\u0037', '\u005c',
+ '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002e',
+ '\u0030', '\u0031', '\u0032', '\u0039', '\u0020', '\u0021', '\u0022', '\u0025',
+ '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u005c', '\u0075',
+ '\u007b', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a',
+ '\u0030', '\u0039', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b',
+ '\u002c', '\u002e', '\u002f', '\u0031', '\u005c', '\u0075', '\u007d', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020',
+ '\u0021', '\u0022', '\u0025', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e',
+ '\u002f', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002a', '\u0030', '\u0039', '\u0020', '\u0022', '\u0027', '\u002b',
+ '\u002d', '\u0036', '\u0037', '\u005c', '\u0075', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u002f', '\u0030', '\u0031', '\u0032', '\u0039', '\u0020',
+ '\u0021', '\u0022', '\u0025', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e',
+ '\u002f', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002a', '\u0030', '\u0039', '\u000d', '\u0020', '\u0027', '\u0029',
+ '\u0009', '\u000c', '\u000a', '\u0020', '\u0027', '\u0029', '\u0009', '\u000d',
+ '\u0020', '\u0027', '\u0029', '\u007c', '\u0009', '\u000d', '\u0020', '\u0027',
+ '\u0009', '\u000a', '\u000c', '\u000d', '\u0027', '\u0029', '\u0027', '\u003f',
+ '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e',
+ '\u002f', '\u005c', '\u0075', '\u007b', '\u007d', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020', '\u0027', '\u003a',
+ '\u003b', '\u005c', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002c', '\u002e', '\u002f', '\u0020', '\u0027', '\u002d', '\u0037', '\u003a',
+ '\u003b', '\u005c', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u0031', '\u0020', '\u0027', '\u002d', '\u003a', '\u005c', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002f', '\u0020', '\u0027', '\u003a', '\u003e',
+ '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002c', '\u002e',
+ '\u002f', '\u0020', '\u0021', '\u0027', '\u003a', '\u005c', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002c', '\u002e', '\u002f', '\u0020', '\u0021',
+ '\u0022', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u0031',
+ '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002a', '\u0030', '\u0039', '\u0020', '\u0021', '\u0022', '\u0025', '\u0027',
+ '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u005c', '\u0075', '\u007d',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039',
+ '\u0020', '\u0022', '\u0027', '\u002b', '\u002d', '\u0036', '\u0037', '\u005c',
+ '\u0075', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002f', '\u0030',
+ '\u0031', '\u0032', '\u0039', '\u0020', '\u0021', '\u0022', '\u0025', '\u0027',
+ '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u005c', '\u0075', '\u007d',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039',
+ '\u000d', '\u0020', '\u0022', '\u0029', '\u0009', '\u000c', '\u000a', '\u0020',
+ '\u0022', '\u0029', '\u0009', '\u000d', '\u0020', '\u0022', '\u0029', '\u007c',
+ '\u0009', '\u000d', '\u0020', '\u0022', '\u0009', '\u000a', '\u000c', '\u000d',
+ '\u0022', '\u0029', '\u0022', '\u003f', '\u0020', '\u0021', '\u0022', '\u0027',
+ '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u005c', '\u0075', '\u007b',
+ '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030',
+ '\u0039', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u0029', '\u002b',
+ '\u002c', '\u002e', '\u002f', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020', '\u0021',
+ '\u0022', '\u0027', '\u0029', '\u002b', '\u002c', '\u002d', '\u002f', '\u0037',
+ '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002e', '\u0030', '\u0031', '\u0032', '\u0039', '\u0020', '\u0021', '\u0022',
+ '\u0025', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u005c',
+ '\u0075', '\u007b', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002a', '\u0030', '\u0039', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028',
+ '\u002b', '\u002c', '\u002e', '\u002f', '\u0031', '\u005c', '\u0075', '\u007d',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039',
+ '\u0020', '\u0021', '\u0022', '\u0025', '\u0027', '\u0028', '\u002b', '\u002c',
+ '\u002e', '\u002f', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020', '\u0022', '\u0027',
+ '\u002b', '\u002d', '\u0036', '\u0037', '\u005c', '\u0075', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002f', '\u0030', '\u0031', '\u0032', '\u0039',
+ '\u0020', '\u0021', '\u0022', '\u0025', '\u0027', '\u0028', '\u002b', '\u002c',
+ '\u002e', '\u002f', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u000d', '\u0020', '\u0022',
+ '\u0029', '\u0009', '\u000c', '\u000a', '\u0020', '\u0022', '\u0029', '\u0009',
+ '\u000d', '\u0020', '\u0022', '\u0029', '\u007c', '\u0009', '\u000d', '\u0020',
+ '\u0022', '\u0009', '\u000a', '\u000c', '\u000d', '\u0022', '\u0029', '\u0022',
+ '\u003f', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c',
+ '\u002e', '\u002f', '\u005c', '\u0075', '\u007b', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020', '\u0022',
+ '\u003a', '\u003b', '\u005c', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002c', '\u002e', '\u002f', '\u0020', '\u0022', '\u002d', '\u0037',
+ '\u003a', '\u003b', '\u005c', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u0031', '\u0020', '\u0022', '\u002d', '\u003a', '\u005c', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002f', '\u0020', '\u0022', '\u003a',
+ '\u003e', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002c',
+ '\u002e', '\u002f', '\u0020', '\u0021', '\u0022', '\u003a', '\u005c', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002c', '\u002e', '\u002f', '\u0022',
+ '\u0027', '\u002d', '\u0037', '\u005c', '\u0000', '\u002f', '\u0030', '\u0031',
+ '\u0032', '\u0039', '\u0022', '\u0027', '\u003e', '\u0022', '\u0027', '\u002d',
+ '\u0021', '\u0022', '\u0027', '\u0022', '\u0027', '\u002d', '\u0022', '\u0027',
+ '\u002d', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c',
+ '\u002e', '\u002f', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0022', '\u0027', '\u002d',
+ '\u0049', '\u0069', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b',
+ '\u002c', '\u002d', '\u002f', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002e', '\u0030', '\u0039', '\u0020', '\u0021',
+ '\u0022', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u003e',
+ '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002a', '\u0030', '\u0039', '\u0020', '\u0021', '\u0022', '\u0025', '\u0027',
+ '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u005c', '\u0075', '\u007b',
+ '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030',
+ '\u0039', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c',
+ '\u002e', '\u002f', '\u0031', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020', '\u0021',
+ '\u0022', '\u0025', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f',
+ '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002a', '\u0030', '\u0039', '\u0020', '\u0022', '\u0027', '\u002b', '\u002d',
+ '\u0036', '\u0037', '\u005c', '\u0075', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002f', '\u0030', '\u0031', '\u0032', '\u0039', '\u0020', '\u0021',
+ '\u0022', '\u0025', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f',
+ '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002a', '\u0030', '\u0039', '\u000d', '\u0020', '\u0022', '\u0027', '\u0029',
+ '\u0009', '\u000c', '\u000a', '\u0020', '\u0022', '\u0027', '\u0029', '\u0009',
+ '\u000d', '\u0020', '\u0022', '\u0027', '\u0029', '\u007c', '\u0009', '\u000d',
+ '\u0020', '\u0022', '\u0027', '\u0009', '\u000a', '\u000c', '\u000d', '\u0022',
+ '\u0027', '\u0029', '\u0022', '\u0027', '\u003f', '\u0020', '\u0021', '\u0022',
+ '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u005c', '\u0075',
+ '\u007b', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a',
+ '\u0030', '\u0039', '\u0020', '\u0022', '\u0027', '\u002b', '\u002d', '\u0037',
+ '\u005c', '\u0075', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002f',
+ '\u0030', '\u0031', '\u0032', '\u0039', '\u0020', '\u0022', '\u0027', '\u002d',
+ '\u0037', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002f',
+ '\u0030', '\u0031', '\u0032', '\u0039', '\u0020', '\u0021', '\u0022', '\u0025',
+ '\u0027', '\u002b', '\u002d', '\u002e', '\u0037', '\u005c', '\u0075', '\u007d',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u002c', '\u002f',
+ '\u0030', '\u0031', '\u0032', '\u0039', '\u000a', '\u0022', '\u0027', '\u003a',
+ '\u005c', '\u000c', '\u000d', '\u0030', '\u0039', '\u0041', '\u0046', '\u0061',
+ '\u0066', '\u0020', '\u0021', '\u0022', '\u0027', '\u002b', '\u002c', '\u002d',
+ '\u002f', '\u0037', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u002e', '\u0030', '\u0031', '\u0032', '\u0039', '\u0020',
+ '\u0021', '\u0022', '\u0027', '\u002b', '\u002c', '\u002d', '\u002f', '\u0037',
+ '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002e', '\u0030', '\u0031', '\u0032', '\u0039', '\u0020', '\u0022', '\u0027',
+ '\u003a', '\u005c', '\u007b', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002c', '\u002e', '\u002f', '\u0020', '\u0022', '\u0027', '\u0031', '\u003a',
+ '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002c', '\u002e',
+ '\u002f', '\u0020', '\u0022', '\u0027', '\u002c', '\u003a', '\u005c', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002b', '\u002e', '\u002f', '\u0022',
+ '\u0027', '\u0036', '\u0022', '\u0027', '\u007d', '\u0022', '\u0027', '\u0028',
+ '\u000d', '\u0022', '\u0027', '\u000a', '\u0022', '\u0027', '\u0022', '\u0027',
+ '\u007c', '\u0020', '\u0022', '\u0027', '\u0009', '\u000a', '\u000c', '\u000d',
+ '\u0022', '\u0027', '\u0029', '\u0022', '\u0027', '\u003f', '\u0020', '\u0022',
+ '\u0027', '\u003a', '\u003b', '\u005c', '\u007d', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u002c', '\u002e', '\u002f', '\u0020', '\u0022', '\u0027',
+ '\u002d', '\u0037', '\u003a', '\u003b', '\u005c', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u0031', '\u0020', '\u0022', '\u0027', '\u002d',
+ '\u003a', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002f',
+ '\u0020', '\u0022', '\u0027', '\u003a', '\u003e', '\u005c', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002c', '\u002e', '\u002f', '\u0020', '\u0021',
+ '\u0022', '\u0027', '\u003a', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002c', '\u002e', '\u002f', '\u0020', '\u0021', '\u0022', '\u0025',
+ '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u005c', '\u0075',
+ '\u007b', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a',
+ '\u0030', '\u0039', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b',
+ '\u002c', '\u002e', '\u002f', '\u0031', '\u005c', '\u0075', '\u007d', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020',
+ '\u0021', '\u0022', '\u0025', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e',
+ '\u002f', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002a', '\u0030', '\u0039', '\u0020', '\u0022', '\u0027', '\u002b',
+ '\u002d', '\u0036', '\u0037', '\u005c', '\u0075', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u002f', '\u0030', '\u0031', '\u0032', '\u0039', '\u0020',
+ '\u0021', '\u0022', '\u0025', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e',
+ '\u002f', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002a', '\u0030', '\u0039', '\u000d', '\u0020', '\u0027', '\u0029',
+ '\u0009', '\u000c', '\u000a', '\u0020', '\u0027', '\u0029', '\u0009', '\u000d',
+ '\u0020', '\u0027', '\u0029', '\u007c', '\u0009', '\u000d', '\u0020', '\u0027',
+ '\u0009', '\u000a', '\u000c', '\u000d', '\u0027', '\u0029', '\u0027', '\u003f',
+ '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e',
+ '\u002f', '\u005c', '\u0075', '\u007b', '\u007d', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020', '\u0027', '\u003a',
+ '\u003b', '\u005c', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002c', '\u002e', '\u002f', '\u0020', '\u0027', '\u002d', '\u0037', '\u003a',
+ '\u003b', '\u005c', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u0031', '\u0020', '\u0027', '\u002d', '\u003a', '\u005c', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002f', '\u0020', '\u0027', '\u003a', '\u003e',
+ '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002c', '\u002e',
+ '\u002f', '\u0020', '\u0021', '\u0027', '\u003a', '\u005c', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002c', '\u002e', '\u002f', '\u0020', '\u0022',
+ '\u003a', '\u003b', '\u005c', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002c', '\u002e', '\u002f', '\u0020', '\u0022', '\u002d', '\u0037',
+ '\u003a', '\u003b', '\u005c', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u0031', '\u0020', '\u0022', '\u002d', '\u003a', '\u005c', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002f', '\u0020', '\u0022', '\u003a',
+ '\u003e', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002c',
+ '\u002e', '\u002f', '\u0020', '\u0021', '\u0022', '\u003a', '\u005c', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002c', '\u002e', '\u002f', '\u0020',
+ '\u0021', '\u0022', '\u0027', '\u0028', '\u0029', '\u002b', '\u002c', '\u002e',
+ '\u002f', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002a', '\u0030', '\u0039', '\u0020', '\u0021', '\u0022', '\u0027',
+ '\u0029', '\u002b', '\u002c', '\u002d', '\u002f', '\u0037', '\u005c', '\u0075',
+ '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002e', '\u0030',
+ '\u0031', '\u0032', '\u0039', '\u0020', '\u0021', '\u0022', '\u0025', '\u0027',
+ '\u0028', '\u002b', '\u002c', '\u002e', '\u002f', '\u005c', '\u0075', '\u007b',
+ '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002a', '\u0030',
+ '\u0039', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c',
+ '\u002e', '\u002f', '\u0031', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020', '\u0021',
+ '\u0022', '\u0025', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f',
+ '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002a', '\u0030', '\u0039', '\u0020', '\u0022', '\u0027', '\u002b', '\u002d',
+ '\u0036', '\u0037', '\u005c', '\u0075', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002f', '\u0030', '\u0031', '\u0032', '\u0039', '\u0020', '\u0021',
+ '\u0022', '\u0025', '\u0027', '\u0028', '\u002b', '\u002c', '\u002e', '\u002f',
+ '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002a', '\u0030', '\u0039', '\u000d', '\u0020', '\u0029', '\u0009', '\u000c',
+ '\u000a', '\u0020', '\u0029', '\u0009', '\u000d', '\u0020', '\u0029', '\u007c',
+ '\u0009', '\u000d', '\u0020', '\u0009', '\u000a', '\u000c', '\u000d', '\u0029',
+ '\u003f', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c',
+ '\u002e', '\u002f', '\u005c', '\u0075', '\u007b', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002a', '\u0030', '\u0039', '\u0020', '\u003a',
+ '\u003b', '\u005c', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002c', '\u002e', '\u002f', '\u0020', '\u002d', '\u0037', '\u003a', '\u003b',
+ '\u005c', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u0031',
+ '\u0020', '\u002d', '\u003a', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002f', '\u0020', '\u003a', '\u003e', '\u005c', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002c', '\u002e', '\u002f', '\u0020', '\u0021',
+ '\u003a', '\u005c', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002c',
+ '\u002e', '\u002f', '\u007b', '\u0020', '\u002d', '\u003c', '\u007b', '\u0009',
+ '\u000d', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c',
+ '\u002d', '\u002f', '\u003c', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002e', '\u0030', '\u0039', '\u0020', '\u0021',
+ '\u0022', '\u0027', '\u002b', '\u002c', '\u002d', '\u002f', '\u0037', '\u003c',
+ '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002e', '\u0030', '\u0031', '\u0032', '\u0039', '\u0020', '\u0022', '\u0027',
+ '\u002d', '\u003c', '\u007b', '\u0009', '\u000d', '\u0020', '\u0021', '\u0022',
+ '\u0027', '\u0028', '\u002b', '\u002c', '\u002d', '\u002f', '\u003c', '\u005c',
+ '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002e',
+ '\u0030', '\u0039', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b',
+ '\u002c', '\u002d', '\u002f', '\u003c', '\u005c', '\u0075', '\u007d', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002e', '\u0030', '\u0039', '\u0020',
+ '\u0021', '\u0022', '\u0027', '\u002b', '\u002c', '\u002d', '\u002f', '\u0037',
+ '\u003c', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002e', '\u0030', '\u0031', '\u0032', '\u0039', '\u0020', '\u0027',
+ '\u002d', '\u003c', '\u007b', '\u0009', '\u000d', '\u0020', '\u0021', '\u0022',
+ '\u0027', '\u0028', '\u002b', '\u002c', '\u002d', '\u002f', '\u003c', '\u005c',
+ '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002e',
+ '\u0030', '\u0039', '\u0020', '\u0021', '\u0022', '\u0027', '\u002b', '\u002c',
+ '\u002d', '\u002f', '\u0037', '\u003c', '\u005c', '\u0075', '\u007d', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002e', '\u0030', '\u0031', '\u0032',
+ '\u0039', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c',
+ '\u002d', '\u002f', '\u003c', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002e', '\u0030', '\u0039', '\u0020', '\u0021',
+ '\u0022', '\u0027', '\u002b', '\u002c', '\u002d', '\u002f', '\u0037', '\u003c',
+ '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002e', '\u0030', '\u0031', '\u0032', '\u0039', '\u0020', '\u0022', '\u002d',
+ '\u003c', '\u007b', '\u0009', '\u000d', '\u0020', '\u0022', '\u0027', '\u002d',
+ '\u003a', '\u003c', '\u005c', '\u007b', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002f', '\u0020', '\u0022', '\u0027', '\u002d', '\u003a', '\u003c',
+ '\u007b', '\u0009', '\u000d', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028',
+ '\u002b', '\u002c', '\u002d', '\u002f', '\u003c', '\u005c', '\u0075', '\u007d',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002e', '\u0030', '\u0039',
+ '\u0020', '\u0021', '\u0022', '\u0027', '\u002b', '\u002c', '\u002d', '\u002f',
+ '\u0037', '\u003c', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u002e', '\u0030', '\u0031', '\u0032', '\u0039', '\u0020',
+ '\u0022', '\u0027', '\u002d', '\u003c', '\u007b', '\u0009', '\u000d', '\u0020',
+ '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c', '\u002d', '\u002f',
+ '\u003c', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002e', '\u0030', '\u0039', '\u0020', '\u0021', '\u0022', '\u0027',
+ '\u0028', '\u002b', '\u002c', '\u002d', '\u002f', '\u003c', '\u005c', '\u0075',
+ '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002e', '\u0030',
+ '\u0039', '\u0020', '\u0021', '\u0022', '\u0027', '\u002b', '\u002c', '\u002d',
+ '\u002f', '\u0037', '\u003c', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002e', '\u0030', '\u0031', '\u0032', '\u0039',
+ '\u0020', '\u0027', '\u002d', '\u003c', '\u007b', '\u0009', '\u000d', '\u0020',
+ '\u0022', '\u0027', '\u002d', '\u003a', '\u003c', '\u005c', '\u007b', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002f', '\u0020', '\u0022', '\u0027',
+ '\u002d', '\u003a', '\u003c', '\u007b', '\u0009', '\u000d', '\u0020', '\u0021',
+ '\u0022', '\u0027', '\u0028', '\u002b', '\u002c', '\u002d', '\u002f', '\u003c',
+ '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002e', '\u0030', '\u0039', '\u0020', '\u0021', '\u0022', '\u0027', '\u002b',
+ '\u002c', '\u002d', '\u002f', '\u0037', '\u003c', '\u005c', '\u0075', '\u007d',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002e', '\u0030', '\u0031',
+ '\u0032', '\u0039', '\u0020', '\u0022', '\u0027', '\u002d', '\u003c', '\u007b',
+ '\u0009', '\u000d', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b',
+ '\u002c', '\u002d', '\u002f', '\u003c', '\u005c', '\u0075', '\u007d', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002e', '\u0030', '\u0039', '\u0020',
+ '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c', '\u002d', '\u002f',
+ '\u003c', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002e', '\u0030', '\u0039', '\u0020', '\u0021', '\u0022', '\u0027',
+ '\u002b', '\u002c', '\u002d', '\u002f', '\u0037', '\u003c', '\u005c', '\u0075',
+ '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002e', '\u0030',
+ '\u0031', '\u0032', '\u0039', '\u0020', '\u0022', '\u002d', '\u003c', '\u007b',
+ '\u0009', '\u000d', '\u0020', '\u0022', '\u0027', '\u002d', '\u003a', '\u003c',
+ '\u005c', '\u007b', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002f',
+ '\u0020', '\u0022', '\u0027', '\u002d', '\u003a', '\u003c', '\u007b', '\u0009',
+ '\u000d', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c',
+ '\u002d', '\u002f', '\u003c', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002e', '\u0030', '\u0039', '\u0020', '\u0027',
+ '\u002d', '\u003a', '\u003c', '\u005c', '\u007b', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u002f', '\u0020', '\u0027', '\u002d', '\u003a', '\u003c',
+ '\u007b', '\u0009', '\u000d', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028',
+ '\u002b', '\u002c', '\u002d', '\u002f', '\u003c', '\u005c', '\u0075', '\u007d',
+ '\u0000', '\u0008', '\u0009', '\u000d', '\u000e', '\u002e', '\u0030', '\u0039',
+ '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c', '\u002d',
+ '\u002f', '\u003c', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009',
+ '\u000d', '\u000e', '\u002e', '\u0030', '\u0039', '\u0020', '\u0022', '\u002d',
+ '\u003a', '\u003c', '\u005c', '\u007b', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002f', '\u0020', '\u0022', '\u002d', '\u003a', '\u003c', '\u007b',
+ '\u0009', '\u000d', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b',
+ '\u002c', '\u002d', '\u002f', '\u003c', '\u005c', '\u0075', '\u007d', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002e', '\u0030', '\u0039', '\u0020',
+ '\u0021', '\u0022', '\u0027', '\u002b', '\u002c', '\u002d', '\u002f', '\u0037',
+ '\u003c', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002e', '\u0030', '\u0031', '\u0032', '\u0039', '\u0020', '\u0022',
+ '\u0027', '\u002d', '\u003c', '\u007b', '\u0009', '\u000d', '\u0020', '\u0021',
+ '\u0022', '\u0027', '\u0028', '\u002b', '\u002c', '\u002d', '\u002f', '\u003c',
+ '\u005c', '\u0075', '\u007d', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002e', '\u0030', '\u0039', '\u0020', '\u0022', '\u0027', '\u002d', '\u003a',
+ '\u003c', '\u005c', '\u007b', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002f', '\u0020', '\u0022', '\u0027', '\u002d', '\u003a', '\u003c', '\u007b',
+ '\u0009', '\u000d', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b',
+ '\u002c', '\u002d', '\u002f', '\u003c', '\u005c', '\u0075', '\u007d', '\u0000',
+ '\u0008', '\u0009', '\u000d', '\u000e', '\u002e', '\u0030', '\u0039', '\u0020',
+ '\u0027', '\u002d', '\u003a', '\u003c', '\u005c', '\u007b', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002f', '\u0020', '\u0027', '\u002d', '\u003a',
+ '\u003c', '\u007b', '\u0009', '\u000d', '\u0020', '\u0022', '\u002d', '\u003a',
+ '\u003c', '\u005c', '\u007b', '\u0000', '\u0008', '\u0009', '\u000d', '\u000e',
+ '\u002f', '\u0020', '\u0022', '\u002d', '\u003a', '\u003c', '\u007b', '\u0009',
+ '\u000d', '\u0020', '\u0021', '\u0022', '\u0027', '\u0028', '\u002b', '\u002c',
+ '\u002d', '\u002f', '\u003c', '\u005c', '\u0075', '\u007d', '\u0000', '\u0008',
+ '\u0009', '\u000d', '\u000e', '\u002e', '\u0030', '\u0039', '\u0020', '\u002d',
+ '\u003a', '\u003c', '\u005c', '\u007b', '\u0000', '\u0008', '\u0009', '\u000d',
+ '\u000e', '\u002f', '\u0020', '\u002d', '\u003a', '\u003c', '\u007b', '\u0009',
+ '\u000d', (char) 0
+};
+
+static readonly sbyte[] _selector_single_lengths = new sbyte [] {
+ 0, 6, 2, 3, 2, 8, 1, 12,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 3, 1, 1, 1, 1, 1, 1,
+ 0, 12, 2, 13, 2, 12, 7, 12,
+ 12, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 4, 7, 3, 4, 3, 8,
+ 2, 12, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 4, 7, 3, 4, 3,
+ 8, 1, 12, 3, 13, 3, 12, 6,
+ 12, 12, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 5, 8, 4, 5, 4,
+ 8, 2, 12, 4, 13, 4, 2, 13,
+ 5, 13, 13, 13, 13, 12, 6, 6,
+ 6, 7, 7, 7, 7, 7, 6, 3,
+ 3, 3, 3, 3, 3, 12, 2, 12,
+ 1, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 4, 7, 3, 4, 3, 8,
+ 3, 1, 12, 3, 13, 3, 12, 7,
+ 13, 13, 1, 12, 3, 13, 1, 13,
+ 6, 14, 13, 13, 12, 6, 4, 4,
+ 5, 5, 5, 5, 5, 6, 2, 2,
+ 2, 2, 2, 2, 2, 12, 1, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3,
+ 4, 7, 3, 4, 3, 8, 1, 12,
+ 3, 13, 3, 12, 7, 12, 12, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 5, 8, 4, 5, 4, 8, 2, 12,
+ 4, 13, 4, 2, 13, 6, 13, 13,
+ 13, 13, 12, 6, 6, 6, 7, 7,
+ 7, 7, 7, 6, 3, 3, 3, 3,
+ 3, 3, 12, 2, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 5, 8, 4,
+ 5, 4, 8, 4, 2, 12, 4, 13,
+ 4, 12, 7, 13, 13, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 5, 8,
+ 4, 5, 4, 8, 2, 12, 4, 13,
+ 12, 6, 14, 2, 13, 13, 13, 12,
+ 6, 6, 6, 7, 7, 7, 7, 7,
+ 6, 3, 3, 3, 3, 3, 3, 5,
+ 3, 3, 3, 3, 3, 12, 5, 12,
+ 13, 13, 13, 9, 13, 5, 5, 5,
+ 3, 3, 3, 13, 8, 6, 12, 5,
+ 5, 4, 8, 5, 12, 1, 13, 13,
+ 13, 12, 6, 6, 6, 7, 7, 7,
+ 7, 7, 6, 2, 2, 2, 2, 2,
+ 2, 4, 2, 2, 2, 2, 2, 12,
+ 4, 12, 13, 4, 12, 4, 12, 0,
+ 13, 13, 13, 12, 6, 4, 4, 5,
+ 5, 5, 5, 5, 6, 1, 1, 1,
+ 1, 1, 1, 3, 12, 3, 12, 13,
+ 5, 5, 5, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 12, 5, 12, 1,
+ 13, 13, 13, 12, 6, 4, 4, 5,
+ 5, 5, 5, 5, 6, 2, 2, 2,
+ 2, 2, 2, 4, 2, 2, 2, 2,
+ 2, 12, 4, 12, 13, 6, 6, 6,
+ 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 7, 9, 6, 6, 6, 13, 13,
+ 13, 13, 12, 6, 6, 6, 7, 7,
+ 7, 7, 7, 6, 3, 3, 3, 3,
+ 3, 3, 5, 3, 3, 3, 3, 3,
+ 12, 5, 12, 13, 14, 2, 13, 13,
+ 13, 9, 13, 5, 5, 5, 3, 3,
+ 3, 13, 8, 6, 12, 5, 5, 4,
+ 8, 5, 12, 1, 13, 13, 13, 12,
+ 6, 6, 6, 7, 7, 7, 7, 7,
+ 6, 2, 2, 2, 2, 2, 2, 4,
+ 2, 2, 2, 2, 2, 12, 4, 12,
+ 13, 4, 4, 3, 8, 3, 4, 4,
+ 4, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 5, 5, 5, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 5, 4,
+ 8, 4, 5, 5, 5, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 6, 6,
+ 6, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 7, 9, 6, 6, 6, 5,
+ 3, 3, 3, 3, 3, 12, 5, 12,
+ 13, 14, 13, 13, 9, 13, 5, 5,
+ 5, 3, 3, 3, 13, 8, 6, 12,
+ 5, 12, 5, 4, 8, 5, 12, 4,
+ 2, 2, 2, 2, 2, 12, 4, 12,
+ 13, 4, 5, 5, 5, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 6, 6,
+ 6, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 7, 9, 6, 6, 6, 13,
+ 13, 13, 13, 14, 13, 13, 9, 13,
+ 4, 4, 4, 2, 2, 2, 13, 6,
+ 8, 5, 5, 5, 13, 13, 9, 13,
+ 4, 4, 4, 2, 2, 2, 13, 13,
+ 13, 14, 13, 13, 9, 13, 4, 4,
+ 4, 2, 2, 2, 13, 6, 8, 5,
+ 5, 5, 5, 3, 3, 3, 3, 3,
+ 12, 5, 12, 13, 14, 13, 13, 9,
+ 13, 5, 5, 5, 3, 3, 3, 13,
+ 8, 6, 12, 5, 12, 12, 6, 6,
+ 6, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 7, 9, 6, 6, 6, 14,
+ 13, 13, 9, 13, 4, 4, 4, 2,
+ 2, 2, 13, 6, 8, 5, 5, 5,
+ 6, 8, 5, 5, 5, 13, 13, 14,
+ 13, 13, 9, 13, 3, 3, 3, 1,
+ 1, 1, 13, 5, 7, 4, 4, 4,
+ 1, 4, 13, 13, 6, 13, 13, 13,
+ 5, 13, 13, 13, 13, 5, 8, 7,
+ 13, 13, 6, 13, 13, 13, 5, 8,
+ 7, 13, 13, 6, 13, 13, 13, 5,
+ 8, 7, 13, 7, 6, 13, 13, 7,
+ 6, 13, 13, 6, 13, 8, 7, 13,
+ 7, 6, 7, 6, 13, 6, 5
+};
+
+static readonly sbyte[] _selector_range_lengths = new sbyte [] {
+ 0, 3, 1, 4, 1, 5, 0, 5,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 0, 0, 0, 0, 0, 0,
+ 1, 6, 3, 4, 1, 4, 4, 4,
+ 5, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 3, 1, 4, 1, 5,
+ 0, 5, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 3, 1, 4, 1,
+ 5, 1, 6, 3, 4, 1, 4, 4,
+ 4, 5, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 3, 1, 4, 1,
+ 5, 1, 6, 3, 4, 1, 1, 5,
+ 4, 4, 5, 4, 4, 4, 3, 3,
+ 6, 3, 3, 3, 3, 3, 3, 0,
+ 0, 0, 2, 0, 0, 5, 0, 5,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 3, 1, 4, 1, 5,
+ 1, 1, 6, 3, 4, 1, 4, 4,
+ 4, 5, 1, 6, 3, 4, 1, 5,
+ 4, 4, 4, 4, 4, 3, 4, 7,
+ 4, 4, 4, 4, 4, 3, 0, 0,
+ 0, 2, 0, 0, 0, 5, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 3, 1, 4, 1, 5, 1, 6,
+ 3, 4, 1, 4, 4, 4, 5, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 3, 1, 4, 1, 5, 1, 6,
+ 3, 4, 1, 1, 5, 4, 4, 5,
+ 4, 4, 4, 3, 3, 6, 3, 3,
+ 3, 3, 3, 3, 0, 0, 0, 2,
+ 0, 0, 5, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 3, 1,
+ 4, 1, 5, 1, 1, 6, 3, 4,
+ 1, 4, 4, 4, 5, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 3,
+ 1, 4, 1, 5, 1, 6, 3, 4,
+ 4, 4, 4, 1, 5, 4, 4, 4,
+ 3, 3, 6, 3, 3, 3, 3, 3,
+ 3, 0, 0, 0, 2, 0, 0, 3,
+ 0, 0, 0, 0, 0, 4, 0, 4,
+ 4, 4, 4, 5, 4, 1, 1, 1,
+ 2, 0, 0, 4, 5, 5, 6, 4,
+ 4, 1, 5, 5, 6, 1, 5, 4,
+ 4, 4, 3, 3, 6, 3, 3, 3,
+ 3, 3, 3, 0, 0, 0, 2, 0,
+ 0, 3, 0, 0, 0, 0, 0, 4,
+ 0, 4, 4, 4, 5, 5, 6, 1,
+ 5, 4, 4, 4, 3, 4, 7, 4,
+ 4, 4, 4, 4, 3, 0, 0, 0,
+ 2, 0, 0, 3, 4, 0, 4, 4,
+ 4, 4, 4, 0, 0, 0, 0, 0,
+ 0, 2, 0, 0, 5, 5, 6, 1,
+ 5, 4, 4, 4, 3, 4, 7, 4,
+ 4, 4, 4, 4, 3, 0, 0, 0,
+ 2, 0, 0, 3, 0, 0, 0, 0,
+ 0, 4, 0, 4, 4, 4, 4, 4,
+ 0, 0, 0, 0, 0, 0, 2, 0,
+ 0, 4, 3, 3, 4, 4, 4, 5,
+ 4, 4, 4, 3, 3, 6, 3, 3,
+ 3, 3, 3, 3, 0, 0, 0, 2,
+ 0, 0, 3, 0, 0, 0, 0, 0,
+ 4, 0, 4, 4, 4, 1, 5, 4,
+ 4, 5, 4, 1, 1, 1, 2, 0,
+ 0, 4, 5, 5, 6, 4, 4, 1,
+ 5, 5, 6, 1, 5, 4, 4, 4,
+ 3, 3, 6, 3, 3, 3, 3, 3,
+ 3, 0, 0, 0, 2, 0, 0, 3,
+ 0, 0, 0, 0, 0, 4, 0, 4,
+ 4, 4, 4, 1, 5, 4, 4, 4,
+ 4, 0, 0, 0, 0, 0, 0, 2,
+ 0, 0, 4, 4, 4, 0, 0, 0,
+ 0, 0, 0, 2, 0, 0, 4, 1,
+ 5, 4, 4, 4, 4, 0, 0, 0,
+ 0, 0, 0, 2, 0, 0, 4, 4,
+ 4, 0, 0, 0, 0, 0, 0, 2,
+ 0, 0, 4, 3, 3, 4, 4, 3,
+ 0, 0, 0, 0, 0, 4, 0, 4,
+ 4, 4, 4, 4, 5, 4, 1, 1,
+ 1, 2, 0, 0, 4, 5, 5, 6,
+ 4, 5, 4, 1, 5, 5, 6, 3,
+ 0, 0, 0, 0, 0, 4, 0, 4,
+ 4, 4, 4, 4, 4, 0, 0, 0,
+ 0, 0, 0, 2, 0, 0, 4, 4,
+ 4, 0, 0, 0, 0, 0, 0, 2,
+ 0, 0, 4, 3, 3, 4, 4, 4,
+ 5, 4, 5, 4, 4, 4, 5, 4,
+ 1, 1, 1, 2, 0, 0, 4, 4,
+ 3, 3, 4, 4, 4, 4, 5, 4,
+ 1, 1, 1, 2, 0, 0, 4, 4,
+ 5, 4, 4, 4, 5, 4, 1, 1,
+ 1, 2, 0, 0, 4, 4, 3, 3,
+ 4, 4, 3, 0, 0, 0, 0, 0,
+ 4, 0, 4, 4, 4, 4, 4, 5,
+ 4, 1, 1, 1, 2, 0, 0, 4,
+ 5, 5, 6, 4, 5, 5, 4, 4,
+ 4, 0, 0, 0, 0, 0, 0, 2,
+ 0, 0, 4, 3, 3, 4, 4, 4,
+ 4, 4, 5, 4, 1, 1, 1, 2,
+ 0, 0, 4, 4, 3, 3, 4, 4,
+ 4, 3, 3, 4, 4, 4, 5, 4,
+ 4, 4, 5, 4, 1, 1, 1, 2,
+ 0, 0, 4, 4, 3, 3, 4, 4,
+ 0, 1, 4, 5, 1, 4, 4, 5,
+ 1, 4, 5, 4, 5, 1, 3, 1,
+ 4, 5, 1, 4, 4, 5, 1, 3,
+ 1, 4, 5, 1, 4, 4, 5, 1,
+ 3, 1, 4, 3, 1, 4, 4, 3,
+ 1, 4, 5, 1, 4, 3, 1, 4,
+ 3, 1, 3, 1, 4, 3, 1
+};
+
+static readonly short[] _selector_index_offsets = new short [] {
+ 0, 0, 10, 14, 22, 26, 40, 42,
+ 60, 63, 66, 69, 72, 75, 78, 81,
+ 84, 87, 92, 94, 96, 98, 100, 102,
+ 104, 106, 125, 131, 149, 153, 170, 182,
+ 199, 217, 221, 225, 229, 233, 237, 241,
+ 245, 249, 253, 259, 270, 275, 284, 289,
+ 303, 306, 324, 328, 332, 336, 340, 344,
+ 348, 352, 356, 360, 366, 377, 382, 391,
+ 396, 410, 413, 432, 439, 457, 462, 479,
+ 490, 507, 525, 530, 535, 540, 545, 550,
+ 555, 560, 565, 570, 577, 589, 595, 605,
+ 611, 625, 629, 648, 656, 674, 680, 684,
+ 703, 713, 731, 750, 768, 786, 803, 813,
+ 823, 836, 847, 858, 869, 880, 891, 901,
+ 905, 909, 913, 919, 923, 927, 945, 948,
+ 966, 968, 972, 976, 980, 984, 988, 992,
+ 996, 1000, 1004, 1010, 1021, 1026, 1035, 1040,
+ 1054, 1059, 1062, 1081, 1088, 1106, 1111, 1128,
+ 1140, 1158, 1177, 1180, 1199, 1206, 1224, 1227,
+ 1246, 1257, 1276, 1294, 1312, 1329, 1339, 1348,
+ 1360, 1370, 1380, 1390, 1400, 1410, 1420, 1423,
+ 1426, 1429, 1434, 1437, 1440, 1443, 1461, 1463,
+ 1467, 1471, 1475, 1479, 1483, 1487, 1491, 1495,
+ 1499, 1505, 1516, 1521, 1530, 1535, 1549, 1552,
+ 1571, 1578, 1596, 1601, 1618, 1630, 1647, 1665,
+ 1670, 1675, 1680, 1685, 1690, 1695, 1700, 1705,
+ 1710, 1717, 1729, 1735, 1745, 1751, 1765, 1769,
+ 1788, 1796, 1814, 1820, 1824, 1843, 1854, 1872,
+ 1891, 1909, 1927, 1944, 1954, 1964, 1977, 1988,
+ 1999, 2010, 2021, 2032, 2042, 2046, 2050, 2054,
+ 2060, 2064, 2068, 2086, 2089, 2094, 2099, 2104,
+ 2109, 2114, 2119, 2124, 2129, 2134, 2141, 2153,
+ 2159, 2169, 2175, 2189, 2195, 2199, 2218, 2226,
+ 2244, 2250, 2267, 2279, 2297, 2316, 2321, 2326,
+ 2331, 2336, 2341, 2346, 2351, 2356, 2361, 2368,
+ 2380, 2386, 2396, 2402, 2416, 2420, 2439, 2447,
+ 2465, 2482, 2493, 2512, 2516, 2535, 2553, 2571,
+ 2588, 2598, 2608, 2621, 2632, 2643, 2654, 2665,
+ 2676, 2686, 2690, 2694, 2698, 2704, 2708, 2712,
+ 2721, 2725, 2729, 2733, 2737, 2741, 2758, 2764,
+ 2781, 2799, 2817, 2835, 2850, 2868, 2875, 2882,
+ 2889, 2895, 2899, 2903, 2921, 2935, 2947, 2966,
+ 2976, 2986, 2992, 3006, 3017, 3036, 3039, 3058,
+ 3076, 3094, 3111, 3121, 3131, 3144, 3155, 3166,
+ 3177, 3188, 3199, 3209, 3212, 3215, 3218, 3223,
+ 3226, 3229, 3237, 3240, 3243, 3246, 3249, 3252,
+ 3269, 3274, 3291, 3309, 3318, 3336, 3346, 3365,
+ 3367, 3386, 3404, 3422, 3439, 3449, 3458, 3470,
+ 3480, 3490, 3500, 3510, 3520, 3530, 3532, 3534,
+ 3536, 3540, 3542, 3544, 3551, 3568, 3572, 3589,
+ 3607, 3617, 3627, 3637, 3640, 3643, 3646, 3649,
+ 3652, 3655, 3660, 3663, 3666, 3684, 3695, 3714,
+ 3717, 3736, 3754, 3772, 3789, 3799, 3808, 3820,
+ 3830, 3840, 3850, 3860, 3870, 3880, 3883, 3886,
+ 3889, 3894, 3897, 3900, 3908, 3911, 3914, 3917,
+ 3920, 3923, 3940, 3945, 3962, 3980, 3991, 4002,
+ 4013, 4017, 4021, 4025, 4029, 4033, 4037, 4043,
+ 4047, 4051, 4063, 4076, 4086, 4097, 4108, 4126,
+ 4145, 4163, 4181, 4198, 4208, 4218, 4231, 4242,
+ 4253, 4264, 4275, 4286, 4296, 4300, 4304, 4308,
+ 4314, 4318, 4322, 4331, 4335, 4339, 4343, 4347,
+ 4351, 4368, 4374, 4391, 4409, 4428, 4432, 4451,
+ 4469, 4487, 4502, 4520, 4527, 4534, 4541, 4547,
+ 4551, 4555, 4573, 4587, 4599, 4618, 4628, 4638,
+ 4644, 4658, 4669, 4688, 4691, 4710, 4728, 4746,
+ 4763, 4773, 4783, 4796, 4807, 4818, 4829, 4840,
+ 4851, 4861, 4864, 4867, 4870, 4875, 4878, 4881,
+ 4889, 4892, 4895, 4898, 4901, 4904, 4921, 4926,
+ 4943, 4961, 4970, 4979, 4984, 4998, 5006, 5015,
+ 5024, 5033, 5035, 5037, 5039, 5041, 5043, 5045,
+ 5049, 5051, 5053, 5063, 5073, 5083, 5086, 5089,
+ 5092, 5095, 5098, 5101, 5106, 5109, 5112, 5122,
+ 5128, 5142, 5151, 5161, 5171, 5181, 5184, 5187,
+ 5190, 5193, 5196, 5199, 5204, 5207, 5210, 5221,
+ 5232, 5243, 5247, 5251, 5255, 5259, 5263, 5267,
+ 5273, 5277, 5281, 5293, 5306, 5316, 5327, 5338,
+ 5347, 5351, 5355, 5359, 5363, 5367, 5384, 5390,
+ 5407, 5425, 5444, 5462, 5480, 5495, 5513, 5520,
+ 5527, 5534, 5540, 5544, 5548, 5566, 5580, 5592,
+ 5611, 5621, 5639, 5649, 5655, 5669, 5680, 5699,
+ 5707, 5710, 5713, 5716, 5719, 5722, 5739, 5744,
+ 5761, 5779, 5788, 5798, 5808, 5818, 5821, 5824,
+ 5827, 5830, 5833, 5836, 5841, 5844, 5847, 5858,
+ 5869, 5880, 5884, 5888, 5892, 5896, 5900, 5904,
+ 5910, 5914, 5918, 5930, 5943, 5953, 5964, 5975,
+ 5993, 6012, 6030, 6049, 6068, 6086, 6104, 6119,
+ 6137, 6143, 6149, 6155, 6160, 6163, 6166, 6184,
+ 6195, 6207, 6216, 6226, 6236, 6254, 6272, 6287,
+ 6305, 6311, 6317, 6323, 6328, 6331, 6334, 6352,
+ 6370, 6389, 6408, 6426, 6444, 6459, 6477, 6483,
+ 6489, 6495, 6500, 6503, 6506, 6524, 6535, 6547,
+ 6556, 6566, 6576, 6585, 6589, 6593, 6597, 6601,
+ 6605, 6622, 6628, 6645, 6663, 6682, 6700, 6718,
+ 6733, 6751, 6758, 6765, 6772, 6778, 6782, 6786,
+ 6804, 6818, 6830, 6849, 6859, 6877, 6895, 6906,
+ 6917, 6928, 6932, 6936, 6940, 6944, 6948, 6952,
+ 6958, 6962, 6966, 6978, 6991, 7001, 7012, 7023,
+ 7042, 7060, 7078, 7093, 7111, 7117, 7123, 7129,
+ 7134, 7137, 7140, 7158, 7169, 7181, 7190, 7200,
+ 7210, 7221, 7233, 7242, 7252, 7262, 7280, 7299,
+ 7318, 7336, 7354, 7369, 7387, 7392, 7397, 7402,
+ 7406, 7408, 7410, 7428, 7438, 7449, 7457, 7466,
+ 7475, 7477, 7483, 7501, 7520, 7528, 7546, 7564,
+ 7583, 7590, 7608, 7627, 7645, 7664, 7671, 7683,
+ 7692, 7710, 7729, 7737, 7755, 7773, 7792, 7799,
+ 7811, 7820, 7838, 7857, 7865, 7883, 7901, 7920,
+ 7927, 7939, 7948, 7966, 7977, 7985, 8003, 8021,
+ 8032, 8040, 8058, 8077, 8085, 8103, 8115, 8124,
+ 8142, 8153, 8161, 8172, 8180, 8198, 8208
+};
+
+static readonly short[] _selector_trans_targs = new short [] {
+ 1, 2, 0, 811, 549, 869, 0, 1,
+ 0, 3, 0, 549, 0, 3, 4, 548,
+ 549, 0, 4, 0, 0, 3, 4, 5,
+ 4, 0, 5, 6, 23, 24, 26, 25,
+ 30, 377, 0, 5, 0, 25, 27, 29,
+ 7, 6, 7, 8, 6, 23, 24, 5,
+ 26, 5, 25, 30, 377, 825, 0, 7,
+ 0, 25, 27, 29, 9, 9, 0, 10,
+ 10, 0, 11, 11, 0, 12, 12, 0,
+ 13, 13, 0, 14, 14, 0, 15, 15,
+ 0, 16, 16, 0, 17, 17, 0, 17,
+ 1, 817, 17, 0, 19, 0, 817, 0,
+ 21, 0, 22, 0, 817, 0, 7, 23,
+ 25, 0, 7, 8, 6, 7, 23, 24,
+ 26, 375, 25, 30, 377, 825, 0, 7,
+ 0, 5, 25, 27, 29, 25, 30, 0,
+ 25, 27, 29, 7, 8, 6, 7, 23,
+ 28, 24, 5, 375, 5, 30, 377, 825,
+ 0, 7, 0, 27, 29, 28, 7, 28,
+ 0, 7, 8, 6, 23, 28, 24, 5,
+ 0, 5, 30, 377, 825, 0, 7, 0,
+ 27, 29, 7, 31, 70, 797, 30, 377,
+ 825, 7, 799, 810, 810, 29, 32, 33,
+ 32, 48, 136, 146, 47, 6, 47, 152,
+ 154, 845, 6, 32, 6, 149, 31, 32,
+ 33, 32, 48, 146, 47, 148, 47, 147,
+ 152, 154, 845, 6, 32, 6, 147, 149,
+ 31, 7, 34, 34, 6, 7, 35, 35,
+ 6, 7, 36, 36, 6, 7, 37, 37,
+ 6, 7, 38, 38, 6, 7, 39, 39,
+ 6, 7, 40, 40, 6, 7, 41, 41,
+ 6, 7, 42, 42, 6, 42, 7, 43,
+ 847, 42, 6, 43, 7, 44, 6, 792,
+ 649, 866, 6, 43, 6, 45, 7, 6,
+ 649, 6, 45, 46, 7, 636, 649, 6,
+ 46, 6, 6, 45, 46, 7, 47, 46,
+ 6, 47, 32, 48, 146, 148, 147, 152,
+ 154, 6, 47, 6, 147, 149, 31, 49,
+ 32, 48, 49, 50, 48, 49, 65, 64,
+ 67, 64, 66, 71, 343, 822, 23, 49,
+ 23, 66, 68, 70, 7, 51, 51, 23,
+ 7, 52, 52, 23, 7, 53, 53, 23,
+ 7, 54, 54, 23, 7, 55, 55, 23,
+ 7, 56, 56, 23, 7, 57, 57, 23,
+ 7, 58, 58, 23, 7, 59, 59, 23,
+ 59, 7, 60, 824, 59, 23, 60, 7,
+ 61, 23, 787, 371, 864, 23, 60, 23,
+ 62, 7, 23, 371, 23, 62, 63, 7,
+ 338, 371, 23, 63, 23, 23, 62, 63,
+ 7, 64, 63, 23, 64, 48, 49, 65,
+ 67, 66, 71, 343, 23, 64, 23, 66,
+ 68, 70, 7, 66, 23, 49, 50, 48,
+ 49, 49, 65, 67, 341, 66, 71, 343,
+ 822, 23, 49, 23, 64, 66, 68, 70,
+ 7, 66, 71, 23, 66, 68, 70, 49,
+ 50, 48, 49, 49, 69, 65, 64, 341,
+ 64, 71, 343, 822, 23, 49, 23, 68,
+ 70, 69, 7, 49, 69, 23, 49, 50,
+ 48, 49, 69, 65, 64, 23, 64, 71,
+ 343, 822, 23, 49, 23, 68, 70, 49,
+ 72, 679, 71, 343, 822, 49, 775, 786,
+ 786, 70, 73, 74, 73, 73, 93, 89,
+ 88, 48, 88, 96, 99, 857, 48, 73,
+ 48, 92, 72, 73, 74, 73, 73, 89,
+ 88, 91, 88, 90, 96, 99, 857, 48,
+ 73, 48, 90, 92, 72, 49, 32, 75,
+ 75, 48, 49, 32, 76, 76, 48, 49,
+ 32, 77, 77, 48, 49, 32, 78, 78,
+ 48, 49, 32, 79, 79, 48, 49, 32,
+ 80, 80, 48, 49, 32, 81, 81, 48,
+ 49, 32, 82, 82, 48, 49, 32, 83,
+ 83, 48, 83, 49, 32, 84, 859, 83,
+ 48, 84, 49, 32, 85, 48, 770, 755,
+ 861, 48, 84, 48, 86, 49, 32, 48,
+ 755, 48, 86, 87, 49, 32, 752, 755,
+ 48, 87, 48, 48, 86, 87, 49, 32,
+ 88, 87, 48, 88, 73, 73, 89, 91,
+ 90, 96, 99, 48, 88, 48, 90, 92,
+ 72, 49, 32, 90, 48, 73, 74, 73,
+ 73, 73, 89, 91, 94, 90, 96, 99,
+ 857, 48, 73, 48, 88, 90, 92, 72,
+ 49, 32, 90, 96, 48, 90, 92, 72,
+ 73, 74, 73, 73, 73, 93, 89, 88,
+ 94, 88, 96, 99, 857, 48, 73, 48,
+ 92, 72, 93, 49, 32, 73, 93, 48,
+ 49, 32, 95, 48, 73, 74, 73, 73,
+ 73, 89, 88, 91, 88, 90, 96, 99,
+ 857, 48, 73, 48, 90, 92, 72, 73,
+ 97, 96, 99, 857, 73, 740, 751, 751,
+ 72, 98, 74, 73, 73, 93, 73, 89,
+ 88, 48, 88, 96, 99, 857, 48, 98,
+ 48, 92, 72, 98, 74, 73, 73, 73,
+ 89, 88, 91, 88, 90, 96, 99, 857,
+ 48, 98, 48, 90, 92, 72, 73, 74,
+ 73, 73, 93, 89, 88, 48, 88, 96,
+ 100, 99, 857, 48, 73, 48, 92, 72,
+ 73, 74, 73, 73, 93, 89, 88, 48,
+ 88, 96, 101, 99, 857, 48, 73, 48,
+ 92, 72, 73, 74, 73, 73, 102, 89,
+ 88, 48, 88, 96, 99, 857, 48, 73,
+ 48, 92, 72, 102, 117, 198, 48, 73,
+ 104, 48, 102, 48, 103, 93, 49, 32,
+ 48, 73, 104, 48, 93, 48, 103, 93,
+ 49, 32, 48, 73, 104, 48, 93, 48,
+ 105, 105, 105, 103, 93, 49, 32, 48,
+ 73, 104, 106, 48, 93, 48, 103, 93,
+ 49, 32, 48, 73, 107, 104, 48, 93,
+ 48, 103, 93, 49, 32, 48, 73, 108,
+ 104, 48, 93, 48, 103, 93, 49, 32,
+ 48, 73, 109, 104, 48, 93, 48, 103,
+ 93, 49, 32, 48, 73, 104, 110, 48,
+ 93, 48, 103, 93, 49, 32, 111, 73,
+ 104, 48, 93, 48, 103, 112, 49, 32,
+ 48, 113, 49, 32, 48, 49, 32, 114,
+ 48, 115, 49, 32, 115, 115, 48, 49,
+ 32, 116, 48, 49, 32, 103, 48, 117,
+ 269, 93, 117, 284, 283, 286, 283, 285,
+ 289, 293, 818, 118, 117, 118, 285, 287,
+ 288, 69, 119, 118, 119, 121, 136, 118,
+ 137, 135, 139, 135, 138, 143, 417, 827,
+ 120, 119, 120, 138, 140, 142, 28, 120,
+ 28, 122, 122, 120, 28, 123, 123, 120,
+ 28, 124, 124, 120, 28, 125, 125, 120,
+ 28, 126, 126, 120, 28, 127, 127, 120,
+ 28, 128, 128, 120, 28, 129, 129, 120,
+ 28, 130, 130, 120, 130, 28, 131, 829,
+ 130, 120, 131, 28, 132, 120, 725, 577,
+ 855, 120, 131, 120, 133, 28, 120, 577,
+ 120, 133, 134, 28, 576, 577, 120, 134,
+ 120, 120, 133, 134, 28, 135, 134, 120,
+ 135, 136, 118, 137, 139, 138, 143, 417,
+ 120, 135, 120, 138, 140, 142, 136, 7,
+ 32, 136, 6, 28, 138, 120, 119, 121,
+ 136, 119, 118, 137, 139, 415, 138, 143,
+ 417, 827, 120, 119, 120, 135, 138, 140,
+ 142, 28, 138, 143, 120, 138, 140, 142,
+ 119, 121, 136, 119, 118, 141, 137, 135,
+ 415, 135, 143, 417, 827, 120, 119, 120,
+ 140, 142, 141, 28, 119, 141, 120, 119,
+ 121, 136, 118, 141, 137, 135, 120, 135,
+ 143, 417, 827, 120, 119, 120, 140, 142,
+ 119, 144, 288, 711, 143, 417, 827, 119,
+ 713, 724, 724, 142, 145, 33, 32, 48,
+ 136, 32, 146, 47, 6, 47, 152, 154,
+ 845, 6, 145, 6, 149, 31, 145, 33,
+ 32, 48, 32, 146, 47, 148, 47, 147,
+ 152, 154, 845, 6, 145, 6, 147, 149,
+ 31, 7, 147, 6, 32, 33, 32, 32,
+ 48, 146, 148, 150, 147, 152, 154, 845,
+ 6, 32, 6, 47, 147, 149, 31, 7,
+ 147, 152, 6, 147, 149, 31, 32, 33,
+ 32, 32, 48, 136, 146, 47, 150, 47,
+ 152, 154, 845, 6, 32, 6, 149, 31,
+ 7, 151, 6, 32, 33, 32, 32, 48,
+ 146, 47, 148, 47, 147, 152, 154, 845,
+ 6, 32, 6, 147, 149, 31, 32, 72,
+ 144, 152, 154, 845, 32, 153, 710, 710,
+ 31, 32, 33, 32, 32, 48, 136, 146,
+ 47, 150, 47, 152, 154, 700, 845, 6,
+ 32, 6, 149, 31, 32, 33, 32, 48,
+ 136, 146, 47, 6, 47, 152, 155, 154,
+ 845, 6, 32, 6, 149, 31, 32, 33,
+ 32, 48, 136, 146, 47, 6, 47, 152,
+ 156, 154, 845, 6, 32, 6, 149, 31,
+ 32, 33, 32, 48, 157, 146, 47, 6,
+ 47, 152, 154, 845, 6, 32, 6, 149,
+ 31, 157, 119, 172, 6, 32, 159, 6,
+ 157, 6, 158, 136, 7, 32, 159, 6,
+ 136, 6, 6, 158, 136, 7, 32, 159,
+ 6, 136, 6, 6, 160, 160, 160, 158,
+ 136, 7, 32, 159, 161, 6, 136, 6,
+ 6, 158, 136, 7, 32, 162, 159, 6,
+ 136, 6, 6, 158, 136, 7, 32, 163,
+ 159, 6, 136, 6, 6, 158, 136, 7,
+ 32, 164, 159, 6, 136, 6, 6, 158,
+ 136, 7, 32, 159, 165, 6, 136, 6,
+ 6, 158, 136, 7, 6, 166, 32, 159,
+ 6, 136, 6, 158, 167, 7, 6, 168,
+ 7, 6, 7, 169, 6, 170, 7, 170,
+ 170, 6, 7, 171, 6, 7, 158, 6,
+ 173, 136, 172, 173, 175, 172, 69, 190,
+ 189, 192, 189, 191, 196, 517, 836, 174,
+ 173, 174, 191, 193, 195, 28, 174, 28,
+ 176, 176, 174, 28, 177, 177, 174, 28,
+ 178, 178, 174, 28, 179, 179, 174, 28,
+ 180, 180, 174, 28, 181, 181, 174, 28,
+ 182, 182, 174, 28, 183, 183, 174, 28,
+ 184, 184, 174, 184, 28, 185, 838, 184,
+ 174, 185, 28, 186, 174, 695, 545, 851,
+ 174, 185, 174, 187, 28, 174, 545, 174,
+ 187, 188, 28, 512, 545, 174, 188, 174,
+ 174, 187, 188, 28, 189, 188, 174, 189,
+ 172, 69, 190, 192, 191, 196, 517, 174,
+ 189, 174, 191, 193, 195, 28, 191, 174,
+ 173, 175, 172, 173, 69, 190, 192, 515,
+ 191, 196, 517, 836, 174, 173, 174, 189,
+ 191, 193, 195, 28, 191, 196, 174, 191,
+ 193, 195, 173, 175, 172, 173, 69, 194,
+ 190, 189, 515, 189, 196, 517, 836, 174,
+ 173, 174, 193, 195, 194, 28, 173, 194,
+ 174, 173, 175, 172, 69, 194, 190, 189,
+ 174, 189, 196, 517, 836, 174, 173, 174,
+ 193, 195, 173, 197, 679, 681, 196, 517,
+ 836, 173, 683, 694, 694, 195, 198, 199,
+ 198, 93, 218, 214, 213, 172, 213, 221,
+ 224, 841, 172, 198, 172, 217, 197, 198,
+ 199, 198, 93, 214, 213, 216, 213, 215,
+ 221, 224, 841, 172, 198, 172, 215, 217,
+ 197, 173, 136, 200, 200, 172, 173, 136,
+ 201, 201, 172, 173, 136, 202, 202, 172,
+ 173, 136, 203, 203, 172, 173, 136, 204,
+ 204, 172, 173, 136, 205, 205, 172, 173,
+ 136, 206, 206, 172, 173, 136, 207, 207,
+ 172, 173, 136, 208, 208, 172, 208, 173,
+ 136, 209, 843, 208, 172, 209, 173, 136,
+ 210, 172, 674, 632, 848, 172, 209, 172,
+ 211, 173, 136, 172, 632, 172, 211, 212,
+ 173, 136, 629, 632, 172, 212, 172, 172,
+ 211, 212, 173, 136, 213, 212, 172, 213,
+ 198, 93, 214, 216, 215, 221, 224, 172,
+ 213, 172, 215, 217, 197, 173, 136, 215,
+ 172, 198, 199, 198, 198, 93, 214, 216,
+ 219, 215, 221, 224, 841, 172, 198, 172,
+ 213, 215, 217, 197, 173, 136, 215, 221,
+ 172, 215, 217, 197, 198, 199, 198, 198,
+ 93, 218, 214, 213, 219, 213, 221, 224,
+ 841, 172, 198, 172, 217, 197, 218, 173,
+ 136, 198, 218, 172, 173, 136, 220, 172,
+ 198, 199, 198, 198, 93, 214, 213, 216,
+ 213, 215, 221, 224, 841, 172, 198, 172,
+ 215, 217, 197, 198, 97, 222, 221, 224,
+ 841, 198, 617, 628, 628, 197, 223, 199,
+ 198, 93, 218, 198, 214, 213, 172, 213,
+ 221, 224, 841, 172, 223, 172, 217, 197,
+ 223, 199, 198, 93, 198, 214, 213, 216,
+ 213, 215, 221, 224, 841, 172, 223, 172,
+ 215, 217, 197, 198, 199, 198, 93, 218,
+ 214, 213, 172, 213, 221, 225, 224, 841,
+ 172, 198, 172, 217, 197, 198, 199, 198,
+ 93, 218, 214, 213, 172, 213, 221, 226,
+ 224, 841, 172, 198, 172, 217, 197, 198,
+ 199, 198, 93, 227, 214, 213, 172, 213,
+ 221, 224, 841, 172, 198, 172, 217, 197,
+ 227, 242, 218, 172, 198, 229, 172, 227,
+ 172, 228, 218, 173, 136, 172, 198, 229,
+ 172, 218, 172, 228, 218, 173, 136, 172,
+ 198, 229, 172, 218, 172, 230, 230, 230,
+ 228, 218, 173, 136, 172, 198, 229, 231,
+ 172, 218, 172, 228, 218, 173, 136, 172,
+ 198, 232, 229, 172, 218, 172, 228, 218,
+ 173, 136, 172, 198, 233, 229, 172, 218,
+ 172, 228, 218, 173, 136, 172, 198, 234,
+ 229, 172, 218, 172, 228, 218, 173, 136,
+ 172, 198, 229, 235, 172, 218, 172, 228,
+ 218, 173, 136, 236, 198, 229, 172, 218,
+ 172, 228, 237, 173, 136, 172, 238, 173,
+ 136, 172, 173, 136, 239, 172, 240, 173,
+ 136, 240, 240, 172, 173, 136, 241, 172,
+ 173, 136, 228, 172, 242, 244, 218, 259,
+ 260, 258, 262, 258, 261, 266, 464, 832,
+ 243, 242, 243, 261, 263, 265, 194, 141,
+ 243, 194, 141, 245, 245, 243, 194, 141,
+ 246, 246, 243, 194, 141, 247, 247, 243,
+ 194, 141, 248, 248, 243, 194, 141, 249,
+ 249, 243, 194, 141, 250, 250, 243, 194,
+ 141, 251, 251, 243, 194, 141, 252, 252,
+ 243, 194, 141, 253, 253, 243, 253, 194,
+ 141, 254, 834, 253, 243, 254, 194, 141,
+ 255, 243, 602, 509, 839, 243, 254, 243,
+ 256, 194, 141, 243, 509, 243, 256, 257,
+ 194, 141, 506, 509, 243, 257, 243, 243,
+ 256, 257, 194, 141, 258, 257, 243, 258,
+ 218, 259, 260, 262, 261, 266, 464, 243,
+ 258, 243, 261, 263, 265, 259, 69, 119,
+ 117, 259, 118, 194, 141, 261, 243, 242,
+ 244, 218, 242, 259, 260, 262, 493, 261,
+ 266, 464, 832, 243, 242, 243, 258, 261,
+ 263, 265, 194, 141, 261, 266, 243, 261,
+ 263, 265, 242, 244, 218, 242, 259, 264,
+ 260, 258, 493, 258, 266, 464, 832, 243,
+ 242, 243, 263, 265, 264, 194, 141, 242,
+ 264, 243, 242, 244, 218, 259, 264, 260,
+ 258, 243, 258, 266, 464, 832, 243, 242,
+ 243, 263, 265, 242, 222, 267, 462, 266,
+ 464, 832, 242, 492, 505, 505, 265, 268,
+ 269, 93, 117, 259, 117, 284, 283, 118,
+ 283, 289, 293, 818, 118, 268, 118, 287,
+ 288, 268, 269, 93, 117, 117, 284, 283,
+ 286, 283, 285, 289, 293, 818, 118, 268,
+ 118, 285, 287, 288, 69, 119, 270, 270,
+ 118, 69, 119, 271, 271, 118, 69, 119,
+ 272, 272, 118, 69, 119, 273, 273, 118,
+ 69, 119, 274, 274, 118, 69, 119, 275,
+ 275, 118, 69, 119, 276, 276, 118, 69,
+ 119, 277, 277, 118, 69, 119, 278, 278,
+ 118, 278, 69, 119, 279, 820, 278, 118,
+ 279, 69, 119, 280, 118, 457, 335, 830,
+ 118, 279, 118, 281, 69, 119, 118, 335,
+ 118, 281, 282, 69, 119, 332, 335, 118,
+ 282, 118, 118, 281, 282, 69, 119, 283,
+ 282, 118, 283, 93, 117, 284, 286, 285,
+ 289, 293, 118, 283, 118, 285, 287, 288,
+ 69, 119, 285, 118, 117, 269, 93, 117,
+ 117, 284, 286, 291, 285, 289, 293, 818,
+ 118, 117, 118, 283, 285, 287, 288, 69,
+ 119, 285, 289, 118, 285, 287, 288, 117,
+ 269, 93, 117, 117, 259, 284, 283, 291,
+ 283, 289, 293, 818, 118, 117, 118, 287,
+ 288, 117, 269, 93, 117, 259, 284, 283,
+ 118, 283, 289, 293, 818, 118, 117, 118,
+ 287, 288, 117, 97, 267, 289, 293, 818,
+ 117, 290, 331, 331, 288, 117, 269, 93,
+ 117, 117, 259, 284, 283, 291, 283, 289,
+ 293, 321, 818, 118, 117, 118, 287, 288,
+ 69, 119, 292, 118, 117, 269, 93, 117,
+ 117, 284, 283, 286, 283, 285, 289, 293,
+ 818, 118, 117, 118, 285, 287, 288, 117,
+ 269, 93, 117, 259, 284, 283, 118, 283,
+ 289, 294, 293, 818, 118, 117, 118, 287,
+ 288, 117, 269, 93, 117, 259, 284, 283,
+ 118, 283, 289, 295, 293, 818, 118, 117,
+ 118, 287, 288, 117, 269, 93, 117, 296,
+ 284, 283, 118, 283, 289, 293, 818, 118,
+ 117, 118, 287, 288, 296, 259, 242, 118,
+ 117, 298, 118, 296, 118, 297, 259, 69,
+ 119, 118, 117, 298, 118, 259, 118, 297,
+ 259, 69, 119, 118, 117, 298, 118, 259,
+ 118, 299, 299, 299, 297, 259, 69, 119,
+ 118, 117, 298, 300, 118, 259, 118, 297,
+ 259, 69, 119, 118, 117, 301, 298, 118,
+ 259, 118, 297, 259, 69, 119, 118, 117,
+ 302, 298, 118, 259, 118, 297, 259, 69,
+ 119, 118, 117, 303, 298, 118, 259, 118,
+ 297, 259, 69, 119, 118, 117, 298, 304,
+ 118, 259, 118, 297, 259, 69, 119, 305,
+ 117, 298, 118, 259, 118, 297, 306, 69,
+ 119, 118, 307, 69, 119, 118, 69, 119,
+ 308, 118, 309, 69, 119, 309, 309, 118,
+ 69, 119, 310, 118, 69, 119, 297, 118,
+ 69, 119, 312, 285, 289, 118, 285, 287,
+ 288, 69, 119, 820, 118, 69, 119, 312,
+ 118, 315, 69, 119, 118, 69, 119, 316,
+ 118, 69, 119, 820, 118, 117, 318, 93,
+ 117, 259, 284, 283, 118, 283, 289, 293,
+ 818, 118, 117, 118, 287, 288, 69, 119,
+ 316, 270, 270, 118, 117, 269, 93, 117,
+ 259, 284, 283, 320, 283, 289, 293, 818,
+ 118, 117, 118, 287, 288, 117, 269, 93,
+ 117, 259, 284, 283, 118, 283, 818, 289,
+ 293, 818, 118, 117, 118, 287, 288, 117,
+ 269, 93, 117, 259, 284, 283, 118, 283,
+ 322, 289, 293, 818, 118, 117, 118, 287,
+ 288, 117, 269, 93, 117, 117, 259, 284,
+ 323, 291, 283, 289, 293, 818, 118, 117,
+ 118, 287, 288, 283, 93, 117, 284, 286,
+ 324, 285, 289, 293, 118, 283, 118, 285,
+ 287, 288, 117, 269, 93, 117, 117, 259,
+ 284, 283, 291, 283, 289, 293, 821, 118,
+ 117, 118, 287, 288, 326, 259, 69, 119,
+ 117, 259, 118, 327, 259, 69, 119, 117,
+ 259, 118, 259, 69, 119, 117, 328, 259,
+ 118, 329, 69, 119, 329, 329, 118, 69,
+ 119, 330, 118, 69, 119, 288, 118, 117,
+ 269, 93, 117, 259, 284, 283, 118, 283,
+ 289, 293, 321, 818, 118, 117, 118, 287,
+ 288, 283, 93, 117, 284, 333, 334, 289,
+ 293, 118, 283, 118, 334, 287, 288, 282,
+ 69, 119, 281, 334, 289, 118, 282, 118,
+ 334, 287, 288, 117, 269, 93, 117, 117,
+ 284, 333, 291, 334, 289, 293, 818, 118,
+ 117, 118, 283, 334, 287, 288, 282, 336,
+ 412, 332, 335, 282, 445, 445, 445, 281,
+ 337, 7, 49, 338, 371, 23, 337, 23,
+ 23, 62, 337, 7, 49, 64, 337, 23,
+ 64, 48, 49, 65, 339, 340, 71, 343,
+ 23, 64, 23, 340, 68, 70, 63, 7,
+ 62, 340, 71, 23, 63, 23, 340, 68,
+ 70, 49, 50, 48, 49, 49, 65, 339,
+ 341, 340, 71, 343, 822, 23, 49, 23,
+ 64, 340, 68, 70, 7, 342, 23, 49,
+ 50, 48, 49, 49, 65, 64, 67, 64,
+ 66, 71, 343, 822, 23, 49, 23, 66,
+ 68, 70, 49, 50, 48, 49, 69, 65,
+ 64, 23, 64, 71, 344, 343, 822, 23,
+ 49, 23, 68, 70, 49, 50, 48, 49,
+ 69, 65, 64, 23, 64, 71, 345, 343,
+ 822, 23, 49, 23, 68, 70, 49, 50,
+ 48, 49, 346, 65, 64, 23, 64, 71,
+ 343, 822, 23, 49, 23, 68, 70, 346,
+ 118, 173, 23, 49, 348, 23, 346, 23,
+ 347, 69, 23, 7, 23, 49, 348, 23,
+ 69, 23, 347, 69, 23, 7, 23, 49,
+ 348, 23, 69, 23, 349, 349, 349, 347,
+ 69, 23, 7, 23, 49, 348, 350, 23,
+ 69, 23, 347, 69, 23, 7, 23, 49,
+ 351, 348, 23, 69, 23, 347, 69, 23,
+ 7, 23, 49, 352, 348, 23, 69, 23,
+ 347, 69, 23, 7, 23, 49, 353, 348,
+ 23, 69, 23, 347, 69, 23, 7, 23,
+ 49, 348, 354, 23, 69, 23, 347, 69,
+ 23, 7, 355, 49, 348, 23, 69, 23,
+ 347, 356, 7, 23, 357, 7, 23, 7,
+ 358, 23, 359, 7, 359, 359, 23, 7,
+ 360, 23, 7, 347, 23, 7, 362, 66,
+ 71, 23, 66, 68, 70, 7, 824, 23,
+ 7, 362, 23, 365, 7, 23, 7, 366,
+ 23, 7, 824, 23, 49, 368, 48, 49,
+ 69, 65, 64, 23, 64, 71, 343, 822,
+ 23, 49, 23, 68, 70, 7, 366, 51,
+ 51, 23, 49, 50, 48, 49, 69, 65,
+ 64, 370, 64, 71, 343, 822, 23, 49,
+ 23, 68, 70, 49, 50, 48, 49, 69,
+ 65, 64, 23, 64, 822, 71, 343, 822,
+ 23, 49, 23, 68, 70, 63, 372, 338,
+ 371, 63, 400, 400, 400, 62, 7, 8,
+ 6, 23, 24, 5, 373, 5, 374, 30,
+ 377, 825, 0, 7, 0, 374, 27, 29,
+ 4, 3, 374, 30, 0, 4, 0, 374,
+ 27, 29, 7, 8, 6, 7, 23, 24,
+ 373, 375, 374, 30, 377, 825, 0, 7,
+ 0, 5, 374, 27, 29, 376, 0, 7,
+ 8, 6, 7, 23, 24, 5, 26, 5,
+ 25, 30, 377, 825, 0, 7, 0, 25,
+ 27, 29, 7, 8, 6, 23, 28, 24,
+ 5, 0, 5, 30, 378, 377, 825, 0,
+ 7, 0, 27, 29, 7, 8, 6, 23,
+ 28, 24, 5, 0, 5, 30, 379, 377,
+ 825, 0, 7, 0, 27, 29, 7, 8,
+ 6, 23, 380, 24, 5, 0, 5, 30,
+ 377, 825, 0, 7, 0, 27, 29, 380,
+ 120, 174, 0, 7, 382, 0, 380, 0,
+ 381, 28, 0, 7, 382, 0, 28, 0,
+ 0, 381, 28, 0, 7, 382, 0, 28,
+ 0, 0, 383, 383, 383, 381, 28, 0,
+ 7, 382, 384, 0, 28, 0, 0, 381,
+ 28, 0, 7, 385, 382, 0, 28, 0,
+ 0, 381, 28, 0, 7, 386, 382, 0,
+ 28, 0, 0, 381, 28, 0, 7, 387,
+ 382, 0, 28, 0, 0, 381, 28, 0,
+ 7, 382, 388, 0, 28, 0, 0, 381,
+ 28, 0, 0, 389, 7, 382, 0, 28,
+ 0, 381, 390, 0, 391, 0, 392, 0,
+ 393, 393, 393, 0, 394, 0, 381, 0,
+ 19, 25, 30, 0, 25, 27, 29, 7,
+ 397, 6, 23, 28, 24, 5, 0, 5,
+ 30, 377, 825, 0, 7, 0, 27, 29,
+ 22, 9, 9, 0, 7, 8, 6, 23,
+ 28, 24, 5, 399, 5, 30, 377, 825,
+ 0, 7, 0, 27, 29, 7, 8, 6,
+ 23, 28, 24, 5, 0, 5, 825, 30,
+ 377, 825, 0, 7, 0, 27, 29, 63,
+ 7, 338, 371, 401, 23, 63, 23, 23,
+ 62, 63, 7, 402, 338, 371, 23, 63,
+ 23, 23, 62, 63, 7, 403, 338, 371,
+ 23, 63, 23, 23, 62, 7, 404, 23,
+ 7, 405, 23, 7, 406, 23, 407, 7,
+ 23, 408, 7, 23, 7, 409, 23, 410,
+ 7, 410, 410, 23, 7, 411, 23, 7,
+ 62, 23, 119, 121, 136, 118, 137, 135,
+ 413, 135, 414, 143, 417, 827, 120, 119,
+ 120, 414, 140, 142, 134, 28, 133, 414,
+ 143, 120, 134, 120, 414, 140, 142, 119,
+ 121, 136, 119, 118, 137, 413, 415, 414,
+ 143, 417, 827, 120, 119, 120, 135, 414,
+ 140, 142, 28, 416, 120, 119, 121, 136,
+ 119, 118, 137, 135, 139, 135, 138, 143,
+ 417, 827, 120, 119, 120, 138, 140, 142,
+ 119, 121, 136, 118, 141, 137, 135, 120,
+ 135, 143, 418, 417, 827, 120, 119, 120,
+ 140, 142, 119, 121, 136, 118, 141, 137,
+ 135, 120, 135, 143, 419, 417, 827, 120,
+ 119, 120, 140, 142, 119, 121, 136, 118,
+ 420, 137, 135, 120, 135, 143, 417, 827,
+ 120, 119, 120, 140, 142, 420, 141, 243,
+ 120, 119, 422, 120, 420, 120, 421, 141,
+ 28, 119, 422, 120, 141, 120, 120, 421,
+ 141, 28, 119, 422, 120, 141, 120, 120,
+ 423, 423, 423, 421, 141, 28, 119, 422,
+ 424, 120, 141, 120, 120, 421, 141, 28,
+ 119, 425, 422, 120, 141, 120, 120, 421,
+ 141, 28, 119, 426, 422, 120, 141, 120,
+ 120, 421, 141, 28, 119, 427, 422, 120,
+ 141, 120, 120, 421, 141, 28, 119, 422,
+ 428, 120, 141, 120, 120, 421, 141, 28,
+ 120, 429, 119, 422, 120, 141, 120, 421,
+ 430, 28, 120, 431, 28, 120, 28, 432,
+ 120, 433, 28, 433, 433, 120, 28, 434,
+ 120, 28, 421, 120, 28, 436, 138, 143,
+ 120, 138, 140, 142, 28, 829, 120, 28,
+ 436, 120, 439, 28, 120, 28, 440, 120,
+ 28, 829, 120, 119, 442, 136, 118, 141,
+ 137, 135, 120, 135, 143, 417, 827, 120,
+ 119, 120, 140, 142, 28, 440, 122, 122,
+ 120, 119, 121, 136, 118, 141, 137, 135,
+ 444, 135, 143, 417, 827, 120, 119, 120,
+ 140, 142, 119, 121, 136, 118, 141, 137,
+ 135, 120, 135, 827, 143, 417, 827, 120,
+ 119, 120, 140, 142, 282, 69, 119, 332,
+ 335, 446, 118, 282, 118, 118, 281, 282,
+ 69, 119, 447, 332, 335, 118, 282, 118,
+ 118, 281, 282, 69, 119, 448, 332, 335,
+ 118, 282, 118, 118, 281, 69, 119, 449,
+ 118, 69, 119, 450, 118, 69, 119, 451,
+ 118, 452, 69, 119, 118, 453, 69, 119,
+ 118, 69, 119, 454, 118, 455, 69, 119,
+ 455, 455, 118, 69, 119, 456, 118, 69,
+ 119, 281, 118, 458, 69, 119, 332, 457,
+ 335, 830, 118, 458, 118, 118, 281, 458,
+ 69, 119, 280, 118, 332, 457, 335, 830,
+ 118, 458, 118, 281, 282, 69, 119, 460,
+ 332, 335, 118, 282, 118, 281, 282, 69,
+ 119, 332, 830, 335, 118, 282, 118, 118,
+ 281, 282, 315, 69, 119, 332, 335, 118,
+ 282, 118, 118, 281, 463, 244, 218, 259,
+ 264, 242, 260, 258, 243, 258, 266, 464,
+ 832, 243, 463, 243, 263, 265, 463, 244,
+ 218, 259, 242, 260, 258, 262, 258, 261,
+ 266, 464, 832, 243, 463, 243, 261, 263,
+ 265, 242, 244, 218, 259, 264, 260, 258,
+ 243, 258, 266, 465, 464, 832, 243, 242,
+ 243, 263, 265, 242, 244, 218, 259, 264,
+ 260, 258, 243, 258, 266, 466, 464, 832,
+ 243, 242, 243, 263, 265, 242, 244, 218,
+ 259, 467, 260, 258, 243, 258, 266, 464,
+ 832, 243, 242, 243, 263, 265, 467, 264,
+ 264, 243, 242, 469, 243, 467, 243, 468,
+ 264, 194, 141, 243, 242, 469, 243, 264,
+ 243, 468, 264, 194, 141, 243, 242, 469,
+ 243, 264, 243, 470, 470, 470, 468, 264,
+ 194, 141, 243, 242, 469, 471, 243, 264,
+ 243, 468, 264, 194, 141, 243, 242, 472,
+ 469, 243, 264, 243, 468, 264, 194, 141,
+ 243, 242, 473, 469, 243, 264, 243, 468,
+ 264, 194, 141, 243, 242, 474, 469, 243,
+ 264, 243, 468, 264, 194, 141, 243, 242,
+ 469, 475, 243, 264, 243, 468, 264, 194,
+ 141, 476, 242, 469, 243, 264, 243, 468,
+ 477, 194, 141, 243, 478, 194, 141, 243,
+ 194, 141, 479, 243, 480, 194, 141, 480,
+ 480, 243, 194, 141, 481, 243, 194, 141,
+ 468, 243, 194, 141, 483, 261, 266, 243,
+ 261, 263, 265, 194, 141, 834, 243, 194,
+ 141, 483, 243, 486, 194, 141, 243, 194,
+ 141, 487, 243, 194, 141, 834, 243, 242,
+ 489, 218, 259, 264, 260, 258, 243, 258,
+ 266, 464, 832, 243, 242, 243, 263, 265,
+ 194, 141, 487, 245, 245, 243, 242, 244,
+ 218, 259, 264, 260, 258, 491, 258, 266,
+ 464, 832, 243, 242, 243, 263, 265, 242,
+ 244, 218, 259, 264, 260, 258, 243, 258,
+ 832, 266, 464, 832, 243, 242, 243, 263,
+ 265, 242, 244, 218, 242, 259, 264, 260,
+ 258, 493, 258, 266, 464, 495, 832, 243,
+ 242, 243, 263, 265, 194, 141, 494, 243,
+ 242, 244, 218, 242, 259, 260, 258, 262,
+ 258, 261, 266, 464, 832, 243, 242, 243,
+ 261, 263, 265, 242, 244, 218, 259, 264,
+ 260, 258, 243, 258, 496, 266, 464, 832,
+ 243, 242, 243, 263, 265, 242, 244, 218,
+ 242, 259, 264, 260, 497, 493, 258, 266,
+ 464, 832, 243, 242, 243, 263, 265, 258,
+ 218, 259, 260, 262, 498, 261, 266, 464,
+ 243, 258, 243, 261, 263, 265, 242, 244,
+ 218, 242, 259, 264, 260, 258, 493, 258,
+ 266, 464, 835, 243, 242, 243, 263, 265,
+ 500, 264, 194, 141, 242, 264, 243, 501,
+ 264, 194, 141, 242, 264, 243, 264, 194,
+ 141, 242, 502, 264, 243, 503, 194, 141,
+ 503, 503, 243, 194, 141, 504, 243, 194,
+ 141, 265, 243, 242, 244, 218, 259, 264,
+ 260, 258, 243, 258, 266, 464, 495, 832,
+ 243, 242, 243, 263, 265, 258, 218, 259,
+ 260, 507, 508, 266, 464, 243, 258, 243,
+ 508, 263, 265, 257, 194, 141, 256, 508,
+ 266, 243, 257, 243, 508, 263, 265, 242,
+ 244, 218, 242, 259, 260, 507, 493, 508,
+ 266, 464, 832, 243, 242, 243, 258, 508,
+ 263, 265, 257, 510, 574, 506, 509, 257,
+ 590, 590, 590, 256, 511, 28, 173, 512,
+ 545, 174, 511, 174, 174, 187, 511, 28,
+ 173, 189, 511, 174, 189, 172, 69, 190,
+ 513, 514, 196, 517, 174, 189, 174, 514,
+ 193, 195, 188, 28, 187, 514, 196, 174,
+ 188, 174, 514, 193, 195, 173, 175, 172,
+ 173, 69, 190, 513, 515, 514, 196, 517,
+ 836, 174, 173, 174, 189, 514, 193, 195,
+ 28, 516, 174, 173, 175, 172, 173, 69,
+ 190, 189, 192, 189, 191, 196, 517, 836,
+ 174, 173, 174, 191, 193, 195, 173, 175,
+ 172, 69, 194, 190, 189, 174, 189, 196,
+ 518, 517, 836, 174, 173, 174, 193, 195,
+ 173, 175, 172, 69, 194, 190, 189, 174,
+ 189, 196, 519, 517, 836, 174, 173, 174,
+ 193, 195, 173, 175, 172, 69, 520, 190,
+ 189, 174, 189, 196, 517, 836, 174, 173,
+ 174, 193, 195, 520, 243, 194, 174, 173,
+ 522, 174, 520, 174, 521, 194, 174, 28,
+ 174, 173, 522, 174, 194, 174, 521, 194,
+ 174, 28, 174, 173, 522, 174, 194, 174,
+ 523, 523, 523, 521, 194, 174, 28, 174,
+ 173, 522, 524, 174, 194, 174, 521, 194,
+ 174, 28, 174, 173, 525, 522, 174, 194,
+ 174, 521, 194, 174, 28, 174, 173, 526,
+ 522, 174, 194, 174, 521, 194, 174, 28,
+ 174, 173, 527, 522, 174, 194, 174, 521,
+ 194, 174, 28, 174, 173, 522, 528, 174,
+ 194, 174, 521, 194, 174, 28, 529, 173,
+ 522, 174, 194, 174, 521, 530, 28, 174,
+ 531, 28, 174, 28, 532, 174, 533, 28,
+ 533, 533, 174, 28, 534, 174, 28, 521,
+ 174, 28, 536, 191, 196, 174, 191, 193,
+ 195, 28, 838, 174, 28, 536, 174, 539,
+ 28, 174, 28, 540, 174, 28, 838, 174,
+ 173, 542, 172, 69, 194, 190, 189, 174,
+ 189, 196, 517, 836, 174, 173, 174, 193,
+ 195, 28, 540, 176, 176, 174, 173, 175,
+ 172, 69, 194, 190, 189, 544, 189, 196,
+ 517, 836, 174, 173, 174, 193, 195, 173,
+ 175, 172, 69, 194, 190, 189, 174, 189,
+ 836, 196, 517, 836, 174, 173, 174, 193,
+ 195, 188, 546, 512, 545, 188, 562, 562,
+ 562, 187, 547, 7, 548, 549, 0, 547,
+ 0, 0, 3, 547, 7, 5, 547, 0,
+ 5, 6, 23, 24, 373, 374, 30, 377,
+ 0, 5, 0, 374, 27, 29, 4, 548,
+ 549, 4, 550, 550, 550, 3, 4, 548,
+ 549, 551, 0, 4, 0, 0, 3, 4,
+ 552, 548, 549, 0, 4, 0, 0, 3,
+ 4, 553, 548, 549, 0, 4, 0, 0,
+ 3, 554, 0, 555, 0, 556, 0, 557,
+ 0, 558, 0, 559, 0, 560, 560, 560,
+ 0, 561, 0, 3, 0, 188, 28, 512,
+ 545, 563, 174, 188, 174, 174, 187, 188,
+ 28, 564, 512, 545, 174, 188, 174, 174,
+ 187, 188, 28, 565, 512, 545, 174, 188,
+ 174, 174, 187, 28, 566, 174, 28, 567,
+ 174, 28, 568, 174, 569, 28, 174, 570,
+ 28, 174, 28, 571, 174, 572, 28, 572,
+ 572, 174, 28, 573, 174, 28, 187, 174,
+ 575, 28, 119, 576, 577, 120, 575, 120,
+ 120, 133, 575, 28, 119, 135, 575, 120,
+ 135, 136, 118, 137, 413, 414, 143, 417,
+ 120, 135, 120, 414, 140, 142, 134, 546,
+ 576, 577, 134, 578, 578, 578, 133, 134,
+ 28, 576, 577, 579, 120, 134, 120, 120,
+ 133, 134, 28, 580, 576, 577, 120, 134,
+ 120, 120, 133, 134, 28, 581, 576, 577,
+ 120, 134, 120, 120, 133, 28, 582, 120,
+ 28, 583, 120, 28, 584, 120, 585, 28,
+ 120, 586, 28, 120, 28, 587, 120, 588,
+ 28, 588, 588, 120, 28, 589, 120, 28,
+ 133, 120, 257, 194, 141, 506, 509, 591,
+ 243, 257, 243, 243, 256, 257, 194, 141,
+ 592, 506, 509, 243, 257, 243, 243, 256,
+ 257, 194, 141, 593, 506, 509, 243, 257,
+ 243, 243, 256, 194, 141, 594, 243, 194,
+ 141, 595, 243, 194, 141, 596, 243, 597,
+ 194, 141, 243, 598, 194, 141, 243, 194,
+ 141, 599, 243, 600, 194, 141, 600, 600,
+ 243, 194, 141, 601, 243, 194, 141, 256,
+ 243, 603, 194, 141, 506, 602, 509, 839,
+ 243, 603, 243, 243, 256, 603, 194, 141,
+ 255, 243, 506, 602, 509, 839, 243, 603,
+ 243, 256, 257, 194, 141, 605, 506, 509,
+ 243, 257, 243, 256, 257, 194, 141, 506,
+ 839, 509, 243, 257, 243, 243, 256, 257,
+ 486, 194, 141, 506, 509, 243, 257, 243,
+ 243, 256, 173, 136, 608, 215, 221, 172,
+ 215, 217, 197, 173, 136, 843, 172, 173,
+ 136, 608, 172, 611, 173, 136, 172, 173,
+ 136, 612, 172, 173, 136, 843, 172, 198,
+ 614, 198, 93, 218, 214, 213, 172, 213,
+ 221, 224, 841, 172, 198, 172, 217, 197,
+ 173, 136, 612, 200, 200, 172, 198, 199,
+ 198, 93, 218, 214, 213, 616, 213, 221,
+ 224, 841, 172, 198, 172, 217, 197, 198,
+ 199, 198, 93, 218, 214, 213, 172, 213,
+ 841, 221, 224, 841, 172, 198, 172, 217,
+ 197, 198, 199, 198, 198, 93, 218, 214,
+ 213, 219, 213, 221, 224, 618, 841, 172,
+ 198, 172, 217, 197, 198, 199, 198, 93,
+ 218, 214, 213, 172, 213, 619, 221, 224,
+ 841, 172, 198, 172, 217, 197, 198, 199,
+ 198, 198, 93, 218, 214, 620, 219, 213,
+ 221, 224, 841, 172, 198, 172, 217, 197,
+ 213, 198, 93, 214, 216, 621, 215, 221,
+ 224, 172, 213, 172, 215, 217, 197, 198,
+ 199, 198, 198, 93, 218, 214, 213, 219,
+ 213, 221, 224, 844, 172, 198, 172, 217,
+ 197, 623, 218, 173, 136, 198, 218, 172,
+ 624, 218, 173, 136, 198, 218, 172, 218,
+ 173, 136, 198, 625, 218, 172, 626, 173,
+ 136, 626, 626, 172, 173, 136, 627, 172,
+ 173, 136, 197, 172, 198, 199, 198, 93,
+ 218, 214, 213, 172, 213, 221, 224, 618,
+ 841, 172, 198, 172, 217, 197, 213, 198,
+ 93, 214, 630, 631, 221, 224, 172, 213,
+ 172, 631, 217, 197, 212, 173, 136, 211,
+ 631, 221, 172, 212, 172, 631, 217, 197,
+ 198, 199, 198, 198, 93, 214, 630, 219,
+ 631, 221, 224, 841, 172, 198, 172, 213,
+ 631, 217, 197, 212, 633, 634, 629, 632,
+ 212, 662, 662, 662, 211, 173, 175, 172,
+ 69, 190, 189, 513, 189, 514, 196, 517,
+ 836, 174, 173, 174, 514, 193, 195, 635,
+ 7, 32, 636, 649, 6, 635, 6, 6,
+ 45, 635, 7, 32, 47, 635, 6, 47,
+ 32, 48, 146, 637, 638, 152, 154, 6,
+ 47, 6, 638, 149, 31, 46, 7, 45,
+ 638, 152, 6, 46, 6, 638, 149, 31,
+ 32, 33, 32, 32, 48, 146, 637, 150,
+ 638, 152, 154, 845, 6, 32, 6, 47,
+ 638, 149, 31, 7, 640, 147, 152, 6,
+ 147, 149, 31, 7, 847, 6, 7, 640,
+ 6, 643, 7, 6, 7, 644, 6, 7,
+ 847, 6, 32, 646, 32, 48, 136, 146,
+ 47, 6, 47, 152, 154, 845, 6, 32,
+ 6, 149, 31, 7, 644, 34, 34, 6,
+ 32, 33, 32, 48, 136, 146, 47, 648,
+ 47, 152, 154, 845, 6, 32, 6, 149,
+ 31, 32, 33, 32, 48, 136, 146, 47,
+ 6, 47, 845, 152, 154, 845, 6, 32,
+ 6, 149, 31, 46, 372, 636, 649, 46,
+ 650, 650, 650, 45, 46, 7, 636, 649,
+ 651, 6, 46, 6, 6, 45, 46, 7,
+ 652, 636, 649, 6, 46, 6, 6, 45,
+ 46, 7, 653, 636, 649, 6, 46, 6,
+ 6, 45, 7, 654, 6, 7, 655, 6,
+ 7, 656, 6, 657, 7, 6, 658, 7,
+ 6, 7, 659, 6, 660, 7, 660, 660,
+ 6, 7, 661, 6, 7, 45, 6, 212,
+ 173, 136, 629, 632, 663, 172, 212, 172,
+ 172, 211, 212, 173, 136, 664, 629, 632,
+ 172, 212, 172, 172, 211, 212, 173, 136,
+ 665, 629, 632, 172, 212, 172, 172, 211,
+ 173, 136, 666, 172, 173, 136, 667, 172,
+ 173, 136, 668, 172, 669, 173, 136, 172,
+ 670, 173, 136, 172, 173, 136, 671, 172,
+ 672, 173, 136, 672, 672, 172, 173, 136,
+ 673, 172, 173, 136, 211, 172, 675, 173,
+ 136, 629, 674, 632, 848, 172, 675, 172,
+ 172, 211, 675, 173, 136, 210, 172, 629,
+ 674, 632, 848, 172, 675, 172, 211, 212,
+ 173, 136, 677, 629, 632, 172, 212, 172,
+ 211, 212, 173, 136, 629, 848, 632, 172,
+ 212, 172, 172, 211, 212, 611, 173, 136,
+ 629, 632, 172, 212, 172, 172, 211, 680,
+ 50, 48, 49, 69, 49, 65, 64, 23,
+ 64, 71, 343, 822, 23, 680, 23, 68,
+ 70, 680, 50, 48, 49, 49, 65, 64,
+ 67, 64, 66, 71, 343, 822, 23, 680,
+ 23, 66, 68, 70, 682, 175, 172, 69,
+ 194, 173, 190, 189, 174, 189, 196, 517,
+ 836, 174, 682, 174, 193, 195, 682, 175,
+ 172, 69, 173, 190, 189, 192, 189, 191,
+ 196, 517, 836, 174, 682, 174, 191, 193,
+ 195, 173, 175, 172, 173, 69, 194, 190,
+ 189, 515, 189, 196, 517, 684, 836, 174,
+ 173, 174, 193, 195, 173, 175, 172, 69,
+ 194, 190, 189, 174, 189, 685, 196, 517,
+ 836, 174, 173, 174, 193, 195, 173, 175,
+ 172, 173, 69, 194, 190, 686, 515, 189,
+ 196, 517, 836, 174, 173, 174, 193, 195,
+ 189, 172, 69, 190, 192, 687, 191, 196,
+ 517, 174, 189, 174, 191, 193, 195, 173,
+ 175, 172, 173, 69, 194, 190, 189, 515,
+ 189, 196, 517, 850, 174, 173, 174, 193,
+ 195, 689, 194, 28, 173, 194, 174, 690,
+ 194, 28, 173, 194, 174, 194, 28, 173,
+ 691, 194, 174, 692, 28, 692, 692, 174,
+ 28, 693, 174, 28, 195, 174, 173, 175,
+ 172, 69, 194, 190, 189, 174, 189, 196,
+ 517, 684, 836, 174, 173, 174, 193, 195,
+ 696, 28, 512, 695, 545, 851, 174, 696,
+ 174, 174, 187, 696, 28, 186, 174, 512,
+ 695, 545, 851, 174, 696, 174, 187, 188,
+ 28, 698, 512, 545, 174, 188, 174, 187,
+ 188, 28, 512, 851, 545, 174, 188, 174,
+ 174, 187, 188, 539, 28, 512, 545, 174,
+ 188, 174, 174, 187, 32, 33, 32, 48,
+ 136, 146, 47, 6, 47, 701, 152, 154,
+ 845, 6, 32, 6, 149, 31, 32, 33,
+ 32, 32, 48, 136, 146, 702, 150, 47,
+ 152, 154, 845, 6, 32, 6, 149, 31,
+ 47, 32, 48, 146, 148, 703, 147, 152,
+ 154, 6, 47, 6, 147, 149, 31, 32,
+ 33, 32, 32, 48, 136, 146, 47, 150,
+ 47, 152, 154, 853, 6, 32, 6, 149,
+ 31, 705, 136, 7, 32, 136, 6, 706,
+ 136, 7, 32, 136, 6, 136, 7, 32,
+ 707, 136, 6, 708, 7, 708, 708, 6,
+ 7, 709, 6, 7, 31, 6, 32, 33,
+ 32, 48, 136, 146, 47, 6, 47, 152,
+ 154, 700, 845, 6, 32, 6, 149, 31,
+ 712, 121, 136, 118, 141, 119, 137, 135,
+ 120, 135, 143, 417, 827, 120, 712, 120,
+ 140, 142, 712, 121, 136, 118, 119, 137,
+ 135, 139, 135, 138, 143, 417, 827, 120,
+ 712, 120, 138, 140, 142, 119, 121, 136,
+ 119, 118, 141, 137, 135, 415, 135, 143,
+ 417, 714, 827, 120, 119, 120, 140, 142,
+ 119, 121, 136, 118, 141, 137, 135, 120,
+ 135, 715, 143, 417, 827, 120, 119, 120,
+ 140, 142, 119, 121, 136, 119, 118, 141,
+ 137, 716, 415, 135, 143, 417, 827, 120,
+ 119, 120, 140, 142, 135, 136, 118, 137,
+ 139, 717, 138, 143, 417, 120, 135, 120,
+ 138, 140, 142, 119, 121, 136, 119, 118,
+ 141, 137, 135, 415, 135, 143, 417, 854,
+ 120, 119, 120, 140, 142, 719, 141, 28,
+ 119, 141, 120, 720, 141, 28, 119, 141,
+ 120, 141, 28, 119, 721, 141, 120, 722,
+ 28, 722, 722, 120, 28, 723, 120, 28,
+ 142, 120, 119, 121, 136, 118, 141, 137,
+ 135, 120, 135, 143, 417, 714, 827, 120,
+ 119, 120, 140, 142, 726, 28, 576, 725,
+ 577, 855, 120, 726, 120, 120, 133, 726,
+ 28, 132, 120, 576, 725, 577, 855, 120,
+ 726, 120, 133, 134, 28, 728, 576, 577,
+ 120, 134, 120, 133, 134, 28, 576, 855,
+ 577, 120, 134, 120, 120, 133, 134, 439,
+ 28, 576, 577, 120, 134, 120, 120, 133,
+ 49, 32, 731, 90, 96, 48, 90, 92,
+ 72, 49, 32, 859, 48, 49, 32, 731,
+ 48, 734, 49, 32, 48, 49, 32, 735,
+ 48, 49, 32, 859, 48, 73, 737, 73,
+ 73, 93, 89, 88, 48, 88, 96, 99,
+ 857, 48, 73, 48, 92, 72, 49, 32,
+ 735, 75, 75, 48, 73, 74, 73, 73,
+ 93, 89, 88, 739, 88, 96, 99, 857,
+ 48, 73, 48, 92, 72, 73, 74, 73,
+ 73, 93, 89, 88, 48, 88, 857, 96,
+ 99, 857, 48, 73, 48, 92, 72, 73,
+ 74, 73, 73, 73, 93, 89, 88, 94,
+ 88, 96, 99, 741, 857, 48, 73, 48,
+ 92, 72, 73, 74, 73, 73, 93, 89,
+ 88, 48, 88, 742, 96, 99, 857, 48,
+ 73, 48, 92, 72, 73, 74, 73, 73,
+ 73, 93, 89, 743, 94, 88, 96, 99,
+ 857, 48, 73, 48, 92, 72, 88, 73,
+ 73, 89, 91, 744, 90, 96, 99, 48,
+ 88, 48, 90, 92, 72, 73, 74, 73,
+ 73, 73, 93, 89, 88, 94, 88, 96,
+ 99, 860, 48, 73, 48, 92, 72, 746,
+ 93, 49, 32, 73, 93, 48, 747, 93,
+ 49, 32, 73, 93, 48, 93, 49, 32,
+ 73, 748, 93, 48, 749, 49, 32, 749,
+ 749, 48, 49, 32, 750, 48, 49, 32,
+ 72, 48, 73, 74, 73, 73, 93, 89,
+ 88, 48, 88, 96, 99, 741, 857, 48,
+ 73, 48, 92, 72, 88, 73, 73, 89,
+ 753, 754, 96, 99, 48, 88, 48, 754,
+ 92, 72, 87, 49, 32, 86, 754, 96,
+ 48, 87, 48, 754, 92, 72, 73, 74,
+ 73, 73, 73, 89, 753, 94, 754, 96,
+ 99, 857, 48, 73, 48, 88, 754, 92,
+ 72, 87, 756, 757, 752, 755, 87, 758,
+ 758, 758, 86, 49, 50, 48, 49, 65,
+ 64, 339, 64, 340, 71, 343, 822, 23,
+ 49, 23, 340, 68, 70, 32, 33, 32,
+ 48, 146, 47, 637, 47, 638, 152, 154,
+ 845, 6, 32, 6, 638, 149, 31, 87,
+ 49, 32, 752, 755, 759, 48, 87, 48,
+ 48, 86, 87, 49, 32, 760, 752, 755,
+ 48, 87, 48, 48, 86, 87, 49, 32,
+ 761, 752, 755, 48, 87, 48, 48, 86,
+ 49, 32, 762, 48, 49, 32, 763, 48,
+ 49, 32, 764, 48, 765, 49, 32, 48,
+ 766, 49, 32, 48, 49, 32, 767, 48,
+ 768, 49, 32, 768, 768, 48, 49, 32,
+ 769, 48, 49, 32, 86, 48, 771, 49,
+ 32, 752, 770, 755, 861, 48, 771, 48,
+ 48, 86, 771, 49, 32, 85, 48, 752,
+ 770, 755, 861, 48, 771, 48, 86, 87,
+ 49, 32, 773, 752, 755, 48, 87, 48,
+ 86, 87, 49, 32, 752, 861, 755, 48,
+ 87, 48, 48, 86, 87, 734, 49, 32,
+ 752, 755, 48, 87, 48, 48, 86, 49,
+ 50, 48, 49, 49, 69, 65, 64, 341,
+ 64, 71, 343, 776, 822, 23, 49, 23,
+ 68, 70, 49, 50, 48, 49, 69, 65,
+ 64, 23, 64, 777, 71, 343, 822, 23,
+ 49, 23, 68, 70, 49, 50, 48, 49,
+ 49, 69, 65, 778, 341, 64, 71, 343,
+ 822, 23, 49, 23, 68, 70, 64, 48,
+ 49, 65, 67, 779, 66, 71, 343, 23,
+ 64, 23, 66, 68, 70, 49, 50, 48,
+ 49, 49, 69, 65, 64, 341, 64, 71,
+ 343, 863, 23, 49, 23, 68, 70, 781,
+ 69, 7, 49, 69, 23, 782, 69, 7,
+ 49, 69, 23, 69, 7, 49, 783, 69,
+ 23, 784, 7, 784, 784, 23, 7, 785,
+ 23, 7, 70, 23, 49, 50, 48, 49,
+ 69, 65, 64, 23, 64, 71, 343, 776,
+ 822, 23, 49, 23, 68, 70, 788, 7,
+ 338, 787, 371, 864, 23, 788, 23, 23,
+ 62, 788, 7, 61, 23, 338, 787, 371,
+ 864, 23, 788, 23, 62, 63, 7, 790,
+ 338, 371, 23, 63, 23, 62, 63, 7,
+ 338, 864, 371, 23, 63, 23, 23, 62,
+ 63, 365, 7, 338, 371, 23, 63, 23,
+ 23, 62, 793, 7, 636, 792, 649, 866,
+ 6, 793, 6, 6, 45, 793, 7, 44,
+ 6, 636, 792, 649, 866, 6, 793, 6,
+ 45, 46, 7, 795, 636, 649, 6, 46,
+ 6, 45, 46, 7, 636, 866, 649, 6,
+ 46, 6, 6, 45, 46, 643, 7, 636,
+ 649, 6, 46, 6, 6, 45, 798, 8,
+ 6, 23, 28, 7, 24, 5, 0, 5,
+ 30, 377, 825, 0, 798, 0, 27, 29,
+ 798, 8, 6, 23, 7, 24, 5, 26,
+ 5, 25, 30, 377, 825, 0, 798, 0,
+ 25, 27, 29, 7, 8, 6, 7, 23,
+ 28, 24, 5, 375, 5, 30, 377, 800,
+ 825, 0, 7, 0, 27, 29, 7, 8,
+ 6, 23, 28, 24, 5, 0, 5, 801,
+ 30, 377, 825, 0, 7, 0, 27, 29,
+ 7, 8, 6, 7, 23, 28, 24, 802,
+ 375, 5, 30, 377, 825, 0, 7, 0,
+ 27, 29, 5, 6, 23, 24, 26, 803,
+ 25, 30, 377, 0, 5, 0, 25, 27,
+ 29, 7, 8, 6, 7, 23, 28, 24,
+ 5, 375, 5, 30, 377, 868, 0, 7,
+ 0, 27, 29, 805, 28, 7, 28, 0,
+ 806, 28, 7, 28, 0, 28, 7, 807,
+ 28, 0, 808, 808, 808, 0, 809, 0,
+ 29, 0, 7, 8, 6, 23, 28, 24,
+ 5, 0, 5, 30, 377, 800, 825, 0,
+ 7, 0, 27, 29, 812, 548, 811, 549,
+ 869, 0, 812, 0, 0, 3, 812, 2,
+ 0, 548, 811, 549, 869, 0, 812, 0,
+ 3, 4, 814, 548, 549, 0, 4, 0,
+ 3, 4, 548, 869, 549, 0, 4, 0,
+ 0, 3, 4, 21, 548, 549, 0, 4,
+ 0, 0, 3, 1, 0, 817, 18, 20,
+ 1, 817, 0, 819, 269, 93, 117, 259,
+ 284, 283, 319, 283, 317, 289, 293, 818,
+ 118, 819, 118, 287, 288, 819, 269, 93,
+ 117, 284, 283, 311, 283, 285, 317, 289,
+ 293, 818, 118, 819, 118, 285, 287, 288,
+ 820, 69, 119, 313, 314, 279, 820, 118,
+ 819, 269, 93, 117, 325, 284, 283, 319,
+ 283, 317, 289, 293, 818, 118, 819, 118,
+ 287, 288, 823, 50, 48, 49, 69, 65,
+ 64, 369, 64, 367, 71, 343, 822, 23,
+ 823, 23, 68, 70, 823, 50, 48, 49,
+ 65, 64, 361, 64, 66, 367, 71, 343,
+ 822, 23, 823, 23, 66, 68, 70, 824,
+ 7, 363, 364, 60, 824, 23, 826, 8,
+ 6, 23, 28, 24, 5, 398, 5, 396,
+ 30, 377, 825, 0, 826, 0, 27, 29,
+ 826, 8, 6, 23, 24, 5, 395, 5,
+ 25, 396, 30, 377, 825, 0, 826, 0,
+ 25, 27, 29, 828, 121, 136, 118, 141,
+ 137, 135, 443, 135, 441, 143, 417, 827,
+ 120, 828, 120, 140, 142, 828, 121, 136,
+ 118, 137, 135, 435, 135, 138, 441, 143,
+ 417, 827, 120, 828, 120, 138, 140, 142,
+ 829, 28, 437, 438, 131, 829, 120, 831,
+ 69, 119, 459, 332, 461, 335, 457, 118,
+ 831, 118, 281, 831, 69, 119, 313, 283,
+ 314, 279, 831, 118, 833, 244, 218, 259,
+ 264, 260, 258, 490, 258, 488, 266, 464,
+ 832, 243, 833, 243, 263, 265, 833, 244,
+ 218, 259, 260, 258, 482, 258, 261, 488,
+ 266, 464, 832, 243, 833, 243, 261, 263,
+ 265, 834, 194, 141, 484, 485, 254, 834,
+ 243, 833, 244, 218, 259, 499, 260, 258,
+ 490, 258, 488, 266, 464, 832, 243, 833,
+ 243, 263, 265, 837, 175, 172, 69, 194,
+ 190, 189, 543, 189, 541, 196, 517, 836,
+ 174, 837, 174, 193, 195, 837, 175, 172,
+ 69, 190, 189, 535, 189, 191, 541, 196,
+ 517, 836, 174, 837, 174, 191, 193, 195,
+ 838, 28, 537, 538, 185, 838, 174, 840,
+ 194, 141, 604, 506, 606, 509, 602, 243,
+ 840, 243, 256, 840, 194, 141, 484, 258,
+ 485, 254, 840, 243, 842, 199, 198, 93,
+ 218, 214, 213, 615, 213, 613, 221, 224,
+ 841, 172, 842, 172, 217, 197, 842, 199,
+ 198, 93, 214, 213, 607, 213, 215, 613,
+ 221, 224, 841, 172, 842, 172, 215, 217,
+ 197, 843, 173, 136, 609, 610, 209, 843,
+ 172, 842, 199, 198, 93, 622, 214, 213,
+ 615, 213, 613, 221, 224, 841, 172, 842,
+ 172, 217, 197, 846, 33, 32, 48, 136,
+ 146, 47, 647, 47, 645, 152, 154, 845,
+ 6, 846, 6, 149, 31, 846, 33, 32,
+ 48, 146, 47, 639, 47, 147, 645, 152,
+ 154, 845, 6, 846, 6, 147, 149, 31,
+ 847, 7, 641, 642, 43, 847, 6, 849,
+ 173, 136, 676, 629, 678, 632, 674, 172,
+ 849, 172, 211, 849, 173, 136, 609, 213,
+ 610, 209, 849, 172, 837, 175, 172, 69,
+ 688, 190, 189, 543, 189, 541, 196, 517,
+ 836, 174, 837, 174, 193, 195, 852, 28,
+ 697, 512, 699, 545, 695, 174, 852, 174,
+ 187, 852, 28, 537, 189, 538, 185, 852,
+ 174, 846, 33, 32, 48, 704, 146, 47,
+ 647, 47, 645, 152, 154, 845, 6, 846,
+ 6, 149, 31, 828, 121, 136, 118, 718,
+ 137, 135, 443, 135, 441, 143, 417, 827,
+ 120, 828, 120, 140, 142, 856, 28, 727,
+ 576, 729, 577, 725, 120, 856, 120, 133,
+ 856, 28, 437, 135, 438, 131, 856, 120,
+ 858, 74, 73, 73, 93, 89, 88, 738,
+ 88, 736, 96, 99, 857, 48, 858, 48,
+ 92, 72, 858, 74, 73, 73, 89, 88,
+ 730, 88, 90, 736, 96, 99, 857, 48,
+ 858, 48, 90, 92, 72, 859, 49, 32,
+ 732, 733, 84, 859, 48, 858, 74, 73,
+ 73, 745, 89, 88, 738, 88, 736, 96,
+ 99, 857, 48, 858, 48, 92, 72, 862,
+ 49, 32, 772, 752, 774, 755, 770, 48,
+ 862, 48, 86, 862, 49, 32, 732, 88,
+ 733, 84, 862, 48, 823, 50, 48, 49,
+ 780, 65, 64, 369, 64, 367, 71, 343,
+ 822, 23, 823, 23, 68, 70, 865, 7,
+ 789, 338, 791, 371, 787, 23, 865, 23,
+ 62, 865, 7, 363, 64, 364, 60, 865,
+ 23, 867, 7, 794, 636, 796, 649, 792,
+ 6, 867, 6, 45, 867, 7, 641, 47,
+ 642, 43, 867, 6, 826, 8, 6, 23,
+ 804, 24, 5, 398, 5, 396, 30, 377,
+ 825, 0, 826, 0, 27, 29, 870, 813,
+ 548, 815, 549, 811, 0, 870, 0, 3,
+ 870, 18, 5, 20, 1, 870, 0, 0
+};
+
+const int selector_start = 816;
+const int selector_first_final = 816;
+const int selector_error = 0;
+
+const int selector_en_main = 816;
+
+
+/* #line 58 "Parser.rl" */
+
+ #endregion
+ }
+}
diff --git a/Source/External/ExCSS/ParserX.cs b/Source/External/ExCSS/ParserX.cs
new file mode 100644
index 0000000000000000000000000000000000000000..91f57f0341c62648ee8d530d126c20f74e38ba4b
--- /dev/null
+++ b/Source/External/ExCSS/ParserX.cs
@@ -0,0 +1,1425 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ExCSS
+{
+ public sealed class CssParser
+ {
+ CssSelectorConstructor selector;
+ Stack function;
+ Boolean skipExceptions;
+ Lexer tokenizer;
+ Boolean fraction;
+ CSSProperty property;
+ CSSValue value;
+ List mvalues;
+ CSSValueList cvalues;
+ Boolean started;
+ Boolean quirks;
+ CSSStyleSheet sheet;
+ Stack open;
+ StringBuilder buffer;
+ CssState state;
+ Object sync;
+ Task task;
+
+ #region ctor
+
+
+ ///
+ /// Creates a new CSS parser instance parser with the specified stylesheet
+ /// based on the given source manager.
+ ///
+ /// The stylesheet to be constructed.
+ /// The source to use.
+ internal CssParser(StylesheetReader reader)
+ {
+ selector = Pool.NewSelectorConstructor();
+ sync = new Object();
+ skipExceptions = true;
+ tokenizer = new Lexer(reader);
+
+ started = false;
+ function = new Stack();
+ sheet = stylesheet;
+ open = new Stack();
+ SwitchTo(CssState.Data);
+ }
+
+ #endregion
+
+ #region Properties
+
+ ///
+ /// Gets if the parser has been started asynchronously.
+ ///
+ public Boolean IsAsync
+ {
+ get { return task != null; }
+ }
+
+ ///
+ /// Gets or sets if the quirks-mode is activated.
+ ///
+ public Boolean IsQuirksMode
+ {
+ get { return quirks; }
+ set { quirks = value; }
+ }
+
+ ///
+ /// Gets the current rule if any.
+ ///
+ internal CSSRule CurrentRule
+ {
+ get { return open.Count > 0 ? open.Peek() : null; }
+ }
+
+ #endregion
+
+ #region Methods
+
+ ///
+ /// Parses the given source asynchronously and creates the stylesheet.
+ ///
+ /// The task which could be awaited or continued differently.
+ public Task ParseAsync()
+ {
+ lock (sync)
+ {
+ if (!started)
+ {
+ started = true;
+ task = Task.Run(() => Kernel());
+ }
+ else if (task == null)
+ throw new InvalidOperationException("The parser has already run synchronously.");
+
+ return task;
+ }
+ }
+
+ ///
+ /// Parses the given source code.
+ ///
+ public void Parse()
+ {
+ var run = false;
+
+ lock (sync)
+ {
+ if (!started)
+ {
+ started = true;
+ run = true;
+ }
+ }
+
+ if (run)
+ {
+ Kernel();
+ }
+ }
+
+ #endregion
+
+ #region States
+
+ ///
+ /// The general state.
+ ///
+ /// The current token.
+ /// The status.
+ Boolean Data(CssToken token)
+ {
+ if (token.Type == CssTokenType.AtKeyword)
+ {
+ switch (((CssKeywordToken)token).Data)
+ {
+ case RuleNames.MEDIA:
+ {
+ AddRule(new CSSMediaRule());
+ SwitchTo(CssState.InMediaList);
+ break;
+ }
+ case RuleNames.PAGE:
+ {
+ AddRule(new CSSPageRule());
+ SwitchTo(CssState.InSelector);
+ break;
+ }
+ case RuleNames.IMPORT:
+ {
+ AddRule(new CSSImportRule());
+ SwitchTo(CssState.BeforeImport);
+ break;
+ }
+ case RuleNames.FONT_FACE:
+ {
+ AddRule(new CSSFontFaceRule());
+ SwitchTo(CssState.InDeclaration);
+ break;
+ }
+ case RuleNames.CHARSET:
+ {
+ AddRule(new CSSCharsetRule());
+ SwitchTo(CssState.BeforeCharset);
+ break;
+ }
+ case RuleNames.NAMESPACE:
+ {
+ AddRule(new CSSNamespaceRule());
+ SwitchTo(CssState.BeforeNamespacePrefix);
+ break;
+ }
+ case RuleNames.SUPPORTS:
+ {
+ buffer = Pool.NewStringBuilder();
+ AddRule(new CSSSupportsRule());
+ SwitchTo(CssState.InCondition);
+ break;
+ }
+ case RuleNames.KEYFRAMES:
+ {
+ AddRule(new CSSKeyframesRule());
+ SwitchTo(CssState.BeforeKeyframesName);
+ break;
+ }
+ case RuleNames.DOCUMENT:
+ {
+ AddRule(new CSSDocumentRule());
+ SwitchTo(CssState.BeforeDocumentFunction);
+ break;
+ }
+ default:
+ {
+ buffer = Pool.NewStringBuilder();
+ AddRule(new CSSUnknownRule());
+ SwitchTo(CssState.InUnknown);
+ InUnknown(token);
+ break;
+ }
+ }
+
+ return true;
+ }
+ else if (token.Type == CssTokenType.CurlyBracketClose)
+ {
+ return CloseRule();
+ }
+ else
+ {
+ AddRule(new CSSStyleRule());
+ SwitchTo(CssState.InSelector);
+ InSelector(token);
+ return true;
+ }
+ }
+
+ ///
+ /// State that is called once in the head of an unknown @ rule.
+ ///
+ /// The current token.
+ /// The status.
+ Boolean InUnknown(CssToken token)
+ {
+ switch (token.Type)
+ {
+ case CssTokenType.Semicolon:
+ CurrentRuleAs().SetInstruction(buffer.ToPool());
+ SwitchTo(CssState.Data);
+ return CloseRule();
+ case CssTokenType.CurlyBracketOpen:
+ CurrentRuleAs().SetCondition(buffer.ToPool());
+ SwitchTo(CssState.Data);
+ break;
+ default:
+ buffer.Append(token.ToValue());
+ break;
+ }
+
+ return true;
+ }
+
+ ///
+ /// State that is called once we are in a CSS selector.
+ ///
+ /// The current token.
+ /// The status.
+ Boolean InSelector(CssToken token)
+ {
+ if (token.Type == CssTokenType.CurlyBracketOpen)
+ {
+ var rule = CurrentRule as ICssSelector;
+
+ if (rule != null)
+ rule.Selector = selector.Result;
+
+ SwitchTo(CurrentRule is CSSStyleRule ? CssState.InDeclaration : CssState.Data);
+ }
+ else if (token.Type == CssTokenType.CurlyBracketClose)
+ return false;
+ else
+ selector.Apply(token);
+
+ return true;
+ }
+
+ ///
+ /// Called before the property name has been detected.
+ ///
+ /// The current token.
+ /// The status.
+ Boolean InDeclaration(CssToken token)
+ {
+ if (token.Type == CssTokenType.CurlyBracketClose)
+ {
+ CloseProperty();
+ SwitchTo(CurrentRule is CSSKeyframeRule ? CssState.KeyframesData : CssState.Data);
+ return CloseRule();
+ }
+ else if (token.Type == CssTokenType.Ident)
+ {
+ AddDeclaration(CSSProperty.Create(((CssKeywordToken)token).Data));
+ SwitchTo(CssState.AfterProperty);
+ return true;
+ }
+
+ return false;
+ }
+
+ ///
+ /// After instruction rules a semicolon is required.
+ ///
+ /// The current token.
+ /// The status.
+ Boolean AfterInstruction(CssToken token)
+ {
+ if (token.Type == CssTokenType.Semicolon)
+ {
+ SwitchTo(CssState.Data);
+ return CloseRule();
+ }
+
+ return false;
+ }
+
+ ///
+ /// In the condition text of a supports rule.
+ ///
+ /// The current token.
+ /// The status.
+ Boolean InCondition(CssToken token)
+ {
+ switch (token.Type)
+ {
+ case CssTokenType.CurlyBracketOpen:
+ CurrentRuleAs().ConditionText = buffer.ToPool();
+ SwitchTo(CssState.Data);
+ break;
+ default:
+ buffer.Append(token.ToValue());
+ break;
+ }
+
+ return true;
+ }
+
+ ///
+ /// Called before a prefix has been found for the namespace rule.
+ ///
+ /// The current token.
+ /// The status.
+ Boolean BeforePrefix(CssToken token)
+ {
+ if (token.Type == CssTokenType.Ident)
+ {
+ CurrentRuleAs().Prefix = ((CssKeywordToken)token).Data;
+ SwitchTo(CssState.AfterNamespacePrefix);
+ return true;
+ }
+
+ SwitchTo(CssState.AfterInstruction);
+ return AfterInstruction(token);
+ }
+
+ ///
+ /// Called before a namespace has been found for the namespace rule.
+ ///
+ /// The current token.
+ /// The status.
+ Boolean BeforeNamespace(CssToken token)
+ {
+ SwitchTo(CssState.AfterInstruction);
+
+ if (token.Type == CssTokenType.String)
+ {
+ CurrentRuleAs().NamespaceURI = ((CssStringToken)token).Data;
+ return true;
+ }
+
+ return AfterInstruction(token);
+ }
+
+ ///
+ /// Before a charset string has been found.
+ ///
+ /// The current token.
+ /// The status.
+ Boolean BeforeCharset(CssToken token)
+ {
+ SwitchTo(CssState.AfterInstruction);
+
+ if (token.Type == CssTokenType.String)
+ {
+ CurrentRuleAs().Encoding = ((CssStringToken)token).Data;
+ return true;
+ }
+
+ return AfterInstruction(token);
+ }
+
+ ///
+ /// Before an URL has been found for the import rule.
+ ///
+ /// The current token.
+ /// The status.
+ Boolean BeforeImport(CssToken token)
+ {
+ if (token.Type == CssTokenType.String || token.Type == CssTokenType.Url)
+ {
+ CurrentRuleAs().Href = ((CssStringToken)token).Data;
+ SwitchTo(CssState.InMediaList);
+ return true;
+ }
+
+ SwitchTo(CssState.AfterInstruction);
+ return false;
+ }
+
+ ///
+ /// Called before the property separating colon has been seen.
+ ///
+ /// The current token.
+ /// The status.
+ Boolean AfterProperty(CssToken token)
+ {
+ if (token.Type == CssTokenType.Colon)
+ {
+ fraction = false;
+ SwitchTo(CssState.BeforeValue);
+ return true;
+ }
+ else if (token.Type == CssTokenType.Semicolon || token.Type == CssTokenType.CurlyBracketClose)
+ AfterValue(token);
+
+ return false;
+ }
+
+ ///
+ /// Called before any token in the value regime had been seen.
+ ///
+ /// The current token.
+ /// The status.
+ Boolean BeforeValue(CssToken token)
+ {
+ if (token.Type == CssTokenType.Semicolon)
+ SwitchTo(CssState.InDeclaration);
+ else if (token.Type == CssTokenType.CurlyBracketClose)
+ InDeclaration(token);
+ else
+ {
+ SwitchTo(CssState.InSingleValue);
+ return InSingleValue(token);
+ }
+
+ return false;
+ }
+
+ ///
+ /// Called when a value has to be computed.
+ ///
+ /// The current token.
+ /// The status.
+ Boolean InSingleValue(CssToken token)
+ {
+ switch (token.Type)
+ {
+ case CssTokenType.Dimension: // e.g. "3px"
+ return AddValue(new CSSPrimitiveValue(((CssUnitToken)token).Unit, ((CssUnitToken)token).Data));
+ case CssTokenType.Hash:// e.g. "#ABCDEF"
+ return InSingleValueHexColor(((CssKeywordToken)token).Data);
+ case CssTokenType.Delim:// e.g. "#"
+ return InSingleValueDelim((CssDelimToken)token);
+ case CssTokenType.Ident: // e.g. "auto"
+ return InSingleValueIdent((CssKeywordToken)token);
+ case CssTokenType.String:// e.g. "'i am a string'"
+ return AddValue(new CSSPrimitiveValue(CssUnit.String, ((CssStringToken)token).Data));
+ case CssTokenType.Url:// e.g. "url('this is a valid URL')"
+ return AddValue(new CSSPrimitiveValue(CssUnit.Uri, ((CssStringToken)token).Data));
+ case CssTokenType.Percentage: // e.g. "5%"
+ return AddValue(new CSSPrimitiveValue(CssUnit.Percentage, ((CssUnitToken)token).Data));
+ case CssTokenType.Number: // e.g. "173"
+ return AddValue(new CSSPrimitiveValue(CssUnit.Number, ((CssNumberToken)token).Data));
+ case CssTokenType.Whitespace: // e.g. " "
+ SwitchTo(CssState.InValueList);
+ return true;
+ case CssTokenType.Function: //e.g. rgba(...)
+ function.Push(new FunctionBuffer(((CssKeywordToken)token).Data));
+ SwitchTo(CssState.InFunction);
+ return true;
+ case CssTokenType.Comma: // e.g. ","
+ SwitchTo(CssState.InValuePool);
+ return true;
+ case CssTokenType.Semicolon: // e.g. ";"
+ case CssTokenType.CurlyBracketClose: // e.g. "}"
+ return AfterValue(token);
+ default:
+ return false;
+ }
+ }
+
+ ///
+ /// Gathers a value inside a function.
+ ///
+ /// The current token.
+ /// The status.
+ Boolean InValueFunction(CssToken token)
+ {
+ switch (token.Type)
+ {
+ case CssTokenType.RoundBracketClose:
+ SwitchTo(CssState.InSingleValue);
+ return AddValue(function.Pop().Done());
+ case CssTokenType.Comma:
+ function.Peek().Include();
+ return true;
+ default:
+ return InSingleValue(token);
+ }
+ }
+
+ ///
+ /// Called when a new value is seen from the zero-POV (whitespace seen previously).
+ ///
+ /// The current token.
+ /// The status.
+ Boolean InValueList(CssToken token)
+ {
+ if (token.Type == CssTokenType.Semicolon || token.Type == CssTokenType.CurlyBracketClose)
+ AfterValue(token);
+ else if (token.Type == CssTokenType.Comma)
+ SwitchTo(CssState.InValuePool);
+ else
+ {
+ //TDO
+ SwitchTo(CssState.InSingleValue);
+ return InSingleValue(token);
+ }
+
+ return true;
+ }
+
+ ///
+ /// Called when a new value is seen from the zero-POV (comma seen previously).
+ ///
+ /// The current token.
+ /// The status.
+ Boolean InValuePool(CssToken token)
+ {
+ if (token.Type == CssTokenType.Semicolon || token.Type == CssTokenType.CurlyBracketClose)
+ AfterValue(token);
+ else
+ {
+ //TODO
+ SwitchTo(CssState.InSingleValue);
+ return InSingleValue(token);
+ }
+
+ return false;
+ }
+
+ ///
+ /// Called if a # sign has been found.
+ ///
+ /// The current token.
+ /// The status.
+ Boolean InHexValue(CssToken token)
+ {
+ switch (token.Type)
+ {
+ case CssTokenType.Number:
+ case CssTokenType.Dimension:
+ case CssTokenType.Ident:
+ var rest = token.ToValue();
+
+ if (buffer.Length + rest.Length <= 6)
+ {
+ buffer.Append(rest);
+ return true;
+ }
+
+ break;
+ }
+
+ var s = buffer.ToPool();
+ InSingleValueHexColor(buffer.ToString());
+ SwitchTo(CssState.InSingleValue);
+ return InSingleValue(token);
+ }
+
+ ///
+ /// Called after the value is known to be over.
+ ///
+ /// The current token.
+ /// The status.
+ Boolean AfterValue(CssToken token)
+ {
+ if (token.Type == CssTokenType.Semicolon)
+ {
+ CloseProperty();
+ SwitchTo(CssState.InDeclaration);
+ return true;
+ }
+ else if (token.Type == CssTokenType.CurlyBracketClose)
+ return InDeclaration(token);
+
+ return false;
+ }
+
+ ///
+ /// Called once an important instruction is expected.
+ ///
+ /// The current token.
+ /// The status.
+ Boolean ValueImportant(CssToken token)
+ {
+ if (token.Type == CssTokenType.Ident && ((CssKeywordToken)token).Data == "important")
+ {
+ SwitchTo(CssState.AfterValue);
+ property.Important = true;
+ return true;
+ }
+
+ return AfterValue(token);
+ }
+
+ ///
+ /// Before the name of an @keyframes rule has been detected.
+ ///
+ /// The current token.
+ /// The status.
+ Boolean BeforeKeyframesName(CssToken token)
+ {
+ SwitchTo(CssState.BeforeKeyframesData);
+
+ if (token.Type == CssTokenType.Ident)
+ {
+ CurrentRuleAs().Name = ((CssKeywordToken)token).Data;
+ return true;
+ }
+ else if (token.Type == CssTokenType.CurlyBracketOpen)
+ {
+ SwitchTo(CssState.KeyframesData);
+ }
+
+ return false;
+ }
+
+ ///
+ /// Before the curly bracket of an @keyframes rule has been seen.
+ ///
+ /// The current token.
+ /// The status.
+ Boolean BeforeKeyframesData(CssToken token)
+ {
+ if (token.Type == CssTokenType.CurlyBracketOpen)
+ {
+ SwitchTo(CssState.BeforeKeyframesData);
+ return true;
+ }
+
+ return false;
+ }
+
+ ///
+ /// Called in the @keyframes rule.
+ ///
+ /// The current token.
+ /// The status.
+ Boolean KeyframesData(CssToken token)
+ {
+ if (token.Type == CssTokenType.CurlyBracketClose)
+ {
+ SwitchTo(CssState.Data);
+ return CloseRule();
+ }
+ else
+ {
+ buffer = Pool.NewStringBuilder();
+ return InKeyframeText(token);
+ }
+ }
+
+ ///
+ /// Called in the text for a frame in the @keyframes rule.
+ ///
+ /// The current token.
+ /// The status.
+ Boolean InKeyframeText(CssToken token)
+ {
+ if (token.Type == CssTokenType.CurlyBracketOpen)
+ {
+ var frame = new CSSKeyframeRule();
+ frame.KeyText = buffer.ToPool();
+ AddRule(frame);
+ SwitchTo(CssState.InDeclaration);
+ return true;
+ }
+ else if (token.Type == CssTokenType.CurlyBracketClose)
+ {
+ buffer.ToPool();
+ KeyframesData(token);
+ return false;
+ }
+
+ buffer.Append(token.ToValue());
+ return true;
+ }
+
+ ///
+ /// Called before a document function has been found.
+ ///
+ /// The current token.
+ /// The status.
+ Boolean BeforeDocumentFunction(CssToken token)
+ {
+ switch (token.Type)
+ {
+ case CssTokenType.Url:
+ CurrentRuleAs().Conditions.Add(Tuple.Create(CSSDocumentRule.DocumentFunction.Url, ((CssStringToken)token).Data));
+ break;
+ case CssTokenType.UrlPrefix:
+ CurrentRuleAs().Conditions.Add(Tuple.Create(CSSDocumentRule.DocumentFunction.UrlPrefix, ((CssStringToken)token).Data));
+ break;
+ case CssTokenType.Domain:
+ CurrentRuleAs().Conditions.Add(Tuple.Create(CSSDocumentRule.DocumentFunction.Domain, ((CssStringToken)token).Data));
+ break;
+ case CssTokenType.Function:
+ if (String.Compare(((CssKeywordToken)token).Data, "regexp", StringComparison.OrdinalIgnoreCase) == 0)
+ {
+ SwitchTo(CssState.InDocumentFunction);
+ return true;
+ }
+ SwitchTo(CssState.AfterDocumentFunction);
+ return false;
+ default:
+ SwitchTo(CssState.Data);
+ return false;
+ }
+
+ SwitchTo(CssState.BetweenDocumentFunctions);
+ return true;
+ }
+
+ ///
+ /// Called before the argument of a document function has been found.
+ ///
+ /// The current token.
+ /// The status.
+ Boolean InDocumentFunction(CssToken token)
+ {
+ SwitchTo(CssState.AfterDocumentFunction);
+
+ if (token.Type == CssTokenType.String)
+ {
+ CurrentRuleAs().Conditions.Add(Tuple.Create(CSSDocumentRule.DocumentFunction.RegExp, ((CssStringToken)token).Data));
+ return true;
+ }
+
+ return false;
+ }
+
+ ///
+ /// Called after the arguments of a document function has been found.
+ ///
+ /// The current token.
+ /// The status.
+ Boolean AfterDocumentFunction(CssToken token)
+ {
+ SwitchTo(CssState.BetweenDocumentFunctions);
+ return token.Type == CssTokenType.RoundBracketClose;
+ }
+
+ ///
+ /// Called after a function has been completed.
+ ///
+ /// The current token.
+ /// The status.
+ Boolean BetweenDocumentFunctions(CssToken token)
+ {
+ if (token.Type == CssTokenType.Comma)
+ {
+ SwitchTo(CssState.BeforeDocumentFunction);
+ return true;
+ }
+ else if (token.Type == CssTokenType.CurlyBracketOpen)
+ {
+ SwitchTo(CssState.Data);
+ return true;
+ }
+
+ SwitchTo(CssState.Data);
+ return false;
+ }
+
+ ///
+ /// Before any medium has been found for the @media or @import rule.
+ ///
+ /// The current token.
+ /// The status.
+ Boolean InMediaList(CssToken token)
+ {
+ if (token.Type == CssTokenType.Semicolon)
+ {
+ CloseRule();
+ SwitchTo(CssState.Data);
+ return true;
+ }
+
+ buffer = Pool.NewStringBuilder();
+ SwitchTo(CssState.InMediaValue);
+ return InMediaValue(token);
+ }
+
+ ///
+ /// Scans the current medium for the @media or @import rule.
+ ///
+ /// The current token.
+ /// The status.
+ Boolean InMediaValue(CssToken token)
+ {
+ switch (token.Type)
+ {
+ case CssTokenType.CurlyBracketOpen:
+ case CssTokenType.Semicolon:
+ {
+ var container = CurrentRule as ICssMedia;
+ var s = buffer.ToPool();
+
+ if (container != null)
+ container.Media.AppendMedium(s);
+
+ if (CurrentRule is CSSImportRule)
+ return AfterInstruction(token);
+
+ SwitchTo(CssState.Data);
+ return token.Type == CssTokenType.CurlyBracketClose;
+ }
+ case CssTokenType.Comma:
+ {
+ var container = CurrentRule as ICssMedia;
+
+ if (container != null)
+ container.Media.AppendMedium(buffer.ToString());
+
+ buffer.Clear();
+ return true;
+ }
+ case CssTokenType.Whitespace:
+ {
+ buffer.Append(' ');
+ return true;
+ }
+ default:
+ {
+ buffer.Append(token.ToValue());
+ return true;
+ }
+ }
+ }
+
+ #endregion
+
+ #region Substates
+
+ ///
+ /// Called in a value - a delimiter has been found.
+ ///
+ /// The current delim token.
+ /// The status.
+ Boolean InSingleValueDelim(CssDelimToken token)
+ {
+ switch (token.Data)
+ {
+ case Specification.EM:
+ SwitchTo(CssState.ValueImportant);
+ return true;
+ case Specification.NUM:
+ buffer = Pool.NewStringBuilder();
+ SwitchTo(CssState.InHexValue);
+ return true;
+ case Specification.SOLIDUS:
+ fraction = true;
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ ///
+ /// Called in a value - an identifier has been found.
+ ///
+ /// The current keyword token.
+ /// The status.
+ Boolean InSingleValueIdent(CssKeywordToken token)
+ {
+ if (token.Data == "inherit")
+ {
+ property.Value = CSSValue.Inherit;
+ SwitchTo(CssState.AfterValue);
+ return true;
+ }
+
+ return AddValue(new CSSPrimitiveValue(CssUnit.Ident, token.Data));
+ }
+
+ ///
+ /// Called in a value - a hash (probably hex) value has been found.
+ ///
+ /// The value of the token.
+ /// The status.
+ Boolean InSingleValueHexColor(String color)
+ {
+ CSSColor value;
+
+ if (CSSColor.TryFromHex(color, out value))
+ return AddValue(new CSSPrimitiveValue(value));
+
+ return false;
+ }
+
+ #endregion
+
+ #region Rule management
+
+ ///
+ /// Adds the new value to the current value (or replaces it).
+ ///
+ /// The value to add.
+ /// The status.
+ Boolean AddValue(CSSValue value)
+ {
+ if (fraction)
+ {
+ if (this.value != null)
+ {
+ value = new CSSPrimitiveValue(CssUnit.Unknown, this.value.ToCss() + "/" + value.ToCss());
+ this.value = null;
+ }
+
+ fraction = false;
+ }
+
+ if (function.Count > 0)
+ function.Peek().Arguments.Add(value);
+ else if (this.value == null)
+ this.value = value;
+ else
+ return false;
+
+ return true;
+ }
+
+ ///
+ /// Closes a property.
+ ///
+ void CloseProperty()
+ {
+ if (property != null)
+ property.Value = value;
+
+ value = null;
+ property = null;
+ }
+
+ ///
+ /// Closes the current rule (if any).
+ ///
+ /// The status.
+ Boolean CloseRule()
+ {
+ if (open.Count > 0)
+ {
+ open.Pop();
+ return true;
+ }
+
+ return false;
+ }
+
+ ///
+ /// Adds a new rule.
+ ///
+ /// The new rule.
+ void AddRule(CSSRule rule)
+ {
+ rule.ParentStyleSheet = sheet;
+
+ if (open.Count > 0)
+ {
+ var container = open.Peek() as ICssRules;
+
+ if (container != null)
+ {
+ container.CssRules.List.Add(rule);
+ rule.ParentRule = open.Peek();
+ }
+ }
+ else
+ sheet.CssRules.List.Add(rule);
+
+ open.Push(rule);
+ }
+
+ ///
+ /// Adds a declaration.
+ ///
+ /// The new property.
+ void AddDeclaration(CSSProperty property)
+ {
+ this.property = property;
+ var rule = CurrentRule as IStyleDeclaration;
+
+ if (rule != null)
+ rule.Style.List.Add(property);
+ }
+
+ #endregion
+
+ #region Helpers
+
+ ///
+ /// Gets the current rule casted to the given type.
+ ///
+ T CurrentRuleAs()
+ where T : CSSRule
+ {
+ if (open.Count > 0)
+ return open.Peek() as T;
+
+ return default(T);
+ }
+
+ ///
+ /// Switches the current state to the given one.
+ ///
+ /// The state to switch to.
+ void SwitchTo(CssState newState)
+ {
+ switch (newState)
+ {
+ case CssState.InSelector:
+ tokenizer.IgnoreComments = true;
+ tokenizer.IgnoreWhitespace = false;
+ selector.Reset();
+ selector.IgnoreErrors = skipExceptions;
+ break;
+
+ case CssState.InHexValue:
+ case CssState.InUnknown:
+ case CssState.InCondition:
+ case CssState.InSingleValue:
+ case CssState.InMediaValue:
+ tokenizer.IgnoreComments = true;
+ tokenizer.IgnoreWhitespace = false;
+ break;
+
+ default:
+ tokenizer.IgnoreComments = true;
+ tokenizer.IgnoreWhitespace = true;
+ break;
+ }
+
+ state = newState;
+ }
+
+ ///
+ /// The kernel that is pulling the tokens into the parser.
+ ///
+ void Kernel()
+ {
+ var tokens = tokenizer.Tokens;
+
+ foreach (var token in tokens)
+ {
+ if (General(token) == false)
+ RaiseErrorOccurred(ErrorCode.InputUnexpected);
+ }
+
+ if (property != null)
+ General(CssSpecialCharacter.Semicolon);
+
+ selector.ToPool();
+ }
+
+ ///
+ /// Examines the token by using the current state.
+ ///
+ /// The current token.
+ /// The status.
+ Boolean General(CssToken token)
+ {
+ switch (state)
+ {
+ case CssState.Data:
+ return Data(token);
+ case CssState.InSelector:
+ return InSelector(token);
+ case CssState.InDeclaration:
+ return InDeclaration(token);
+ case CssState.AfterProperty:
+ return AfterProperty(token);
+ case CssState.BeforeValue:
+ return BeforeValue(token);
+ case CssState.InValuePool:
+ return InValuePool(token);
+ case CssState.InValueList:
+ return InValueList(token);
+ case CssState.InSingleValue:
+ return InSingleValue(token);
+ case CssState.ValueImportant:
+ return ValueImportant(token);
+ case CssState.AfterValue:
+ return AfterValue(token);
+ case CssState.InMediaList:
+ return InMediaList(token);
+ case CssState.InMediaValue:
+ return InMediaValue(token);
+ case CssState.BeforeImport:
+ return BeforeImport(token);
+ case CssState.AfterInstruction:
+ return AfterInstruction(token);
+ case CssState.BeforeCharset:
+ return BeforeCharset(token);
+ case CssState.BeforeNamespacePrefix:
+ return BeforePrefix(token);
+ case CssState.AfterNamespacePrefix:
+ return BeforeNamespace(token);
+ case CssState.InCondition:
+ return InCondition(token);
+ case CssState.InUnknown:
+ return InUnknown(token);
+ case CssState.InKeyframeText:
+ return InKeyframeText(token);
+ case CssState.BeforeDocumentFunction:
+ return BeforeDocumentFunction(token);
+ case CssState.InDocumentFunction:
+ return InDocumentFunction(token);
+ case CssState.AfterDocumentFunction:
+ return AfterDocumentFunction(token);
+ case CssState.BetweenDocumentFunctions:
+ return BetweenDocumentFunctions(token);
+ case CssState.BeforeKeyframesName:
+ return BeforeKeyframesName(token);
+ case CssState.BeforeKeyframesData:
+ return BeforeKeyframesData(token);
+ case CssState.KeyframesData:
+ return KeyframesData(token);
+ case CssState.InHexValue:
+ return InHexValue(token);
+ case CssState.InFunction:
+ return InValueFunction(token);
+ default:
+ return false;
+ }
+ }
+
+ #endregion
+
+ #region Public static methods
+
+ ///
+ /// Takes a string and transforms it into a selector object.
+ ///
+ /// The string to parse.
+ /// The Selector object.
+ public static Selector ParseSelector(String selector)
+ {
+ var tokenizer = new CssTokenizer(new SourceManager(selector));
+ var tokens = tokenizer.Tokens;
+ var selctor = Pool.NewSelectorConstructor();
+
+ foreach (var token in tokens)
+ selctor.Apply(token);
+
+ var result = selctor.Result;
+ selctor.ToPool();
+ return result;
+ }
+
+ ///
+ /// Takes a string and transforms it into a CSS stylesheet.
+ ///
+ /// The string to parse.
+ /// Optional: The status of the quirks mode flag (usually not set).
+ /// The CSSStyleSheet object.
+ public static CSSStyleSheet ParseStyleSheet(String stylesheet, Boolean quirksMode = false)
+ {
+ var parser = new CssParser(stylesheet);
+ parser.IsQuirksMode = quirksMode;
+ return parser.Result;
+ }
+
+ ///
+ /// Takes a string and transforms it into a CSS rule.
+ ///
+ /// The string to parse.
+ /// Optional: The status of the quirks mode flag (usually not set).
+ /// The CSSRule object.
+ public static CSSRule ParseRule(String rule, Boolean quirksMode = false)
+ {
+ var parser = new CssParser(rule);
+ parser.skipExceptions = false;
+ parser.IsQuirksMode = quirksMode;
+ parser.Parse();
+
+ if (parser.sheet.CssRules.Length > 0)
+ return parser.sheet.CssRules[0];
+
+ return null;
+ }
+
+ ///
+ /// Takes a string and transforms it into CSS declarations.
+ ///
+ /// The string to parse.
+ /// Optional: The status of the quirks mode flag (usually not set).
+ /// The CSSStyleDeclaration object.
+ public static CSSStyleDeclaration ParseDeclarations(String declarations, Boolean quirksMode = false)
+ {
+ var decl = new CSSStyleDeclaration();
+ AppendDeclarations(decl, declarations, quirksMode);
+ return decl;
+ }
+
+ ///
+ /// Takes a string and transforms it into a CSS declaration (CSS property).
+ ///
+ /// The string to parse.
+ /// Optional: The status of the quirks mode flag (usually not set).
+ /// The CSSProperty object.
+ public static CSSProperty ParseDeclaration(String declarations, Boolean quirksMode = false)
+ {
+ var parser = new CssParser(declarations);
+ parser.state = CssState.InDeclaration;
+ parser.IsQuirksMode = quirksMode;
+ parser.skipExceptions = false;
+ parser.Parse();
+ return parser.property;
+ }
+
+ ///
+ /// Takes a string and transforms it into a CSS value.
+ ///
+ /// The string to parse.
+ /// Optional: The status of the quirks mode flag (usually not set).
+ /// The CSSValue object.
+ public static CSSValue ParseValue(String source, Boolean quirksMode = false)
+ {
+ var parser = new CssParser(source);
+ var property = new CSSProperty(String.Empty);
+ parser.property = property;
+ parser.IsQuirksMode = quirksMode;
+ parser.skipExceptions = false;
+ parser.state = CssState.BeforeValue;
+ parser.Parse();
+ return property.Value;
+ }
+
+ #endregion
+
+ #region Internal static methods
+
+ ///
+ /// Takes a string and transforms it into a list of CSS values.
+ ///
+ /// The string to parse.
+ /// Optional: The status of the quirks mode flag (usually not set).
+ /// The CSSValueList object.
+ internal static CSSValueList ParseValueList(String source, Boolean quirksMode = false)
+ {
+ var parser = new CssParser(source);
+ var list = new CSSValueList();
+ var property = new CSSProperty(String.Empty);
+ property.Value = list;
+ parser.property = property;
+ parser.IsQuirksMode = quirksMode;
+ parser.skipExceptions = false;
+ parser.state = CssState.InValueList;
+ parser.Parse();
+ return list;
+ }
+
+ ///
+ /// Takes a comma separated string and transforms it into a list of CSS values.
+ ///
+ /// The string to parse.
+ /// Optional: The status of the quirks mode flag (usually not set).
+ /// The CSSValueList object.
+ internal static CSSValuePool ParseMultipleValues(String source, Boolean quirksMode = false)
+ {
+ var parser = new CssParser(source);
+ var pool = new CSSValuePool();
+ var property = new CSSProperty(String.Empty);
+ property.Value = pool;
+ parser.property = property;
+ parser.IsQuirksMode = quirksMode;
+ parser.skipExceptions = false;
+ parser.state = CssState.InValuePool;
+ parser.Parse();
+ return pool;
+ }
+
+ ///
+ /// Takes a string and transforms it into a CSS keyframe rule.
+ ///
+ /// The string to parse.
+ /// Optional: The status of the quirks mode flag (usually not set).
+ /// The CSSKeyframeRule object.
+ internal static CSSKeyframeRule ParseKeyframeRule(String rule, Boolean quirksMode = false)
+ {
+ var parser = new CssParser(rule);
+ var keyframe = new CSSKeyframeRule();
+ parser.AddRule(keyframe);
+ parser.IsQuirksMode = quirksMode;
+ parser.skipExceptions = false;
+ parser.state = CssState.InKeyframeText;
+ parser.Parse();
+ return keyframe;
+ }
+
+ ///
+ /// Takes a string and appends all rules to the given list of properties.
+ ///
+ /// The list of css properties to append to.
+ /// The string to parse.
+ /// Optional: The status of the quirks mode flag (usually not set).
+ internal static void AppendDeclarations(CSSStyleDeclaration list, String declarations, Boolean quirksMode = false)
+ {
+ var parser = new CssParser(declarations);
+ parser.IsQuirksMode = quirksMode;
+ parser.skipExceptions = false;
+
+ if (list.ParentRule != null)
+ parser.AddRule(list.ParentRule);
+ else
+ parser.AddRule(new CSSStyleRule(list));
+
+ parser.state = CssState.InDeclaration;
+ parser.Parse();
+ }
+
+ #endregion
+
+ #region State Enumeration
+
+ ///
+ /// The enumeration with possible state values.
+ ///
+ enum CssState
+ {
+ Data,
+ InSelector,
+ InDeclaration,
+ AfterProperty,
+ BeforeValue,
+ InValuePool,
+ InValueList,
+ InSingleValue,
+ InMediaList,
+ InMediaValue,
+ BeforeImport,
+ BeforeCharset,
+ BeforeNamespacePrefix,
+ AfterNamespacePrefix,
+ AfterInstruction,
+ InCondition,
+ BeforeKeyframesName,
+ BeforeKeyframesData,
+ KeyframesData,
+ InKeyframeText,
+ BeforeDocumentFunction,
+ InDocumentFunction,
+ AfterDocumentFunction,
+ BetweenDocumentFunctions,
+ InUnknown,
+ ValueImportant,
+ AfterValue,
+ InHexValue,
+ InFunction
+ }
+
+ ///
+ /// A buffer for functions.
+ ///
+ class FunctionBuffer
+ {
+ #region Members
+
+ String name;
+ List arguments;
+ CSSValue value;
+
+ #endregion
+
+ #region ctor
+
+ internal FunctionBuffer(String name)
+ {
+ this.arguments = new List();
+ this.name = name;
+ }
+
+ #endregion
+
+ #region Properties
+
+ public List Arguments
+ {
+ get { return arguments; }
+ }
+
+ public CSSValue Value
+ {
+ get { return value; }
+ set { this.value = value; }
+ }
+
+ #endregion
+
+ #region Methods
+
+ public void Include()
+ {
+ if (value != null)
+ arguments.Add(value);
+
+ value = null;
+ }
+
+ public CSSValue Done()
+ {
+ Include();
+ return CSSFunction.Create(name, arguments);
+ }
+
+ #endregion
+ }
+
+ #endregion
+ }
+}
diff --git a/Source/External/ExCSS/StyleSheet.cs b/Source/External/ExCSS/StyleSheet.cs
new file mode 100644
index 0000000000000000000000000000000000000000..6be25e459d6ec7034524e0d5ba2fe437b3a276ca
--- /dev/null
+++ b/Source/External/ExCSS/StyleSheet.cs
@@ -0,0 +1,146 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using ExCSS.Model.Extensions;
+
+// ReSharper disable once CheckNamespace
+namespace ExCSS
+{
+ public sealed class StyleSheet
+ {
+ private readonly List _rules;
+
+ public StyleSheet()
+ {
+ _rules = new List();
+ Errors = new List();
+ }
+
+ public List Rules
+ {
+ get { return _rules; }
+ }
+
+ public StyleSheet RemoveRule(int index)
+ {
+ if (index >= 0 && index < _rules.Count)
+ {
+ _rules.RemoveAt(index);
+ }
+
+ return this;
+ }
+
+ public StyleSheet InsertRule(string rule, int index)
+ {
+ if (index < 0 || index > _rules.Count)
+ {
+ return this;
+ }
+
+ var value = Parser.ParseRule(rule);
+ _rules.Insert(index, value);
+
+ return this;
+ }
+
+ public IList StyleRules
+ {
+ get
+ {
+ return Rules.Where(r => r is StyleRule).Cast().ToList();
+ }
+ }
+
+ public IList CharsetDirectives
+ {
+ get
+ {
+ return GetDirectives(RuleType.Charset);
+ }
+ }
+
+ public IList ImportDirectives
+ {
+ get
+ {
+ return GetDirectives(RuleType.Import);
+ }
+ }
+
+ public IList FontFaceDirectives
+ {
+ get
+ {
+ return GetDirectives(RuleType.FontFace);
+ }
+ }
+
+ public IList KeyframeDirectives
+ {
+ get
+ {
+ return GetDirectives(RuleType.Keyframes);
+ }
+ }
+
+ public IList MediaDirectives
+ {
+ get
+ {
+ return GetDirectives(RuleType.Media);
+
+ }
+ }
+
+ public IList PageDirectives
+ {
+ get
+ {
+ return GetDirectives(RuleType.Page);
+
+ }
+ }
+
+ public IList SupportsDirectives
+ {
+ get
+ {
+ return GetDirectives(RuleType.Supports);
+ }
+ }
+
+ public IList NamespaceDirectives
+ {
+ get
+ {
+ return GetDirectives(RuleType.Namespace);
+ }
+ }
+
+ private IList GetDirectives(RuleType ruleType)
+ {
+ return Rules.Where(r => r.RuleType == ruleType).Cast().ToList();
+ }
+
+ public List Errors { get; private set; }
+
+ public override string ToString()
+ {
+ return ToString(false);
+ }
+
+ public string ToString(bool friendlyFormat, int indentation = 0)
+ {
+ var builder = new StringBuilder();
+
+ foreach (var rule in _rules)
+ {
+ builder.Append(rule.ToString(friendlyFormat, indentation).TrimStart() + (friendlyFormat ? Environment.NewLine : ""));
+ }
+
+ return builder.TrimFirstLine().TrimLastLine().ToString();
+ }
+ }
+}
diff --git a/Source/External/ExCSS/StylesheetParseError.cs b/Source/External/ExCSS/StylesheetParseError.cs
new file mode 100644
index 0000000000000000000000000000000000000000..090629c5fda57c46545dad0943cfa5fec54dd90c
--- /dev/null
+++ b/Source/External/ExCSS/StylesheetParseError.cs
@@ -0,0 +1,27 @@
+
+namespace ExCSS
+{
+ public sealed class StylesheetParseError
+ {
+ public StylesheetParseError(ParserError error, string errorMessage, int line, int column)
+ {
+ ParserError = error;
+ Message = errorMessage;
+ Line = line;
+ Column = column;
+ }
+
+ public ParserError ParserError { get; set; }
+
+ public int Line{get;set;}
+
+ public int Column{get;set;}
+
+ public string Message{get;private set;}
+
+ public override string ToString()
+ {
+ return string.Format("Line {0}, Column {1}: {2}.", Line, Column, Message);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/External/ExCSS/StylesheetReader.cs b/Source/External/ExCSS/StylesheetReader.cs
new file mode 100644
index 0000000000000000000000000000000000000000..0446822b718849f66e883018711aa09198d95c35
--- /dev/null
+++ b/Source/External/ExCSS/StylesheetReader.cs
@@ -0,0 +1,186 @@
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using ExCSS.Model;
+
+namespace ExCSS
+{
+ internal class StylesheetReader
+ {
+ private int _insertion;
+ private readonly Stack _collengths;
+ private TextReader _reader;
+ private readonly StringBuilder _buffer;
+ private bool _lineWithReturn;
+
+ StylesheetReader()
+ {
+ _buffer = new StringBuilder();
+ _collengths = new Stack();
+ Column = 1;
+ Line = 1;
+ }
+
+ internal StylesheetReader(string styleText) : this()
+ {
+ _reader = new StringReader(styleText);
+ ReadCurrent();
+ }
+
+ internal StylesheetReader(Stream styleStream) : this()
+ {
+ _reader = new StreamReader(styleStream, true);
+ ReadCurrent();
+ }
+
+ internal bool IsBeginning
+ {
+ get { return _insertion < 2; }
+ }
+
+ internal int Line { get; private set; }
+
+ internal int Column { get; private set; }
+
+ internal bool IsEnded { get; private set; }
+
+ internal bool IsEnding
+ {
+ get { return Current == Specification.EndOfFile; }
+ }
+
+ internal char Current { get; private set; }
+
+ internal char Next
+ {
+ get
+ {
+ Advance();
+
+ return Current;
+ }
+ }
+
+ internal char Previous
+ {
+ get
+ {
+ Back();
+
+ return Current;
+ }
+ }
+
+ internal void Advance()
+ {
+ if (!IsEnding)
+ {
+ AdvanceUnsafe();
+ }
+ else if (!IsEnded)
+ {
+ IsEnded = true;
+ }
+ }
+
+ internal void Advance(int positions)
+ {
+ while (positions-- > 0 && !IsEnding)
+ {
+ AdvanceUnsafe();
+ }
+ }
+
+ internal void Back()
+ {
+ IsEnded = false;
+
+ if (!IsBeginning)
+ {
+ BackUnsafe();
+ }
+ }
+
+ internal void Back(int positions)
+ {
+ IsEnded = false;
+
+ while (positions-- > 0 && !IsBeginning)
+ {
+ BackUnsafe();
+ }
+ }
+
+ private void ReadCurrent()
+ {
+ if (_insertion < _buffer.Length)
+ {
+ Current = _buffer[_insertion];
+ _insertion++;
+ return;
+ }
+
+ var nextPosition = _reader.Read();
+ Current = nextPosition == -1 ? Specification.EndOfFile : (char)nextPosition;
+
+ if (Current == Specification.CarriageReturn)
+ {
+ Current = Specification.LineFeed;
+ _lineWithReturn = true;
+ }
+ else if (_lineWithReturn)
+ {
+ _lineWithReturn = false;
+
+ if (Current == Specification.LineFeed)
+ {
+ ReadCurrent();
+ return;
+ }
+ }
+
+ _buffer.Append(Current);
+ _insertion++;
+ }
+
+ private void AdvanceUnsafe()
+ {
+ if (Current.IsLineBreak())
+ {
+ _collengths.Push(Column);
+ Column = 1;
+ Line++;
+ }
+ else
+ {
+ Column++;
+ }
+
+ ReadCurrent();
+ }
+
+ private void BackUnsafe()
+ {
+ _insertion--;
+
+ if (_insertion == 0)
+ {
+ Column = 0;
+ Current = Specification.Null;
+ return;
+ }
+
+ Current = _buffer[_insertion - 1];
+
+ if (Current.IsLineBreak())
+ {
+ Column = _collengths.Count != 0 ? _collengths.Pop() : 1;
+ Line--;
+ }
+ else
+ {
+ Column--;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/External/Fizzler/Either.cs b/Source/External/Fizzler/Either.cs
new file mode 100644
index 0000000000000000000000000000000000000000..23725636ad3d48343690aab706d1892187c80df7
--- /dev/null
+++ b/Source/External/Fizzler/Either.cs
@@ -0,0 +1,136 @@
+//
+// Copyright (c) 2008 Novell, Inc. (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace Fizzler
+{
+ #region Imports
+
+ using System;
+ using System.Collections.Generic;
+
+ #endregion
+
+ // Adapted from Mono Rocks
+
+ internal abstract class Either
+ : IEquatable>
+ {
+ private Either() {}
+
+ public static Either A(TA value)
+ {
+ if (value == null) throw new ArgumentNullException("value");
+ return new AImpl(value);
+ }
+
+ public static Either B(TB value)
+ {
+ if (value == null) throw new ArgumentNullException("value");
+ return new BImpl(value);
+ }
+
+ public override abstract bool Equals(object obj);
+ public abstract bool Equals(Either obj);
+ public override abstract int GetHashCode();
+ public override abstract string ToString();
+ public abstract TResult Fold(Func a, Func b);
+
+ private sealed class AImpl : Either
+ {
+ private readonly TA _value;
+
+ public AImpl(TA value)
+ {
+ _value = value;
+ }
+
+ public override int GetHashCode()
+ {
+ return _value.GetHashCode();
+ }
+
+ public override bool Equals(object obj)
+ {
+ return Equals(obj as AImpl);
+ }
+
+ public override bool Equals(Either obj)
+ {
+ var a = obj as AImpl;
+ return a != null
+ && EqualityComparer.Default.Equals(_value, a._value);
+ }
+
+ public override TResult Fold(Func a, Func b)
+ {
+ if (a == null) throw new ArgumentNullException("a");
+ if (b == null) throw new ArgumentNullException("b");
+ return a(_value);
+ }
+
+ public override string ToString()
+ {
+ return _value.ToString();
+ }
+ }
+
+ private sealed class BImpl : Either
+ {
+ private readonly TB _value;
+
+ public BImpl(TB value)
+ {
+ _value = value;
+ }
+
+ public override int GetHashCode()
+ {
+ return _value.GetHashCode();
+ }
+
+ public override bool Equals(object obj)
+ {
+ return Equals(obj as BImpl);
+ }
+
+ public override bool Equals(Either obj)
+ {
+ var b = obj as BImpl;
+ return b != null
+ && EqualityComparer.Default.Equals(_value, b._value);
+ }
+
+ public override TResult Fold(Func a, Func b)
+ {
+ if (a == null) throw new ArgumentNullException("a");
+ if (b == null) throw new ArgumentNullException("b");
+ return b(_value);
+ }
+
+ public override string ToString()
+ {
+ return _value.ToString();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/External/Fizzler/HumanReadableSelectorGenerator.cs b/Source/External/Fizzler/HumanReadableSelectorGenerator.cs
new file mode 100644
index 0000000000000000000000000000000000000000..8070c0f79bf34a1dc2c3b7af51a5219f61e24cfc
--- /dev/null
+++ b/Source/External/Fizzler/HumanReadableSelectorGenerator.cs
@@ -0,0 +1,256 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace Fizzler
+{
+ using System;
+
+ ///
+ /// An implementation that generates
+ /// human-readable description of the selector.
+ ///
+ public class HumanReadableSelectorGenerator : ISelectorGenerator
+ {
+ private int _chainCount;
+
+ ///
+ /// Initializes the text.
+ ///
+ public virtual void OnInit()
+ {
+ Text = null;
+ }
+
+ ///
+ /// Gets the generated human-readable description text.
+ ///
+ public string Text { get; private set; }
+
+ ///
+ /// Generates human-readable for a selector in a group.
+ ///
+ public virtual void OnSelector()
+ {
+ if (string.IsNullOrEmpty(Text))
+ Text = "Take all";
+ else
+ Text += " and select them. Combined with previous, take all";
+ }
+
+ ///
+ /// Concludes the text.
+ ///
+ public virtual void OnClose()
+ {
+ Text = Text.Trim();
+ Text += " and select them.";
+ }
+
+ ///
+ /// Adds to the generated human-readable text.
+ ///
+ protected void Add(string selector)
+ {
+ if (selector == null) throw new ArgumentNullException("selector");
+ Text += selector;
+ }
+
+ ///
+ /// Generates human-readable text of this type selector.
+ ///
+ public void Type(NamespacePrefix prefix, string type)
+ {
+ Add(string.Format(" <{0}> elements", type));
+ }
+
+ ///
+ /// Generates human-readable text of this universal selector.
+ ///
+ public void Universal(NamespacePrefix prefix)
+ {
+ Add(" elements");
+ }
+
+ ///
+ /// Generates human-readable text of this ID selector.
+ ///
+ public void Id(string id)
+ {
+ Add(string.Format(" with an ID of '{0}'", id));
+ }
+
+ ///
+ /// Generates human-readable text of this class selector.
+ ///
+ void ISelectorGenerator.Class(string clazz)
+ {
+ Add(string.Format(" with a class of '{0}'", clazz));
+ }
+
+ ///
+ /// Generates human-readable text of this attribute selector.
+ ///
+ public void AttributeExists(NamespacePrefix prefix, string name)
+ {
+ Add(string.Format(" which have attribute {0} defined", name));
+ }
+
+ ///
+ /// Generates human-readable text of this attribute selector.
+ ///
+ public void AttributeExact(NamespacePrefix prefix, string name, string value)
+ {
+ Add(string.Format(" which have attribute {0} with a value of '{1}'", name, value));
+ }
+
+ ///
+ /// Generates human-readable text of this attribute selector.
+ ///
+ public void AttributeIncludes(NamespacePrefix prefix, string name, string value)
+ {
+ Add(string.Format(" which have attribute {0} that includes the word '{1}'", name, value));
+ }
+
+ ///
+ /// Generates human-readable text of this attribute selector.
+ ///
+ public void AttributeDashMatch(NamespacePrefix prefix, string name, string value)
+ {
+ Add(string.Format(" which have attribute {0} with a hyphen separated value matching '{1}'", name, value));
+ }
+
+ ///
+ /// Generates human-readable text of this attribute selector.
+ ///
+ public void AttributePrefixMatch(NamespacePrefix prefix, string name, string value)
+ {
+ Add(string.Format(" which have attribute {0} whose value begins with '{1}'", name, value));
+ }
+
+ ///
+ /// Generates human-readable text of this attribute selector.
+ ///
+ public void AttributeSuffixMatch(NamespacePrefix prefix, string name, string value)
+ {
+ Add(string.Format(" which have attribute {0} whose value ends with '{1}'", name, value));
+ }
+
+ ///
+ /// Generates human-readable text of this attribute selector.
+ ///
+ public void AttributeSubstring(NamespacePrefix prefix, string name, string value)
+ {
+ Add(string.Format(" which have attribute {0} whose value contains '{1}'", name, value));
+ }
+
+ ///
+ /// Generates human-readable text of this pseudo-class selector.
+ ///
+ public void FirstChild()
+ {
+ Add(" which are the first child of their parent");
+ }
+
+ ///
+ /// Generates human-readable text of this pseudo-class selector.
+ ///
+ public void LastChild()
+ {
+ Add(" which are the last child of their parent");
+ }
+
+ ///
+ /// Generates human-readable text of this pseudo-class selector.
+ ///
+ public void NthChild(int a, int b)
+ {
+ Add(string.Format(" where the element has {0}n+{1}-1 sibling before it", a, b));
+ }
+
+ ///
+ /// Generates human-readable text of this pseudo-class selector.
+ ///
+ public void OnlyChild()
+ {
+ Add(" where the element is the only child");
+ }
+
+ ///
+ /// Generates human-readable text of this pseudo-class selector.
+ ///
+ public void Empty()
+ {
+ Add(" where the element is empty");
+ }
+
+ ///
+ /// Generates human-readable text of this combinator.
+ ///
+ public void Child()
+ {
+ Add(", then take their immediate children which are");
+ }
+
+ ///
+ /// Generates human-readable text of this combinator.
+ ///
+ public void Descendant()
+ {
+ if (_chainCount > 0)
+ {
+ Add(". With those, take only their descendants which are");
+ }
+ else
+ {
+ Add(", then take their descendants which are");
+ _chainCount++;
+ }
+ }
+
+ ///
+ /// Generates human-readable text of this combinator.
+ ///
+ public void Adjacent()
+ {
+ Add(", then take their immediate siblings which are");
+ }
+
+ ///
+ /// Generates a combinator,
+ /// which separates two sequences of simple selectors. The elements represented
+ /// by the two sequences share the same parent in the document tree and the
+ /// element represented by the first sequence precedes (not necessarily
+ /// immediately) the element represented by the second one.
+ ///
+ public void GeneralSibling()
+ {
+ Add(", then take their siblings which are");
+ }
+
+ ///
+ /// Generates human-readable text of this combinator.
+ ///
+ public void NthLastChild(int a, int b)
+ {
+ Add(string.Format(" where the element has {0}n+{1}-1 sibling after it", a, b));
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/External/Fizzler/IElementOps.cs b/Source/External/Fizzler/IElementOps.cs
new file mode 100644
index 0000000000000000000000000000000000000000..e33fb48242cf376b6cf50f2698eefbebb968e64b
--- /dev/null
+++ b/Source/External/Fizzler/IElementOps.cs
@@ -0,0 +1,190 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace Fizzler
+{
+ ///
+ /// Represents a selectors implementation for an arbitrary document/node system.
+ ///
+ public interface IElementOps
+ {
+ //
+ // Selectors
+ //
+
+ ///
+ /// Generates a type selector,
+ /// which represents an instance of the element type in the document tree.
+ ///
+ Selector Type(NamespacePrefix prefix, string name);
+
+ ///
+ /// Generates a universal selector,
+ /// any single element in the document tree in any namespace
+ /// (including those without a namespace) if no default namespace
+ /// has been specified for selectors.
+ ///
+ Selector Universal(NamespacePrefix prefix);
+
+ ///
+ /// Generates a ID selector,
+ /// which represents an element instance that has an identifier that
+ /// matches the identifier in the ID selector.
+ ///
+ Selector Id(string id);
+
+ ///
+ /// Generates a class selector,
+ /// which is an alternative when
+ /// representing the class attribute.
+ ///
+ Selector Class(string clazz);
+
+ //
+ // Attribute selectors
+ //
+
+ ///
+ /// Generates an attribute selector
+ /// that represents an element with the given attribute
+ /// whatever the values of the attribute.
+ ///
+ Selector AttributeExists(NamespacePrefix prefix, string name);
+
+ ///
+ /// Generates an attribute selector
+ /// that represents an element with the given attribute
+ /// and whose value is exactly .
+ ///
+ Selector AttributeExact(NamespacePrefix prefix, string name, string value);
+
+ ///
+ /// Generates an attribute selector
+ /// that represents an element with the given attribute
+ /// and whose value is a whitespace-separated list of words, one of
+ /// which is exactly .
+ ///
+ Selector AttributeIncludes(NamespacePrefix prefix, string name, string value);
+
+ ///
+ /// Generates an attribute selector
+ /// that represents an element with the given attribute ,
+ /// its value either being exactly or beginning
+ /// with immediately followed by "-" (U+002D).
+ ///
+ Selector AttributeDashMatch(NamespacePrefix prefix, string name, string value);
+
+ ///
+ /// Generates an attribute selector
+ /// that represents an element with the attribute
+ /// whose value begins with the prefix .
+ ///
+ Selector AttributePrefixMatch(NamespacePrefix prefix, string name, string value);
+
+ ///
+ /// Generates an attribute selector
+ /// that represents an element with the attribute
+ /// whose value ends with the suffix .
+ ///
+ Selector AttributeSuffixMatch(NamespacePrefix prefix, string name, string value);
+
+ ///
+ /// Generates an attribute selector
+ /// that represents an element with the attribute
+ /// whose value contains at least one instance of the substring .
+ ///
+ Selector AttributeSubstring(NamespacePrefix prefix, string name, string value);
+
+ //
+ // Pseudo-class selectors
+ //
+
+ ///
+ /// Generates a pseudo-class selector,
+ /// which represents an element that is the first child of some other element.
+ ///
+ Selector FirstChild();
+
+ ///
+ /// Generates a pseudo-class selector,
+ /// which represents an element that is the last child of some other element.
+ ///
+ Selector LastChild();
+
+ ///
+ /// Generates a pseudo-class selector,
+ /// which represents an element that is the N-th child of some other element.
+ ///
+ Selector NthChild(int a, int b);
+
+ ///
+ /// Generates a pseudo-class selector,
+ /// which represents an element that has a parent element and whose parent
+ /// element has no other element children.
+ ///
+ Selector OnlyChild();
+
+ ///
+ /// Generates a pseudo-class selector,
+ /// which represents an element that has no children at all.
+ ///
+ Selector Empty();
+
+ //
+ // Combinators
+ //
+
+ ///
+ /// Generates a combinator,
+ /// which represents a childhood relationship between two elements.
+ ///
+ Selector Child();
+
+ ///
+ /// Generates a combinator,
+ /// which represents a relationship between two elements where one element is an
+ /// arbitrary descendant of some ancestor element.
+ ///
+ Selector Descendant();
+
+ ///
+ /// Generates a combinator,
+ /// which represents elements that share the same parent in the document tree and
+ /// where the first element immediately precedes the second element.
+ ///
+ Selector Adjacent();
+
+ ///
+ /// Generates a combinator,
+ /// which separates two sequences of simple selectors. The elements represented
+ /// by the two sequences share the same parent in the document tree and the
+ /// element represented by the first sequence precedes (not necessarily
+ /// immediately) the element represented by the second one.
+ ///
+ Selector GeneralSibling();
+
+ ///
+ /// Generates a pseudo-class selector,
+ /// which represents an element that is the N-th child from bottom up of some other element.
+ ///
+ Selector NthLastChild(int a, int b);
+ }
+}
\ No newline at end of file
diff --git a/Source/External/Fizzler/ISelectorGenerator.cs b/Source/External/Fizzler/ISelectorGenerator.cs
new file mode 100644
index 0000000000000000000000000000000000000000..6d1b18354bee24b8c84043e81ac65c8c7a93a9b7
--- /dev/null
+++ b/Source/External/Fizzler/ISelectorGenerator.cs
@@ -0,0 +1,206 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace Fizzler
+{
+ ///
+ /// Represent an implementation that is responsible for generating
+ /// an implementation for a selector.
+ ///
+ public interface ISelectorGenerator
+ {
+ ///
+ /// Delimits the initialization of a generation.
+ ///
+ void OnInit();
+
+ ///
+ /// Delimits the closing/conclusion of a generation.
+ ///
+ void OnClose();
+
+ ///
+ /// Delimits a selector generation in a group of selectors.
+ ///
+ void OnSelector();
+
+ //
+ // Selectors
+ //
+
+ ///
+ /// Generates a type selector,
+ /// which represents an instance of the element type in the document tree.
+ ///
+ void Type(NamespacePrefix prefix, string name);
+
+ ///
+ /// Generates a universal selector,
+ /// any single element in the document tree in any namespace
+ /// (including those without a namespace) if no default namespace
+ /// has been specified for selectors.
+ ///
+ void Universal(NamespacePrefix prefix);
+
+ ///
+ /// Generates a ID selector,
+ /// which represents an element instance that has an identifier that
+ /// matches the identifier in the ID selector.
+ ///
+ void Id(string id);
+
+ ///
+ /// Generates a class selector,
+ /// which is an alternative when
+ /// representing the class attribute.
+ ///
+ void Class(string clazz);
+
+ //
+ // Attribute selectors
+ //
+
+ ///
+ /// Generates an attribute selector
+ /// that represents an element with the given attribute
+ /// whatever the values of the attribute.
+ ///
+ void AttributeExists(NamespacePrefix prefix, string name);
+
+ ///
+ /// Generates an attribute selector
+ /// that represents an element with the given attribute
+ /// and whose value is exactly .
+ ///
+ void AttributeExact(NamespacePrefix prefix, string name, string value);
+
+ ///
+ /// Generates an attribute selector
+ /// that represents an element with the given attribute
+ /// and whose value is a whitespace-separated list of words, one of
+ /// which is exactly .
+ ///
+ void AttributeIncludes(NamespacePrefix prefix, string name, string value);
+
+ ///
+ /// Generates an attribute selector
+ /// that represents an element with the given attribute ,
+ /// its value either being exactly or beginning
+ /// with immediately followed by "-" (U+002D).
+ ///
+ void AttributeDashMatch(NamespacePrefix prefix, string name, string value);
+
+ ///
+ /// Generates an attribute selector
+ /// that represents an element with the attribute
+ /// whose value begins with the prefix .
+ ///
+ void AttributePrefixMatch(NamespacePrefix prefix, string name, string value);
+
+ ///
+ /// Generates an attribute selector
+ /// that represents an element with the attribute
+ /// whose value ends with the suffix .
+ ///
+ void AttributeSuffixMatch(NamespacePrefix prefix, string name, string value);
+
+ ///
+ /// Generates an attribute selector
+ /// that represents an element with the attribute
+ /// whose value contains at least one instance of the substring .
+ ///
+ void AttributeSubstring(NamespacePrefix prefix, string name, string value);
+
+ //
+ // Pseudo-class selectors
+ //
+
+ ///
+ /// Generates a pseudo-class selector,
+ /// which represents an element that is the first child of some other element.
+ ///
+ void FirstChild();
+
+ ///
+ /// Generates a pseudo-class selector,
+ /// which represents an element that is the last child of some other element.
+ ///
+ void LastChild();
+
+ ///
+ /// Generates a pseudo-class selector,
+ /// which represents an element that is the N-th child of some other element.
+ ///
+ void NthChild(int a, int b);
+
+ ///
+ /// Generates a pseudo-class selector,
+ /// which represents an element that has a parent element and whose parent
+ /// element has no other element children.
+ ///
+ void OnlyChild();
+
+ ///
+ /// Generates a pseudo-class selector,
+ /// which represents an element that has no children at all.
+ ///
+ void Empty();
+
+ //
+ // Combinators
+ //
+
+ ///
+ /// Generates a combinator,
+ /// which represents a childhood relationship between two elements.
+ ///
+ void Child();
+
+ ///
+ /// Generates a combinator,
+ /// which represents a relationship between two elements where one element is an
+ /// arbitrary descendant of some ancestor element.
+ ///
+ void Descendant();
+
+ ///
+ /// Generates a combinator,
+ /// which represents elements that share the same parent in the document tree and
+ /// where the first element immediately precedes the second element.
+ ///
+ void Adjacent();
+
+ ///
+ /// Generates a combinator,
+ /// which separates two sequences of simple selectors. The elements represented
+ /// by the two sequences share the same parent in the document tree and the
+ /// element represented by the first sequence precedes (not necessarily
+ /// immediately) the element represented by the second one.
+ ///
+ void GeneralSibling();
+
+ ///
+ /// Generates a pseudo-class selector,
+ /// which represents an element that is the N-th child from bottom up of some other element.
+ ///
+ void NthLastChild(int a, int b);
+ }
+}
\ No newline at end of file
diff --git a/Source/External/Fizzler/NamespacePrefix.cs b/Source/External/Fizzler/NamespacePrefix.cs
new file mode 100644
index 0000000000000000000000000000000000000000..7843d3076c0a04de9a96eba2a0aa33d85d139436
--- /dev/null
+++ b/Source/External/Fizzler/NamespacePrefix.cs
@@ -0,0 +1,135 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace Fizzler
+{
+ using System;
+
+ ///
+ /// Represent a type or attribute name.
+ ///
+ [Serializable]
+ public struct NamespacePrefix
+ {
+ ///
+ /// Represents a name from either the default or any namespace
+ /// in a target document, depending on whether a default namespace is
+ /// in effect or not.
+ ///
+ public static readonly NamespacePrefix None = new NamespacePrefix(null);
+
+ ///
+ /// Represents an empty namespace.
+ ///
+ public static readonly NamespacePrefix Empty = new NamespacePrefix(string.Empty);
+
+ ///
+ /// Represents any namespace.
+ ///
+ public static readonly NamespacePrefix Any = new NamespacePrefix("*");
+
+ ///
+ /// Initializes an instance with a namespace prefix specification.
+ ///
+ public NamespacePrefix(string text) : this()
+ {
+ Text = text;
+ }
+
+ ///
+ /// Gets the raw text value of this instance.
+ ///
+ public string Text { get; private set; }
+
+ ///
+ /// Indicates whether this instance represents a name
+ /// from either the default or any namespace in a target
+ /// document, depending on whether a default namespace is
+ /// in effect or not.
+ ///
+ public bool IsNone { get { return Text == null; } }
+
+ ///
+ /// Indicates whether this instance represents a name
+ /// from any namespace (including one without one)
+ /// in a target document.
+ ///
+ public bool IsAny
+ {
+ get { return !IsNone && Text.Length == 1 && Text[0] == '*'; }
+ }
+
+ ///
+ /// Indicates whether this instance represents a name
+ /// without a namespace in a target document.
+ ///
+ public bool IsEmpty { get { return !IsNone && Text.Length == 0; } }
+
+ ///
+ /// Indicates whether this instance represents a name from a
+ /// specific namespace or not.
+ ///
+ public bool IsSpecific { get {return !IsNone && !IsAny; } }
+
+ ///
+ /// Indicates whether this instance and a specified object are equal.
+ ///
+ public override bool Equals(object obj)
+ {
+ return obj is NamespacePrefix && Equals((NamespacePrefix) obj);
+ }
+
+ ///
+ /// Indicates whether this instance and another are equal.
+ ///
+ public bool Equals(NamespacePrefix other)
+ {
+ return Text == other.Text;
+ }
+
+ ///
+ /// Returns the hash code for this instance.
+ ///
+ public override int GetHashCode()
+ {
+ return IsNone ? 0 : Text.GetHashCode();
+ }
+
+ ///
+ /// Returns a string representation of this instance.
+ ///
+ public override string ToString()
+ {
+ return IsNone ? "(none)" : Text;
+ }
+
+ ///
+ /// Formats this namespace together with a name.
+ ///
+ public string Format(string name)
+ {
+ if (name == null) throw new ArgumentNullException("name");
+ if (name.Length == 0) throw new ArgumentException(null, "name");
+
+ return Text + (IsNone ? null : "|") + name;
+ }
+ }
+}
diff --git a/Source/External/Fizzler/Parser.cs b/Source/External/Fizzler/Parser.cs
new file mode 100644
index 0000000000000000000000000000000000000000..3af3ed55612d547dc5dbbd22184a21a3e8fe8fe7
--- /dev/null
+++ b/Source/External/Fizzler/Parser.cs
@@ -0,0 +1,483 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace Fizzler
+{
+ #region Imports
+
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics;
+ using System.Globalization;
+ using System.Linq;
+
+ using TokenSpec = Either;
+
+ #endregion
+
+ ///
+ /// Semantic parser for CSS selector grammar.
+ ///
+ public sealed class Parser
+ {
+ private readonly Reader _reader;
+ private readonly ISelectorGenerator _generator;
+
+ private Parser(Reader reader, ISelectorGenerator generator)
+ {
+ Debug.Assert(reader != null);
+ Debug.Assert(generator != null);
+ _reader = reader;
+ _generator = generator;
+ }
+
+ ///
+ /// Parses a CSS selector group and generates its implementation.
+ ///
+ public static TGenerator Parse(string selectors, TGenerator generator)
+ where TGenerator : ISelectorGenerator
+ {
+ return Parse(selectors, generator, g => g);
+ }
+
+ ///
+ /// Parses a CSS selector group and generates its implementation.
+ ///
+ public static T Parse(string selectors, TGenerator generator, Func resultor)
+ where TGenerator : ISelectorGenerator
+ {
+ if (selectors == null) throw new ArgumentNullException("selectors");
+ if (selectors.Length == 0) throw new ArgumentException(null, "selectors");
+
+ return Parse(Tokener.Tokenize(selectors), generator, resultor);
+ }
+
+ ///
+ /// Parses a tokenized stream representing a CSS selector group and
+ /// generates its implementation.
+ ///
+ public static TGenerator Parse(IEnumerable tokens, TGenerator generator)
+ where TGenerator : ISelectorGenerator
+ {
+ return Parse(tokens, generator, g => g);
+ }
+
+ ///
+ /// Parses a tokenized stream representing a CSS selector group and
+ /// generates its implementation.
+ ///
+ public static T Parse(IEnumerable tokens, TGenerator generator, Func resultor)
+ where TGenerator : ISelectorGenerator
+ {
+ if (tokens == null) throw new ArgumentNullException("tokens");
+ if (resultor == null) throw new ArgumentNullException("resultor");
+
+ new Parser(new Reader(tokens.GetEnumerator()), generator).Parse();
+ return resultor(generator);
+ }
+
+ private void Parse()
+ {
+ _generator.OnInit();
+ SelectorGroup();
+ _generator.OnClose();
+ }
+
+ private void SelectorGroup()
+ {
+ //selectors_group
+ // : selector [ COMMA S* selector ]*
+ // ;
+
+ Selector();
+ while (TryRead(ToTokenSpec(Token.Comma())) != null)
+ {
+ TryRead(ToTokenSpec(TokenKind.WhiteSpace));
+ Selector();
+ }
+
+ Read(ToTokenSpec(TokenKind.Eoi));
+ }
+
+ private void Selector()
+ {
+ _generator.OnSelector();
+
+ //selector
+ // : simple_selector_sequence [ combinator simple_selector_sequence ]*
+ // ;
+
+ SimpleSelectorSequence();
+ while (TryCombinator())
+ SimpleSelectorSequence();
+ }
+
+ private bool TryCombinator()
+ {
+ //combinator
+ // /* combinators can be surrounded by whitespace */
+ // : PLUS S* | GREATER S* | TILDE S* | S+
+ // ;
+
+ var token = TryRead(ToTokenSpec(TokenKind.Plus), ToTokenSpec(TokenKind.Greater), ToTokenSpec(TokenKind.Tilde), ToTokenSpec(TokenKind.WhiteSpace));
+
+ if (token == null)
+ return false;
+
+ if (token.Value.Kind == TokenKind.WhiteSpace)
+ {
+ _generator.Descendant();
+ }
+ else
+ {
+ switch (token.Value.Kind)
+ {
+ case TokenKind.Tilde: _generator.GeneralSibling(); break;
+ case TokenKind.Greater: _generator.Child(); break;
+ case TokenKind.Plus: _generator.Adjacent(); break;
+ }
+
+ TryRead(ToTokenSpec(TokenKind.WhiteSpace));
+ }
+
+ return true;
+ }
+
+ private void SimpleSelectorSequence()
+ {
+ //simple_selector_sequence
+ // : [ type_selector | universal ]
+ // [ HASH | class | attrib | pseudo | negation ]*
+ // | [ HASH | class | attrib | pseudo | negation ]+
+ // ;
+
+ var named = false;
+ for (var modifiers = 0; ; modifiers++)
+ {
+ var token = TryRead(ToTokenSpec(TokenKind.Hash), ToTokenSpec(Token.Dot()), ToTokenSpec(Token.LeftBracket()), ToTokenSpec(Token.Colon()));
+
+ if (token == null)
+ {
+ if (named || modifiers > 0)
+ break;
+ TypeSelectorOrUniversal();
+ named = true;
+ }
+ else
+ {
+ if (modifiers == 0 && !named)
+ _generator.Universal(NamespacePrefix.None); // implied
+
+ if (token.Value.Kind == TokenKind.Hash)
+ {
+ _generator.Id(token.Value.Text);
+ }
+ else
+ {
+ Unread(token.Value);
+ switch (token.Value.Text[0])
+ {
+ case '.': Class(); break;
+ case '[': Attrib(); break;
+ case ':': Pseudo(); break;
+ default: throw new Exception("Internal error.");
+ }
+ }
+ }
+ }
+ }
+
+ private void Pseudo()
+ {
+ //pseudo
+ // /* '::' starts a pseudo-element, ':' a pseudo-class */
+ // /* Exceptions: :first-line, :first-letter, :before and :after. */
+ // /* Note that pseudo-elements are restricted to one per selector and */
+ // /* occur only in the last simple_selector_sequence. */
+ // : ':' ':'? [ IDENT | functional_pseudo ]
+ // ;
+
+ PseudoClass(); // We do pseudo-class only for now
+ }
+
+ private void PseudoClass()
+ {
+ //pseudo
+ // : ':' [ IDENT | functional_pseudo ]
+ // ;
+
+ Read(ToTokenSpec(Token.Colon()));
+ if (!TryFunctionalPseudo())
+ {
+ var clazz = Read(ToTokenSpec(TokenKind.Ident)).Text;
+ switch (clazz)
+ {
+ case "first-child": _generator.FirstChild(); break;
+ case "last-child": _generator.LastChild(); break;
+ case "only-child": _generator.OnlyChild(); break;
+ case "empty": _generator.Empty(); break;
+ default:
+ {
+ throw new FormatException(string.Format(
+ "Unknown pseudo-class '{0}'. Use either first-child, last-child, only-child or empty.", clazz));
+ }
+ }
+ }
+ }
+
+ private bool TryFunctionalPseudo()
+ {
+ //functional_pseudo
+ // : FUNCTION S* expression ')'
+ // ;
+
+ var token = TryRead(ToTokenSpec(TokenKind.Function));
+ if (token == null)
+ return false;
+
+ TryRead(ToTokenSpec(TokenKind.WhiteSpace));
+
+ var func = token.Value.Text;
+ switch (func)
+ {
+ case "nth-child": Nth(); break;
+ case "nth-last-child": NthLast(); break;
+ default:
+ {
+ throw new FormatException(string.Format(
+ "Unknown functional pseudo '{0}'. Only nth-child and nth-last-child are supported.", func));
+ }
+ }
+
+ Read(ToTokenSpec(Token.RightParenthesis()));
+ return true;
+ }
+
+ private void Nth()
+ {
+ //nth
+ // : S* [ ['-'|'+']? INTEGER? {N} [ S* ['-'|'+'] S* INTEGER ]? |
+ // ['-'|'+']? INTEGER | {O}{D}{D} | {E}{V}{E}{N} ] S*
+ // ;
+
+ // TODO Add support for the full syntax
+ // At present, only INTEGER is allowed
+
+ _generator.NthChild(1, NthB());
+ }
+
+ private void NthLast()
+ {
+ //nth
+ // : S* [ ['-'|'+']? INTEGER? {N} [ S* ['-'|'+'] S* INTEGER ]? |
+ // ['-'|'+']? INTEGER | {O}{D}{D} | {E}{V}{E}{N} ] S*
+ // ;
+
+ // TODO Add support for the full syntax
+ // At present, only INTEGER is allowed
+
+ _generator.NthLastChild(1, NthB());
+ }
+
+ private int NthB()
+ {
+ return int.Parse(Read(ToTokenSpec(TokenKind.Integer)).Text, CultureInfo.InvariantCulture);
+ }
+
+ private void Attrib()
+ {
+ //attrib
+ // : '[' S* [ namespace_prefix ]? IDENT S*
+ // [ [ PREFIXMATCH |
+ // SUFFIXMATCH |
+ // SUBSTRINGMATCH |
+ // '=' |
+ // INCLUDES |
+ // DASHMATCH ] S* [ IDENT | STRING ] S*
+ // ]? ']'
+ // ;
+
+ Read(ToTokenSpec(Token.LeftBracket()));
+ var prefix = TryNamespacePrefix() ?? NamespacePrefix.None;
+ var name = Read(ToTokenSpec(TokenKind.Ident)).Text;
+
+ var hasValue = false;
+ while (true)
+ {
+ var op = TryRead(
+ ToTokenSpec(Token.Equals()),
+ ToTokenSpec(TokenKind.Includes),
+ ToTokenSpec(TokenKind.DashMatch),
+ ToTokenSpec(TokenKind.PrefixMatch),
+ ToTokenSpec(TokenKind.SuffixMatch),
+ ToTokenSpec(TokenKind.SubstringMatch));
+
+ if (op == null)
+ break;
+
+ hasValue = true;
+ var value = Read(ToTokenSpec(TokenKind.String), ToTokenSpec(TokenKind.Ident)).Text;
+
+ if (op.Value == Token.Equals())
+ {
+ _generator.AttributeExact(prefix, name, value);
+ }
+ else
+ {
+ switch (op.Value.Kind)
+ {
+ case TokenKind.Includes: _generator.AttributeIncludes(prefix, name, value); break;
+ case TokenKind.DashMatch: _generator.AttributeDashMatch(prefix, name, value); break;
+ case TokenKind.PrefixMatch: _generator.AttributePrefixMatch(prefix, name, value); break;
+ case TokenKind.SuffixMatch: _generator.AttributeSuffixMatch(prefix, name, value); break;
+ case TokenKind.SubstringMatch: _generator.AttributeSubstring(prefix, name, value); break;
+ }
+ }
+ }
+
+ if (!hasValue)
+ _generator.AttributeExists(prefix, name);
+
+ Read(ToTokenSpec(Token.RightBracket()));
+ }
+
+ private void Class()
+ {
+ //class
+ // : '.' IDENT
+ // ;
+
+ Read(ToTokenSpec(Token.Dot()));
+ _generator.Class(Read(ToTokenSpec(TokenKind.Ident)).Text);
+ }
+
+ private NamespacePrefix? TryNamespacePrefix()
+ {
+ //namespace_prefix
+ // : [ IDENT | '*' ]? '|'
+ // ;
+
+ var pipe = Token.Pipe();
+ var token = TryRead(ToTokenSpec(TokenKind.Ident), ToTokenSpec(Token.Star()), ToTokenSpec(pipe));
+
+ if (token == null)
+ return null;
+
+ if (token.Value == pipe)
+ return NamespacePrefix.Empty;
+
+ var prefix = token.Value;
+ if (TryRead(ToTokenSpec(pipe)) == null)
+ {
+ Unread(prefix);
+ return null;
+ }
+
+ return prefix.Kind == TokenKind.Ident
+ ? new NamespacePrefix(prefix.Text)
+ : NamespacePrefix.Any;
+ }
+
+ private void TypeSelectorOrUniversal()
+ {
+ //type_selector
+ // : [ namespace_prefix ]? element_name
+ // ;
+ //element_name
+ // : IDENT
+ // ;
+ //universal
+ // : [ namespace_prefix ]? '*'
+ // ;
+
+ var prefix = TryNamespacePrefix() ?? NamespacePrefix.None;
+ var token = Read(ToTokenSpec(TokenKind.Ident), ToTokenSpec(Token.Star()));
+ if (token.Kind == TokenKind.Ident)
+ _generator.Type(prefix, token.Text);
+ else
+ _generator.Universal(prefix);
+ }
+
+ private Token Peek()
+ {
+ return _reader.Peek();
+ }
+
+ private Token Read(TokenSpec spec)
+ {
+ var token = TryRead(spec);
+ if (token == null)
+ {
+ throw new FormatException(
+ string.Format(@"Unexpected token {{{0}}} where {{{1}}} was expected.",
+ Peek().Kind, spec));
+ }
+ return token.Value;
+ }
+
+ private Token Read(params TokenSpec[] specs)
+ {
+ var token = TryRead(specs);
+ if (token == null)
+ {
+ throw new FormatException(string.Format(
+ @"Unexpected token {{{0}}} where one of [{1}] was expected.",
+ Peek().Kind, string.Join(", ", specs.Select(k => k.ToString()).ToArray())));
+ }
+ return token.Value;
+ }
+
+ private Token? TryRead(params TokenSpec[] specs)
+ {
+ foreach (var kind in specs)
+ {
+ var token = TryRead(kind);
+ if (token != null)
+ return token;
+ }
+ return null;
+ }
+
+ private Token? TryRead(TokenSpec spec)
+ {
+ var token = Peek();
+ if (!spec.Fold(a => a == token.Kind, b => b == token))
+ return null;
+ _reader.Read();
+ return token;
+ }
+
+ private void Unread(Token token)
+ {
+ _reader.Unread(token);
+ }
+
+ private static TokenSpec ToTokenSpec(TokenKind kind)
+ {
+ return TokenSpec.A(kind);
+ }
+
+ private static TokenSpec ToTokenSpec(Token token)
+ {
+ return TokenSpec.B(token);
+ }
+ }
+}
diff --git a/Source/External/Fizzler/Reader.cs b/Source/External/Fizzler/Reader.cs
new file mode 100644
index 0000000000000000000000000000000000000000..ace8b6ce0252b65701be6fcaf39e7187b26d12af
--- /dev/null
+++ b/Source/External/Fizzler/Reader.cs
@@ -0,0 +1,175 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace Fizzler
+{
+ #region Imports
+
+ using System;
+ using System.Collections;
+ using System.Collections.Generic;
+
+ #endregion
+
+ ///
+ /// Adds reading semantics to a base with the
+ /// option to un-read and insert new elements while consuming the source.
+ ///
+ public sealed class Reader : IDisposable, IEnumerable
+ {
+ private IEnumerator _enumerator;
+ private Stack _buffer;
+
+ ///
+ /// Initialize a new with a base
+ /// object.
+ ///
+ public Reader(IEnumerable e) :
+ this(CheckNonNull(e).GetEnumerator()) { }
+
+ private static IEnumerable CheckNonNull(IEnumerable e)
+ {
+ if (e == null) throw new ArgumentNullException("e");
+ return e;
+ }
+
+ ///
+ /// Initialize a new with a base
+ /// object.
+ ///
+ public Reader(IEnumerator e)
+ {
+ if(e == null) throw new ArgumentNullException("e");
+ _enumerator = e;
+ _buffer = new Stack();
+ RealRead();
+ }
+
+ ///
+ /// Indicates whether there is, at least, one value waiting to be read or not.
+ ///
+ public bool HasMore
+ {
+ get
+ {
+ EnsureAlive();
+ return _buffer.Count > 0;
+ }
+ }
+
+ ///
+ /// Pushes back a new value that will be returned on the next read.
+ ///
+ public void Unread(T value)
+ {
+ EnsureAlive();
+ _buffer.Push(value);
+ }
+
+ ///
+ /// Reads and returns the next value.
+ ///
+ public T Read()
+ {
+ if (!HasMore)
+ throw new InvalidOperationException();
+
+ var value = _buffer.Pop();
+
+ if (_buffer.Count == 0)
+ RealRead();
+
+ return value;
+ }
+
+ ///
+ /// Peeks the next value waiting to be read.
+ ///
+ ///
+ /// Thrown if there is no value waiting to be read.
+ ///
+ public T Peek()
+ {
+ if (!HasMore)
+ throw new InvalidOperationException();
+
+ return _buffer.Peek();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+
+ ///
+ /// Returns an enumerator that iterates through the remaining
+ /// values to be read.
+ ///
+ public IEnumerator GetEnumerator()
+ {
+ EnsureAlive();
+ return GetEnumeratorImpl();
+ }
+
+ private IEnumerator GetEnumeratorImpl()
+ {
+ while (HasMore)
+ yield return Read();
+ }
+
+ private void RealRead()
+ {
+ EnsureAlive();
+
+ if (_enumerator.MoveNext())
+ Unread(_enumerator.Current);
+ }
+
+ ///
+ /// Disposes the enumerator used to initialize this object
+ /// if that enumerator supports .
+ ///
+ public void Close()
+ {
+ Dispose();
+ }
+
+ void IDisposable.Dispose()
+ {
+ Dispose();
+ }
+
+ void Dispose()
+ {
+ if(_enumerator == null)
+ return;
+ _enumerator.Dispose();
+ _enumerator = null;
+ _buffer = null;
+ }
+
+ private void EnsureAlive()
+ {
+ if (_enumerator == null)
+ throw new ObjectDisposedException(GetType().Name);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/External/Fizzler/Selector.cs b/Source/External/Fizzler/Selector.cs
new file mode 100644
index 0000000000000000000000000000000000000000..ac7d85ccac690764efb06a50f5bf4f31350f58b0
--- /dev/null
+++ b/Source/External/Fizzler/Selector.cs
@@ -0,0 +1,30 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace Fizzler
+{
+ using System.Collections.Generic;
+
+ ///
+ /// Represents a selector implementation over an arbitrary type of elements.
+ ///
+ public delegate IEnumerable Selector(IEnumerable elements);
+}
\ No newline at end of file
diff --git a/Source/External/Fizzler/SelectorGenerator.cs b/Source/External/Fizzler/SelectorGenerator.cs
new file mode 100644
index 0000000000000000000000000000000000000000..1f3d1773d556c4970e4c7681bb6987028a63496a
--- /dev/null
+++ b/Source/External/Fizzler/SelectorGenerator.cs
@@ -0,0 +1,341 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace Fizzler
+{
+ #region Imports
+
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+
+ #endregion
+
+ ///
+ /// A selector generator implementation for an arbitrary document/element system.
+ ///
+ public class SelectorGenerator : ISelectorGenerator
+ {
+ private readonly IEqualityComparer _equalityComparer;
+ private readonly Stack> _selectors;
+
+ ///
+ /// Initializes a new instance of this object with an instance
+ /// of and the default equality
+ /// comparer that is used for determining if two elements are equal.
+ ///
+ public SelectorGenerator(IElementOps ops) : this(ops, null) {}
+
+ ///
+ /// Initializes a new instance of this object with an instance
+ /// of and an equality comparer
+ /// used for determining if two elements are equal.
+ ///
+ public SelectorGenerator(IElementOps ops, IEqualityComparer equalityComparer)
+ {
+ if(ops == null) throw new ArgumentNullException("ops");
+ Ops = ops;
+ _equalityComparer = equalityComparer ?? EqualityComparer.Default;
+ _selectors = new Stack>();
+ }
+
+ ///
+ /// Gets the selector implementation.
+ ///
+ ///
+ /// If the generation is not complete, this property returns the
+ /// last generated selector.
+ ///
+ public Selector Selector { get; private set; }
+
+ ///
+ /// Gets the