diff --git a/QobuzDownloaderX/AboutForm.Designer.cs b/QobuzDownloaderX/AboutForm.Designer.cs
new file mode 100644
index 0000000..64a9226
--- /dev/null
+++ b/QobuzDownloaderX/AboutForm.Designer.cs
@@ -0,0 +1,178 @@
+namespace QobuzDownloaderX
+{
+ partial class AboutForm
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AboutForm));
+ this.panel1 = new System.Windows.Forms.Panel();
+ this.verNumLabel2 = new System.Windows.Forms.Label();
+ this.exitLabel = new System.Windows.Forms.Label();
+ this.pictureBox1 = new System.Windows.Forms.PictureBox();
+ this.devLabel = new System.Windows.Forms.Label();
+ this.label1 = new System.Windows.Forms.Label();
+ this.label2 = new System.Windows.Forms.Label();
+ this.label3 = new System.Windows.Forms.Label();
+ this.panel1.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
+ this.SuspendLayout();
+ //
+ // panel1
+ //
+ this.panel1.BackgroundImage = global::QobuzDownloaderX.Properties.Resources.login_frame;
+ this.panel1.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
+ this.panel1.Controls.Add(this.exitLabel);
+ this.panel1.Controls.Add(this.pictureBox1);
+ this.panel1.Dock = System.Windows.Forms.DockStyle.Top;
+ this.panel1.Location = new System.Drawing.Point(0, 0);
+ this.panel1.Name = "panel1";
+ this.panel1.Size = new System.Drawing.Size(365, 95);
+ this.panel1.TabIndex = 1;
+ this.panel1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseMove);
+ //
+ // verNumLabel2
+ //
+ this.verNumLabel2.BackColor = System.Drawing.Color.Transparent;
+ this.verNumLabel2.Font = new System.Drawing.Font("Trebuchet MS", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.verNumLabel2.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102)))));
+ this.verNumLabel2.Location = new System.Drawing.Point(12, 98);
+ this.verNumLabel2.Name = "verNumLabel2";
+ this.verNumLabel2.Size = new System.Drawing.Size(341, 18);
+ this.verNumLabel2.TabIndex = 32;
+ this.verNumLabel2.Text = "#.#.#.#";
+ this.verNumLabel2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
+ this.verNumLabel2.MouseMove += new System.Windows.Forms.MouseEventHandler(this.verNumLabel2_MouseMove);
+ //
+ // exitLabel
+ //
+ this.exitLabel.AutoSize = true;
+ this.exitLabel.BackColor = System.Drawing.Color.Transparent;
+ this.exitLabel.Font = new System.Drawing.Font("Calibri", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.exitLabel.ForeColor = System.Drawing.Color.Black;
+ this.exitLabel.Location = new System.Drawing.Point(345, 0);
+ this.exitLabel.Name = "exitLabel";
+ this.exitLabel.Size = new System.Drawing.Size(20, 23);
+ this.exitLabel.TabIndex = 9;
+ this.exitLabel.Text = "X";
+ this.exitLabel.TextAlign = System.Drawing.ContentAlignment.TopCenter;
+ this.exitLabel.Click += new System.EventHandler(this.exitLabel_Click);
+ //
+ // pictureBox1
+ //
+ this.pictureBox1.BackColor = System.Drawing.Color.Transparent;
+ this.pictureBox1.Image = global::QobuzDownloaderX.Properties.Resources.qbdlx_white;
+ this.pictureBox1.Location = new System.Drawing.Point(53, 12);
+ this.pictureBox1.Name = "pictureBox1";
+ this.pictureBox1.Size = new System.Drawing.Size(258, 64);
+ this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
+ this.pictureBox1.TabIndex = 29;
+ this.pictureBox1.TabStop = false;
+ this.pictureBox1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseMove);
+ //
+ // devLabel
+ //
+ this.devLabel.AutoSize = true;
+ this.devLabel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102)))));
+ this.devLabel.Location = new System.Drawing.Point(140, 131);
+ this.devLabel.Name = "devLabel";
+ this.devLabel.Size = new System.Drawing.Size(84, 13);
+ this.devLabel.TabIndex = 34;
+ this.devLabel.Text = "Developer - AiiR";
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102)))));
+ this.label1.Location = new System.Drawing.Point(79, 154);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(207, 13);
+ this.label1.TabIndex = 35;
+ this.label1.Text = "Inspired By - Qo-DL by Sorrow and DashLt";
+ this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
+ //
+ // label2
+ //
+ this.label2.AutoSize = true;
+ this.label2.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102)))));
+ this.label2.Location = new System.Drawing.Point(47, 177);
+ this.label2.Name = "label2";
+ this.label2.Size = new System.Drawing.Size(271, 26);
+ this.label2.TabIndex = 36;
+ this.label2.Text = "Thanks to the users on Github and Telegram for offering\r\nbug reports and ideas!";
+ this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
+ //
+ // label3
+ //
+ this.label3.AutoSize = true;
+ this.label3.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102)))));
+ this.label3.Location = new System.Drawing.Point(15, 237);
+ this.label3.Name = "label3";
+ this.label3.Size = new System.Drawing.Size(334, 26);
+ this.label3.TabIndex = 37;
+ this.label3.Text = "IF YOU PAID FOR THIS PROGRAM, YOU HAVE BEEN SCAMMED!\r\nTHIS SOFTWARE IS COMPLETELY" +
+ " FREE AND OPEN-SOURCE.";
+ this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
+ //
+ // AboutForm
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(20)))), ((int)(((byte)(20)))), ((int)(((byte)(20)))));
+ this.ClientSize = new System.Drawing.Size(365, 289);
+ this.Controls.Add(this.label3);
+ this.Controls.Add(this.label2);
+ this.Controls.Add(this.label1);
+ this.Controls.Add(this.devLabel);
+ this.Controls.Add(this.verNumLabel2);
+ this.Controls.Add(this.panel1);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
+ this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
+ this.Name = "AboutForm";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
+ this.Text = "QobuzDLX | About";
+ this.Load += new System.EventHandler(this.AboutForm_Load);
+ this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.AboutForm_MouseMove);
+ this.panel1.ResumeLayout(false);
+ this.panel1.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Panel panel1;
+ private System.Windows.Forms.Label verNumLabel2;
+ private System.Windows.Forms.Label exitLabel;
+ private System.Windows.Forms.PictureBox pictureBox1;
+ private System.Windows.Forms.Label devLabel;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.Label label2;
+ private System.Windows.Forms.Label label3;
+ }
+}
\ No newline at end of file
diff --git a/QobuzDownloaderX/AboutForm.cs b/QobuzDownloaderX/AboutForm.cs
new file mode 100644
index 0000000..1d56b16
--- /dev/null
+++ b/QobuzDownloaderX/AboutForm.cs
@@ -0,0 +1,78 @@
+using QobuzDownloaderX.Properties;
+using System;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using System.Reflection;
+
+namespace QobuzDownloaderX
+{
+ public partial class AboutForm : Form
+ {
+ public AboutForm()
+ {
+ InitializeComponent();
+ }
+
+ public const int WM_NCLBUTTONDOWN = 0xA1;
+ public const int HT_CAPTION = 0x2;
+
+ [DllImportAttribute("user32.dll")]
+ public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
+ [DllImportAttribute("user32.dll")]
+ public static extern bool ReleaseCapture();
+
+ private void AboutForm_Load(object sender, EventArgs e)
+ {
+ // Get and display version number.
+ verNumLabel2.Text = Assembly.GetExecutingAssembly().GetName().Version.ToString();
+ }
+
+ private void exitLabel_Click(object sender, EventArgs e)
+ {
+ this.Close();
+ }
+
+ private void panel1_MouseMove(object sender, MouseEventArgs e)
+ {
+ if (e.Button == MouseButtons.Left)
+ {
+ ReleaseCapture();
+ SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
+ }
+ }
+
+ private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
+ {
+ if (e.Button == MouseButtons.Left)
+ {
+ ReleaseCapture();
+ SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
+ }
+ }
+
+ private void verNumLabel2_MouseMove(object sender, MouseEventArgs e)
+ {
+ if (e.Button == MouseButtons.Left)
+ {
+ ReleaseCapture();
+ SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
+ }
+ }
+
+ private void AboutForm_MouseMove(object sender, MouseEventArgs e)
+ {
+ if (e.Button == MouseButtons.Left)
+ {
+ ReleaseCapture();
+ SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
+ }
+ }
+ }
+}
diff --git a/QobuzDownloaderX/AboutForm.resx b/QobuzDownloaderX/AboutForm.resx
new file mode 100644
index 0000000..800af8a
--- /dev/null
+++ b/QobuzDownloaderX/AboutForm.resx
@@ -0,0 +1,1052 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+
+
+ 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
+ AP8UFBT/tra2/////////////////////////////Pz8/4SEhP8DAwP/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8NDQ3/wMDA///////e3t7/IyMj8wAAAE4AAAC2ampq////////////Y2Nj/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/1tbW//6+vr///////7+/v/q6ur/8fHx////////////4uLi/yoqKv8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wEBAf+cnJz//////+/v7/84ODj8AAAAbAoKCsl5eXn///////r6+v9PT0//AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/jo6O////////////29vb/zo6Ov9gYGD/9fX1///////7+/v/VFRU/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/4mJif//////9fX1/0VFRf4AAAB8CwsLynp6ev//////+fn5/05O
+ Tv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP+RkZH////////////X19f/Li4u/1ZWVv/09PT///////v7
+ +/9VVVX/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/iYmJ///////19fX/RUVF/gAAAHwBAQG5bW1t////
+ ///+/v7/YGBg/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/2FhYf/7+/v///////7+/v/h4eH/6urq////
+ ////////5eXl/y4uLv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP+bm5v//////+/v7/85OTn8AAAAbQAA
+ AJlRUVH/+vr6//////+FhYX/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/GBgY/8DAwP//////////////
+ //////////////////+Pj4//BAQE/wAAAP8AAAD/AAAA/wAAAP8AAAD/DAwM/76+vv//////39/f/yQk
+ JPMAAABPAAAAay0tLfvn5+f//////7u7u/8MDAz/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/MTEx/7u7
+ u//5+fn////////////x8fH/mJiY/xcXF/8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8sLCz/5eXl////
+ //+8vLz/Dg4O4AAAACsAAAA2DQ0N5rq6uv//////7e3t/zs7O/8AAAD/AAAA/wAAAP8AAAD/AQEB/w4O
+ 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
+ ///////////////////9/f3/9fX1/+rq6v/c3Nz/zc3N/7y8vP+rq6v/mZmZ/4WFhf9nZ2f/Nzc3/w4O
+ Dv8AAAD8AAAA9AoKCv5/f3//9PT0/////////////////5+fn/8LCwv/AAAA6woKClwAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAGgAAAJwAAAD4JSUl/52dnf/09PT/////////////////////////
+ ///8/Pz/7u7u/9XV1f+4uLj/pKSk/5qamv+bm5v/o6Oj/7CwsP+7u7v/vr6+/7Ozs/+fn5//iIiI/3Jy
+ cv9aWlr/RkZG/y8vL/8PDw//CwsL/39/f//09PT////////////+/v7/rKys/x4eHv8AAADtAAAAaQAA
+ AAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbAAAAqQAAAP07Ozv/x8fH////////////////////
+ ////////8fHx/7y8vP93d3f/Pz8//xsbG/8NDQ3/BwcH/wQEBP8FBQX/CAgI/w8PD/8fHx//Pj4+/2Ji
+ Yv97e3v/eXl5/2JiYv9KSkr/OTk5/ycnJ/8dHR3/gYGB//T09P////////////7+/v+srKz/HR0d/wAA
+ AO0AAABpAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABMAAACiAAAA/kZGRv/W1tb/////////
+ //////////////T09P+vr6//TU1N/xAQEP8BAQH/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wICAv8SEhL/MjIy/0VFRf8+Pj7/LCws/yEhIf+EhIT/9fX1/////////////v7+/6ys
+ rP8dHR3/AAAA7QAAAGoAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAAIYAAAD7Pz8//9jY
+ 2P//////////////////////1NTU/2BgYP8ODg7/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wsLC/8dHR3/JSUl/4eHh//19fX/////////
+ ////////rq6u/xwcHP8AAADsAAAAaQAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWQAA
+ APAqKir/y8vL//////////////////39/f+1tbX/MDAw/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8LCwv/goKC//X1
+ 9f/////////////////+/v7/kZGR/wcHB/8AAADOAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAmAAAA0BAQEP+oqKj//////////////////f39/6Ojo/8bGxv/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/woK
+ Cv9+fn7/9PT0////////////////////////////8fHx/1xcXP8AAAD7AAAAfgAAAAMAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAQAAACKAAAA/mtra//4+Pj/////////////////ra2t/xkZGf8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/CgoK/35+fv/09PT////////////9/f3/+fn5/////////////////9LS0v8oKCj/AAAA4gAA
+ ADcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADUAAADiJycn/9XV1f/////////////////Ly8v/KCgo/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8KCgr/fn5+//T09P////////////7+/v+srKz/fX19//Ly8v//////////////
+ //+Ojo7/BQUF/wAAAJoAAAAHAAAAAAAAAAAAAAAAAAAAAwAAAI0CAgL/goKC//7+/v///////////+7u
+ 7v9QUFD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wICAv9wcHD/9PT0/////////////v7+/62trf8dHR3/CQkJ/5yc
+ nP/////////////////k5OT/Nzc3/wAAAOYAAAA3AAAAAAAAAAAAAAAAAAAAIwAAANciIiL/1dXV////
+ /////////////5ubm/8ICAj/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/xAQEP+/v7/////////////+/v7/rq6u/x4e
+ Hv8AAAD/AAAA/y8vL//b29v/////////////////jo6O/wMDA/8AAACGAAAAAQAAAAAAAAAAAAAAYAAA
+ APlmZmb/+vr6////////////5ubm/zg4OP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AQEB/wUFBf8EBAT/AAAA/wAAAP8AAAD/AAAA/wYGBv+Tk5P//f39//z8
+ /P+tra3/Hh4e/wAAAP8AAAD/AAAA/wICAv+Dg4P//v7+////////////19fX/yIiIv8AAADMAAAAGAAA
+ AAAAAAAHAAAAoAoKCv+srKz/////////////////pKSk/wgICP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/xISEv9OTk7/h4eH/5+fn/+ZmZn/c3Nz/zIyMv8GBgb/AAAA/wAA
+ AP8aGhr/a2tr/2tra/8aGhr/AAAA/wAAAP8AAAD/AAAA/wAAAP8wMDD/4+Pj////////////+Pj4/1xc
+ XP8AAADxAAAARwAAAAAAAAAdAAAA0SQkJP/e3t7////////////39/f/WVlZ/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8BAQH/Ozs7/7W1tf/z8/P//////////////////f39/+Pj
+ 4/+FhYX/FhYW/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8JCQn/qKio////
+ /////////////5iYmP8EBAT/AAAAewAAAAAAAABCAAAA605OTv/09PT////////////d3d3/JCQk/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP9BQUH/2NjY////////////////////
+ ///////////////////7+/v/oqKi/xQUFP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/ampq//z8/P///////////8fHx/8TExP/AAAApwAAAAkAAABnAAAA9nR0dP//////////////
+ //+1tbX/DQ0N/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/x0dHf/FxcX/////////
+ ////////////////////////////////////////+/v7/3t7e/8CAgL/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/PDw8/+3t7f///////////+Xl5f8pKSn/AAAAyAAAABYGBgaEAgIC/ZKS
+ kv////////////////+SkpL/AgIC/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/2xs
+ bP/7+/v//////////////////////////////////////////////////////9jY2P8lJSX/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/Hh4e/9ra2v////////////Dw8P9DQ0P/AAAA3gAA
+ ACYUFBScBwcH/6Wlpf////////////////94eHj/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/CgoK/62trf//////////////////////3Nzc/4qKiv+mpqb/9vb2//////////////////j4
+ +P9bW1v/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/EhIS/8bGxv////////////b2
+ 9v9VVVX/AAAA6AAAADYcHBypCgoK/6+vr/////////////39/f9qamr/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/FBQU/83Nzf/////////////////4+Pj/ZWVl/wAAAP8RERH/tLS0////
+ //////////////////98fHz/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/Dw8P/7u7
+ u/////////////n5+f9fX1//AAAA6wAAAD4dHR2qCgoK/7CwsP////////////39/f9qamr/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/FRUV/87Ozv/////////////////39/f/XFxc/wAA
+ AP8MDAz/ra2t//////////////////////9+fn7/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/Dw8P/7u7u/////////////n5+f9fX1//AAAA6wAAAD4WFhafCAgI/6enp///////////////
+ //91dXX/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/DAwM/7Ozs///////////////
+ ////////0NDQ/3Fxcf+QkJD/8vLy//////////////////n5+f9gYGD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/EhIS/8bGxv////////////b29v9WVlb/AAAA6AAAADYJCQmJAwMD/peX
+ l/////////////////+NjY3/AQEB/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/3Z2
+ dv/9/f3///////////////////////39/f/+/v7//////////////////////9/f3/8rKyv/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/HR0d/9nZ2f////////////Dw8P9ERET/AAAA3gAA
+ ACcAAABsAAAA+Hp6ev////////////////+urq7/CgoK/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/yUlJf/Q0ND//////////////////////////////////////////////////v7+/4iI
+ iP8EBAT/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/OTk5/+3t7f///////////+bm
+ 5v8rKyv/AAAAyQAAABcAAABJAAAA7lVVVf/29vb////////////X19f/Hh4e/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP9SUlL/5eXl////////////////////////////////////
+ ////////tbW1/x0dHf8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/ZmZm//v7
+ +////////////8nJyf8UFBT/AAAAqQAAAAoAAAAiAAAA1ysrK//j4+P////////////09PT/T09P/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wEBAf8DAwP/TU1N/8nJyf/6+vr/////////
+ /////////////+/v7/+bm5v/ISEh/wAAAP8BAQH/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8HBwf/oqKi/////////////////5ycnP8FBQX/AAAAfgAAAAAAAAAKAAAAqQ0NDf+1tbX/////////
+ ////////mJiY/wUFBf8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AgIC/w4ODv8WFhb/CAgI/x0d
+ Hf9kZGT/nZ2d/7W1tf+vr6//ioqK/0VFRf8MDAz/Dg4O/xcXF/8ICAj/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8qKir/3t7e////////////+fn5/2FhYf8AAADzAAAASgAAAAAAAAAAAAAAawAA
+ APxxcXH//f39////////////39/f/y8vL/8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8BAQH/DAwM/x4e
+ Hv8zMzP/PDw8/ysrK/8UFBT/EBAQ/xQUFP8TExP/Dw8P/x0dHf81NTX/PDw8/ysrK/8XFxf/BgYG/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP94eHj//f39////////////3Nzc/ycnJ/8AAADQAAAAGwAA
+ AAAAAAAAAAAAKwAAAN8qKir/3d3d/////////////////42Njf8EBAT/AAAA/wAAAP8AAAD/AAAA/wEB
+ Af8KCgr/Ghoa/ywsLP8+Pj7/VFRU/2lpaf90dHT/eXl5/35+fv98fHz/d3d3/3Fxcf9hYWH/S0tL/zc3
+ N/8lJSX/ExMT/wUFBf8AAAD/AAAA/wAAAP8AAAD/AAAA/yYmJv/T09P/////////////////mJiY/wUF
+ Bf8AAACMAAAAAgAAAAAAAAAAAAAABgAAAJkEBAT/j4+P/////////////////+fn5/9DQ0P/AAAA/wAA
+ AP8AAAD/AQEB/wkJCf8XFxf/JiYm/zc3N/9JSUn/W1tb/29vb/+Ghob/n5+f/7W1tf+urq7/lJSU/3x8
+ fP9nZ2f/U1NT/0FBQf8xMTH/ICAg/xEREf8EBAT/AAAA/wAAAP8AAAD/BgYG/4yMjP/+/v7/////////
+ ///r6+v/QUFB/wAAAOoAAAA9AAAAAAAAAAAAAAAAAAAAAAAAAD8AAADqMDAw/93d3f//////////////
+ //+/v7//Hh4e/wAAAP8BAQH/BwcH/xQUFP8iIiL/MTEx/0BAQP9RUVH/YmJi/3V1df+JiYn/np6e/7Gx
+ sf+rq6v/lZWV/4GBgf9tbW3/W1tb/0pKSv86Ojr/Kysr/x0dHf8PDw//BAQE/wAAAP8AAAD/VVVV/+3t
+ 7f////////////////+dnZ3/CAgI/wAAAKQAAAAJAAAAAAAAAAAAAAAAAAAAAAAAAAcAAACYAgIC/3p6
+ ev/7+/v////////////9/f3/m5ub/xAQEP8CAgL/ERER/x8fH/8sLCz/Ojo6/0lJSf9YWFj/aWlp/3p6
+ ev+NjY3/oKCg/7Kysv+srKz/mJiY/4WFhf9zc3P/YmJi/1JSUv9DQ0P/NDQ0/ycnJ/8aGhr/CgoK/wAA
+ AP86Ojr/1tbW/////////////////9zc3P8yMjL/AAAA6AAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAvAAAA2RcXF/+3t7f/////////////////+fn5/4+Pj/8QEBD/BwcH/yMjI/82Njb/QkJC/1BQ
+ UP9fX1//bm5u/35+fv+Pj4//oqKi/7Kysv+tra3/mpqa/4iIiP94eHj/aGho/1lZWf9KSkr/PT09/zAw
+ MP8YGBj/AgIC/zc3N//MzMz/////////////////9vb2/25ubv8BAQH+AAAAjAAAAAUAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAABAAAAaAAAAPU2Njb/19fX//////////////////n5+f+dnZ3/Hx8f/wcH
+ B/8nJyf/RkZG/1hYWP9lZWX/c3Nz/4KCgv+SkpL/o6Oj/7Kysv+tra3/nJyc/4uLi/98fHz/bW1t/2Bg
+ YP9SUlL/PDw8/xgYGP8GBgb/S0tL/9LS0v/////////////////+/v7/mpqa/w0NDf8AAADGAAAAIQAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAJcAAAD9T09P/+Tk5P//////////////
+ ///9/f3/wsLC/0dHR/8JCQn/FxcX/0BAQP9iYmL/eHh4/4iIiP+Xl5f/p6en/7S0tP+wsLD/oKCg/5GR
+ kf+CgoL/cHBw/1VVVf8uLi7/CwsL/xgYGP98fHz/5+fn//////////////////////+ysrL/HBwc/wAA
+ AOMAAABFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAACzAgIC/1lZ
+ Wf/k5OT//////////////////////+rq6v+VlZX/NjY2/wwMDP8VFRX/NjY2/1paWv94eHj/kJCQ/6Cg
+ oP+bm5v/h4eH/21tbf9LS0v/Jycn/w0NDf8WFhb/Wlpa/8DAwP/5+fn//////////////////v7+/7W1
+ tf8kJCT/AAAA7wAAAGUAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAnAAAAvAICAv9OTk7/1dXV///////////////////////+/v7/5eXl/6Wlpf9dXV3/KSkp/xUV
+ Ff8RERH/FBQU/xkZGf8XFxf/EhIS/xISEv8ZGRn/PDw8/3p6ev/ExMT/9fX1////////////////////
+ ///4+Pj/oqKi/x8fH/8AAADwAAAAcgAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAJwAAALIAAAD9NDQ0/7S0tP/5+fn/////////////////////////
+ ///4+Pj/4uLi/7+/v/+goKD/jY2N/4KCgv+FhYX/k5OT/6ysrP/Pz8//7u7u//39/f//////////////
+ /////////////+fn5/97e3v/EBAQ/wAAAOkAAABrAAAABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABoAAACTAAAA9BUVFf91dXX/2tra//39
+ /f//////////////////////////////////////////////////////////////////////////////
+ ///////////////////19fX/s7Oz/0JCQv8FBQX/AAAA0gAAAFAAAAAEAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALAAAAYwAA
+ ANUCAgL+Kioq/4WFhf/X19f/+vr6////////////////////////////////////////////////////
+ ////////////////////////8PDw/7e3t/9aWlr/EBAQ/wAAAPMAAACjAAAALQAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAQAAACoAAACPAAAA5AMDA/4jIyP/ZGRk/6enp//Y2Nj/8fHx//v7+///////////////
+ //////////////7+/v/39/f/6enp/8bGxv+Li4v/RUVF/w8PD/8AAAD3AAAAwQAAAFkAAAAMAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAANgAAAIsAAADWAAAA9wgICP8fHx//RERE/2Vl
+ Zf+BgYH/k5OT/5qamv+YmJj/jY2N/3Z2dv9YWFj/NDQ0/xMTE/8DAwP9AAAA7AAAALUAAABfAAAAFwAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAgAAAAWgAA
+ AJYAAADGAAAA5QAAAPEBAQH4BQUF/AcHB/0HBwf9BAQE+gAAAPUAAADsAAAA2QAAALEAAAB6AAAAOwAA
+ AA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAUCAgIWDg4OMxUVFVQYGBhsGxsbfCAgIIQeHh6CGRkZdRcXF2ITExNFCAgIJAAA
+ AA0AAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAD//4AD/48AAP/8AAB/BwAA//AAAB4DAAD/4AAABAEAAP+AAAAAAAAA/wAAAAAA
+ AAD+AAAAAAAAAPwAAAAAAQAA+AAAAAADAADwAAAAAAcAAPAAAAAADwAA4AAAAAAHAADAAAAAAAcAAMAA
+ AAAAAwAAgAAAAAADAACAAAAAAAEAAIAAAAAAAQAAAAAAAAABAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAABAAAAAAAAAAEAAIAAAAAAAQAAgAAAAAABAACAAAAAAAMAAMAAAAAAAwAAwAAAAAAH
+ AADgAAAAAAcAAOAAAAAADwAA8AAAAAAfAAD4AAAAAB8AAPwAAAAAPwAA/gAAAAB/AAD/AAAAAP8AAP+A
+ AAAD/wAA/8AAAAf/AAD/8AAAH/8AAP/8AAB//wAA//+AAf//AAAoAAAAYAAAAMAAAAABACAAAAAAAACQ
+ AAAAAAAAAAAAAAAAAAAAAAAAv7+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAswAA
+ AHUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrIAv7+/AAAAAAAAAAAAAAAAAAAA
+ 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
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAKgAAAD/AAAA/wAAAP8AAAD/e3t7/0lJ
+ Sf8AAAD/AAAA/wAAAP8AAAD/AAAAZQAAAAAAAAAAAAAAAAAAAACysrIAv7+/AAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADkAAACwAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/xYW
+ Fv9TU1P/l5eX/9HR0f/29vb/////////////////////////////////////////////////////////
+ /////////////////////////v7+//b29v/i4uL/wMDA/42Njf9RUVH/Gxsb/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAC5AAAAQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAApwAA
+ AP8AAAD/AAAA/wAAAP9/f3////////Pz8/9AQED/AAAA/wAAAP8AAAD/AAAA/wAAAGUAAAAAAAAAAAAA
+ AACysrIAv7+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiAAAAnwAAAP0AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wwMDP9TU1P/q6ur/+zs7P//////////////////////////////////////////////
+ //////////////////////////////7+/v/7+/v/+Pj4//X19f/x8fH/7Ozs/+fn5//j4+P/4eHh/+Dg
+ 4P/Y2Nj/v7+//42Njf9KSkr/ERER/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAKsAAAArAAAAAAAA
+ AAAAAAAAAAAAAAAAAAQAAACnAAAA/wAAAP8AAAD/AAAA/39/f//////////////////x8fH/QEBA/wAA
+ AP8AAAD/AAAA/wAAAP8AAABlAAAAAAAAAACysrIAv7+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAA
+ AHEAAADtAAAA/wAAAP8AAAD/AAAA/wAAAP8gICD/goKC/93d3f//////////////////////////////
+ /////////////////////////////////////////////////////////v7+//z8/P/5+fn/9vb2//Ly
+ 8v/t7e3/6Ojo/+Li4v/c3Nz/1tbW/8/Pz//Hx8f/wcHB/7+/v/+4uLj/mpqa/19fX/8eHh7/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD0AAAAfgAAAAgAAAAAAAAABAAAAKcAAAD/AAAA/wAAAP8AAAD/f39/////
+ ////////////////////////8fHx/0BAQP8AAAD/AAAA/wAAAP8AAAD/AAAAZAAAAACysrIAv7+/AAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAArAAAAvgAAAP8AAAD/AAAA/wAAAP8AAAD/IyMj/5OTk//x8fH/////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////f39//r6+v/39/f/8/Pz/+/v7//q6ur/5OTk/97e3v/Y2Nj/0dHR/8nJyf/BwcH/ubm5/7Cw
+ sP+np6f/oKCg/5ycnP+Kior/V1dX/xsbG/8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAMoAAAA+AAAAoQAA
+ AP8AAAD/AAAA/wAAAP9+fn7///////////////////////////////////////Hx8f9FRUX/AQEB/wAA
+ AP8AAAD/AAAA/wAAAGaysrIDv7+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGEAAADwAAAA/wAAAP8AAAD/AAAA/xIS
+ Ev+FhYX/8fHx////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////9/f3/+/v7//j4+P/09PT/8PDw/+vr6//m5ub/4ODg/9ra
+ 2v/T09P/y8vL/8TExP+7u7v/s7Oz/6qqqv+goKD/lpaW/4uLi/+CgoL/fHx8/2tra/8+Pj7/DQ0N/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/35+fv//////////////////////////////
+ ///////////////////U1NT/CQkJ/wAAAP8AAAD/AAAA/wAAAPGysrIcv7+/AAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAlQAA
+ AP8AAAD/AAAA/wAAAP8AAAD/WFhY/93d3f//////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////7+/v/8/Pz/+fn5//b2
+ 9v/x8fH/7e3t/+jo6P/i4uL/29vb/9XV1f/Ozs7/xsbG/76+vv+1tbX/rKys/6Ojo/+ZmZn/jo6O/4SE
+ hP94eHj/bW1t/2JiYv9aWlr/R0dH/yEhIf8CAgL/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/fn5+////
+ /////////////////////////////////////////////+Pj4/8vLy//AAAA/wAAAP8AAAD/AAAA9AAA
+ AEaysrIAv7+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAABYAAAC7AAAA/wAAAP8AAAD/AAAA/xkZGf+np6f/////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////39/f/7+/v/9/f3//Dw8P/n5+f/3Nzc/9HR0f/IyMj/wMDA/7i4
+ uP+vr6//pqam/5ycnP+RkZH/h4eH/3x8fP9wcHD/ZGRk/1hYWP9MTEz/RERE/z8/P/8qKir/CgoK/wAA
+ AP8AAAD/AAAA/wAAAP9+fn7/////////////////////////////////////////////////4+Pj/ysr
+ K/8AAAD/AAAA/wAAAP8AAAD0AAAARgAAAACysrIAv7+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIgAAANIAAAD/AAAA/wAAAP8AAAD/R0dH/+Dg
+ 4P//////////////////////////////////////////////////////////////////////////////
+ /////////////+np6f/Gxsb/oKCg/39/f/9lZWX/UlJS/0ZGRv9DQ0P/Q0ND/01NTf9aWlr/b29v/4mJ
+ if+kpKT/vb29/8zMzP/Ozs7/w8PD/7W1tf+oqKj/n5+f/5WVlf+Kior/f39//3R0dP9oaGj/XFxc/09P
+ T/9FRUX/PT09/zU1Nf8vLy//JiYm/w8PD/8AAAD/AAAA/319ff//////////////////////////////
+ ///////////////////j4+P/Kysr/wAAAP8AAAD/AAAA/wAAAPQAAABGAAAAAAAAAACysrIAv7+/AAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAA3gAA
+ AP8AAAD/AAAA/wAAAP92dnb//f39////////////////////////////////////////////////////
+ ////////////////////////9PT0/7y8vP93d3f/Ozs7/xISEv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/CwsL/ycnJ/9RUVH/fn5+/6CgoP+qqqr/n5+f/46O
+ jv+CgoL/d3d3/2xsbP9fX1//U1NT/0hISP8/Pz//ODg4/y8vL/8nJyf/ICAg/xcXF/8AAAD/fX19////
+ /////////////////////////////////////////////+Pj4/8rKyv/AAAA/wAAAP8AAAD/AAAA9AAA
+ AEYAAAAAAAAAAAAAAACysrIAv7+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAACYAAADgAAAA/wAAAP8AAAD/BAQE/5qamv//////////////////////////////
+ /////////////////////////////////////////////8nJyf9ubm7/ISEh/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/w8PD/86Ojr/a2tr/4aGhv+BgYH/cHBw/2NjY/9WVlb/SkpK/0JCQv86Ojr/MjIy/yoq
+ Kv8iIiL/GBgY/wMDA/+Dg4P/////////////////////////////////////////////////4+Pj/yws
+ LP8AAAD/AAAA/wAAAP8AAAD1AAAARwAAAAAAAAAAAAAAAAAAAACysrIAv7+/AAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGwAAANoAAAD/AAAA/wAAAP8KCgr/r6+v////
+ //////////////////////////////////////////////////////////////////+xsbH/RERE/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/xkZGf9ISEj/ZWVl/19f
+ X/9OTk7/RERE/zw8PP80NDT/LCws/yQkJP8aGhr/BgYG/4SEhP//////////////////////////////
+ ///////////////////j4+P/LCws/wAAAP8AAAD/AAAA/wAAAPUAAABHAAAAAAAAAAAAAAAAAAAAAAAA
+ AACysrIAv7+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANAAAAygAA
+ AP8AAAD/AAAA/wsLC/+4uLj/////////////////////////////////////////////////////////
+ ////////urq6/z4+Pv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/EBAQ/zY2Nv9JSUn/QUFB/zY2Nv8uLi7/Jycn/xwcHP8ICAj/hISE////
+ /////////////////////////////////////////////+Tk5P8sLCz/AAAA/wAAAP8AAAD/AAAA9QAA
+ AEcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrIAv7+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAACrAAAA/wAAAP8AAAD/BwcH/7W1tf//////////////////////////////
+ /////////////////////////////+Hh4f9bW1v/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8SEhL/MDAw/zQ0
+ NP8pKSn/Hx8f/wsLC/+FhYX/////////////////////////////////////////////////5OTk/yws
+ LP8AAAD/AAAA/wAAAP8AAAD1AAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrIAv7+/AAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHsAAAD/AAAA/wAAAP8AAAD/paWl////
+ ////////////////////////////////////////////////////////o6Oj/xcXF/8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AgIC/xkZGf8jIyP/Dg4O/4eHh///////////////////////////////
+ ///////////////////Z2dn/Kysr/wAAAP8AAAD/AAAA/wAAAOwAAABIAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAACysrIAv7+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQQAA
+ AP0AAAD/AAAA/wAAAP+Ghob///////////////////////////////////////////////////////f3
+ 9/9oaGj/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/iIiI////
+ //////////////////////////////////////////////////+ysrL/AAAA/wAAAP8AAAD/AAAA/wAA
+ AHwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrIAv7+/AAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAARAAAA3gAAAP8AAAD/AAAA/1lZWf//////////////////////////////
+ ////////////////////////4uLi/z4+Pv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP96enr/////////////////////////////////////////////////////////
+ ////////gICA/wAAAP8AAAD/AAAA/wAAAOAAAAAZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AACysrIAv7+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACaAAAA/wAAAP8AAAD/KCgo//Hx
+ 8f/////////////////////////////////////////////////U1NT/IyMj/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/3t7e///////////////////////////////
+ /////////////////////////////////////////////0hISP8AAAD/AAAA/wAAAP8AAACsAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrIAv7+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AEEAAAD/AAAA/wAAAP8FBQX/xsbG/////////////////////////////////////////////////9LS
+ 0v8aGhr/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/e3t7////
+ /////////////////////////////////////////////////////////////////////////////+Pj
+ 4/8VFRX/AAAA/wAAAP8AAAD/AAAAUgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrIAv7+/AAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAM8AAAD/AAAA/wAAAP95eXn/////////////////////////
+ ////////////////////////29vb/x0dHf8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP96enr/////////////////////////////////////////////////////////
+ //////////////////////////////////+kpKT/AAAA/wAAAP8AAAD/AAAA3gAAAAwAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAACysrIAv7+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZgAAAP8AAAD/AAAA/ycn
+ J//29vb////////////////////////////////////////////t7e3/Kysr/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/3p6ev//////////////////////////////
+ ////////////////////////////////////////////////////////////////////////SkpK/wAA
+ AP8AAAD/AAAA/wAAAHwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrIAv7+/AAAAAAAAAAAAAAAAAAAA
+ AAAAAAANAAAA4gAAAP8AAAD/AAAA/7Kysv////////////////////////////////////////////7+
+ /v9LS0v/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/enp6////
+ /////////////////////////////////////////////+Li4v9bW1v/7Ozs////////////////////
+ ////////////////////////19fX/wkJCf8AAAD/AAAA/wAAAO4AAAAYAAAAAAAAAAAAAAAAAAAAAAAA
+ AACysrIAv7+/AAAAAAAAAAAAAAAAAAAAAAAAAABwAAAA/wAAAP8AAAD/RERE////////////////////
+ /////////////////////////////4ODg/8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP96enr/////////////////////////////////////////////////5eXl/y4u
+ Lv8AAAD/WFhY/////////////////////////////////////////////////3Fxcf8AAAD/AAAA/wAA
+ AP8AAACHAAAAAAAAAAAAAAAAAAAAAAAAAACysrIAv7+/AAAAAAAAAAAAAAAAAAAAAAoAAADfAAAA/wAA
+ AP8BAQH/xcXF////////////////////////////////////////////x8fH/wQEBP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/3h4eP//////////////////////////////
+ ///////////////////l5eX/Li4u/wAAAP8AAAD/AAAA/5+fn///////////////////////////////
+ /////////////+fn5/8RERH/AAAA/wAAAP8AAADtAAAAFAAAAAAAAAAAAAAAAAAAAACysrIAv7+/AAAA
+ AAAAAAAAAAAAAAAAAFsAAAD/AAAA/wAAAP9HR0f/////////////////////////////////////////
+ ///5+fn/MDAw/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/Q0ND////
+ /////////////////////////////////////////////+Xl5f8uLi7/AAAA/wAAAP8AAAD/AAAA/xMT
+ E//l5eX///////////////////////////////////////////93d3f/AAAA/wAAAP8AAAD/AAAAcwAA
+ AAAAAAAAAAAAAAAAAACysrIAv7+/AAAAAAAAAAAAAAAAAAAAAMMAAAD/AAAA/wAAAP+6urr/////////
+ //////////////////////////////////+NjY3/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/pKSk////////////////////////////////////////////5eXl/y4u
+ Lv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP9dXV3/////////////////////////////////////////
+ ///i4uL/DAwM/wAAAP8AAAD/AAAA2AAAAAUAAAAAAAAAAAAAAACysrIAv7+/AAAAAAAAAAAAAAAALwAA
+ AP0AAAD/AAAA/y8vL//9/f3//////////////////////////////////////+np6f8TExP/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/ubm5////////////////////
+ ///////////////////m5ub/Li4u/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8CAgL/yMjI////
+ ////////////////////////////////////////Xl5e/wAAAP8AAAD/AAAA/wAAAEUAAAAAAAAAAAAA
+ AACysrIAv7+/AAAAAAAAAAAAAAAAhwAAAP8AAAD/AAAA/5GRkf//////////////////////////////
+ /////////////3l5ef8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/hoaG/////////////////////////////////+bm5v8vLy//AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/R0dH////////////////////////////////////////////w8PD/wAA
+ AP8AAAD/AAAA/wAAAKEAAAAAAAAAAAAAAACysrIAv7+/AAAAAAAAAAAEAAAA1wAAAP8AAAD/CwsL/+Tk
+ 5P//////////////////////////////////////6+vr/xISEv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/Gxsb/+Pj4///////////////////////5eXl/y8v
+ L/8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/8fHx///////////////
+ /////////////////////////Pz8/ywsLP8AAAD/AAAA/wAAAOkAAAAOAAAAAAAAAACysrIAv7+/AAAA
+ AAAAAAAzAAAA/wAAAP8AAAD/SkpK////////////////////////////////////////////jY2N/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8QEBD/MjIy/01N
+ Tf9XV1f/T09P/zg4OP8XFxf/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/ygo
+ KP+wsLD/6+vr/+vr6/+wsLD/Jycn/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/1lZWf///////////////////////////////////////////39/f/8AAAD/AAAA/wAA
+ AP8AAABKAAAAAAAAAACysrIAv7+/AAAAAAAAAAB5AAAA/wAAAP8AAAD/mpqa////////////////////
+ ///////////////////8/Pz/LCws/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8HBwf/VlZW/6+vr//n5+f////////////////////////////u7u7/vLy8/2hoaP8SEhL/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/EhIS/xISEv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wsLC//j4+P/////////////////////////
+ /////////////8zMzP8BAQH/AAAA/wAAAP8AAACUAAAAAAAAAACysrIAv7+/AAAAAAAAAAC8AAAA/wAA
+ AP8GBgb/29vb///////////////////////////////////////ExMT/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/1NTU//R0dH/////////////////////////////////////////
+ ///////////////////i4uL/bGxs/wEBAf8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP+RkZH///////////////////////////////////////r6+v8lJSX/AAAA/wAAAP8AAADSAAAAAgAA
+ AACysrIAv7+/AAAAABAAAADsAAAA/wAAAP8uLi7//v7+////////////////////////////////////
+ //9xcXH/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8ICAj/mpqa////////////////////
+ /////////////////////////////////////////////////////////////7e3t/8ZGRn/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP89PT3/////////////////////////////////////////
+ //9hYWH/AAAA/wAAAP8AAAD5AAAAIQAAAACysrIAv7+/AAAAADgAAAD/AAAA/wAAAP9mZmb/////////
+ //////////////////////////////z8/P8rKyv/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wwM
+ DP+6urr/////////////////////////////////////////////////////////////////////////
+ ///////////////////X19f/ISEh/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8ICAj/4eHh////
+ //////////////////////////////////+enp7/AAAA/wAAAP8AAAD/AAAAUAAAAACysrIAv7+/AAAA
+ AGYAAAD/AAAA/wAAAP+dnZ3//////////////////////////////////////9fX1/8DAwP/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AgIC/7Gxsf//////////////////////////////////////////////
+ ////////////////////////////////////////////////////////0tLS/xEREf8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/pqam///////////////////////////////////////Q0ND/AQEB/wAA
+ AP8AAAD/AAAAgQAAAACysrIAv7+/AAAAAJIAAAD/AAAA/wAAAP/Jycn/////////////////////////
+ /////////////6Ghof8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/enp6////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////6Wlpf8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/aWlp////////////////////
+ ///////////////////x8fH/FxcX/wAAAP8AAAD/AAAArQAAAACysrIAv7+/AAAAALYAAAD/AAAA/w8P
+ D//p6en//////////////////////////////////////2xsbP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8lJSX/9/f3////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////9JSUn/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/ODg4////////////////////////////////////////////NjY2/wAAAP8AAAD/AAAAzwAA
+ AAGysrIAv7+/AwAAANEAAAD/AAAA/ycnJ//8/Pz//////////////////////////////////////0FB
+ Qf8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP+cnJz/////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///Hx8f/AgIC/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/FhYW//Hx8f//////////////////////////////
+ ////////VlZW/wAAAP8AAAD/AAAA5wAAAA2ysrIAv7+/EgAAAOQAAAD/AAAA/0BAQP//////////////
+ ////////////////////////+vr6/yMjI/8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/xcXF//x8fH/////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////ODg4/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AwMD/9fX
+ 1///////////////////////////////////////dHR0/wAAAP8AAAD/AAAA9wAAAB6ysrIAv7+/IQAA
+ APEAAAD/AAAA/1dXV///////////////////////////////////////6enp/w8PD/8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/1paWv////////////////////////////////////////////////////////////z8
+ /P/k5OT/9vb2////////////////////////////////////////////////////////////iIiI/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/7+/v///////////////////////////////////////jIyM/wAA
+ AP8AAAD/AAAA/wAAAC6ysrIAv7+/LwAAAPkAAAD/AAAA/2lpaf//////////////////////////////
+ ////////2dnZ/wQEBP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/5eXl///////////////////////////////
+ ////////////////////////tLS0/y8vL/8MDAz/IiIi/5aWlv//////////////////////////////
+ ////////////////////////w8PD/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/6qqqv//////////////
+ ////////////////////////np6e/wAAAP8AAAD/AAAA/wAAADuysrIAv7+/OgAAAP0AAAD/AAAA/3V1
+ df//////////////////////////////////////zMzM/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/76+
+ vv/////////////////////////////////////////////////S0tL/BwcH/wAAAP8AAAD/AAAA/wAA
+ AP+tra3/////////////////////////////////////////////////4uLi/woKCv8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/5ycnP//////////////////////////////////////qqqq/wAAAP8AAAD/AAAA/wAA
+ AEWysrIAv7+/PwAAAP8AAAD/AAAA/319ff//////////////////////////////////////xcXF/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/9DQ0P//////////////////////////////////////////////
+ //93d3f/AAAA/wAAAP8AAAD/AAAA/wAAAP9JSUn/////////////////////////////////////////
+ ////////8PDw/xYWFv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/5SUlP//////////////////////////////
+ ////////r6+v/wAAAP8AAAD/AAAA/wAAAEqysrIAv7+/QAAAAP8AAAD/AAAA/35+fv//////////////
+ ////////////////////////xMTE/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/9LS0v//////////////
+ //////////////////////////////////9tbW3/AAAA/wAAAP8AAAD/AAAA/wAAAP9AQED/////////
+ ////////////////////////////////////////8fHx/xgYGP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/5SU
+ lP//////////////////////////////////////sLCw/wAAAP8AAAD/AAAA/wAAAEqysrIAv7+/PQAA
+ AP4AAAD/AAAA/3l5ef//////////////////////////////////////ycnJ/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/8XFxf////////////////////////////////////////////////+7u7v/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP+QkJD/////////////////////////////////////////////////5+fn/w0N
+ Df8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/5ubm///////////////////////////////////////qqqq/wAA
+ AP8AAAD/AAAA/wAAAEWysrIAv7+/NAAAAPsAAAD/AAAA/25ubv//////////////////////////////
+ ////////1NTU/wEBAf8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/6SkpP//////////////////////////////
+ ////////////////////////hISE/woKCv8AAAD/AgIC/2JiYv/6+vr/////////////////////////
+ ////////////////////////zMzM/wEBAf8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/6mpqf//////////////
+ ////////////////////////n5+f/wAAAP8AAAD/AAAA/wAAADyysrIAv7+/JwAAAPQAAAD/AAAA/15e
+ Xv//////////////////////////////////////4+Pj/wsLC/8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/2xs
+ bP///////////////////////////////////////////////////////////9vb2/+1tbX/0NDQ////
+ ////////////////////////////////////////////////////////mJiY/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/729vf//////////////////////////////////////jY2N/wAAAP8AAAD/AAAA/wAA
+ AC+ysrIAv7+/GAAAAOoAAAD/AAAA/0lJSf//////////////////////////////////////9PT0/xsb
+ G/8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/yYmJv/7+/v/////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////S0tL/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AgIC/9XV1f//////////////////////////////
+ ////////dnZ2/wAAAP8AAAD/AAAA+AAAAB+ysrIAv7+/BwAAANkAAAD/AAAA/zExMf//////////////
+ /////////////////////////////zU1Nf8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP+4uLj/////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////d3d3/CQkJ/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/FBQU/+7u
+ 7v//////////////////////////////////////WVlZ/wAAAP8AAAD/AAAA6AAAAA6ysrIAv7+/AAAA
+ AMEAAAD/AAAA/xgYGP/y8vL//////////////////////////////////////1xcXP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP9AQED/////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////9paWn/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/MzMz////////////////////////////////////////////OTk5/wAA
+ AP8AAAD/AAAA0QAAAAGysrIAv7+/AAAAAKAAAAD/AAAA/wMDA//X19f/////////////////////////
+ /////////////4+Pj/8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/oqKi////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////8nJyf8FBQX/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/YmJi////////////////////
+ ///////////////////09PT/Ghoa/wAAAP8AAAD/AAAAsAAAAACysrIAv7+/AAAAAHYAAAD/AAAA/wAA
+ AP+vr6///////////////////////////////////////8bGxv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/EhIS/9fX1///////////////////////////////////////////////////////////////
+ ////////////////////////////////////////8PDw/yoqKv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/nJyc///////////////////////////////////////U1NT/AgIC/wAAAP8AAAD/AAAAhgAA
+ AACysrIAv7+/AAAAAEgAAAD/AAAA/wAAAP96enr///////////////////////////////////////T0
+ 9P8aGhr/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/ycnJ//h4eH/////////////////////////
+ ///////////////////////////////////////////////////////////////////19fX/RkZG/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8EBAT/2NjY////////////////////////////////////
+ //+lpaX/AAAA/wAAAP8AAAD/AAAAVQAAAACysrIAv7+/AAAAABwAAAD2AAAA/wAAAP9BQUH/////////
+ //////////////////////////////////9ZWVn/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8lJSX/y8vL////////////////////////////////////////////////////////////////////
+ /////////////+Hh4f8+Pj7/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8xMTH//v7+////
+ //////////////////////////////////9paWn/AAAA/wAAAP8AAAD7AAAAJgAAAACysrIAv7+/AAAA
+ AAEAAADPAAAA/wAAAP8QEBD/6+vr//////////////////////////////////////+srKz/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8DAwP/AAAA/wAAAP8AAAD/CwsL/4qKiv/29vb/////////////////////////
+ ////////////////////////////////////////oqKi/xoaGv8AAAD/AAAA/wAAAP8EBAT/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP9/f3////////////////////////////////////////39/f8tLS3/AAAA/wAA
+ AP8AAADYAAAABAAAAACysrIAv7+/AAAAAAAAAACRAAAA/wAAAP8AAAD/srKy////////////////////
+ ///////////////////y8vL/GBgY/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wQEBP8PDw//ExMT/wMDA/8AAAD/AAAA/wAA
+ AP8qKir/kJCQ/9/f3///////////////////////////////////////6Ojo/6CgoP85OTn/AAAA/wAA
+ AP8AAAD/AQEB/xISEv8SEhL/BgYG/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wQEBP/V1dX/////////////////////////
+ /////////////9bW1v8EBAT/AAAA/wAAAP8AAACcAAAAAAAAAACysrIAv7+/AAAAAAAAAABKAAAA/wAA
+ AP8AAAD/Y2Nj////////////////////////////////////////////cHBw/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AwMD/w0N
+ Df8XFxf/JCQk/ygoKP8PDw//AAAA/wAAAP8AAAD/AAAA/wsLC/86Ojr/Z2dn/4aGhv+RkZH/iYmJ/25u
+ bv9DQ0P/EhIS/wAAAP8AAAD/AAAA/wAAAP8LCwv/JSUl/ycnJ/8aGhr/Dw8P/wUFBf8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/0JC
+ Qv///////////////////////////////////////////46Ojv8AAAD/AAAA/wAAAP8AAABUAAAAAAAA
+ AACysrIAv7+/AAAAAAAAAAAPAAAA6QAAAP8AAAD/Ghoa//T09P//////////////////////////////
+ ////////19fX/wUFBf8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8DAwP/DAwM/xUVFf8gICD/Kioq/zY2Nv9AQED/Li4u/w0NDf8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/CQkJ/ykpKf9AQED/OTk5/yws
+ LP8iIiL/GBgY/w4ODv8FBQX/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/66urv///////////////////////////////////////////zs7
+ O/8AAAD/AAAA/wAAAPAAAAAVAAAAAAAAAACysrIAv7+/AAAAAAAAAAAAAAAAowAAAP8AAAD/AAAA/62t
+ rf///////////////////////////////////////////1hYWP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wICAv8LCwv/FBQU/x0dHf8nJyf/MDAw/zs7
+ O/9GRkb/VVVV/1lZWf9ERET/IyMj/woKCv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/BwcH/x8f
+ H/9AQED/WFhY/1hYWP9JSUn/PT09/zMzM/8pKSn/Hx8f/xYWFv8NDQ3/BAQE/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/LS0t//v7+///////////////
+ ////////////////////////1NTU/wQEBP8AAAD/AAAA/wAAAK4AAAAAAAAAAAAAAACysrIAv7+/AAAA
+ AAAAAAAAAAAASAAAAP8AAAD/AAAA/0pKSv///////////////////////////////////////////9PT
+ 0/8FBQX/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AgIC/woK
+ Cv8SEhL/Gxsb/yQkJP8tLS3/Nzc3/0FBQf9LS0v/VVVV/2JiYv9ycnL/fX19/3p6ev9vb2//YWFh/1lZ
+ Wf9XV1f/WFhY/19fX/9sbGz/eXl5/35+fv91dXX/ZWVl/1hYWP9NTU3/Q0ND/zk5Of8vLy//JiYm/x0d
+ Hf8UFBT/DAwM/wQEBP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/qamp////////////////////////////////////////////dXV1/wAAAP8AAAD/AAAA/wAA
+ AFMAAAAAAAAAAAAAAACysrIAv7+/AAAAAAAAAAAAAAAABwAAANwAAAD/AAAA/wUFBf/V1dX/////////
+ //////////////////////////////////9oaGj/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8CAgL/CQkJ/xEREf8ZGRn/IiIi/yoqKv8zMzP/PDw8/0ZGRv9QUFD/Wlpa/2Vl
+ Zf9wcHD/e3t7/4qKiv+ampr/qqqq/7m5uf/BwcH/vLy8/62trf+dnZ3/jY2N/35+fv9ycnL/Z2dn/1xc
+ XP9SUlL/SEhI/z4+Pv81NTX/LCws/yQkJP8bGxv/ExMT/wsLC/8DAwP/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP86Ojr//v7+////////////////////////////////////
+ ///x8fH/GRkZ/wAAAP8AAAD/AAAA5AAAAAsAAAAAAAAAAAAAAACysrIAv7+/AAAAAAAAAAAAAAAAAAAA
+ AHoAAAD/AAAA/wAAAP9nZ2f////////////////////////////////////////////p6en/FxcX/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wICAv8ICAj/EBAQ/xgYGP8gICD/KCgo/zAw
+ MP85OTn/QkJC/0tLS/9UVFT/Xl5e/2hoaP9zc3P/fn5+/4mJif+VlZX/oqKi/6+vr/+2trb/sbGx/6Sk
+ pP+Xl5f/i4uL/4CAgP91dXX/ampq/2BgYP9WVlb/TU1N/0NDQ/87Ozv/MjIy/yoqKv8iIiL/GRkZ/xIS
+ Ev8KCgr/AwMD/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wMDA//Jycn/////////
+ //////////////////////////////////+Wlpb/AAAA/wAAAP8AAAD/AAAAhgAAAAAAAAAAAAAAAAAA
+ AACysrIAv7+/AAAAAAAAAAAAAAAAAAAAABkAAADxAAAA/wAAAP8LCwv/39/f////////////////////
+ ////////////////////////pKSk/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AQEB/wgI
+ CP8PDw//FhYW/x4eHv8lJSX/LS0t/zU1Nf8+Pj7/RkZG/09PT/9ZWVn/YmJi/2xsbP92dnb/gICA/4yM
+ jP+Xl5f/o6Oj/6+vr/+2trb/sbGx/6Wlpf+ZmZn/jY2N/4KCgv94eHj/bm5u/2RkZP9aWlr/UVFR/0hI
+ SP9AQED/Nzc3/y8vL/8nJyf/ICAg/xgYGP8RERH/CQkJ/wMDA/8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/3R0dP////////////////////////////////////////////f39/8kJCT/AAAA/wAA
+ AP8AAAD3AAAAIQAAAAAAAAAAAAAAAAAAAACysrIAv7+/AAAAAAAAAAAAAAAAAAAAAAAAAACRAAAA/wAA
+ AP8AAAD/ZWVl/////////////////////////////////////////////////1paWv8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8BAQH/BwcH/w4ODv8VFRX/HBwc/yMjI/8rKyv/MjIy/zo6Ov9CQkL/S0tL/1NT
+ U/9cXFz/ZWVl/29vb/95eXn/g4OD/42Njf+YmJj/o6Oj/6+vr/+2trb/sbGx/6ampv+ampr/j4+P/4WF
+ hf96enr/cXFx/2dnZ/9eXl7/VVVV/0xMTP9ERET/PDw8/zQ0NP8sLCz/JSUl/x4eHv8WFhb/EBAQ/wkJ
+ Cf8CAgL/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/MDAw//b29v//////////////////////////////
+ /////////////5WVlf8AAAD/AAAA/wAAAP8AAACfAAAAAAAAAAAAAAAAAAAAAAAAAACysrIAv7+/AAAA
+ AAAAAAAAAAAAAAAAAAAAAAAfAAAA9AAAAP8AAAD/BgYG/9HR0f//////////////////////////////
+ /////////////+/v7/8oKCj/AAAA/wAAAP8AAAD/AAAA/wEBAf8HBwf/DQ0N/xQUFP8aGhr/IiIi/ykp
+ Kf8wMDD/Nzc3/z8/P/9HR0f/T09P/1dXV/9gYGD/aWlp/3Jycv97e3v/hYWF/4+Pj/+ZmZn/pKSk/7Cw
+ sP+2trb/sbGx/6ampv+bm5v/kZGR/4eHh/99fX3/c3Nz/2pqav9hYWH/WVlZ/1BQUP9ISEj/QEBA/zk5
+ Of8xMTH/Kioq/yMjI/8cHBz/FRUV/w8PD/8ICAj/AgIC/wAAAP8AAAD/AAAA/wAAAP8ODg7/09PT////
+ ////////////////////////////////////////7+/v/xoaGv8AAAD/AAAA/wAAAPkAAAAoAAAAAAAA
+ AAAAAAAAAAAAAAAAAACysrIAv7+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAigAAAP8AAAD/AAAA/0RE
+ RP/////////////////////////////////////////////////S0tL/EBAQ/wAAAP8AAAD/AAAA/wYG
+ Bv8NDQ3/EhIS/xkZGf8gICD/JiYm/y0tLf80NDT/PDw8/0NDQ/9LS0v/UlJS/1tbW/9jY2P/a2tr/3R0
+ dP99fX3/h4eH/5GRkf+ampr/paWl/7CwsP+2trb/srKy/6enp/+cnJz/kpKS/4mJif9/f3//dnZ2/21t
+ bf9lZWX/XFxc/1RUVP9MTEz/RUVF/z09Pf82Njb/Ly8v/ygoKP8hISH/Gxsb/xQUFP8ODg7/CAgI/wEB
+ Af8AAAD/AAAA/wAAAP+srKz/////////////////////////////////////////////////cnJy/wAA
+ AP8AAAD/AAAA/wAAAJkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrIAv7+/AAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAEwAAAOgAAAD/AAAA/wAAAP+goKD/////////////////////////////////////////
+ ////////t7e3/wYGBv8AAAD/AAAA/wMDA/8RERH/GRkZ/x4eHv8lJSX/Kysr/zIyMv85OTn/QEBA/0dH
+ R/9OTk7/VlZW/15eXv9mZmb/bm5u/3d3d/9/f3//iYmJ/5KSkv+cnJz/pqam/7CwsP+2trb/srKy/6io
+ qP+dnZ3/lJSU/4qKiv+BgYH/eHh4/3BwcP9oaGj/YGBg/1hYWP9QUFD/SEhI/0FBQf86Ojr/MzMz/yws
+ LP8mJib/ICAg/xoaGv8TExP/BQUF/wAAAP8AAAD/AAAA/4+Pj///////////////////////////////
+ ///////////////////Ly8v/BQUF/wAAAP8AAAD/AAAA7wAAABsAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AACysrIAv7+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGMAAAD/AAAA/wAAAP8UFBT/4+Pj////
+ /////////////////////////////////////////////6ioqP8DAwP/AAAA/wAAAP8EBAT/GRkZ/yUl
+ Jf8pKSn/Ly8v/zY2Nv89PT3/RERE/0pKSv9SUlL/WVlZ/2FhYf9paWn/cXFx/3l5ef+BgYH/ioqK/5OT
+ k/+dnZ3/pqam/7CwsP+2trb/srKy/6ioqP+enp7/lZWV/4yMjP+Dg4P/e3t7/3Jycv9qamr/YmJi/1tb
+ W/9TU1P/TExM/0VFRf8+Pj7/Nzc3/zExMf8qKir/JiYm/x0dHf8HBwf/AAAA/wAAAP8AAAD/goKC////
+ //////////////////////////////////////////////n5+f8zMzP/AAAA/wAAAP8AAAD/AAAAcwAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrIAv7+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAEAAAC+AAAA/wAAAP8AAAD/SEhI////////////////////////////////////////////////////
+ //+pqan/BwcH/wAAAP8AAAD/AwMD/xwcHP8wMDD/NDQ0/zo6Ov9AQED/R0dH/05OTv9VVVX/XV1d/2Rk
+ ZP9ra2v/c3Nz/3t7e/+Dg4P/jIyM/5SUlP+enp7/p6en/7CwsP+2trb/srKy/6ioqP+fn5//lpaW/42N
+ jf+FhYX/fX19/3V1df9tbW3/ZWVl/15eXv9XV1f/T09P/0hISP9CQkL/Ozs7/zU1Nf8yMjL/ISEh/wYG
+ Bv8AAAD/AAAA/wAAAP+Hh4f//////////////////////////////////////////////////////3V1
+ df8AAAD/AAAA/wAAAP8AAADLAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrIAv7+/AAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAnAAAA8wAAAP8AAAD/AAAA/4ODg///////////////
+ ////////////////////////////////////////uLi4/xQUFP8AAAD/AAAA/wAAAP8WFhb/NjY2/0FB
+ Qf9ERET/SkpK/1FRUf9YWFj/X19f/2ZmZv9ubm7/dXV1/319ff+FhYX/jY2N/5aWlv+enp7/p6en/7Cw
+ sP+2trb/srKy/6mpqf+goKD/l5eX/4+Pj/+Hh4f/fn5+/3d3d/9vb2//aGho/2FhYf9aWlr/U1NT/0xM
+ TP9FRUX/QkJC/zo6Ov8cHBz/AgIC/wAAAP8AAAD/BgYG/5ubm///////////////////////////////
+ ////////////////////////r6+v/wAAAP8AAAD/AAAA/wAAAPkAAAAzAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAACysrIAv7+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZwAA
+ AP8AAAD/AAAA/wICAv+ysrL//////////////////////////////////////////////////////9TU
+ 1P8xMTH/AAAA/wAAAP8AAAD/CgoK/y4uLv9KSkr/UVFR/1RUVP9bW1v/YmJi/2lpaf9wcHD/d3d3/39/
+ f/+Hh4f/j4+P/5eXl/+fn5//qKio/7Gxsf+2trb/srKy/6mpqf+hoaH/mJiY/5CQkP+IiIj/gICA/3l5
+ ef9ycnL/ampq/2NjY/9cXFz/VlZW/1JSUv9NTU3/NTU1/w8PD/8AAAD/AAAA/wAAAP8eHh7/vb29////
+ ///////////////////////////////////////////////////V1dX/ERER/wAAAP8AAAD/AAAA/wAA
+ AHcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrIAv7+/AAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKUAAAD/AAAA/wAAAP8QEBD/zs7O////////////////////
+ ///////////////////////////////////y8vL/ZmZm/wAAAP8AAAD/AAAA/wAAAP8WFhb/Pz8//1tb
+ W/9jY2P/ZmZm/2tra/9ycnL/eXl5/4GBgf+IiIj/kJCQ/5iYmP+goKD/qKio/7Gxsf+2trb/srKy/6qq
+ qv+hoaH/mZmZ/5GRkf+Kior/goKC/3t7e/90dHT/bW1t/2ZmZv9kZGT/XV1d/0VFRf8dHR3/AQEB/wAA
+ AP8AAAD/AAAA/1BQUP/k5OT//////////////////////////////////////////////////////+np
+ 6f8oKCj/AAAA/wAAAP8AAAD/AAAAtAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AACysrIAv7+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAADRAAAA/wAA
+ AP8AAAD/Hh4e/9zc3P///////////////////////////////////////////////////////////66u
+ rv8lJSX/AAAA/wAAAP8AAAD/AAAA/xoaGv9DQ0P/ZGRk/3R0dP96enr/fX19/4KCgv+JiYn/kZGR/5mZ
+ mf+hoaH/qamp/7Gxsf+2trb/srKy/6qqqv+ioqL/mpqa/5KSkv+Li4v/hISE/35+fv96enr/dnZ2/2ho
+ aP9JSUn/ICAg/wICAv8AAAD/AAAA/wAAAP8YGBj/mpqa////////////////////////////////////
+ ////////////////////////8vLy/zo6Ov8AAAD/AAAA/wAAAP8AAADbAAAAFQAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrIAv7+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAlAAAA6QAAAP8AAAD/AAAA/ycnJ//g4OD/////////////////////////
+ ///////////////////////////////////w8PD/fX19/xAQEP8AAAD/AAAA/wAAAP8AAAD/Dw8P/zIy
+ Mv9YWFj/dnZ2/4mJif+UlJT/mpqa/5+fn/+mpqb/rKys/7S0tP+5ubn/tbW1/62trf+np6f/oKCg/5ub
+ m/+VlZX/i4uL/3p6ev9eXl7/ODg4/xMTE/8AAAD/AAAA/wAAAP8AAAD/CAgI/2tra//k5OT/////////
+ ///////////////////////////////////////////////////z8/P/Q0ND/wAAAP8AAAD/AAAA/wAA
+ APAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrIAv7+/AAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPQAAAPUAAAD/AAAA/wAA
+ AP8nJyf/2tra/////////////////////////////////////////////////////////////////9/f
+ 3/9ycnL/FBQU/wAAAP8AAAD/AAAA/wAAAP8AAAD/DQ0N/ycnJ/9FRUX/YmJi/3t7e/+Ojo7/nZ2d/6qq
+ qv+vr6//q6ur/6Ghof+SkpL/f39//2dnZ/9LS0v/LCws/xEREf8AAAD/AAAA/wAAAP8AAAD/AAAA/wwM
+ DP9jY2P/09PT/////////////////////////////////////////////////////////////////+7u
+ 7v9BQUH/AAAA/wAAAP8AAAD/AAAA+gAAAEkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAACysrIAv7+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAE0AAAD5AAAA/wAAAP8AAAD/Hh4e/8rKyv//////////////////////////////
+ ////////////////////////////////////////5ubm/4+Pj/80NDT/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8GBgb/Dg4O/xQUFP8UFBT/FBQU/w8PD/8HBwf/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8qKir/gYGB/93d3f//////////////////////////////////////////////
+ ////////////////////////39/f/zMzM/8AAAD/AAAA/wAAAP8AAAD9AAAAWAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrIAv7+/AAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSAAAA+QAAAP8AAAD/AAAA/w8P
+ D/+rq6v/////////////////////////////////////////////////////////////////////////
+ ////////y8vL/4GBgf89PT3/Dw8P/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/woKCv80NDT/dnZ2/8HBwf/6+vr/////////////////////////
+ ///////////////////////////////////////////////////CwsL/Hh4e/wAAAP8AAAD/AAAA/wAA
+ APwAAABdAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AACysrIAv7+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAATAAAAPMAAAD/AAAA/wAAAP8AAAD/fX19//39/f//////////////////////////////
+ ////////////////////////////////////////////////////////5ubm/7u7u/+NjY3/ZGRk/0VF
+ Rf8vLy//ISEh/xkZGf8WFhb/GBgY/x8fH/8sLCz/QEBA/15eXv+FhYX/s7Oz/+Dg4P//////////////
+ /////////////////////////////////////////////////////////////////////////////5SU
+ lP8ICAj/AAAA/wAAAP8AAAD/AAAA9wAAAFUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrIAv7+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADsAAADkAAAA/wAAAP8AAAD/AAAA/0RE
+ RP/Y2Nj/////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////+Pj4//Hx8f/v7+//8PDw//b29v/+/v7/////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////l5eX/V1dX/wAAAP8AAAD/AAAA/wAAAP8AAADpAAAAQgAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrIAv7+/AAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAkAAAAyAAAAP8AAAD/AAAA/wAAAP8RERH/kpKS//39/f//////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////6Ojo/8cHBz/AAAA/wAAAP8AAAD/AAAA/wAA
+ AM0AAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAACysrIAv7+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAJsAAAD/AAAA/wAAAP8AAAD/AAAA/zs7
+ O/++vr7/////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////Ly8v/SUlJ/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAAnwAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrIAv7+/AAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAABeAAAA6gAAAP8AAAD/AAAA/wAAAP8AAAD/VVVV/8rKyv//////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////1NTU/2JiYv8EBAT/AAAA/wAAAP8AAAD/AAAA/wAAAOwAAABhAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AACysrIAv7+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIQAAAKwAAAD/AAAA/wAAAP8AAAD/AAAA/wMD
+ A/9RUVH/u7u7//7+/v//////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////8XFxf9dXV3/CAgI/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAArgAA
+ ACMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrIAv7+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAABUAAAA1QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/zMzM/+NjY3/3Nzc////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////+Pj4/+YmJj/PT09/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAANYAAABVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrIAv7+/AAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAHMAAADiAAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/CQkJ/0JCQv+Li4v/zMzM//b29v//////////////////////////////////////////////
+ ////////////////////////////////////////////////////////+vr6/9PT0/+VlZX/S0tL/w8P
+ D/8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADiAAAAcwAAAAsAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAACysrIAv7+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAASAAAAdAAAANoAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/yAgIP9PT0//gYGB/6ys
+ rP/Ozs7/5ubm//b29v//////////////////////////////////////+Pj4/+rq6v/T09P/s7Oz/4iI
+ iP9XV1f/Jycn/wMDA/8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA2gAAAHQAAAATAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrIAv7+/AAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsAAABZAAAAugAAAPoAAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/Dg4O/x8fH/8uLi7/Ojo6/0JCQv9GRkb/RERE/z09
+ Pf8xMTH/IiIi/xEREf8CAgL/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+gAA
+ ALoAAABaAAAACwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AACysrIAv7+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAACoAAAB5AAAAxgAAAPgAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA+QAAAMcAAAB6AAAAKwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrIAvr6+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACUAAABhAAAAoAAA
+ ANMAAAD1AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8AAAD2AAAA1AAAAKIAAABjAAAAJgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwsLAAyMjIACIi
+ IgAiIiIAIiIiACIiIgAiIiIAIiIiACIiIgAiIiIAIiIiACIiIgAiIiIAIiIiACIiIgAiIiIAIiIiACIi
+ IgAiIiIAIiIiACIiIgAiIiIAIiIiACIiIgAiIiIAIiIiACIiIgAiIiIAIiIiACIiIgAiIiIAIiIiACIi
+ IgAiIiIAIiIiACIiIgAiIiIAIiIiACIiIgIiIiIeIiIiQSIiImciIiKJIiIipiIiIrwiIiLLIiIi1SIi
+ ItsiIiLdIiIi3CIiItYiIiLMIiIivSIiIqgiIiKLIiIiaSIiIkMiIiIfIiIiAyIiIgAiIiIAIiIiACIi
+ IgAiIiIAIiIiACIiIgAiIiIAIiIiACIiIgAiIiIAIiIiACIiIgAiIiIAIiIiACIiIgAiIiIAIiIiACIi
+ IgAiIiIAIiIiACIiIgAiIiIAIiIiACIiIgAiIiIAIiIiACIiIgAiIiIAIiIiACIiIgAiIiIAIiIiACIi
+ IgAiIiIAIiIiACIiIgC9vb0A/Pz8APT09AD09PQA9PT0APT09AD09PQA9PT0APT09AD09PQA9PT0APT0
+ 9AD09PQA9PT0APT09AD09PQA9PT0APT09AD09PQA9PT0APT09AD09PQA9PT0APT09AD09PQA9PT0APT0
+ 9AD09PQA9PT0APT09AD09PQA9PT0APT09AD09PQA9PT0APT09AD09PQA9PT0APT09AD09PQA9PT0APT0
+ 9AD09PQA9PT0APT09AD09PQA9PT0BfT09Ar09PQL9PT0CvT09Ab09PQA9PT0APT09AD09PQA9PT0APT0
+ 9AD09PQA9PT0APT09AD09PQA9PT0APT09AD09PQA9PT0APT09AD09PQA9PT0APT09AD09PQA9PT0APT0
+ 9AD09PQA9PT0APT09AD09PQA9PT0APT09AD09PQA9PT0APT09AD09PQA9PT0APT09AD09PQA9PT0APT0
+ 9AD09PQA9PT0APT09AD09PQA9PT0APT09AD09PQA9PT0APT09AD8/PwA/////////////+P///////4A
+ AP///8H//////8AAAAf//4D//////gAAAAD//wB/////+AAAAAA//gA/////4AAAAAAP/AAf////gAAA
+ AAAD+AAP///+AAAAAAAA8AAH///4AAAAAAAAIAAD///wAAAAAAAAAAAA///gAAAAAAAAAAAA//+AAAAA
+ AAAAAAAB//8AAAAAAAAAAAAD//4AAAAAAAAAAAAH//wAAAAAAAAAAAAP//gAAAAAAAAAAAAf//AAAAAA
+ AAAAAAA//+AAAAAAAAAAAAB//+AAAAAAAAAAAAD//8AAAAAAAAAAAAH//4AAAAAAAAAAAAP//wAAAAAA
+ AAAAAAH//wAAAAAAAAAAAAH//gAAAAAAAAAAAAD//AAAAAAAAAAAAAB//AAAAAAAAAAAAAB/+AAAAAAA
+ AAAAAAA/+AAAAAAAAAAAAAA/8AAAAAAAAAAAAAAf8AAAAAAAAAAAAAAf8AAAAAAAAAAAAAAP4AAAAAAA
+ AAAAAAAP4AAAAAAAAAAAAAAPwAAAAAAAAAAAAAAHwAAAAAAAAAAAAAAHwAAAAAAAAAAAAAAHwAAAAAAA
+ AAAAAAADgAAAAAAAAAAAAAADgAAAAAAAAAAAAAADgAAAAAAAAAAAAAADgAAAAAAAAAAAAAADgAAAAAAA
+ AAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAA
+ AAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAA
+ AAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABgAAAAAAAAAAAAAABgAAAAAAAAAAAAAADgAAAAAAA
+ AAAAAAADgAAAAAAAAAAAAAADgAAAAAAAAAAAAAADgAAAAAAAAAAAAAADwAAAAAAAAAAAAAAHwAAAAAAA
+ AAAAAAAHwAAAAAAAAAAAAAAH4AAAAAAAAAAAAAAP4AAAAAAAAAAAAAAP4AAAAAAAAAAAAAAP8AAAAAAA
+ AAAAAAAf8AAAAAAAAAAAAAAf+AAAAAAAAAAAAAA/+AAAAAAAAAAAAAA//AAAAAAAAAAAAAB//AAAAAAA
+ AAAAAAB//gAAAAAAAAAAAAD//gAAAAAAAAAAAAD//wAAAAAAAAAAAAH//4AAAAAAAAAAAAP//8AAAAAA
+ AAAAAAP//8AAAAAAAAAAAAf//+AAAAAAAAAAAA////AAAAAAAAAAAB////gAAAAAAAAAAD////wAAAAA
+ AAAAAH////4AAAAAAAAAAP////8AAAAAAAAAAf////+AAAAAAAAAA//////AAAAAAAAAB//////wAAAA
+ AAAAH//////4AAAAAAAAP//////+AAAAAAAA////////AAAAAAAB////////wAAAAAAH////////8AAA
+ AAAf/////////gAAAAD//////////8AAAAf///////////gAAD/////////////4P///////
+
+
+
\ No newline at end of file
diff --git a/QobuzDownloaderX/Form1.Designer.cs b/QobuzDownloaderX/Form1.Designer.cs
index ce78c6b..b1dd146 100644
--- a/QobuzDownloaderX/Form1.Designer.cs
+++ b/QobuzDownloaderX/Form1.Designer.cs
@@ -106,6 +106,7 @@
this.artSizeSelect = new System.Windows.Forms.ComboBox();
this.artSizeLabel = new System.Windows.Forms.Label();
this.typeCheckbox = new System.Windows.Forms.CheckBox();
+ this.aboutLabel = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.albumArtPicBox)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.logoBox)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.profilePictureBox)).BeginInit();
@@ -982,12 +983,29 @@
this.typeCheckbox.UseVisualStyleBackColor = true;
this.typeCheckbox.CheckedChanged += new System.EventHandler(this.typeCheckbox_CheckedChanged);
//
+ // aboutLabel
+ //
+ this.aboutLabel.AutoSize = true;
+ this.aboutLabel.BackColor = System.Drawing.Color.Transparent;
+ this.aboutLabel.Font = new System.Drawing.Font("Calibri", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.aboutLabel.ForeColor = System.Drawing.Color.White;
+ this.aboutLabel.Location = new System.Drawing.Point(866, 8);
+ this.aboutLabel.Name = "aboutLabel";
+ this.aboutLabel.Size = new System.Drawing.Size(15, 23);
+ this.aboutLabel.TabIndex = 99;
+ this.aboutLabel.Text = "i";
+ this.aboutLabel.TextAlign = System.Drawing.ContentAlignment.TopCenter;
+ this.aboutLabel.Click += new System.EventHandler(this.aboutLabel_Click);
+ this.aboutLabel.MouseLeave += new System.EventHandler(this.aboutLabel_MouseLeave);
+ this.aboutLabel.MouseHover += new System.EventHandler(this.aboutLabel_MouseHover);
+ //
// QobuzDownloaderX
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(20)))), ((int)(((byte)(20)))), ((int)(((byte)(20)))));
this.ClientSize = new System.Drawing.Size(938, 733);
+ this.Controls.Add(this.aboutLabel);
this.Controls.Add(this.typeCheckbox);
this.Controls.Add(this.artSizeSelect);
this.Controls.Add(this.artSizeLabel);
@@ -1151,6 +1169,7 @@
private System.Windows.Forms.ComboBox artSizeSelect;
private System.Windows.Forms.Label artSizeLabel;
private System.Windows.Forms.CheckBox typeCheckbox;
+ private System.Windows.Forms.Label aboutLabel;
}
}
diff --git a/QobuzDownloaderX/Form1.cs b/QobuzDownloaderX/Form1.cs
index ed14935..ff6058b 100644
--- a/QobuzDownloaderX/Form1.cs
+++ b/QobuzDownloaderX/Form1.cs
@@ -21,6 +21,7 @@ using System.Drawing.Imaging;
using TagLib;
using TagLib.Flac;
using TagLib.Id3v2;
+using Newtonsoft.Json.Linq;
using System.Globalization;
using System.Threading;
@@ -33,6 +34,8 @@ namespace QobuzDownloaderX
InitializeComponent();
}
+ AboutForm about = new AboutForm();
+
public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HT_CAPTION = 0x2;
@@ -50,8 +53,6 @@ namespace QobuzDownloaderX
public string userID { get; set; }
public string accountType { get; set; }
public string appSecret { get; set; }
- public string albumId { get; set; }
- public string trackIdString { get; set; }
public string formatIdString { get; set; }
public string audioFileType { get; set; }
public string trackRequest { get; set; }
@@ -61,6 +62,56 @@ namespace QobuzDownloaderX
public int MaxLength { get; set; }
public int devClickEggThingValue { get; set; }
+ // Important strings
+ public string loc { get; set; }
+ public string fullLoc { get; set; }
+ public string fullLocVersion { get; set; }
+ public string qualityPath { get; set; }
+ public string stream { get; set; }
+ public string type { get; set; }
+ public string userAgent { get; set; }
+ public string path1Full { get; set; }
+ public string path2Full { get; set; }
+ public string path3Full { get; set; }
+ public string path4Full { get; set; }
+ public string path5Full { get; set; }
+ public string path6Full { get; set; }
+
+
+ // Info / Tagging strings
+ public string albumId { get; set; }
+ public string trackIdString { get; set; }
+ public string versionName { get; set; }
+ public string advisory { get; set; }
+ public string albumArtist { get; set; }
+ public string albumName { get; set; }
+ public string performerName { get; set; }
+ public string composerName { get; set; }
+ public string trackName { get; set; }
+ public string copyright { get; set; }
+ public string genre { get; set; }
+ public string releaseDate { get; set; }
+ public string isrc { get; set; }
+ public string upc { get; set; }
+ public string frontCoverImg { get; set; }
+ public string frontCoverImgBox { get; set; }
+ public string goodiesPDF { get; set; }
+
+ // Info strings for creating paths
+ public string albumArtistPath { get; set; }
+ public string albumNamePath { get; set; }
+ public string performerNamePath { get; set; }
+ public string trackNamePath { get; set; }
+ public string versionNamePath { get; set; }
+
+ // Info / Tagging ints
+ public int discNumber { get; set; }
+ public int discTotal { get; set; }
+ public int trackNumber { get; set; }
+ public int trackTotal { get; set; }
+
+ public string discFolder { get; set; }
+
searchForm searchF = new searchForm();
private void Form1_Load(object sender, EventArgs e)
@@ -78,18 +129,21 @@ namespace QobuzDownloaderX
// Show account type if user logged in normally.
if (accountType == null | accountType == "")
{
- output.Invoke(new Action(() => output.AppendText("\r\n")));
+ output.Invoke(new Action(() => output.AppendText("\r\n")));
}
else
{
output.Invoke(new Action(() => output.AppendText("Qobuz Account Type - " + accountType + "\r\n\r\n")));
}
-
+
output.Invoke(new Action(() => output.AppendText("Your user_auth_token has been set for this session!")));
// Get and display version number.
verNumLabel.Text = Assembly.GetExecutingAssembly().GetName().Version.ToString();
+ // Set user agent for web requests (HttpClient, etc)
+ userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0";
+
// Set app_id & auth_token for the Search Form
searchF.appid = appid;
searchF.userAuth = userAuth;
@@ -154,7 +208,7 @@ namespace QobuzDownloaderX
// Run anything put into the debug events (For Testing)
debuggingEvents(sender, e);
}
-
+
private void debuggingEvents(object sender, EventArgs e)
{
#region Debug Events, For Testing
@@ -187,7 +241,8 @@ namespace QobuzDownloaderX
return Regex.Replace(
value,
@"\\u(?[a-zA-Z0-9]{4})",
- m => {
+ m =>
+ {
return ((char)int.Parse(m.Groups["Value"].Value, NumberStyles.HexNumber)).ToString();
});
}
@@ -297,6 +352,9 @@ namespace QobuzDownloaderX
{
testURLBox.Invoke(new Action(() => testURLBox.AppendText(string.Format("{0}", m.Value))));
}
+
+ // Set stream string to streaming URL
+ stream = testURLBox.Text;
}
catch (Exception ex)
{
@@ -305,11 +363,7 @@ namespace QobuzDownloaderX
output.Invoke(new Action(() => output.Text = String.Empty));
output.Invoke(new Action(() => output.AppendText("Failed to get streaming URL. Error information below.\r\n\r\n")));
output.Invoke(new Action(() => output.AppendText(getError)));
- mp3Checkbox.Invoke(new Action(() => mp3Checkbox.Visible = true));
- flacLowCheckbox.Invoke(new Action(() => flacLowCheckbox.Visible = true));
- flacMidCheckbox.Invoke(new Action(() => flacMidCheckbox.Visible = true));
- flacHighCheckbox.Invoke(new Action(() => flacHighCheckbox.Visible = true));
- downloadButton.Invoke(new Action(() => downloadButton.Enabled = true));
+ enableBoxes(sender, e);
return;
}
}
@@ -317,20 +371,35 @@ namespace QobuzDownloaderX
{
// If the hash can't be verified.
output.Invoke(new Action(() => output.AppendText("The hash can't be verified. Please retry.\r\n")));
- mp3Checkbox.Invoke(new Action(() => mp3Checkbox.Visible = true));
- flacLowCheckbox.Invoke(new Action(() => flacLowCheckbox.Visible = true));
- flacMidCheckbox.Invoke(new Action(() => flacMidCheckbox.Visible = true));
- flacHighCheckbox.Invoke(new Action(() => flacHighCheckbox.Visible = true));
- downloadButton.Invoke(new Action(() => downloadButton.Enabled = true));
+ enableBoxes(sender, e);
return;
}
}
}
+ private void disableBoxes(object sender, EventArgs e)
+ {
+ mp3Checkbox.Invoke(new Action(() => mp3Checkbox.Visible = false));
+ flacLowCheckbox.Invoke(new Action(() => flacLowCheckbox.Visible = false));
+ flacMidCheckbox.Invoke(new Action(() => flacMidCheckbox.Visible = false));
+ flacHighCheckbox.Invoke(new Action(() => flacHighCheckbox.Visible = false));
+ downloadButton.Invoke(new Action(() => downloadButton.Enabled = false));
+ }
+
+ private void enableBoxes(object sender, EventArgs e)
+ {
+ mp3Checkbox.Invoke(new Action(() => mp3Checkbox.Visible = true));
+ flacLowCheckbox.Invoke(new Action(() => flacLowCheckbox.Visible = true));
+ flacMidCheckbox.Invoke(new Action(() => flacMidCheckbox.Visible = true));
+ flacHighCheckbox.Invoke(new Action(() => flacHighCheckbox.Visible = true));
+ downloadButton.Invoke(new Action(() => downloadButton.Enabled = true));
+ }
+
#region Choosing / Opening folder
private void selectFolder_Click(object sender, EventArgs e)
{
- Thread t = new Thread((ThreadStart)(() => {
+ Thread t = new Thread((ThreadStart)(() =>
+ {
// Open Folder Browser to select path & Save the selection
folderBrowserDialog.ShowDialog();
Settings.Default.savedFolder = folderBrowserDialog.SelectedPath;
@@ -371,11 +440,7 @@ namespace QobuzDownloaderX
#region Getting Type of URL
private void getLinkTypeBG_DoWork(object sender, DoWorkEventArgs e)
{
- mp3Checkbox.Invoke(new Action(() => mp3Checkbox.Visible = false));
- flacLowCheckbox.Invoke(new Action(() => flacLowCheckbox.Visible = false));
- flacMidCheckbox.Invoke(new Action(() => flacMidCheckbox.Visible = false));
- flacHighCheckbox.Invoke(new Action(() => flacHighCheckbox.Visible = false));
- downloadButton.Invoke(new Action(() => downloadButton.Enabled = false));
+ disableBoxes(sender, e);
// Check if there's no selected path.
if (folderBrowserDialog.SelectedPath == null | folderBrowserDialog.SelectedPath == "")
@@ -383,11 +448,7 @@ namespace QobuzDownloaderX
// If there is NOT a saved path.
output.Invoke(new Action(() => output.Text = String.Empty));
output.Invoke(new Action(() => output.AppendText("No path has been set! Remember to Choose a Folder!\r\n")));
- mp3Checkbox.Invoke(new Action(() => mp3Checkbox.Visible = true));
- flacLowCheckbox.Invoke(new Action(() => flacLowCheckbox.Visible = true));
- flacMidCheckbox.Invoke(new Action(() => flacMidCheckbox.Visible = true));
- flacHighCheckbox.Invoke(new Action(() => flacHighCheckbox.Visible = true));
- downloadButton.Invoke(new Action(() => downloadButton.Enabled = true));
+ enableBoxes(sender, e);
return;
}
@@ -429,11 +490,7 @@ namespace QobuzDownloaderX
{
output.Invoke(new Action(() => output.Text = String.Empty));
output.Invoke(new Action(() => output.AppendText("Downloading favorites only works on favorite albums at the moment. More options will be added in the future.\r\n\r\nIf you'd like to go ahead and grab your favorite albums, paste this link in the URL section - https://play.qobuz.com/user/library/favorites/albums")));
- mp3Checkbox.Invoke(new Action(() => mp3Checkbox.Visible = true));
- flacLowCheckbox.Invoke(new Action(() => flacLowCheckbox.Visible = true));
- flacMidCheckbox.Invoke(new Action(() => flacMidCheckbox.Visible = true));
- flacHighCheckbox.Invoke(new Action(() => flacHighCheckbox.Visible = true));
- downloadButton.Invoke(new Action(() => downloadButton.Enabled = true));
+ enableBoxes(sender, e);
return;
}
}
@@ -441,12 +498,8 @@ namespace QobuzDownloaderX
{
// Say what isn't available at the moment.
output.Invoke(new Action(() => output.Text = String.Empty));
- output.Invoke(new Action(() => output.AppendText("Downloading playlists or artists is not available right now. Maybe in the future. Sorry.")));
- mp3Checkbox.Invoke(new Action(() => mp3Checkbox.Visible = true));
- flacLowCheckbox.Invoke(new Action(() => flacLowCheckbox.Visible = true));
- flacMidCheckbox.Invoke(new Action(() => flacMidCheckbox.Visible = true));
- flacHighCheckbox.Invoke(new Action(() => flacHighCheckbox.Visible = true));
- downloadButton.Invoke(new Action(() => downloadButton.Enabled = true));
+ output.Invoke(new Action(() => output.AppendText("Downloading playlists is not available right now. Maybe in the future. Sorry.")));
+ enableBoxes(sender, e);
return;
}
else
@@ -454,11 +507,7 @@ namespace QobuzDownloaderX
// Say what isn't available at the moment.
output.Invoke(new Action(() => output.Text = String.Empty));
output.Invoke(new Action(() => output.AppendText("URL not understood. Is there a typo?")));
- mp3Checkbox.Invoke(new Action(() => mp3Checkbox.Visible = true));
- flacLowCheckbox.Invoke(new Action(() => flacLowCheckbox.Visible = true));
- flacMidCheckbox.Invoke(new Action(() => flacMidCheckbox.Visible = true));
- flacHighCheckbox.Invoke(new Action(() => flacHighCheckbox.Visible = true));
- downloadButton.Invoke(new Action(() => downloadButton.Enabled = true));
+ enableBoxes(sender, e);
return;
}
}
@@ -469,33 +518,49 @@ namespace QobuzDownloaderX
private async void downloadDiscogBG_DoWork(object sender, DoWorkEventArgs e)
{
#region If URL has "artist"
- string loc = folderBrowserDialog.SelectedPath;
+ // Set "loc" as the selected path.
+ String loc = folderBrowserDialog.SelectedPath;
- trackIdString = albumId;
+ // Create HttpClient to grab Favorites ID
+ var artistClient = new HttpClient();
+ // Run through TLS to allow secure connection.
+ ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
+ // Set user-agent to Firefox.
+ artistClient.DefaultRequestHeaders.Add("User-Agent", userAgent);
+ // Set referer to localhost that mora qualitas uses
+ artistClient.DefaultRequestHeaders.Add("Referer", "https://play.qobuz.com/album/" + albumId);
- WebRequest artistwr = WebRequest.Create("https://www.qobuz.com/api.json/0.2/artist/get?artist_id=" + albumId + "&extra=albums%2Cfocus&offset=0&limit=500&sort=release_desc&app_id=" + appid + "&user_auth_token=" + userAuth);
-
- // Empty output, then say Starting Downloads.
+ // Empty output, then say Grabbing IDs.
output.Invoke(new Action(() => output.Text = String.Empty));
output.Invoke(new Action(() => output.AppendText("Grabbing Album IDs...\r\n\r\n")));
try
{
- WebResponse artistws = artistwr.GetResponse();
- StreamReader artistsr = new StreamReader(artistws.GetResponseStream());
+ // Grab response from Qobuz to get Track IDs from Album response.
+ var artistUrl = "https://www.qobuz.com/api.json/0.2/artist/get?artist_id=" + albumId + "&extra=albums%2Cfocus&offset=0&limit=9999999999&sort=release_desc&app_id=" + appid + "&user_auth_token=" + userAuth;
+ var artistResponse = await artistClient.GetAsync(artistUrl);
+ string artistResponseString = artistResponse.Content.ReadAsStringAsync().Result;
- string artistRequest = artistsr.ReadToEnd();
+ // Grab all Album IDs listed on the API.
+ string artistAlbumIDspattern = ",\"maximum_channel_count\":(?.*?),\"id\":\"(?.*?)\",";
+ string artistAlbumIDsInput = artistResponseString;
+ RegexOptions artistAlbumIDsOptions = RegexOptions.Multiline;
- // Grab all Track IDs listed on the API.
- string artistAlbumIdspattern = ",\"maximum_channel_count\":(?.*?),\"id\":\"(?.*?)\",";
- string input = artistRequest;
- RegexOptions options = RegexOptions.Multiline;
-
- foreach (Match m in Regex.Matches(input, artistAlbumIdspattern, options))
+ foreach (Match m in Regex.Matches(artistAlbumIDsInput, artistAlbumIDspattern, artistAlbumIDsOptions))
{
- string albumIdDiscog = string.Format("{0}", m.Groups["albumIds"].Value);
+ // Make sure buttons are disabled during downloads.
+ disableBoxes(sender, e);
- WebRequest wr = WebRequest.Create("https://www.qobuz.com/api.json/0.2/album/get?album_id=" + albumIdDiscog + "&app_id=" + appid + "&user_auth_token=" + userAuth);
+ string albumIDArtist = string.Format("{0}", m.Groups["albumIds"].Value);
+
+ // Create HttpClient to grab Album ID
+ var albumIDClient = new HttpClient();
+ // Run through TLS to allow secure connection.
+ ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
+ // Set user-agent to Firefox.
+ albumIDClient.DefaultRequestHeaders.Add("User-Agent", userAgent);
+ // Set referer to localhost that mora qualitas uses
+ albumIDClient.DefaultRequestHeaders.Add("Referer", "https://play.qobuz.com/album/" + albumIDArtist);
// Empty output, then say Starting Downloads.
output.Invoke(new Action(() => output.Text = String.Empty));
@@ -503,299 +568,235 @@ namespace QobuzDownloaderX
try
{
- // Make sure buttons are disabled during downloads.
- mp3Checkbox.Invoke(new Action(() => mp3Checkbox.Visible = false));
- flacLowCheckbox.Invoke(new Action(() => flacLowCheckbox.Visible = false));
- flacMidCheckbox.Invoke(new Action(() => flacMidCheckbox.Visible = false));
- flacHighCheckbox.Invoke(new Action(() => flacHighCheckbox.Visible = false));
- downloadButton.Invoke(new Action(() => downloadButton.Enabled = false));
+ // Grab response from Qobuz to get Track IDs from Album response.
+ var albumIDUrl = "https://www.qobuz.com/api.json/0.2/album/get?album_id=" + albumIDArtist + "&app_id=" + appid + "&user_auth_token=" + userAuth;
+ var albumIDResponse = await albumIDClient.GetAsync(albumIDUrl);
+ string albumIDResponseString = albumIDResponse.Content.ReadAsStringAsync().Result;
- // Set "loc" as the selected path.
- loc = folderBrowserDialog.SelectedPath;
+ // Grab metadata from API JSON response
+ JObject joAlbumResponse = JObject.Parse(albumIDResponseString);
- WebResponse ws = wr.GetResponse();
- StreamReader sr = new StreamReader(ws.GetResponseStream());
+ #region Availability Check (Valid Link?)
+ // Check if available at all.
+ string errorCheckAlbum = (string)joAlbumResponse["code"];
+ string errorMessageCheck = (string)joAlbumResponse["message"];
- string albumRequest = sr.ReadToEnd();
-
- string text = albumRequest;
-
- var tracksLog = Regex.Match(albumRequest, "tracks_count\":(?\\d+)").Groups;
- var tracks = tracksLog[1].Value;
-
- // Album Name tag
- var discogAlbumLog = Regex.Match(albumRequest, "\"title\":\"(?.*?)\",\\\"").Groups;
- var discogAlbum = discogAlbumLog[1].Value;
-
- // For converting unicode characters to ASCII
- string unicodeDiscogAlbum = discogAlbum;
- string decodedDiscogAlbum = DecodeEncodedNonAsciiCharacters(unicodeDiscogAlbum);
- discogAlbum = decodedDiscogAlbum;
-
- output.Invoke(new Action(() => output.AppendText("Downloading Album - " + discogAlbum + " ......\r\n\r\n")));
-
- #region Cover Art URL
- // Grab Cover Art URL
- var frontCoverLog = Regex.Match(albumRequest, "\"image\":{\"large\":\"(?[A-Za-z0-9:().,\\\\\\/._\\-']+)").Groups;
- var frontCover = frontCoverLog[1].Value;
-
- // Remove backslashes from the stream URL to have a proper URL.
- string imagepattern = @"(?[^\\]+)";
- string imageinput = frontCover;
- RegexOptions imageoptions = RegexOptions.Multiline;
-
- imageURLTextbox.Invoke(new Action(() => imageURLTextbox.Text = String.Empty));
-
- foreach (Match mImg in Regex.Matches(imageinput, imagepattern, imageoptions))
+ switch (errorCheckAlbum)
{
- imageURLTextbox.Invoke(new Action(() => imageURLTextbox.AppendText(string.Format("{0}", mImg.Value))));
+ case "404":
+ output.Invoke(new Action(() => output.Text = String.Empty));
+ output.Invoke(new Action(() => output.AppendText("ERROR: 404\r\n")));
+ output.Invoke(new Action(() => output.AppendText("Error message is \"" + errorMessageCheck + "\"\r\n")));
+ output.Invoke(new Action(() => output.AppendText("This usually means the link is invalid, or isn't available in the region your account is from.")));
+ enableBoxes(sender, e);
+ return;
+ }
+ #endregion
+
+ #region Quality Info (Bitrate & Sample Rate)
+ // Grab sample rate and bit depth for album track is from.
+ var bitDepth = (string)joAlbumResponse["maximum_bit_depth"];
+ var sampleRate = (string)joAlbumResponse["maximum_sampling_rate"];
+
+ var quality = "FLAC (" + bitDepth + "bit/" + sampleRate + "kHz)";
+ var qualityPath = quality.Replace(@"\", "-").Replace(@"/", "-");
+
+ switch (formatIdString)
+ {
+ case "5":
+ quality = "MP3 320kbps CBR";
+ qualityPath = "MP3";
+ break;
+ case "6":
+ quality = "FLAC (16bit/44.1kHz)";
+ qualityPath = "FLAC (16bit-44.1kHz)";
+ break;
+ case "7":
+ if (quality == "FLAC (24bit/192kHz)")
+ {
+ quality = "FLAC (24bit/96kHz)";
+ qualityPath = "FLAC (24bit-96kHz)";
+ }
+ break;
}
- string frontCoverImg = imageURLTextbox.Text;
- string frontCoverImgBox = frontCoverImg.Replace("_600.jpg", "_150.jpg");
+ // Display album quality in quality textbox.
+ qualityTextbox.Invoke(new Action(() => qualityTextbox.Text = quality));
+ #endregion
+
+ #region Cover Art URL
+ // Grab cover art link
+ frontCoverImg = (string)joAlbumResponse["image"]["large"];
+ // Get 150x150 artwork for cover art box
+ frontCoverImgBox = frontCoverImg.Replace("_600.jpg", "_150.jpg");
+ // Get max sized artwork
frontCoverImg = frontCoverImg.Replace("_600.jpg", "_max.jpg");
albumArtPicBox.Invoke(new Action(() => albumArtPicBox.ImageLocation = frontCoverImgBox));
-
- imageURLTextbox.Invoke(new Action(() => imageURLTextbox.Text = Settings.Default.savedEmail));
#endregion
#region "Goodies" URL (Digital Booklets)
// Look for "Goodies" (digital booklet)
- var goodiesLog = Regex.Match(albumRequest, "\"goodies\":\\[{(?.*?),\"url\":\"(?.*?)\",").Groups;
- var goodies = goodiesLog[2].Value;
-
- // Remove backslashes from the stream URL to have a proper URL.
- string bookpattern = @"(?[^\\]+)";
- string bookinput = goodies;
- RegexOptions bookoptions = RegexOptions.Multiline;
-
- imageURLTextbox.Invoke(new Action(() => imageURLTextbox.Text = String.Empty));
-
- foreach (Match mBook in Regex.Matches(bookinput, bookpattern, bookoptions))
- {
- imageURLTextbox.Invoke(new Action(() => imageURLTextbox.AppendText(string.Format("{0}", mBook.Value))));
- }
-
- string goodiesPDF = imageURLTextbox.Text;
-
- imageURLTextbox.Invoke(new Action(() => imageURLTextbox.Text = Settings.Default.savedEmail));
+ var goodiesLog = Regex.Match(albumIDResponseString, "\"goodies\":\\[{(?.*?),\"url\":\"(?.*?)\",").Groups;
+ var goodiesPDF = goodiesLog[2].Value.Replace(@"\/", "/");
#endregion
- // Grab sample rate and bit depth for album.
- var qualityLog = Regex.Match(albumRequest, "\"maximum_sampling_rate\":(?.*?),(?:.*?)\"maximum_bit_depth\":(?.*?),\"duration\"").Groups;
-
- var bitDepthLog = Regex.Match(albumRequest, "\"maximum_bit_depth\":(?.*?),").Groups;
- var sampleRateLog = Regex.Match(albumRequest, "\"maximum_sampling_rate\":(?.*?),").Groups;
-
- var bitDepth = bitDepthLog[1].Value;
- var sampleRate = sampleRateLog[1].Value;
- var quality = "FLAC (" + bitDepth + "bit/" + sampleRate + "kHz)";
- var qualityPath = quality.Replace(@"\", "-").Replace(@"/", "-");
-
- if (formatIdString == "5")
- {
- quality = "MP3 320kbps CBR";
- qualityPath = "MP3";
- }
- else if (formatIdString == "6")
- {
- quality = "FLAC (16bit/44.1kHz)";
- qualityPath = "FLAC (16bit-44.1kHz)";
- }
- else if (formatIdString == "7")
- {
- if (quality == "FLAC (24bit/192kHz)")
- {
- quality = "FLAC (24bit/96kHz)";
- qualityPath = "FLAC (24bit-96kHz)";
- }
- }
-
// Grab all Track IDs listed on the API.
- string trackIdspattern = "\"version\":(?:.*?),\"id\":(?.*?),";
- string trackinput = text;
- RegexOptions trackoptions = RegexOptions.Multiline;
+ string trackIDsPattern = "\"version\":(?:.*?),\"id\":(?.*?),";
+ string trackIDsInput = albumIDResponseString;
+ RegexOptions trackIDsOptions = RegexOptions.Multiline;
-
- foreach (Match mtrack in Regex.Matches(trackinput, trackIdspattern, trackoptions))
+ foreach (Match m2 in Regex.Matches(trackIDsInput, trackIDsPattern, trackIDsOptions))
{
- //output.Invoke(new Action(() => output.AppendText(string.Format("{0}\r\n", m.Groups["trackId"].Value))));
- trackIdString = string.Format("{0}", mtrack.Groups["trackId"].Value);
+ // Grab matches for Track IDs
+ trackIdString = string.Format("{0}", m2.Groups["trackId"].Value);
- WebRequest trackwr = WebRequest.Create("https://www.qobuz.com/api.json/0.2/track/get?track_id=" + trackIdString + "&app_id=" + appid + "&user_auth_token=" + userAuth);
+ // Create HttpClient to grab Track ID
+ var trackIDClient = new HttpClient();
+ // Run through TLS to allow secure connection.
+ ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
+ // Set user-agent to Firefox.
+ trackIDClient.DefaultRequestHeaders.Add("User-Agent", userAgent);
+ // Set referer to localhost that mora qualitas uses
+ trackIDClient.DefaultRequestHeaders.Add("Referer", "https://play.qobuz.com/album/" + albumIDArtist);
- WebResponse trackws = trackwr.GetResponse();
- StreamReader tracksr = new StreamReader(trackws.GetResponseStream());
+ // Grab response from Qobuz to get info using Track IDs.
+ var trackIDUrl = "https://www.qobuz.com/api.json/0.2/track/get?track_id=" + trackIdString + "&app_id=" + appid + "&user_auth_token=" + userAuth;
+ var trackIDResponse = await trackIDClient.GetAsync(trackIDUrl);
+ string trackIDResponseString = trackIDResponse.Content.ReadAsStringAsync().Result;
- string trackRequest = tracksr.ReadToEnd();
+ // Grab metadata from API JSON response
+ JObject joTrackResponse = JObject.Parse(trackIDResponseString);
- #region Availability Check (Valid Link?)
- // Check if available at all.
- var errorCheckLog = Regex.Match(trackRequest, "\"code\":404,\"message\":\"(?.*?)\\\"").Groups;
- var errorCheck = errorCheckLog[1].Value;
+ #region Get Information (Tags, Titles, etc.)
+ // Grab tag strings
+ albumArtist = (string)joTrackResponse["album"]["artist"]["name"]; albumArtist = DecodeEncodedNonAsciiCharacters(albumArtist);
+ albumArtistPath = GetSafeFilename(albumArtist);
+ albumArtistTextBox.Invoke(new Action(() => albumArtistTextBox.Text = albumArtist));
- if (errorCheck == "No result matching given argument")
+ performerName = (string)joTrackResponse["performer"]["name"]; performerName = DecodeEncodedNonAsciiCharacters(albumArtist);
+ performerNamePath = GetSafeFilename(performerName);
+
+ try { composerName = (string)joTrackResponse["composer"]["name"]; composerName = DecodeEncodedNonAsciiCharacters(composerName); } catch { /*Ignore if fails*/ }
+
+ advisory = (string)joTrackResponse["parental_warning"];
+
+ albumName = (string)joTrackResponse["album"]["title"]; albumName = DecodeEncodedNonAsciiCharacters(albumName);
+ albumNamePath = GetSafeFilename(albumName);
+ albumTextBox.Invoke(new Action(() => albumTextBox.Text = albumName));
+
+ trackName = (string)joTrackResponse["title"]; trackName = trackName.Trim(); trackName = DecodeEncodedNonAsciiCharacters(trackName);
+ trackNamePath = GetSafeFilename(trackName);
+
+ versionName = (string)joTrackResponse["version"];
+ if (versionName != null)
{
- output.Invoke(new Action(() => output.Text = String.Empty));
- output.Invoke(new Action(() => output.AppendText("ERROR: 404\r\n")));
- output.Invoke(new Action(() => output.AppendText("Error message is \"No result matching given argument\"\r\n")));
- output.Invoke(new Action(() => output.AppendText("This could mean either the link is invalid, or isn't available in the region you're downloading from (even if the account is in the correct region). If the latter is true, use a VPN for the region it's available in to download.")));
- mp3Checkbox.Invoke(new Action(() => mp3Checkbox.Visible = true));
- flacLowCheckbox.Invoke(new Action(() => flacLowCheckbox.Visible = true));
- flacMidCheckbox.Invoke(new Action(() => flacMidCheckbox.Visible = true));
- flacHighCheckbox.Invoke(new Action(() => flacHighCheckbox.Visible = true));
- downloadButton.Invoke(new Action(() => downloadButton.Enabled = true));
- return;
+ versionName = DecodeEncodedNonAsciiCharacters(versionName);
+ versionNamePath = GetSafeFilename(versionName);
+ }
+
+ genre = (string)joTrackResponse["album"]["genre"]["name"]; genre = DecodeEncodedNonAsciiCharacters(genre);
+
+ releaseDate = (string)joTrackResponse["album"]["release_date_stream"];
+ releaseDateTextBox.Invoke(new Action(() => releaseDateTextBox.Text = releaseDate));
+
+ copyright = (string)joTrackResponse["copyright"]; copyright = DecodeEncodedNonAsciiCharacters(copyright);
+
+ upc = (string)joTrackResponse["album"]["upc"];
+ upcTextBox.Invoke(new Action(() => upcTextBox.Text = upc));
+
+ isrc = (string)joTrackResponse["isrc"];
+
+ type = (string)joTrackResponse["album"]["release_type"];
+
+ // Grab tag ints
+ trackNumber = (int)joTrackResponse["track_number"];
+
+ trackTotal = (int)joTrackResponse["album"]["tracks_count"];
+ totalTracksTextbox.Invoke(new Action(() => totalTracksTextbox.Text = trackTotal.ToString()));
+
+ discNumber = (int)joTrackResponse["media_number"];
+
+ discTotal = (int)joTrackResponse["album"]["media_count"];
+
+ // Debug output to make sure values are grabbed properly
+ //output.Invoke(new Action(() => output.AppendText("Tags found, listed below...\r\n")));
+ //output.Invoke(new Action(() => output.AppendText(" Album Artist - " + albumArtist + "\r\n")));
+ //output.Invoke(new Action(() => output.AppendText(" Track Artist - " + performerName + "\r\n")));
+ //output.Invoke(new Action(() => output.AppendText(" Composer - " + composerName + "\r\n")));
+ //output.Invoke(new Action(() => output.AppendText(" Advisory - " + advisory + "\r\n")));
+ //output.Invoke(new Action(() => output.AppendText(" Album Name - " + albumName + "\r\n")));
+ //output.Invoke(new Action(() => output.AppendText(" Track Name - " + trackName + "\r\n")));
+ //output.Invoke(new Action(() => output.AppendText(" Track Version - " + versionName + "\r\n")));
+ //output.Invoke(new Action(() => output.AppendText(" Genre - " + genre + "\r\n")));
+ //output.Invoke(new Action(() => output.AppendText(" Release Date - " + releaseDate + "\r\n")));
+ //output.Invoke(new Action(() => output.AppendText(" Copyright - " + copyright + "\r\n")));
+ //output.Invoke(new Action(() => output.AppendText(" UPC - " + upc + "\r\n")));
+ //output.Invoke(new Action(() => output.AppendText(" ISRC - " + isrc + "\r\n")));
+ //output.Invoke(new Action(() => output.AppendText(" Media Type - " + type + "\r\n")));
+ //output.Invoke(new Action(() => output.AppendText(" Track Number - " + trackNumber.ToString() + "\r\n")));
+ //output.Invoke(new Action(() => output.AppendText(" Track Total - " + trackTotal.ToString() + "\r\n")));
+ //output.Invoke(new Action(() => output.AppendText(" Disc Number - " + discNumber.ToString() + "\r\n")));
+ //output.Invoke(new Action(() => output.AppendText(" Disc Total - " + discTotal.ToString() + "\r\n")));
+
+ #region Availability Check (Streamable?)
+ // Check if available for streaming.
+ string streamCheck = (string)joTrackResponse["streamable"];
+
+ switch (streamCheck.ToLower())
+ {
+ case "true":
+ break;
+ default:
+ switch (streamableCheckbox.Checked)
+ {
+ case true:
+ output.Invoke(new Action(() => output.AppendText("Track " + trackNumber.ToString() + " is not available for streaming. Unable to download.\r\n")));
+ System.Threading.Thread.Sleep(100);
+ enableBoxes(sender, e);
+ continue;
+ default:
+ output.Invoke(new Action(() => output.AppendText("Track is not available for streaming. But stremable check is being ignored for debugging, or messed up releases. Attempting to download...\r\n")));
+ break;
+ }
+ break;
}
#endregion
- // Display album quality in quality textbox.
- qualityTextbox.Invoke(new Action(() => qualityTextbox.Text = quality));
+ #endregion
- #region Get Information (Tags, Titles, etc.)
- // Track Number tag
- var trackNumberLog = Regex.Match(trackRequest, "\"track_number\":(?[0-9]+)").Groups;
- var trackNumber = trackNumberLog[1].Value;
+ #region Filename Number Padding
+ // Set default track number padding length
+ var paddingLength = 2;
- // Disc Number tag
- var discNumberLog = Regex.Match(trackRequest, "\"media_number\":(?.*?),\\\"").Groups;
- var discNumber = discNumberLog[1].Value;
+ // Prepare track number padding in filename.
+ string paddingLog = Math.Floor(Math.Log10(trackTotal) + 1).ToString();
- // Album Artist tag
- var albumArtistLog = Regex.Match(trackRequest, "\"artist\":{(?.*?)\"name\":\"(?.*?)\",").Groups;
- var albumArtist = albumArtistLog[2].Value;
+ switch (paddingLog)
+ {
+ case "1":
+ paddingLength = 2;
+ break;
+ default:
+ paddingLength = (int)Math.Floor(Math.Log10(trackTotal) + 1);
+ break;
+ }
- // For converting unicode characters to ASCII
- string unicodeAlbumArtist = albumArtist;
- string decodedAlbumArtist = DecodeEncodedNonAsciiCharacters(unicodeAlbumArtist);
- albumArtist = decodedAlbumArtist;
+ // Set default disc number padding length
+ var paddingDiscLength = 2;
- albumArtist = albumArtist.Replace("\\\"", "\"").Replace(@"\\/", @"/").Replace(@"\\", @"\").Replace(@"\/", @"/");
- var albumArtistPath = albumArtist.Replace(@"\", "-").Replace(@"/", "-").Replace("\\\"", "-").Replace("\\\"", "-").Replace("\"", "-").Replace(":", "-").Replace("<", "-").Replace(">", "-").Replace("|", "-").Replace("?", "-").Replace("*", "-");
+ // Prepare disc number padding in filename.
+ string paddingDiscLog = Math.Floor(Math.Log10(discTotal) + 1).ToString();
- // Display album artist in text box under cover art.
- albumArtistTextBox.Invoke(new Action(() => albumArtistTextBox.Text = albumArtist));
-
- // Track Artist tag
- var performerNameLog = Regex.Match(trackRequest, "\"performer\":{\"id\":(?.*?),\"name\":\"(?.*?)\"},\\\"").Groups;
- var performerName = performerNameLog[2].Value;
-
- // For converting unicode characters to ASCII
- string unicodePerformerName = performerName;
- string decodedPerformerName = DecodeEncodedNonAsciiCharacters(unicodePerformerName);
- performerName = decodedPerformerName;
-
- performerName = performerName.Replace("\\\"", "\"").Replace(@"\\/", @"/").Replace(@"\\", @"\").Replace(@"\/", @"/");
- var performerNamePath = performerName.Replace("\\\"", "-").Replace("\"", "-").Replace(@"\", "-").Replace(@"/", "-").Replace(":", "-").Replace("<", "-").Replace(">", "-").Replace("|", "-").Replace("?", "-").Replace("*", "-");
-
- // Track Composer tag
- var composerNameLog = Regex.Match(trackRequest, "\"composer\":{\"id\":(?.*?),\"name\":\"(?.*?)\",").Groups;
- var composerName = composerNameLog[2].Value;
-
- // Track Explicitness
- var advisoryLog = Regex.Match(trackRequest, "\"performers\":(?:.*?)\"parental_warning\":(?.*?),").Groups;
- var advisory = advisoryLog[1].Value;
-
- // For converting unicode characters to ASCII
- string unicodeComposerName = composerName;
- string decodedComposerName = DecodeEncodedNonAsciiCharacters(unicodeComposerName);
- composerName = decodedComposerName;
-
- composerName = composerName.Replace("\\\"", "\"").Replace(@"\\/", @"/").Replace(@"\\", @"\").Replace(@"\/", @"/");
-
- // Album Name tag
- var albumNameLog = Regex.Match(trackRequest, "\"title\":\"(?.*?)\",\\\"").Groups;
- var albumName = albumNameLog[1].Value;
-
- // For converting unicode characters to ASCII
- string unicodeAlbumName = albumName;
- string decodedAlbumName = DecodeEncodedNonAsciiCharacters(unicodeAlbumName);
- albumName = decodedAlbumName;
-
- albumName = albumName.Replace("\\\"", "\"").Replace(@"\\/", @"/").Replace(@"\\", @"\").Replace(@"\/", @"/");
- var albumNamePath = albumName.Replace("\\\"", "-").Replace("\"", "-").Replace(@"\", "-").Replace(@"/", "-").Replace(":", "-").Replace("<", "-").Replace(">", "-").Replace("|", "-").Replace("?", "-").Replace("*", "-");
-
- // Display album name in text box under cover art.
- albumTextBox.Invoke(new Action(() => albumTextBox.Text = albumName));
-
- // Track Name tag
- var trackNameLog = Regex.Match(trackRequest, "\"isrc\":\"(?.*?)\",\"title\":\"(?.*?)\",\"").Groups;
- var trackName = trackNameLog[2].Value;
- trackName = trackName.Trim(); // Remove spaces from end of track name
-
- // For converting unicode characters to ASCII
- string unicodeTrackName = trackName;
- string decodedTrackName = DecodeEncodedNonAsciiCharacters(unicodeTrackName);
- trackName = decodedTrackName;
-
- trackName = trackName.Replace("\\\"", "\"").Replace(@"\\/", @"/").Replace(@"\\", @"\").Replace(@"\/", @"/");
- var trackNamePath = trackName.Replace("\\\"", "-").Replace("\"", "-").Replace(@"\", "-").Replace(@"/", "-").Replace(":", "-").Replace("<", "-").Replace(">", "-").Replace("|", "-").Replace("?", "-").Replace("*", "-");
-
- // Version Name tag
- var versionNameLog = Regex.Match(trackRequest, "\"version\":\"(?.*?)\",\\\"").Groups;
- var versionName = versionNameLog[1].Value;
-
- // For converting unicode characters to ASCII
- string unicodeVersionName = versionName;
- string decodedVersionName = DecodeEncodedNonAsciiCharacters(unicodeVersionName);
- versionName = decodedVersionName;
-
- versionName = versionName.Replace("\\\"", "\"").Replace(@"\\/", @"/").Replace(@"\\", @"\").Replace(@"\/", @"/");
- var versionNamePath = versionName.Replace("\\\"", "-").Replace("\"", "-").Replace(@"\", "-").Replace(@"/", "-").Replace(":", "-").Replace("<", "-").Replace(">", "-").Replace("|", "-").Replace("?", "-").Replace("*", "-");
-
- // Genre tag
- var genreLog = Regex.Match(trackRequest, "\"genre\":{\"id\":(?.*?),\"color\":\"(?.*?)\",\"name\":\"(?.*?)\",\\\"").Groups;
- var genre = genreLog[3].Value;
-
- // For converting unicode characters to ASCII
- string unicodeGenre = genre;
- string decodedGenre = DecodeEncodedNonAsciiCharacters(unicodeGenre);
- genre = decodedGenre.Replace("\\\"", "\"").Replace(@"\\/", @"/").Replace(@"\\", @"\").Replace(@"\/", @"/");
-
- // Release Date tag, grabs the available "stream" date
- var releaseDateLog = Regex.Match(trackRequest, "\"release_date_stream\":\"(?.*?)\",\\\"").Groups;
- var releaseDate = releaseDateLog[1].Value;
-
- // Display release date in text box under cover art.
- releaseDateTextBox.Invoke(new Action(() => releaseDateTextBox.Text = releaseDate));
-
- // Copyright tag
- var copyrightLog = Regex.Match(trackRequest, "\"copyright\":\"(?.*?)\"copyright\":\"(?.*?)\\\"").Groups;
- var copyright = copyrightLog[2].Value;
-
- // For converting unicode characters to ASCII
- string unicodeCopyright = copyright;
- string decodedCopyright = DecodeEncodedNonAsciiCharacters(unicodeCopyright);
- copyright = decodedCopyright;
-
- copyright = copyright.Replace("\\\"", "\"").Replace(@"\\/", @"/").Replace(@"\\", @"\").Replace(@"\/", @"/").Replace(@"\u2117", @"℗");
-
- // UPC tag
- var upcLog = Regex.Match(trackRequest, "\"upc\":\"(?.*?)\",\\\"").Groups;
- var upc = upcLog[1].Value;
-
- // Display UPC in text box under cover art.
- upcTextBox.Invoke(new Action(() => upcTextBox.Text = upc));
-
- // ISRC tag
- var isrcLog = Regex.Match(trackRequest, "\"isrc\":\"(?.*?)\",\\\"").Groups;
- var isrc = isrcLog[1].Value;
-
- // Release Type tag
- var typeLog = Regex.Match(trackRequest, "\"release_type\":\"(?.*?)\",\"").Groups;
- var type = typeLog[1].Value.ToUpper();
-
- // Total Tracks tag
- var trackTotalLog = Regex.Match(trackRequest, "\"tracks_count\":(?[0-9]+)").Groups;
- var trackTotal = trackTotalLog[1].Value;
-
- // Display Total Tracks in text box under cover art.
- totalTracksTextbox.Invoke(new Action(() => totalTracksTextbox.Text = trackTotal));
-
- // Total Discs tag
- var discTotalLog = Regex.Match(trackRequest, "\"media_count\":(?[0-9]+)").Groups;
- var discTotal = discTotalLog[1].Value;
+ switch (paddingDiscLog)
+ {
+ case "1":
+ paddingDiscLength = 2;
+ break;
+ default:
+ paddingDiscLength = (int)Math.Floor(Math.Log10(trackTotal) + 1);
+ break;
+ }
#endregion
#region Create Shortened Strings
@@ -816,600 +817,398 @@ namespace QobuzDownloaderX
}
#endregion
- #region Filename Number Padding
- // Set default track number padding length
- var paddingLength = 2;
-
- // Prepare track number padding in filename.
- string paddingLog = trackTotal.Length.ToString();
- if (paddingLog == "1")
- {
- paddingLength = 2;
- }
- else
- {
- paddingLength = trackTotal.Length;
- }
-
- // Set default disc number padding length
- var paddingDiscLength = 2;
-
- // Prepare disc number padding in filename.
- string paddingDiscLog = discTotal.Length.ToString();
- if (paddingDiscLog == "1")
- {
- paddingDiscLength = 1;
- }
- else
- {
- paddingDiscLength = discTotal.Length;
- }
- #endregion
-
#region Create Directories
// Create strings for disc folders
string discFolder = null;
string discFolderCreate = null;
// If more than 1 disc, create folders for discs. Otherwise, strings will remain null.
- if (discTotal != "1")
+ if (discTotal != 1)
{
- discFolder = "CD " + discNumber.PadLeft(paddingDiscLength, '0') + "\\";
- discFolderCreate = "\\CD " + discNumber.PadLeft(paddingDiscLength, '0') + "\\";
+ discFolder = "CD " + discNumber.ToString().PadLeft(paddingDiscLength, '0') + "\\";
+ discFolderCreate = "\\CD " + discNumber.ToString().PadLeft(paddingDiscLength, '0') + "\\";
}
- System.IO.Directory.CreateDirectory(loc + "\\" + albumArtistPath);
- System.IO.Directory.CreateDirectory(loc + "\\" + albumArtistPath + "\\" + albumNamePath + " [" + albumIdDiscog + "]");
- System.IO.Directory.CreateDirectory(loc + "\\" + albumArtistPath + "\\" + albumNamePath + " [" + albumIdDiscog + "]" + "\\" + qualityPath);
- System.IO.Directory.CreateDirectory(loc + "\\" + albumArtistPath + "\\" + albumNamePath + " [" + albumIdDiscog + "]" + "\\" + qualityPath + discFolderCreate);
+ // Create directories
+ string[] path1 = { loc, albumArtistPath };
+ path1Full = Path.Combine(path1);
+ string[] path2 = { loc, albumArtistPath, albumNamePath + " [" + albumIDArtist + "]" };
+ path2Full = Path.Combine(path2);
+ string[] path3 = { loc, albumArtistPath, albumNamePath + " [" + albumIDArtist + "]", qualityPath };
+ path3Full = Path.Combine(path3);
- string discogPath = loc + "\\" + albumArtistPath + "\\" + albumNamePath + " [" + albumIdDiscog + "]" + "\\" + qualityPath + discFolderCreate;
+ switch (discTotal)
+ {
+ case 1:
+ path4Full = path3Full;
+ break;
+ default:
+ string[] path4 = { loc, albumArtistPath, albumNamePath + " [" + albumIDArtist + "]", qualityPath, discFolder };
+ path4Full = Path.Combine(path4);
+ break;
+ }
+
+ System.IO.Directory.CreateDirectory(path1Full);
+ System.IO.Directory.CreateDirectory(path2Full);
+ System.IO.Directory.CreateDirectory(path3Full);
+ System.IO.Directory.CreateDirectory(path4Full);
+
+ // Set albumPath to the created directories.
+ string trackPath = path4Full;
#endregion
#region Create Shortened Strings (Again)
// Create final shortened track file names to avoid errors with file names being too long.
- if (versionName == null | versionName == "")
+ switch (versionName)
{
- if ((trackNumber.PadLeft(paddingLength, '0') + " " + trackNamePath).Length > MaxLength)
- {
- finalTrackNamePath = (trackNumber.PadLeft(paddingLength, '0') + " " + trackNamePath).Substring(0, MaxLength).TrimEnd();
- }
- else
- {
- finalTrackNamePath = (trackNumber.PadLeft(paddingLength, '0') + " " + trackNamePath).TrimEnd();
- }
-
- }
- else
- {
- if ((trackNumber.PadLeft(paddingLength, '0') + " " + trackNamePath + " (" + versionNamePath + ")").Length > MaxLength)
- {
- finalTrackNameVersionPath = (trackNumber.PadLeft(paddingLength, '0') + " " + trackNamePath + " (" + versionNamePath + ")").Substring(0, MaxLength).TrimEnd();
- }
- else
- {
- finalTrackNameVersionPath = (trackNumber.PadLeft(paddingLength, '0') + " " + trackNamePath + " (" + versionNamePath + ")").TrimEnd();
- }
- }
- #endregion
-
- #region Availability Check (Streamable?)
- // Check if available for streaming.
- var streamCheckLog = Regex.Match(trackRequest, "\"track_number\":(?.*?)\"streamable\":(?.*?),\"").Groups;
- var streamCheck = streamCheckLog[2].Value;
-
- if (streamCheck != "true")
- {
- if (streamableCheckbox.Checked == true)
- {
- output.Invoke(new Action(() => output.AppendText("Track " + trackNumber + " \"" + trackName + "\" is not available for streaming. Skipping track...\r\n")));
- System.Threading.Thread.Sleep(400);
- continue;
- }
- else
- {
- output.Invoke(new Action(() => output.AppendText("\r\nTrack " + trackNumber + " \"" + trackName + "\" is not available for streaming. But stremable check is being ignored for debugging, or messed up releases. Attempting to download...\r\n")));
- }
+ case null:
+ if ((trackNumber.ToString().PadLeft(paddingLength, '0') + " " + trackNamePath).Length > MaxLength)
+ {
+ finalTrackNamePath = (trackNumber.ToString().PadLeft(paddingLength, '0') + " " + trackNamePath).Substring(0, MaxLength).TrimEnd();
+ }
+ else
+ {
+ finalTrackNamePath = (trackNumber.ToString().PadLeft(paddingLength, '0') + " " + trackNamePath).TrimEnd();
+ }
+ break;
+ default:
+ if ((trackNumber.ToString().PadLeft(paddingLength, '0') + " " + trackNamePath + " (" + versionNamePath + ")").Length > MaxLength)
+ {
+ finalTrackNameVersionPath = (trackNumber.ToString().PadLeft(paddingLength, '0') + " " + trackNamePath + " (" + versionNamePath + ")").Substring(0, MaxLength).TrimEnd();
+ }
+ else
+ {
+ finalTrackNameVersionPath = (trackNumber.ToString().PadLeft(paddingLength, '0') + " " + trackNamePath + " (" + versionNamePath + ")").TrimEnd();
+ }
+ break;
}
#endregion
#region Check if File Exists
// Check if there is a version name.
- if (versionName == null | versionName == "")
+ switch (versionName)
{
- if (System.IO.File.Exists(discogPath + "\\" + finalTrackNamePath + audioFileType))
- {
- output.Invoke(new Action(() => output.AppendText("File for \"" + trackNumber.PadLeft(paddingLength, '0') + " " + trackName + "\" already exists. Skipping.\r\n")));
- System.Threading.Thread.Sleep(400);
- continue;
- }
- }
- else
- {
- if (System.IO.File.Exists(discogPath + "\\" + finalTrackNameVersionPath + audioFileType))
- {
- output.Invoke(new Action(() => output.AppendText("File for \"" + trackNumber.PadLeft(paddingLength, '0') + " " + trackName + " (" + versionName + ")" + "\" already exists. Skipping.\r\n")));
- System.Threading.Thread.Sleep(400);
- continue;
- }
+ case null:
+ string[] path6 = { trackPath, finalTrackNamePath + audioFileType };
+ string checkFile = Path.Combine(path6);
+
+ if (System.IO.File.Exists(checkFile))
+ {
+ output.Invoke(new Action(() => output.AppendText("File for \"" + trackNumber.ToString().PadLeft(paddingLength, '0') + " " + trackName + "\" already exists. Skipping.\r\n")));
+ System.Threading.Thread.Sleep(100);
+ continue;
+ }
+ break;
+ default:
+ string[] path6Version = { trackPath, finalTrackNameVersionPath + audioFileType };
+ string checkFileVersion = Path.Combine(path6Version);
+
+ if (System.IO.File.Exists(checkFileVersion))
+ {
+ output.Invoke(new Action(() => output.AppendText("File for \"" + trackNumber.ToString().PadLeft(paddingLength, '0') + " " + trackName + " (" + versionName + ")" + "\" already exists. Skipping.\r\n")));
+ System.Threading.Thread.Sleep(100);
+ continue;
+ }
+ break;
}
#endregion
- // Close web request and create streaming URL.
- trackwr.Abort();
+ // Create streaming URL.
createURL(sender, e);
try
{
#region Downloading
// Check if there is a version name.
- if (versionName == null | versionName == "")
+ switch (versionName)
{
- output.Invoke(new Action(() => output.AppendText("Downloading - " + trackNumber.PadLeft(paddingLength, '0') + " - " + trackName + " ......")));
+ case null:
+ output.Invoke(new Action(() => output.AppendText("Downloading - " + trackNumber.ToString().PadLeft(paddingLength, '0') + " - " + trackName + " ......")));
+ break;
+ default:
+ output.Invoke(new Action(() => output.AppendText("Downloading - " + trackNumber.ToString().PadLeft(paddingLength, '0') + " - " + trackName + " (" + versionName + ")" + " ......")));
+ break;
}
- else
- {
- output.Invoke(new Action(() => output.AppendText("Downloading - " + trackNumber.PadLeft(paddingLength, '0') + " - " + trackName + " (" + versionName + ")" + " ......")));
- }
- // Being download process.
- var client = new HttpClient();
- // Run through TLS to allow secure connection.
- ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3;
- // Set "range" header to nearly unlimited.
- client.DefaultRequestHeaders.Range = new RangeHeaderValue(0, 999999999999);
- // Set user-agent to Firefox.
- client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0");
- // Set referer URL to album ID.
- client.DefaultRequestHeaders.Add("Referer", "https://play.qobuz.com/album/" + albumIdDiscog);
- // Download the URL in the "Streamed URL" Textbox (Will most likely be replaced).
- using (var stream = await client.GetStreamAsync(testURLBox.Text))
- // Save single track in selected path.
- if (versionNamePath == null | versionNamePath == "")
+ // Save streamed file from link
+ using (HttpClient streamClient = new HttpClient())
+ {
+ // Set "range" header to nearly unlimited.
+ streamClient.DefaultRequestHeaders.Range = new RangeHeaderValue(0, 999999999999);
+ // Set user-agent to Firefox.
+ streamClient.DefaultRequestHeaders.Add("User-Agent", userAgent);
+ // Set referer URL to album ID.
+ streamClient.DefaultRequestHeaders.Add("Referer", "https://play.qobuz.com/album/" + albumId);
+
+ using (HttpResponseMessage streamResponse = await streamClient.GetAsync(stream, HttpCompletionOption.ResponseHeadersRead))
+ using (Stream streamToReadFrom = await streamResponse.Content.ReadAsStreamAsync())
{
- // If there is NOT a version name.
- using (var output = System.IO.File.Create(loc + "\\" + albumArtistPath + "\\" + albumNamePath + " [" + albumIdDiscog + "]" + "\\" + qualityPath + "\\" + discFolder + finalTrackNamePath + audioFileType))
+ string fileName = Path.GetTempFileName();
+ using (Stream streamToWriteTo = System.IO.File.Open(fileName, FileMode.Create))
{
- await stream.CopyToAsync(output);
- }
- }
- else
- {
- // If there is a version name.
- using (var output = System.IO.File.Create(loc + "\\" + albumArtistPath + "\\" + albumNamePath + " [" + albumIdDiscog + "]" + "\\" + qualityPath + "\\" + discFolder + finalTrackNameVersionPath + audioFileType))
- {
- await stream.CopyToAsync(output);
+ await streamToReadFrom.CopyToAsync(streamToWriteTo);
+ }
+
+ switch (versionName)
+ {
+ case null:
+ string[] path6 = { trackPath, finalTrackNamePath + audioFileType };
+ string filePath = Path.Combine(path6);
+
+ System.IO.File.Move(fileName, filePath);
+ break;
+ default:
+ string[] path6Version = { trackPath, finalTrackNameVersionPath + audioFileType };
+ string filePathVersion = Path.Combine(path6Version);
+
+ System.IO.File.Move(fileName, filePathVersion);
+ break;
}
}
+ }
#endregion
#region Cover Art Saving
- if (System.IO.File.Exists(loc + "\\" + albumArtistPath + "\\" + albumNamePath + " [" + albumIdDiscog + "]" + "\\" + qualityPath + "\\" + "Cover.jpg"))
- {
- // Skip, don't re-download.
+ string[] path7 = { loc, albumArtistPath, albumNamePath + " [" + albumIDArtist + "]", qualityPath, "Cover.jpg" };
+ string coverArtPath = Path.Combine(path7);
+ string[] path7Tag = { loc, albumArtistPath, albumNamePath + " [" + albumIDArtist + "]", qualityPath, artSize + ".jpg" };
+ string coverArtTagPath = Path.Combine(path7Tag);
- // Download selected cover art size for tagging files (Currently happens every time a track is downloaded).
- using (WebClient imgClient = new WebClient())
+ if (System.IO.File.Exists(coverArtPath))
+ {
+ try
{
- imgClient.DownloadFile(new Uri(frontCoverImg.Replace("_max", "_" + artSize)), loc + "\\" + albumArtistPath + "\\" + albumNamePath + " [" + albumIdDiscog + "]" + "\\" + qualityPath + "\\" + artSize + ".jpg");
+ // Skip, don't re-download.
+
+ // Download selected cover art size for tagging files (Currently happens every time a track is downloaded).
+ using (WebClient imgClient = new WebClient())
+ {
+ imgClient.DownloadFile(new Uri(frontCoverImg.Replace("_max", "_" + artSize)), coverArtTagPath);
+ }
+ }
+ catch
+ {
+ // Ignore, Qobuz servers throw a 404 as if the image doesn't exist.
}
}
else
{
- if (imageCheckbox.Checked == true)
+ try
{
- // Save cover art to selected path (Currently happens every time a track is downloaded).
+ // Save cover art to selected path.
using (WebClient imgClient = new WebClient())
{
// Download max quality Cover Art to "Cover.jpg" file in chosen path.
- imgClient.DownloadFile(new Uri(frontCoverImg), loc + "\\" + albumArtistPath + "\\" + albumNamePath + " [" + albumIdDiscog + "]" + "\\" + qualityPath + "\\" + "Cover.jpg");
+ imgClient.DownloadFile(new Uri(frontCoverImg), coverArtPath);
// Download selected cover art size for tagging files (Currently happens every time a track is downloaded).
- imgClient.DownloadFile(new Uri(frontCoverImg.Replace("_max", "_" + artSize)), loc + "\\" + albumArtistPath + "\\" + albumNamePath + " [" + albumIdDiscog + "]" + "\\" + qualityPath + "\\" + artSize + ".jpg");
+ imgClient.DownloadFile(new Uri(frontCoverImg.Replace("_max", "_" + artSize)), coverArtTagPath);
}
}
+ catch
+ {
+ // Ignore, Qobuz servers throw a 404 as if the image doesn't exist.
+ }
}
#endregion
#region Tagging
- // Check if audio file type is FLAC or MP3
- if (audioFileType == ".mp3")
+ switch (versionName)
{
- #region MP3 Tagging (Needs Work)
- // Select the downloaded file to prepare for tagging.
- // Check if there's a version name or not
- if (versionName == null | versionName == "")
- {
- // If there is NOT a version name.
- var tfile = TagLib.File.Create(loc + "\\" + albumArtistPath + "\\" + albumNamePath + " [" + albumIdDiscog + "]" + "\\" + qualityPath + "\\" + discFolder + finalTrackNamePath + audioFileType);
- // For custom / troublesome tags.
- TagLib.Id3v2.Tag t = (TagLib.Id3v2.Tag)tfile.GetTag(TagLib.TagTypes.Id3v2);
-
-
- // Saving cover art to file(s)
- if (imageCheckbox.Checked == true)
- {
- // Define cover art to use for MP3 file(s)
- TagLib.Id3v2.AttachedPictureFrame pic = new TagLib.Id3v2.AttachedPictureFrame();
- pic.TextEncoding = TagLib.StringType.Latin1;
- pic.MimeType = System.Net.Mime.MediaTypeNames.Image.Jpeg;
- pic.Type = TagLib.PictureType.FrontCover;
- pic.Data = TagLib.ByteVector.FromPath(loc + "\\" + albumArtistPath + "\\" + albumNamePath + " [" + albumIdDiscog + "]" + "\\" + qualityPath + "\\" + artSize + ".jpg");
-
- // Save cover art to MP3 file.
- tfile.Tag.Pictures = new TagLib.IPicture[1] { pic };
- tfile.Save();
- }
-
- // Track Title tag
- if (trackTitleCheckbox.Checked == true)
- {
- tfile.Tag.Title = trackName;
- }
-
- // Album Title tag
- if (albumCheckbox.Checked == true)
- {
- tfile.Tag.Album = albumName;
- }
-
- // Album Artits tag
- if (albumArtistCheckbox.Checked == true)
- {
- tfile.Tag.AlbumArtists = new string[] { albumArtist };
- }
-
- // Track Artist tag
- if (artistCheckbox.Checked == true)
- {
- tfile.Tag.Performers = new string[] { performerName };
- }
-
- // Composer tag
- if (composerCheckbox.Checked == true)
- {
- tfile.Tag.Composers = new string[] { composerName };
- }
-
- // Release Date tag
- if (releaseCheckbox.Checked == true)
- {
- releaseDate = releaseDate.Substring(0, 4);
- tfile.Tag.Year = UInt32.Parse(releaseDate);
- }
-
- // Genre tag
- if (genreCheckbox.Checked == true)
- {
- tfile.Tag.Genres = new string[] { genre };
- }
-
- // Track Number tag
- if (trackNumberCheckbox.Checked == true)
- {
- tfile.Tag.Track = UInt32.Parse(trackNumber);
- }
-
- // Disc Number tag
- if (discNumberCheckbox.Checked == true)
- {
- tfile.Tag.Disc = UInt32.Parse(discNumber);
- }
-
- // Total Discs tag
- if (discTotalCheckbox.Checked == true)
- {
- tfile.Tag.DiscCount = UInt32.Parse(discTotal);
- }
-
- // Total Tracks tag
- if (trackTotalCheckbox.Checked == true)
- {
- tfile.Tag.TrackCount = UInt32.Parse(trackTotal);
- }
-
- // Comment tag
- if (commentCheckbox.Checked == true)
- {
- tfile.Tag.Comment = commentTextbox.Text;
- }
-
- // Copyright tag
- if (copyrightCheckbox.Checked == true)
- {
- tfile.Tag.Copyright = copyright;
- }
- // UPC tag
- if (upcCheckbox.Checked == true)
- {
- // Not available on MP3 at the moment
- }
-
- // ISRC tag
- if (isrcCheckbox.Checked == true)
- {
- TagLib.Id3v2.Tag tag = (TagLib.Id3v2.Tag)tfile.GetTag(TagTypes.Id3v2, true);
- tag.SetTextFrame("TSRC", isrc);
- }
-
- // Release Type tag
- if (type != null)
- {
- if (typeCheckbox.Checked == true)
- {
- TagLib.Id3v2.Tag tag = (TagLib.Id3v2.Tag)tfile.GetTag(TagTypes.Id3v2, true);
- tag.SetTextFrame("TMED", type);
- }
- }
-
- // Explicit tag
- if (explicitCheckbox.Checked == true)
- {
- // Not available on MP3 at the moment
- }
-
- // Save all selected tags to file
- tfile.Save();
- }
- else
- {
- // If there is a version name.
- var tfile = TagLib.File.Create(loc + "\\" + albumArtistPath + "\\" + albumNamePath + " [" + albumIdDiscog + "]" + "\\" + qualityPath + "\\" + discFolder + finalTrackNameVersionPath + audioFileType);
- // For custom / troublesome tags.
- TagLib.Id3v2.Tag t = (TagLib.Id3v2.Tag)tfile.GetTag(TagLib.TagTypes.Id3v2);
-
-
- // Saving cover art to file(s)
- if (imageCheckbox.Checked == true)
- {
- // Define cover art to use for FLAC file(s)
- TagLib.Id3v2.AttachedPictureFrame pic = new TagLib.Id3v2.AttachedPictureFrame();
- pic.TextEncoding = TagLib.StringType.Latin1;
- pic.MimeType = System.Net.Mime.MediaTypeNames.Image.Jpeg;
- pic.Type = TagLib.PictureType.FrontCover;
- pic.Data = TagLib.ByteVector.FromPath(loc + "\\" + albumArtistPath + "\\" + albumNamePath + " [" + albumIdDiscog + "]" + "\\" + qualityPath + "\\" + artSize + ".jpg");
-
- // Save cover art to FLAC file.
- tfile.Tag.Pictures = new TagLib.IPicture[1] { pic };
- tfile.Save();
- }
-
- // Track Title tag
- if (trackTitleCheckbox.Checked == true)
- {
- tfile.Tag.Title = trackName + " (" + versionName + ")";
- }
-
- // Album Title tag
- if (albumCheckbox.Checked == true)
- {
- tfile.Tag.Album = albumName;
- }
-
- // Album Artits tag
- if (albumArtistCheckbox.Checked == true)
- {
- tfile.Tag.AlbumArtists = new string[] { albumArtist };
- }
-
- // Track Artist tag
- if (artistCheckbox.Checked == true)
- {
- tfile.Tag.Performers = new string[] { performerName };
- }
-
- // Composer tag
- if (composerCheckbox.Checked == true)
- {
- tfile.Tag.Composers = new string[] { composerName };
- }
-
- // Release Date tag
- if (releaseCheckbox.Checked == true)
- {
- releaseDate = releaseDate.Substring(0, 4);
- tfile.Tag.Year = UInt32.Parse(releaseDate);
- }
-
- // Genre tag
- if (genreCheckbox.Checked == true)
- {
- tfile.Tag.Genres = new string[] { genre };
- }
-
- // Track Number tag
- if (trackNumberCheckbox.Checked == true)
- {
- tfile.Tag.Track = UInt32.Parse(trackNumber);
- }
-
- // Disc Number tag
- if (discNumberCheckbox.Checked == true)
- {
- tfile.Tag.Disc = UInt32.Parse(discNumber);
- }
-
- // Total Discs tag
- if (discTotalCheckbox.Checked == true)
- {
- tfile.Tag.DiscCount = UInt32.Parse(discTotal);
- }
-
- // Total Tracks tag
- if (trackTotalCheckbox.Checked == true)
- {
- tfile.Tag.TrackCount = UInt32.Parse(trackTotal);
- }
-
- // Comment tag
- if (commentCheckbox.Checked == true)
- {
- tfile.Tag.Comment = commentTextbox.Text;
- }
-
- // Copyright tag
- if (copyrightCheckbox.Checked == true)
- {
- tfile.Tag.Copyright = copyright;
- }
- // UPC tag
- if (upcCheckbox.Checked == true)
- {
- // Not available on MP3 at the moment
- }
-
- // ISRC tag
- if (isrcCheckbox.Checked == true)
- {
- TagLib.Id3v2.Tag tag = (TagLib.Id3v2.Tag)tfile.GetTag(TagTypes.Id3v2, true);
- tag.SetTextFrame("TSRC", isrc);
- }
-
- // Release Type tag
- if (type != null)
- {
- if (typeCheckbox.Checked == true)
- {
- TagLib.Id3v2.Tag tag = (TagLib.Id3v2.Tag)tfile.GetTag(TagTypes.Id3v2, true);
- tag.SetTextFrame("TMED", type);
- }
- }
-
- // Explicit tag
- if (explicitCheckbox.Checked == true)
- {
- // Not available on MP3 at the moment
- }
-
- // Save all selected tags to file
- tfile.Save();
- }
- #endregion
+ case null:
+ break;
+ default:
+ finalTrackNamePath = finalTrackNameVersionPath;
+ break;
}
- else
+
+ string[] path8 = { trackPath, finalTrackNamePath + audioFileType };
+ string tagFilePath = Path.Combine(path8);
+ string[] path9 = { loc, albumArtistPath, albumNamePath + " [" + albumIDArtist + "]", qualityPath, artSize + ".jpg" };
+ string tagCoverArtFilePath = Path.Combine(path9);
+
+ // Set file to tag
+ var tfile = TagLib.File.Create(tagFilePath);
+
+ switch (audioFileType)
{
- #region FLAC Tagging
- // Select the downloaded file to prepare for tagging.
- // Check if there's a version name or not
- if (versionName == null | versionName == "")
- {
- // If there is NOT a version name.
- var tfile = TagLib.File.Create(loc + "\\" + albumArtistPath + "\\" + albumNamePath + " [" + albumIdDiscog + "]" + "\\" + qualityPath + "\\" + discFolder + finalTrackNamePath + audioFileType);
+ case ".mp3":
+ #region MP3 Tagging
+ // For custom / troublesome tags.
+ TagLib.Id3v2.Tag t = (TagLib.Id3v2.Tag)tfile.GetTag(TagLib.TagTypes.Id3v2);
+
+ // Saving cover art to file(s)
+ if (imageCheckbox.Checked == true)
+ {
+ try
+ {
+ // Define cover art to use for MP3 file(s)
+ TagLib.Id3v2.AttachedPictureFrame pic = new TagLib.Id3v2.AttachedPictureFrame();
+ pic.TextEncoding = TagLib.StringType.Latin1;
+ pic.MimeType = System.Net.Mime.MediaTypeNames.Image.Jpeg;
+ pic.Type = TagLib.PictureType.FrontCover;
+ pic.Data = TagLib.ByteVector.FromPath(tagCoverArtFilePath);
+
+ // Save cover art to MP3 file.
+ tfile.Tag.Pictures = new TagLib.IPicture[1] { pic };
+ tfile.Save();
+ }
+ catch
+ {
+ output.Invoke(new Action(() => output.AppendText("Cover art tag fail, .jpg still exists?...")));
+ }
+ }
+
+ // Track Title tag
+ if (trackTitleCheckbox.Checked == true)
+ {
+ switch (versionName)
+ {
+ case null:
+ tfile.Tag.Title = trackName;
+ break;
+ default:
+ tfile.Tag.Title = trackName + " (" + versionName + ")";
+ break;
+ }
+
+ }
+
+ // Album Title tag
+ if (albumCheckbox.Checked == true) { tfile.Tag.Album = albumName; }
+
+ // Album Artits tag
+ if (albumArtistCheckbox.Checked == true) { tfile.Tag.AlbumArtists = new string[] { albumArtist }; }
+
+ // Track Artist tag
+ if (artistCheckbox.Checked == true) { tfile.Tag.Performers = new string[] { performerName }; }
+
+ // Composer tag
+ if (composerCheckbox.Checked == true) { tfile.Tag.Composers = new string[] { composerName }; }
+
+ // Release Date tag
+ if (releaseCheckbox.Checked == true) { releaseDate = releaseDate.Substring(0, 4); tfile.Tag.Year = UInt32.Parse(releaseDate); }
+
+ // Genre tag
+ if (genreCheckbox.Checked == true) { tfile.Tag.Genres = new string[] { genre }; }
+
+ // Track Number tag
+ if (trackNumberCheckbox.Checked == true) { tfile.Tag.Track = Convert.ToUInt32(trackNumber); }
+
+ // Disc Number tag
+ if (discNumberCheckbox.Checked == true) { tfile.Tag.Disc = Convert.ToUInt32(discNumber); }
+
+ // Total Discs tag
+ if (discTotalCheckbox.Checked == true) { tfile.Tag.DiscCount = Convert.ToUInt32(discTotal); }
+
+ // Total Tracks tag
+ if (trackTotalCheckbox.Checked == true) { tfile.Tag.TrackCount = Convert.ToUInt32(trackTotal); }
+
+ // Comment tag
+ if (commentCheckbox.Checked == true) { tfile.Tag.Comment = commentTextbox.Text; }
+
+ // Copyright tag
+ if (copyrightCheckbox.Checked == true) { tfile.Tag.Copyright = copyright; }
+
+ // ISRC tag
+ if (isrcCheckbox.Checked == true) { TagLib.Id3v2.Tag tag = (TagLib.Id3v2.Tag)tfile.GetTag(TagTypes.Id3v2, true); tag.SetTextFrame("TSRC", isrc); }
+
+ // Release Type tag
+ if (type != null)
+ {
+ if (typeCheckbox.Checked == true) { TagLib.Id3v2.Tag tag = (TagLib.Id3v2.Tag)tfile.GetTag(TagTypes.Id3v2, true); tag.SetTextFrame("TMED", type); }
+ }
+
+ // Save all selected tags to file
+ tfile.Save();
+ #endregion
+ break;
+ case ".flac":
+ #region FLAC Tagging
// For custom / troublesome tags.
var custom = (TagLib.Ogg.XiphComment)tfile.GetTag(TagLib.TagTypes.Xiph);
-
// Saving cover art to file(s)
if (imageCheckbox.Checked == true)
{
- // Define cover art to use for FLAC file(s)
- TagLib.Id3v2.AttachedPictureFrame pic = new TagLib.Id3v2.AttachedPictureFrame();
- pic.TextEncoding = TagLib.StringType.Latin1;
- pic.MimeType = System.Net.Mime.MediaTypeNames.Image.Jpeg;
- pic.Type = TagLib.PictureType.FrontCover;
- pic.Data = TagLib.ByteVector.FromPath(loc + "\\" + albumArtistPath + "\\" + albumNamePath + " [" + albumIdDiscog + "]" + "\\" + qualityPath + "\\" + artSize + ".jpg");
+ try
+ {
+ // Define cover art to use for FLAC file(s)
+ TagLib.Id3v2.AttachedPictureFrame pic = new TagLib.Id3v2.AttachedPictureFrame();
+ pic.TextEncoding = TagLib.StringType.Latin1;
+ pic.MimeType = System.Net.Mime.MediaTypeNames.Image.Jpeg;
+ pic.Type = TagLib.PictureType.FrontCover;
+ pic.Data = TagLib.ByteVector.FromPath(tagCoverArtFilePath);
- // Save cover art to FLAC file.
- tfile.Tag.Pictures = new TagLib.IPicture[1] { pic };
- tfile.Save();
+ // Save cover art to FLAC file.
+ tfile.Tag.Pictures = new TagLib.IPicture[1] { pic };
+ tfile.Save();
+ }
+ catch
+ {
+ output.Invoke(new Action(() => output.AppendText("Cover art tag fail, .jpg still exists?...")));
+ }
}
// Track Title tag
if (trackTitleCheckbox.Checked == true)
{
- tfile.Tag.Title = trackName;
+ switch (versionName)
+ {
+ case null:
+ tfile.Tag.Title = trackName;
+ break;
+ default:
+ tfile.Tag.Title = trackName + " (" + versionName + ")";
+ break;
+ }
}
// Album Title tag
- if (albumCheckbox.Checked == true)
- {
- tfile.Tag.Album = albumName;
- }
+ if (albumCheckbox.Checked == true) { tfile.Tag.Album = albumName; }
// Album Artits tag
- if (albumArtistCheckbox.Checked == true)
- {
- custom.SetField("ALBUMARTIST", new string[] { albumArtist });
- }
+ if (albumArtistCheckbox.Checked == true) { custom.SetField("ALBUMARTIST", new string[] { albumArtist }); }
// Track Artist tag
- if (artistCheckbox.Checked == true)
- {
- custom.SetField("ARTIST", new string[] { performerName });
- }
+ if (artistCheckbox.Checked == true) { custom.SetField("ARTIST", new string[] { performerName }); }
// Composer tag
- if (composerCheckbox.Checked == true)
- {
- custom.SetField("COMPOSER", new string[] { composerName });
- }
+ if (composerCheckbox.Checked == true) { custom.SetField("COMPOSER", new string[] { composerName }); }
// Release Date tag
- if (releaseCheckbox.Checked == true)
- {
- custom.SetField("YEAR", new string[] { releaseDate });
- }
+ if (releaseCheckbox.Checked == true) { custom.SetField("YEAR", new string[] { releaseDate }); }
// Genre tag
- if (genreCheckbox.Checked == true)
- {
- custom.SetField("GENRE", new string[] { genre });
- }
+ if (genreCheckbox.Checked == true) { custom.SetField("GENRE", new string[] { genre }); }
// Track Number tag
- if (trackNumberCheckbox.Checked == true)
- {
- tfile.Tag.Track = UInt32.Parse(trackNumber);
- }
+ if (trackNumberCheckbox.Checked == true) { tfile.Tag.Track = Convert.ToUInt32(trackNumber); }
// Disc Number tag
- if (discNumberCheckbox.Checked == true)
- {
- tfile.Tag.Disc = UInt32.Parse(discNumber);
- }
+ if (discNumberCheckbox.Checked == true) { tfile.Tag.Disc = Convert.ToUInt32(discNumber); }
// Total Discs tag
- if (discTotalCheckbox.Checked == true)
- {
- tfile.Tag.DiscCount = UInt32.Parse(discTotal);
- }
+ if (discTotalCheckbox.Checked == true) { tfile.Tag.DiscCount = Convert.ToUInt32(discTotal); }
// Total Tracks tag
- if (trackTotalCheckbox.Checked == true)
- {
- tfile.Tag.TrackCount = UInt32.Parse(trackTotal);
- }
+ if (trackTotalCheckbox.Checked == true) { tfile.Tag.TrackCount = Convert.ToUInt32(trackTotal); }
// Comment tag
- if (commentCheckbox.Checked == true)
- {
- custom.SetField("COMMENT", new string[] { commentTextbox.Text });
- }
+ if (commentCheckbox.Checked == true) { custom.SetField("COMMENT", new string[] { commentTextbox.Text }); }
// Copyright tag
- if (copyrightCheckbox.Checked == true)
- {
- custom.SetField("COPYRIGHT", new string[] { copyright });
- }
+ if (copyrightCheckbox.Checked == true) { custom.SetField("COPYRIGHT", new string[] { copyright }); }
// UPC tag
- if (upcCheckbox.Checked == true)
- {
- custom.SetField("UPC", new string[] { upc });
- }
+ if (upcCheckbox.Checked == true) { custom.SetField("UPC", new string[] { upc }); }
// ISRC tag
- if (isrcCheckbox.Checked == true)
- {
- custom.SetField("ISRC", new string[] { isrc });
- }
+ if (isrcCheckbox.Checked == true) { custom.SetField("ISRC", new string[] { isrc }); }
// Release Type tag
if (type != null)
{
- if (typeCheckbox.Checked == true)
- {
- custom.SetField("MEDIATYPE", new string[] { type });
- }
+ if (typeCheckbox.Checked == true) { custom.SetField("MEDIATYPE", new string[] { type }); }
}
// Explicit tag
@@ -1420,163 +1219,8 @@ namespace QobuzDownloaderX
// Save all selected tags to file
tfile.Save();
- }
- else
- {
- // If there is a version name.
- var tfile = TagLib.File.Create(loc + "\\" + albumArtistPath + "\\" + albumNamePath + " [" + albumIdDiscog + "]" + "\\" + qualityPath + "\\" + discFolder + finalTrackNameVersionPath + audioFileType);
- // For custom / troublesome tags.
- var custom = (TagLib.Ogg.XiphComment)tfile.GetTag(TagLib.TagTypes.Xiph);
-
-
- // Saving cover art to file(s)
- if (imageCheckbox.Checked == true)
- {
- // Define cover art to use for FLAC file(s)
- TagLib.Id3v2.AttachedPictureFrame pic = new TagLib.Id3v2.AttachedPictureFrame();
- pic.TextEncoding = TagLib.StringType.Latin1;
- pic.MimeType = System.Net.Mime.MediaTypeNames.Image.Jpeg;
- pic.Type = TagLib.PictureType.FrontCover;
- pic.Data = TagLib.ByteVector.FromPath(loc + "\\" + albumArtistPath + "\\" + albumNamePath + " [" + albumIdDiscog + "]" + "\\" + qualityPath + "\\" + artSize + ".jpg");
-
- // Save cover art to FLAC file.
- tfile.Tag.Pictures = new TagLib.IPicture[1] { pic };
- tfile.Save();
- }
-
- // Track Title tag
- if (trackTitleCheckbox.Checked == true)
- {
- tfile.Tag.Title = trackName + " (" + versionName + ")";
- }
-
- // Album Title tag
- if (albumCheckbox.Checked == true)
- {
- tfile.Tag.Album = albumName;
- }
-
- // Album Artits tag
- if (albumArtistCheckbox.Checked == true)
- {
- custom.SetField("ALBUMARTIST", new string[] { albumArtist });
- }
-
- // Track Artist tag
- if (artistCheckbox.Checked == true)
- {
- custom.SetField("ARTIST", new string[] { performerName });
- }
-
- // Composer tag
- if (composerCheckbox.Checked == true)
- {
- custom.SetField("COMPOSER", new string[] { composerName });
- }
-
- // Release Date tag
- if (releaseCheckbox.Checked == true)
- {
- custom.SetField("YEAR", new string[] { releaseDate });
- }
-
- // Genre tag
- if (genreCheckbox.Checked == true)
- {
- custom.SetField("GENRE", new string[] { genre });
- }
-
- // Track Number tag
- if (trackNumberCheckbox.Checked == true)
- {
- tfile.Tag.Track = UInt32.Parse(trackNumber);
- }
-
- // Disc Number tag
- if (discNumberCheckbox.Checked == true)
- {
- tfile.Tag.Disc = UInt32.Parse(discNumber);
- }
-
- // Total Discs tag
- if (discTotalCheckbox.Checked == true)
- {
- tfile.Tag.DiscCount = UInt32.Parse(discTotal);
- }
-
- // Total Tracks tag
- if (trackTotalCheckbox.Checked == true)
- {
- tfile.Tag.TrackCount = UInt32.Parse(trackTotal);
- }
-
- // Comment tag
- if (commentCheckbox.Checked == true)
- {
- custom.SetField("COMMENT", new string[] { commentTextbox.Text });
- }
-
- // Copyright tag
- if (copyrightCheckbox.Checked == true)
- {
- custom.SetField("COPYRIGHT", new string[] { copyright });
- }
- // UPC tag
- if (upcCheckbox.Checked == true)
- {
- custom.SetField("UPC", new string[] { upc });
- }
-
- // ISRC tag
- if (isrcCheckbox.Checked == true)
- {
- custom.SetField("ISRC", new string[] { isrc });
- }
-
- // Release Type tag
- if (type != null)
- {
- if (typeCheckbox.Checked == true)
- {
- custom.SetField("MEDIATYPE", new string[] { type });
- }
- }
-
- // Explicit tag
- if (explicitCheckbox.Checked == true)
- {
- if (advisory == "false") { custom.SetField("ITUNESADVISORY", new string[] { "0" }); } else { custom.SetField("ITUNESADVISORY", new string[] { "1" }); }
- }
-
- // Save all selected tags to file
- tfile.Save();
- }
- #endregion
- }
- #endregion
-
- #region Digital Booklet
- // If a booklet was found, save it.
- if (goodiesPDF == null | goodiesPDF == "")
- {
- // No need to download something that doesn't exist.
- }
- else
- {
- if (System.IO.File.Exists(loc + "\\" + albumArtistPath + "\\" + albumNamePath + " [" + albumIdDiscog + "]" + "\\" + qualityPath + "\\" + "Digital Booklet.pdf"))
- {
- // Skip, don't re-download.
- }
- else
- {
- // Save digital booklet to selected path
- output.Invoke(new Action(() => output.AppendText("\r\nGoodies found, downloading...")));
- using (WebClient bookClient = new WebClient())
- {
- // Download max quality Cover Art to "Cover.jpg" file in chosen path.
- bookClient.DownloadFile(new Uri(goodiesPDF), loc + "\\" + albumArtistPath + "\\" + albumNamePath + " [" + albumIdDiscog + "]" + "\\" + qualityPath + "\\" + "Digital Booklet.pdf");
- }
- }
+ #endregion
+ break;
}
#endregion
}
@@ -1587,46 +1231,63 @@ namespace QobuzDownloaderX
output.Invoke(new Action(() => output.AppendText("\r\n\r\n")));
output.Invoke(new Action(() => output.AppendText("Track Download ERROR. Information below.\r\n\r\n")));
output.Invoke(new Action(() => output.AppendText(error)));
- output.Invoke(new Action(() => output.AppendText("\r\n\r\nIf some tracks aren't available for streaming on the album you're trying to download, try to manually download the available tracks individually.")));
- mp3Checkbox.Invoke(new Action(() => mp3Checkbox.Visible = true));
- flacLowCheckbox.Invoke(new Action(() => flacLowCheckbox.Visible = true));
- flacMidCheckbox.Invoke(new Action(() => flacMidCheckbox.Visible = true));
- flacHighCheckbox.Invoke(new Action(() => flacHighCheckbox.Visible = true));
- downloadButton.Invoke(new Action(() => downloadButton.Enabled = true));
+ enableBoxes(sender, e);
return;
}
// Delete image file used for tagging
- if (System.IO.File.Exists(loc + "\\" + albumArtistPath + "\\" + albumNamePath + " [" + albumIdDiscog + "]" + "\\" + qualityPath + "\\" + artSize + ".jpg"))
+ string[] path11 = { loc, albumArtistPath, albumNamePath + " [" + albumIDArtist + "]", qualityPath, artSize + ".jpg" };
+ string coverArtTagDelete = Path.Combine(path11);
+
+ if (System.IO.File.Exists(coverArtTagDelete))
{
- System.IO.File.Delete(loc + "\\" + albumArtistPath + "\\" + albumNamePath + " [" + albumIdDiscog + "]" + "\\" + qualityPath + "\\" + artSize + ".jpg");
+ System.IO.File.Delete(coverArtTagDelete);
}
// Say when a track is done downloading, then wait for the next track / end.
output.Invoke(new Action(() => output.AppendText("Track Download Done!\r\n")));
- System.Threading.Thread.Sleep(400);
+ System.Threading.Thread.Sleep(100);
}
+ #region Digital Booklet
+ string[] path12 = { loc, albumArtistPath, albumNamePath + " [" + albumIDArtist + "]", qualityPath, "Digital Booklet.pdf" };
+ string goodiesPath = Path.Combine(path12);
+ // If a booklet was found, save it.
+ if (goodiesPDF == null | goodiesPDF == "")
+ {
+ // No need to download something that doesn't exist.
+ }
+ else
+ {
+ if (System.IO.File.Exists(goodiesPath))
+ {
+ // Skip, don't re-download.
+ }
+ else
+ {
+ // Save digital booklet to selected path
+ output.Invoke(new Action(() => output.AppendText("Goodies found, downloading...")));
+ using (WebClient bookClient = new WebClient())
+ {
+ // Download max quality Cover Art to "Cover.jpg" file in chosen path.
+ bookClient.DownloadFile(new Uri(goodiesPDF), goodiesPath);
+ }
+ }
+ }
+ #endregion
+
// Say that downloading is completed.
output.Invoke(new Action(() => output.AppendText("\r\n\r\n")));
output.Invoke(new Action(() => output.AppendText("Downloading job completed! All downloaded files will be located in your chosen path.")));
- mp3Checkbox.Invoke(new Action(() => mp3Checkbox.Visible = true));
- flacLowCheckbox.Invoke(new Action(() => flacLowCheckbox.Visible = true));
- flacMidCheckbox.Invoke(new Action(() => flacMidCheckbox.Visible = true));
- flacHighCheckbox.Invoke(new Action(() => flacHighCheckbox.Visible = true));
- downloadButton.Invoke(new Action(() => downloadButton.Enabled = true));
+ enableBoxes(sender, e);
}
catch (Exception ex)
{
string error = ex.ToString();
- output.Invoke(new Action(() => output.Text = String.Empty));
+ //output.Invoke(new Action(() => output.Text = String.Empty));
output.Invoke(new Action(() => output.AppendText("Failed to download (First Phase). Error information below.\r\n\r\n")));
output.Invoke(new Action(() => output.AppendText(error)));
- mp3Checkbox.Invoke(new Action(() => mp3Checkbox.Visible = true));
- flacLowCheckbox.Invoke(new Action(() => flacLowCheckbox.Visible = true));
- flacMidCheckbox.Invoke(new Action(() => flacMidCheckbox.Visible = true));
- flacHighCheckbox.Invoke(new Action(() => flacHighCheckbox.Visible = true));
- downloadButton.Invoke(new Action(() => downloadButton.Enabled = true));
+ enableBoxes(sender, e);
return;
}
}
@@ -1638,11 +1299,7 @@ namespace QobuzDownloaderX
output.Invoke(new Action(() => output.Text = String.Empty));
output.Invoke(new Action(() => output.AppendText("Artist Download ERROR. Information below.\r\n\r\n")));
output.Invoke(new Action(() => output.AppendText(error)));
- mp3Checkbox.Invoke(new Action(() => mp3Checkbox.Visible = true));
- flacLowCheckbox.Invoke(new Action(() => flacLowCheckbox.Visible = true));
- flacMidCheckbox.Invoke(new Action(() => flacMidCheckbox.Visible = true));
- flacHighCheckbox.Invoke(new Action(() => flacHighCheckbox.Visible = true));
- downloadButton.Invoke(new Action(() => downloadButton.Enabled = true));
+ enableBoxes(sender, e);
return;
}
#endregion
@@ -1652,342 +1309,294 @@ namespace QobuzDownloaderX
private async void downloadLabelBG_DoWork(object sender, DoWorkEventArgs e)
{
#region If URL has "label"
- string loc = folderBrowserDialog.SelectedPath;
+ // Set "loc" as the selected path.
+ String loc = folderBrowserDialog.SelectedPath;
- trackIdString = albumId;
+ // Create HttpClient to grab Favorites ID
+ var labelClient = new HttpClient();
+ // Run through TLS to allow secure connection.
+ ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
+ // Set user-agent to Firefox.
+ labelClient.DefaultRequestHeaders.Add("User-Agent", userAgent);
+ // Set referer to localhost that mora qualitas uses
+ labelClient.DefaultRequestHeaders.Add("Referer", "https://play.qobuz.com/album/" + albumId);
- WebRequest artistwr = WebRequest.Create("https://www.qobuz.com/api.json/0.2/label/get?label_id=" + albumId + "&extra=albums%2Cfocus&offset=0&limit=999999999999&app_id=" + appid + "&user_auth_token=" + userAuth);
-
- // Empty output, then say Starting Downloads.
+ // Empty output, then say Grabbing IDs.
output.Invoke(new Action(() => output.Text = String.Empty));
- output.Invoke(new Action(() => output.AppendText("LABEL DOWNLOADS MAY HAVE SOME ERRORS, THIS IS A NEW FEATURE. IF YOU RUN INTO AN ISSUE, PLEASE REPORT IT ON GITHUB!\r\n")));
output.Invoke(new Action(() => output.AppendText("Grabbing Album IDs...\r\n\r\n")));
try
{
- WebResponse artistws = artistwr.GetResponse();
- StreamReader artistsr = new StreamReader(artistws.GetResponseStream());
+ // Grab response from Qobuz to get Track IDs from Album response.
+ var labelUrl = "https://www.qobuz.com/api.json/0.2/label/get?label_id=" + albumId + "&extra=albums%2Cfocus&offset=0&limit=999999999999&app_id=" + appid + "&user_auth_token=" + userAuth;
+ var labelResponse = await labelClient.GetAsync(labelUrl);
+ string labelResponseString = labelResponse.Content.ReadAsStringAsync().Result;
- string artistRequest = artistsr.ReadToEnd();
+ // Grab metadata from API JSON response
+ JObject joLabelResponse = JObject.Parse(labelResponseString);
// Grab Label Name
- var labelNameLog = Regex.Match(artistRequest, "\"name\":\"(?