summaryrefslogtreecommitdiffstats
path: root/lib/libUPnP/Platinum/Source/Devices
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 18:07:22 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 18:07:22 +0000
commitc04dcc2e7d834218ef2d4194331e383402495ae1 (patch)
tree7333e38d10d75386e60f336b80c2443c1166031d /lib/libUPnP/Platinum/Source/Devices
parentInitial commit. (diff)
downloadkodi-c04dcc2e7d834218ef2d4194331e383402495ae1.tar.xz
kodi-c04dcc2e7d834218ef2d4194331e383402495ae1.zip
Adding upstream version 2:20.4+dfsg.upstream/2%20.4+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'lib/libUPnP/Platinum/Source/Devices')
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaConnect/PltMediaConnect.cpp348
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaConnect/PltMediaConnect.h110
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaConnect/PltXbox360.cpp214
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaConnect/PltXbox360.h73
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaConnect/X_MS_MediaReceiverRegistrarSCPD.cpp176
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaConnect/X_MS_MediaReceiverRegistrarSCPD.xml88
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaConnect/process_scpds.sh9
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaRenderer/AVTransportSCPD.cpp996
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaRenderer/AVTransportSCPD.xml515
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaRenderer/AVTransportSCPDFull.xml561
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaController.cpp1392
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaController.h349
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaRenderer.cpp516
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaRenderer.h119
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaRenderer/RdrConnectionManagerSCPD.cpp257
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaRenderer/RdrConnectionManagerSCPD.xml132
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaRenderer/RenderingControlSCPD.cpp434
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaRenderer/RenderingControlSCPD.xml216
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaRenderer/RenderingControlSCPD_Full.xml749
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaRenderer/process_scpds.sh15
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaServer/ConnectionManagerSCPD.cpp262
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaServer/ConnectionManagerSCPD.xml132
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaServer/ContentDirectorySCPD.cpp267
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaServer/ContentDirectorySCPD.xml148
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaServer/ContentDirectorywSearchSCPD.cpp453
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaServer/ContentDirectorywSearchSCPD.xml231
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.cpp406
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.h197
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaServer/PltFileMediaServer.cpp519
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaServer/PltFileMediaServer.h151
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaBrowser.cpp571
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaBrowser.h184
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaCache.cpp37
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaCache.h203
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp1128
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.h348
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaServer.cpp711
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaServer.h196
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.cpp578
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.h218
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaServer/process_scpds.sh15
41 files changed, 14224 insertions, 0 deletions
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaConnect/PltMediaConnect.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaConnect/PltMediaConnect.cpp
new file mode 100644
index 0000000..ccac60d
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaConnect/PltMediaConnect.cpp
@@ -0,0 +1,348 @@
+/*****************************************************************
+|
+| Platinum - AV Media Connect Device
+|
+| Copyright (c) 2004-2010, Plutinosoft, LLC.
+| All rights reserved.
+| http://www.plutinosoft.com
+|
+| This program is free software; you can redistribute it and/or
+| modify it under the terms of the GNU General Public License
+| as published by the Free Software Foundation; either version 2
+| of the License, or (at your option) any later version.
+|
+| OEMs, ISVs, VARs and other distributors that combine and
+| distribute commercially licensed software with Platinum software
+| and do not wish to distribute the source code for the commercially
+| licensed software under version 2, or (at your option) any later
+| version, of the GNU General Public License (the "GPL") must enter
+| into a commercial license agreement with Plutinosoft, LLC.
+| licensing@plutinosoft.com
+|
+| This program is distributed in the hope that it will be useful,
+| but WITHOUT ANY WARRANTY; without even the implied warranty of
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+| GNU General Public License for more details.
+|
+| You should have received a copy of the GNU General Public License
+| along with this program; see the file LICENSE.txt. If not, write to
+| the Free Software Foundation, Inc.,
+| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+| http://www.gnu.org/licenses/gpl-2.0.html
+|
+****************************************************************/
+
+/*----------------------------------------------------------------------
+| includes
++---------------------------------------------------------------------*/
+#include "Neptune.h"
+#include "Platinum.h"
+#include "PltMediaConnect.h"
+
+NPT_SET_LOCAL_LOGGER("platinum.devices.mediaconnect")
+
+/*----------------------------------------------------------------------
+| forward references
++---------------------------------------------------------------------*/
+extern NPT_UInt8 X_MS_MediaReceiverRegistrarSCPD[];
+extern NPT_UInt8 MS_ContentDirectorySCPD[];
+
+/*----------------------------------------------------------------------
+| PLT_MediaConnect::PLT_MediaConnect
++---------------------------------------------------------------------*/
+PLT_MediaConnect::PLT_MediaConnect(const char* friendly_name,
+ bool add_hostname /* = true */,
+ const char* udn /* = NULL */,
+ NPT_UInt16 port /* = 0 */,
+ bool port_rebind /* = false */) :
+ PLT_MediaServer(friendly_name, false, udn, port, port_rebind),
+ m_AddHostname(add_hostname)
+{
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaConnect::~PLT_MediaConnect
++---------------------------------------------------------------------*/
+PLT_MediaConnect::~PLT_MediaConnect()
+{
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaConnect::SetupServices
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaConnect::SetupServices()
+{
+ NPT_Reference<PLT_Service> service(new PLT_Service(
+ this,
+ "urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1",
+ "urn:microsoft.com:serviceId:X_MS_MediaReceiverRegistrar",
+ "X_MS_MediaReceiverRegistrar"));
+
+ NPT_CHECK_FATAL(service->SetSCPDXML((const char*) X_MS_MediaReceiverRegistrarSCPD));
+ NPT_CHECK_FATAL(AddService(service.AsPointer()));
+
+ service->SetStateVariable("AuthorizationGrantedUpdateID", "1");
+ service->SetStateVariable("AuthorizationDeniedUpdateID", "1");
+ service->SetStateVariable("ValidationSucceededUpdateID", "0");
+ service->SetStateVariable("ValidationRevokedUpdateID", "0");
+
+ service.Detach();
+ return PLT_MediaServer::SetupServices();
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaConnect::ProcessGetDescription
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaConnect::ProcessGetDescription(NPT_HttpRequest& request,
+ const NPT_HttpRequestContext& context,
+ NPT_HttpResponse& response)
+{
+ // lock to make sure another request is not modifying the device while we are already
+ NPT_AutoLock lock(m_Lock);
+
+ NPT_Result res = NPT_SUCCESS;
+ NPT_String oldModelName = m_ModelName;
+ NPT_String oldModelNumber = m_ModelNumber;
+ NPT_String oldModelURL = m_ModelURL;
+ NPT_String oldManufacturerURL = m_ManufacturerURL;
+ NPT_String oldDlnaDoc = m_DlnaDoc;
+ NPT_String oldDlnaCap = m_DlnaCap;
+ NPT_String oldAggregationFlags = m_AggregationFlags;
+ NPT_String oldFriendlyName = m_FriendlyName;
+
+ NPT_String hostname;
+ NPT_System::GetMachineName(hostname);
+
+ PLT_DeviceSignature signature = PLT_HttpHelper::GetDeviceSignature(request);
+
+ if (signature == PLT_DEVICE_XBOX_360 || signature == PLT_DEVICE_XBOX_ONE /*|| signature == PLT_SONOS*/) {
+ // XBox needs to see something behind a ':' to even show it
+ if (m_AddHostname && hostname.GetLength() > 0) {
+ m_FriendlyName += ": " + hostname;
+ } else if (m_FriendlyName.Find(":") == -1) {
+ m_FriendlyName += ": 1";
+ }
+ }
+ else if (m_AddHostname && hostname.GetLength() > 0) {
+ m_FriendlyName += " (" + hostname + ")";
+ }
+
+ // change some things based on device signature from request
+ if (signature == PLT_DEVICE_XBOX_360 || signature == PLT_DEVICE_XBOX_ONE || signature == PLT_DEVICE_WMP /*|| signature == PLT_SONOS*/) {
+ m_ModelName = "Windows Media Player Sharing";
+ m_ModelNumber = (signature == PLT_DEVICE_SONOS)?"3.0":"12.0";
+ m_ModelURL = "http://www.microsoft.com/";//"http://go.microsoft.com/fwlink/?LinkId=105926";
+ m_Manufacturer = (signature == PLT_DEVICE_SONOS)?"Microsoft":"Microsoft Corporation";
+ m_ManufacturerURL = "http://www.microsoft.com/";
+ m_DlnaDoc = (signature == PLT_DEVICE_SONOS)?"DMS-1.00":"DMS-1.50";
+ m_DlnaCap = "";
+ m_AggregationFlags = "";
+
+ //PLT_UPnPMessageHelper::GenerateGUID(m_SerialNumber);
+ // TODO: http://msdn.microsoft.com/en-us/library/ff362657(PROT.10).aspx
+ // TODO: <serialNumber>GUID</serialNumber>
+
+ } else if (signature == PLT_DEVICE_SONOS) {
+ m_ModelName = "Rhapsody";
+ m_ModelNumber = "3.0";
+ } else if (signature == PLT_DEVICE_PS3) {
+ m_DlnaDoc = "DMS-1.50";
+ m_DlnaCap = "";
+ m_AggregationFlags = "10";
+ }
+
+ // return description with modified params
+ res = PLT_MediaServer::ProcessGetDescription(request, context, response);
+
+ // reset to old values now
+ m_FriendlyName = oldFriendlyName;
+ m_ModelName = oldModelName;
+ m_ModelNumber = oldModelNumber;
+ m_ModelURL = oldModelURL;
+ m_ManufacturerURL = oldManufacturerURL;
+ m_DlnaDoc = oldDlnaDoc;
+ m_DlnaCap = oldDlnaCap;
+ m_AggregationFlags = oldAggregationFlags;
+
+ return res;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaConnect::ProcessGetSCPD
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaConnect::ProcessGetSCPD(PLT_Service* service,
+ NPT_HttpRequest& request,
+ const NPT_HttpRequestContext& context,
+ NPT_HttpResponse& response)
+{
+ PLT_DeviceSignature signature = PLT_HttpHelper::GetDeviceSignature(request);
+
+ // Override SCPD response by providing an SCPD without a Search action
+ // to all devices except XBox or WMP which need it
+ if (service->GetServiceType() == "urn:schemas-upnp-org:service:ContentDirectory:1" &&
+ signature != PLT_DEVICE_XBOX_360 &&
+ signature != PLT_DEVICE_XBOX_ONE &&
+ signature != PLT_DEVICE_WMP &&
+ signature != PLT_DEVICE_SONOS) {
+ NPT_HttpEntity* entity;
+ PLT_HttpHelper::SetBody(response, (const char*) MS_ContentDirectorySCPD, &entity);
+ entity->SetContentType("text/xml; charset=\"utf-8\"");
+ return NPT_SUCCESS;
+ }
+
+ return PLT_MediaServer::ProcessGetSCPD(service, request, context, response);
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaConnect::OnAction
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaConnect::OnAction(PLT_ActionReference& action,
+
+ const PLT_HttpRequestContext& context)
+{
+ /* parse the action name */
+ NPT_String name = action->GetActionDesc().GetName();
+
+ /* handle X_MS_MediaReceiverRegistrar actions here */
+ if (name.Compare("IsAuthorized") == 0) {
+ return OnIsAuthorized(action);
+ }
+ if (name.Compare("RegisterDevice") == 0) {
+ return OnRegisterDevice(action);
+ }
+ if (name.Compare("IsValidated") == 0) {
+ return OnIsValidated(action);
+ }
+
+ return PLT_MediaServer::OnAction(action, context);
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaConnect::OnIsAuthorized
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaConnect::OnIsAuthorized(PLT_ActionReference& action)
+{
+ NPT_CHECK_WARNING(action->SetArgumentValue("Result", "1"));
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaConnect::OnRegisterDevice
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaConnect::OnRegisterDevice(PLT_ActionReference& action)
+{
+ NPT_String reqMsgBase64;
+ NPT_CHECK_WARNING(action->GetArgumentValue("RegistrationReqMsg", reqMsgBase64));
+
+ NPT_String respMsgBase64;
+ NPT_CHECK_WARNING(action->SetArgumentValue("RegistrationRespMsg", respMsgBase64));
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaConnect::OnIsValidated
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaConnect::OnIsValidated(PLT_ActionReference& action)
+{
+ NPT_CHECK_WARNING(action->SetArgumentValue("Result", "1"));
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaConnect::GetMappedObjectId
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaConnect::GetMappedObjectId(const char* object_id, NPT_String& mapped_object_id)
+{
+ if (!object_id) return NPT_ERROR_INVALID_PARAMETERS;
+
+ // Reroute XBox 360 and WMP requests to our route
+ if (NPT_StringsEqual(object_id, "15")) {
+ mapped_object_id = "0/Videos"; // Videos
+ } else if (NPT_StringsEqual(object_id, "16")) {
+ mapped_object_id = "0/Photos"; // Photos
+ } else {
+ mapped_object_id = object_id;
+ }
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_FileMediaConnectDelegate::GetFilePath
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_FileMediaConnectDelegate::GetFilePath(const char* object_id, NPT_String& filepath)
+{
+ if (!object_id) return NPT_ERROR_INVALID_PARAMETERS;
+
+ // Reroute XBox 360 and WMP requests to our route
+ if (NPT_StringsEqual(object_id, "15")) {
+ return PLT_FileMediaServerDelegate::GetFilePath("", filepath); // Videos
+ } else if (NPT_StringsEqual(object_id, "16")) {
+ return PLT_FileMediaServerDelegate::GetFilePath("", filepath); // Photos
+ } else if (NPT_StringsEqual(object_id, "13") || NPT_StringsEqual(object_id, "4")) {
+ return PLT_FileMediaServerDelegate::GetFilePath("", filepath); // Music
+ }
+
+ return PLT_FileMediaServerDelegate::GetFilePath(object_id, filepath);;
+}
+
+/*----------------------------------------------------------------------
+| PLT_FileMediaConnectDelegate::OnSearchContainer
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_FileMediaConnectDelegate::OnSearchContainer(PLT_ActionReference& action,
+ const char* object_id,
+ const char* search_criteria,
+ const char* filter,
+ NPT_UInt32 starting_index,
+ NPT_UInt32 requested_count,
+ const char* sort_criteria,
+ const PLT_HttpRequestContext& context)
+{
+ /* parse search criteria */
+
+ /* TODO: HACK TO PASS DLNA */
+ if (search_criteria && NPT_StringsEqual(search_criteria, "Unknownfieldname")) {
+ /* error */
+ NPT_LOG_WARNING_1("Unsupported or invalid search criteria %s", search_criteria);
+ action->SetError(708, "Unsupported or invalid search criteria");
+ return NPT_FAILURE;
+ }
+
+ /* locate the file from the object ID */
+ NPT_String dir;
+ if (NPT_FAILED(GetFilePath(object_id, dir))) {
+ /* error */
+ NPT_LOG_WARNING("ObjectID not found.");
+ action->SetError(710, "No Such Container.");
+ return NPT_FAILURE;
+ }
+
+ /* retrieve the item type */
+ NPT_FileInfo info;
+ NPT_Result res = NPT_File::GetInfo(dir, &info);
+ if (NPT_FAILED(res) || (info.m_Type != NPT_FileInfo::FILE_TYPE_DIRECTORY)) {
+ /* error */
+ NPT_LOG_WARNING("No such container");
+ action->SetError(710, "No such container");
+ return NPT_FAILURE;
+ }
+
+ /* hack for now to return something back to XBox 360 */
+ return OnBrowseDirectChildren(action,
+ object_id,
+ filter,
+ starting_index,
+ requested_count,
+ sort_criteria,
+ context);
+}
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaConnect/PltMediaConnect.h b/lib/libUPnP/Platinum/Source/Devices/MediaConnect/PltMediaConnect.h
new file mode 100644
index 0000000..b628d9b
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaConnect/PltMediaConnect.h
@@ -0,0 +1,110 @@
+/*****************************************************************
+|
+| Platinum - AV Media Connect Device
+|
+| Copyright (c) 2004-2010, Plutinosoft, LLC.
+| All rights reserved.
+| http://www.plutinosoft.com
+|
+| This program is free software; you can redistribute it and/or
+| modify it under the terms of the GNU General Public License
+| as published by the Free Software Foundation; either version 2
+| of the License, or (at your option) any later version.
+|
+| OEMs, ISVs, VARs and other distributors that combine and
+| distribute commercially licensed software with Platinum software
+| and do not wish to distribute the source code for the commercially
+| licensed software under version 2, or (at your option) any later
+| version, of the GNU General Public License (the "GPL") must enter
+| into a commercial license agreement with Plutinosoft, LLC.
+| licensing@plutinosoft.com
+| licensing@plutinosoft.com
+|
+| This program is distributed in the hope that it will be useful,
+| but WITHOUT ANY WARRANTY; without even the implied warranty of
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+| GNU General Public License for more details.
+|
+| You should have received a copy of the GNU General Public License
+| along with this program; see the file LICENSE.txt. If not, write to
+| the Free Software Foundation, Inc.,
+| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+| http://www.gnu.org/licenses/gpl-2.0.html
+|
+****************************************************************/
+
+#ifndef _PLT_MEDIA_CONNECT_H_
+#define _PLT_MEDIA_CONNECT_H_
+
+/*----------------------------------------------------------------------
+| includes
++---------------------------------------------------------------------*/
+#include "Neptune.h"
+#include "PltFileMediaServer.h"
+
+/*----------------------------------------------------------------------
+| PLT_MediaConnect
++---------------------------------------------------------------------*/
+class PLT_MediaConnect : public PLT_MediaServer
+{
+public:
+ // class methods
+ static NPT_Result GetMappedObjectId(const char* object_id,
+ NPT_String& mapped_object_id);
+
+ // constructor
+ PLT_MediaConnect(const char* friendly_name,
+ bool add_hostname = true,
+ const char* udn = NULL,
+ NPT_UInt16 port = 0,
+ bool port_rebind = false);
+
+protected:
+ ~PLT_MediaConnect() override;
+
+ // PLT_DeviceHost methods
+ NPT_Result SetupServices() override;
+ NPT_Result OnAction(PLT_ActionReference& action,
+ const PLT_HttpRequestContext& context) override;
+ NPT_Result ProcessGetDescription(NPT_HttpRequest& request,
+ const NPT_HttpRequestContext& context,
+ NPT_HttpResponse& response) override;
+ NPT_Result ProcessGetSCPD(PLT_Service* service,
+ NPT_HttpRequest& request,
+ const NPT_HttpRequestContext& context,
+ NPT_HttpResponse& response) override;
+
+ // X_MS_MediaReceiverRegistrar
+ virtual NPT_Result OnIsAuthorized(PLT_ActionReference& action);
+ virtual NPT_Result OnRegisterDevice(PLT_ActionReference& action);
+ virtual NPT_Result OnIsValidated(PLT_ActionReference& action);
+
+protected:
+ NPT_Mutex m_Lock;
+ bool m_AddHostname;
+};
+
+/*----------------------------------------------------------------------
+ | PLT_FileMediaConnectDelegate class
+ +---------------------------------------------------------------------*/
+class PLT_FileMediaConnectDelegate : public PLT_FileMediaServerDelegate
+{
+public:
+ // constructor & destructor
+ PLT_FileMediaConnectDelegate(const char* url_root, const char* file_root) :
+ PLT_FileMediaServerDelegate(url_root, file_root) {}
+ ~PLT_FileMediaConnectDelegate() override {}
+
+ // PLT_FileMediaServerDelegate methods
+ NPT_Result GetFilePath(const char* object_id, NPT_String& filepath) override;
+ NPT_Result OnSearchContainer(PLT_ActionReference& action,
+ const char* object_id,
+ const char* search_criteria,
+ const char* filter,
+ NPT_UInt32 starting_index,
+ NPT_UInt32 requested_count,
+ const char* sort_criteria,
+ const PLT_HttpRequestContext& context) override;
+};
+
+#endif /* _PLT_MEDIA_CONNECT_H_ */
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaConnect/PltXbox360.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaConnect/PltXbox360.cpp
new file mode 100644
index 0000000..dd54bc8
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaConnect/PltXbox360.cpp
@@ -0,0 +1,214 @@
+/*****************************************************************
+|
+| Platinum - XBox 360
+|
+| Copyright (c) 2004-2010, Plutinosoft, LLC.
+| All rights reserved.
+| http://www.plutinosoft.com
+|
+| This program is free software; you can redistribute it and/or
+| modify it under the terms of the GNU General Public License
+| as published by the Free Software Foundation; either version 2
+| of the License, or (at your option) any later version.
+|
+| OEMs, ISVs, VARs and other distributors that combine and
+| distribute commercially licensed software with Platinum software
+| and do not wish to distribute the source code for the commercially
+| licensed software under version 2, or (at your option) any later
+| version, of the GNU General Public License (the "GPL") must enter
+| into a commercial license agreement with Plutinosoft, LLC.
+| licensing@plutinosoft.com
+|
+| This program is distributed in the hope that it will be useful,
+| but WITHOUT ANY WARRANTY; without even the implied warranty of
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+| GNU General Public License for more details.
+|
+| You should have received a copy of the GNU General Public License
+| along with this program; see the file LICENSE.txt. If not, write to
+| the Free Software Foundation, Inc.,
+| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+| http://www.gnu.org/licenses/gpl-2.0.html
+|
+****************************************************************/
+
+/*----------------------------------------------------------------------
+| includes
++---------------------------------------------------------------------*/
+#include "Neptune.h"
+#include "PltXbox360.h"
+#include "PltService.h"
+#include "PltUtilities.h"
+#include "PltSsdp.h"
+
+/*----------------------------------------------------------------------
+| externals
++---------------------------------------------------------------------*/
+extern NPT_UInt8 Platinum_48x48_png[4681];
+
+/*----------------------------------------------------------------------
+| PLT_Xbox360::PLT_Xbox360
++---------------------------------------------------------------------*/
+PLT_Xbox360::PLT_Xbox360(const char* uuid /* = NULL */,
+ unsigned int port /* = 0 */,
+ bool port_rebind /* = false */) :
+ PLT_MediaRenderer("Xbox 360", false, uuid, port, port_rebind)
+{
+}
+
+/*----------------------------------------------------------------------
+| PLT_Xbox360::~PLT_Xbox360
++---------------------------------------------------------------------*/
+PLT_Xbox360::~PLT_Xbox360()
+{
+}
+
+/*----------------------------------------------------------------------
+| PLT_Xbox360::SetupServices
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_Xbox360::SetupServices()
+{
+ NPT_CHECK(PLT_MediaRenderer::SetupServices());
+
+ m_ModelDescription = "Xbox 360";
+ m_ModelName = "Xbox 360";
+ m_ModelURL = "http://www.xbox.com";
+ m_Manufacturer = "Microsoft Corporation";
+ m_ManufacturerURL = "http://www.microsoft.com";
+
+ NPT_Array<PLT_Service*>::Iterator service;
+
+ if (NPT_SUCCEEDED(NPT_ContainerFind(
+ m_Services,
+ PLT_ServiceTypeFinder("urn:schemas-upnp-org:service:RenderingControl:1"),
+ service))) {
+ InitServiceURLs(*service, "RenderingControl");
+ }
+
+ if (NPT_SUCCEEDED(NPT_ContainerFind(
+ m_Services,
+ PLT_ServiceTypeFinder("urn:schemas-upnp-org:service:ConnectionManager:1"),
+ service))) {
+ InitServiceURLs(*service, "ConnectionManager");
+ }
+
+ // remove AVTransport
+ if (NPT_SUCCEEDED(NPT_ContainerFind(
+ m_Services,
+ PLT_ServiceTypeFinder("urn:schemas-upnp-org:service:AVTransport:1"),
+ service))) {
+ m_Services.Erase(service);
+ }
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_Service::InitServiceURLs
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_Xbox360::InitServiceURLs(PLT_Service* service, const char* service_name)
+{
+ service->SetSCPDURL("/Content/" + NPT_String(service_name));
+ service->SetControlURL("/Control/" + NPT_String(service_name));
+ service->SetEventSubURL("/Event/" + NPT_String(service_name));
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_Xbox360::GetDescription
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_Xbox360::GetDescription(NPT_XmlElementNode* root, NPT_XmlElementNode** device_out)
+{
+ // if no device out passed, pass one
+ NPT_XmlElementNode* device_out_local;
+ if (!device_out) device_out = &device_out_local;
+
+ NPT_CHECK(PLT_MediaRenderer::GetDescription(root, device_out));
+
+ // add extra stuff
+ root->SetNamespaceUri("ms", " urn:microsoft-com:wmc-1-0");
+ root->SetNamespaceUri("microsoft", "urn-schemas-microsoft-com:WMPNSS-1-0");
+
+ if (*device_out) {
+ (*device_out)->SetAttribute("ms", "X_MS_SupportsWMDRM", "true");
+ NPT_XmlElementNode* device_caps = new NPT_XmlElementNode("microsoft", "X_DeviceCaps");
+ device_caps->AddText("4754");
+ (*device_out)->AddChild(device_caps);
+
+ NPT_XmlElementNode* handshake = new NPT_XmlElementNode("microsoft", "HandshakeFlags");
+ handshake->AddText("1");
+ (*device_out)->AddChild(handshake);
+ }
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_Xbox360::SetupIcons
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_Xbox360::SetupIcons()
+{
+ AddIcon(
+ PLT_DeviceIcon("image/png", 48, 48, 32, "/xbox360.png"),
+ Platinum_48x48_png, sizeof(Platinum_48x48_png), false);
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_DeviceHost::Announce
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_Xbox360::Announce(PLT_DeviceData* device,
+ NPT_HttpRequest& req,
+ NPT_UdpSocket& socket,
+ PLT_SsdpAnnounceType type)
+{
+ AnnouncePresence(socket, "");
+
+ return PLT_MediaRenderer::Announce(device, req, socket, type);
+}
+
+/*----------------------------------------------------------------------
+| PLT_DeviceHost::AnnouncePresence
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_Xbox360::AnnouncePresence(NPT_UdpSocket& socket,
+ const char* serial_number)
+{
+ NPT_COMPILER_UNUSED(serial_number);
+
+ NPT_HttpRequest req(
+ NPT_HttpUrl("239.255.255.250", 1900, "*"),
+ "NOTIFY",
+ NPT_HTTP_PROTOCOL_1_1);
+ PLT_HttpHelper::SetHost(req, "239.255.255.250:1900");
+
+ NPT_Result res = NPT_SUCCESS;
+ // get location URL based on ip address of interface
+ PLT_UPnPMessageHelper::SetNTS(req, "ssdp:alive");
+ PLT_UPnPMessageHelper::SetLeaseTime(req, NPT_TimeInterval(4.));
+ PLT_UPnPMessageHelper::SetServer(req, "dashboard/1.0 UpnP/1.0 xbox/2.0", true);
+ req.GetHeaders().SetHeader("AL",
+ "<urn:schemas-microsoft-com:nhed:attributes?type=X02&firmwarever=8955.0&udn=uuid:10000000-0000-0000-0200-00125A8FEFAC>");
+ PLT_UPnPMessageHelper::SetLocation(req, "*");
+
+ // target address
+ NPT_IpAddress ip;
+ if (NPT_FAILED(res = ip.ResolveName(req.GetUrl().GetHost()))) {
+ return res;
+ }
+ NPT_SocketAddress addr(ip, req.GetUrl().GetPort());
+
+ PLT_SsdpSender::SendSsdp(req,
+ "uuid:00000000-0000-0000-0200-00125A8FEFAC::urn:schemas-microsoft-com:nhed:presence:1",
+ "urn:schemas-microsoft-com:nhed:presence:1",
+ socket,
+ true,
+ &addr);
+
+ return NPT_SUCCESS;
+}
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaConnect/PltXbox360.h b/lib/libUPnP/Platinum/Source/Devices/MediaConnect/PltXbox360.h
new file mode 100644
index 0000000..346ce57
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaConnect/PltXbox360.h
@@ -0,0 +1,73 @@
+/*****************************************************************
+|
+| Platinum - XBox 360
+|
+| Copyright (c) 2004-2010, Plutinosoft, LLC.
+| All rights reserved.
+| http://www.plutinosoft.com
+|
+| This program is free software; you can redistribute it and/or
+| modify it under the terms of the GNU General Public License
+| as published by the Free Software Foundation; either version 2
+| of the License, or (at your option) any later version.
+|
+| OEMs, ISVs, VARs and other distributors that combine and
+| distribute commercially licensed software with Platinum software
+| and do not wish to distribute the source code for the commercially
+| licensed software under version 2, or (at your option) any later
+| version, of the GNU General Public License (the "GPL") must enter
+| into a commercial license agreement with Plutinosoft, LLC.
+| licensing@plutinosoft.com
+|
+| This program is distributed in the hope that it will be useful,
+| but WITHOUT ANY WARRANTY; without even the implied warranty of
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+| GNU General Public License for more details.
+|
+| You should have received a copy of the GNU General Public License
+| along with this program; see the file LICENSE.txt. If not, write to
+| the Free Software Foundation, Inc.,
+| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+| http://www.gnu.org/licenses/gpl-2.0.html
+|
+****************************************************************/
+
+#ifndef _PLT_XBOX360_H_
+#define _PLT_XBOX360_H_
+
+/*----------------------------------------------------------------------
+| includes
++---------------------------------------------------------------------*/
+#include "PltMediaRenderer.h"
+
+class PLT_Xbox360 : public PLT_MediaRenderer
+{
+public:
+ PLT_Xbox360(const char* uuid = NULL,
+ unsigned int port = 0,
+ bool port_rebind = false);
+
+protected:
+ // PLT_DeviceHost methods
+ NPT_Result SetupServices() override;
+ NPT_Result SetupIcons() override;
+ virtual NPT_Result InitServiceURLs(PLT_Service* service, const char* service_name);
+
+ virtual NPT_Result Announce(PLT_DeviceData* device,
+ NPT_HttpRequest& request,
+ NPT_UdpSocket& socket,
+ PLT_SsdpAnnounceType type);
+
+ // PLT_DeviceData methods
+ NPT_Result GetDescription(NPT_String& desc) override { return PLT_MediaRenderer::GetDescription(desc); }
+ NPT_Result GetDescription(NPT_XmlElementNode* parent,
+ NPT_XmlElementNode** device = NULL) override;
+
+protected:
+ ~PLT_Xbox360() override;
+
+ virtual NPT_Result AnnouncePresence(NPT_UdpSocket& socket,
+ const char* serial_number);
+};
+
+#endif /* _PLT_XBOX360_H_ */
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaConnect/X_MS_MediaReceiverRegistrarSCPD.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaConnect/X_MS_MediaReceiverRegistrarSCPD.cpp
new file mode 100644
index 0000000..e05504b
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaConnect/X_MS_MediaReceiverRegistrarSCPD.cpp
@@ -0,0 +1,176 @@
+/*****************************************************************
+|
+| Platinum - MediaConnect SCPD
+|
+| Copyright (c) 2004-2010, Plutinosoft, LLC.
+| All rights reserved.
+| http://www.plutinosoft.com
+|
+| This program is free software; you can redistribute it and/or
+| modify it under the terms of the GNU General Public License
+| as published by the Free Software Foundation; either version 2
+| of the License, or (at your option) any later version.
+|
+| OEMs, ISVs, VARs and other distributors that combine and
+| distribute commercially licensed software with Platinum software
+| and do not wish to distribute the source code for the commercially
+| licensed software under version 2, or (at your option) any later
+| version, of the GNU General Public License (the "GPL") must enter
+| into a commercial license agreement with Plutinosoft, LLC.
+| licensing@plutinosoft.com
+|
+| This program is distributed in the hope that it will be useful,
+| but WITHOUT ANY WARRANTY; without even the implied warranty of
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+| GNU General Public License for more details.
+|
+| You should have received a copy of the GNU General Public License
+| along with this program; see the file LICENSE.txt. If not, write to
+| the Free Software Foundation, Inc.,
+| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+| http://www.gnu.org/licenses/gpl-2.0.html
+|
+****************************************************************/
+
+/*----------------------------------------------------------------------
+| includes
++---------------------------------------------------------------------*/
+#include "Neptune.h"
+
+/*----------------------------------------------------------------------
+| globals
++---------------------------------------------------------------------*/
+NPT_UInt8 X_MS_MediaReceiverRegistrarSCPD[2589] =
+{
+ 0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x31, 0x2E, 0x30, 0x22, 0x20,
+ 0x65, 0x6E, 0x63, 0x6F, 0x64, 0x69, 0x6E, 0x67, 0x3D, 0x22, 0x75, 0x74, 0x66, 0x2D, 0x38, 0x22, 0x3F, 0x3E, 0x0D, 0x0A,
+ 0x3C, 0x73, 0x63, 0x70, 0x64, 0x20, 0x78, 0x6D, 0x6C, 0x6E, 0x73, 0x3D, 0x27, 0x75, 0x72, 0x6E, 0x3A, 0x73, 0x63, 0x68,
+ 0x65, 0x6D, 0x61, 0x73, 0x2D, 0x75, 0x70, 0x6E, 0x70, 0x2D, 0x6F, 0x72, 0x67, 0x3A, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
+ 0x65, 0x2D, 0x31, 0x2D, 0x30, 0x27, 0x3E, 0x0D, 0x0A, 0x09, 0x3C, 0x73, 0x70, 0x65, 0x63, 0x56, 0x65, 0x72, 0x73, 0x69,
+ 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x6D, 0x61, 0x6A, 0x6F, 0x72, 0x3E, 0x31, 0x3C, 0x2F, 0x6D, 0x61, 0x6A,
+ 0x6F, 0x72, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x6D, 0x69, 0x6E, 0x6F, 0x72, 0x3E, 0x30, 0x3C, 0x2F, 0x6D, 0x69, 0x6E,
+ 0x6F, 0x72, 0x3E, 0x0D, 0x0A, 0x09, 0x3C, 0x2F, 0x73, 0x70, 0x65, 0x63, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3E,
+ 0x0D, 0x0A, 0x09, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C,
+ 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x73,
+ 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x7A, 0x65, 0x64, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09,
+ 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09,
+ 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C,
+ 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+ 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E,
+ 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C,
+ 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
+ 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x44,
+ 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
+ 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E,
+ 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x73, 0x75, 0x6C, 0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D,
+ 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E,
+ 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61,
+ 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x52, 0x65, 0x73, 0x75, 0x6C,
+ 0x74, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61,
+ 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74,
+ 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74,
+ 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x61,
+ 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x67,
+ 0x69, 0x73, 0x74, 0x65, 0x72, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A,
+ 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09,
+ 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x52, 0x65,
+ 0x71, 0x4D, 0x73, 0x67, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64,
+ 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69,
+ 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74,
+ 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59,
+ 0x50, 0x45, 0x5F, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x52, 0x65, 0x71, 0x4D, 0x73,
+ 0x67, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61,
+ 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74,
+ 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69,
+ 0x6F, 0x6E, 0x52, 0x65, 0x73, 0x70, 0x4D, 0x73, 0x67, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64,
+ 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C,
+ 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F,
+ 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6F,
+ 0x6E, 0x52, 0x65, 0x73, 0x70, 0x4D, 0x73, 0x67, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61,
+ 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61,
+ 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D,
+ 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E,
+ 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E,
+ 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x73, 0x56, 0x61, 0x6C, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x3C, 0x2F, 0x6E, 0x61, 0x6D,
+ 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74,
+ 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F,
+ 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69,
+ 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72,
+ 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x44, 0x65, 0x76,
+ 0x69, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56,
+ 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75,
+ 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74,
+ 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x73, 0x75, 0x6C, 0x74,
+ 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63,
+ 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E,
+ 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65,
+ 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F,
+ 0x52, 0x65, 0x73, 0x75, 0x6C, 0x74, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65,
+ 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67,
+ 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E,
+ 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D,
+ 0x0A, 0x09, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x3C, 0x73,
+ 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09,
+ 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64,
+ 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61,
+ 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65,
+ 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54,
+ 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65,
+ 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
+ 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20,
+ 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x09, 0x09,
+ 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x52, 0x65,
+ 0x73, 0x75, 0x6C, 0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74,
+ 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x69, 0x6E, 0x74, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E,
+ 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E,
+ 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73,
+ 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09,
+ 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x52, 0x65, 0x67,
+ 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x52, 0x65, 0x71, 0x4D, 0x73, 0x67, 0x3C, 0x2F, 0x6E, 0x61, 0x6D,
+ 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x62, 0x69, 0x6E,
+ 0x2E, 0x62, 0x61, 0x73, 0x65, 0x36, 0x34, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A,
+ 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A,
+ 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E,
+ 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E,
+ 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x52, 0x65, 0x67, 0x69, 0x73,
+ 0x74, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x52, 0x65, 0x73, 0x70, 0x4D, 0x73, 0x67, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65,
+ 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x62, 0x69, 0x6E, 0x2E,
+ 0x62, 0x61, 0x73, 0x65, 0x36, 0x34, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x09,
+ 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09,
+ 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64,
+ 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x79, 0x65, 0x73, 0x22, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E,
+ 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x7A, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x47, 0x72, 0x61,
+ 0x6E, 0x74, 0x65, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D,
+ 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x75, 0x69, 0x34, 0x3C, 0x2F, 0x64,
+ 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56,
+ 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
+ 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x79,
+ 0x65, 0x73, 0x22, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x75, 0x74, 0x68, 0x6F,
+ 0x72, 0x69, 0x7A, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x44, 0x65, 0x6E, 0x69, 0x65, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
+ 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54,
+ 0x79, 0x70, 0x65, 0x3E, 0x75, 0x69, 0x34, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A,
+ 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A,
+ 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E,
+ 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x79, 0x65, 0x73, 0x22, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C,
+ 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x56, 0x61, 0x6C, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x53, 0x75, 0x63, 0x63, 0x65,
+ 0x65, 0x64, 0x65, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D,
+ 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x75, 0x69, 0x34, 0x3C, 0x2F, 0x64,
+ 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56,
+ 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
+ 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x79,
+ 0x65, 0x73, 0x22, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x56, 0x61, 0x6C, 0x69, 0x64,
+ 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x52, 0x65, 0x76, 0x6F, 0x6B, 0x65, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x44,
+ 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70,
+ 0x65, 0x3E, 0x75, 0x69, 0x34, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09,
+ 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x3C,
+ 0x2F, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D,
+ 0x0A, 0x3C, 0x2F, 0x73, 0x63, 0x70, 0x64, 0x3E, 0x00
+};
+
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaConnect/X_MS_MediaReceiverRegistrarSCPD.xml b/lib/libUPnP/Platinum/Source/Devices/MediaConnect/X_MS_MediaReceiverRegistrarSCPD.xml
new file mode 100644
index 0000000..aa90cb0
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaConnect/X_MS_MediaReceiverRegistrarSCPD.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8"?>
+<scpd xmlns='urn:schemas-upnp-org:service-1-0'>
+ <specVersion>
+ <major>1</major>
+ <minor>0</minor>
+ </specVersion>
+ <actionList>
+ <action>
+ <name>IsAuthorized</name>
+ <argumentList>
+ <argument>
+ <name>DeviceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_DeviceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Result</name>
+ <direction>out</direction>
+ <relatedStateVariable>A_ARG_TYPE_Result</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>RegisterDevice</name>
+ <argumentList>
+ <argument>
+ <name>RegistrationReqMsg</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_RegistrationReqMsg</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>RegistrationRespMsg</name>
+ <direction>out</direction>
+ <relatedStateVariable>A_ARG_TYPE_RegistrationRespMsg</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>IsValidated</name>
+ <argumentList>
+ <argument>
+ <name>DeviceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_DeviceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Result</name>
+ <direction>out</direction>
+ <relatedStateVariable>A_ARG_TYPE_Result</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ </actionList>
+ <serviceStateTable>
+ <stateVariable sendEvents="no">
+ <name>A_ARG_TYPE_DeviceID</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>A_ARG_TYPE_Result</name>
+ <dataType>int</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>A_ARG_TYPE_RegistrationReqMsg</name>
+ <dataType>bin.base64</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>A_ARG_TYPE_RegistrationRespMsg</name>
+ <dataType>bin.base64</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="yes">
+ <name>AuthorizationGrantedUpdateID</name>
+ <dataType>ui4</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="yes">
+ <name>AuthorizationDeniedUpdateID</name>
+ <dataType>ui4</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="yes">
+ <name>ValidationSucceededUpdateID</name>
+ <dataType>ui4</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="yes">
+ <name>ValidationRevokedUpdateID</name>
+ <dataType>ui4</dataType>
+ </stateVariable>
+ </serviceStateTable>
+</scpd> \ No newline at end of file
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaConnect/process_scpds.sh b/lib/libUPnP/Platinum/Source/Devices/MediaConnect/process_scpds.sh
new file mode 100644
index 0000000..50e446b
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaConnect/process_scpds.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+set -x
+
+# abort on any errors
+set -e
+
+# ContentDirectory
+../../../Targets/x86-unknown-cygwin/Debug/TextToHeader.exe -v X_MS_MediaReceiverRegistrarSCPD -h MediaConnect X_MS_MediaReceiverRegistrarSCPD.xml X_MS_MediaReceiverRegistrarSCPD.cpp
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/AVTransportSCPD.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/AVTransportSCPD.cpp
new file mode 100644
index 0000000..4803a33
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/AVTransportSCPD.cpp
@@ -0,0 +1,996 @@
+/*****************************************************************
+|
+| Platinum - AVTransport SCPD
+|
+| Copyright (c) 2004-2010, Plutinosoft, LLC.
+| All rights reserved.
+| http://www.plutinosoft.com
+|
+| This program is free software; you can redistribute it and/or
+| modify it under the terms of the GNU General Public License
+| as published by the Free Software Foundation; either version 2
+| of the License, or (at your option) any later version.
+|
+| OEMs, ISVs, VARs and other distributors that combine and
+| distribute commercially licensed software with Platinum software
+| and do not wish to distribute the source code for the commercially
+| licensed software under version 2, or (at your option) any later
+| version, of the GNU General Public License (the "GPL") must enter
+| into a commercial license agreement with Plutinosoft, LLC.
+| licensing@plutinosoft.com
+|
+| This program is distributed in the hope that it will be useful,
+| but WITHOUT ANY WARRANTY; without even the implied warranty of
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+| GNU General Public License for more details.
+|
+| You should have received a copy of the GNU General Public License
+| along with this program; see the file LICENSE.txt. If not, write to
+| the Free Software Foundation, Inc.,
+| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+| http://www.gnu.org/licenses/gpl-2.0.html
+|
+****************************************************************/
+
+/*----------------------------------------------------------------------
+| includes
++---------------------------------------------------------------------*/
+#include "Neptune.h"
+
+/*----------------------------------------------------------------------
+| globals
++---------------------------------------------------------------------*/
+NPT_UInt8 RDR_AVTransportSCPD[] =
+{
+ 0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x31, 0x2E, 0x30, 0x22, 0x20,
+ 0x65, 0x6E, 0x63, 0x6F, 0x64, 0x69, 0x6E, 0x67, 0x3D, 0x22, 0x75, 0x74, 0x66, 0x2D, 0x38, 0x22, 0x3F, 0x3E, 0x0A, 0x3C,
+ 0x73, 0x63, 0x70, 0x64, 0x20, 0x78, 0x6D, 0x6C, 0x6E, 0x73, 0x3D, 0x22, 0x75, 0x72, 0x6E, 0x3A, 0x73, 0x63, 0x68, 0x65,
+ 0x6D, 0x61, 0x73, 0x2D, 0x75, 0x70, 0x6E, 0x70, 0x2D, 0x6F, 0x72, 0x67, 0x3A, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+ 0x2D, 0x31, 0x2D, 0x30, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x65, 0x63, 0x56, 0x65, 0x72, 0x73, 0x69,
+ 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6D, 0x61, 0x6A, 0x6F, 0x72, 0x3E, 0x31, 0x3C, 0x2F,
+ 0x6D, 0x61, 0x6A, 0x6F, 0x72, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6D, 0x69, 0x6E, 0x6F, 0x72, 0x3E,
+ 0x30, 0x3C, 0x2F, 0x6D, 0x69, 0x6E, 0x6F, 0x72, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x70, 0x65, 0x63, 0x56,
+ 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x4C, 0x69,
+ 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72,
+ 0x72, 0x65, 0x6E, 0x74, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x73,
+ 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72,
+ 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74,
+ 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E,
+ 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74,
+ 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59,
+ 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74,
+ 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E,
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65,
+ 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65,
+ 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E,
+ 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65,
+ 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x43,
+ 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6F,
+ 0x6E, 0x73, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69,
+ 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F,
+ 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63,
+ 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65,
+ 0x3E, 0x47, 0x65, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6C, 0x69, 0x74, 0x69,
+ 0x65, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E,
+ 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F,
+ 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64,
+ 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F,
+ 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C,
+ 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E,
+ 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75,
+ 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x50, 0x6C, 0x61, 0x79, 0x4D, 0x65, 0x64, 0x69, 0x61, 0x3C, 0x2F, 0x6E, 0x61,
+ 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63,
+ 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
+ 0x6C, 0x65, 0x3E, 0x50, 0x6F, 0x73, 0x73, 0x69, 0x62, 0x6C, 0x65, 0x50, 0x6C, 0x61, 0x79, 0x62, 0x61, 0x63, 0x6B, 0x53,
+ 0x74, 0x6F, 0x72, 0x61, 0x67, 0x65, 0x4D, 0x65, 0x64, 0x69, 0x61, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64,
+ 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74,
+ 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61,
+ 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x63, 0x4D, 0x65, 0x64, 0x69, 0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63,
+ 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E,
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C,
+ 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x50, 0x6F,
+ 0x73, 0x73, 0x69, 0x62, 0x6C, 0x65, 0x52, 0x65, 0x63, 0x6F, 0x72, 0x64, 0x53, 0x74, 0x6F, 0x72, 0x61, 0x67, 0x65, 0x4D,
+ 0x65, 0x64, 0x69, 0x61, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
+ 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x63, 0x51,
+ 0x75, 0x61, 0x6C, 0x69, 0x74, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63,
+ 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E,
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C,
+ 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x50, 0x6F,
+ 0x73, 0x73, 0x69, 0x62, 0x6C, 0x65, 0x52, 0x65, 0x63, 0x6F, 0x72, 0x64, 0x51, 0x75, 0x61, 0x6C, 0x69, 0x74, 0x79, 0x4D,
+ 0x6F, 0x64, 0x65, 0x73, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
+ 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61,
+ 0x6D, 0x65, 0x3E, 0x47, 0x65, 0x74, 0x4D, 0x65, 0x64, 0x69, 0x61, 0x49, 0x6E, 0x66, 0x6F, 0x3C, 0x2F, 0x6E, 0x61, 0x6D,
+ 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E,
+ 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49,
+ 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64,
+ 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
+ 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E,
+ 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61,
+ 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+ 0x4E, 0x72, 0x54, 0x72, 0x61, 0x63, 0x6B, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F,
+ 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65,
+ 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x4E, 0x75, 0x6D, 0x62, 0x65,
+ 0x72, 0x4F, 0x66, 0x54, 0x72, 0x61, 0x63, 0x6B, 0x73, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74,
+ 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65,
+ 0x3E, 0x4D, 0x65, 0x64, 0x69, 0x61, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65,
+ 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69,
+ 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69,
+ 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
+ 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x4D, 0x65, 0x64, 0x69, 0x61, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6F,
+ 0x6E, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61,
+ 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61,
+ 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74,
+ 0x55, 0x52, 0x49, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74,
+ 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74,
+ 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72,
+ 0x74, 0x55, 0x52, 0x49, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
+ 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72,
+ 0x65, 0x6E, 0x74, 0x55, 0x52, 0x49, 0x4D, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65,
+ 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69,
+ 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69,
+ 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
+ 0x3E, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x55, 0x52, 0x49, 0x4D, 0x65, 0x74, 0x61, 0x44,
+ 0x61, 0x74, 0x61, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72,
+ 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4E, 0x65, 0x78, 0x74, 0x55,
+ 0x52, 0x49, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C,
+ 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65,
+ 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x4E, 0x65, 0x78, 0x74, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73,
+ 0x70, 0x6F, 0x72, 0x74, 0x55, 0x52, 0x49, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74,
+ 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4E,
+ 0x65, 0x78, 0x74, 0x55, 0x52, 0x49, 0x4D, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65,
+ 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69,
+ 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69,
+ 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
+ 0x3E, 0x4E, 0x65, 0x78, 0x74, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x55, 0x52, 0x49, 0x4D,
+ 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74,
+ 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x50,
+ 0x6C, 0x61, 0x79, 0x4D, 0x65, 0x64, 0x69, 0x75, 0x6D, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69,
+ 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74,
+ 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x50, 0x6C, 0x61, 0x79,
+ 0x62, 0x61, 0x63, 0x6B, 0x53, 0x74, 0x6F, 0x72, 0x61, 0x67, 0x65, 0x4D, 0x65, 0x64, 0x69, 0x75, 0x6D, 0x3C, 0x2F, 0x72,
+ 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E,
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D,
+ 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72,
+ 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x63, 0x6F, 0x72, 0x64, 0x4D, 0x65, 0x64, 0x69, 0x75,
+ 0x6D, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F,
+ 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56,
+ 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x52, 0x65, 0x63, 0x6F, 0x72, 0x64, 0x53, 0x74, 0x6F, 0x72, 0x61, 0x67,
+ 0x65, 0x4D, 0x65, 0x64, 0x69, 0x75, 0x6D, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74,
+ 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x57,
+ 0x72, 0x69, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74,
+ 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61,
+ 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x52, 0x65, 0x63,
+ 0x6F, 0x72, 0x64, 0x4D, 0x65, 0x64, 0x69, 0x75, 0x6D, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
+ 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
+ 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72,
+ 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61,
+ 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69,
+ 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x47,
+ 0x65, 0x74, 0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x49, 0x6E, 0x66, 0x6F, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65,
+ 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74,
+ 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61,
+ 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44,
+ 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69,
+ 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72,
+ 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73,
+ 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74,
+ 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x54,
+ 0x72, 0x61, 0x63, 0x6B, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75,
+ 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61,
+ 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x72,
+ 0x61, 0x63, 0x6B, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72,
+ 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x54, 0x72, 0x61, 0x63, 0x6B,
+ 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F,
+ 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65,
+ 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65,
+ 0x6E, 0x74, 0x54, 0x72, 0x61, 0x63, 0x6B, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x3C, 0x2F, 0x72, 0x65, 0x6C,
+ 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E,
+ 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75,
+ 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x54, 0x72, 0x61, 0x63, 0x6B, 0x4D, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61,
+ 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64,
+ 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
+ 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x72, 0x61, 0x63, 0x6B, 0x4D,
+ 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74,
+ 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x54,
+ 0x72, 0x61, 0x63, 0x6B, 0x55, 0x52, 0x49, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E,
+ 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64,
+ 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E,
+ 0x74, 0x54, 0x72, 0x61, 0x63, 0x6B, 0x55, 0x52, 0x49, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74,
+ 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65,
+ 0x3E, 0x52, 0x65, 0x6C, 0x54, 0x69, 0x6D, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F,
+ 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65,
+ 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x52, 0x65, 0x6C, 0x61, 0x74,
+ 0x69, 0x76, 0x65, 0x54, 0x69, 0x6D, 0x65, 0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3C, 0x2F, 0x72, 0x65, 0x6C,
+ 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E,
+ 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75,
+ 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x62, 0x73, 0x54, 0x69, 0x6D, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65,
+ 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69,
+ 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69,
+ 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
+ 0x3E, 0x41, 0x62, 0x73, 0x6F, 0x6C, 0x75, 0x74, 0x65, 0x54, 0x69, 0x6D, 0x65, 0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F,
+ 0x6E, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61,
+ 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61,
+ 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x6C, 0x43, 0x6F, 0x75, 0x6E,
+ 0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F,
+ 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56,
+ 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x52, 0x65, 0x6C, 0x61, 0x74, 0x69, 0x76, 0x65, 0x43, 0x6F, 0x75, 0x6E,
+ 0x74, 0x65, 0x72, 0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64,
+ 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74,
+ 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61,
+ 0x6D, 0x65, 0x3E, 0x41, 0x62, 0x73, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63,
+ 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E,
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C,
+ 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x62,
+ 0x73, 0x6F, 0x6C, 0x75, 0x74, 0x65, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x65, 0x72, 0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F,
+ 0x6E, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61,
+ 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61,
+ 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F,
+ 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74,
+ 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+ 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x49, 0x6E, 0x66, 0x6F, 0x3C, 0x2F, 0x6E, 0x61,
+ 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65,
+ 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65,
+ 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F,
+ 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56,
+ 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49,
+ 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74,
+ 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65,
+ 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x53, 0x74, 0x61,
+ 0x74, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C,
+ 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65,
+ 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x53, 0x74,
+ 0x61, 0x74, 0x65, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72,
+ 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65,
+ 0x6E, 0x74, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3C, 0x2F, 0x6E,
+ 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65,
+ 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61,
+ 0x62, 0x6C, 0x65, 0x3E, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3C,
+ 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C,
+ 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67,
+ 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x53, 0x70,
+ 0x65, 0x65, 0x64, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74,
+ 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74,
+ 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x50,
+ 0x6C, 0x61, 0x79, 0x53, 0x70, 0x65, 0x65, 0x64, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61,
+ 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E,
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x53,
+ 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74,
+ 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61,
+ 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72,
+ 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E,
+ 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65,
+ 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41,
+ 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44,
+ 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
+ 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72,
+ 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x50, 0x6C, 0x61, 0x79, 0x4D, 0x6F, 0x64, 0x65,
+ 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64,
+ 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
+ 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x50, 0x6C, 0x61, 0x79, 0x4D, 0x6F,
+ 0x64, 0x65, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69,
+ 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F,
+ 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x63, 0x51, 0x75, 0x61,
+ 0x6C, 0x69, 0x74, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F,
+ 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65,
+ 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65,
+ 0x6E, 0x74, 0x52, 0x65, 0x63, 0x6F, 0x72, 0x64, 0x51, 0x75, 0x61, 0x6C, 0x69, 0x74, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x3C,
+ 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C,
+ 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67,
+ 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72,
+ 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F,
+ 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F,
+ 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4E, 0x65,
+ 0x78, 0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E,
+ 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F,
+ 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64,
+ 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F,
+ 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C,
+ 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E,
+ 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65,
+ 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69,
+ 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x50, 0x61, 0x75, 0x73, 0x65, 0x3C,
+ 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67,
+ 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61,
+ 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69,
+ 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61,
+ 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50,
+ 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65,
+ 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C,
+ 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E,
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x50, 0x6C, 0x61, 0x79, 0x3C, 0x2F, 0x6E, 0x61, 0x6D,
+ 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E,
+ 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49,
+ 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64,
+ 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
+ 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E,
+ 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61,
+ 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+ 0x53, 0x70, 0x65, 0x65, 0x64, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69,
+ 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61,
+ 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74,
+ 0x50, 0x6C, 0x61, 0x79, 0x53, 0x70, 0x65, 0x65, 0x64, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74,
+ 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74,
+ 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x50, 0x72, 0x65, 0x76, 0x69, 0x6F, 0x75, 0x73, 0x3C, 0x2F, 0x6E, 0x61,
+ 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65,
+ 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65,
+ 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F,
+ 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56,
+ 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49,
+ 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74,
+ 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74,
+ 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x65, 0x65, 0x6B, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69,
+ 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67,
+ 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F,
+ 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65,
+ 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61,
+ 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61,
+ 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56,
+ 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x55, 0x6E, 0x69,
+ 0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64,
+ 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
+ 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x53, 0x65,
+ 0x65, 0x6B, 0x4D, 0x6F, 0x64, 0x65, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65,
+ 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x54, 0x61,
+ 0x72, 0x67, 0x65, 0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E,
+ 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74,
+ 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45,
+ 0x5F, 0x53, 0x65, 0x65, 0x6B, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64,
+ 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69,
+ 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x65, 0x74, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73,
+ 0x70, 0x6F, 0x72, 0x74, 0x55, 0x52, 0x49, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74,
+ 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61,
+ 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72,
+ 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E,
+ 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65,
+ 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41,
+ 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44,
+ 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
+ 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72,
+ 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x55,
+ 0x52, 0x49, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F,
+ 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56,
+ 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x55,
+ 0x52, 0x49, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69,
+ 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F,
+ 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E,
+ 0x74, 0x55, 0x52, 0x49, 0x4D, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65,
+ 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E,
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C,
+ 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x56,
+ 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x55, 0x52, 0x49, 0x4D, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61,
+ 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
+ 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72,
+ 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61,
+ 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69,
+ 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53,
+ 0x65, 0x74, 0x4E, 0x65, 0x78, 0x74, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x55, 0x52, 0x49,
+ 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72,
+ 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74,
+ 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E,
+ 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74,
+ 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59,
+ 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74,
+ 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E,
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65,
+ 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4E, 0x65, 0x78, 0x74, 0x55, 0x52, 0x49, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65,
+ 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E,
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C,
+ 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x4E, 0x65,
+ 0x78, 0x74, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x55, 0x52, 0x49, 0x3C, 0x2F, 0x72, 0x65,
+ 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65,
+ 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67,
+ 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4E, 0x65, 0x78, 0x74, 0x55, 0x52, 0x49, 0x4D, 0x65, 0x74, 0x61, 0x44,
+ 0x61, 0x74, 0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C,
+ 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65,
+ 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x4E, 0x65, 0x78, 0x74, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73,
+ 0x70, 0x6F, 0x72, 0x74, 0x55, 0x52, 0x49, 0x4D, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x3C, 0x2F, 0x72, 0x65, 0x6C,
+ 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E,
+ 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65,
+ 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69,
+ 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x65, 0x74, 0x50, 0x6C, 0x61,
+ 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65,
+ 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63,
+ 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61,
+ 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41,
+ 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F,
+ 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
+ 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75,
+ 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61,
+ 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4E, 0x65, 0x77, 0x50, 0x6C, 0x61, 0x79, 0x4D, 0x6F, 0x64,
+ 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64,
+ 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
+ 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x50, 0x6C, 0x61, 0x79, 0x4D, 0x6F,
+ 0x64, 0x65, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69,
+ 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F,
+ 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63,
+ 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65,
+ 0x3E, 0x53, 0x74, 0x6F, 0x70, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65,
+ 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63,
+ 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61,
+ 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41,
+ 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F,
+ 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
+ 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75,
+ 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67,
+ 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61,
+ 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x4C, 0x69,
+ 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65,
+ 0x54, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56,
+ 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22,
+ 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+ 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x50, 0x6C, 0x61, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D,
+ 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70,
+ 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C,
+ 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x4E, 0x4F, 0x52, 0x4D, 0x41, 0x4C,
+ 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75,
+ 0x65, 0x3E, 0x52, 0x45, 0x50, 0x45, 0x41, 0x54, 0x5F, 0x4F, 0x4E, 0x45, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65,
+ 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x52, 0x45, 0x50, 0x45, 0x41, 0x54,
+ 0x5F, 0x41, 0x4C, 0x4C, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64,
+ 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x53, 0x48, 0x55, 0x46, 0x46, 0x4C, 0x45, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77,
+ 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x53, 0x48, 0x55, 0x46, 0x46,
+ 0x4C, 0x45, 0x5F, 0x4E, 0x4F, 0x52, 0x45, 0x50, 0x45, 0x41, 0x54, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64,
+ 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C,
+ 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x4E,
+ 0x4F, 0x52, 0x4D, 0x41, 0x4C, 0x3C, 0x2F, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E,
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
+ 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69,
+ 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22,
+ 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x63,
+ 0x6F, 0x72, 0x64, 0x53, 0x74, 0x6F, 0x72, 0x61, 0x67, 0x65, 0x4D, 0x65, 0x64, 0x69, 0x75, 0x6D, 0x3C, 0x2F, 0x6E, 0x61,
+ 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79,
+ 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E,
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61,
+ 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x4E, 0x4F, 0x54, 0x5F, 0x49,
+ 0x4D, 0x50, 0x4C, 0x45, 0x4D, 0x45, 0x4E, 0x54, 0x45, 0x44, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56,
+ 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C, 0x6C,
+ 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73,
+ 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x79, 0x65, 0x73, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4C, 0x61, 0x73, 0x74, 0x43, 0x68, 0x61, 0x6E,
+ 0x67, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74,
+ 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65,
+ 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61,
+ 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74,
+ 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61,
+ 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x6C, 0x61, 0x74, 0x69, 0x76, 0x65, 0x54, 0x69, 0x6D, 0x65, 0x50, 0x6F, 0x73, 0x69, 0x74,
+ 0x69, 0x6F, 0x6E, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61,
+ 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74,
+ 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74,
+ 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E,
+ 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E,
+ 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x72, 0x61, 0x63, 0x6B, 0x55, 0x52, 0x49, 0x3C,
+ 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74,
+ 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79,
+ 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72,
+ 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56,
+ 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22,
+ 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+ 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x72, 0x61, 0x63, 0x6B, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E,
+ 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61,
+ 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54,
+ 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
+ 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65,
+ 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D,
+ 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65,
+ 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x52, 0x65, 0x63, 0x6F, 0x72, 0x64, 0x51, 0x75, 0x61, 0x6C, 0x69, 0x74,
+ 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F,
+ 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61,
+ 0x6C, 0x75, 0x65, 0x3E, 0x4E, 0x4F, 0x54, 0x5F, 0x49, 0x4D, 0x50, 0x4C, 0x45, 0x4D, 0x45, 0x4E, 0x54, 0x45, 0x44, 0x3C,
+ 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69,
+ 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72,
+ 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56,
+ 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22,
+ 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+ 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x4D, 0x65, 0x64, 0x69, 0x61, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E,
+ 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61,
+ 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54,
+ 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
+ 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65,
+ 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D,
+ 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65,
+ 0x3E, 0x41, 0x62, 0x73, 0x6F, 0x6C, 0x75, 0x74, 0x65, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x65, 0x72, 0x50, 0x6F, 0x73, 0x69,
+ 0x74, 0x69, 0x6F, 0x6E, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x69, 0x34, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54,
+ 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
+ 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65,
+ 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D,
+ 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65,
+ 0x3E, 0x52, 0x65, 0x6C, 0x61, 0x74, 0x69, 0x76, 0x65, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x65, 0x72, 0x50, 0x6F, 0x73, 0x69,
+ 0x74, 0x69, 0x6F, 0x6E, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x69, 0x34, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54,
+ 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
+ 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65,
+ 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D,
+ 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65,
+ 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65,
+ 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x75, 0x69, 0x34, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79,
+ 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72,
+ 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56,
+ 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22,
+ 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+ 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x55, 0x52, 0x49, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65,
+ 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65,
+ 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
+ 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
+ 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x54, 0x72, 0x61, 0x6E, 0x73,
+ 0x70, 0x6F, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69,
+ 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74,
+ 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77,
+ 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x53, 0x54, 0x4F, 0x50, 0x50, 0x45, 0x44, 0x3C, 0x2F, 0x61, 0x6C, 0x6C,
+ 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x50, 0x41, 0x55,
+ 0x53, 0x45, 0x44, 0x5F, 0x50, 0x4C, 0x41, 0x59, 0x42, 0x41, 0x43, 0x4B, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65,
+ 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x50, 0x4C, 0x41, 0x59, 0x49, 0x4E,
+ 0x47, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C,
+ 0x75, 0x65, 0x3E, 0x54, 0x52, 0x41, 0x4E, 0x53, 0x49, 0x54, 0x49, 0x4F, 0x4E, 0x49, 0x4E, 0x47, 0x3C, 0x2F, 0x61, 0x6C,
+ 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x4E, 0x4F,
+ 0x5F, 0x4D, 0x45, 0x44, 0x49, 0x41, 0x5F, 0x50, 0x52, 0x45, 0x53, 0x45, 0x4E, 0x54, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F,
+ 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
+ 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
+ 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65,
+ 0x6E, 0x74, 0x54, 0x72, 0x61, 0x63, 0x6B, 0x4D, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D,
+ 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70,
+ 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C,
+ 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61,
+ 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E,
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4E, 0x65, 0x78, 0x74,
+ 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x55, 0x52, 0x49, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65,
+ 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65,
+ 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
+ 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
+ 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x50, 0x6F, 0x73, 0x73, 0x69,
+ 0x62, 0x6C, 0x65, 0x52, 0x65, 0x63, 0x6F, 0x72, 0x64, 0x51, 0x75, 0x61, 0x6C, 0x69, 0x74, 0x79, 0x4D, 0x6F, 0x64, 0x65,
+ 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64,
+ 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61,
+ 0x54, 0x79, 0x70, 0x65, 0x3E, 0x20, 0x20, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C,
+ 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75,
+ 0x65, 0x3E, 0x4E, 0x4F, 0x54, 0x5F, 0x49, 0x4D, 0x50, 0x4C, 0x45, 0x4D, 0x45, 0x4E, 0x54, 0x45, 0x44, 0x3C, 0x2F, 0x61,
+ 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74,
+ 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61,
+ 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72,
+ 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F,
+ 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x75,
+ 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x72, 0x61, 0x63, 0x6B, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x75, 0x69, 0x34,
+ 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x52, 0x61, 0x6E, 0x67, 0x65, 0x3E,
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6D, 0x69, 0x6E, 0x69, 0x6D, 0x75,
+ 0x6D, 0x3E, 0x30, 0x3C, 0x2F, 0x6D, 0x69, 0x6E, 0x69, 0x6D, 0x75, 0x6D, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6D, 0x61, 0x78, 0x69, 0x6D, 0x75, 0x6D, 0x3E, 0x36, 0x35, 0x35, 0x33, 0x35,
+ 0x3C, 0x2F, 0x6D, 0x61, 0x78, 0x69, 0x6D, 0x75, 0x6D, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x65, 0x70, 0x3E, 0x31, 0x3C, 0x2F, 0x73, 0x74, 0x65, 0x70, 0x3E, 0x0A, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75,
+ 0x65, 0x52, 0x61, 0x6E, 0x67, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74,
+ 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74,
+ 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E,
+ 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E,
+ 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x62, 0x73, 0x6F, 0x6C, 0x75, 0x74, 0x65, 0x54, 0x69, 0x6D, 0x65, 0x50, 0x6F, 0x73, 0x69,
+ 0x74, 0x69, 0x6F, 0x6E, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64,
+ 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61,
+ 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73,
+ 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65,
+ 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4E, 0x65, 0x78, 0x74, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74,
+ 0x55, 0x52, 0x49, 0x4D, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74,
+ 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20,
+ 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x50, 0x6C, 0x61, 0x79, 0x62, 0x61, 0x63, 0x6B,
+ 0x53, 0x74, 0x6F, 0x72, 0x61, 0x67, 0x65, 0x4D, 0x65, 0x64, 0x69, 0x75, 0x6D, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E,
+ 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65,
+ 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61,
+ 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x4E, 0x4F, 0x4E, 0x45, 0x3C, 0x2F, 0x61, 0x6C,
+ 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x55, 0x4E,
+ 0x4B, 0x4E, 0x4F, 0x57, 0x4E, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E,
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65,
+ 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x43, 0x44, 0x2D, 0x44, 0x41, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65,
+ 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x48, 0x44, 0x44, 0x3C, 0x2F, 0x61,
+ 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x4E,
+ 0x45, 0x54, 0x57, 0x4F, 0x52, 0x4B, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65,
+ 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64,
+ 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73,
+ 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45,
+ 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70,
+ 0x6F, 0x72, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72,
+ 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73,
+ 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x63, 0x6F, 0x72, 0x64, 0x4D, 0x65, 0x64,
+ 0x69, 0x75, 0x6D, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65,
+ 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65,
+ 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75,
+ 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x4E, 0x4F, 0x54, 0x5F, 0x49, 0x4D, 0x50,
+ 0x4C, 0x45, 0x4D, 0x45, 0x4E, 0x54, 0x45, 0x44, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C,
+ 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77,
+ 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E,
+ 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x50, 0x6F, 0x73, 0x73, 0x69, 0x62, 0x6C, 0x65, 0x50, 0x6C, 0x61,
+ 0x79, 0x62, 0x61, 0x63, 0x6B, 0x53, 0x74, 0x6F, 0x72, 0x61, 0x67, 0x65, 0x4D, 0x65, 0x64, 0x69, 0x61, 0x3C, 0x2F, 0x6E,
+ 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54,
+ 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65,
+ 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56,
+ 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x4E, 0x4F, 0x4E, 0x45,
+ 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75,
+ 0x65, 0x3E, 0x55, 0x4E, 0x4B, 0x4E, 0x4F, 0x57, 0x4E, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61,
+ 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C,
+ 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x43, 0x44, 0x2D, 0x44, 0x41, 0x3C, 0x2F, 0x61, 0x6C,
+ 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x48, 0x44,
+ 0x44, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C,
+ 0x75, 0x65, 0x3E, 0x4E, 0x45, 0x54, 0x57, 0x4F, 0x52, 0x4B, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56,
+ 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C, 0x6C,
+ 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73,
+ 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F,
+ 0x72, 0x74, 0x55, 0x52, 0x49, 0x4D, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E,
+ 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E,
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C,
+ 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4E, 0x75, 0x6D, 0x62, 0x65, 0x72,
+ 0x4F, 0x66, 0x54, 0x72, 0x61, 0x63, 0x6B, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x75, 0x69, 0x34, 0x3C, 0x2F,
+ 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x52, 0x61, 0x6E, 0x67, 0x65, 0x3E, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6D, 0x69, 0x6E, 0x69, 0x6D, 0x75, 0x6D, 0x3E,
+ 0x30, 0x3C, 0x2F, 0x6D, 0x69, 0x6E, 0x69, 0x6D, 0x75, 0x6D, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6D, 0x61, 0x78, 0x69, 0x6D, 0x75, 0x6D, 0x3E, 0x36, 0x35, 0x35, 0x33, 0x35, 0x3C, 0x2F,
+ 0x6D, 0x61, 0x78, 0x69, 0x6D, 0x75, 0x6D, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F,
+ 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x52, 0x61, 0x6E, 0x67, 0x65, 0x3E, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
+ 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
+ 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47,
+ 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x53, 0x65, 0x65, 0x6B, 0x4D, 0x6F, 0x64, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65,
+ 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65,
+ 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75,
+ 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x52, 0x45, 0x4C, 0x5F, 0x54, 0x49, 0x4D,
+ 0x45, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C,
+ 0x75, 0x65, 0x3E, 0x54, 0x52, 0x41, 0x43, 0x4B, 0x5F, 0x4E, 0x52, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64,
+ 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C,
+ 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20,
+ 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59,
+ 0x50, 0x45, 0x5F, 0x53, 0x65, 0x65, 0x6B, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E,
+ 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E,
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C,
+ 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x50, 0x6F, 0x73, 0x73, 0x69, 0x62,
+ 0x6C, 0x65, 0x52, 0x65, 0x63, 0x6F, 0x72, 0x64, 0x53, 0x74, 0x6F, 0x72, 0x61, 0x67, 0x65, 0x4D, 0x65, 0x64, 0x69, 0x61,
+ 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61,
+ 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54,
+ 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77,
+ 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x4E,
+ 0x4F, 0x54, 0x5F, 0x49, 0x4D, 0x50, 0x4C, 0x45, 0x4D, 0x45, 0x4E, 0x54, 0x45, 0x44, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F,
+ 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
+ 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
+ 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x54, 0x72, 0x61, 0x6E, 0x73,
+ 0x70, 0x6F, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72,
+ 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73,
+ 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F,
+ 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x4F, 0x4B, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64,
+ 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x45, 0x52, 0x52, 0x4F, 0x52, 0x5F, 0x4F,
+ 0x43, 0x43, 0x55, 0x52, 0x52, 0x45, 0x44, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75,
+ 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65,
+ 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F,
+ 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64,
+ 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x50, 0x6C, 0x61,
+ 0x79, 0x53, 0x70, 0x65, 0x65, 0x64, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C,
+ 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56,
+ 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x31, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65,
+ 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64,
+ 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73,
+ 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73,
+ 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x3C, 0x2F,
+ 0x73, 0x63, 0x70, 0x64, 0x3E, 0x00
+};
+
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/AVTransportSCPD.xml b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/AVTransportSCPD.xml
new file mode 100644
index 0000000..f9ee988
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/AVTransportSCPD.xml
@@ -0,0 +1,515 @@
+<?xml version="1.0" encoding="utf-8"?>
+<scpd xmlns="urn:schemas-upnp-org:service-1-0">
+ <specVersion>
+ <major>1</major>
+ <minor>0</minor>
+ </specVersion>
+ <actionList>
+ <action>
+ <name>GetCurrentTransportActions</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Actions</name>
+ <direction>out</direction>
+ <relatedStateVariable>CurrentTransportActions</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetDeviceCapabilities</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>PlayMedia</name>
+ <direction>out</direction>
+ <relatedStateVariable>PossiblePlaybackStorageMedia</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>RecMedia</name>
+ <direction>out</direction>
+ <relatedStateVariable>PossibleRecordStorageMedia</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>RecQualityModes</name>
+ <direction>out</direction>
+ <relatedStateVariable>PossibleRecordQualityModes</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetMediaInfo</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>NrTracks</name>
+ <direction>out</direction>
+ <relatedStateVariable>NumberOfTracks</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>MediaDuration</name>
+ <direction>out</direction>
+ <relatedStateVariable>CurrentMediaDuration</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentURI</name>
+ <direction>out</direction>
+ <relatedStateVariable>AVTransportURI</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentURIMetaData</name>
+ <direction>out</direction>
+ <relatedStateVariable>AVTransportURIMetaData</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>NextURI</name>
+ <direction>out</direction>
+ <relatedStateVariable>NextAVTransportURI</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>NextURIMetaData</name>
+ <direction>out</direction>
+ <relatedStateVariable>NextAVTransportURIMetaData</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>PlayMedium</name>
+ <direction>out</direction>
+ <relatedStateVariable>PlaybackStorageMedium</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>RecordMedium</name>
+ <direction>out</direction>
+ <relatedStateVariable>RecordStorageMedium</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>WriteStatus</name>
+ <direction>out</direction>
+ <relatedStateVariable>RecordMediumWriteStatus</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetPositionInfo</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Track</name>
+ <direction>out</direction>
+ <relatedStateVariable>CurrentTrack</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>TrackDuration</name>
+ <direction>out</direction>
+ <relatedStateVariable>CurrentTrackDuration</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>TrackMetaData</name>
+ <direction>out</direction>
+ <relatedStateVariable>CurrentTrackMetaData</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>TrackURI</name>
+ <direction>out</direction>
+ <relatedStateVariable>CurrentTrackURI</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>RelTime</name>
+ <direction>out</direction>
+ <relatedStateVariable>RelativeTimePosition</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>AbsTime</name>
+ <direction>out</direction>
+ <relatedStateVariable>AbsoluteTimePosition</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>RelCount</name>
+ <direction>out</direction>
+ <relatedStateVariable>RelativeCounterPosition</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>AbsCount</name>
+ <direction>out</direction>
+ <relatedStateVariable>AbsoluteCounterPosition</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetTransportInfo</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentTransportState</name>
+ <direction>out</direction>
+ <relatedStateVariable>TransportState</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentTransportStatus</name>
+ <direction>out</direction>
+ <relatedStateVariable>TransportStatus</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentSpeed</name>
+ <direction>out</direction>
+ <relatedStateVariable>TransportPlaySpeed</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetTransportSettings</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>PlayMode</name>
+ <direction>out</direction>
+ <relatedStateVariable>CurrentPlayMode</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>RecQualityMode</name>
+ <direction>out</direction>
+ <relatedStateVariable>CurrentRecordQualityMode</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>Next</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>Pause</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>Play</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Speed</name>
+ <direction>in</direction>
+ <relatedStateVariable>TransportPlaySpeed</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>Previous</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>Seek</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Unit</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_SeekMode</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Target</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_SeekTarget</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>SetAVTransportURI</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentURI</name>
+ <direction>in</direction>
+ <relatedStateVariable>AVTransportURI</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentURIMetaData</name>
+ <direction>in</direction>
+ <relatedStateVariable>AVTransportURIMetaData</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>SetNextAVTransportURI</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>NextURI</name>
+ <direction>in</direction>
+ <relatedStateVariable>NextAVTransportURI</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>NextURIMetaData</name>
+ <direction>in</direction>
+ <relatedStateVariable>NextAVTransportURIMetaData</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>SetPlayMode</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>NewPlayMode</name>
+ <direction>in</direction>
+ <relatedStateVariable>CurrentPlayMode</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>Stop</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ </actionList>
+ <serviceStateTable>
+ <stateVariable sendEvents="no">
+ <name>CurrentPlayMode</name>
+ <dataType>string</dataType>
+ <allowedValueList>
+ <allowedValue>NORMAL</allowedValue>
+ <allowedValue>REPEAT_ONE</allowedValue>
+ <allowedValue>REPEAT_ALL</allowedValue>
+ <allowedValue>SHUFFLE</allowedValue>
+ <allowedValue>SHUFFLE_NOREPEAT</allowedValue>
+ </allowedValueList>
+ <defaultValue>NORMAL</defaultValue>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>RecordStorageMedium</name>
+ <dataType>string</dataType>
+ <allowedValueList>
+ <allowedValue>NOT_IMPLEMENTED</allowedValue>
+ </allowedValueList>
+ </stateVariable>
+ <stateVariable sendEvents="yes">
+ <name>LastChange</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>RelativeTimePosition</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>CurrentTrackURI</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>CurrentTrackDuration</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>CurrentRecordQualityMode</name>
+ <dataType>string</dataType>
+ <allowedValueList>
+ <allowedValue>NOT_IMPLEMENTED</allowedValue>
+ </allowedValueList>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>CurrentMediaDuration</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>AbsoluteCounterPosition</name>
+ <dataType>i4</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>RelativeCounterPosition</name>
+ <dataType>i4</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>A_ARG_TYPE_InstanceID</name>
+ <dataType>ui4</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>AVTransportURI</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>TransportState</name>
+ <dataType>string</dataType>
+ <allowedValueList>
+ <allowedValue>STOPPED</allowedValue>
+ <allowedValue>PAUSED_PLAYBACK</allowedValue>
+ <allowedValue>PLAYING</allowedValue>
+ <allowedValue>TRANSITIONING</allowedValue>
+ <allowedValue>NO_MEDIA_PRESENT</allowedValue>
+ </allowedValueList>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>CurrentTrackMetaData</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>NextAVTransportURI</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>PossibleRecordQualityModes</name>
+ <dataType>string</dataType>
+ <allowedValueList>
+ <allowedValue>NOT_IMPLEMENTED</allowedValue>
+ </allowedValueList>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>CurrentTrack</name>
+ <dataType>ui4</dataType>
+ <allowedValueRange>
+ <minimum>0</minimum>
+ <maximum>65535</maximum>
+ <step>1</step>
+ </allowedValueRange>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>AbsoluteTimePosition</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>NextAVTransportURIMetaData</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>PlaybackStorageMedium</name>
+ <dataType>string</dataType>
+ <allowedValueList>
+ <allowedValue>NONE</allowedValue>
+ <allowedValue>UNKNOWN</allowedValue>
+ <allowedValue>CD-DA</allowedValue>
+ <allowedValue>HDD</allowedValue>
+ <allowedValue>NETWORK</allowedValue>
+ </allowedValueList>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>CurrentTransportActions</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>RecordMediumWriteStatus</name>
+ <dataType>string</dataType>
+ <allowedValueList>
+ <allowedValue>NOT_IMPLEMENTED</allowedValue>
+ </allowedValueList>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>PossiblePlaybackStorageMedia</name>
+ <dataType>string</dataType>
+ <allowedValueList>
+ <allowedValue>NONE</allowedValue>
+ <allowedValue>UNKNOWN</allowedValue>
+ <allowedValue>CD-DA</allowedValue>
+ <allowedValue>HDD</allowedValue>
+ <allowedValue>NETWORK</allowedValue>
+ </allowedValueList>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>AVTransportURIMetaData</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>NumberOfTracks</name>
+ <dataType>ui4</dataType>
+ <allowedValueRange>
+ <minimum>0</minimum>
+ <maximum>65535</maximum>
+ </allowedValueRange>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>A_ARG_TYPE_SeekMode</name>
+ <dataType>string</dataType>
+ <allowedValueList>
+ <allowedValue>REL_TIME</allowedValue>
+ <allowedValue>TRACK_NR</allowedValue>
+ </allowedValueList>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>A_ARG_TYPE_SeekTarget</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>PossibleRecordStorageMedia</name>
+ <dataType>string</dataType>
+ <allowedValueList>
+ <allowedValue>NOT_IMPLEMENTED</allowedValue>
+ </allowedValueList>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>TransportStatus</name>
+ <dataType>string</dataType>
+ <allowedValueList>
+ <allowedValue>OK</allowedValue>
+ <allowedValue>ERROR_OCCURRED</allowedValue>
+ </allowedValueList>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>TransportPlaySpeed</name>
+ <dataType>string</dataType>
+ <allowedValueList>
+ <allowedValue>1</allowedValue>
+ </allowedValueList>
+ </stateVariable>
+ </serviceStateTable>
+</scpd> \ No newline at end of file
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/AVTransportSCPDFull.xml b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/AVTransportSCPDFull.xml
new file mode 100644
index 0000000..72de6b0
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/AVTransportSCPDFull.xml
@@ -0,0 +1,561 @@
+<?xml version="1.0" encoding="utf-8"?>
+<scpd xmlns="urn:schemas-upnp-org:service-1-0">
+ <specVersion>
+ <major>1</major>
+ <minor>0</minor>
+ </specVersion>
+ <actionList>
+ <action>
+ <name>GetCurrentTransportActions</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Actions</name>
+ <direction>out</direction>
+ <relatedStateVariable>CurrentTransportActions</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetDeviceCapabilities</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>PlayMedia</name>
+ <direction>out</direction>
+ <relatedStateVariable>PossiblePlaybackStorageMedia</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>RecMedia</name>
+ <direction>out</direction>
+ <relatedStateVariable>PossibleRecordStorageMedia</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>RecQualityModes</name>
+ <direction>out</direction>
+ <relatedStateVariable>PossibleRecordQualityModes</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetMediaInfo</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>NrTracks</name>
+ <direction>out</direction>
+ <relatedStateVariable>NumberOfTracks</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>MediaDuration</name>
+ <direction>out</direction>
+ <relatedStateVariable>CurrentMediaDuration</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentURI</name>
+ <direction>out</direction>
+ <relatedStateVariable>AVTransportURI</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentURIMetaData</name>
+ <direction>out</direction>
+ <relatedStateVariable>AVTransportURIMetaData</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>NextURI</name>
+ <direction>out</direction>
+ <relatedStateVariable>NextAVTransportURI</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>NextURIMetaData</name>
+ <direction>out</direction>
+ <relatedStateVariable>NextAVTransportURIMetaData</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>PlayMedium</name>
+ <direction>out</direction>
+ <relatedStateVariable>PlaybackStorageMedium</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>RecordMedium</name>
+ <direction>out</direction>
+ <relatedStateVariable>RecordStorageMedium</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>WriteStatus</name>
+ <direction>out</direction>
+ <relatedStateVariable>RecordMediumWriteStatus</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetPositionInfo</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Track</name>
+ <direction>out</direction>
+ <relatedStateVariable>CurrentTrack</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>TrackDuration</name>
+ <direction>out</direction>
+ <relatedStateVariable>CurrentTrackDuration</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>TrackMetaData</name>
+ <direction>out</direction>
+ <relatedStateVariable>CurrentTrackMetaData</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>TrackURI</name>
+ <direction>out</direction>
+ <relatedStateVariable>CurrentTrackURI</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>RelTime</name>
+ <direction>out</direction>
+ <relatedStateVariable>RelativeTimePosition</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>AbsTime</name>
+ <direction>out</direction>
+ <relatedStateVariable>AbsoluteTimePosition</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>RelCount</name>
+ <direction>out</direction>
+ <relatedStateVariable>RelativeCounterPosition</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>AbsCount</name>
+ <direction>out</direction>
+ <relatedStateVariable>AbsoluteCounterPosition</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetTransportInfo</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentTransportState</name>
+ <direction>out</direction>
+ <relatedStateVariable>TransportState</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentTransportStatus</name>
+ <direction>out</direction>
+ <relatedStateVariable>TransportStatus</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentSpeed</name>
+ <direction>out</direction>
+ <relatedStateVariable>TransportPlaySpeed</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetTransportSettings</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>PlayMode</name>
+ <direction>out</direction>
+ <relatedStateVariable>CurrentPlayMode</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>RecQualityMode</name>
+ <direction>out</direction>
+ <relatedStateVariable>CurrentRecordQualityMode</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>Next</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>Pause</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>Play</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Speed</name>
+ <direction>in</direction>
+ <relatedStateVariable>TransportPlaySpeed</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>Previous</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>Seek</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Unit</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_SeekMode</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Target</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_SeekTarget</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>SetAVTransportURI</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentURI</name>
+ <direction>in</direction>
+ <relatedStateVariable>AVTransportURI</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentURIMetaData</name>
+ <direction>in</direction>
+ <relatedStateVariable>AVTransportURIMetaData</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>SetPlayMode</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>NewPlayMode</name>
+ <direction>in</direction>
+ <relatedStateVariable>CurrentPlayMode</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>Stop</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ </actionList>
+ <serviceStateTable>
+ <stateVariable sendEvents="no">
+ <name>CurrentPlayMode</name>
+ <dataType>string</dataType>
+ <allowedValueList>
+ <allowedValue>NORMAL</allowedValue>
+ <allowedValue>REPEAT_ALL</allowedValue>
+ <allowedValue>INTRO</allowedValue>
+ </allowedValueList>
+ <defaultValue>NORMAL</defaultValue>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>RecordStorageMedium</name>
+ <dataType>string</dataType>
+ <allowedValueList>
+ <allowedValue>UNKNOWN</allowedValue>
+ <allowedValue>DV</allowedValue>
+ <allowedValue>MINI-DV</allowedValue>
+ <allowedValue>VHS</allowedValue>
+ <allowedValue>W-VHS</allowedValue>
+ <allowedValue>S-VHS</allowedValue>
+ <allowedValue>D-VHS</allowedValue>
+ <allowedValue>VHSC</allowedValue>
+ <allowedValue>VIDEO8</allowedValue>
+ <allowedValue>HI8</allowedValue>
+ <allowedValue>CD-ROM</allowedValue>
+ <allowedValue>CD-DA</allowedValue>
+ <allowedValue>CD-R</allowedValue>
+ <allowedValue>CD-RW</allowedValue>
+ <allowedValue>VIDEO-CD</allowedValue>
+ <allowedValue>SACD</allowedValue>
+ <allowedValue>MD-AUDIO</allowedValue>
+ <allowedValue>MD-PICTURE</allowedValue>
+ <allowedValue>DVD-ROM</allowedValue>
+ <allowedValue>DVD-VIDEO</allowedValue>
+ <allowedValue>DVD-R</allowedValue>
+ <allowedValue>DVD+RW</allowedValue>
+ <allowedValue>DVD-RW</allowedValue>
+ <allowedValue>DVD-RAM</allowedValue>
+ <allowedValue>DVD-AUDIO</allowedValue>
+ <allowedValue>DAT</allowedValue>
+ <allowedValue>LD</allowedValue>
+ <allowedValue>HDD</allowedValue>
+ <allowedValue>MICRO-MV</allowedValue>
+ <allowedValue>NETWORK</allowedValue>
+ <allowedValue>NONE</allowedValue>
+ <allowedValue>NOT_IMPLEMENTED</allowedValue>
+ <allowedValue> vendor-defined </allowedValue>
+ </allowedValueList>
+ </stateVariable>
+ <stateVariable sendEvents="yes">
+ <name>LastChange</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>RelativeTimePosition</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>CurrentTrackURI</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>CurrentTrackDuration</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>CurrentRecordQualityMode</name>
+ <dataType>string</dataType>
+ <allowedValueList>
+ <allowedValue>0:EP</allowedValue>
+ <allowedValue>1:LP</allowedValue>
+ <allowedValue>2:SP</allowedValue>
+ <allowedValue>0:BASIC</allowedValue>
+ <allowedValue>1:MEDIUM</allowedValue>
+ <allowedValue>2:HIGH</allowedValue>
+ <allowedValue>NOT_IMPLEMENTED</allowedValue>
+ <allowedValue> vendor-defined </allowedValue>
+ </allowedValueList>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>CurrentMediaDuration</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>AbsoluteCounterPosition</name>
+ <dataType>i4</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>RelativeCounterPosition</name>
+ <dataType>i4</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>A_ARG_TYPE_InstanceID</name>
+ <dataType>ui4</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>AVTransportURI</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>TransportState</name>
+ <dataType>string</dataType>
+ <allowedValueList>
+ <allowedValue>STOPPED</allowedValue>
+ <allowedValue>PAUSED_PLAYBACK</allowedValue>
+ <allowedValue>PAUSED_RECORDING</allowedValue>
+ <allowedValue>PLAYING</allowedValue>
+ <allowedValue>RECORDING</allowedValue>
+ <allowedValue>TRANSITIONING</allowedValue>
+ <allowedValue>NO_MEDIA_PRESENT</allowedValue>
+ </allowedValueList>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>CurrentTrackMetaData</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>NextAVTransportURI</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>PossibleRecordQualityModes</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>CurrentTrack</name>
+ <dataType>ui4</dataType>
+ <allowedValueRange>
+ <minimum>0</minimum>
+ <maximum>4294967295</maximum>
+ <step>1</step>
+ </allowedValueRange>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>AbsoluteTimePosition</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>NextAVTransportURIMetaData</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>PlaybackStorageMedium</name>
+ <dataType>string</dataType>
+ <allowedValueList>
+ <allowedValue>UNKNOWN</allowedValue>
+ <allowedValue>DV</allowedValue>
+ <allowedValue>MINI-DV</allowedValue>
+ <allowedValue>VHS</allowedValue>
+ <allowedValue>W-VHS</allowedValue>
+ <allowedValue>S-VHS</allowedValue>
+ <allowedValue>D-VHS</allowedValue>
+ <allowedValue>VHSC</allowedValue>
+ <allowedValue>VIDEO8</allowedValue>
+ <allowedValue>HI8</allowedValue>
+ <allowedValue>CD-ROM</allowedValue>
+ <allowedValue>CD-DA</allowedValue>
+ <allowedValue>CD-R</allowedValue>
+ <allowedValue>CD-RW</allowedValue>
+ <allowedValue>VIDEO-CD</allowedValue>
+ <allowedValue>SACD</allowedValue>
+ <allowedValue>MD-AUDIO</allowedValue>
+ <allowedValue>MD-PICTURE</allowedValue>
+ <allowedValue>DVD-ROM</allowedValue>
+ <allowedValue>DVD-VIDEO</allowedValue>
+ <allowedValue>DVD-R</allowedValue>
+ <allowedValue>DVD+RW</allowedValue>
+ <allowedValue>DVD-RW</allowedValue>
+ <allowedValue>DVD-RAM</allowedValue>
+ <allowedValue>DVD-AUDIO</allowedValue>
+ <allowedValue>DAT</allowedValue>
+ <allowedValue>LD</allowedValue>
+ <allowedValue>HDD</allowedValue>
+ <allowedValue>MICRO-MV</allowedValue>
+ <allowedValue>NETWORK</allowedValue>
+ <allowedValue>NONE</allowedValue>
+ <allowedValue>NOT_IMPLEMENTED</allowedValue>
+ <allowedValue> vendor-defined </allowedValue>
+ </allowedValueList>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>CurrentTransportActions</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>RecordMediumWriteStatus</name>
+ <dataType>string</dataType>
+ <allowedValueList>
+ <allowedValue>WRITABLE</allowedValue>
+ <allowedValue>PROTECTED</allowedValue>
+ <allowedValue>NOT_WRITABLE</allowedValue>
+ <allowedValue>UNKNOWN</allowedValue>
+ <allowedValue>NOT_IMPLEMENTED</allowedValue>
+ </allowedValueList>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>PossiblePlaybackStorageMedia</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>AVTransportURIMetaData</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>NumberOfTracks</name>
+ <dataType>ui4</dataType>
+ <allowedValueRange>
+ <minimum>0</minimum>
+ <maximum>4294967295</maximum>
+ </allowedValueRange>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>A_ARG_TYPE_SeekMode</name>
+ <dataType>string</dataType>
+ <allowedValueList>
+ <allowedValue>ABS_TIME</allowedValue>
+ <allowedValue>REL_TIME</allowedValue>
+ <allowedValue>ABS_COUNT</allowedValue>
+ <allowedValue>REL_COUNT</allowedValue>
+ <allowedValue>TRACK_NR</allowedValue>
+ <allowedValue>CHANNEL_FREQ</allowedValue>
+ <allowedValue>TAPE-INDEX</allowedValue>
+ <allowedValue>FRAME</allowedValue>
+ </allowedValueList>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>A_ARG_TYPE_SeekTarget</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>PossibleRecordStorageMedia</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>TransportStatus</name>
+ <dataType>string</dataType>
+ <allowedValueList>
+ <allowedValue>OK</allowedValue>
+ <allowedValue>ERROR_OCCURRED</allowedValue>
+ <allowedValue> vendor-defined </allowedValue>
+ </allowedValueList>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>TransportPlaySpeed</name>
+ <dataType>string</dataType>
+ <allowedValueList>
+ <allowedValue>1</allowedValue>
+ <allowedValue> vendor-defined </allowedValue>
+ </allowedValueList>
+ </stateVariable>
+ </serviceStateTable>
+</scpd> \ No newline at end of file
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaController.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaController.cpp
new file mode 100644
index 0000000..87aabf3
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaController.cpp
@@ -0,0 +1,1392 @@
+/*****************************************************************
+|
+| Platinum - AV Media Controller (Media Renderer Control Point)
+|
+| Copyright (c) 2004-2010, Plutinosoft, LLC.
+| All rights reserved.
+| http://www.plutinosoft.com
+|
+| This program is free software; you can redistribute it and/or
+| modify it under the terms of the GNU General Public License
+| as published by the Free Software Foundation; either version 2
+| of the License, or (at your option) any later version.
+|
+| OEMs, ISVs, VARs and other distributors that combine and
+| distribute commercially licensed software with Platinum software
+| and do not wish to distribute the source code for the commercially
+| licensed software under version 2, or (at your option) any later
+| version, of the GNU General Public License (the "GPL") must enter
+| into a commercial license agreement with Plutinosoft, LLC.
+| licensing@plutinosoft.com
+|
+| This program is distributed in the hope that it will be useful,
+| but WITHOUT ANY WARRANTY; without even the implied warranty of
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+| GNU General Public License for more details.
+|
+| You should have received a copy of the GNU General Public License
+| along with this program; see the file LICENSE.txt. If not, write to
+| the Free Software Foundation, Inc.,
+| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+| http://www.gnu.org/licenses/gpl-2.0.html
+|
+****************************************************************/
+
+/*----------------------------------------------------------------------
+| includes
++---------------------------------------------------------------------*/
+#include "Neptune.h"
+#include "PltMediaController.h"
+#include "PltDidl.h"
+#include "PltDeviceData.h"
+#include "PltUtilities.h"
+
+NPT_SET_LOCAL_LOGGER("platinum.media.renderer.controller")
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::PLT_MediaController
++---------------------------------------------------------------------*/
+PLT_MediaController::PLT_MediaController(PLT_CtrlPointReference& ctrl_point,
+ PLT_MediaControllerDelegate* delegate /* = NULL */) :
+ m_CtrlPoint(ctrl_point),
+ m_Delegate(delegate)
+{
+ m_CtrlPoint->AddListener(this);
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::~PLT_MediaController
++---------------------------------------------------------------------*/
+PLT_MediaController::~PLT_MediaController()
+{
+ m_CtrlPoint->RemoveListener(this);
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::OnDeviceAdded
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::OnDeviceAdded(PLT_DeviceDataReference& device)
+{
+ // verify the device implements the function we need
+ PLT_Service* serviceAVT = NULL;
+ PLT_Service* serviceCMR;
+ PLT_Service* serviceRC;
+ NPT_String type;
+
+ if (!device->GetType().StartsWith("urn:schemas-upnp-org:device:MediaRenderer"))
+ return NPT_FAILURE;
+
+ // optional service
+ type = "urn:schemas-upnp-org:service:AVTransport:*";
+ if (NPT_SUCCEEDED(device->FindServiceByType(type, serviceAVT))) {
+ // in case it's a newer upnp implementation, force to 1
+ NPT_LOG_FINE_1("Service %s found", (const char*)type);
+ serviceAVT->ForceVersion(1);
+ }
+
+ // required services
+ type = "urn:schemas-upnp-org:service:ConnectionManager:*";
+ if (NPT_FAILED(device->FindServiceByType(type, serviceCMR))) {
+ NPT_LOG_FINE_1("Service %s not found", (const char*)type);
+ return NPT_FAILURE;
+ } else {
+ // in case it's a newer upnp implementation, force to 1
+ serviceCMR->ForceVersion(1);
+ }
+
+ type = "urn:schemas-upnp-org:service:RenderingControl:*";
+ if (NPT_FAILED(device->FindServiceByType(type, serviceRC))) {
+ NPT_LOG_FINE_1("Service %s not found", (const char*)type);
+ return NPT_FAILURE;
+ } else {
+ // in case it's a newer upnp implementation, force to 1
+ serviceRC->ForceVersion(1);
+ }
+
+ {
+ NPT_AutoLock lock(m_MediaRenderers);
+
+ PLT_DeviceDataReference data;
+ NPT_String uuid = device->GetUUID();
+
+ // is it a new device?
+ if (NPT_SUCCEEDED(NPT_ContainerFind(m_MediaRenderers,
+ PLT_DeviceDataFinder(uuid), data))) {
+ NPT_LOG_WARNING_1("Device (%s) is already in our list!", (const char*)uuid);
+ return NPT_FAILURE;
+ }
+
+ NPT_LOG_FINE_1("Device Found: %s", (const char*)*device);
+
+ m_MediaRenderers.Add(device);
+ }
+
+ if (m_Delegate && m_Delegate->OnMRAdded(device)) {
+ // subscribe to services eventing only if delegate wants it
+ if (serviceAVT) m_CtrlPoint->Subscribe(serviceAVT);
+
+ // subscribe to required services
+ m_CtrlPoint->Subscribe(serviceCMR);
+ m_CtrlPoint->Subscribe(serviceRC);
+ }
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::OnDeviceRemoved
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::OnDeviceRemoved(PLT_DeviceDataReference& device)
+{
+ if (!device->GetType().StartsWith("urn:schemas-upnp-org:device:MediaRenderer"))
+ return NPT_FAILURE;
+
+ {
+ NPT_AutoLock lock(m_MediaRenderers);
+
+ // only release if we have kept it around
+ PLT_DeviceDataReference data;
+ NPT_String uuid = device->GetUUID();
+
+ // Have we seen that device?
+ if (NPT_FAILED(NPT_ContainerFind(m_MediaRenderers, PLT_DeviceDataFinder(uuid), data))) {
+ NPT_LOG_WARNING_1("Device (%s) not found in our list!", (const char*)uuid);
+ return NPT_FAILURE;
+ }
+
+ NPT_LOG_FINE_1("Device Removed: %s", (const char*)*device);
+
+ m_MediaRenderers.Remove(device);
+ }
+
+ if (m_Delegate) {
+ m_Delegate->OnMRRemoved(device);
+ }
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::FindRenderer
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::FindRenderer(const char* uuid, PLT_DeviceDataReference& device)
+{
+ NPT_AutoLock lock(m_MediaRenderers);
+
+ if (NPT_FAILED(NPT_ContainerFind(m_MediaRenderers, PLT_DeviceDataFinder(uuid), device))) {
+ NPT_LOG_FINE_1("Device (%s) not found in our list of renderers", (const char*)uuid);
+ return NPT_FAILURE;
+ }
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::GetProtocolInfoSink
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::GetProtocolInfoSink(const NPT_String& device_uuid,
+ NPT_List<NPT_String>& sinks)
+{
+ PLT_DeviceDataReference renderer;
+ NPT_CHECK_WARNING(FindRenderer(device_uuid, renderer));
+
+ // look for ConnectionManager service
+ PLT_Service* serviceCMR;
+ NPT_CHECK_SEVERE(renderer->FindServiceByType("urn:schemas-upnp-org:service:ConnectionManager:*",
+ serviceCMR));
+
+ NPT_String value;
+ NPT_CHECK_SEVERE(serviceCMR->GetStateVariableValue("SinkProtocolInfo",
+ value));
+
+ sinks = value.Split(",");
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::GetTransportState
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::GetTransportState(const NPT_String& device_uuid,
+ NPT_String& state)
+{
+ PLT_DeviceDataReference renderer;
+ NPT_CHECK_WARNING(FindRenderer(device_uuid, renderer));
+
+ // look for AVTransport service
+ PLT_Service* serviceAVT;
+ NPT_CHECK_SEVERE(renderer->FindServiceByType("urn:schemas-upnp-org:service:AVTransport:*",
+ serviceAVT));
+
+ NPT_CHECK_SEVERE(serviceAVT->GetStateVariableValue("TransportState",
+ state));
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::GetVolumeState
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::GetVolumeState(const NPT_String& device_uuid,
+ NPT_UInt32& volume)
+{
+ PLT_DeviceDataReference renderer;
+ NPT_CHECK_WARNING(FindRenderer(device_uuid, renderer));
+
+ // look for RenderingControl service
+ PLT_Service* serviceRC;
+ NPT_CHECK_SEVERE(renderer->FindServiceByType("urn:schemas-upnp-org:service:RenderingControl:*",
+ serviceRC));
+
+ NPT_String value;
+ NPT_CHECK_SEVERE(serviceRC->GetStateVariableValue("Volume",
+ value));
+
+ return value.ToInteger32(volume);
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::FindMatchingProtocolInfo
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::FindMatchingProtocolInfo(NPT_List<NPT_String>& sinks,
+ const char* protocol_info)
+{
+ PLT_ProtocolInfo protocol(protocol_info);
+ for (NPT_List<NPT_String>::Iterator iter = sinks.GetFirstItem();
+ iter;
+ iter++) {
+ PLT_ProtocolInfo sink(*iter);
+ if (sink.Match(protocol)) {
+ return NPT_SUCCESS;
+ }
+ }
+
+ return NPT_ERROR_NO_SUCH_ITEM;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::FindBestResource
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::FindBestResource(PLT_DeviceDataReference& device,
+ PLT_MediaObject& item,
+ NPT_Cardinal& resource_index)
+{
+ if (item.m_Resources.GetItemCount() <= 0) return NPT_ERROR_INVALID_PARAMETERS;
+
+ NPT_List<NPT_String> sinks;
+ NPT_CHECK_SEVERE(GetProtocolInfoSink(device->GetUUID(), sinks));
+
+ // look for best resource
+ for (NPT_Cardinal i=0; i< item.m_Resources.GetItemCount(); i++) {
+ if (NPT_SUCCEEDED(FindMatchingProtocolInfo(
+ sinks,
+ item.m_Resources[i].m_ProtocolInfo.ToString()))) {
+ resource_index = i;
+ return NPT_SUCCESS;
+ }
+ }
+
+ return NPT_ERROR_NO_SUCH_ITEM;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::InvokeActionWithInstance
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::InvokeActionWithInstance(PLT_ActionReference& action,
+ NPT_UInt32 instance_id,
+ void* userdata)
+{
+ // Set the object id
+ NPT_CHECK_SEVERE(action->SetArgumentValue(
+ "InstanceID",
+ NPT_String::FromInteger(instance_id)));
+
+ // set the arguments on the action, this will check the argument values
+ return m_CtrlPoint->InvokeAction(action, userdata);
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::GetCurrentTransportActions
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::GetCurrentTransportActions(PLT_DeviceDataReference& device,
+ NPT_UInt32 instance_id,
+ void* userdata)
+{
+ PLT_ActionReference action;
+ NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction(
+ device,
+ "urn:schemas-upnp-org:service:AVTransport:1",
+ "GetCurrentTransportActions",
+ action));
+ return InvokeActionWithInstance(action, instance_id, userdata);
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::GetDeviceCapabilities
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::GetDeviceCapabilities(PLT_DeviceDataReference& device,
+ NPT_UInt32 instance_id,
+ void* userdata)
+{
+ PLT_ActionReference action;
+ NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction(
+ device,
+ "urn:schemas-upnp-org:service:AVTransport:1",
+ "GetDeviceCapabilities",
+ action));
+ return InvokeActionWithInstance(action, instance_id, userdata);
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::GetMediaInfo
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::GetMediaInfo(PLT_DeviceDataReference& device,
+ NPT_UInt32 instance_id,
+ void* userdata)
+{
+ PLT_ActionReference action;
+ NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction(
+ device,
+ "urn:schemas-upnp-org:service:AVTransport:1",
+ "GetMediaInfo",
+ action));
+ return InvokeActionWithInstance(action, instance_id, userdata);
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::GetPositionInfo
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::GetPositionInfo(PLT_DeviceDataReference& device,
+ NPT_UInt32 instance_id,
+ void* userdata)
+{
+ PLT_ActionReference action;
+ NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction(
+ device,
+ "urn:schemas-upnp-org:service:AVTransport:1",
+ "GetPositionInfo",
+ action));
+ return InvokeActionWithInstance(action, instance_id, userdata);
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::GetTransportInfo
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::GetTransportInfo(PLT_DeviceDataReference& device,
+ NPT_UInt32 instance_id,
+ void* userdata)
+{
+ PLT_ActionReference action;
+ NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction(
+ device,
+ "urn:schemas-upnp-org:service:AVTransport:1",
+ "GetTransportInfo",
+ action));
+ return InvokeActionWithInstance(action, instance_id, userdata);
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::GetTransportSettings
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::GetTransportSettings(PLT_DeviceDataReference& device,
+ NPT_UInt32 instance_id,
+ void* userdata)
+{
+ PLT_ActionReference action;
+ NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction(
+ device,
+ "urn:schemas-upnp-org:service:AVTransport:1",
+ "GetTransportSettings",
+ action));
+ return InvokeActionWithInstance(action, instance_id, userdata);
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::Next
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::Next(PLT_DeviceDataReference& device,
+ NPT_UInt32 instance_id,
+ void* userdata)
+{
+ PLT_ActionReference action;
+ NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction(
+ device,
+ "urn:schemas-upnp-org:service:AVTransport:1",
+ "Next",
+ action));
+ return InvokeActionWithInstance(action, instance_id, userdata);
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::Pause
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::Pause(PLT_DeviceDataReference& device,
+ NPT_UInt32 instance_id,
+ void* userdata)
+{
+ PLT_ActionReference action;
+ NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction(
+ device,
+ "urn:schemas-upnp-org:service:AVTransport:1",
+ "Pause",
+ action));
+ return InvokeActionWithInstance(action, instance_id, userdata);
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::Play
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::Play(PLT_DeviceDataReference& device,
+ NPT_UInt32 instance_id,
+ NPT_String speed,
+ void* userdata)
+{
+ PLT_ActionReference action;
+ NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction(
+ device,
+ "urn:schemas-upnp-org:service:AVTransport:1",
+ "Play",
+ action));
+
+ // Set the speed
+ if (NPT_FAILED(action->SetArgumentValue("Speed", speed))) {
+ return NPT_ERROR_INVALID_PARAMETERS;
+ }
+
+ return InvokeActionWithInstance(action, instance_id, userdata);
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::Previous
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::Previous(PLT_DeviceDataReference& device,
+ NPT_UInt32 instance_id,
+ void* userdata)
+{
+ PLT_ActionReference action;
+ NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction(
+ device,
+ "urn:schemas-upnp-org:service:AVTransport:1",
+ "Previous",
+ action));
+ return InvokeActionWithInstance(action, instance_id, userdata);
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::Seek
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::Seek(PLT_DeviceDataReference& device,
+ NPT_UInt32 instance_id,
+ NPT_String unit,
+ NPT_String target,
+ void* userdata)
+{
+ PLT_ActionReference action;
+ NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction(
+ device,
+ "urn:schemas-upnp-org:service:AVTransport:1",
+ "Seek",
+ action));
+
+ // Set the unit
+ if (NPT_FAILED(action->SetArgumentValue("Unit", unit))) {
+ return NPT_ERROR_INVALID_PARAMETERS;
+ }
+
+ // Set the target
+ if (NPT_FAILED(action->SetArgumentValue("Target", target))) {
+ return NPT_ERROR_INVALID_PARAMETERS;
+ }
+
+ return InvokeActionWithInstance(action, instance_id, userdata);
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::CanSetNextAVTransportURI
++---------------------------------------------------------------------*/
+bool
+PLT_MediaController::CanSetNextAVTransportURI(PLT_DeviceDataReference &device)
+{
+ if (device.IsNull()) return false;
+
+ PLT_ActionDesc* action_desc;
+ NPT_Result result = m_CtrlPoint->FindActionDesc(device,
+ "urn:schemas-upnp-org:service:AVTransport:1",
+ "SetNextAVTransportURI",
+ action_desc);
+ return (result == NPT_SUCCESS);
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::SetAVTransportURI
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::SetAVTransportURI(PLT_DeviceDataReference& device,
+ NPT_UInt32 instance_id,
+ const char* uri,
+ const char* metadata,
+ void* userdata)
+{
+ PLT_ActionReference action;
+ NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction(
+ device,
+ "urn:schemas-upnp-org:service:AVTransport:1",
+ "SetAVTransportURI",
+ action));
+
+ // set the uri
+ if (NPT_FAILED(action->SetArgumentValue("CurrentURI", uri))) {
+ return NPT_ERROR_INVALID_PARAMETERS;
+ }
+
+ // set the uri metadata
+ if (NPT_FAILED(action->SetArgumentValue("CurrentURIMetaData", metadata))) {
+ return NPT_ERROR_INVALID_PARAMETERS;
+ }
+
+ return InvokeActionWithInstance(action, instance_id, userdata);
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::SetNextAVTransportURI
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::SetNextAVTransportURI(PLT_DeviceDataReference& device,
+ NPT_UInt32 instance_id,
+ const char* next_uri,
+ const char* next_metadata,
+ void* userdata)
+{
+ PLT_ActionReference action;
+ NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction(device,
+ "urn:schemas-upnp-org:service:AVTransport:1",
+ "SetNextAVTransportURI",
+ action));
+
+ // set the uri
+ if (NPT_FAILED(action->SetArgumentValue("NextURI", next_uri))) {
+ return NPT_ERROR_INVALID_PARAMETERS;
+ }
+
+ // set the uri metadata
+ if (NPT_FAILED(action->SetArgumentValue("NextURIMetaData", next_metadata))) {
+ return NPT_ERROR_INVALID_PARAMETERS;
+ }
+
+ return InvokeActionWithInstance(action, instance_id, userdata);
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::SetPlayMode
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::SetPlayMode(PLT_DeviceDataReference& device,
+ NPT_UInt32 instance_id,
+ NPT_String new_play_mode,
+ void* userdata)
+{
+ PLT_ActionReference action;
+ NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction(
+ device,
+ "urn:schemas-upnp-org:service:AVTransport:1",
+ "SetPlayMode",
+ action));
+
+ // set the New PlayMode
+ if (NPT_FAILED(action->SetArgumentValue("NewPlayMode", new_play_mode))) {
+ return NPT_ERROR_INVALID_PARAMETERS;
+ }
+
+ return InvokeActionWithInstance(action, instance_id, userdata);
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::Stop
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::Stop(PLT_DeviceDataReference& device,
+ NPT_UInt32 instance_id,
+ void* userdata)
+{
+ PLT_ActionReference action;
+ NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction(
+ device,
+ "urn:schemas-upnp-org:service:AVTransport:1",
+ "Stop",
+ action));
+ return InvokeActionWithInstance(action, instance_id, userdata);
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::GetCurrentConnectionIDs
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::GetCurrentConnectionIDs(PLT_DeviceDataReference& device,
+ void* userdata)
+{
+ PLT_ActionReference action;
+ NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction(
+ device,
+ "urn:schemas-upnp-org:service:ConnectionManager:1",
+ "GetCurrentConnectionIDs",
+ action));
+
+ // set the arguments on the action, this will check the argument values
+ if (NPT_FAILED(m_CtrlPoint->InvokeAction(action, userdata))) {
+ return NPT_ERROR_INVALID_PARAMETERS;
+ }
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::GetCurrentConnectionInfo
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::GetCurrentConnectionInfo(PLT_DeviceDataReference& device,
+ NPT_UInt32 connection_id,
+ void* userdata)
+{
+ PLT_ActionReference action;
+ NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction(
+ device,
+ "urn:schemas-upnp-org:service:ConnectionManager:1",
+ "GetCurrentConnectionInfo",
+ action));
+
+ // set the New PlayMode
+ if (NPT_FAILED(action->SetArgumentValue("ConnectionID",
+ NPT_String::FromInteger(connection_id)))) {
+ return NPT_ERROR_INVALID_PARAMETERS;
+ }
+
+ // set the arguments on the action, this will check the argument values
+ if (NPT_FAILED(m_CtrlPoint->InvokeAction(action, userdata))) {
+ return NPT_ERROR_INVALID_PARAMETERS;
+ }
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::GetProtocolInfo
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::GetProtocolInfo(PLT_DeviceDataReference& device,
+ void* userdata)
+{
+ PLT_ActionReference action;
+ NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction(
+ device,
+ "urn:schemas-upnp-org:service:ConnectionManager:1",
+ "GetProtocolInfo",
+ action));
+
+ // set the arguments on the action, this will check the argument values
+ if (NPT_FAILED(m_CtrlPoint->InvokeAction(action, userdata))) {
+ return NPT_ERROR_INVALID_PARAMETERS;
+ }
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::SetMute
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::SetMute(PLT_DeviceDataReference& device,
+ NPT_UInt32 instance_id,
+ const char* channel,
+ bool mute,
+ void* userdata)
+{
+ PLT_ActionReference action;
+ NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction(
+ device,
+ "urn:schemas-upnp-org:service:RenderingControl:1",
+ "SetMute",
+ action));
+
+ // set the channel
+ if (NPT_FAILED(action->SetArgumentValue("Channel", channel))) {
+ return NPT_ERROR_INVALID_PARAMETERS;
+ }
+
+ // set the channel
+ if (NPT_FAILED(action->SetArgumentValue("DesiredMute",
+ mute?"1":"0"))) {
+ return NPT_ERROR_INVALID_PARAMETERS;
+ }
+
+ return InvokeActionWithInstance(action, instance_id, userdata);
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::SetVolume
++---------------------------------------------------------------------*/
+NPT_Result PLT_MediaController::SetVolume(PLT_DeviceDataReference& device,
+ NPT_UInt32 instance_id,
+ const char* channel,
+ int volume,
+ void* userdata)
+{
+
+ PLT_ActionReference action;
+ NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction(
+ device,
+ "urn:schemas-upnp-org:service:RenderingControl:1",
+ "SetVolume",
+ action));
+
+ // set the channel
+ if (NPT_FAILED(action->SetArgumentValue("Channel", channel))) {
+ return NPT_ERROR_INVALID_PARAMETERS;
+ }
+
+ if (NPT_FAILED(action->SetArgumentValue("DesiredVolume",
+ NPT_String::FromInteger(volume)))) {
+ return NPT_ERROR_INVALID_PARAMETERS;
+ }
+
+ return InvokeActionWithInstance(action, instance_id, userdata);
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::GetMute
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::GetMute(PLT_DeviceDataReference& device,
+ NPT_UInt32 instance_id,
+ const char* channel,
+ void* userdata)
+{
+ PLT_ActionReference action;
+ NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction(
+ device,
+ "urn:schemas-upnp-org:service:RenderingControl:1",
+ "GetMute",
+ action));
+
+ // set the channel
+ if (NPT_FAILED(action->SetArgumentValue("Channel", channel))) {
+ return NPT_ERROR_INVALID_PARAMETERS;
+ }
+
+ return InvokeActionWithInstance(action, instance_id, userdata);
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::GetVolume
++---------------------------------------------------------------------*/
+NPT_Result PLT_MediaController::GetVolume(PLT_DeviceDataReference& device,
+ NPT_UInt32 instance_id,
+ const char* channel,
+ void* userdata)
+{
+ PLT_ActionReference action;
+ NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction(
+ device,
+ "urn:schemas-upnp-org:service:RenderingControl:1",
+ "GetVolume",
+ action));
+
+ // set the channel
+ if (NPT_FAILED(action->SetArgumentValue("Channel", channel))) {
+ return NPT_ERROR_INVALID_PARAMETERS;
+ }
+
+ return InvokeActionWithInstance(action, instance_id, userdata);
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::OnActionResponse
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::OnActionResponse(NPT_Result res,
+ PLT_ActionReference& action,
+ void* userdata)
+{
+ if (m_Delegate == NULL) return NPT_SUCCESS;
+
+ PLT_DeviceDataReference device;
+ NPT_String uuid = action->GetActionDesc().GetService()->GetDevice()->GetUUID();
+
+ /* extract action name */
+ NPT_String actionName = action->GetActionDesc().GetName();
+
+ /* AVTransport response ? */
+ if (actionName.Compare("GetCurrentTransportActions", true) == 0) {
+ if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE;
+ return OnGetCurrentTransportActionsResponse(res, device, action, userdata);
+ }
+ else if (actionName.Compare("GetDeviceCapabilities", true) == 0) {
+ if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE;
+ return OnGetDeviceCapabilitiesResponse(res, device, action, userdata);
+ }
+ else if (actionName.Compare("GetMediaInfo", true) == 0) {
+ if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE;
+ return OnGetMediaInfoResponse(res, device, action, userdata);
+ }
+ else if (actionName.Compare("GetPositionInfo", true) == 0) {
+ if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE;
+ return OnGetPositionInfoResponse(res, device, action, userdata);
+ }
+ else if (actionName.Compare("GetTransportInfo", true) == 0) {
+ if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE;
+ return OnGetTransportInfoResponse(res, device, action, userdata);
+ }
+ else if (actionName.Compare("GetTransportSettings", true) == 0) {
+ if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE;
+ return OnGetTransportSettingsResponse(res, device, action, userdata);
+ }
+ else if (actionName.Compare("Next", true) == 0) {
+ if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE;
+ m_Delegate->OnNextResult(res, device, userdata);
+ }
+ else if (actionName.Compare("Pause", true) == 0) {
+ if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE;
+ m_Delegate->OnPauseResult(res, device, userdata);
+ }
+ else if (actionName.Compare("Play", true) == 0) {
+ if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE;
+ m_Delegate->OnPlayResult(res, device, userdata);
+ }
+ else if (actionName.Compare("Previous", true) == 0) {
+ if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE;
+ m_Delegate->OnPreviousResult(res, device, userdata);
+ }
+ else if (actionName.Compare("Seek", true) == 0) {
+ if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE;
+ m_Delegate->OnSeekResult(res, device, userdata);
+ }
+ else if (actionName.Compare("SetAVTransportURI", true) == 0) {
+ if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE;
+ m_Delegate->OnSetAVTransportURIResult(res, device, userdata);
+ }
+ else if (actionName.Compare("SetNextAVTransportURI", true) == 0) {
+ if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE;
+ m_Delegate->OnSetNextAVTransportURIResult(res, device, userdata);
+ }
+ else if (actionName.Compare("SetPlayMode", true) == 0) {
+ if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE;
+ m_Delegate->OnSetPlayModeResult(res, device, userdata);
+ }
+ else if (actionName.Compare("Stop", true) == 0) {
+ if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE;
+ m_Delegate->OnStopResult(res, device, userdata);
+ }
+ else if (actionName.Compare("GetCurrentConnectionIDs", true) == 0) {
+ if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE;
+ return OnGetCurrentConnectionIDsResponse(res, device, action, userdata);
+ }
+ else if (actionName.Compare("GetCurrentConnectionInfo", true) == 0) {
+ if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE;
+ return OnGetCurrentConnectionInfoResponse(res, device, action, userdata);
+ }
+ else if (actionName.Compare("GetProtocolInfo", true) == 0) {
+ if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE;
+ return OnGetProtocolInfoResponse(res, device, action, userdata);
+ }
+ else if (actionName.Compare("SetMute", true) == 0) {
+ if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE;
+ m_Delegate->OnSetMuteResult(res, device, userdata);
+ }
+ else if (actionName.Compare("GetMute", true) == 0) {
+ if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE;
+ return OnGetMuteResponse(res, device, action, userdata);
+ }
+ else if (actionName.Compare("SetVolume", true) == 0) {
+ if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE;
+ m_Delegate->OnSetVolumeResult(res, device, userdata);
+ }
+ else if (actionName.Compare("GetVolume", true) == 0) {
+ if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE;
+ return OnGetVolumeResponse(res, device, action, userdata);
+ }
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::OnGetCurrentTransportActionsResponse
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::OnGetCurrentTransportActionsResponse(NPT_Result res,
+ PLT_DeviceDataReference& device,
+ PLT_ActionReference& action,
+ void* userdata)
+{
+ NPT_String actions;
+ PLT_StringList values;
+
+ if (NPT_FAILED(res) || action->GetErrorCode() != 0) {
+ goto bad_action;
+ }
+
+ if (NPT_FAILED(action->GetArgumentValue("Actions", actions))) {
+ goto bad_action;
+ }
+
+ // parse the list of actions and return a list to listener
+ ParseCSV(actions, values);
+
+ m_Delegate->OnGetCurrentTransportActionsResult(NPT_SUCCESS, device, &values, userdata);
+ return NPT_SUCCESS;
+
+bad_action:
+ m_Delegate->OnGetCurrentTransportActionsResult(NPT_FAILURE, device, NULL, userdata);
+ return NPT_FAILURE;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::OnGetDeviceCapabilitiesResponse
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::OnGetDeviceCapabilitiesResponse(NPT_Result res,
+ PLT_DeviceDataReference& device,
+ PLT_ActionReference& action,
+ void* userdata)
+{
+ NPT_String value;
+ PLT_DeviceCapabilities capabilities;
+
+ if (NPT_FAILED(res) || action->GetErrorCode() != 0) {
+ goto bad_action;
+ }
+
+ if (NPT_FAILED(action->GetArgumentValue("PlayMedia", value))) {
+ goto bad_action;
+ }
+ // parse the list of medias and return a list to listener
+ ParseCSV(value, capabilities.play_media);
+
+ if (NPT_FAILED(action->GetArgumentValue("RecMedia", value))) {
+ goto bad_action;
+ }
+ // parse the list of rec and return a list to listener
+ ParseCSV(value, capabilities.rec_media);
+
+ if (NPT_FAILED(action->GetArgumentValue("RecQualityModes", value))) {
+ goto bad_action;
+ }
+ // parse the list of modes and return a list to listener
+ ParseCSV(value, capabilities.rec_quality_modes);
+
+ m_Delegate->OnGetDeviceCapabilitiesResult(NPT_SUCCESS, device, &capabilities, userdata);
+ return NPT_SUCCESS;
+
+bad_action:
+ m_Delegate->OnGetDeviceCapabilitiesResult(NPT_FAILURE, device, NULL, userdata);
+ return NPT_FAILURE;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::OnGetMediaInfoResponse
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::OnGetMediaInfoResponse(NPT_Result res,
+ PLT_DeviceDataReference& device,
+ PLT_ActionReference& action,
+ void* userdata)
+{
+ NPT_String value;
+ PLT_MediaInfo info;
+
+ if (NPT_FAILED(res) || action->GetErrorCode() != 0) {
+ goto bad_action;
+ }
+
+ if (NPT_FAILED(action->GetArgumentValue("NrTracks", info.num_tracks))) {
+ goto bad_action;
+ }
+ if (NPT_FAILED(action->GetArgumentValue("MediaDuration", value))) {
+ goto bad_action;
+ }
+ if (NPT_FAILED(PLT_Didl::ParseTimeStamp(value, info.media_duration))) {
+ goto bad_action;
+ }
+
+ if (NPT_FAILED(action->GetArgumentValue("CurrentURI", info.cur_uri))) {
+ goto bad_action;
+ }
+ if (NPT_FAILED(action->GetArgumentValue("CurrentURIMetaData", info.cur_metadata))) {
+ goto bad_action;
+ }
+ if (NPT_FAILED(action->GetArgumentValue("NextURI", info.next_uri))) {
+ goto bad_action;
+ }
+ if (NPT_FAILED(action->GetArgumentValue("NextURIMetaData", info.next_metadata))) {
+ goto bad_action;
+ }
+ if (NPT_FAILED(action->GetArgumentValue("PlayMedium", info.play_medium))) {
+ goto bad_action;
+ }
+ if (NPT_FAILED(action->GetArgumentValue("RecordMedium", info.rec_medium))) {
+ goto bad_action;
+ }
+ if (NPT_FAILED(action->GetArgumentValue("WriteStatus", info.write_status))) {
+ goto bad_action;
+ }
+
+ m_Delegate->OnGetMediaInfoResult(NPT_SUCCESS, device, &info, userdata);
+ return NPT_SUCCESS;
+
+bad_action:
+ m_Delegate->OnGetMediaInfoResult(NPT_FAILURE, device, NULL, userdata);
+ return NPT_FAILURE;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::OnGetPositionInfoResponse
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::OnGetPositionInfoResponse(NPT_Result res,
+ PLT_DeviceDataReference& device,
+ PLT_ActionReference& action,
+ void* userdata)
+{
+ NPT_String value;
+ PLT_PositionInfo info;
+
+ if (NPT_FAILED(res) || action->GetErrorCode() != 0) {
+ goto bad_action;
+ }
+
+ if (NPT_FAILED(action->GetArgumentValue("Track", info.track))) {
+ goto bad_action;
+ }
+
+ if (NPT_FAILED(action->GetArgumentValue("TrackDuration", value))) {
+ goto bad_action;
+ }
+ if (NPT_FAILED(PLT_Didl::ParseTimeStamp(value, info.track_duration))) {
+ // some renderers return garbage sometimes
+ info.track_duration = NPT_TimeStamp(0.);
+ }
+
+ if (NPT_FAILED(action->GetArgumentValue("TrackMetaData", info.track_metadata))) {
+ goto bad_action;
+ }
+
+ if (NPT_FAILED(action->GetArgumentValue("TrackURI", info.track_uri))) {
+ goto bad_action;
+ }
+
+ if (NPT_FAILED(action->GetArgumentValue("RelTime", value))) {
+ goto bad_action;
+ }
+
+ // NOT_IMPLEMENTED is a valid value according to spec
+ if (value != "NOT_IMPLEMENTED" && NPT_FAILED(PLT_Didl::ParseTimeStamp(value, info.rel_time))) {
+ // some dogy renderers return garbage sometimes
+ info.rel_time = NPT_TimeStamp(-1.0f);
+ }
+
+ if (NPT_FAILED(action->GetArgumentValue("AbsTime", value))) {
+ goto bad_action;
+ }
+
+ // NOT_IMPLEMENTED is a valid value according to spec
+ if (value != "NOT_IMPLEMENTED" && NPT_FAILED(PLT_Didl::ParseTimeStamp(value, info.abs_time))) {
+ // some dogy renderers return garbage sometimes
+ info.abs_time = NPT_TimeStamp(-1.0f);
+ }
+
+ if (NPT_FAILED(action->GetArgumentValue("RelCount", info.rel_count))) {
+ goto bad_action;
+ }
+ if (NPT_FAILED(action->GetArgumentValue("AbsCount", info.abs_count))) {
+ goto bad_action;
+ }
+
+ m_Delegate->OnGetPositionInfoResult(NPT_SUCCESS, device, &info, userdata);
+ return NPT_SUCCESS;
+
+bad_action:
+ m_Delegate->OnGetPositionInfoResult(NPT_FAILURE, device, NULL, userdata);
+ return NPT_FAILURE;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::OnGetTransportInfoResponse
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::OnGetTransportInfoResponse(NPT_Result res,
+ PLT_DeviceDataReference& device,
+ PLT_ActionReference& action,
+ void* userdata)
+{
+ PLT_TransportInfo info;
+
+ if (NPT_FAILED(res) || action->GetErrorCode() != 0) {
+ goto bad_action;
+ }
+
+ if (NPT_FAILED(action->GetArgumentValue("CurrentTransportState", info.cur_transport_state))) {
+ goto bad_action;
+ }
+ if (NPT_FAILED(action->GetArgumentValue("CurrentTransportStatus", info.cur_transport_status))) {
+ goto bad_action;
+ }
+ if (NPT_FAILED(action->GetArgumentValue("CurrentSpeed", info.cur_speed))) {
+ goto bad_action;
+ }
+
+ m_Delegate->OnGetTransportInfoResult(NPT_SUCCESS, device, &info, userdata);
+ return NPT_SUCCESS;
+
+bad_action:
+ m_Delegate->OnGetTransportInfoResult(NPT_FAILURE, device, NULL, userdata);
+ return NPT_FAILURE;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::OnGetTransportSettingsResponse
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::OnGetTransportSettingsResponse(NPT_Result res,
+ PLT_DeviceDataReference& device,
+ PLT_ActionReference& action,
+ void* userdata)
+{
+ PLT_TransportSettings settings;
+
+ if (NPT_FAILED(res) || action->GetErrorCode() != 0) {
+ goto bad_action;
+ }
+
+ if (NPT_FAILED(action->GetArgumentValue("PlayMode", settings.play_mode))) {
+ goto bad_action;
+ }
+ if (NPT_FAILED(action->GetArgumentValue("RecQualityMode", settings.rec_quality_mode))) {
+ goto bad_action;
+ }
+
+ m_Delegate->OnGetTransportSettingsResult(NPT_SUCCESS, device, &settings, userdata);
+ return NPT_SUCCESS;
+
+bad_action:
+ m_Delegate->OnGetTransportSettingsResult(NPT_FAILURE, device, NULL, userdata);
+ return NPT_FAILURE;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::OnGetCurrentConnectionIDsResponse
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::OnGetCurrentConnectionIDsResponse(NPT_Result res,
+ PLT_DeviceDataReference& device,
+ PLT_ActionReference& action,
+ void* userdata)
+{
+ NPT_String value;
+ PLT_StringList IDs;
+
+ if (NPT_FAILED(res) || action->GetErrorCode() != 0) {
+ goto bad_action;
+ }
+
+ if (NPT_FAILED(action->GetArgumentValue("ConnectionIDs", value))) {
+ goto bad_action;
+ }
+ // parse the list of medias and return a list to listener
+ ParseCSV(value, IDs);
+
+ m_Delegate->OnGetCurrentConnectionIDsResult(NPT_SUCCESS, device, &IDs, userdata);
+ return NPT_SUCCESS;
+
+bad_action:
+ m_Delegate->OnGetCurrentConnectionIDsResult(NPT_FAILURE, device, NULL, userdata);
+ return NPT_FAILURE;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::OnGetCurrentConnectionInfoResponse
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::OnGetCurrentConnectionInfoResponse(NPT_Result res,
+ PLT_DeviceDataReference& device,
+ PLT_ActionReference& action,
+ void* userdata)
+{
+ NPT_String value;
+ PLT_ConnectionInfo info;
+
+ if (NPT_FAILED(res) || action->GetErrorCode() != 0) {
+ goto bad_action;
+ }
+
+ if (NPT_FAILED(action->GetArgumentValue("RcsID", info.rcs_id))) {
+ goto bad_action;
+ }
+ if (NPT_FAILED(action->GetArgumentValue("AVTransportID", info.avtransport_id))) {
+ goto bad_action;
+ }
+ if (NPT_FAILED(action->GetArgumentValue("ProtocolInfo", info.protocol_info))) {
+ goto bad_action;
+ }
+ if (NPT_FAILED(action->GetArgumentValue("PeerConnectionManager", info.peer_connection_mgr))) {
+ goto bad_action;
+ }
+ if (NPT_FAILED(action->GetArgumentValue("PeerConnectionID", info.peer_connection_id))) {
+ goto bad_action;
+ }
+ if (NPT_FAILED(action->GetArgumentValue("Direction", info.direction))) {
+ goto bad_action;
+ }
+ if (NPT_FAILED(action->GetArgumentValue("Status", info.status))) {
+ goto bad_action;
+ }
+ m_Delegate->OnGetCurrentConnectionInfoResult(NPT_SUCCESS, device, &info, userdata);
+ return NPT_SUCCESS;
+
+bad_action:
+ m_Delegate->OnGetCurrentConnectionInfoResult(NPT_FAILURE, device, NULL, userdata);
+ return NPT_FAILURE;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::OnGetProtocolInfoResponse
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::OnGetProtocolInfoResponse(NPT_Result res,
+ PLT_DeviceDataReference& device,
+ PLT_ActionReference& action,
+ void* userdata)
+{
+ NPT_String source_info, sink_info;
+ PLT_StringList sources, sinks;
+
+ if (NPT_FAILED(res) || action->GetErrorCode() != 0) {
+ goto bad_action;
+ }
+
+ if (NPT_FAILED(action->GetArgumentValue("Source", source_info))) {
+ goto bad_action;
+ }
+ ParseCSV(source_info, sources);
+
+ if (NPT_FAILED(action->GetArgumentValue("Sink", sink_info))) {
+ goto bad_action;
+ }
+ ParseCSV(sink_info, sinks);
+
+ m_Delegate->OnGetProtocolInfoResult(NPT_SUCCESS, device, &sources, &sinks, userdata);
+ return NPT_SUCCESS;
+
+bad_action:
+ m_Delegate->OnGetProtocolInfoResult(NPT_FAILURE, device, NULL, NULL, userdata);
+ return NPT_FAILURE;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::OnGetMuteResponse
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::OnGetMuteResponse(NPT_Result res,
+ PLT_DeviceDataReference& device,
+ PLT_ActionReference& action,
+ void* userdata)
+{
+ NPT_String channel, mute;
+
+ if (NPT_FAILED(res) || action->GetErrorCode() != 0) {
+ goto bad_action;
+ }
+
+ if (NPT_FAILED(action->GetArgumentValue("Channel", channel))) {
+ goto bad_action;
+ }
+
+ if (NPT_FAILED(action->GetArgumentValue("CurrentMute", mute))) {
+ goto bad_action;
+ }
+
+ m_Delegate->OnGetMuteResult(
+ NPT_SUCCESS,
+ device,
+ channel,
+ PLT_Service::IsTrue(mute)?true:false,
+ userdata);
+ return NPT_SUCCESS;
+
+bad_action:
+ m_Delegate->OnGetMuteResult(NPT_FAILURE, device, "", false, userdata);
+ return NPT_FAILURE;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::OnGetVolumeResponse
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::OnGetVolumeResponse(NPT_Result res,
+ PLT_DeviceDataReference& device,
+ PLT_ActionReference& action,
+ void* userdata)
+{
+ NPT_String channel;
+ NPT_String current_volume;
+ NPT_UInt32 volume;
+
+ if (NPT_FAILED(res) || action->GetErrorCode() != 0) {
+ goto bad_action;
+ }
+
+ if (NPT_FAILED(action->GetArgumentValue("Channel", channel))) {
+ goto bad_action;
+ }
+
+ if (NPT_FAILED(action->GetArgumentValue("CurrentVolume", current_volume))) {
+ goto bad_action;
+ }
+
+ if (NPT_FAILED(current_volume.ToInteger(volume))) {
+ goto bad_action;
+ }
+
+ m_Delegate->OnGetVolumeResult(NPT_SUCCESS, device, channel, volume, userdata);
+ return NPT_SUCCESS;
+
+bad_action:
+ m_Delegate->OnGetVolumeResult(NPT_FAILURE, device, "", 0, userdata);
+ return NPT_FAILURE;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaController::OnEventNotify
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaController::OnEventNotify(PLT_Service* service,
+ NPT_List<PLT_StateVariable*>* vars)
+{
+ if (!service->GetDevice()->GetType().StartsWith("urn:schemas-upnp-org:device:MediaRenderer"))
+ return NPT_FAILURE;
+
+ if (!m_Delegate) return NPT_SUCCESS;
+
+ /* make sure device associated to service is still around */
+ PLT_DeviceDataReference data;
+ NPT_CHECK_WARNING(FindRenderer(service->GetDevice()->GetUUID(), data));
+
+ m_Delegate->OnMRStateVariablesChanged(service, vars);
+ return NPT_SUCCESS;
+}
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaController.h b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaController.h
new file mode 100644
index 0000000..743c94f
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaController.h
@@ -0,0 +1,349 @@
+/*****************************************************************
+|
+| Platinum - AV Media Controller (Media Renderer Control Point)
+|
+| Copyright (c) 2004-2010, Plutinosoft, LLC.
+| All rights reserved.
+| http://www.plutinosoft.com
+|
+| This program is free software; you can redistribute it and/or
+| modify it under the terms of the GNU General Public License
+| as published by the Free Software Foundation; either version 2
+| of the License, or (at your option) any later version.
+|
+| OEMs, ISVs, VARs and other distributors that combine and
+| distribute commercially licensed software with Platinum software
+| and do not wish to distribute the source code for the commercially
+| licensed software under version 2, or (at your option) any later
+| version, of the GNU General Public License (the "GPL") must enter
+| into a commercial license agreement with Plutinosoft, LLC.
+| licensing@plutinosoft.com
+|
+| This program is distributed in the hope that it will be useful,
+| but WITHOUT ANY WARRANTY; without even the implied warranty of
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+| GNU General Public License for more details.
+|
+| You should have received a copy of the GNU General Public License
+| along with this program; see the file LICENSE.txt. If not, write to
+| the Free Software Foundation, Inc.,
+| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+| http://www.gnu.org/licenses/gpl-2.0.html
+|
+****************************************************************/
+
+#ifndef _PLT_MEDIA_CONTROLLER_H_
+#define _PLT_MEDIA_CONTROLLER_H_
+
+/*----------------------------------------------------------------------
+| includes
++---------------------------------------------------------------------*/
+#include "PltCtrlPoint.h"
+#include "PltMediaItem.h"
+
+/*----------------------------------------------------------------------
+| Defines
++---------------------------------------------------------------------*/
+typedef NPT_List<NPT_String> PLT_StringList;
+
+typedef struct {
+ PLT_StringList play_media;
+ PLT_StringList rec_media;
+ PLT_StringList rec_quality_modes;
+} PLT_DeviceCapabilities;
+
+typedef struct {
+ NPT_UInt32 num_tracks;
+ NPT_TimeStamp media_duration;
+ NPT_String cur_uri;
+ NPT_String cur_metadata;
+ NPT_String next_uri;
+ NPT_String next_metadata;
+ NPT_String play_medium;
+ NPT_String rec_medium;
+ NPT_String write_status;
+} PLT_MediaInfo;
+
+typedef struct {
+ NPT_UInt32 track;
+ NPT_TimeStamp track_duration;
+ NPT_String track_metadata;
+ NPT_String track_uri;
+ NPT_TimeStamp rel_time;
+ NPT_TimeStamp abs_time;
+ NPT_Int32 rel_count;
+ NPT_Int32 abs_count;
+} PLT_PositionInfo;
+
+typedef struct {
+ NPT_String cur_transport_state;
+ NPT_String cur_transport_status;
+ NPT_String cur_speed;
+} PLT_TransportInfo;
+
+typedef struct {
+ NPT_String play_mode;
+ NPT_String rec_quality_mode;
+} PLT_TransportSettings;
+
+typedef struct {
+ NPT_UInt32 rcs_id;
+ NPT_UInt32 avtransport_id;
+ NPT_String protocol_info;
+ NPT_String peer_connection_mgr;
+ NPT_UInt32 peer_connection_id;
+ NPT_String direction;
+ NPT_String status;
+} PLT_ConnectionInfo;
+
+/*----------------------------------------------------------------------
+| PLT_MediaControllerDelegate
++---------------------------------------------------------------------*/
+class PLT_MediaControllerDelegate
+{
+public:
+ virtual ~PLT_MediaControllerDelegate() {}
+
+ virtual bool OnMRAdded(PLT_DeviceDataReference& /* device */) { return true; }
+ virtual void OnMRRemoved(PLT_DeviceDataReference& /* device */) {}
+ virtual void OnMRStateVariablesChanged(PLT_Service* /* service */,
+ NPT_List<PLT_StateVariable*>* /* vars */) {}
+
+ // AVTransport
+ virtual void OnGetCurrentTransportActionsResult(
+ NPT_Result /* res */,
+ PLT_DeviceDataReference& /* device */,
+ PLT_StringList* /* actions */,
+ void* /* userdata */) {}
+
+ virtual void OnGetDeviceCapabilitiesResult(
+ NPT_Result /* res */,
+ PLT_DeviceDataReference& /* device */,
+ PLT_DeviceCapabilities* /* capabilities */,
+ void* /* userdata */) {}
+
+ virtual void OnGetMediaInfoResult(
+ NPT_Result /* res */,
+ PLT_DeviceDataReference& /* device */,
+ PLT_MediaInfo* /* info */,
+ void* /* userdata */) {}
+
+ virtual void OnGetPositionInfoResult(
+ NPT_Result /* res */,
+ PLT_DeviceDataReference& /* device */,
+ PLT_PositionInfo* /* info */,
+ void* /* userdata */) {}
+
+ virtual void OnGetTransportInfoResult(
+ NPT_Result /* res */,
+ PLT_DeviceDataReference& /* device */,
+ PLT_TransportInfo* /* info */,
+ void* /* userdata */) {}
+
+ virtual void OnGetTransportSettingsResult(
+ NPT_Result /* res */,
+ PLT_DeviceDataReference& /* device */,
+ PLT_TransportSettings* /* settings */,
+ void* /* userdata */) {}
+
+ virtual void OnNextResult(
+ NPT_Result /* res */,
+ PLT_DeviceDataReference& /* device */,
+ void* /* userdata */) {}
+
+ virtual void OnPauseResult(
+ NPT_Result /* res */,
+ PLT_DeviceDataReference& /* device */,
+ void* /* userdata */) {}
+
+ virtual void OnPlayResult(
+ NPT_Result /* res */,
+ PLT_DeviceDataReference& /* device */,
+ void* /* userdata */) {}
+
+ virtual void OnPreviousResult(
+ NPT_Result /* res */,
+ PLT_DeviceDataReference& /* device */,
+ void* /* userdata */) {}
+
+ virtual void OnSeekResult(
+ NPT_Result /* res */,
+ PLT_DeviceDataReference& /* device */,
+ void* /* userdata */) {}
+
+ virtual void OnSetAVTransportURIResult(
+ NPT_Result /* res */,
+ PLT_DeviceDataReference& /* device */,
+ void* /* userdata */) {}
+
+ virtual void OnSetNextAVTransportURIResult(
+ NPT_Result /* res */,
+ PLT_DeviceDataReference& /* device */,
+ void* /* userdata */) {}
+
+ virtual void OnSetPlayModeResult(
+ NPT_Result /* res */,
+ PLT_DeviceDataReference& /* device */,
+ void* /* userdata */) {}
+
+ virtual void OnStopResult(
+ NPT_Result /* res */,
+ PLT_DeviceDataReference& /* device */,
+ void* /* userdata */) {}
+
+ // ConnectionManager
+ virtual void OnGetCurrentConnectionIDsResult(
+ NPT_Result /* res */,
+ PLT_DeviceDataReference& /* device */,
+ PLT_StringList* /* ids */,
+ void* /* userdata */) {}
+
+ virtual void OnGetCurrentConnectionInfoResult(
+ NPT_Result /* res */,
+ PLT_DeviceDataReference& /* device */,
+ PLT_ConnectionInfo* /* info */,
+ void* /* userdata */) {}
+
+ virtual void OnGetProtocolInfoResult(
+ NPT_Result /* res */,
+ PLT_DeviceDataReference& /* device */,
+ PLT_StringList* /* sources */,
+ PLT_StringList* /* sinks */,
+ void* /* userdata */) {}
+
+ // RenderingControl
+ virtual void OnSetMuteResult(
+ NPT_Result /* res */,
+ PLT_DeviceDataReference& /* device */,
+ void* /* userdata */) {}
+
+ virtual void OnGetMuteResult(
+ NPT_Result /* res */,
+ PLT_DeviceDataReference& /* device */,
+ const char* /* channel */,
+ bool /* mute */,
+ void* /* userdata */) {}
+
+ virtual void OnSetVolumeResult(
+ NPT_Result /* res */,
+ PLT_DeviceDataReference& /* device */,
+ void* /* userdata */) {}
+
+ virtual void OnGetVolumeResult(
+ NPT_Result /* res */,
+ PLT_DeviceDataReference& /* device */,
+ const char* /* channel */,
+ NPT_UInt32 /* volume */,
+ void* /* userdata */) {}
+};
+
+/*----------------------------------------------------------------------
+| PLT_MediaController
++---------------------------------------------------------------------*/
+class PLT_MediaController : public PLT_CtrlPointListener
+{
+public:
+ PLT_MediaController(PLT_CtrlPointReference& ctrl_point,
+ PLT_MediaControllerDelegate* delegate = NULL);
+ ~PLT_MediaController() override;
+
+ // public methods
+ virtual void SetDelegate(PLT_MediaControllerDelegate* delegate) {
+ m_Delegate = delegate;
+ }
+
+ // PLT_CtrlPointListener methods
+ NPT_Result OnDeviceAdded(PLT_DeviceDataReference& device) override;
+ NPT_Result OnDeviceRemoved(PLT_DeviceDataReference& device) override;
+ NPT_Result OnActionResponse(NPT_Result res, PLT_ActionReference& action, void* userdata) override;
+ NPT_Result OnEventNotify(PLT_Service* service, NPT_List<PLT_StateVariable*>* vars) override;
+
+ // AVTransport
+ NPT_Result GetCurrentTransportActions(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, void* userdata);
+ NPT_Result GetDeviceCapabilities(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, void* userdata);
+ NPT_Result GetMediaInfo(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, void* userdata);
+ NPT_Result GetPositionInfo(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, void* userdata);
+ NPT_Result GetTransportInfo(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, void* userdata);
+ NPT_Result GetTransportSettings(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, void* userdata);
+ NPT_Result Next(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, void* userdata);
+ NPT_Result Pause(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, void* userdata);
+ NPT_Result Play(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, NPT_String speed, void* userdata);
+ NPT_Result Previous(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, void* userdata);
+ NPT_Result Seek(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, NPT_String unit, NPT_String target, void* userdata);
+ bool CanSetNextAVTransportURI(PLT_DeviceDataReference& device);
+ NPT_Result SetAVTransportURI(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, const char* uri, const char* metadata, void* userdata);
+ NPT_Result SetNextAVTransportURI(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, const char* next_uri, const char* next_metadata, void* userdata);
+ NPT_Result SetPlayMode(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, NPT_String new_play_mode, void* userdata);
+ NPT_Result Stop(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, void* userdata);
+
+ // ConnectionManager
+ NPT_Result GetCurrentConnectionIDs(PLT_DeviceDataReference& device, void* userdata);
+ NPT_Result GetCurrentConnectionInfo(PLT_DeviceDataReference& device, NPT_UInt32 connection_id, void* userdata);
+ NPT_Result GetProtocolInfo(PLT_DeviceDataReference& device, void* userdata);
+
+ // RenderingControl
+ NPT_Result SetMute(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, const char* channel, bool mute, void* userdata);
+ NPT_Result GetMute(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, const char* channel, void* userdata);
+ NPT_Result SetVolume(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, const char* channel, int volume, void* userdata);
+ NPT_Result GetVolume(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, const char* channel, void* userdata);
+
+ // VariableStates
+ virtual NPT_Result GetProtocolInfoSink(const NPT_String& device_uuid, NPT_List<NPT_String>& sinks);
+ virtual NPT_Result GetTransportState(const NPT_String& device_uuid, NPT_String& state);
+ virtual NPT_Result GetVolumeState(const NPT_String& device_uuid, NPT_UInt32& volume);
+
+ // methods
+ virtual NPT_Result FindRenderer(const char* uuid, PLT_DeviceDataReference& device);
+ virtual NPT_Result FindMatchingProtocolInfo(NPT_List<NPT_String>& sinks, const char* protocol_info);
+ virtual NPT_Result FindBestResource(PLT_DeviceDataReference& device, PLT_MediaObject& item, NPT_Cardinal& resource_index);
+
+private:
+ NPT_Result InvokeActionWithInstance(PLT_ActionReference& action, NPT_UInt32 instance_id, void* userdata = NULL);
+
+ NPT_Result OnGetCurrentTransportActionsResponse(NPT_Result res, PLT_DeviceDataReference& device, PLT_ActionReference& action, void* userdata);
+ NPT_Result OnGetDeviceCapabilitiesResponse(NPT_Result res, PLT_DeviceDataReference& device, PLT_ActionReference& action, void* userdata);
+ NPT_Result OnGetMediaInfoResponse(NPT_Result res, PLT_DeviceDataReference& device, PLT_ActionReference& action, void* userdata);
+ NPT_Result OnGetPositionInfoResponse(NPT_Result res, PLT_DeviceDataReference& device, PLT_ActionReference& action, void* userdata);
+ NPT_Result OnGetTransportInfoResponse(NPT_Result res, PLT_DeviceDataReference& device, PLT_ActionReference& action, void* userdata);
+ NPT_Result OnGetTransportSettingsResponse(NPT_Result res, PLT_DeviceDataReference& device, PLT_ActionReference& action, void* userdata);
+
+ NPT_Result OnGetCurrentConnectionIDsResponse(NPT_Result res, PLT_DeviceDataReference& device, PLT_ActionReference& action, void* userdata);
+ NPT_Result OnGetCurrentConnectionInfoResponse(NPT_Result res, PLT_DeviceDataReference& device, PLT_ActionReference& action, void* userdata);
+ NPT_Result OnGetProtocolInfoResponse(NPT_Result res, PLT_DeviceDataReference& device, PLT_ActionReference& action, void* userdata);
+
+ NPT_Result OnGetMuteResponse(NPT_Result res, PLT_DeviceDataReference& device, PLT_ActionReference& action, void* userdata);
+ NPT_Result OnGetVolumeResponse(NPT_Result res, PLT_DeviceDataReference& device, PLT_ActionReference& action, void* userdata);
+
+public:
+ static void ParseCSV(const char* csv, PLT_StringList& values) {
+ const char* start = csv;
+ const char* p = start;
+
+ // look for the , character
+ while (*p) {
+ if (*p == ',') {
+ NPT_String val(start, (int)(p-start));
+ val.Trim(' ');
+ values.Add(val);
+ start = p + 1;
+ }
+ p++;
+ }
+
+ // last one
+ NPT_String last(start, (int)(p-start));
+ last.Trim(' ');
+ if (last.GetLength()) {
+ values.Add(last);
+ }
+ }
+
+private:
+ PLT_CtrlPointReference m_CtrlPoint;
+ PLT_MediaControllerDelegate* m_Delegate;
+ NPT_Lock<PLT_DeviceDataReferenceList> m_MediaRenderers;
+};
+
+typedef NPT_Reference<PLT_MediaController> PLT_MediaControllerReference;
+
+#endif /* _PLT_MEDIA_CONTROLLER_H_ */
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaRenderer.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaRenderer.cpp
new file mode 100644
index 0000000..88144f7
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaRenderer.cpp
@@ -0,0 +1,516 @@
+/*****************************************************************
+|
+| Platinum - AV Media Renderer Device
+|
+| Copyright (c) 2004-2010, Plutinosoft, LLC.
+| All rights reserved.
+| http://www.plutinosoft.com
+|
+| This program is free software; you can redistribute it and/or
+| modify it under the terms of the GNU General Public License
+| as published by the Free Software Foundation; either version 2
+| of the License, or (at your option) any later version.
+|
+| OEMs, ISVs, VARs and other distributors that combine and
+| distribute commercially licensed software with Platinum software
+| and do not wish to distribute the source code for the commercially
+| licensed software under version 2, or (at your option) any later
+| version, of the GNU General Public License (the "GPL") must enter
+| into a commercial license agreement with Plutinosoft, LLC.
+| licensing@plutinosoft.com
+|
+| This program is distributed in the hope that it will be useful,
+| but WITHOUT ANY WARRANTY; without even the implied warranty of
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+| GNU General Public License for more details.
+|
+| You should have received a copy of the GNU General Public License
+| along with this program; see the file LICENSE.txt. If not, write to
+| the Free Software Foundation, Inc.,
+| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+| http://www.gnu.org/licenses/gpl-2.0.html
+|
+****************************************************************/
+
+/*----------------------------------------------------------------------
+| includes
++---------------------------------------------------------------------*/
+#include "Neptune.h"
+#include "PltMediaRenderer.h"
+#include "PltService.h"
+
+NPT_SET_LOCAL_LOGGER("platinum.media.renderer")
+
+/*----------------------------------------------------------------------
+| external references
++---------------------------------------------------------------------*/
+extern NPT_UInt8 RDR_ConnectionManagerSCPD[];
+extern NPT_UInt8 RDR_AVTransportSCPD[];
+extern NPT_UInt8 RDR_RenderingControlSCPD[];
+
+/*----------------------------------------------------------------------
+| PLT_MediaRenderer::PLT_MediaRenderer
++---------------------------------------------------------------------*/
+PLT_MediaRenderer::PLT_MediaRenderer(const char* friendly_name,
+ bool show_ip /* = false */,
+ const char* uuid /* = NULL */,
+ unsigned int port /* = 0 */,
+ bool port_rebind /* = false */) :
+ PLT_DeviceHost("/",
+ uuid,
+ "urn:schemas-upnp-org:device:MediaRenderer:1",
+ friendly_name,
+ show_ip,
+ port,
+ port_rebind),
+ m_Delegate(NULL)
+{
+ m_ModelDescription = "Plutinosoft AV Media Renderer Device";
+ m_ModelName = "AV Renderer Device";
+ m_ModelURL = "http://www.plutinosoft.com/platinum";
+ m_DlnaDoc = "DMR-1.50";
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaRenderer::~PLT_MediaRenderer
++---------------------------------------------------------------------*/
+PLT_MediaRenderer::~PLT_MediaRenderer()
+{
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaRenderer::SetupServices
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaRenderer::SetupServices()
+{
+ NPT_Reference<PLT_Service> service;
+
+ {
+ /* AVTransport */
+ service = new PLT_Service(
+ this,
+ "urn:schemas-upnp-org:service:AVTransport:1",
+ "urn:upnp-org:serviceId:AVTransport",
+ "AVTransport",
+ "urn:schemas-upnp-org:metadata-1-0/AVT/");
+ NPT_CHECK_FATAL(service->SetSCPDXML((const char*) RDR_AVTransportSCPD));
+ NPT_CHECK_FATAL(AddService(service.AsPointer()));
+
+ service->SetStateVariableRate("LastChange", NPT_TimeInterval(0.2f));
+ service->SetStateVariable("A_ARG_TYPE_InstanceID", "0");
+
+ // GetCurrentTransportActions
+ service->SetStateVariable("CurrentTransportActions", "Play,Pause,Stop,Seek,Next,Previous");
+
+ // GetDeviceCapabilities
+ service->SetStateVariable("PossiblePlaybackStorageMedia", "NONE,NETWORK,HDD,CD-DA,UNKNOWN");
+ service->SetStateVariable("PossibleRecordStorageMedia", "NOT_IMPLEMENTED");
+ service->SetStateVariable("PossibleRecordQualityModes", "NOT_IMPLEMENTED");
+
+ // GetMediaInfo
+ service->SetStateVariable("NumberOfTracks", "0");
+ service->SetStateVariable("CurrentMediaDuration", "00:00:00");
+ service->SetStateVariable("AVTransportURI", "");
+ service->SetStateVariable("AVTransportURIMetadata", "");;
+ service->SetStateVariable("NextAVTransportURI", "NOT_IMPLEMENTED");
+ service->SetStateVariable("NextAVTransportURIMetadata", "NOT_IMPLEMENTED");
+ service->SetStateVariable("PlaybackStorageMedium", "NONE");
+ service->SetStateVariable("RecordStorageMedium", "NOT_IMPLEMENTED");
+ service->SetStateVariable("RecordMediumWriteStatus", "NOT_IMPLEMENTED");
+
+ // GetPositionInfo
+ service->SetStateVariable("CurrentTrack", "0");
+ service->SetStateVariable("CurrentTrackDuration", "00:00:00");
+ service->SetStateVariable("CurrentTrackMetadata", "");
+ service->SetStateVariable("CurrentTrackURI", "");
+ service->SetStateVariable("RelativeTimePosition", "00:00:00");
+ service->SetStateVariable("AbsoluteTimePosition", "00:00:00");
+ service->SetStateVariable("RelativeCounterPosition", "2147483647"); // means NOT_IMPLEMENTED
+ service->SetStateVariable("AbsoluteCounterPosition", "2147483647"); // means NOT_IMPLEMENTED
+
+ // disable indirect eventing for certain state variables
+ PLT_StateVariable* var;
+ var = service->FindStateVariable("RelativeTimePosition");
+ if (var) var->DisableIndirectEventing();
+ var = service->FindStateVariable("AbsoluteTimePosition");
+ if (var) var->DisableIndirectEventing();
+ var = service->FindStateVariable("RelativeCounterPosition");
+ if (var) var->DisableIndirectEventing();
+ var = service->FindStateVariable("AbsoluteCounterPosition");
+ if (var) var->DisableIndirectEventing();
+
+ // GetTransportInfo
+ service->SetStateVariable("TransportState", "NO_MEDIA_PRESENT");
+ service->SetStateVariable("TransportStatus", "OK");
+ service->SetStateVariable("TransportPlaySpeed", "1");
+
+ // GetTransportSettings
+ service->SetStateVariable("CurrentPlayMode", "NORMAL");
+ service->SetStateVariable("CurrentRecordQualityMode", "NOT_IMPLEMENTED");
+
+ service.Detach();
+ service = NULL;
+ }
+
+ {
+ /* ConnectionManager */
+ service = new PLT_Service(
+ this,
+ "urn:schemas-upnp-org:service:ConnectionManager:1",
+ "urn:upnp-org:serviceId:ConnectionManager",
+ "ConnectionManager");
+ NPT_CHECK_FATAL(service->SetSCPDXML((const char*) RDR_ConnectionManagerSCPD));
+ NPT_CHECK_FATAL(AddService(service.AsPointer()));
+
+ service->SetStateVariable("CurrentConnectionIDs", "0");
+
+ // put all supported mime types here instead
+ service->SetStateVariable("SinkProtocolInfo", "http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_PRO,http-get:*:video/x-ms-asf:DLNA.ORG_PN=MPEG4_P2_ASF_SP_G726,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_FULL,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_MED,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_BASE,http-get:*:audio/L16;rate=44100;channels=1:DLNA.ORG_PN=LPCM,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_PAL,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVHIGH_PRO,http-get:*:audio/L16;rate=44100;channels=2:DLNA.ORG_PN=LPCM,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_SM,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L1_WMA,http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMDRM_WMABASE,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVHIGH_FULL,http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMAFULL,http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMABASE,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVSPLL_BASE,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC_XAC3,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMDRM_WMVSPLL_BASE,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVSPML_BASE,http-get:*:video/x-ms-asf:DLNA.ORG_PN=MPEG4_P2_ASF_ASP_L5_SO_G726,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_LRG,http-get:*:audio/mpeg:DLNA.ORG_PN=MP3,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_PAL_XAC3,http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMAPRO,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG1,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_TN,http-get:*:video/x-ms-asf:DLNA.ORG_PN=MPEG4_P2_ASF_ASP_L4_SO_G726,http-get:*:audio/L16;rate=48000;channels=2:DLNA.ORG_PN=LPCM,http-get:*:audio/mpeg:DLNA.ORG_PN=MP3X,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVSPML_MP3,http-get:*:video/x-ms-wmv:*");
+ service->SetStateVariable("SourceProtocolInfo", "");
+
+ service.Detach();
+ service = NULL;
+ }
+
+ {
+ /* RenderingControl */
+ service = new PLT_Service(
+ this,
+ "urn:schemas-upnp-org:service:RenderingControl:1",
+ "urn:upnp-org:serviceId:RenderingControl",
+ "RenderingControl",
+ "urn:schemas-upnp-org:metadata-1-0/RCS/");
+ NPT_CHECK_FATAL(service->SetSCPDXML((const char*) RDR_RenderingControlSCPD));
+ NPT_CHECK_FATAL(AddService(service.AsPointer()));
+
+ service->SetStateVariableRate("LastChange", NPT_TimeInterval(0.2f));
+
+ service->SetStateVariable("Mute", "0");
+ service->SetStateVariableExtraAttribute("Mute", "Channel", "Master");
+ service->SetStateVariable("Volume", "100");
+ service->SetStateVariableExtraAttribute("Volume", "Channel", "Master");
+ service->SetStateVariable("VolumeDB", "0");
+ service->SetStateVariableExtraAttribute("VolumeDB", "Channel", "Master");
+
+ service->SetStateVariable("PresetNameList", "FactoryDefaults");
+
+ service.Detach();
+ service = NULL;
+ }
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaRenderer::OnAction
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaRenderer::OnAction(PLT_ActionReference& action,
+ const PLT_HttpRequestContext& context)
+{
+ NPT_COMPILER_UNUSED(context);
+
+ /* parse the action name */
+ NPT_String name = action->GetActionDesc().GetName();
+
+ // since all actions take an instance ID and we only support 1 instance
+ // verify that the Instance ID is 0 and return an error here now if not
+ NPT_String serviceType = action->GetActionDesc().GetService()->GetServiceType();
+ if (serviceType.Compare("urn:schemas-upnp-org:service:AVTransport:1", true) == 0) {
+ if (NPT_FAILED(action->VerifyArgumentValue("InstanceID", "0"))) {
+ action->SetError(718, "Not valid InstanceID");
+ return NPT_FAILURE;
+ }
+ }
+ serviceType = action->GetActionDesc().GetService()->GetServiceType();
+ if (serviceType.Compare("urn:schemas-upnp-org:service:RenderingControl:1", true) == 0) {
+ if (NPT_FAILED(action->VerifyArgumentValue("InstanceID", "0"))) {
+ action->SetError(702, "Not valid InstanceID");
+ return NPT_FAILURE;
+ }
+ }
+
+ /* Is it a ConnectionManager Service Action ? */
+ if (name.Compare("GetCurrentConnectionInfo", true) == 0) {
+ return OnGetCurrentConnectionInfo(action);
+ }
+
+ /* Is it a AVTransport Service Action ? */
+ if (name.Compare("Next", true) == 0) {
+ return OnNext(action);
+ }
+ if (name.Compare("Pause", true) == 0) {
+ return OnPause(action);
+ }
+ if (name.Compare("Play", true) == 0) {
+ return OnPlay(action);
+ }
+ if (name.Compare("Previous", true) == 0) {
+ return OnPrevious(action);
+ }
+ if (name.Compare("Seek", true) == 0) {
+ return OnSeek(action);
+ }
+ if (name.Compare("Stop", true) == 0) {
+ return OnStop(action);
+ }
+ if (name.Compare("SetAVTransportURI", true) == 0) {
+ return OnSetAVTransportURI(action);
+ }
+ if (name.Compare("SetNextAVTransportURI", true) == 0) {
+ return OnSetNextAVTransportURI(action);
+ }
+ if (name.Compare("SetPlayMode", true) == 0) {
+ return OnSetPlayMode(action);
+ }
+
+ /* Is it a RendererControl Service Action ? */
+ if (name.Compare("SetVolume", true) == 0) {
+ return OnSetVolume(action);
+ }
+ if (name.Compare("SetVolumeDB", true) == 0) {
+ return OnSetVolumeDB(action);
+ }
+ if (name.Compare("GetVolumeDBRange", true) == 0) {
+ return OnGetVolumeDBRange(action);
+
+ }
+ if (name.Compare("SetMute", true) == 0) {
+ return OnSetMute(action);
+ }
+
+ // other actions rely on state variables
+ NPT_CHECK_LABEL_WARNING(action->SetArgumentsOutFromStateVariable(), failure);
+ return NPT_SUCCESS;
+
+failure:
+ action->SetError(401,"No Such Action.");
+ return NPT_FAILURE;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaRenderer::OnGetCurrentConnectionInfo
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaRenderer::OnGetCurrentConnectionInfo(PLT_ActionReference& action)
+{
+ if (m_Delegate) {
+ return m_Delegate->OnGetCurrentConnectionInfo(action);
+ }
+
+ if (NPT_FAILED(action->VerifyArgumentValue("ConnectionID", "0"))) {
+ action->SetError(706,"No Such Connection.");
+ return NPT_FAILURE;
+ }
+
+ if (NPT_FAILED(action->SetArgumentValue("RcsID", "0"))){
+ return NPT_FAILURE;
+ }
+ if (NPT_FAILED(action->SetArgumentValue("AVTransportID", "0"))) {
+ return NPT_FAILURE;
+ }
+ if (NPT_FAILED(action->SetArgumentOutFromStateVariable("ProtocolInfo"))) {
+ return NPT_FAILURE;
+ }
+ if (NPT_FAILED(action->SetArgumentValue("PeerConnectionManager", "/"))) {
+ return NPT_FAILURE;
+ }
+ if (NPT_FAILED(action->SetArgumentValue("PeerConnectionID", "-1"))) {
+ return NPT_FAILURE;
+ }
+ if (NPT_FAILED(action->SetArgumentValue("Direction", "Input"))) {
+ return NPT_FAILURE;
+ }
+ if (NPT_FAILED(action->SetArgumentValue("Status", "Unknown"))) {
+ return NPT_FAILURE;
+ }
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaRenderer::OnNext
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaRenderer::OnNext(PLT_ActionReference& action)
+{
+ if (m_Delegate) {
+ return m_Delegate->OnNext(action);
+ }
+ return NPT_ERROR_NOT_IMPLEMENTED;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaRenderer::OnPause
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaRenderer::OnPause(PLT_ActionReference& action)
+{
+ if (m_Delegate) {
+ return m_Delegate->OnPause(action);
+ }
+ return NPT_ERROR_NOT_IMPLEMENTED;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaRenderer::OnPlay
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaRenderer::OnPlay(PLT_ActionReference& action)
+{
+ if (m_Delegate) {
+ return m_Delegate->OnPlay(action);
+ }
+ return NPT_ERROR_NOT_IMPLEMENTED;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaRenderer::OnPrevious
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaRenderer::OnPrevious(PLT_ActionReference& action)
+{
+ if (m_Delegate) {
+ return m_Delegate->OnPrevious(action);
+ }
+ return NPT_ERROR_NOT_IMPLEMENTED;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaRenderer::OnSeek
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaRenderer::OnSeek(PLT_ActionReference& action)
+{
+ if (m_Delegate) {
+ return m_Delegate->OnSeek(action);
+ }
+ return NPT_ERROR_NOT_IMPLEMENTED;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaRenderer::OnStop
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaRenderer::OnStop(PLT_ActionReference& action)
+{
+ if (m_Delegate) {
+ return m_Delegate->OnStop(action);
+ }
+ return NPT_ERROR_NOT_IMPLEMENTED;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaRenderer::OnSetAVTransportURI
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaRenderer::OnSetAVTransportURI(PLT_ActionReference& action)
+{
+ if (m_Delegate) {
+ return m_Delegate->OnSetAVTransportURI(action);
+ }
+
+ // default implementation is using state variable
+ NPT_String uri;
+ NPT_CHECK_WARNING(action->GetArgumentValue("CurrentURI", uri));
+
+ NPT_String metadata;
+ NPT_CHECK_WARNING(action->GetArgumentValue("CurrentURIMetaData", metadata));
+
+ PLT_Service* serviceAVT;
+ NPT_CHECK_WARNING(FindServiceByType("urn:schemas-upnp-org:service:AVTransport:1", serviceAVT));
+
+ // update service state variables
+ serviceAVT->SetStateVariable("AVTransportURI", uri);
+ serviceAVT->SetStateVariable("AVTransportURIMetaData", metadata);
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+ | PLT_MediaRenderer::OnSetAVTransportURI
+ +---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaRenderer::OnSetNextAVTransportURI(PLT_ActionReference& action)
+{
+ if (m_Delegate) {
+ return m_Delegate->OnSetNextAVTransportURI(action);
+ }
+
+ // default implementation is using state variable
+ NPT_String uri;
+ NPT_CHECK_WARNING(action->GetArgumentValue("NextURI", uri));
+
+ NPT_String metadata;
+ NPT_CHECK_WARNING(action->GetArgumentValue("NextURIMetaData", metadata));
+
+ PLT_Service* serviceAVT;
+ NPT_CHECK_WARNING(FindServiceByType("urn:schemas-upnp-org:service:AVTransport:1", serviceAVT));
+
+ // update service state variables
+ serviceAVT->SetStateVariable("NextAVTransportURI", uri);
+ serviceAVT->SetStateVariable("NextAVTransportURIMetaData", metadata);
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaRenderer::OnSetPlayMode
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaRenderer::OnSetPlayMode(PLT_ActionReference& action)
+{
+ if (m_Delegate) {
+ return m_Delegate->OnSetPlayMode(action);
+ }
+ return NPT_ERROR_NOT_IMPLEMENTED;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaRenderer::OnSetVolume
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaRenderer::OnSetVolume(PLT_ActionReference& action)
+{
+ if (m_Delegate) {
+ return m_Delegate->OnSetVolume(action);
+ }
+ return NPT_ERROR_NOT_IMPLEMENTED;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaRenderer::OnSetVolumeDB
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaRenderer::OnSetVolumeDB(PLT_ActionReference& action)
+{
+ if (m_Delegate) {
+ return m_Delegate->OnSetVolumeDB(action);
+ }
+ return NPT_ERROR_NOT_IMPLEMENTED;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaRenderer::OnGetVolumeDBRange
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaRenderer::OnGetVolumeDBRange(PLT_ActionReference& action)
+{
+ if (m_Delegate) {
+ return m_Delegate->OnGetVolumeDBRange(action);
+ }
+ return NPT_ERROR_NOT_IMPLEMENTED;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaRenderer::OnSetMute
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaRenderer::OnSetMute(PLT_ActionReference& action)
+{
+ if (m_Delegate) {
+ return m_Delegate->OnSetMute(action);
+ }
+ return NPT_ERROR_NOT_IMPLEMENTED;
+}
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaRenderer.h b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaRenderer.h
new file mode 100644
index 0000000..ec30a36
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaRenderer.h
@@ -0,0 +1,119 @@
+/*****************************************************************
+|
+| Platinum - AV Media Renderer Device
+|
+| Copyright (c) 2004-2010, Plutinosoft, LLC.
+| All rights reserved.
+| http://www.plutinosoft.com
+|
+| This program is free software; you can redistribute it and/or
+| modify it under the terms of the GNU General Public License
+| as published by the Free Software Foundation; either version 2
+| of the License, or (at your option) any later version.
+|
+| OEMs, ISVs, VARs and other distributors that combine and
+| distribute commercially licensed software with Platinum software
+| and do not wish to distribute the source code for the commercially
+| licensed software under version 2, or (at your option) any later
+| version, of the GNU General Public License (the "GPL") must enter
+| into a commercial license agreement with Plutinosoft, LLC.
+| licensing@plutinosoft.com
+|
+| This program is distributed in the hope that it will be useful,
+| but WITHOUT ANY WARRANTY; without even the implied warranty of
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+| GNU General Public License for more details.
+|
+| You should have received a copy of the GNU General Public License
+| along with this program; see the file LICENSE.txt. If not, write to
+| the Free Software Foundation, Inc.,
+| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+| http://www.gnu.org/licenses/gpl-2.0.html
+|
+****************************************************************/
+
+#ifndef _PLT_MEDIA_RENDERER_H_
+#define _PLT_MEDIA_RENDERER_H_
+
+/*----------------------------------------------------------------------
+| includes
++---------------------------------------------------------------------*/
+#include "PltDeviceHost.h"
+
+/*----------------------------------------------------------------------
+| PLT_MediaRendererDelegate
++---------------------------------------------------------------------*/
+class PLT_MediaRendererDelegate
+{
+public:
+ virtual ~PLT_MediaRendererDelegate() {}
+
+ // ConnectionManager
+ virtual NPT_Result OnGetCurrentConnectionInfo(PLT_ActionReference& action) = 0;
+
+ // AVTransport
+ virtual NPT_Result OnNext(PLT_ActionReference& action) = 0;
+ virtual NPT_Result OnPause(PLT_ActionReference& action) = 0;
+ virtual NPT_Result OnPlay(PLT_ActionReference& action) = 0;
+ virtual NPT_Result OnPrevious(PLT_ActionReference& action) = 0;
+ virtual NPT_Result OnSeek(PLT_ActionReference& action) = 0;
+ virtual NPT_Result OnStop(PLT_ActionReference& action) = 0;
+ virtual NPT_Result OnSetAVTransportURI(PLT_ActionReference& action) = 0;
+ virtual NPT_Result OnSetNextAVTransportURI(PLT_ActionReference& action) = 0;
+ virtual NPT_Result OnSetPlayMode(PLT_ActionReference& action) = 0;
+
+ // RenderingControl
+ virtual NPT_Result OnSetVolume(PLT_ActionReference& action) = 0;
+ virtual NPT_Result OnSetVolumeDB(PLT_ActionReference& action) = 0;
+ virtual NPT_Result OnGetVolumeDBRange(PLT_ActionReference& action) = 0;
+ virtual NPT_Result OnSetMute(PLT_ActionReference& action) = 0;
+};
+
+/*----------------------------------------------------------------------
+| PLT_MediaRenderer
++---------------------------------------------------------------------*/
+class PLT_MediaRenderer : public PLT_DeviceHost
+{
+public:
+ PLT_MediaRenderer(const char* friendly_name,
+ bool show_ip = false,
+ const char* uuid = NULL,
+ unsigned int port = 0,
+ bool port_rebind = false);
+ // methods
+ virtual void SetDelegate(PLT_MediaRendererDelegate* delegate) { m_Delegate = delegate; }
+
+ // PLT_DeviceHost methods
+ NPT_Result SetupServices() override;
+ NPT_Result OnAction(PLT_ActionReference& action,
+ const PLT_HttpRequestContext& context) override;
+
+protected:
+ ~PLT_MediaRenderer() override;
+
+ // PLT_MediaRendererInterface methods
+ // ConnectionManager
+ virtual NPT_Result OnGetCurrentConnectionInfo(PLT_ActionReference& action);
+
+ // AVTransport
+ virtual NPT_Result OnNext(PLT_ActionReference& action);
+ virtual NPT_Result OnPause(PLT_ActionReference& action);
+ virtual NPT_Result OnPlay(PLT_ActionReference& action);
+ virtual NPT_Result OnPrevious(PLT_ActionReference& action);
+ virtual NPT_Result OnSeek(PLT_ActionReference& action);
+ virtual NPT_Result OnStop(PLT_ActionReference& action);
+ virtual NPT_Result OnSetAVTransportURI(PLT_ActionReference& action);
+ virtual NPT_Result OnSetNextAVTransportURI(PLT_ActionReference& action);
+ virtual NPT_Result OnSetPlayMode(PLT_ActionReference& action);
+
+ // RenderingControl
+ virtual NPT_Result OnSetVolume(PLT_ActionReference& action);
+ virtual NPT_Result OnSetVolumeDB(PLT_ActionReference &action);
+ virtual NPT_Result OnGetVolumeDBRange(PLT_ActionReference &action);
+ virtual NPT_Result OnSetMute(PLT_ActionReference& action);
+
+private:
+ PLT_MediaRendererDelegate* m_Delegate;
+};
+
+#endif /* _PLT_MEDIA_RENDERER_H_ */
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/RdrConnectionManagerSCPD.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/RdrConnectionManagerSCPD.cpp
new file mode 100644
index 0000000..4cc0e02
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/RdrConnectionManagerSCPD.cpp
@@ -0,0 +1,257 @@
+/*****************************************************************
+|
+| Platinum - ConnectionManager SCPD
+|
+| Copyright (c) 2004-2010, Plutinosoft, LLC.
+| All rights reserved.
+| http://www.plutinosoft.com
+|
+| This program is free software; you can redistribute it and/or
+| modify it under the terms of the GNU General Public License
+| as published by the Free Software Foundation; either version 2
+| of the License, or (at your option) any later version.
+|
+| OEMs, ISVs, VARs and other distributors that combine and
+| distribute commercially licensed software with Platinum software
+| and do not wish to distribute the source code for the commercially
+| licensed software under version 2, or (at your option) any later
+| version, of the GNU General Public License (the "GPL") must enter
+| into a commercial license agreement with Plutinosoft, LLC.
+| licensing@plutinosoft.com
+|
+| This program is distributed in the hope that it will be useful,
+| but WITHOUT ANY WARRANTY; without even the implied warranty of
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+| GNU General Public License for more details.
+|
+| You should have received a copy of the GNU General Public License
+| along with this program; see the file LICENSE.txt. If not, write to
+| the Free Software Foundation, Inc.,
+| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+| http://www.gnu.org/licenses/gpl-2.0.html
+|
+****************************************************************/
+
+/*----------------------------------------------------------------------
+| includes
++---------------------------------------------------------------------*/
+#include "Neptune.h"
+
+/*----------------------------------------------------------------------
+| globals
++---------------------------------------------------------------------*/
+NPT_UInt8 RDR_ConnectionManagerSCPD[] =
+{
+ 0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x31, 0x2E, 0x30, 0x22, 0x20,
+ 0x65, 0x6E, 0x63, 0x6F, 0x64, 0x69, 0x6E, 0x67, 0x3D, 0x22, 0x75, 0x74, 0x66, 0x2D, 0x38, 0x22, 0x3F, 0x3E, 0x0D, 0x0A,
+ 0x3C, 0x73, 0x63, 0x70, 0x64, 0x20, 0x78, 0x6D, 0x6C, 0x6E, 0x73, 0x3D, 0x27, 0x75, 0x72, 0x6E, 0x3A, 0x73, 0x63, 0x68,
+ 0x65, 0x6D, 0x61, 0x73, 0x2D, 0x75, 0x70, 0x6E, 0x70, 0x2D, 0x6F, 0x72, 0x67, 0x3A, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
+ 0x65, 0x2D, 0x31, 0x2D, 0x30, 0x27, 0x3E, 0x0D, 0x0A, 0x09, 0x3C, 0x73, 0x70, 0x65, 0x63, 0x56, 0x65, 0x72, 0x73, 0x69,
+ 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x6D, 0x61, 0x6A, 0x6F, 0x72, 0x3E, 0x31, 0x3C, 0x2F, 0x6D, 0x61, 0x6A,
+ 0x6F, 0x72, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x6D, 0x69, 0x6E, 0x6F, 0x72, 0x3E, 0x30, 0x3C, 0x2F, 0x6D, 0x69, 0x6E,
+ 0x6F, 0x72, 0x3E, 0x0D, 0x0A, 0x09, 0x3C, 0x2F, 0x73, 0x70, 0x65, 0x63, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3E,
+ 0x0D, 0x0A, 0x09, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C,
+ 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x47, 0x65,
+ 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x49, 0x6E,
+ 0x66, 0x6F, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D,
+ 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D,
+ 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x6F, 0x6E,
+ 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69,
+ 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61,
+ 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41,
+ 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x49, 0x44,
+ 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
+ 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E,
+ 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 0x63, 0x73, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65,
+ 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F,
+ 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
+ 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x52, 0x63, 0x73, 0x49, 0x44, 0x3C,
+ 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C,
+ 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D,
+ 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x49,
+ 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65,
+ 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E,
+ 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74,
+ 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45,
+ 0x5F, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61,
+ 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09,
+ 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09,
+ 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61,
+ 0x6D, 0x65, 0x3E, 0x50, 0x72, 0x6F, 0x74, 0x6F, 0x63, 0x6F, 0x6C, 0x49, 0x6E, 0x66, 0x6F, 0x3C, 0x2F, 0x6E, 0x61, 0x6D,
+ 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E,
+ 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61,
+ 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x50, 0x72, 0x6F, 0x74, 0x6F,
+ 0x63, 0x6F, 0x6C, 0x49, 0x6E, 0x66, 0x6F, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74,
+ 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72,
+ 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65,
+ 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x50, 0x65, 0x65, 0x72,
+ 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x4D, 0x61, 0x6E, 0x61, 0x67, 0x65, 0x72, 0x3C, 0x2F, 0x6E,
+ 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F,
+ 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72,
+ 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43, 0x6F, 0x6E,
+ 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x4D, 0x61, 0x6E, 0x61, 0x67, 0x65, 0x72, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61,
+ 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09,
+ 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09,
+ 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61,
+ 0x6D, 0x65, 0x3E, 0x50, 0x65, 0x65, 0x72, 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x49, 0x44, 0x3C,
+ 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74,
+ 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D,
+ 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56,
+ 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43,
+ 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64,
+ 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09,
+ 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72,
+ 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+ 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64,
+ 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C,
+ 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F,
+ 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3C, 0x2F,
+ 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
+ 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A,
+ 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+ 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75,
+ 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C,
+ 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74,
+ 0x69, 0x6F, 0x6E, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74,
+ 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x2F,
+ 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75,
+ 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F,
+ 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C,
+ 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6F, 0x74, 0x6F, 0x63, 0x6F, 0x6C, 0x49, 0x6E, 0x66, 0x6F,
+ 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E,
+ 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E,
+ 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x6F, 0x75, 0x72, 0x63,
+ 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65,
+ 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E,
+ 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74,
+ 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x53, 0x6F, 0x75, 0x72, 0x63, 0x65, 0x50, 0x72, 0x6F, 0x74,
+ 0x6F, 0x63, 0x6F, 0x6C, 0x49, 0x6E, 0x66, 0x6F, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61,
+ 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61,
+ 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D,
+ 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x69, 0x6E,
+ 0x6B, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65,
+ 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E,
+ 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74,
+ 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x53, 0x69, 0x6E, 0x6B, 0x50, 0x72, 0x6F, 0x74, 0x6F, 0x63,
+ 0x6F, 0x6C, 0x49, 0x6E, 0x66, 0x6F, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65,
+ 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67,
+ 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E,
+ 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D,
+ 0x0A, 0x09, 0x09, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D,
+ 0x65, 0x3E, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x69,
+ 0x6F, 0x6E, 0x49, 0x44, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72,
+ 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72,
+ 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+ 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x49, 0x44, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+ 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75,
+ 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C,
+ 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x49,
+ 0x44, 0x73, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69,
+ 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E,
+ 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73,
+ 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x3C, 0x2F,
+ 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x3C, 0x73, 0x65, 0x72, 0x76, 0x69,
+ 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74,
+ 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E,
+ 0x74, 0x73, 0x3D, 0x27, 0x6E, 0x6F, 0x27, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D,
+ 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x50, 0x72, 0x6F, 0x74, 0x6F, 0x63, 0x6F,
+ 0x6C, 0x49, 0x6E, 0x66, 0x6F, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20,
+ 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61,
+ 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
+ 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72,
+ 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x27, 0x6E, 0x6F,
+ 0x27, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52,
+ 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x53, 0x74, 0x61,
+ 0x74, 0x75, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64,
+ 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61,
+ 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65,
+ 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x4F, 0x4B, 0x3C,
+ 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E,
+ 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x46, 0x6F, 0x72, 0x6D, 0x61, 0x74, 0x4D, 0x69, 0x73, 0x6D, 0x61, 0x74, 0x63,
+ 0x68, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75,
+ 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x75, 0x66, 0x66, 0x69, 0x63, 0x69, 0x65, 0x6E, 0x74, 0x42, 0x61, 0x6E, 0x64, 0x77, 0x69,
+ 0x64, 0x74, 0x68, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A,
+ 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61,
+ 0x6C, 0x75, 0x65, 0x3E, 0x55, 0x6E, 0x72, 0x65, 0x6C, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x43, 0x68, 0x61, 0x6E, 0x6E, 0x65,
+ 0x6C, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75,
+ 0x65, 0x3E, 0x55, 0x6E, 0x6B, 0x6E, 0x6F, 0x77, 0x6E, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61,
+ 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65,
+ 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61,
+ 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74,
+ 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73,
+ 0x3D, 0x27, 0x6E, 0x6F, 0x27, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+ 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F,
+ 0x72, 0x74, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x69, 0x34, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70,
+ 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C,
+ 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
+ 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x27, 0x6E, 0x6F, 0x27, 0x3E, 0x0D, 0x0A, 0x09,
+ 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50,
+ 0x45, 0x5F, 0x52, 0x63, 0x73, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x69, 0x34, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61,
+ 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69,
+ 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61,
+ 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x27, 0x6E, 0x6F, 0x27, 0x3E,
+ 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F,
+ 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x49, 0x44, 0x3C, 0x2F, 0x6E,
+ 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70,
+ 0x65, 0x3E, 0x69, 0x34, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C,
+ 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C,
+ 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76,
+ 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x27, 0x6E, 0x6F, 0x27, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E,
+ 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43, 0x6F, 0x6E, 0x6E, 0x65,
+ 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x4D, 0x61, 0x6E, 0x61, 0x67, 0x65, 0x72, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D,
+ 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72,
+ 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F,
+ 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73,
+ 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65,
+ 0x6E, 0x74, 0x73, 0x3D, 0x27, 0x79, 0x65, 0x73, 0x27, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E,
+ 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x6F, 0x75, 0x72, 0x63, 0x65, 0x50, 0x72, 0x6F, 0x74, 0x6F, 0x63, 0x6F, 0x6C, 0x49, 0x6E,
+ 0x66, 0x6F, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61,
+ 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54,
+ 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61,
+ 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
+ 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x27, 0x79, 0x65, 0x73, 0x27, 0x3E,
+ 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x69, 0x6E, 0x6B, 0x50, 0x72,
+ 0x6F, 0x74, 0x6F, 0x63, 0x6F, 0x6C, 0x49, 0x6E, 0x66, 0x6F, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09,
+ 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E,
+ 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74,
+ 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61,
+ 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74,
+ 0x73, 0x3D, 0x27, 0x6E, 0x6F, 0x27, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65,
+ 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F,
+ 0x6E, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74,
+ 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79,
+ 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56,
+ 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x49, 0x6E, 0x70, 0x75, 0x74,
+ 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65,
+ 0x3E, 0x4F, 0x75, 0x74, 0x70, 0x75, 0x74, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75,
+ 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56,
+ 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65,
+ 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56,
+ 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x27,
+ 0x79, 0x65, 0x73, 0x27, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43,
+ 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x49, 0x44, 0x73, 0x3C,
+ 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54,
+ 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65,
+ 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
+ 0x3E, 0x0D, 0x0A, 0x09, 0x3C, 0x2F, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x54, 0x61,
+ 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x3C, 0x2F, 0x73, 0x63, 0x70, 0x64, 0x3E, 0x0D, 0x0A, 0x00
+};
+
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/RdrConnectionManagerSCPD.xml b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/RdrConnectionManagerSCPD.xml
new file mode 100644
index 0000000..9545801
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/RdrConnectionManagerSCPD.xml
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="utf-8"?>
+<scpd xmlns='urn:schemas-upnp-org:service-1-0'>
+ <specVersion>
+ <major>1</major>
+ <minor>0</minor>
+ </specVersion>
+ <actionList>
+ <action>
+ <name>GetCurrentConnectionInfo</name>
+ <argumentList>
+ <argument>
+ <name>ConnectionID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_ConnectionID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>RcsID</name>
+ <direction>out</direction>
+ <relatedStateVariable>A_ARG_TYPE_RcsID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>AVTransportID</name>
+ <direction>out</direction>
+ <relatedStateVariable>A_ARG_TYPE_AVTransportID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>ProtocolInfo</name>
+ <direction>out</direction>
+ <relatedStateVariable>A_ARG_TYPE_ProtocolInfo</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>PeerConnectionManager</name>
+ <direction>out</direction>
+ <relatedStateVariable>A_ARG_TYPE_ConnectionManager</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>PeerConnectionID</name>
+ <direction>out</direction>
+ <relatedStateVariable>A_ARG_TYPE_ConnectionID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Direction</name>
+ <direction>out</direction>
+ <relatedStateVariable>A_ARG_TYPE_Direction</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Status</name>
+ <direction>out</direction>
+ <relatedStateVariable>A_ARG_TYPE_ConnectionStatus</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetProtocolInfo</name>
+ <argumentList>
+ <argument>
+ <name>Source</name>
+ <direction>out</direction>
+ <relatedStateVariable>SourceProtocolInfo</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Sink</name>
+ <direction>out</direction>
+ <relatedStateVariable>SinkProtocolInfo</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetCurrentConnectionIDs</name>
+ <argumentList>
+ <argument>
+ <name>ConnectionIDs</name>
+ <direction>out</direction>
+ <relatedStateVariable>CurrentConnectionIDs</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ </actionList>
+ <serviceStateTable>
+ <stateVariable sendEvents='no'>
+ <name>A_ARG_TYPE_ProtocolInfo</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents='no'>
+ <name>A_ARG_TYPE_ConnectionStatus</name>
+ <dataType>string</dataType>
+ <allowedValueList>
+ <allowedValue>OK</allowedValue>
+ <allowedValue>ContentFormatMismatch</allowedValue>
+ <allowedValue>InsufficientBandwidth</allowedValue>
+ <allowedValue>UnreliableChannel</allowedValue>
+ <allowedValue>Unknown</allowedValue>
+ </allowedValueList>
+ </stateVariable>
+ <stateVariable sendEvents='no'>
+ <name>A_ARG_TYPE_AVTransportID</name>
+ <dataType>i4</dataType>
+ </stateVariable>
+ <stateVariable sendEvents='no'>
+ <name>A_ARG_TYPE_RcsID</name>
+ <dataType>i4</dataType>
+ </stateVariable>
+ <stateVariable sendEvents='no'>
+ <name>A_ARG_TYPE_ConnectionID</name>
+ <dataType>i4</dataType>
+ </stateVariable>
+ <stateVariable sendEvents='no'>
+ <name>A_ARG_TYPE_ConnectionManager</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents='yes'>
+ <name>SourceProtocolInfo</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents='yes'>
+ <name>SinkProtocolInfo</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents='no'>
+ <name>A_ARG_TYPE_Direction</name>
+ <dataType>string</dataType>
+ <allowedValueList>
+ <allowedValue>Input</allowedValue>
+ <allowedValue>Output</allowedValue>
+ </allowedValueList>
+ </stateVariable>
+ <stateVariable sendEvents='yes'>
+ <name>CurrentConnectionIDs</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ </serviceStateTable>
+</scpd>
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/RenderingControlSCPD.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/RenderingControlSCPD.cpp
new file mode 100644
index 0000000..a01b1c9
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/RenderingControlSCPD.cpp
@@ -0,0 +1,434 @@
+/*****************************************************************
+|
+| Platinum - RenderingControl SCPD
+|
+| Copyright (c) 2004-2010, Plutinosoft, LLC.
+| All rights reserved.
+| http://www.plutinosoft.com
+|
+| This program is free software; you can redistribute it and/or
+| modify it under the terms of the GNU General Public License
+| as published by the Free Software Foundation; either version 2
+| of the License, or (at your option) any later version.
+|
+| OEMs, ISVs, VARs and other distributors that combine and
+| distribute commercially licensed software with Platinum software
+| and do not wish to distribute the source code for the commercially
+| licensed software under version 2, or (at your option) any later
+| version, of the GNU General Public License (the "GPL") must enter
+| into a commercial license agreement with Plutinosoft, LLC.
+| licensing@plutinosoft.com
+|
+| This program is distributed in the hope that it will be useful,
+| but WITHOUT ANY WARRANTY; without even the implied warranty of
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+| GNU General Public License for more details.
+|
+| You should have received a copy of the GNU General Public License
+| along with this program; see the file LICENSE.txt. If not, write to
+| the Free Software Foundation, Inc.,
+| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+| http://www.gnu.org/licenses/gpl-2.0.html
+|
+****************************************************************/
+
+/*----------------------------------------------------------------------
+| includes
++---------------------------------------------------------------------*/
+#include "Neptune.h"
+
+/*----------------------------------------------------------------------
+| globals
++---------------------------------------------------------------------*/
+NPT_UInt8 RDR_RenderingControlSCPD[7748] =
+{
+ 0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x31, 0x2E, 0x30, 0x22, 0x20,
+ 0x65, 0x6E, 0x63, 0x6F, 0x64, 0x69, 0x6E, 0x67, 0x3D, 0x22, 0x75, 0x74, 0x66, 0x2D, 0x38, 0x22, 0x3F, 0x3E, 0x0D, 0x0A,
+ 0x3C, 0x73, 0x63, 0x70, 0x64, 0x20, 0x78, 0x6D, 0x6C, 0x6E, 0x73, 0x3D, 0x22, 0x75, 0x72, 0x6E, 0x3A, 0x73, 0x63, 0x68,
+ 0x65, 0x6D, 0x61, 0x73, 0x2D, 0x75, 0x70, 0x6E, 0x70, 0x2D, 0x6F, 0x72, 0x67, 0x3A, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
+ 0x65, 0x2D, 0x31, 0x2D, 0x30, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x65, 0x63, 0x56, 0x65, 0x72,
+ 0x73, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6D, 0x61, 0x6A, 0x6F, 0x72, 0x3E,
+ 0x31, 0x3C, 0x2F, 0x6D, 0x61, 0x6A, 0x6F, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6D, 0x69,
+ 0x6E, 0x6F, 0x72, 0x3E, 0x30, 0x3C, 0x2F, 0x6D, 0x69, 0x6E, 0x6F, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x3C, 0x2F,
+ 0x73, 0x70, 0x65, 0x63, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63,
+ 0x74, 0x69, 0x6F, 0x6E, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63,
+ 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D,
+ 0x65, 0x3E, 0x47, 0x65, 0x74, 0x4D, 0x75, 0x74, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74,
+ 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75,
+ 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F,
+ 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72,
+ 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72,
+ 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73,
+ 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74,
+ 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D,
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D,
+ 0x65, 0x3E, 0x43, 0x68, 0x61, 0x6E, 0x6E, 0x65, 0x6C, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74,
+ 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61,
+ 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41,
+ 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43, 0x68, 0x61, 0x6E, 0x6E, 0x65, 0x6C, 0x3C, 0x2F, 0x72, 0x65, 0x6C,
+ 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65,
+ 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72,
+ 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x4D, 0x75, 0x74,
+ 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C,
+ 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74,
+ 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x4D, 0x75, 0x74, 0x65, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61,
+ 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E,
+ 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D,
+ 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63,
+ 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E,
+ 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x47, 0x65,
+ 0x74, 0x56, 0x6F, 0x6C, 0x75, 0x6D, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D,
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65,
+ 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61,
+ 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63,
+ 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61,
+ 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61,
+ 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56,
+ 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+ 0x43, 0x68, 0x61, 0x6E, 0x6E, 0x65, 0x6C, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F,
+ 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65,
+ 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47,
+ 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43, 0x68, 0x61, 0x6E, 0x6E, 0x65, 0x6C, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74,
+ 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74,
+ 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75,
+ 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x56, 0x6F, 0x6C, 0x75, 0x6D,
+ 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C,
+ 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74,
+ 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x56, 0x6F, 0x6C, 0x75, 0x6D, 0x65, 0x3C, 0x2F, 0x72, 0x65,
+ 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D,
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D,
+ 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67,
+ 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F,
+ 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69,
+ 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+ 0x47, 0x65, 0x74, 0x56, 0x6F, 0x6C, 0x75, 0x6D, 0x65, 0x44, 0x42, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69,
+ 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72,
+ 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44,
+ 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64,
+ 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56,
+ 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49,
+ 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74,
+ 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74,
+ 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E,
+ 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x68, 0x61, 0x6E, 0x6E, 0x65, 0x6C, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65,
+ 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E,
+ 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65,
+ 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41,
+ 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43, 0x68, 0x61, 0x6E, 0x6E, 0x65, 0x6C, 0x3C, 0x2F, 0x72,
+ 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E,
+ 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75,
+ 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x56,
+ 0x6F, 0x6C, 0x75, 0x6D, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E,
+ 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64,
+ 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x56, 0x6F, 0x6C, 0x75, 0x6D, 0x65,
+ 0x44, 0x42, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69,
+ 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x47, 0x65, 0x74, 0x56, 0x6F, 0x6C, 0x75, 0x6D, 0x65, 0x44, 0x42, 0x52, 0x61, 0x6E,
+ 0x67, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65,
+ 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65,
+ 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E,
+ 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65,
+ 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41,
+ 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44,
+ 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
+ 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61,
+ 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x68, 0x61, 0x6E, 0x6E,
+ 0x65, 0x6C, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C,
+ 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74,
+ 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45,
+ 0x5F, 0x43, 0x68, 0x61, 0x6E, 0x6E, 0x65, 0x6C, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61,
+ 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E,
+ 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61,
+ 0x6D, 0x65, 0x3E, 0x4D, 0x69, 0x6E, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65,
+ 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E,
+ 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72,
+ 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E,
+ 0x56, 0x6F, 0x6C, 0x75, 0x6D, 0x65, 0x44, 0x42, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61,
+ 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E,
+ 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61,
+ 0x6D, 0x65, 0x3E, 0x4D, 0x61, 0x78, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65,
+ 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E,
+ 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72,
+ 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E,
+ 0x56, 0x6F, 0x6C, 0x75, 0x6D, 0x65, 0x44, 0x42, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61,
+ 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73,
+ 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D,
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4C, 0x69, 0x73, 0x74, 0x50, 0x72, 0x65, 0x73,
+ 0x65, 0x74, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D,
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D,
+ 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D,
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72,
+ 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E,
+ 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72,
+ 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E,
+ 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49,
+ 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61,
+ 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F,
+ 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72,
+ 0x65, 0x6E, 0x74, 0x50, 0x72, 0x65, 0x73, 0x65, 0x74, 0x4E, 0x61, 0x6D, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3C, 0x2F, 0x6E,
+ 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72,
+ 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72,
+ 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x50, 0x72, 0x65, 0x73, 0x65, 0x74, 0x4E, 0x61, 0x6D, 0x65, 0x4C, 0x69, 0x73, 0x74,
+ 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
+ 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61,
+ 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E,
+ 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x50, 0x72, 0x65, 0x73, 0x65, 0x74, 0x3C, 0x2F, 0x6E, 0x61,
+ 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D,
+ 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61,
+ 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E,
+ 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53,
+ 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54,
+ 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61,
+ 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E,
+ 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67,
+ 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x50, 0x72, 0x65, 0x73, 0x65, 0x74, 0x4E, 0x61, 0x6D, 0x65, 0x3C,
+ 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69,
+ 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
+ 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x50, 0x72,
+ 0x65, 0x73, 0x65, 0x74, 0x4E, 0x61, 0x6D, 0x65, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61,
+ 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73,
+ 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D,
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x65, 0x74, 0x4D, 0x75, 0x74, 0x65, 0x3C,
+ 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72,
+ 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E,
+ 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69,
+ 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74,
+ 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52,
+ 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72,
+ 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E,
+ 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75,
+ 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x68, 0x61, 0x6E, 0x6E, 0x65, 0x6C, 0x3C,
+ 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69,
+ 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
+ 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43, 0x68,
+ 0x61, 0x6E, 0x6E, 0x65, 0x6C, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56,
+ 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+ 0x44, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x4D, 0x75, 0x74, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65,
+ 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E,
+ 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65,
+ 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x4D,
+ 0x75, 0x74, 0x65, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72,
+ 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x65, 0x74, 0x56, 0x6F, 0x6C, 0x75, 0x6D, 0x65, 0x3C, 0x2F, 0x6E, 0x61,
+ 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D,
+ 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61,
+ 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E,
+ 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53,
+ 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54,
+ 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61,
+ 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E,
+ 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67,
+ 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x68, 0x61, 0x6E, 0x6E, 0x65, 0x6C, 0x3C, 0x2F, 0x6E, 0x61,
+ 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63,
+ 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61,
+ 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43, 0x68, 0x61, 0x6E, 0x6E,
+ 0x65, 0x6C, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69,
+ 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x44, 0x65, 0x73,
+ 0x69, 0x72, 0x65, 0x64, 0x56, 0x6F, 0x6C, 0x75, 0x6D, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63,
+ 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D,
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C,
+ 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x56, 0x6F,
+ 0x6C, 0x75, 0x6D, 0x65, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
+ 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20,
+ 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x3C, 0x73,
+ 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20,
+ 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x79, 0x65, 0x73, 0x22, 0x3E, 0x0D, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4C, 0x61, 0x73, 0x74, 0x43, 0x68,
+ 0x61, 0x6E, 0x67, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F,
+ 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73,
+ 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64,
+ 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F,
+ 0x43, 0x68, 0x61, 0x6E, 0x6E, 0x65, 0x6C, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E,
+ 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74,
+ 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F,
+ 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x4D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x3C, 0x2F, 0x61, 0x6C, 0x6C,
+ 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E,
+ 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61,
+ 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
+ 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E,
+ 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+ 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49,
+ 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x75, 0x69, 0x34, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79,
+ 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
+ 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74,
+ 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73,
+ 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61,
+ 0x6D, 0x65, 0x3E, 0x56, 0x6F, 0x6C, 0x75, 0x6D, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x75, 0x69, 0x32,
+ 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x52, 0x61, 0x6E, 0x67, 0x65,
+ 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6D, 0x69, 0x6E, 0x69,
+ 0x6D, 0x75, 0x6D, 0x3E, 0x30, 0x3C, 0x2F, 0x6D, 0x69, 0x6E, 0x69, 0x6D, 0x75, 0x6D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6D, 0x61, 0x78, 0x69, 0x6D, 0x75, 0x6D, 0x3E, 0x31, 0x30,
+ 0x30, 0x3C, 0x2F, 0x6D, 0x61, 0x78, 0x69, 0x6D, 0x75, 0x6D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x65, 0x70, 0x3E, 0x31, 0x3C, 0x2F, 0x73, 0x74, 0x65, 0x70, 0x3E, 0x0D,
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56,
+ 0x61, 0x6C, 0x75, 0x65, 0x52, 0x61, 0x6E, 0x67, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F,
+ 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E,
+ 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4D, 0x75, 0x74, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65,
+ 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70,
+ 0x65, 0x3E, 0x62, 0x6F, 0x6F, 0x6C, 0x65, 0x61, 0x6E, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E,
+ 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61,
+ 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
+ 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E,
+ 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+ 0x50, 0x72, 0x65, 0x73, 0x65, 0x74, 0x4E, 0x61, 0x6D, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65,
+ 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70,
+ 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D,
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61,
+ 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x46, 0x61, 0x63, 0x74,
+ 0x6F, 0x72, 0x79, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x73, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64,
+ 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61,
+ 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E,
+ 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
+ 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D,
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52,
+ 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x50, 0x72, 0x65, 0x73, 0x65, 0x74, 0x4E, 0x61, 0x6D, 0x65, 0x3C, 0x2F, 0x6E,
+ 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61,
+ 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70,
+ 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65,
+ 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x46,
+ 0x61, 0x63, 0x74, 0x6F, 0x72, 0x79, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x73, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F,
+ 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D,
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
+ 0x6C, 0x65, 0x3E, 0x20, 0x20, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72,
+ 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F,
+ 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x56,
+ 0x6F, 0x6C, 0x75, 0x6D, 0x65, 0x44, 0x42, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x69, 0x32, 0x3C, 0x2F, 0x64,
+ 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x52, 0x61, 0x6E, 0x67, 0x65, 0x3E, 0x0D, 0x0A,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6D, 0x69, 0x6E, 0x69, 0x6D, 0x75, 0x6D,
+ 0x3E, 0x2D, 0x33, 0x32, 0x37, 0x36, 0x37, 0x3C, 0x2F, 0x6D, 0x69, 0x6E, 0x69, 0x6D, 0x75, 0x6D, 0x3E, 0x0D, 0x0A, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6D, 0x61, 0x78, 0x69, 0x6D, 0x75, 0x6D, 0x3E,
+ 0x33, 0x32, 0x37, 0x36, 0x37, 0x3C, 0x2F, 0x6D, 0x61, 0x78, 0x69, 0x6D, 0x75, 0x6D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65,
+ 0x52, 0x61, 0x6E, 0x67, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74,
+ 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x20, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x3C, 0x2F,
+ 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A,
+ 0x3C, 0x2F, 0x73, 0x63, 0x70, 0x64, 0x3E, 0x00
+};
+
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/RenderingControlSCPD.xml b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/RenderingControlSCPD.xml
new file mode 100644
index 0000000..c5e9d29
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/RenderingControlSCPD.xml
@@ -0,0 +1,216 @@
+<?xml version="1.0" encoding="utf-8"?>
+<scpd xmlns="urn:schemas-upnp-org:service-1-0">
+ <specVersion>
+ <major>1</major>
+ <minor>0</minor>
+ </specVersion>
+ <actionList>
+ <action>
+ <name>GetMute</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Channel</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_Channel</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentMute</name>
+ <direction>out</direction>
+ <relatedStateVariable>Mute</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetVolume</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Channel</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_Channel</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentVolume</name>
+ <direction>out</direction>
+ <relatedStateVariable>Volume</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetVolumeDB</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Channel</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_Channel</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentVolume</name>
+ <direction>out</direction>
+ <relatedStateVariable>VolumeDB</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetVolumeDBRange</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Channel</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_Channel</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>MinValue</name>
+ <direction>out</direction>
+ <relatedStateVariable>VolumeDB</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>MaxValue</name>
+ <direction>out</direction>
+ <relatedStateVariable>VolumeDB</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>ListPresets</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentPresetNameList</name>
+ <direction>out</direction>
+ <relatedStateVariable>PresetNameList</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>SelectPreset</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>PresetName</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_PresetName</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>SetMute</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Channel</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_Channel</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>DesiredMute</name>
+ <direction>in</direction>
+ <relatedStateVariable>Mute</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>SetVolume</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Channel</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_Channel</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>DesiredVolume</name>
+ <direction>in</direction>
+ <relatedStateVariable>Volume</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ </actionList>
+ <serviceStateTable>
+ <stateVariable sendEvents="yes">
+ <name>LastChange</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>A_ARG_TYPE_Channel</name>
+ <dataType>string</dataType>
+ <allowedValueList>
+ <allowedValue>Master</allowedValue>
+ </allowedValueList>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>A_ARG_TYPE_InstanceID</name>
+ <dataType>ui4</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>Volume</name>
+ <dataType>ui2</dataType>
+ <allowedValueRange>
+ <minimum>0</minimum>
+ <maximum>100</maximum>
+ <step>1</step>
+ </allowedValueRange>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>Mute</name>
+ <dataType>boolean</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>PresetNameList</name>
+ <dataType>string</dataType>
+ <allowedValueList>
+ <allowedValue>FactoryDefaults</allowedValue>
+ </allowedValueList>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>A_ARG_TYPE_PresetName</name>
+ <dataType>string</dataType>
+ <allowedValueList>
+ <allowedValue>FactoryDefaults</allowedValue>
+ </allowedValueList>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>VolumeDB</name>
+ <dataType>i2</dataType>
+ <allowedValueRange>
+ <minimum>-32767</minimum>
+ <maximum>32767</maximum>
+ </allowedValueRange>
+ </stateVariable>
+ </serviceStateTable>
+</scpd> \ No newline at end of file
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/RenderingControlSCPD_Full.xml b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/RenderingControlSCPD_Full.xml
new file mode 100644
index 0000000..59af0fd
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/RenderingControlSCPD_Full.xml
@@ -0,0 +1,749 @@
+<?xml version="1.0" encoding="utf-8"?>
+<scpd xmlns="urn:schemas-upnp-org:service-1-0">
+ <specVersion>
+ <major>1</major>
+ <minor>0</minor>
+ </specVersion>
+ <actionList>
+ <action>
+ <name>GetBlueVideoBlackLevel</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentBlueVideoBlackLevel</name>
+ <direction>out</direction>
+ <relatedStateVariable>BlueVideoBlackLevel</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetBlueVideoGain</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentBlueVideoGain</name>
+ <direction>out</direction>
+ <relatedStateVariable>BlueVideoGain</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetBrightness</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentBrightness</name>
+ <direction>out</direction>
+ <relatedStateVariable>Brightness</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetColorTemperature</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentColorTemperature</name>
+ <direction>out</direction>
+ <relatedStateVariable>ColorTemperature</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetContrast</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentContrast</name>
+ <direction>out</direction>
+ <relatedStateVariable>Contrast</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetGreenVideoBlackLevel</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentGreenVideoBlackLevel</name>
+ <direction>out</direction>
+ <relatedStateVariable>GreenVideoBlackLevel</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetGreenVideoGain</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentGreenVideoGain</name>
+ <direction>out</direction>
+ <relatedStateVariable>GreenVideoGain</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetHorizontalKeystone</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentHorizontalKeystone</name>
+ <direction>out</direction>
+ <relatedStateVariable>HorizontalKeystone</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetLoudness</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Channel</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_Channel</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentLoudness</name>
+ <direction>out</direction>
+ <relatedStateVariable>Loudness</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetMute</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Channel</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_Channel</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentMute</name>
+ <direction>out</direction>
+ <relatedStateVariable>Mute</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetRedVideoBlackLevel</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentRedVideoBlackLevel</name>
+ <direction>out</direction>
+ <relatedStateVariable>RedVideoBlackLevel</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetRedVideoGain</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentRedVideoGain</name>
+ <direction>out</direction>
+ <relatedStateVariable>RedVideoGain</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetSharpness</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentSharpness</name>
+ <direction>out</direction>
+ <relatedStateVariable>Sharpness</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetVerticalKeystone</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentVerticalKeystone</name>
+ <direction>out</direction>
+ <relatedStateVariable>VerticalKeystone</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetVolume</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Channel</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_Channel</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentVolume</name>
+ <direction>out</direction>
+ <relatedStateVariable>Volume</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetVolumeDB</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Channel</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_Channel</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentVolume</name>
+ <direction>out</direction>
+ <relatedStateVariable>VolumeDB</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetVolumeDBRange</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Channel</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_Channel</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>MinValue</name>
+ <direction>out</direction>
+ <relatedStateVariable>VolumeDB</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>MaxValue</name>
+ <direction>out</direction>
+ <relatedStateVariable>VolumeDB</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>ListPresets</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentPresetNameList</name>
+ <direction>out</direction>
+ <relatedStateVariable>PresetNameList</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>SelectPreset</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>PresetName</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_PresetName</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>SetBlueVideoBlackLevel</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>DesiredBlueVideoBlackLevel</name>
+ <direction>in</direction>
+ <relatedStateVariable>BlueVideoBlackLevel</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>SetBlueVideoGain</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>DesiredBlueVideoGain</name>
+ <direction>in</direction>
+ <relatedStateVariable>BlueVideoGain</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>SetBrightness</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>DesiredBrightness</name>
+ <direction>in</direction>
+ <relatedStateVariable>Brightness</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>SetColorTemperature</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>DesiredColorTemperature</name>
+ <direction>in</direction>
+ <relatedStateVariable>ColorTemperature</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>SetContrast</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>DesiredContrast</name>
+ <direction>in</direction>
+ <relatedStateVariable>Contrast</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>SetGreenVideoBlackLevel</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>DesiredGreenVideoBlackLevel</name>
+ <direction>in</direction>
+ <relatedStateVariable>GreenVideoBlackLevel</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>SetGreenVideoGain</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>DesiredGreenVideoGain</name>
+ <direction>in</direction>
+ <relatedStateVariable>GreenVideoGain</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>SetHorizontalKeystone</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>DesiredHorizontalKeystone</name>
+ <direction>in</direction>
+ <relatedStateVariable>HorizontalKeystone</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>SetLoudness</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Channel</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_Channel</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>DesiredLoudness</name>
+ <direction>in</direction>
+ <relatedStateVariable>Loudness</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>SetMute</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Channel</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_Channel</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>DesiredMute</name>
+ <direction>in</direction>
+ <relatedStateVariable>Mute</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>SetRedVideoBlackLevel</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>DesiredRedVideoBlackLevel</name>
+ <direction>in</direction>
+ <relatedStateVariable>RedVideoBlackLevel</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>SetRedVideoGain</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>DesiredRedVideoGain</name>
+ <direction>in</direction>
+ <relatedStateVariable>RedVideoGain</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>SetSharpness</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>DesiredSharpness</name>
+ <direction>in</direction>
+ <relatedStateVariable>Sharpness</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>SetVerticalKeystone</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>DesiredVerticalKeystone</name>
+ <direction>in</direction>
+ <relatedStateVariable>VerticalKeystone</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>SetVolume</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Channel</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_Channel</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>DesiredVolume</name>
+ <direction>in</direction>
+ <relatedStateVariable>Volume</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>SetVolumeDB</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Channel</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_Channel</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>DesiredVolume</name>
+ <direction>in</direction>
+ <relatedStateVariable>VolumeDB</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ </actionList>
+ <serviceStateTable>
+ <stateVariable sendEvents="no">
+ <name>VerticalKeystone</name>
+ <dataType>i2</dataType>
+ <allowedValueRange>
+ <minimum>-32768</minimum>
+ <maximum>32767</maximum>
+ <step>1</step>
+ </allowedValueRange>
+ </stateVariable>
+ <stateVariable sendEvents="yes">
+ <name>LastChange</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>A_ARG_TYPE_Channel</name>
+ <dataType>string</dataType>
+ <allowedValueList>
+ <allowedValue>Master</allowedValue>
+ <allowedValue>LF</allowedValue>
+ <allowedValue>RF</allowedValue>
+ </allowedValueList>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>Loudness</name>
+ <dataType>boolean</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>HorizontalKeystone</name>
+ <dataType>i2</dataType>
+ <allowedValueRange>
+ <minimum>-32768</minimum>
+ <maximum>32767</maximum>
+ <step>1</step>
+ </allowedValueRange>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>A_ARG_TYPE_InstanceID</name>
+ <dataType>ui4</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>BlueVideoBlackLevel</name>
+ <dataType>ui2</dataType>
+ <allowedValueRange>
+ <minimum>0</minimum>
+ <maximum>100</maximum>
+ <step>1</step>
+ </allowedValueRange>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>RedVideoGain</name>
+ <dataType>ui2</dataType>
+ <allowedValueRange>
+ <minimum>0</minimum>
+ <maximum>100</maximum>
+ <step>1</step>
+ </allowedValueRange>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>GreenVideoBlackLevel</name>
+ <dataType>ui2</dataType>
+ <allowedValueRange>
+ <minimum>0</minimum>
+ <maximum>100</maximum>
+ <step>1</step>
+ </allowedValueRange>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>Volume</name>
+ <dataType>ui2</dataType>
+ <allowedValueRange>
+ <minimum>0</minimum>
+ <maximum>100</maximum>
+ <step>1</step>
+ </allowedValueRange>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>Mute</name>
+ <dataType>boolean</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>Brightness</name>
+ <dataType>ui2</dataType>
+ <allowedValueRange>
+ <minimum>0</minimum>
+ <maximum>100</maximum>
+ <step>1</step>
+ </allowedValueRange>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>PresetNameList</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>A_ARG_TYPE_PresetName</name>
+ <dataType>string</dataType>
+ <allowedValueList>
+ <allowedValue>FactoryDefaults</allowedValue>
+ <allowedValue>InstallationDefaults</allowedValue>
+ <allowedValue>Vendor defined</allowedValue>
+ </allowedValueList>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>ColorTemperature</name>
+ <dataType>ui2</dataType>
+ <allowedValueRange>
+ <minimum>0</minimum>
+ <maximum>65535</maximum>
+ <step>1</step>
+ </allowedValueRange>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>VolumeDB</name>
+ <dataType>i2</dataType>
+ <allowedValueRange>
+ <minimum>-32768</minimum>
+ <maximum>32767</maximum>
+ </allowedValueRange>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>Contrast</name>
+ <dataType>ui2</dataType>
+ <allowedValueRange>
+ <minimum>0</minimum>
+ <maximum>100</maximum>
+ <step>1</step>
+ </allowedValueRange>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>GreenVideoGain</name>
+ <dataType>ui2</dataType>
+ <allowedValueRange>
+ <minimum>0</minimum>
+ <maximum>100</maximum>
+ <step>1</step>
+ </allowedValueRange>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>RedVideoBlackLevel</name>
+ <dataType>ui2</dataType>
+ <allowedValueRange>
+ <minimum>0</minimum>
+ <maximum>100</maximum>
+ <step>1</step>
+ </allowedValueRange>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>BlueVideoGain</name>
+ <dataType>ui2</dataType>
+ <allowedValueRange>
+ <minimum>0</minimum>
+ <maximum>100</maximum>
+ <step>1</step>
+ </allowedValueRange>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>Sharpness</name>
+ <dataType>ui2</dataType>
+ <allowedValueRange>
+ <minimum>0</minimum>
+ <maximum>100</maximum>
+ <step>1</step>
+ </allowedValueRange>
+ </stateVariable>
+ </serviceStateTable>
+</scpd> \ No newline at end of file
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/process_scpds.sh b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/process_scpds.sh
new file mode 100644
index 0000000..07d5056
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/process_scpds.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+set -x
+
+# abort on any errors
+set -e
+
+# AVTransport
+../../../Targets/x86-unknown-cygwin/Debug/TextToHeader.exe -v RDR_AVTransportSCPD -h AVTransport AVTransportSCPD.xml AVTransportSCPD.cpp
+
+# Rendering Control
+../../../Targets/x86-unknown-cygwin/Debug/TextToHeader.exe -v RDR_RenderingControlSCPD -h RenderingControl RenderingControlSCPD.xml RenderingControlSCPD.cpp
+
+# ConnectionManager
+../../../Targets/x86-unknown-cygwin/Debug/TextToHeader.exe -v RDR_ConnectionManagerSCPD -h ConnectionManager ConnectionManagerSCPD.xml RdrConnectionManagerSCPD.cpp \ No newline at end of file
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/ConnectionManagerSCPD.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaServer/ConnectionManagerSCPD.cpp
new file mode 100644
index 0000000..973b3b1
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/ConnectionManagerSCPD.cpp
@@ -0,0 +1,262 @@
+/*****************************************************************
+|
+| Platinum - ConnectionManager SCPD
+|
+| Copyright (c) 2004-2010, Plutinosoft, LLC.
+| All rights reserved.
+| http://www.plutinosoft.com
+|
+| This program is free software; you can redistribute it and/or
+| modify it under the terms of the GNU General Public License
+| as published by the Free Software Foundation; either version 2
+| of the License, or (at your option) any later version.
+|
+| OEMs, ISVs, VARs and other distributors that combine and
+| distribute commercially licensed software with Platinum software
+| and do not wish to distribute the source code for the commercially
+| licensed software under version 2, or (at your option) any later
+| version, of the GNU General Public License (the "GPL") must enter
+| into a commercial license agreement with Plutinosoft, LLC.
+| licensing@plutinosoft.com
+|
+| This program is distributed in the hope that it will be useful,
+| but WITHOUT ANY WARRANTY; without even the implied warranty of
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+| GNU General Public License for more details.
+|
+| You should have received a copy of the GNU General Public License
+| along with this program; see the file LICENSE.txt. If not, write to
+| the Free Software Foundation, Inc.,
+| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+| http://www.gnu.org/licenses/gpl-2.0.html
+|
+****************************************************************/
+
+/** @file
+ UPnP Service SCPD for urn:schemas-upnp-org:service:ConnectionManager:1
+ */
+
+/*----------------------------------------------------------------------
+| includes
++---------------------------------------------------------------------*/
+#include "Neptune.h"
+
+/*----------------------------------------------------------------------
+| globals
++---------------------------------------------------------------------*/
+NPT_UInt8 MS_ConnectionManagerSCPD[4216] =
+{
+ 0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x31, 0x2E, 0x30, 0x22, 0x20,
+ 0x65, 0x6E, 0x63, 0x6F, 0x64, 0x69, 0x6E, 0x67, 0x3D, 0x22, 0x75, 0x74, 0x66, 0x2D, 0x38, 0x22, 0x3F, 0x3E, 0x0D, 0x0A,
+ 0x3C, 0x73, 0x63, 0x70, 0x64, 0x20, 0x78, 0x6D, 0x6C, 0x6E, 0x73, 0x3D, 0x27, 0x75, 0x72, 0x6E, 0x3A, 0x73, 0x63, 0x68,
+ 0x65, 0x6D, 0x61, 0x73, 0x2D, 0x75, 0x70, 0x6E, 0x70, 0x2D, 0x6F, 0x72, 0x67, 0x3A, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
+ 0x65, 0x2D, 0x31, 0x2D, 0x30, 0x27, 0x3E, 0x0D, 0x0A, 0x09, 0x3C, 0x73, 0x70, 0x65, 0x63, 0x56, 0x65, 0x72, 0x73, 0x69,
+ 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x6D, 0x61, 0x6A, 0x6F, 0x72, 0x3E, 0x31, 0x3C, 0x2F, 0x6D, 0x61, 0x6A,
+ 0x6F, 0x72, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x6D, 0x69, 0x6E, 0x6F, 0x72, 0x3E, 0x30, 0x3C, 0x2F, 0x6D, 0x69, 0x6E,
+ 0x6F, 0x72, 0x3E, 0x0D, 0x0A, 0x09, 0x3C, 0x2F, 0x73, 0x70, 0x65, 0x63, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3E,
+ 0x0D, 0x0A, 0x09, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C,
+ 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x47, 0x65,
+ 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x49, 0x6E,
+ 0x66, 0x6F, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D,
+ 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D,
+ 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x6F, 0x6E,
+ 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69,
+ 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61,
+ 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41,
+ 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x49, 0x44,
+ 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
+ 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E,
+ 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 0x63, 0x73, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65,
+ 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F,
+ 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
+ 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x52, 0x63, 0x73, 0x49, 0x44, 0x3C,
+ 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C,
+ 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D,
+ 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x49,
+ 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65,
+ 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E,
+ 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74,
+ 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45,
+ 0x5F, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61,
+ 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09,
+ 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09,
+ 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61,
+ 0x6D, 0x65, 0x3E, 0x50, 0x72, 0x6F, 0x74, 0x6F, 0x63, 0x6F, 0x6C, 0x49, 0x6E, 0x66, 0x6F, 0x3C, 0x2F, 0x6E, 0x61, 0x6D,
+ 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E,
+ 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61,
+ 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x50, 0x72, 0x6F, 0x74, 0x6F,
+ 0x63, 0x6F, 0x6C, 0x49, 0x6E, 0x66, 0x6F, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74,
+ 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72,
+ 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65,
+ 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x50, 0x65, 0x65, 0x72,
+ 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x4D, 0x61, 0x6E, 0x61, 0x67, 0x65, 0x72, 0x3C, 0x2F, 0x6E,
+ 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F,
+ 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72,
+ 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43, 0x6F, 0x6E,
+ 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x4D, 0x61, 0x6E, 0x61, 0x67, 0x65, 0x72, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61,
+ 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09,
+ 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09,
+ 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61,
+ 0x6D, 0x65, 0x3E, 0x50, 0x65, 0x65, 0x72, 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x49, 0x44, 0x3C,
+ 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74,
+ 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D,
+ 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56,
+ 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43,
+ 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64,
+ 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09,
+ 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72,
+ 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+ 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64,
+ 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C,
+ 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F,
+ 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3C, 0x2F,
+ 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
+ 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A,
+ 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+ 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75,
+ 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C,
+ 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74,
+ 0x69, 0x6F, 0x6E, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74,
+ 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x2F,
+ 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75,
+ 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F,
+ 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C,
+ 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6F, 0x74, 0x6F, 0x63, 0x6F, 0x6C, 0x49, 0x6E, 0x66, 0x6F,
+ 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E,
+ 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E,
+ 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x6F, 0x75, 0x72, 0x63,
+ 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65,
+ 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E,
+ 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74,
+ 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x53, 0x6F, 0x75, 0x72, 0x63, 0x65, 0x50, 0x72, 0x6F, 0x74,
+ 0x6F, 0x63, 0x6F, 0x6C, 0x49, 0x6E, 0x66, 0x6F, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61,
+ 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61,
+ 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D,
+ 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x69, 0x6E,
+ 0x6B, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65,
+ 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E,
+ 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74,
+ 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x53, 0x69, 0x6E, 0x6B, 0x50, 0x72, 0x6F, 0x74, 0x6F, 0x63,
+ 0x6F, 0x6C, 0x49, 0x6E, 0x66, 0x6F, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65,
+ 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67,
+ 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E,
+ 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D,
+ 0x0A, 0x09, 0x09, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D,
+ 0x65, 0x3E, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x69,
+ 0x6F, 0x6E, 0x49, 0x44, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72,
+ 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72,
+ 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+ 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x49, 0x44, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+ 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75,
+ 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C,
+ 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x49,
+ 0x44, 0x73, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69,
+ 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E,
+ 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73,
+ 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x3C, 0x2F,
+ 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x3C, 0x73, 0x65, 0x72, 0x76, 0x69,
+ 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74,
+ 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E,
+ 0x74, 0x73, 0x3D, 0x27, 0x6E, 0x6F, 0x27, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D,
+ 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x50, 0x72, 0x6F, 0x74, 0x6F, 0x63, 0x6F,
+ 0x6C, 0x49, 0x6E, 0x66, 0x6F, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20,
+ 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61,
+ 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
+ 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72,
+ 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x27, 0x6E, 0x6F,
+ 0x27, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52,
+ 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x53, 0x74, 0x61,
+ 0x74, 0x75, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64,
+ 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61,
+ 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65,
+ 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x4F, 0x4B, 0x3C,
+ 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E,
+ 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x46, 0x6F, 0x72, 0x6D, 0x61, 0x74, 0x4D, 0x69, 0x73, 0x6D, 0x61, 0x74, 0x63,
+ 0x68, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75,
+ 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x75, 0x66, 0x66, 0x69, 0x63, 0x69, 0x65, 0x6E, 0x74, 0x42, 0x61, 0x6E, 0x64, 0x77, 0x69,
+ 0x64, 0x74, 0x68, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A,
+ 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61,
+ 0x6C, 0x75, 0x65, 0x3E, 0x55, 0x6E, 0x72, 0x65, 0x6C, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x43, 0x68, 0x61, 0x6E, 0x6E, 0x65,
+ 0x6C, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75,
+ 0x65, 0x3E, 0x55, 0x6E, 0x6B, 0x6E, 0x6F, 0x77, 0x6E, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61,
+ 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65,
+ 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61,
+ 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74,
+ 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73,
+ 0x3D, 0x27, 0x6E, 0x6F, 0x27, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+ 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F,
+ 0x72, 0x74, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C,
+ 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x69, 0x34, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70,
+ 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C,
+ 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
+ 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x27, 0x6E, 0x6F, 0x27, 0x3E, 0x0D, 0x0A, 0x09,
+ 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50,
+ 0x45, 0x5F, 0x52, 0x63, 0x73, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20,
+ 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x69, 0x34, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61,
+ 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69,
+ 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61,
+ 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x27, 0x6E, 0x6F, 0x27, 0x3E,
+ 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F,
+ 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x49, 0x44, 0x3C, 0x2F, 0x6E,
+ 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70,
+ 0x65, 0x3E, 0x69, 0x34, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C,
+ 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C,
+ 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76,
+ 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x27, 0x6E, 0x6F, 0x27, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E,
+ 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43, 0x6F, 0x6E, 0x6E, 0x65,
+ 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x4D, 0x61, 0x6E, 0x61, 0x67, 0x65, 0x72, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D,
+ 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72,
+ 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F,
+ 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73,
+ 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65,
+ 0x6E, 0x74, 0x73, 0x3D, 0x27, 0x79, 0x65, 0x73, 0x27, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E,
+ 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x6F, 0x75, 0x72, 0x63, 0x65, 0x50, 0x72, 0x6F, 0x74, 0x6F, 0x63, 0x6F, 0x6C, 0x49, 0x6E,
+ 0x66, 0x6F, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61,
+ 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54,
+ 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61,
+ 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
+ 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x27, 0x79, 0x65, 0x73, 0x27, 0x3E,
+ 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x69, 0x6E, 0x6B, 0x50, 0x72,
+ 0x6F, 0x74, 0x6F, 0x63, 0x6F, 0x6C, 0x49, 0x6E, 0x66, 0x6F, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09,
+ 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E,
+ 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74,
+ 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61,
+ 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74,
+ 0x73, 0x3D, 0x27, 0x6E, 0x6F, 0x27, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65,
+ 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F,
+ 0x6E, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74,
+ 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79,
+ 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56,
+ 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x49, 0x6E, 0x70, 0x75, 0x74,
+ 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65,
+ 0x3E, 0x4F, 0x75, 0x74, 0x70, 0x75, 0x74, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75,
+ 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56,
+ 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65,
+ 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56,
+ 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x27,
+ 0x79, 0x65, 0x73, 0x27, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43,
+ 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x49, 0x44, 0x73, 0x3C,
+ 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54,
+ 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65,
+ 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
+ 0x3E, 0x0D, 0x0A, 0x09, 0x3C, 0x2F, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x54, 0x61,
+ 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x3C, 0x2F, 0x73, 0x63, 0x70, 0x64, 0x3E, 0x0D, 0x0A, 0x00
+};
+
+/** @} */
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/ConnectionManagerSCPD.xml b/lib/libUPnP/Platinum/Source/Devices/MediaServer/ConnectionManagerSCPD.xml
new file mode 100644
index 0000000..9545801
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/ConnectionManagerSCPD.xml
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="utf-8"?>
+<scpd xmlns='urn:schemas-upnp-org:service-1-0'>
+ <specVersion>
+ <major>1</major>
+ <minor>0</minor>
+ </specVersion>
+ <actionList>
+ <action>
+ <name>GetCurrentConnectionInfo</name>
+ <argumentList>
+ <argument>
+ <name>ConnectionID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_ConnectionID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>RcsID</name>
+ <direction>out</direction>
+ <relatedStateVariable>A_ARG_TYPE_RcsID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>AVTransportID</name>
+ <direction>out</direction>
+ <relatedStateVariable>A_ARG_TYPE_AVTransportID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>ProtocolInfo</name>
+ <direction>out</direction>
+ <relatedStateVariable>A_ARG_TYPE_ProtocolInfo</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>PeerConnectionManager</name>
+ <direction>out</direction>
+ <relatedStateVariable>A_ARG_TYPE_ConnectionManager</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>PeerConnectionID</name>
+ <direction>out</direction>
+ <relatedStateVariable>A_ARG_TYPE_ConnectionID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Direction</name>
+ <direction>out</direction>
+ <relatedStateVariable>A_ARG_TYPE_Direction</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Status</name>
+ <direction>out</direction>
+ <relatedStateVariable>A_ARG_TYPE_ConnectionStatus</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetProtocolInfo</name>
+ <argumentList>
+ <argument>
+ <name>Source</name>
+ <direction>out</direction>
+ <relatedStateVariable>SourceProtocolInfo</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Sink</name>
+ <direction>out</direction>
+ <relatedStateVariable>SinkProtocolInfo</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetCurrentConnectionIDs</name>
+ <argumentList>
+ <argument>
+ <name>ConnectionIDs</name>
+ <direction>out</direction>
+ <relatedStateVariable>CurrentConnectionIDs</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ </actionList>
+ <serviceStateTable>
+ <stateVariable sendEvents='no'>
+ <name>A_ARG_TYPE_ProtocolInfo</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents='no'>
+ <name>A_ARG_TYPE_ConnectionStatus</name>
+ <dataType>string</dataType>
+ <allowedValueList>
+ <allowedValue>OK</allowedValue>
+ <allowedValue>ContentFormatMismatch</allowedValue>
+ <allowedValue>InsufficientBandwidth</allowedValue>
+ <allowedValue>UnreliableChannel</allowedValue>
+ <allowedValue>Unknown</allowedValue>
+ </allowedValueList>
+ </stateVariable>
+ <stateVariable sendEvents='no'>
+ <name>A_ARG_TYPE_AVTransportID</name>
+ <dataType>i4</dataType>
+ </stateVariable>
+ <stateVariable sendEvents='no'>
+ <name>A_ARG_TYPE_RcsID</name>
+ <dataType>i4</dataType>
+ </stateVariable>
+ <stateVariable sendEvents='no'>
+ <name>A_ARG_TYPE_ConnectionID</name>
+ <dataType>i4</dataType>
+ </stateVariable>
+ <stateVariable sendEvents='no'>
+ <name>A_ARG_TYPE_ConnectionManager</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents='yes'>
+ <name>SourceProtocolInfo</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents='yes'>
+ <name>SinkProtocolInfo</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents='no'>
+ <name>A_ARG_TYPE_Direction</name>
+ <dataType>string</dataType>
+ <allowedValueList>
+ <allowedValue>Input</allowedValue>
+ <allowedValue>Output</allowedValue>
+ </allowedValueList>
+ </stateVariable>
+ <stateVariable sendEvents='yes'>
+ <name>CurrentConnectionIDs</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ </serviceStateTable>
+</scpd>
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/ContentDirectorySCPD.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaServer/ContentDirectorySCPD.cpp
new file mode 100644
index 0000000..03f0924
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/ContentDirectorySCPD.cpp
@@ -0,0 +1,267 @@
+/*****************************************************************
+|
+| Platinum - ContentDirectory SCPD
+|
+| Copyright (c) 2004-2008, Plutinosoft, LLC.
+| All rights reserved.
+| http://www.plutinosoft.com
+|
+| This program is free software; you can redistribute it and/or
+| modify it under the terms of the GNU General Public License
+| as published by the Free Software Foundation; either version 2
+| of the License, or (at your option) any later version.
+|
+| OEMs, ISVs, VARs and other distributors that combine and
+| distribute commercially licensed software with Platinum software
+| and do not wish to distribute the source code for the commercially
+| licensed software under version 2, or (at your option) any later
+| version, of the GNU General Public License (the "GPL") must enter
+| into a commercial license agreement with Plutinosoft, LLC.
+| licensing@plutinosoft.com
+|
+| This program is distributed in the hope that it will be useful,
+| but WITHOUT ANY WARRANTY; without even the implied warranty of
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+| GNU General Public License for more details.
+|
+| You should have received a copy of the GNU General Public License
+| along with this program; see the file LICENSE.txt. If not, write to
+| the Free Software Foundation, Inc.,
+| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+| http://www.gnu.org/licenses/gpl-2.0.html
+|
+****************************************************************/
+
+/*----------------------------------------------------------------------
+| includes
++---------------------------------------------------------------------*/
+#include "Neptune.h"
+
+/*----------------------------------------------------------------------
+| globals
++---------------------------------------------------------------------*/
+NPT_UInt8 MS_ContentDirectorySCPD[4409] =
+{
+ 0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x31, 0x2E, 0x30, 0x22, 0x20,
+ 0x65, 0x6E, 0x63, 0x6F, 0x64, 0x69, 0x6E, 0x67, 0x3D, 0x22, 0x75, 0x74, 0x66, 0x2D, 0x38, 0x22, 0x3F, 0x3E, 0x0D, 0x0A,
+ 0x3C, 0x73, 0x63, 0x70, 0x64, 0x20, 0x78, 0x6D, 0x6C, 0x6E, 0x73, 0x3D, 0x22, 0x75, 0x72, 0x6E, 0x3A, 0x73, 0x63, 0x68,
+ 0x65, 0x6D, 0x61, 0x73, 0x2D, 0x75, 0x70, 0x6E, 0x70, 0x2D, 0x6F, 0x72, 0x67, 0x3A, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
+ 0x65, 0x2D, 0x31, 0x2D, 0x30, 0x22, 0x3E, 0x0D, 0x0A, 0x09, 0x3C, 0x73, 0x70, 0x65, 0x63, 0x56, 0x65, 0x72, 0x73, 0x69,
+ 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x6D, 0x61, 0x6A, 0x6F, 0x72, 0x3E, 0x31, 0x3C, 0x2F, 0x6D, 0x61, 0x6A,
+ 0x6F, 0x72, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x6D, 0x69, 0x6E, 0x6F, 0x72, 0x3E, 0x30, 0x3C, 0x2F, 0x6D, 0x69,
+ 0x6E, 0x6F, 0x72, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x3C, 0x2F, 0x73, 0x70, 0x65, 0x63, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F,
+ 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09,
+ 0x09, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x42,
+ 0x72, 0x6F, 0x77, 0x73, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x61, 0x72,
+ 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67,
+ 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4F, 0x62,
+ 0x6A, 0x65, 0x63, 0x74, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09,
+ 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63,
+ 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64,
+ 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F,
+ 0x54, 0x59, 0x50, 0x45, 0x5F, 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74,
+ 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09,
+ 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61,
+ 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+ 0x42, 0x72, 0x6F, 0x77, 0x73, 0x65, 0x46, 0x6C, 0x61, 0x67, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A,
+ 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64,
+ 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C,
+ 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F,
+ 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x42, 0x72, 0x6F, 0x77, 0x73, 0x65, 0x46, 0x6C, 0x61, 0x67, 0x3C,
+ 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C,
+ 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D,
+ 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09,
+ 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x46, 0x69, 0x6C, 0x74, 0x65, 0x72, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20,
+ 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C,
+ 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72,
+ 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E,
+ 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x46, 0x69, 0x6C, 0x74, 0x65, 0x72, 0x3C, 0x2F, 0x72,
+ 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E,
+ 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09,
+ 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E,
+ 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x74, 0x61, 0x72, 0x74, 0x69, 0x6E, 0x67, 0x49, 0x6E, 0x64, 0x65, 0x78, 0x3C, 0x2F, 0x6E,
+ 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F,
+ 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0D, 0x0A, 0x09,
+ 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69,
+ 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x64, 0x65,
+ 0x78, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61,
+ 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74,
+ 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09,
+ 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x43, 0x6F, 0x75,
+ 0x6E, 0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72,
+ 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E,
+ 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74,
+ 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45,
+ 0x5F, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65,
+ 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67,
+ 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74,
+ 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x6F, 0x72, 0x74, 0x43, 0x72, 0x69,
+ 0x74, 0x65, 0x72, 0x69, 0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C,
+ 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74,
+ 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53,
+ 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54,
+ 0x59, 0x50, 0x45, 0x5F, 0x53, 0x6F, 0x72, 0x74, 0x43, 0x72, 0x69, 0x74, 0x65, 0x72, 0x69, 0x61, 0x3C, 0x2F, 0x72, 0x65,
+ 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20,
+ 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09,
+ 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61,
+ 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x73, 0x75, 0x6C, 0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09,
+ 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64,
+ 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C,
+ 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F,
+ 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x52, 0x65, 0x73, 0x75, 0x6C, 0x74, 0x3C, 0x2F, 0x72, 0x65, 0x6C,
+ 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0D,
+ 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09,
+ 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D,
+ 0x65, 0x3E, 0x4E, 0x75, 0x6D, 0x62, 0x65, 0x72, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x65, 0x64, 0x3C, 0x2F, 0x6E, 0x61,
+ 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E,
+ 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0D, 0x0A, 0x09,
+ 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69,
+ 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43, 0x6F, 0x75, 0x6E,
+ 0x74, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61,
+ 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74,
+ 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09,
+ 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x54, 0x6F, 0x74, 0x61, 0x6C, 0x4D, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73,
+ 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63,
+ 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E,
+ 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65,
+ 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F,
+ 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56,
+ 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75,
+ 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E,
+ 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x44,
+ 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63,
+ 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E,
+ 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65,
+ 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F,
+ 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61,
+ 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61,
+ 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65,
+ 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E,
+ 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61,
+ 0x6D, 0x65, 0x3E, 0x47, 0x65, 0x74, 0x53, 0x6F, 0x72, 0x74, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6C, 0x69, 0x74, 0x69,
+ 0x65, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75,
+ 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75,
+ 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x6F,
+ 0x72, 0x74, 0x43, 0x61, 0x70, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72,
+ 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61,
+ 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x53, 0x6F, 0x72,
+ 0x74, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6C, 0x69, 0x74, 0x69, 0x65, 0x73, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74,
+ 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09,
+ 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C,
+ 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F,
+ 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D,
+ 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x47, 0x65, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x55,
+ 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09,
+ 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09,
+ 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61,
+ 0x6D, 0x65, 0x3E, 0x49, 0x64, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65,
+ 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74,
+ 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x53, 0x79, 0x73, 0x74,
+ 0x65, 0x6D, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53,
+ 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09,
+ 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72,
+ 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x63, 0x74,
+ 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09,
+ 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x47, 0x65, 0x74, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x43, 0x61, 0x70, 0x61,
+ 0x62, 0x69, 0x6C, 0x69, 0x74, 0x69, 0x65, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09,
+ 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09,
+ 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E,
+ 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x43, 0x61, 0x70, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65,
+ 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E,
+ 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69,
+ 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6C, 0x69, 0x74,
+ 0x69, 0x65, 0x73, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72,
+ 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D,
+ 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C,
+ 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09,
+ 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x3C, 0x73, 0x65, 0x72,
+ 0x76, 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C,
+ 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76,
+ 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65,
+ 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x42, 0x72, 0x6F, 0x77, 0x73, 0x65, 0x46, 0x6C,
+ 0x61, 0x67, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61,
+ 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70,
+ 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75,
+ 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64,
+ 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x42, 0x72, 0x6F, 0x77, 0x73, 0x65, 0x4D, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
+ 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09,
+ 0x09, 0x09, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x42, 0x72, 0x6F, 0x77,
+ 0x73, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x43, 0x68, 0x69, 0x6C, 0x64, 0x72, 0x65, 0x6E, 0x3C, 0x2F, 0x61, 0x6C,
+ 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61,
+ 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09,
+ 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09,
+ 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45,
+ 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x79, 0x65, 0x73, 0x22, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61,
+ 0x6D, 0x65, 0x3E, 0x43, 0x6F, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x44,
+ 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54,
+ 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65,
+ 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C,
+ 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
+ 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x79, 0x65, 0x73, 0x22, 0x3E, 0x0D, 0x0A,
+ 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x55, 0x70, 0x64, 0x61, 0x74,
+ 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74,
+ 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x75, 0x69, 0x34, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E,
+ 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
+ 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20,
+ 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x09, 0x09,
+ 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43, 0x6F,
+ 0x75, 0x6E, 0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74,
+ 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x75, 0x69, 0x34, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E,
+ 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
+ 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20,
+ 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x09, 0x09,
+ 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x53, 0x6F,
+ 0x72, 0x74, 0x43, 0x72, 0x69, 0x74, 0x65, 0x72, 0x69, 0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A,
+ 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C,
+ 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61,
+ 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74,
+ 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73,
+ 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x6F, 0x72,
+ 0x74, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6C, 0x69, 0x74, 0x69, 0x65, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+ 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69,
+ 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F,
+ 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73,
+ 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65,
+ 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+ 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x64, 0x65, 0x78, 0x3C, 0x2F, 0x6E, 0x61,
+ 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x75,
+ 0x69, 0x34, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F,
+ 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73,
+ 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65,
+ 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+ 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x49, 0x44, 0x3C,
+ 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70,
+ 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x20,
+ 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E,
+ 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73,
+ 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09,
+ 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x55, 0x70, 0x64,
+ 0x61, 0x74, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64,
+ 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x75, 0x69, 0x34, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70,
+ 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
+ 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C,
+ 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A,
+ 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F,
+ 0x52, 0x65, 0x73, 0x75, 0x6C, 0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C,
+ 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74,
+ 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
+ 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72,
+ 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F,
+ 0x22, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x43,
+ 0x61, 0x70, 0x61, 0x62, 0x69, 0x6C, 0x69, 0x74, 0x69, 0x65, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D,
+ 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67,
+ 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74,
+ 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61,
+ 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74,
+ 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F,
+ 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x46, 0x69, 0x6C, 0x74, 0x65, 0x72, 0x3C, 0x2F, 0x6E, 0x61, 0x6D,
+ 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74,
+ 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09,
+ 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x3C,
+ 0x2F, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D,
+ 0x0A, 0x3C, 0x2F, 0x73, 0x63, 0x70, 0x64, 0x3E, 0x00
+};
+
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/ContentDirectorySCPD.xml b/lib/libUPnP/Platinum/Source/Devices/MediaServer/ContentDirectorySCPD.xml
new file mode 100644
index 0000000..9605f91
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/ContentDirectorySCPD.xml
@@ -0,0 +1,148 @@
+<?xml version="1.0" encoding="utf-8"?>
+<scpd xmlns="urn:schemas-upnp-org:service-1-0">
+ <specVersion>
+ <major>1</major>
+ <minor>0</minor>
+ </specVersion>
+ <actionList>
+ <action>
+ <name>Browse</name>
+ <argumentList>
+ <argument>
+ <name>ObjectID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_ObjectID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>BrowseFlag</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_BrowseFlag</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Filter</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_Filter</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>StartingIndex</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_Index</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>RequestedCount</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_Count</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>SortCriteria</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_SortCriteria</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Result</name>
+ <direction>out</direction>
+ <relatedStateVariable>A_ARG_TYPE_Result</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>NumberReturned</name>
+ <direction>out</direction>
+ <relatedStateVariable>A_ARG_TYPE_Count</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>TotalMatches</name>
+ <direction>out</direction>
+ <relatedStateVariable>A_ARG_TYPE_Count</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>UpdateID</name>
+ <direction>out</direction>
+ <relatedStateVariable>A_ARG_TYPE_UpdateID</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetSortCapabilities</name>
+ <argumentList>
+ <argument>
+ <name>SortCaps</name>
+ <direction>out</direction>
+ <relatedStateVariable>SortCapabilities</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetSystemUpdateID</name>
+ <argumentList>
+ <argument>
+ <name>Id</name>
+ <direction>out</direction>
+ <relatedStateVariable>SystemUpdateID</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetSearchCapabilities</name>
+ <argumentList>
+ <argument>
+ <name>SearchCaps</name>
+ <direction>out</direction>
+ <relatedStateVariable>SearchCapabilities</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ </actionList>
+ <serviceStateTable>
+ <stateVariable sendEvents="no">
+ <name>A_ARG_TYPE_BrowseFlag</name>
+ <dataType>string</dataType>
+ <allowedValueList>
+ <allowedValue>BrowseMetadata</allowedValue>
+ <allowedValue>BrowseDirectChildren</allowedValue>
+ </allowedValueList>
+ </stateVariable>
+ <stateVariable sendEvents="yes">
+ <name>ContainerUpdateIDs</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="yes">
+ <name>SystemUpdateID</name>
+ <dataType>ui4</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>A_ARG_TYPE_Count</name>
+ <dataType>ui4</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>A_ARG_TYPE_SortCriteria</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>SortCapabilities</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>A_ARG_TYPE_Index</name>
+ <dataType>ui4</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>A_ARG_TYPE_ObjectID</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>A_ARG_TYPE_UpdateID</name>
+ <dataType>ui4</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>A_ARG_TYPE_Result</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>SearchCapabilities</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>A_ARG_TYPE_Filter</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ </serviceStateTable>
+</scpd> \ No newline at end of file
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/ContentDirectorywSearchSCPD.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaServer/ContentDirectorywSearchSCPD.cpp
new file mode 100644
index 0000000..bc16048
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/ContentDirectorywSearchSCPD.cpp
@@ -0,0 +1,453 @@
+/*****************************************************************
+|
+| Platinum - ContentDirectory SCPD
+|
+| Copyright (c) 2004-2010, Plutinosoft, LLC.
+| All rights reserved.
+| http://www.plutinosoft.com
+|
+| This program is free software; you can redistribute it and/or
+| modify it under the terms of the GNU General Public License
+| as published by the Free Software Foundation; either version 2
+| of the License, or (at your option) any later version.
+|
+| OEMs, ISVs, VARs and other distributors that combine and
+| distribute commercially licensed software with Platinum software
+| and do not wish to distribute the source code for the commercially
+| licensed software under version 2, or (at your option) any later
+| version, of the GNU General Public License (the "GPL") must enter
+| into a commercial license agreement with Plutinosoft, LLC.
+| licensing@plutinosoft.com
+|
+| This program is distributed in the hope that it will be useful,
+| but WITHOUT ANY WARRANTY; without even the implied warranty of
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+| GNU General Public License for more details.
+|
+| You should have received a copy of the GNU General Public License
+| along with this program; see the file LICENSE.txt. If not, write to
+| the Free Software Foundation, Inc.,
+| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+| http://www.gnu.org/licenses/gpl-2.0.html
+|
+****************************************************************/
+
+/*----------------------------------------------------------------------
+| includes
++---------------------------------------------------------------------*/
+#include "Neptune.h"
+
+/*----------------------------------------------------------------------
+| globals
++---------------------------------------------------------------------*/
+NPT_UInt8 MS_ContentDirectorywSearchSCPD[8121] =
+{
+ 0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x31, 0x2E, 0x30, 0x22, 0x20,
+0x65, 0x6E, 0x63, 0x6F, 0x64, 0x69, 0x6E, 0x67, 0x3D, 0x22, 0x75, 0x74, 0x66, 0x2D, 0x38, 0x22, 0x3F, 0x3E, 0x0A, 0x3C,
+0x73, 0x63, 0x70, 0x64, 0x20, 0x78, 0x6D, 0x6C, 0x6E, 0x73, 0x3D, 0x22, 0x75, 0x72, 0x6E, 0x3A, 0x73, 0x63, 0x68, 0x65,
+0x6D, 0x61, 0x73, 0x2D, 0x75, 0x70, 0x6E, 0x70, 0x2D, 0x6F, 0x72, 0x67, 0x3A, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+0x2D, 0x31, 0x2D, 0x30, 0x22, 0x3E, 0x0A, 0x09, 0x3C, 0x73, 0x70, 0x65, 0x63, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E,
+0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x6D, 0x61, 0x6A, 0x6F, 0x72, 0x3E, 0x31, 0x3C, 0x2F, 0x6D, 0x61, 0x6A, 0x6F, 0x72, 0x3E,
+0x20, 0x0A, 0x09, 0x09, 0x3C, 0x6D, 0x69, 0x6E, 0x6F, 0x72, 0x3E, 0x30, 0x3C, 0x2F, 0x6D, 0x69, 0x6E, 0x6F, 0x72, 0x3E,
+0x20, 0x0A, 0x09, 0x3C, 0x2F, 0x73, 0x70, 0x65, 0x63, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x09, 0x3C,
+0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F,
+0x6E, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x42, 0x72, 0x6F, 0x77, 0x73, 0x65, 0x3C, 0x2F, 0x6E,
+0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73,
+0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09,
+0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D,
+0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69,
+0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C,
+0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
+0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x49, 0x44,
+0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
+0x6C, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A,
+0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E,
+0x61, 0x6D, 0x65, 0x3E, 0x42, 0x72, 0x6F, 0x77, 0x73, 0x65, 0x46, 0x6C, 0x61, 0x67, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65,
+0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E,
+0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72,
+0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E,
+0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x42, 0x72, 0x6F, 0x77, 0x73, 0x65, 0x46, 0x6C, 0x61,
+0x67, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61,
+0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E,
+0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C,
+0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x46, 0x69, 0x6C, 0x74, 0x65, 0x72, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A,
+0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64,
+0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61,
+0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41,
+0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x46, 0x69, 0x6C, 0x74, 0x65, 0x72, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61,
+0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0A, 0x09,
+0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72,
+0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x74,
+0x61, 0x72, 0x74, 0x69, 0x6E, 0x67, 0x49, 0x6E, 0x64, 0x65, 0x78, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A,
+0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64,
+0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61,
+0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41,
+0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x64, 0x65, 0x78, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74,
+0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09,
+0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67,
+0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x71,
+0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A,
+0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64,
+0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61,
+0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41,
+0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74,
+0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09,
+0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67,
+0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x6F, 0x72,
+0x74, 0x43, 0x72, 0x69, 0x74, 0x65, 0x72, 0x69, 0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09,
+0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72,
+0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65,
+0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47,
+0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x53, 0x6F, 0x72, 0x74, 0x43, 0x72, 0x69, 0x74, 0x65, 0x72, 0x69, 0x61, 0x3C, 0x2F,
+0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
+0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09,
+0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D,
+0x65, 0x3E, 0x52, 0x65, 0x73, 0x75, 0x6C, 0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09,
+0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72,
+0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65,
+0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47,
+0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x52, 0x65, 0x73, 0x75, 0x6C, 0x74, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65,
+0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09,
+0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75,
+0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4E, 0x75, 0x6D, 0x62,
+0x65, 0x72, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x65, 0x64, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09,
+0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64,
+0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61,
+0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41,
+0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74,
+0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09,
+0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67,
+0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x54, 0x6F, 0x74,
+0x61, 0x6C, 0x4D, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09,
+0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69,
+0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74,
+0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52,
+0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65,
+0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09,
+0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75,
+0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x55, 0x70, 0x64, 0x61,
+0x74, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69,
+0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69,
+0x6F, 0x6E, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61,
+0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50,
+0x45, 0x5F, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53,
+0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F,
+0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65,
+0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A,
+0x09, 0x09, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+0x47, 0x65, 0x74, 0x53, 0x6F, 0x72, 0x74, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6C, 0x69, 0x74, 0x69, 0x65, 0x73, 0x3C,
+0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74,
+0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E,
+0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x6F, 0x72, 0x74, 0x43, 0x61, 0x70, 0x73,
+0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63,
+0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E,
+0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65,
+0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x53, 0x6F, 0x72, 0x74, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6C,
+0x69, 0x74, 0x69, 0x65, 0x73, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56,
+0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75,
+0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C,
+0x69, 0x73, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x09, 0x09, 0x3C,
+0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x47, 0x65, 0x74,
+0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65,
+0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E,
+0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x09,
+0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x64, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09,
+0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64,
+0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C,
+0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x53, 0x79,
+0x73, 0x74, 0x65, 0x6D, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65,
+0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09,
+0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72,
+0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69,
+0x6F, 0x6E, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E,
+0x61, 0x6D, 0x65, 0x3E, 0x47, 0x65, 0x74, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6C,
+0x69, 0x74, 0x69, 0x65, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72,
+0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67,
+0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x65,
+0x61, 0x72, 0x63, 0x68, 0x43, 0x61, 0x70, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09,
+0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69,
+0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61,
+0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x53, 0x65, 0x61,
+0x72, 0x63, 0x68, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6C, 0x69, 0x74, 0x69, 0x65, 0x73, 0x3C, 0x2F, 0x72, 0x65, 0x6C,
+0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0A,
+0x09, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C,
+0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x61,
+0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x09, 0x09,
+0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x3C, 0x2F, 0x6E, 0x61,
+0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67,
+0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E,
+0x61, 0x6D, 0x65, 0x3E, 0x43, 0x6F, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x65, 0x72, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D,
+0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69,
+0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0A, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72,
+0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E,
+0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x49, 0x44, 0x3C,
+0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C,
+0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E,
+0x61, 0x6D, 0x65, 0x3E, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x43, 0x72, 0x69, 0x74, 0x65, 0x72, 0x69, 0x61, 0x3C, 0x2F,
+0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C,
+0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72,
+0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x53, 0x65, 0x61,
+0x72, 0x63, 0x68, 0x43, 0x72, 0x69, 0x74, 0x65, 0x72, 0x69, 0x61, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64,
+0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E,
+0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x46, 0x69, 0x6C, 0x74,
+0x65, 0x72, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E,
+0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C,
+0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F,
+0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x46, 0x69, 0x6C, 0x74, 0x65, 0x72, 0x3C, 0x2F, 0x72, 0x65, 0x6C,
+0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67,
+0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+0x53, 0x74, 0x61, 0x72, 0x74, 0x69, 0x6E, 0x67, 0x49, 0x6E, 0x64, 0x65, 0x78, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65,
+0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65,
+0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F,
+0x49, 0x6E, 0x64, 0x65, 0x78, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56,
+0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65,
+0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x43,
+0x6F, 0x75, 0x6E, 0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69,
+0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72,
+0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E,
+0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x3C, 0x2F, 0x72, 0x65,
+0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72,
+0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65,
+0x3E, 0x53, 0x6F, 0x72, 0x74, 0x43, 0x72, 0x69, 0x74, 0x65, 0x72, 0x69, 0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65,
+0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0A, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65,
+0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41,
+0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x53, 0x6F, 0x72, 0x74, 0x43, 0x72, 0x69, 0x74, 0x65, 0x72,
+0x69, 0x61, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69,
+0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E,
+0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x73, 0x75, 0x6C, 0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72,
+0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74,
+0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45,
+0x5F, 0x52, 0x65, 0x73, 0x75, 0x6C, 0x74, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74,
+0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75,
+0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4E, 0x75, 0x6D, 0x62, 0x65, 0x72, 0x52, 0x65,
+0x74, 0x75, 0x72, 0x6E, 0x65, 0x64, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63,
+0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E,
+0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
+0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x3C,
+0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C,
+0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E,
+0x61, 0x6D, 0x65, 0x3E, 0x54, 0x6F, 0x74, 0x61, 0x6C, 0x4D, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x3C, 0x2F, 0x6E, 0x61,
+0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F,
+0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53,
+0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54,
+0x59, 0x50, 0x45, 0x5F, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74,
+0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E,
+0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72,
+0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
+0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E,
+0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74,
+0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45,
+0x5F, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74,
+0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E,
+0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D,
+0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61,
+0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74,
+0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E,
+0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4F, 0x62, 0x6A, 0x65,
+0x63, 0x74, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69,
+0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72,
+0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E,
+0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x49, 0x44, 0x3C,
+0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C,
+0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67,
+0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72,
+0x65, 0x6E, 0x74, 0x54, 0x61, 0x67, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74,
+0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
+0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x54, 0x61,
+0x67, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53,
+0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E,
+0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4E, 0x65, 0x77, 0x54, 0x61, 0x67, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3C, 0x2F,
+0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C,
+0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64,
+0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F,
+0x54, 0x59, 0x50, 0x45, 0x5F, 0x54, 0x61, 0x67, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3C, 0x2F, 0x72,
+0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E,
+0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D,
+0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C,
+0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x09, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E,
+0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x09, 0x3C, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65,
+0x54, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61,
+0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E,
+0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45,
+0x5F, 0x42, 0x72, 0x6F, 0x77, 0x73, 0x65, 0x46, 0x6C, 0x61, 0x67, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A,
+0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C,
+0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x6C, 0x6C, 0x6F,
+0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61,
+0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x42, 0x72, 0x6F, 0x77, 0x73, 0x65, 0x4D, 0x65,
+0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65,
+0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65,
+0x3E, 0x42, 0x72, 0x6F, 0x77, 0x73, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x43, 0x68, 0x69, 0x6C, 0x64, 0x72, 0x65,
+0x6E, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09,
+0x09, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E,
+0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A,
+0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E,
+0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x79, 0x65, 0x73, 0x22, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E,
+0x61, 0x6D, 0x65, 0x3E, 0x43, 0x6F, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49,
+0x44, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54,
+0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65,
+0x3E, 0x20, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
+0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73,
+0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x79, 0x65, 0x73, 0x22, 0x3E, 0x0A, 0x09, 0x09, 0x09,
+0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x44,
+0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70,
+0x65, 0x3E, 0x75, 0x69, 0x34, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09,
+0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x09, 0x09, 0x3C,
+0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76,
+0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
+0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x3C, 0x2F, 0x6E, 0x61,
+0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x75, 0x69,
+0x34, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74,
+0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74,
+0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73,
+0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52,
+0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x53, 0x6F, 0x72, 0x74, 0x43, 0x72, 0x69, 0x74, 0x65, 0x72, 0x69, 0x61, 0x3C,
+0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65,
+0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x20, 0x0A,
+0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x09,
+0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64,
+0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D,
+0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x43,
+0x72, 0x69, 0x74, 0x65, 0x72, 0x69, 0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64,
+0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61,
+0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61,
+0x62, 0x6C, 0x65, 0x3E, 0x20, 0x20, 0x20, 0x20, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72,
+0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F,
+0x22, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x6F, 0x72, 0x74, 0x43, 0x61, 0x70, 0x61,
+0x62, 0x69, 0x6C, 0x69, 0x74, 0x69, 0x65, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09,
+0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61,
+0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
+0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69,
+0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22,
+0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50,
+0x45, 0x5F, 0x49, 0x6E, 0x64, 0x65, 0x78, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x3C,
+0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x75, 0x69, 0x34, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79,
+0x70, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
+0x6C, 0x65, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
+0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x09, 0x09,
+0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x4F, 0x62,
+0x6A, 0x65, 0x63, 0x74, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64,
+0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61,
+0x54, 0x79, 0x70, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69,
+0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
+0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A,
+0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F,
+0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09,
+0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x75, 0x69, 0x34, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54,
+0x79, 0x70, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61,
+0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C,
+0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x09,
+0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x52,
+0x65, 0x73, 0x75, 0x6C, 0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61,
+0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54,
+0x79, 0x70, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61,
+0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C,
+0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x09,
+0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69,
+0x6C, 0x69, 0x74, 0x69, 0x65, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64,
+0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61,
+0x54, 0x79, 0x70, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69,
+0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
+0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A,
+0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F,
+0x46, 0x69, 0x6C, 0x74, 0x65, 0x72, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64,
+0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61,
+0x54, 0x79, 0x70, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69,
+0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
+0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A,
+0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F,
+0x54, 0x61, 0x67, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A,
+0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C,
+0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65,
+0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x09, 0x3C, 0x2F, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+0x53, 0x74, 0x61, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x3C, 0x2F, 0x73, 0x63, 0x70, 0x64, 0x3E, 0x0A,
+0x00
+};
+
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/ContentDirectorywSearchSCPD.xml b/lib/libUPnP/Platinum/Source/Devices/MediaServer/ContentDirectorywSearchSCPD.xml
new file mode 100644
index 0000000..cba42e5
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/ContentDirectorywSearchSCPD.xml
@@ -0,0 +1,231 @@
+<?xml version="1.0" encoding="utf-8"?>
+<scpd xmlns="urn:schemas-upnp-org:service-1-0">
+ <specVersion>
+ <major>1</major>
+ <minor>0</minor>
+ </specVersion>
+ <actionList>
+ <action>
+ <name>Browse</name>
+ <argumentList>
+ <argument>
+ <name>ObjectID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_ObjectID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>BrowseFlag</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_BrowseFlag</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Filter</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_Filter</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>StartingIndex</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_Index</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>RequestedCount</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_Count</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>SortCriteria</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_SortCriteria</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Result</name>
+ <direction>out</direction>
+ <relatedStateVariable>A_ARG_TYPE_Result</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>NumberReturned</name>
+ <direction>out</direction>
+ <relatedStateVariable>A_ARG_TYPE_Count</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>TotalMatches</name>
+ <direction>out</direction>
+ <relatedStateVariable>A_ARG_TYPE_Count</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>UpdateID</name>
+ <direction>out</direction>
+ <relatedStateVariable>A_ARG_TYPE_UpdateID</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetSortCapabilities</name>
+ <argumentList>
+ <argument>
+ <name>SortCaps</name>
+ <direction>out</direction>
+ <relatedStateVariable>SortCapabilities</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetSystemUpdateID</name>
+ <argumentList>
+ <argument>
+ <name>Id</name>
+ <direction>out</direction>
+ <relatedStateVariable>SystemUpdateID</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetSearchCapabilities</name>
+ <argumentList>
+ <argument>
+ <name>SearchCaps</name>
+ <direction>out</direction>
+ <relatedStateVariable>SearchCapabilities</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>Search</name>
+ <argumentList>
+ <argument>
+ <name>ContainerID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_ObjectID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>SearchCriteria</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_SearchCriteria</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Filter</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_Filter</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>StartingIndex</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_Index</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>RequestedCount</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_Count</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>SortCriteria</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_SortCriteria</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>Result</name>
+ <direction>out</direction>
+ <relatedStateVariable>A_ARG_TYPE_Result</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>NumberReturned</name>
+ <direction>out</direction>
+ <relatedStateVariable>A_ARG_TYPE_Count</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>TotalMatches</name>
+ <direction>out</direction>
+ <relatedStateVariable>A_ARG_TYPE_Count</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>UpdateID</name>
+ <direction>out</direction>
+ <relatedStateVariable>A_ARG_TYPE_UpdateID</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>UpdateObject</name>
+ <argumentList>
+ <argument>
+ <name>ObjectID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_ObjectID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>CurrentTagValue</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_TagValueList</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>NewTagValue</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_TagValueList</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
+ </actionList>
+ <serviceStateTable>
+ <stateVariable sendEvents="no">
+ <name>A_ARG_TYPE_BrowseFlag</name>
+ <dataType>string</dataType>
+ <allowedValueList>
+ <allowedValue>BrowseMetadata</allowedValue>
+ <allowedValue>BrowseDirectChildren</allowedValue>
+ </allowedValueList>
+ </stateVariable>
+ <stateVariable sendEvents="yes">
+ <name>ContainerUpdateIDs</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="yes">
+ <name>SystemUpdateID</name>
+ <dataType>ui4</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>A_ARG_TYPE_Count</name>
+ <dataType>ui4</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>A_ARG_TYPE_SortCriteria</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>A_ARG_TYPE_SearchCriteria</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>SortCapabilities</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>A_ARG_TYPE_Index</name>
+ <dataType>ui4</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>A_ARG_TYPE_ObjectID</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>A_ARG_TYPE_UpdateID</name>
+ <dataType>ui4</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>A_ARG_TYPE_Result</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>SearchCapabilities</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>A_ARG_TYPE_Filter</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ <stateVariable sendEvents="no">
+ <name>A_ARG_TYPE_TagValueList</name>
+ <dataType>string</dataType>
+ </stateVariable>
+ </serviceStateTable>
+</scpd>
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.cpp
new file mode 100644
index 0000000..37d36dd
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.cpp
@@ -0,0 +1,406 @@
+/*****************************************************************
+|
+| Platinum - DIDL
+|
+| Copyright (c) 2004-2010, Plutinosoft, LLC.
+| All rights reserved.
+| http://www.plutinosoft.com
+|
+| This program is free software; you can redistribute it and/or
+| modify it under the terms of the GNU General Public License
+| as published by the Free Software Foundation; either version 2
+| of the License, or (at your option) any later version.
+|
+| OEMs, ISVs, VARs and other distributors that combine and
+| distribute commercially licensed software with Platinum software
+| and do not wish to distribute the source code for the commercially
+| licensed software under version 2, or (at your option) any later
+| version, of the GNU General Public License (the "GPL") must enter
+| into a commercial license agreement with Plutinosoft, LLC.
+| licensing@plutinosoft.com
+|
+| This program is distributed in the hope that it will be useful,
+| but WITHOUT ANY WARRANTY; without even the implied warranty of
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+| GNU General Public License for more details.
+|
+| You should have received a copy of the GNU General Public License
+| along with this program; see the file LICENSE.txt. If not, write to
+| the Free Software Foundation, Inc.,
+| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+| http://www.gnu.org/licenses/gpl-2.0.html
+|
+****************************************************************/
+
+/*----------------------------------------------------------------------
+| includes
++---------------------------------------------------------------------*/
+#include "PltDidl.h"
+#include "PltUtilities.h"
+#include "PltService.h"
+
+NPT_SET_LOCAL_LOGGER("platinum.media.server.didl")
+
+/*----------------------------------------------------------------------
+| globals
++---------------------------------------------------------------------*/
+const char* didl_header = "<DIDL-Lite xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\""
+ " xmlns:dc=\"http://purl.org/dc/elements/1.1/\""
+ " xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\""
+ " xmlns:dlna=\"urn:schemas-dlna-org:metadata-1-0/\""
+ " xmlns:sec=\"http://www.sec.co.kr/\""
+ " xmlns:xbmc=\"urn:schemas-xbmc-org:metadata-1-0/\">";
+const char* didl_footer = "</DIDL-Lite>";
+const char* didl_namespace_dc = "http://purl.org/dc/elements/1.1/";
+const char* didl_namespace_upnp = "urn:schemas-upnp-org:metadata-1-0/upnp/";
+const char* didl_namespace_dlna = "urn:schemas-dlna-org:metadata-1-0/";
+const char* didl_namespace_xbmc = "urn:schemas-xbmc-org:metadata-1-0/";
+
+/*----------------------------------------------------------------------
+| PLT_Didl::ConvertFilterToMask
++---------------------------------------------------------------------*/
+NPT_UInt64
+PLT_Didl::ConvertFilterToMask(const NPT_String& filter)
+{
+ // easy out
+ if (filter.GetLength() == 0) return PLT_FILTER_MASK_ALL;
+
+ // a filter string is a comma delimited set of fields identifying
+ // a given DIDL property (or set of properties).
+ // These fields are or start with: upnp:, @, res@, res, dc:, container@
+
+ NPT_UInt64 mask = 0;
+ const char* s = filter;
+ int i = 0;
+
+ while (s[i] != '\0') {
+ int next_comma = filter.Find(',', i);
+ int len = ((next_comma < 0)?(int)filter.GetLength():next_comma)-i;
+
+ if (NPT_String::CompareN(s+i, "*", 1) == 0) {
+ // return now, there's no point in parsing the rest
+ return PLT_FILTER_MASK_ALL;
+ }
+
+ // title is required, so we return a non empty mask
+ mask |= PLT_FILTER_MASK_TITLE;
+
+ if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_TITLE, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_TITLE;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_REFID, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_REFID;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_CREATOR, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_CREATOR;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_ARTIST, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_ARTIST;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_ACTOR, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_ACTOR;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_DIRECTOR, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_DIRECTOR;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_AUTHOR, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_AUTHOR;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_DATE, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_DATE;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_ALBUM, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_ALBUM;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_GENRE, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_GENRE;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_ALBUMARTURI, len, true) == 0 ||
+ NPT_String::CompareN(s+i, PLT_FILTER_FIELD_ALBUMARTURI_DLNAPROFILEID, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_ALBUMARTURI;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_DESCRIPTION, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_DESCRIPTION;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_LONGDESCRIPTION, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_LONGDESCRIPTION;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_ORIGINALTRACK, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_ORIGINALTRACK;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_LASTPOSITION, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_LASTPOSITION;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_LASTPLAYBACK, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_LASTPLAYBACK;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_PLAYCOUNT, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_PLAYCOUNT;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_SEARCHABLE, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_SEARCHABLE;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_SEARCHCLASS, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_SEARCHCLASS;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_CONTAINER_SEARCHABLE, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_SEARCHABLE;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_CHILDCOUNT, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_CHILDCOUNT;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_CONTAINER_CHILDCOUNT, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_CHILDCOUNT;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_PROGRAMTITLE, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_PROGRAMTITLE;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_SERIESTITLE, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_SERIESTITLE;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_EPISODE, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_EPISODE;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_RATING, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_RATING;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_PUBLISHER, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_PUBLISHER;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_RES, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_RES;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_RES_DURATION, len, true) == 0 ||
+ NPT_String::CompareN(s+i, PLT_FILTER_FIELD_RES_DURATION_SHORT, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_RES | PLT_FILTER_MASK_RES_DURATION;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_RES_SIZE, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_RES | PLT_FILTER_MASK_RES_SIZE;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_RES_PROTECTION, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_RES | PLT_FILTER_MASK_RES_PROTECTION;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_RES_RESOLUTION, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_RES | PLT_FILTER_MASK_RES_RESOLUTION;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_RES_BITRATE, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_RES | PLT_FILTER_MASK_RES_BITRATE;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_RES_BITSPERSAMPLE, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_RES | PLT_FILTER_MASK_RES_BITSPERSAMPLE;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_RES_NRAUDIOCHANNELS, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_RES | PLT_FILTER_MASK_RES_NRAUDIOCHANNELS;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_RES_SAMPLEFREQUENCY, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_RES | PLT_FILTER_MASK_RES_SAMPLEFREQUENCY;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_EPISODE_COUNT, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_EPISODE_COUNT;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_EPISODE_SEASON, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_EPISODE_SEASON;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_XBMC_LASTPLAYERSTATE, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_XBMC_LASTPLAYERSTATE;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_XBMC_DATEADDED, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_XBMC_DATEADDED;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_XBMC_RATING, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_XBMC_RATING;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_XBMC_VOTES, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_XBMC_VOTES;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_XBMC_ARTWORK, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_XBMC_ARTWORK;
+ } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_XBMC_UNIQUE_IDENTIFIER, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_XBMC_UNIQUE_IDENTIFIER;
+ } else if (NPT_String::CompareN(s + i, PLT_FILTER_FIELD_XBMC_COUNTRY, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_XBMC_COUNTRY;
+ } else if (NPT_String::CompareN(s + i, PLT_FILTER_FIELD_XBMC_USERRATING, len, true) == 0) {
+ mask |= PLT_FILTER_MASK_XBMC_USERRATING;
+ }
+
+ if (next_comma < 0) {
+ return mask;
+ }
+
+ i = next_comma + 1;
+ }
+
+ return mask;
+}
+
+/*----------------------------------------------------------------------
+| PLT_Didl::AppendXmlUnEscape
++---------------------------------------------------------------------*/
+void
+PLT_Didl::AppendXmlUnEscape(NPT_String& out, const char* in)
+{
+ unsigned int i=0;
+ while (i<NPT_StringLength(in)) {
+ if (NPT_String::CompareN(in+i, "&lt;", 4) == 0) {
+ out += '<';
+ i +=4;
+ } else if (NPT_String::CompareN(in+i, "&gt;", 4) == 0) {
+ out += '>';
+ i += 4;
+ } else if (NPT_String::CompareN(in+i, "&amp;", 5) == 0) {
+ out += '&';
+ i += 5;
+ } else if (NPT_String::CompareN(in+i, "&quot;", 6) == 0) {
+ out += '"';
+ i += 6;
+ } else if (NPT_String::CompareN(in+i, "&apos;", 6) == 0) {
+ out += '\'';
+ i += 6;
+ } else {
+ out += *(in+i);
+ i++;
+ }
+ }
+}
+
+/*----------------------------------------------------------------------
+| PLT_Didl::AppendXmlEscape
++---------------------------------------------------------------------*/
+void
+PLT_Didl::AppendXmlEscape(NPT_String& out, const char* in)
+{
+ if (!in) return;
+
+ for (int i=0; i<(int)NPT_StringLength(in); i++) {
+ if (*(in+i) == '<') {
+ out += "&lt;";
+ } else if (*(in+i) == '>') {
+ out += "&gt;";
+ } else if (*(in+i) == '&') {
+ out += "&amp;";
+ } else if (*(in+i) == '"') {
+ out += "&quot;";
+ } else if (*(in+i) == '\'') {
+ out += "&apos;";
+ } else {
+ out += *(in+i);
+ }
+ }
+}
+
+/*----------------------------------------------------------------------
+| PLT_Didl::FormatTimeStamp
++---------------------------------------------------------------------*/
+NPT_String
+PLT_Didl::FormatTimeStamp(NPT_UInt32 seconds)
+{
+ NPT_String result;
+ int hours = seconds/3600;
+ if (hours == 0) {
+ result += "0:";
+ } else {
+ result += NPT_String::FromInteger(hours) + ":";
+ }
+
+ int minutes = (seconds/60)%60;
+ if (minutes == 0) {
+ result += "00:";
+ } else {
+ if (minutes < 10) {
+ result += '0';
+ }
+ result += NPT_String::FromInteger(minutes) + ":";
+ }
+
+ int secs = seconds%60;
+ if (secs == 0) {
+ result += "00";
+ } else {
+ if (secs < 10) {
+ result += '0';
+ }
+ result += NPT_String::FromInteger(secs);
+ }
+
+ result += ".000"; // needed for XBOX360 otherwise it won't play the track
+ return result;
+}
+
+/*----------------------------------------------------------------------
+| PLT_Didl::ParseTimeStamp
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_Didl::ParseTimeStamp(const NPT_String& timestamp, NPT_UInt32& seconds)
+{
+ // assume a timestamp in the format HH:MM:SS.FFF
+ int separator;
+ NPT_String str = timestamp;
+ NPT_UInt32 value;
+
+ // reset output params first
+ seconds = 0;
+
+ // remove milliseconds first if any
+ if ((separator = str.ReverseFind('.')) != -1) {
+ str = str.Left(separator);
+ }
+
+ // look for next separator
+ if ((separator = str.ReverseFind(':')) == -1) return NPT_FAILURE;
+
+ // extract seconds
+ NPT_CHECK_WARNING(str.SubString(separator+1).ToInteger(value));
+ seconds = value;
+ str = str.Left(separator);
+
+ // look for next separator
+ if ((separator = str.ReverseFind(':')) == -1) return NPT_FAILURE;
+
+ // extract minutes
+ NPT_CHECK_WARNING(str.SubString(separator+1).ToInteger(value));
+ seconds += 60*value;
+ str = str.Left(separator);
+
+ // extract hours
+ NPT_CHECK_WARNING(str.ToInteger(value));
+ seconds += 3600*value;
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_Didl::ToDidl
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_Didl::ToDidl(PLT_MediaObject& object, const NPT_String& filter, NPT_String& didl)
+{
+ NPT_UInt64 mask = ConvertFilterToMask(filter);
+
+ // Allocate enough space for the didl
+ didl.Reserve(2048);
+
+ return object.ToDidl(mask, didl);
+}
+
+/*----------------------------------------------------------------------
+| PLT_Didl::FromDidl
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_Didl::FromDidl(const char* xml, PLT_MediaObjectListReference& objects)
+{
+ NPT_String str;
+ PLT_MediaObject* object = NULL;
+ NPT_XmlNode* node = NULL;
+ NPT_XmlElementNode* didl = NULL;
+ NPT_XmlParser parser;
+
+ NPT_LOG_FINE("Parsing Didl...");
+
+ NPT_CHECK_LABEL_SEVERE(parser.Parse(xml, node), cleanup);
+ if (!node || !node->AsElementNode()) {
+ NPT_LOG_SEVERE("Invalid node type");
+ goto cleanup;
+ }
+
+ didl = node->AsElementNode();
+
+ if (didl->GetTag().Compare("DIDL-Lite", true)) {
+ NPT_LOG_SEVERE("Invalid node tag");
+ goto cleanup;
+ }
+
+ // create entry list
+ objects = new PLT_MediaObjectList();
+
+ // for each child, find out if it's a container or not
+ // and then invoke the FromDidl on it
+ for (NPT_List<NPT_XmlNode*>::Iterator children = didl->GetChildren().GetFirstItem(); children; children++) {
+ NPT_XmlElementNode* child = (*children)->AsElementNode();
+ if (!child) continue;
+
+ if (child->GetTag().Compare("Container", true) == 0) {
+ object = new PLT_MediaContainer();
+ } else if (child->GetTag().Compare("item", true) == 0) {
+ object = new PLT_MediaItem();
+ } else {
+ NPT_LOG_WARNING("Invalid node tag");
+ continue;
+ }
+
+ if (NPT_FAILED(object->FromDidl(child))) {
+ NPT_LOG_WARNING_1("Invalid didl for object: %s",
+ (const char*) PLT_XmlHelper::Serialize(*child, false));
+ continue;
+ }
+
+ objects->Add(object);
+ object = NULL; // reset to make sure it doesn't get deleted twice in case of error
+ }
+
+ delete node;
+ return NPT_SUCCESS;
+
+cleanup:
+ objects = NULL;
+ delete node;
+ delete object;
+ return NPT_FAILURE;
+}
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.h b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.h
new file mode 100644
index 0000000..b74ed0f
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.h
@@ -0,0 +1,197 @@
+/*****************************************************************
+|
+| Platinum - DIDL handling
+|
+| Copyright (c) 2004-2010, Plutinosoft, LLC.
+| All rights reserved.
+| http://www.plutinosoft.com
+|
+| This program is free software; you can redistribute it and/or
+| modify it under the terms of the GNU General Public License
+| as published by the Free Software Foundation; either version 2
+| of the License, or (at your option) any later version.
+|
+| OEMs, ISVs, VARs and other distributors that combine and
+| distribute commercially licensed software with Platinum software
+| and do not wish to distribute the source code for the commercially
+| licensed software under version 2, or (at your option) any later
+| version, of the GNU General Public License (the "GPL") must enter
+| into a commercial license agreement with Plutinosoft, LLC.
+| licensing@plutinosoft.com
+|
+| This program is distributed in the hope that it will be useful,
+| but WITHOUT ANY WARRANTY; without even the implied warranty of
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+| GNU General Public License for more details.
+|
+| You should have received a copy of the GNU General Public License
+| along with this program; see the file LICENSE.txt. If not, write to
+| the Free Software Foundation, Inc.,
+| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+| http://www.gnu.org/licenses/gpl-2.0.html
+|
+****************************************************************/
+
+/** @file
+ UPnP AV Didl
+ */
+
+#ifndef _PLT_DIDL_H_
+#define _PLT_DIDL_H_
+
+/*----------------------------------------------------------------------
+| includes
++---------------------------------------------------------------------*/
+#include "Neptune.h"
+#include "PltMediaItem.h"
+
+/*----------------------------------------------------------------------
+| constants
++---------------------------------------------------------------------*/
+#define PLT_FILTER_MASK_ALL NPT_UINT64_C(0xFFFFFFFFFFFFFFFF)
+
+#define PLT_FILTER_MASK_CREATOR NPT_UINT64_C(0x0000000000000001)
+#define PLT_FILTER_MASK_ARTIST NPT_UINT64_C(0x0000000000000002)
+#define PLT_FILTER_MASK_ALBUM NPT_UINT64_C(0x0000000000000004)
+#define PLT_FILTER_MASK_GENRE NPT_UINT64_C(0x0000000000000008)
+#define PLT_FILTER_MASK_ALBUMARTURI NPT_UINT64_C(0x0000000000000010)
+#define PLT_FILTER_MASK_DESCRIPTION NPT_UINT64_C(0x0000000000000020)
+#define PLT_FILTER_MASK_SEARCHABLE NPT_UINT64_C(0x0000000000000040)
+#define PLT_FILTER_MASK_CHILDCOUNT NPT_UINT64_C(0x0000000000000080)
+#define PLT_FILTER_MASK_ORIGINALTRACK NPT_UINT64_C(0x0000000000000100)
+#define PLT_FILTER_MASK_ACTOR NPT_UINT64_C(0x0000000000000200)
+#define PLT_FILTER_MASK_AUTHOR NPT_UINT64_C(0x0000000000000400)
+#define PLT_FILTER_MASK_DIRECTOR NPT_UINT64_C(0x0000000000000800)
+#define PLT_FILTER_MASK_DATE NPT_UINT64_C(0x0000000000001000)
+#define PLT_FILTER_MASK_PROGRAMTITLE NPT_UINT64_C(0x0000000000002000)
+#define PLT_FILTER_MASK_SERIESTITLE NPT_UINT64_C(0x0000000000004000)
+#define PLT_FILTER_MASK_EPISODE NPT_UINT64_C(0x0000000000008000)
+#define PLT_FILTER_MASK_TITLE NPT_UINT64_C(0x0000000000010000)
+
+#define PLT_FILTER_MASK_RES NPT_UINT64_C(0x0000000000020000)
+#define PLT_FILTER_MASK_RES_DURATION NPT_UINT64_C(0x0000000000040000)
+#define PLT_FILTER_MASK_RES_SIZE NPT_UINT64_C(0x0000000000080000)
+#define PLT_FILTER_MASK_RES_PROTECTION NPT_UINT64_C(0x0000000000100000)
+#define PLT_FILTER_MASK_RES_RESOLUTION NPT_UINT64_C(0x0000000000200000)
+#define PLT_FILTER_MASK_RES_BITRATE NPT_UINT64_C(0x0000000000400000)
+#define PLT_FILTER_MASK_RES_BITSPERSAMPLE NPT_UINT64_C(0x0000000000800000)
+#define PLT_FILTER_MASK_RES_NRAUDIOCHANNELS NPT_UINT64_C(0x0000000001000000)
+#define PLT_FILTER_MASK_RES_SAMPLEFREQUENCY NPT_UINT64_C(0x0000000002000000)
+
+#define PLT_FILTER_MASK_LONGDESCRIPTION NPT_UINT64_C(0x0000000004000000)
+#define PLT_FILTER_MASK_ICON NPT_UINT64_C(0x0000000008000000)
+#define PLT_FILTER_MASK_RATING NPT_UINT64_C(0x0000000010000000)
+
+#define PLT_FILTER_MASK_TOC NPT_UINT64_C(0x0000000020000000)
+#define PLT_FILTER_MASK_SEARCHCLASS NPT_UINT64_C(0x0000000040000000)
+#define PLT_FILTER_MASK_REFID NPT_UINT64_C(0x0000000080000000)
+
+#define PLT_FILTER_MASK_LASTPOSITION NPT_UINT64_C(0x0000000100000000)
+#define PLT_FILTER_MASK_LASTPLAYBACK NPT_UINT64_C(0x0000000200000000)
+#define PLT_FILTER_MASK_PLAYCOUNT NPT_UINT64_C(0x0000000400000000)
+
+#define PLT_FILTER_MASK_PUBLISHER NPT_UINT64_C(0x0000000800000000)
+
+#define PLT_FILTER_MASK_EPISODE_COUNT NPT_UINT64_C(0x0000001000000000)
+#define PLT_FILTER_MASK_EPISODE_SEASON NPT_UINT64_C(0x0000002000000000)
+
+#define PLT_FILTER_MASK_XBMC_DATEADDED NPT_UINT64_C(0x0000100000000000)
+#define PLT_FILTER_MASK_XBMC_RATING NPT_UINT64_C(0x0000200000000000)
+#define PLT_FILTER_MASK_XBMC_VOTES NPT_UINT64_C(0x0000400000000000)
+#define PLT_FILTER_MASK_XBMC_ARTWORK NPT_UINT64_C(0x0000800000000000)
+#define PLT_FILTER_MASK_XBMC_UNIQUE_IDENTIFIER NPT_UINT64_C(0x0001000000000000)
+#define PLT_FILTER_MASK_XBMC_COUNTRY NPT_UINT64_C(0x0002000000000000)
+#define PLT_FILTER_MASK_XBMC_USERRATING NPT_UINT64_C(0x0004000000000000)
+#define PLT_FILTER_MASK_XBMC_LASTPLAYERSTATE NPT_UINT64_C(0x0008000000000000)
+
+#define PLT_FILTER_FIELD_TITLE "dc:title"
+#define PLT_FILTER_FIELD_CREATOR "dc:creator"
+#define PLT_FILTER_FIELD_DATE "dc:date"
+#define PLT_FILTER_FIELD_ARTIST "upnp:artist"
+#define PLT_FILTER_FIELD_ACTOR "upnp:actor"
+#define PLT_FILTER_FIELD_AUTHOR "upnp:author"
+#define PLT_FILTER_FIELD_DIRECTOR "upnp:director"
+#define PLT_FILTER_FIELD_ALBUM "upnp:album"
+#define PLT_FILTER_FIELD_GENRE "upnp:genre"
+#define PLT_FILTER_FIELD_ALBUMARTURI "upnp:albumArtURI"
+#define PLT_FILTER_FIELD_ALBUMARTURI_DLNAPROFILEID "upnp:albumArtURI@dlna:profileID"
+#define PLT_FILTER_FIELD_DESCRIPTION "dc:description"
+#define PLT_FILTER_FIELD_LONGDESCRIPTION "upnp:longDescription"
+#define PLT_FILTER_FIELD_ICON "upnp:icon"
+#define PLT_FILTER_FIELD_RATING "upnp:rating"
+#define PLT_FILTER_FIELD_ORIGINALTRACK "upnp:originalTrackNumber"
+#define PLT_FILTER_FIELD_PROGRAMTITLE "upnp:programTitle"
+#define PLT_FILTER_FIELD_SERIESTITLE "upnp:seriesTitle"
+#define PLT_FILTER_FIELD_EPISODE "upnp:episodeNumber"
+#define PLT_FILTER_FIELD_LASTPOSITION "upnp:lastPlaybackPosition"
+#define PLT_FILTER_FIELD_LASTPLAYBACK "upnp:lastPlaybackTime"
+#define PLT_FILTER_FIELD_PLAYCOUNT "upnp:playbackCount"
+#define PLT_FILTER_FIELD_SEARCHCLASS "upnp:searchClass"
+#define PLT_FILTER_FIELD_SEARCHABLE "@searchable"
+#define PLT_FILTER_FIELD_CHILDCOUNT "@childcount"
+#define PLT_FILTER_FIELD_CONTAINER_CHILDCOUNT "container@childCount"
+#define PLT_FILTER_FIELD_CONTAINER_SEARCHABLE "container@searchable"
+#define PLT_FILTER_FIELD_REFID "@refID"
+#define PLT_FILTER_FIELD_PUBLISHER "dc:publisher"
+
+#define PLT_FILTER_FIELD_RES "res"
+#define PLT_FILTER_FIELD_RES_DURATION "res@duration"
+#define PLT_FILTER_FIELD_RES_DURATION_SHORT "@duration"
+#define PLT_FILTER_FIELD_RES_SIZE "res@size"
+#define PLT_FILTER_FIELD_RES_PROTECTION "res@protection"
+#define PLT_FILTER_FIELD_RES_RESOLUTION "res@resolution"
+#define PLT_FILTER_FIELD_RES_BITRATE "res@bitrate"
+#define PLT_FILTER_FIELD_RES_BITSPERSAMPLE "res@bitsPerSample"
+#define PLT_FILTER_FIELD_RES_NRAUDIOCHANNELS "res@nrAudioChannels"
+#define PLT_FILTER_FIELD_RES_SAMPLEFREQUENCY "res@sampleFrequency"
+
+#define PLT_FILTER_FIELD_EPISODE_COUNT "upnp:episodeCount"
+#define PLT_FILTER_FIELD_EPISODE_SEASON "upnp:episodeSeason"
+
+#define PLT_FILTER_FIELD_XBMC_LASTPLAYERSTATE "xbmc:lastPlayerState"
+#define PLT_FILTER_FIELD_XBMC_DATEADDED "xbmc:dateadded"
+#define PLT_FILTER_FIELD_XBMC_RATING "xbmc:rating"
+#define PLT_FILTER_FIELD_XBMC_VOTES "xbmc:votes"
+#define PLT_FILTER_FIELD_XBMC_ARTWORK "xbmc:artwork"
+#define PLT_FILTER_FIELD_XBMC_UNIQUE_IDENTIFIER "xbmc:uniqueidentifier"
+#define PLT_FILTER_FIELD_XBMC_COUNTRY "xbmc:country"
+#define PLT_FILTER_FIELD_XBMC_USERRATING "xbmc:userrating"
+
+extern const char* didl_header;
+extern const char* didl_footer;
+extern const char* didl_namespace_dc;
+extern const char* didl_namespace_upnp;
+extern const char* didl_namespace_dlna;
+extern const char* didl_namespace_xbmc;
+
+/*----------------------------------------------------------------------
+| PLT_Didl
++---------------------------------------------------------------------*/
+/**
+ DIDL manipulation.
+ The PLT_Didl class provides a mechanism to (de)serialize a PLT_MediaObject or
+ list of PLT_MediaObject (PLT_MediaObjectList).
+ */
+class PLT_Didl
+{
+public:
+ static NPT_Result ToDidl(PLT_MediaObject& object,
+ const NPT_String& filter,
+ NPT_String& didl);
+ static NPT_Result FromDidl(const char* didl,
+ PLT_MediaObjectListReference& objects);
+ static void AppendXmlEscape(NPT_String& out, const char* in);
+ static void AppendXmlUnEscape(NPT_String& out, const char* in);
+ static NPT_Result ParseTimeStamp(const NPT_String& timestamp, NPT_UInt32& seconds);
+ static NPT_String FormatTimeStamp(NPT_UInt32 seconds);
+ static NPT_Result ParseTimeStamp(const NPT_String& in, NPT_TimeStamp& timestamp) {
+ NPT_UInt32 seconds;
+ NPT_Result res = ParseTimeStamp(in, seconds);
+ timestamp = NPT_TimeStamp((double)seconds);
+ return res;
+ }
+
+ static NPT_UInt64 ConvertFilterToMask(const NPT_String& filter);
+};
+
+#endif /* _PLT_DIDL_H_ */
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltFileMediaServer.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltFileMediaServer.cpp
new file mode 100644
index 0000000..421d0c2
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltFileMediaServer.cpp
@@ -0,0 +1,519 @@
+/*****************************************************************
+|
+| Platinum - File Media Server Delegate
+|
+| Copyright (c) 2004-2010, Plutinosoft, LLC.
+| All rights reserved.
+| http://www.plutinosoft.com
+|
+| This program is free software; you can redistribute it and/or
+| modify it under the terms of the GNU General Public License
+| as published by the Free Software Foundation; either version 2
+| of the License, or (at your option) any later version.
+|
+| OEMs, ISVs, VARs and other distributors that combine and
+| distribute commercially licensed software with Platinum software
+| and do not wish to distribute the source code for the commercially
+| licensed software under version 2, or (at your option) any later
+| version, of the GNU General Public License (the "GPL") must enter
+| into a commercial license agreement with Plutinosoft, LLC.
+| licensing@plutinosoft.com
+|
+| This program is distributed in the hope that it will be useful,
+| but WITHOUT ANY WARRANTY; without even the implied warranty of
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+| GNU General Public License for more details.
+|
+| You should have received a copy of the GNU General Public License
+| along with this program; see the file LICENSE.txt. If not, write to
+| the Free Software Foundation, Inc.,
+| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+| http://www.gnu.org/licenses/gpl-2.0.html
+|
+****************************************************************/
+
+/*----------------------------------------------------------------------
+| includes
++---------------------------------------------------------------------*/
+#include "PltUPnP.h"
+#include "PltFileMediaServer.h"
+#include "PltMediaItem.h"
+#include "PltService.h"
+#include "PltTaskManager.h"
+#include "PltHttpServer.h"
+#include "PltDidl.h"
+#include "PltVersion.h"
+#include "PltMimeType.h"
+
+NPT_SET_LOCAL_LOGGER("platinum.media.server.file.delegate")
+
+/*----------------------------------------------------------------------
+| PLT_FileMediaServerDelegate::PLT_FileMediaServerDelegate
++---------------------------------------------------------------------*/
+PLT_FileMediaServerDelegate::PLT_FileMediaServerDelegate(const char* url_root,
+ const char* file_root,
+ bool use_cache) :
+ m_UrlRoot(url_root),
+ m_FileRoot(file_root),
+ m_FilterUnknownOut(false),
+ m_UseCache(use_cache)
+{
+ /* Trim excess separators */
+ m_FileRoot.TrimRight("/\\");
+}
+
+/*----------------------------------------------------------------------
+| PLT_FileMediaServerDelegate::~PLT_FileMediaServerDelegate
++---------------------------------------------------------------------*/
+PLT_FileMediaServerDelegate::~PLT_FileMediaServerDelegate()
+{
+}
+
+/*----------------------------------------------------------------------
+| PLT_FileMediaServerDelegate::ProcessFileRequest
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_FileMediaServerDelegate::ProcessFileRequest(NPT_HttpRequest& request,
+ const NPT_HttpRequestContext& context,
+ NPT_HttpResponse& response)
+{
+ NPT_HttpUrlQuery query(request.GetUrl().GetQuery());
+
+ PLT_LOG_HTTP_REQUEST(NPT_LOG_LEVEL_FINE, "PLT_FileMediaServerDelegate::ProcessFileRequest:", &request);
+
+ if (request.GetMethod().Compare("GET") && request.GetMethod().Compare("HEAD")) {
+ response.SetStatus(500, "Internal Server Error");
+ return NPT_SUCCESS;
+ }
+
+ /* Extract file path from url */
+ NPT_String file_path;
+ NPT_CHECK_LABEL_WARNING(ExtractResourcePath(request.GetUrl(), file_path), failure);
+
+ /* Serve file */
+ NPT_CHECK_WARNING(ServeFile(request, context, response, NPT_FilePath::Create(m_FileRoot, file_path)));
+ return NPT_SUCCESS;
+
+failure:
+ response.SetStatus(404, "File Not Found");
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_FileMediaServerDelegate::ServeFile
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_FileMediaServerDelegate::ServeFile(const NPT_HttpRequest& request,
+ const NPT_HttpRequestContext& context,
+ NPT_HttpResponse& response,
+ const NPT_String& file_path)
+{
+ NPT_CHECK_WARNING(PLT_HttpServer::ServeFile(request, context, response, file_path));
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_FileMediaServerDelegate::OnBrowseMetadata
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_FileMediaServerDelegate::OnBrowseMetadata(PLT_ActionReference& action,
+ const char* object_id,
+ const char* filter,
+ NPT_UInt32 starting_index,
+ NPT_UInt32 requested_count,
+ const char* sort_criteria,
+ const PLT_HttpRequestContext& context)
+{
+ NPT_COMPILER_UNUSED(sort_criteria);
+ NPT_COMPILER_UNUSED(requested_count);
+ NPT_COMPILER_UNUSED(starting_index);
+
+ NPT_String didl;
+ PLT_MediaObjectReference item;
+
+ /* locate the file from the object ID */
+ NPT_String filepath;
+ if (NPT_FAILED(GetFilePath(object_id, filepath))) {
+ /* error */
+ NPT_LOG_WARNING("PLT_FileMediaServerDelegate::OnBrowse - ObjectID not found.");
+ action->SetError(701, "No Such Object.");
+ return NPT_FAILURE;
+ }
+
+ /* build the object didl */
+ item = BuildFromFilePath(filepath, context, true, false, (NPT_String(filter).Find("ALLIP")!=-1));
+ if (item.IsNull()) return NPT_FAILURE;
+ NPT_String tmp;
+ NPT_CHECK_SEVERE(PLT_Didl::ToDidl(*item.AsPointer(), filter, tmp));
+
+ /* add didl header and footer */
+ didl = didl_header + tmp + didl_footer;
+
+ NPT_CHECK_SEVERE(action->SetArgumentValue("Result", didl));
+ NPT_CHECK_SEVERE(action->SetArgumentValue("NumberReturned", "1"));
+ NPT_CHECK_SEVERE(action->SetArgumentValue("TotalMatches", "1"));
+
+ /* update ID may be wrong here, it should be the one of the container?
+ TODO: We need to keep track of the overall updateID of the CDS */
+ NPT_CHECK_SEVERE(action->SetArgumentValue("UpdateId", "1"));
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_FileMediaServerDelegate::OnBrowseDirectChildren
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_FileMediaServerDelegate::OnBrowseDirectChildren(PLT_ActionReference& action,
+ const char* object_id,
+ const char* filter,
+ NPT_UInt32 starting_index,
+ NPT_UInt32 requested_count,
+ const char* sort_criteria,
+ const PLT_HttpRequestContext& context)
+{
+ NPT_COMPILER_UNUSED(sort_criteria);
+
+ /* locate the file from the object ID */
+ NPT_String dir;
+ NPT_FileInfo info;
+ if (NPT_FAILED(GetFilePath(object_id, dir)) || NPT_FAILED(NPT_File::GetInfo(dir, &info)) || info.m_Type != NPT_FileInfo::FILE_TYPE_DIRECTORY) {
+ /* error */
+ NPT_LOG_WARNING_1("ObjectID \'%s\' not found or not allowed", object_id);
+ action->SetError(701, "No such Object");
+ NPT_CHECK_WARNING(NPT_FAILURE);
+ }
+
+ /* get uuid from device via action reference */
+ NPT_String uuid = action->GetActionDesc().GetService()->GetDevice()->GetUUID();
+
+ /* Try to get list from cache if allowed */
+ NPT_Result res;
+ NPT_Reference<NPT_List<NPT_String> > entries;
+ NPT_TimeStamp cached_entries_time;
+ if (!m_UseCache || NPT_FAILED(m_DirCache.Get(uuid, dir, entries, &cached_entries_time)) || cached_entries_time < info.m_ModificationTime) {
+ /* if not found in cache or if current dir has newer modified time fetch fresh new list from source */
+ entries = new NPT_List<NPT_String>();
+ res = NPT_File::ListDir(dir, *entries);
+ if (NPT_FAILED(res)) {
+ NPT_LOG_WARNING_1("PLT_FileMediaServerDelegate::OnBrowseDirectChildren - failed to open dir %s", (const char*) dir);
+ NPT_CHECK_WARNING(res);
+ }
+
+ /* sort results according to modification date */
+ res = entries->Sort(NPT_FileDateComparator(dir));
+ if (NPT_FAILED(res)) {
+ NPT_LOG_WARNING_1("PLT_FileMediaServerDelegate::OnBrowseDirectChildren - failed to open sort dir %s", (const char*) dir);
+ NPT_CHECK_WARNING(res);
+ }
+
+ /* add new list to cache */
+ if (m_UseCache) {
+ m_DirCache.Put(uuid, dir, entries, &info.m_ModificationTime);
+ }
+ }
+
+ unsigned long cur_index = 0;
+ unsigned long num_returned = 0;
+ unsigned long total_matches = 0;
+ NPT_String didl = didl_header;
+ bool allip = (NPT_String(filter).Find("ALLIP") != -1);
+
+ PLT_MediaObjectReference item;
+ for (NPT_List<NPT_String>::Iterator it = entries->GetFirstItem();
+ it;
+ ++it) {
+ NPT_String filepath = NPT_FilePath::Create(dir, *it);
+
+ /* verify we want to process this file first */
+ if (!ProcessFile(filepath, filter)) continue;
+
+ /* build item object from file path */
+ item = BuildFromFilePath(filepath,
+ context,
+ true,
+ false,
+ allip);
+
+ /* generate didl if within range requested */
+ if (!item.IsNull()) {
+ if ((cur_index >= starting_index) &&
+ ((num_returned < requested_count) || (requested_count == 0))) {
+ NPT_String tmp;
+ NPT_CHECK_SEVERE(PLT_Didl::ToDidl(*item.AsPointer(), filter, tmp));
+
+ didl += tmp;
+ ++num_returned;
+ }
+ ++cur_index;
+ ++total_matches;
+ }
+ };
+
+ didl += didl_footer;
+
+ NPT_LOG_FINE_6("BrowseDirectChildren from %s returning %d-%lu/%lu objects (%lu out of %d requested)",
+ (const char*)context.GetLocalAddress().GetIpAddress().ToString(),
+ starting_index, starting_index+num_returned, total_matches, num_returned, requested_count);
+
+ NPT_CHECK_SEVERE(action->SetArgumentValue("Result", didl));
+ NPT_CHECK_SEVERE(action->SetArgumentValue("NumberReturned", NPT_String::FromInteger(num_returned)));
+ NPT_CHECK_SEVERE(action->SetArgumentValue("TotalMatches", NPT_String::FromInteger(total_matches))); // 0 means we don't know how many we have but most browsers don't like that!!
+ NPT_CHECK_SEVERE(action->SetArgumentValue("UpdateId", "1"));
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_FileMediaServerDelegate::OnSearchContainer
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_FileMediaServerDelegate::OnSearchContainer(PLT_ActionReference& action,
+ const char* object_id,
+ const char* search_criteria,
+ const char* /* filter */,
+ NPT_UInt32 /* starting_index */,
+ NPT_UInt32 /* requested_count */,
+ const char* /* sort_criteria */,
+ const PLT_HttpRequestContext& /* context */)
+{
+ /* parse search criteria */
+
+ /* TODO: HACK TO PASS DLNA */
+ if (search_criteria && NPT_StringsEqual(search_criteria, "Unknownfieldname")) {
+ /* error */
+ NPT_LOG_WARNING_1("Unsupported or invalid search criteria %s", search_criteria);
+ action->SetError(708, "Unsupported or invalid search criteria");
+ return NPT_FAILURE;
+ }
+
+ /* locate the file from the object ID */
+ NPT_String dir;
+ if (NPT_FAILED(GetFilePath(object_id, dir))) {
+ /* error */
+ NPT_LOG_WARNING("ObjectID not found.");
+ action->SetError(710, "No Such Container.");
+ return NPT_FAILURE;
+ }
+
+ /* retrieve the item type */
+ NPT_FileInfo info;
+ NPT_Result res = NPT_File::GetInfo(dir, &info);
+ if (NPT_FAILED(res) || (info.m_Type != NPT_FileInfo::FILE_TYPE_DIRECTORY)) {
+ /* error */
+ NPT_LOG_WARNING("No such container");
+ action->SetError(710, "No such container");
+ return NPT_FAILURE;
+ }
+
+ return NPT_ERROR_NOT_IMPLEMENTED;
+}
+
+/*----------------------------------------------------------------------
+| PLT_FileMediaServerDelegate::GetFilePath
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_FileMediaServerDelegate::GetFilePath(const char* object_id,
+ NPT_String& filepath)
+{
+ if (!object_id) return NPT_ERROR_INVALID_PARAMETERS;
+
+ filepath = m_FileRoot;
+
+ /* object id is formatted as 0/<filepath> */
+ if (NPT_StringLength(object_id) >= 1) {
+ filepath += (object_id + (object_id[0]=='0'?1:0));
+ }
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_FileMediaServerDelegate::BuildSafeResourceUri
++---------------------------------------------------------------------*/
+NPT_String
+PLT_FileMediaServerDelegate::BuildSafeResourceUri(const NPT_HttpUrl& base_uri,
+ const char* host,
+ const char* file_path)
+{
+ NPT_String result;
+ NPT_HttpUrl uri = base_uri;
+
+ if (host) uri.SetHost(host);
+
+ NPT_String uri_path = uri.GetPath();
+ if (!uri_path.EndsWith("/")) uri_path += "/";
+
+ /* some controllers (like WMP) will call us with an already urldecoded version.
+ We're intentionally prepending a known urlencoded string
+ to detect it when we receive the request urlencoded or already decoded to avoid double decoding*/
+ uri_path += "%/";
+ uri_path += file_path;
+
+ /* set path */
+ uri.SetPath(uri_path);
+
+ /* 360 hack: force inclusion of port in case it's 80 */
+ return uri.ToStringWithDefaultPort(0);
+}
+
+/*----------------------------------------------------------------------
+| PLT_FileMediaServerDelegate::ExtractResourcePath
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_FileMediaServerDelegate::ExtractResourcePath(const NPT_HttpUrl& url,
+ NPT_String& file_path)
+{
+ /* Extract non decoded path, we need to autodetect urlencoding */
+ NPT_String uri_path = url.GetPath();
+ NPT_String url_root_encode = NPT_Uri::PercentEncode(m_UrlRoot, NPT_Uri::PathCharsToEncode);
+
+ NPT_Ordinal skip = 0;
+ if (uri_path.StartsWith(m_UrlRoot)) {
+ skip = m_UrlRoot.GetLength();
+ } else if (uri_path.StartsWith(url_root_encode)) {
+ skip = url_root_encode.GetLength();
+ } else {
+ return NPT_FAILURE;
+ }
+
+ /* account for extra slash */
+ skip += ((m_UrlRoot=="/")?0:1);
+ file_path = uri_path.SubString(skip);
+
+ /* detect if client such as WMP sent a non urlencoded url */
+ if (file_path.StartsWith("%/")) {
+ NPT_LOG_FINE("Received a urldecoded version of our url!");
+ file_path.Erase(0, 2);
+ } else {
+ /* remove our prepended string we used to detect urldecoded version */
+ if (file_path.StartsWith("%25/")) file_path.Erase(0, 4);
+
+ /* ok to urldecode */
+ file_path = NPT_Uri::PercentDecode(file_path);
+ }
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_FileMediaServerDelegate::BuildResourceUri
++---------------------------------------------------------------------*/
+NPT_String
+PLT_FileMediaServerDelegate::BuildResourceUri(const NPT_HttpUrl& base_uri,
+ const char* host,
+ const char* file_path)
+{
+ return BuildSafeResourceUri(base_uri, host, file_path);
+}
+
+/*----------------------------------------------------------------------
+| PLT_FileMediaServerDelegate::BuildFromFilePath
++---------------------------------------------------------------------*/
+PLT_MediaObject*
+PLT_FileMediaServerDelegate::BuildFromFilePath(const NPT_String& filepath,
+ const PLT_HttpRequestContext& context,
+ bool with_count /* = true */,
+ bool keep_extension_in_title /* = false */,
+ bool allip /* = false */)
+{
+ NPT_String root = m_FileRoot;
+ PLT_MediaItemResource resource;
+ PLT_MediaObject* object = NULL;
+
+ NPT_LOG_FINEST_1("Building didl for file '%s'", (const char*)filepath);
+
+ /* retrieve the entry type (directory or file) */
+ NPT_FileInfo info;
+ NPT_CHECK_LABEL_FATAL(NPT_File::GetInfo(filepath, &info), failure);
+
+ if (info.m_Type == NPT_FileInfo::FILE_TYPE_REGULAR) {
+ object = new PLT_MediaItem();
+
+ /* Set the title using the filename for now */
+ object->m_Title = NPT_FilePath::BaseName(filepath, keep_extension_in_title);
+ if (object->m_Title.GetLength() == 0) goto failure;
+
+ /* make sure we return something with a valid mimetype */
+ if (m_FilterUnknownOut &&
+ NPT_StringsEqual(PLT_MimeType::GetMimeType(filepath, &context),
+ "application/octet-stream")) {
+ goto failure;
+ }
+
+ /* Set the protocol Info from the extension */
+ resource.m_ProtocolInfo = PLT_ProtocolInfo::GetProtocolInfo(filepath, true, &context);
+ if (!resource.m_ProtocolInfo.IsValid()) goto failure;
+
+ /* Set the resource file size */
+ resource.m_Size = info.m_Size;
+
+ /* format the resource URI */
+ NPT_String url = filepath.SubString(root.GetLength()+1);
+
+ // get list of ip addresses
+ NPT_List<NPT_IpAddress> ips;
+ NPT_CHECK_LABEL_SEVERE(PLT_UPnPMessageHelper::GetIPAddresses(ips), failure);
+
+ /* if we're passed an interface where we received the request from
+ move the ip to the top so that it is used for the first resource */
+ if (context.GetLocalAddress().GetIpAddress().ToString() != "0.0.0.0") {
+ ips.Remove(context.GetLocalAddress().GetIpAddress());
+ ips.Insert(ips.GetFirstItem(), context.GetLocalAddress().GetIpAddress());
+ } else if (!allip) {
+ NPT_LOG_WARNING("Couldn't determine local interface IP so we might return an unreachable IP");
+ }
+ object->m_ObjectClass.type = PLT_MediaItem::GetUPnPClass(filepath, &context);
+
+ /* add as many resources as we have interfaces s*/
+ NPT_HttpUrl base_uri("127.0.0.1", context.GetLocalAddress().GetPort(), NPT_HttpUrl::PercentEncode(m_UrlRoot, NPT_Uri::PathCharsToEncode));
+ NPT_List<NPT_IpAddress>::Iterator ip = ips.GetFirstItem();
+ while (ip) {
+ resource.m_Uri = BuildResourceUri(base_uri, ip->ToString(), url);
+ object->m_Resources.Add(resource);
+ ++ip;
+
+ /* if we only want the one resource reachable by client */
+ if (!allip) break;
+ }
+ } else {
+ object = new PLT_MediaContainer;
+
+ /* Assign a title for this container */
+ if (filepath.Compare(root, true) == 0) {
+ object->m_Title = "Root";
+ } else {
+ object->m_Title = NPT_FilePath::BaseName(filepath, keep_extension_in_title);
+ if (object->m_Title.GetLength() == 0) goto failure;
+ }
+
+ /* Get the number of children for this container */
+ NPT_LargeSize count = 0;
+ if (with_count && NPT_SUCCEEDED(NPT_File::GetSize(filepath, count))) {
+ ((PLT_MediaContainer*)object)->m_ChildrenCount = (NPT_Int32)count;
+ }
+
+ object->m_ObjectClass.type = "object.container.storageFolder";
+ }
+
+ /* is it the root? */
+ if (filepath.Compare(root, true) == 0) {
+ object->m_ParentID = "-1";
+ object->m_ObjectID = "0";
+ } else {
+ NPT_String directory = NPT_FilePath::DirName(filepath);
+ /* is the parent path the root? */
+ if (directory.GetLength() == root.GetLength()) {
+ object->m_ParentID = "0";
+ } else {
+ object->m_ParentID = "0" + filepath.SubString(root.GetLength(), directory.GetLength() - root.GetLength());
+ }
+ object->m_ObjectID = "0" + filepath.SubString(root.GetLength());
+ }
+
+ return object;
+
+failure:
+ delete object;
+ return NULL;
+}
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltFileMediaServer.h b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltFileMediaServer.h
new file mode 100644
index 0000000..fa4b5e4
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltFileMediaServer.h
@@ -0,0 +1,151 @@
+/*****************************************************************
+|
+| Platinum - File Media Server
+|
+| Copyright (c) 2004-2010, Plutinosoft, LLC.
+| All rights reserved.
+| http://www.plutinosoft.com
+|
+| This program is free software; you can redistribute it and/or
+| modify it under the terms of the GNU General Public License
+| as published by the Free Software Foundation; either version 2
+| of the License, or (at your option) any later version.
+|
+| OEMs, ISVs, VARs and other distributors that combine and
+| distribute commercially licensed software with Platinum software
+| and do not wish to distribute the source code for the commercially
+| licensed software under version 2, or (at your option) any later
+| version, of the GNU General Public License (the "GPL") must enter
+| into a commercial license agreement with Plutinosoft, LLC.
+| licensing@plutinosoft.com
+|
+| This program is distributed in the hope that it will be useful,
+| but WITHOUT ANY WARRANTY; without even the implied warranty of
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+| GNU General Public License for more details.
+|
+| You should have received a copy of the GNU General Public License
+| along with this program; see the file LICENSE.txt. If not, write to
+| the Free Software Foundation, Inc.,
+| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+| http://www.gnu.org/licenses/gpl-2.0.html
+|
+****************************************************************/
+
+/** @file
+ UPnP AV Filesystem based Media Server sample implementation
+ */
+
+#ifndef _PLT_FILE_MEDIA_SERVER_H_
+#define _PLT_FILE_MEDIA_SERVER_H_
+
+/*----------------------------------------------------------------------
+| includes
++---------------------------------------------------------------------*/
+#include "Neptune.h"
+#include "PltMediaServer.h"
+#include "PltMediaCache.h"
+
+/*----------------------------------------------------------------------
+| PLT_FileMediaServerDelegate
++---------------------------------------------------------------------*/
+/**
+ File Media Server Delegate.
+ The PLT_FileMediaServerDelegate class is an example of a PLT_MediaServerDelegate
+ implementation for a file system backed Media Server.
+ */
+class PLT_FileMediaServerDelegate : public PLT_MediaServerDelegate
+{
+public:
+ // class methods
+ static NPT_String BuildSafeResourceUri(const NPT_HttpUrl& base_uri,
+ const char* host,
+ const char* file_path);
+ // constructor & destructor
+ PLT_FileMediaServerDelegate(const char* url_root, const char* file_root, bool use_cache = false);
+ ~PLT_FileMediaServerDelegate() override;
+
+protected:
+ // PLT_MediaServerDelegate methods
+ NPT_Result OnBrowseMetadata(PLT_ActionReference& action,
+ const char* object_id,
+ const char* filter,
+ NPT_UInt32 starting_index,
+ NPT_UInt32 requested_count,
+ const char* sort_criteria,
+ const PLT_HttpRequestContext& context) override;
+ NPT_Result OnBrowseDirectChildren(PLT_ActionReference& action,
+ const char* object_id,
+ const char* filter,
+ NPT_UInt32 starting_index,
+ NPT_UInt32 requested_count,
+ const char* sort_criteria,
+ const PLT_HttpRequestContext& context) override;
+ NPT_Result OnSearchContainer(PLT_ActionReference& action,
+ const char* object_id,
+ const char* search_criteria,
+ const char* filter,
+ NPT_UInt32 starting_index,
+ NPT_UInt32 requested_count,
+ const char* sort_criteria,
+ const PLT_HttpRequestContext& context) override;
+ NPT_Result ProcessFileRequest(NPT_HttpRequest& request,
+ const NPT_HttpRequestContext& context,
+ NPT_HttpResponse& response) override;
+
+ // overridable methods
+ virtual NPT_Result ExtractResourcePath(const NPT_HttpUrl& url, NPT_String& file_path);
+ virtual NPT_String BuildResourceUri(const NPT_HttpUrl& base_uri, const char* host, const char* file_path);
+ virtual NPT_Result ServeFile(const NPT_HttpRequest& request,
+ const NPT_HttpRequestContext& context,
+ NPT_HttpResponse& response,
+ const NPT_String& file_path);
+ virtual NPT_Result GetFilePath(const char* object_id, NPT_String& filepath);
+ virtual bool ProcessFile(const NPT_String&, const char* filter = NULL) { NPT_COMPILER_UNUSED(filter); return true;}
+ virtual PLT_MediaObject* BuildFromFilePath(const NPT_String& filepath,
+ const PLT_HttpRequestContext& context,
+ bool with_count = true,
+ bool keep_extension_in_title = false,
+ bool allip = false);
+
+protected:
+ friend class PLT_MediaItem;
+
+ NPT_String m_UrlRoot;
+ NPT_String m_FileRoot;
+ bool m_FilterUnknownOut;
+ bool m_UseCache;
+
+ PLT_MediaCache<NPT_Reference<NPT_List<NPT_String> >, NPT_TimeStamp> m_DirCache;
+};
+
+/*----------------------------------------------------------------------
+| PLT_FileMediaServer
++---------------------------------------------------------------------*/
+/**
+ File Media Server.
+ The PLT_FileMediaServer class is an example of a PLT_MediaServer implementation
+ for a file system backed Media Server.
+ */
+class PLT_FileMediaServer : public PLT_MediaServer,
+ public PLT_FileMediaServerDelegate
+{
+public: // constructor
+ PLT_FileMediaServer(const char* file_root,
+ const char* friendly_name,
+ bool show_ip = false,
+ const char* uuid = NULL,
+ NPT_UInt16 port = 0,
+ bool port_rebind = false) :
+ PLT_MediaServer(friendly_name,
+ show_ip,
+ uuid,
+ port,
+ port_rebind),
+ PLT_FileMediaServerDelegate("/", file_root) {SetDelegate(this);}
+
+protected:
+ ~PLT_FileMediaServer() override {}
+};
+
+#endif /* _PLT_FILE_MEDIA_SERVER_H_ */
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaBrowser.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaBrowser.cpp
new file mode 100644
index 0000000..2478441
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaBrowser.cpp
@@ -0,0 +1,571 @@
+/*****************************************************************
+|
+| Platinum - AV Media Browser (Media Server Control Point)
+|
+| Copyright (c) 2004-2010, Plutinosoft, LLC.
+| All rights reserved.
+| http://www.plutinosoft.com
+|
+| This program is free software; you can redistribute it and/or
+| modify it under the terms of the GNU General Public License
+| as published by the Free Software Foundation; either version 2
+| of the License, or (at your option) any later version.
+|
+| OEMs, ISVs, VARs and other distributors that combine and
+| distribute commercially licensed software with Platinum software
+| and do not wish to distribute the source code for the commercially
+| licensed software under version 2, or (at your option) any later
+| version, of the GNU General Public License (the "GPL") must enter
+| into a commercial license agreement with Plutinosoft, LLC.
+| licensing@plutinosoft.com
+|
+| This program is distributed in the hope that it will be useful,
+| but WITHOUT ANY WARRANTY; without even the implied warranty of
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+| GNU General Public License for more details.
+|
+| You should have received a copy of the GNU General Public License
+| along with this program; see the file LICENSE.txt. If not, write to
+| the Free Software Foundation, Inc.,
+| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+| http://www.gnu.org/licenses/gpl-2.0.html
+|
+****************************************************************/
+
+/*----------------------------------------------------------------------
+| includes
++---------------------------------------------------------------------*/
+#include "Neptune.h"
+#include "PltMediaBrowser.h"
+#include "PltDidl.h"
+
+NPT_SET_LOCAL_LOGGER("platinum.media.server.browser")
+
+/*----------------------------------------------------------------------
+| PLT_MediaBrowser::PLT_MediaBrowser
++---------------------------------------------------------------------*/
+PLT_MediaBrowser::PLT_MediaBrowser(PLT_CtrlPointReference& ctrl_point,
+ PLT_MediaBrowserDelegate* delegate /* = NULL */) :
+ m_CtrlPoint(ctrl_point),
+ m_Delegate(delegate)
+{
+ m_CtrlPoint->AddListener(this);
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaBrowser::~PLT_MediaBrowser
++---------------------------------------------------------------------*/
+PLT_MediaBrowser::~PLT_MediaBrowser()
+{
+ m_CtrlPoint->RemoveListener(this);
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaBrowser::OnDeviceAdded
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaBrowser::OnDeviceAdded(PLT_DeviceDataReference& device)
+{
+ // verify the device implements the function we need
+ PLT_Service* serviceCDS;
+ PLT_Service* serviceCMR;
+ NPT_String type;
+
+ if (!device->GetType().StartsWith("urn:schemas-upnp-org:device:MediaServer"))
+ return NPT_FAILURE;
+
+ type = "urn:schemas-upnp-org:service:ContentDirectory:*";
+ if (NPT_FAILED(device->FindServiceByType(type, serviceCDS))) {
+ NPT_LOG_WARNING_2("Service %s not found in device \"%s\"",
+ type.GetChars(),
+ device->GetFriendlyName().GetChars());
+ return NPT_FAILURE;
+ } else {
+ // in case it's a newer upnp implementation, force to 1
+ serviceCDS->ForceVersion(1);
+ }
+
+ type = "urn:schemas-upnp-org:service:ConnectionManager:*";
+ if (NPT_FAILED(device->FindServiceByType(type, serviceCMR))) {
+ NPT_LOG_WARNING_2("Service %s not found in device \"%s\"",
+ type.GetChars(),
+ device->GetFriendlyName().GetChars());
+ return NPT_FAILURE;
+ } else {
+ // in case it's a newer upnp implementation, force to 1
+ serviceCMR->ForceVersion(1);
+ }
+
+ {
+ NPT_AutoLock lock(m_MediaServers);
+
+ PLT_DeviceDataReference data;
+ NPT_String uuid = device->GetUUID();
+
+ // is it a new device?
+ if (NPT_SUCCEEDED(NPT_ContainerFind(m_MediaServers, PLT_DeviceDataFinder(uuid), data))) {
+ NPT_LOG_WARNING_1("Device (%s) is already in our list!", (const char*)uuid);
+ return NPT_FAILURE;
+ }
+
+ NPT_LOG_FINE_1("Device Found: %s", (const char*)*device);
+
+ m_MediaServers.Add(device);
+ }
+
+ if (m_Delegate && m_Delegate->OnMSAdded(device)) {
+ m_CtrlPoint->Subscribe(serviceCDS);
+ m_CtrlPoint->Subscribe(serviceCMR);
+ }
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaBrowser::OnDeviceRemoved
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaBrowser::OnDeviceRemoved(PLT_DeviceDataReference& device)
+{
+ if (!device->GetType().StartsWith("urn:schemas-upnp-org:device:MediaServer"))
+ return NPT_FAILURE;
+
+ {
+ NPT_AutoLock lock(m_MediaServers);
+
+ // only release if we have kept it around
+ PLT_DeviceDataReference data;
+ NPT_String uuid = device->GetUUID();
+
+ // Have we seen that device?
+ if (NPT_FAILED(NPT_ContainerFind(m_MediaServers, PLT_DeviceDataFinder(uuid), data))) {
+ NPT_LOG_WARNING_1("Device (%s) not found in our list!", (const char*)uuid);
+ return NPT_FAILURE;
+ }
+
+ NPT_LOG_FINE_1("Device Removed: %s", (const char*)*device);
+
+ m_MediaServers.Remove(device);
+ }
+
+ if (m_Delegate) {
+ m_Delegate->OnMSRemoved(device);
+ }
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaBrowser::FindServer
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaBrowser::FindServer(const char* uuid, PLT_DeviceDataReference& device)
+{
+ NPT_AutoLock lock(m_MediaServers);
+
+ if (NPT_FAILED(NPT_ContainerFind(m_MediaServers, PLT_DeviceDataFinder(uuid), device))) {
+ NPT_LOG_FINE_1("Device (%s) not found in our list of servers", (const char*)uuid);
+ return NPT_FAILURE;
+ }
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaBrowser::Search
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaBrowser::Search(PLT_DeviceDataReference& device,
+ const char* container_id,
+ const char* search_criteria,
+ NPT_UInt32 start_index,
+ NPT_UInt32 count,
+ const char* filter,
+ void* userdata)
+{
+ // verify device still in our list
+ PLT_DeviceDataReference device_data;
+ NPT_CHECK_WARNING(FindServer(device->GetUUID(), device_data));
+
+ // create action
+ PLT_ActionReference action;
+ NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction(
+ device,
+ "urn:schemas-upnp-org:service:ContentDirectory:1",
+ "Search",
+ action));
+
+ // Set the container id
+ PLT_Arguments args;
+ if (NPT_FAILED(action->SetArgumentValue("ContainerID", container_id))) {
+ return NPT_ERROR_INVALID_PARAMETERS;
+ }
+
+ // set the Search Criteria
+ if (NPT_FAILED(action->SetArgumentValue("SearchCriteria", search_criteria))) {
+ return NPT_ERROR_INVALID_PARAMETERS;
+ }
+
+
+ // set the Filter
+ if (NPT_FAILED(action->SetArgumentValue("Filter", filter))) {
+ return NPT_ERROR_INVALID_PARAMETERS;
+ }
+
+ // set the Starting Index
+ if (NPT_FAILED(action->SetArgumentValue("StartingIndex",
+ NPT_String::FromInteger(start_index)))) {
+ return NPT_ERROR_INVALID_PARAMETERS;
+ }
+
+ // set the Requested Count
+ if (NPT_FAILED(action->SetArgumentValue("RequestedCount",
+ NPT_String::FromInteger(count)))) {
+ return NPT_ERROR_INVALID_PARAMETERS;
+ }
+
+ // set the Requested Count
+ if (NPT_FAILED(action->SetArgumentValue("SortCriteria", ""))) {
+ return NPT_ERROR_INVALID_PARAMETERS;
+ }
+
+ // invoke the action
+ if (NPT_FAILED(m_CtrlPoint->InvokeAction(action, userdata))) {
+ return NPT_ERROR_INVALID_PARAMETERS;
+ }
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaBrowser::Browse
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaBrowser::Browse(PLT_DeviceDataReference& device,
+ const char* obj_id,
+ NPT_UInt32 start_index,
+ NPT_UInt32 count,
+ bool browse_metadata,
+ const char* filter,
+ const char* sort_criteria,
+ void* userdata)
+{
+ // verify device still in our list
+ PLT_DeviceDataReference device_data;
+ NPT_CHECK_WARNING(FindServer(device->GetUUID(), device_data));
+
+ // create action
+ PLT_ActionReference action;
+ NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction(
+ device,
+ "urn:schemas-upnp-org:service:ContentDirectory:1",
+ "Browse",
+ action));
+
+ // Set the object id
+ PLT_Arguments args;
+ if (NPT_FAILED(action->SetArgumentValue("ObjectID", obj_id))) {
+ return NPT_ERROR_INVALID_PARAMETERS;
+ }
+
+ // set the browse_flag
+ if (NPT_FAILED(action->SetArgumentValue("BrowseFlag",
+ browse_metadata?"BrowseMetadata":"BrowseDirectChildren"))) {
+ return NPT_ERROR_INVALID_PARAMETERS;
+ }
+
+ // set the Filter
+ if (NPT_FAILED(action->SetArgumentValue("Filter", filter))) {
+ return NPT_ERROR_INVALID_PARAMETERS;
+ }
+
+ // set the Starting Index
+ if (NPT_FAILED(action->SetArgumentValue("StartingIndex",
+ NPT_String::FromInteger(start_index)))) {
+ return NPT_ERROR_INVALID_PARAMETERS;
+ }
+
+ // set the Requested Count
+ if (NPT_FAILED(action->SetArgumentValue("RequestedCount",
+ NPT_String::FromInteger(count)))) {
+ return NPT_ERROR_INVALID_PARAMETERS;
+ }
+
+ // set the Requested Count
+ if (NPT_FAILED(action->SetArgumentValue("SortCriteria", sort_criteria))) {
+ return NPT_ERROR_INVALID_PARAMETERS;
+ }
+
+ // invoke the action
+ if (NPT_FAILED(m_CtrlPoint->InvokeAction(action, userdata))) {
+ return NPT_ERROR_INVALID_PARAMETERS;
+ }
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaBrowser::GetSearchCapabilities
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaBrowser::GetSearchCapabilities(PLT_DeviceDataReference& device,
+ void* userdata)
+{
+ // verify device still in our list
+ PLT_DeviceDataReference device_data;
+ NPT_CHECK_WARNING(FindServer(device->GetUUID(), device_data));
+
+ // create action
+ PLT_ActionReference action;
+ NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction(
+ device,
+ "urn:schemas-upnp-org:service:ContentDirectory:1",
+ "GetSearchCapabilities",
+ action));
+
+ // invoke the action
+ if (NPT_FAILED(m_CtrlPoint->InvokeAction(action, userdata))) {
+ return NPT_ERROR_INVALID_PARAMETERS;
+ }
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaBrowser::GetSortCapabilities
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaBrowser::GetSortCapabilities(PLT_DeviceDataReference& device,
+ void* userdata)
+{
+ // verify device still in our list
+ PLT_DeviceDataReference device_data;
+ NPT_CHECK_WARNING(FindServer(device->GetUUID(), device_data));
+
+ // create action
+ PLT_ActionReference action;
+ NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction(
+ device,
+ "urn:schemas-upnp-org:service:ContentDirectory:1",
+ "GetSortCapabilities",
+ action));
+
+ // invoke the action
+ if (NPT_FAILED(m_CtrlPoint->InvokeAction(action, userdata))) {
+ return NPT_ERROR_INVALID_PARAMETERS;
+ }
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaBrowser::OnActionResponse
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaBrowser::OnActionResponse(NPT_Result res,
+ PLT_ActionReference& action,
+ void* userdata)
+{
+ // look for device in our list first
+ PLT_DeviceDataReference device;
+ NPT_String uuid = action->GetActionDesc().GetService()->GetDevice()->GetUUID();
+ if (NPT_FAILED(FindServer(uuid, device))) res = NPT_FAILURE;
+
+ NPT_String actionName = action->GetActionDesc().GetName();
+ if (actionName.Compare("Browse", true) == 0) {
+ return OnBrowseResponse(res, device, action, userdata);
+ } else if (actionName.Compare("Search", true) == 0) {
+ return OnSearchResponse(res, device, action, userdata);
+ } else if (actionName.Compare("GetSearchCapabilities", true) == 0) {
+ return OnGetSearchCapabilitiesResponse(res, device, action, userdata);
+ } else if (actionName.Compare("GetSortCapabilities", true) == 0) {
+ return OnGetSortCapabilitiesResponse(res, device, action, userdata);
+ }
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaBrowser::OnBrowseResponse
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaBrowser::OnBrowseResponse(NPT_Result res,
+ PLT_DeviceDataReference& device,
+ PLT_ActionReference& action,
+ void* userdata)
+{
+ NPT_String value;
+ PLT_BrowseInfo info;
+ NPT_String unescaped;
+
+ if (!m_Delegate) return NPT_SUCCESS;
+
+ if (NPT_FAILED(res) || action->GetErrorCode() != 0) {
+ goto bad_action;
+ }
+
+ if (NPT_FAILED(action->GetArgumentValue("ObjectID", info.object_id))) {
+ goto bad_action;
+ }
+ if (NPT_FAILED(action->GetArgumentValue("UpdateID", value)) ||
+ value.GetLength() == 0 ||
+ NPT_FAILED(value.ToInteger(info.uid))) {
+ goto bad_action;
+ }
+ if (NPT_FAILED(action->GetArgumentValue("NumberReturned", value)) ||
+ value.GetLength() == 0 ||
+ NPT_FAILED(value.ToInteger(info.nr))) {
+ goto bad_action;
+ }
+ if (NPT_FAILED(action->GetArgumentValue("TotalMatches", value)) ||
+ value.GetLength() == 0 ||
+ NPT_FAILED(value.ToInteger(info.tm))) {
+ goto bad_action;
+ }
+ if (NPT_FAILED(action->GetArgumentValue("Result", value)) ||
+ value.GetLength() == 0) {
+ goto bad_action;
+ }
+
+ if (NPT_FAILED(PLT_Didl::FromDidl(value, info.items))) {
+ goto bad_action;
+ }
+
+ m_Delegate->OnBrowseResult(NPT_SUCCESS, device, &info, userdata);
+ return NPT_SUCCESS;
+
+bad_action:
+ m_Delegate->OnBrowseResult(NPT_FAILURE, device, NULL, userdata);
+ return NPT_FAILURE;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaBrowser::OnSearchResponse
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaBrowser::OnSearchResponse(NPT_Result res,
+ PLT_DeviceDataReference& device,
+ PLT_ActionReference& action,
+ void* userdata)
+{
+ NPT_String value;
+ PLT_BrowseInfo info;
+ NPT_String unescaped;
+
+ if (!m_Delegate) return NPT_SUCCESS;
+
+ if (NPT_FAILED(res) || action->GetErrorCode() != 0) {
+ goto bad_action;
+ }
+
+ if (NPT_FAILED(action->GetArgumentValue("ContainerId", info.object_id))) {
+ goto bad_action;
+ }
+ if (NPT_FAILED(action->GetArgumentValue("UpdateID", value)) ||
+ value.GetLength() == 0 ||
+ NPT_FAILED(value.ToInteger(info.uid))) {
+ goto bad_action;
+ }
+ if (NPT_FAILED(action->GetArgumentValue("NumberReturned", value)) ||
+ value.GetLength() == 0 ||
+ NPT_FAILED(value.ToInteger(info.nr))) {
+ goto bad_action;
+ }
+ if (NPT_FAILED(action->GetArgumentValue("TotalMatches", value)) ||
+ value.GetLength() == 0 ||
+ NPT_FAILED(value.ToInteger(info.tm))) {
+ goto bad_action;
+ }
+ if (NPT_FAILED(action->GetArgumentValue("Result", value)) ||
+ value.GetLength() == 0) {
+ goto bad_action;
+ }
+
+ if (NPT_FAILED(PLT_Didl::FromDidl(value, info.items))) {
+ goto bad_action;
+ }
+
+ m_Delegate->OnSearchResult(NPT_SUCCESS, device, &info, userdata);
+ return NPT_SUCCESS;
+
+bad_action:
+ m_Delegate->OnSearchResult(NPT_FAILURE, device, NULL, userdata);
+ return NPT_FAILURE;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaBrowser::OnGetSearchCapabilitiesResponse
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaBrowser::OnGetSearchCapabilitiesResponse(NPT_Result res,
+ PLT_DeviceDataReference& device,
+ PLT_ActionReference& action,
+ void* userdata)
+{
+ NPT_String value;
+
+ if (!m_Delegate) return NPT_SUCCESS;
+
+ if (NPT_FAILED(res) || action->GetErrorCode() != 0) {
+ goto bad_action;
+ }
+
+ if (NPT_FAILED(action->GetArgumentValue("SearchCaps", value))) {
+ goto bad_action;
+ }
+
+ m_Delegate->OnGetSearchCapabilitiesResult(NPT_SUCCESS, device, value, userdata);
+ return NPT_SUCCESS;
+
+bad_action:
+ m_Delegate->OnGetSearchCapabilitiesResult(NPT_FAILURE, device, value, userdata);
+ return NPT_FAILURE;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaBrowser::OnGetSearchCapabilitiesResponse
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaBrowser::OnGetSortCapabilitiesResponse(NPT_Result res,
+ PLT_DeviceDataReference& device,
+ PLT_ActionReference& action,
+ void* userdata)
+{
+ NPT_String value;
+
+ if (!m_Delegate) return NPT_SUCCESS;
+
+ if (NPT_FAILED(res) || action->GetErrorCode() != 0) {
+ goto bad_action;
+ }
+
+ if (NPT_FAILED(action->GetArgumentValue("SortCaps", value))) {
+ goto bad_action;
+ }
+
+ m_Delegate->OnGetSortCapabilitiesResult(NPT_SUCCESS, device, value, userdata);
+ return NPT_SUCCESS;
+
+bad_action:
+ m_Delegate->OnGetSortCapabilitiesResult(NPT_FAILURE, device, value, userdata);
+ return NPT_FAILURE;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaBrowser::OnEventNotify
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaBrowser::OnEventNotify(PLT_Service* service, NPT_List<PLT_StateVariable*>* vars)
+{
+ if (!service->GetDevice()->GetType().StartsWith("urn:schemas-upnp-org:device:MediaServer"))
+ return NPT_FAILURE;
+
+ if (!m_Delegate) return NPT_SUCCESS;
+
+ /* make sure device associated to service is still around */
+ PLT_DeviceDataReference data;
+ NPT_CHECK_WARNING(FindServer(service->GetDevice()->GetUUID(), data));
+
+ m_Delegate->OnMSStateVariablesChanged(service, vars);
+ return NPT_SUCCESS;
+}
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaBrowser.h b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaBrowser.h
new file mode 100644
index 0000000..2484dcc
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaBrowser.h
@@ -0,0 +1,184 @@
+/*****************************************************************
+|
+| Platinum - AV Media Browser (Media Server Control Point)
+|
+| Copyright (c) 2004-2010, Plutinosoft, LLC.
+| All rights reserved.
+| http://www.plutinosoft.com
+|
+| This program is free software; you can redistribute it and/or
+| modify it under the terms of the GNU General Public License
+| as published by the Free Software Foundation; either version 2
+| of the License, or (at your option) any later version.
+|
+| OEMs, ISVs, VARs and other distributors that combine and
+| distribute commercially licensed software with Platinum software
+| and do not wish to distribute the source code for the commercially
+| licensed software under version 2, or (at your option) any later
+| version, of the GNU General Public License (the "GPL") must enter
+| into a commercial license agreement with Plutinosoft, LLC.
+| licensing@plutinosoft.com
+|
+| This program is distributed in the hope that it will be useful,
+| but WITHOUT ANY WARRANTY; without even the implied warranty of
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+| GNU General Public License for more details.
+|
+| You should have received a copy of the GNU General Public License
+| along with this program; see the file LICENSE.txt. If not, write to
+| the Free Software Foundation, Inc.,
+| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+| http://www.gnu.org/licenses/gpl-2.0.html
+|
+****************************************************************/
+
+/** @file
+ UPnP AV Media Controller implementation.
+ */
+
+#ifndef _PLT_MEDIA_BROWSER_H_
+#define _PLT_MEDIA_BROWSER_H_
+
+/*----------------------------------------------------------------------
+| includes
++---------------------------------------------------------------------*/
+#include "PltCtrlPoint.h"
+#include "PltMediaItem.h"
+
+/*----------------------------------------------------------------------
+| PLT_BrowseInfo
++---------------------------------------------------------------------*/
+/**
+ The PLT_BrowseInfo struct is used to marshall Browse or Search action
+ response results across different threads of execution.
+ */
+typedef struct {
+ NPT_String object_id;
+ PLT_MediaObjectListReference items;
+ NPT_UInt32 si;
+ NPT_UInt32 nr;
+ NPT_UInt32 tm;
+ NPT_UInt32 uid;
+} PLT_BrowseInfo;
+
+/*----------------------------------------------------------------------
+| PLT_MediaBrowserDelegate
++---------------------------------------------------------------------*/
+/**
+ The PLT_MediaBrowserDelegate class is an interface for receiving PLT_MediaBrowser
+ events or action responses.
+ */
+class PLT_MediaBrowserDelegate
+{
+public:
+ virtual ~PLT_MediaBrowserDelegate() {}
+
+ virtual bool OnMSAdded(PLT_DeviceDataReference& /* device */) { return true; }
+ virtual void OnMSRemoved(PLT_DeviceDataReference& /* device */) {}
+ virtual void OnMSStateVariablesChanged(
+ PLT_Service* /*service*/,
+ NPT_List<PLT_StateVariable*>* /*vars*/) {}
+
+ // ContentDirectory
+ virtual void OnBrowseResult(
+ NPT_Result /*res*/,
+ PLT_DeviceDataReference& /*device*/,
+ PLT_BrowseInfo* /*info*/,
+ void* /*userdata*/) {}
+
+ virtual void OnSearchResult(
+ NPT_Result /*res*/,
+ PLT_DeviceDataReference& /*device*/,
+ PLT_BrowseInfo* /*info*/,
+ void* /*userdata*/) {}
+
+ virtual void OnGetSearchCapabilitiesResult(
+ NPT_Result /*res*/,
+ PLT_DeviceDataReference& /*device*/,
+ NPT_String /*searchCapabilities*/,
+ void* /*userdata*/) {}
+
+ virtual void OnGetSortCapabilitiesResult(
+ NPT_Result /*res*/,
+ PLT_DeviceDataReference& /*device*/,
+ NPT_String /*sortCapabilities*/,
+ void* /*userdata*/) {}
+};
+
+/*----------------------------------------------------------------------
+| PLT_MediaBrowser
++---------------------------------------------------------------------*/
+/**
+ The PLT_MediaBrowser class implements a UPnP AV Media Server control point.
+ */
+class PLT_MediaBrowser : public PLT_CtrlPointListener
+{
+public:
+ PLT_MediaBrowser(PLT_CtrlPointReference& ctrl_point,
+ PLT_MediaBrowserDelegate* delegate = NULL);
+ ~PLT_MediaBrowser() override;
+
+ // ContentDirectory service
+ virtual NPT_Result Browse(PLT_DeviceDataReference& device,
+ const char* object_id,
+ NPT_UInt32 start_index,
+ NPT_UInt32 count = 30, // DLNA recommendations
+ bool browse_metadata = false,
+ const char* filter = "dc:date,upnp:genre,res,res@duration,res@size,upnp:albumArtURI,upnp:originalTrackNumber,upnp:album,upnp:artist,upnp:author", // explicitely specify res otherwise WMP won't return a URL!
+ const char* sort_criteria = "",
+ void* userdata = NULL);
+
+ virtual NPT_Result Search(PLT_DeviceDataReference& device,
+ const char* container_id,
+ const char* search_criteria,
+ NPT_UInt32 start_index,
+ NPT_UInt32 count = 30, // DLNA recommendations
+ const char* filter = "dc:date,upnp:genre,res,res@duration,res@size,upnp:albumArtURI,upnp:originalTrackNumber,upnp:album,upnp:artist,upnp:author", // explicitely specify res otherwise WMP won't return a URL!
+ void* userdata = NULL);
+
+ virtual NPT_Result GetSearchCapabilities(PLT_DeviceDataReference& device,
+ void* userdata = NULL);
+
+ virtual NPT_Result GetSortCapabilities(PLT_DeviceDataReference& device,
+ void* userdata = NULL);
+
+ // methods
+ virtual const NPT_Lock<PLT_DeviceDataReferenceList>& GetMediaServers() { return m_MediaServers; }
+ virtual NPT_Result FindServer(const char* uuid, PLT_DeviceDataReference& device);
+ virtual void SetDelegate(PLT_MediaBrowserDelegate* delegate) { m_Delegate = delegate; }
+
+protected:
+ // PLT_CtrlPointListener methods
+ NPT_Result OnDeviceAdded(PLT_DeviceDataReference& device) override;
+ NPT_Result OnDeviceRemoved(PLT_DeviceDataReference& device) override;
+ NPT_Result OnActionResponse(NPT_Result res, PLT_ActionReference& action, void* userdata) override;
+ NPT_Result OnEventNotify(PLT_Service* service, NPT_List<PLT_StateVariable*>* vars) override;
+
+ // ContentDirectory service responses
+ virtual NPT_Result OnBrowseResponse(NPT_Result res,
+ PLT_DeviceDataReference& device,
+ PLT_ActionReference& action,
+ void* userdata);
+
+ virtual NPT_Result OnSearchResponse(NPT_Result res,
+ PLT_DeviceDataReference& device,
+ PLT_ActionReference& action,
+ void* userdata);
+
+ virtual NPT_Result OnGetSearchCapabilitiesResponse(NPT_Result res,
+ PLT_DeviceDataReference& device,
+ PLT_ActionReference& action,
+ void* userdata);
+
+ virtual NPT_Result OnGetSortCapabilitiesResponse(NPT_Result res,
+ PLT_DeviceDataReference& device,
+ PLT_ActionReference& action,
+ void* userdata);
+
+protected:
+ PLT_CtrlPointReference m_CtrlPoint;
+ PLT_MediaBrowserDelegate* m_Delegate;
+ NPT_Lock<PLT_DeviceDataReferenceList> m_MediaServers;
+};
+
+#endif /* _PLT_MEDIA_BROWSER_H_ */
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaCache.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaCache.cpp
new file mode 100644
index 0000000..aae5d01
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaCache.cpp
@@ -0,0 +1,37 @@
+/*****************************************************************
+|
+| Platinum - AV Media Cache
+|
+| Copyright (c) 2004-2010, Plutinosoft, LLC.
+| All rights reserved.
+| http://www.plutinosoft.com
+|
+| This program is free software; you can redistribute it and/or
+| modify it under the terms of the GNU General Public License
+| as published by the Free Software Foundation; either version 2
+| of the License, or (at your option) any later version.
+|
+| OEMs, ISVs, VARs and other distributors that combine and
+| distribute commercially licensed software with Platinum software
+| and do not wish to distribute the source code for the commercially
+| licensed software under version 2, or (at your option) any later
+| version, of the GNU General Public License (the "GPL") must enter
+| into a commercial license agreement with Plutinosoft, LLC.
+| licensing@plutinosoft.com
+|
+| This program is distributed in the hope that it will be useful,
+| but WITHOUT ANY WARRANTY; without even the implied warranty of
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+| GNU General Public License for more details.
+|
+| You should have received a copy of the GNU General Public License
+| along with this program; see the file LICENSE.txt. If not, write to
+| the Free Software Foundation, Inc.,
+| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+| http://www.gnu.org/licenses/gpl-2.0.html
+|
+****************************************************************/
+
+/*----------------------------------------------------------------------
+| includes
++---------------------------------------------------------------------*/
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaCache.h b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaCache.h
new file mode 100644
index 0000000..8e365d8
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaCache.h
@@ -0,0 +1,203 @@
+/*****************************************************************
+|
+| Platinum - AV Media Cache
+|
+| Copyright (c) 2004-2010, Plutinosoft, LLC.
+| All rights reserved.
+| http://www.plutinosoft.com
+|
+| This program is free software; you can redistribute it and/or
+| modify it under the terms of the GNU General Public License
+| as published by the Free Software Foundation; either version 2
+| of the License, or (at your option) any later version.
+|
+| OEMs, ISVs, VARs and other distributors that combine and
+| distribute commercially licensed software with Platinum software
+| and do not wish to distribute the source code for the commercially
+| licensed software under version 2, or (at your option) any later
+| version, of the GNU General Public License (the "GPL") must enter
+| into a commercial license agreement with Plutinosoft, LLC.
+| licensing@plutinosoft.com
+|
+| This program is distributed in the hope that it will be useful,
+| but WITHOUT ANY WARRANTY; without even the implied warranty of
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+| GNU General Public License for more details.
+|
+| You should have received a copy of the GNU General Public License
+| along with this program; see the file LICENSE.txt. If not, write to
+| the Free Software Foundation, Inc.,
+| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+| http://www.gnu.org/licenses/gpl-2.0.html
+|
+****************************************************************/
+
+/** @file
+ Simple Object Caching utility.
+ */
+
+#ifndef _PLT_MEDIA_CACHE_H_
+#define _PLT_MEDIA_CACHE_H_
+
+/*----------------------------------------------------------------------
+| includes
++---------------------------------------------------------------------*/
+#include "Neptune.h"
+
+/*----------------------------------------------------------------------
+| PLT_MediaCache
++---------------------------------------------------------------------*/
+/**
+ The PLT_MediaCache template provides a way to hold references to object in
+ memory.
+ */
+template <typename T, typename U>
+class PLT_MediaCache
+{
+public:
+ typedef typename NPT_Map<NPT_String,T>::Entry ElementEntry;
+ typedef typename NPT_List<ElementEntry*>::Iterator ElementIterator;
+
+ PLT_MediaCache<T,U>() {}
+ virtual ~PLT_MediaCache<T,U>() {}
+
+ NPT_Result Put(const char* root, const char* key, T& value, U* tag = NULL);
+ NPT_Result Get(const char* root, const char* key, T& value, U* tag = NULL);
+ NPT_Result Clear(const char* root, const char* key);
+ NPT_Result Clear(const char* root = NULL);
+
+private:
+ // methods
+ NPT_String GenerateKey(const char* root, const char* key);
+
+private:
+ // members
+ NPT_Mutex m_Mutex;
+ NPT_Map<NPT_String, T> m_Items;
+ NPT_Map<NPT_String, U> m_Tags;
+};
+
+/*----------------------------------------------------------------------
+| PLT_MediaCache::GenerateKey
++---------------------------------------------------------------------*/
+template <typename T, typename U>
+inline
+NPT_String
+PLT_MediaCache<T,U>::GenerateKey(const char* root, const char* key)
+{
+ // TODO: There could be collision
+ NPT_String result = root;
+ result += "/";
+ result += key;
+ return result;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaCache::Put
++---------------------------------------------------------------------*/
+template <typename T, typename U>
+inline
+NPT_Result
+PLT_MediaCache<T,U>::Put(const char* root,
+ const char* key,
+ T& value,
+ U* tag)
+{
+ NPT_AutoLock lock(m_Mutex);
+
+ NPT_String fullkey = GenerateKey(root, key);
+ if (fullkey.GetLength() == 0) return NPT_ERROR_INVALID_PARAMETERS;
+
+ m_Items.Erase(fullkey);
+ NPT_CHECK(m_Items.Put(fullkey, value));
+
+ if (tag) NPT_CHECK(m_Tags.Put(fullkey, *tag));
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaCache::Get
++---------------------------------------------------------------------*/
+template <typename T, typename U>
+inline
+NPT_Result
+PLT_MediaCache<T,U>::Get(const char* root,
+ const char* key,
+ T& value,
+ U* tag /* = NULL */)
+{
+ NPT_AutoLock lock(m_Mutex);
+
+ NPT_String fullkey = GenerateKey(root, key);
+ if (fullkey.GetLength() == 0) return NPT_ERROR_INVALID_PARAMETERS;
+
+ T* _value = NULL;
+ NPT_CHECK(m_Items.Get(fullkey, _value));
+
+ U* _tag;
+ if (tag) {
+ m_Tags.Get(fullkey, _tag);
+ if (_tag) *tag = *_tag;
+ }
+
+ value = *_value;
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaCache::Clear
++---------------------------------------------------------------------*/
+template <typename T, typename U>
+inline
+NPT_Result
+PLT_MediaCache<T,U>::Clear(const char* root, const char* key)
+{
+ NPT_AutoLock lock(m_Mutex);
+
+ NPT_String fullkey = GenerateKey(root, key);
+ if (fullkey.GetLength() == 0) return NPT_ERROR_INVALID_PARAMETERS;
+
+ ElementIterator entries = m_Items.GetEntries().GetFirstItem();
+ ElementIterator entry;
+ while (entries) {
+ entry = entries++;
+ if ((*entry)->GetKey() == (fullkey)) {
+ m_Items.Erase(fullkey);
+ m_Tags.Erase(fullkey);
+ return NPT_SUCCESS;
+ }
+ }
+
+ return NPT_ERROR_NO_SUCH_ITEM;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaCache::Clear
++---------------------------------------------------------------------*/
+template <typename T, typename U>
+inline
+NPT_Result
+PLT_MediaCache<T,U>::Clear(const char* root)
+{
+ NPT_AutoLock lock(m_Mutex);
+
+ if (!root || root[0]=='\0')
+ return m_Items.Clear();
+
+ NPT_String key = GenerateKey(root, "");
+ ElementIterator entries = m_Items.GetEntries().GetFirstItem();
+ ElementIterator entry;
+ while (entries) {
+ entry = entries++;
+ NPT_String entry_key = (*entry)->GetKey();
+ if (entry_key.StartsWith(key)) {
+ m_Items.Erase(entry_key);
+ m_Tags.Erase(entry_key);
+ }
+ }
+
+ return NPT_SUCCESS;
+}
+
+#endif /* _PLT_MEDIA_CACHE_H_ */
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp
new file mode 100644
index 0000000..fac1690
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp
@@ -0,0 +1,1128 @@
+/*****************************************************************
+|
+| Platinum - AV Media Item
+|
+| Copyright (c) 2004-2010, Plutinosoft, LLC.
+| All rights reserved.
+| http://www.plutinosoft.com
+|
+| This program is free software; you can redistribute it and/or
+| modify it under the terms of the GNU General Public License
+| as published by the Free Software Foundation; either version 2
+| of the License, or (at your option) any later version.
+|
+| OEMs, ISVs, VARs and other distributors that combine and
+| distribute commercially licensed software with Platinum software
+| and do not wish to distribute the source code for the commercially
+| licensed software under version 2, or (at your option) any later
+| version, of the GNU General Public License (the "GPL") must enter
+| into a commercial license agreement with Plutinosoft, LLC.
+| licensing@plutinosoft.com
+|
+| This program is distributed in the hope that it will be useful,
+| but WITHOUT ANY WARRANTY; without even the implied warranty of
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+| GNU General Public License for more details.
+|
+| You should have received a copy of the GNU General Public License
+| along with this program; see the file LICENSE.txt. If not, write to
+| the Free Software Foundation, Inc.,
+| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+| http://www.gnu.org/licenses/gpl-2.0.html
+|
+****************************************************************/
+
+/*----------------------------------------------------------------------
+| includes
++---------------------------------------------------------------------*/
+#include "PltMediaItem.h"
+#include "PltMediaServer.h"
+#include "PltDidl.h"
+#include "PltUtilities.h"
+#include "PltService.h"
+#include "PltMimeType.h"
+
+NPT_SET_LOCAL_LOGGER("platinum.media.server.item")
+
+/*----------------------------------------------------------------------
+| globals
++---------------------------------------------------------------------*/
+NPT_DEFINE_DYNAMIC_CAST_ANCHOR(PLT_MediaObject)
+NPT_DEFINE_DYNAMIC_CAST_ANCHOR(PLT_MediaItem)
+NPT_DEFINE_DYNAMIC_CAST_ANCHOR(PLT_MediaContainer)
+
+/*----------------------------------------------------------------------
+| PLT_PersonRoles::AddPerson
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_PersonRoles::Add(const NPT_String& name, const NPT_String& role /* = "" */)
+{
+ PLT_PersonRole person;
+ person.name = name;
+ person.role = role;
+
+ return NPT_List<PLT_PersonRole>::Add(person);
+}
+
+/*----------------------------------------------------------------------
+| PLT_PersonRoles::ToDidl
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_PersonRoles::ToDidl(NPT_String& didl, const NPT_String& tag)
+{
+ NPT_String tmp;
+ for (NPT_List<PLT_PersonRole>::Iterator it =
+ NPT_List<PLT_PersonRole>::GetFirstItem(); it; it++) {
+ // if there's an empty artist, allow it only if there's nothing else
+ if (it->name.IsEmpty() && m_ItemCount>1 && !tmp.IsEmpty()) continue;
+
+ tmp += "<upnp:" + tag;
+ if (!it->role.IsEmpty()) {
+ tmp += " role=\"";
+ PLT_Didl::AppendXmlEscape(tmp, it->role);
+ tmp += "\"";
+ }
+ tmp += ">";
+ PLT_Didl::AppendXmlEscape(tmp, it->name);
+ tmp += "</upnp:" + tag + ">";
+ }
+
+ didl += tmp;
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_PersonRoles::ToDidl
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_PersonRoles::FromDidl(const NPT_Array<NPT_XmlElementNode*>& nodes)
+{
+ for (NPT_Cardinal i=0; i<nodes.GetItemCount(); i++) {
+ PLT_PersonRole person;
+ const NPT_String* name = nodes[i]->GetText();
+ const NPT_String* role = nodes[i]->GetAttribute("role");
+ // DLNA 7.3.17
+ if (name) person.name = name->SubString(0, 1024);
+ if (role) person.role = role->SubString(0, 1024);
+ NPT_CHECK(NPT_List<PLT_PersonRole>::Add(person));
+ }
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_Artworks::Add
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_Artworks::Add(const NPT_String& type, const NPT_String& url)
+{
+ PLT_Artwork artwork;
+ artwork.type = type;
+ artwork.url = url;
+
+ return NPT_List<PLT_Artwork>::Add(artwork);
+}
+
+/*----------------------------------------------------------------------
+| PLT_Artworks::ToDidl
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_Artworks::ToDidl(NPT_String& didl, const NPT_String& tag)
+{
+ NPT_String tmp;
+ for (NPT_List<PLT_Artwork>::Iterator it =
+ NPT_List<PLT_Artwork>::GetFirstItem(); it; it++) {
+ if (it->type.IsEmpty()) continue;
+
+ tmp += "<xbmc:" + tag;
+ if (!it->type.IsEmpty()) {
+ tmp += " type=\"";
+ PLT_Didl::AppendXmlEscape(tmp, it->type);
+ tmp += "\"";
+ }
+ tmp += ">";
+ PLT_Didl::AppendXmlEscape(tmp, it->url);
+ tmp += "</xbmc:" + tag + ">";
+ }
+
+ didl += tmp;
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_Artworks::ToDidl
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_Artworks::FromDidl(const NPT_Array<NPT_XmlElementNode*>& nodes)
+{
+ for (NPT_Cardinal i=0; i<nodes.GetItemCount(); i++) {
+ PLT_Artwork artwork;
+ const NPT_String* url = nodes[i]->GetText();
+ const NPT_String* type = nodes[i]->GetAttribute("type");
+ if (type) artwork.type = *type;
+ if (url) artwork.url = *url;
+ NPT_CHECK(NPT_List<PLT_Artwork>::Add(artwork));
+ }
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaItemResource::PLT_MediaItemResource
++---------------------------------------------------------------------*/
+PLT_MediaItemResource::PLT_MediaItemResource()
+{
+ m_Uri = "";
+ m_ProtocolInfo = PLT_ProtocolInfo();
+ m_Duration = (NPT_UInt32)-1;
+ m_Size = (NPT_LargeSize)-1;
+ m_Protection = "";
+ m_Bitrate = (NPT_UInt32)-1;
+ m_BitsPerSample = (NPT_UInt32)-1;
+ m_SampleFrequency = (NPT_UInt32)-1;
+ m_NbAudioChannels = (NPT_UInt32)-1;
+ m_Resolution = "";
+ m_ColorDepth = (NPT_UInt32)-1;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaObject::GetUPnPClass
++---------------------------------------------------------------------*/
+const char*
+PLT_MediaObject::GetUPnPClass(const char* filename,
+ const PLT_HttpRequestContext* context /* = NULL */)
+{
+ NPT_COMPILER_UNUSED(context);
+
+ const char* ret = NULL;
+ NPT_String mime_type = PLT_MimeType::GetMimeType(filename, context);
+
+ if (mime_type.StartsWith("audio")) {
+ ret = "object.item.audioItem.musicTrack";
+ } else if (mime_type.StartsWith("video")) {
+ ret = "object.item.videoItem"; //Note: 360 wants "object.item.videoItem" and not "object.item.videoItem.Movie"
+ } else if (mime_type.StartsWith("image")) {
+ ret = "object.item.imageItem.photo";
+ } else {
+ ret = "object.item";
+ }
+
+ return ret;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaObject::Reset
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaObject::Reset()
+{
+ m_ObjectClass.type = "";
+ m_ObjectClass.friendly_name = "";
+ m_ObjectID = "";
+ m_ParentID = "";
+
+ m_Title = "";
+ m_Creator = "";
+ m_Date = "";
+ m_Restricted = true;
+
+ m_People.actors.Clear();
+ m_People.artists.Clear();
+ m_People.authors.Clear();
+ m_People.directors.Clear();
+ m_People.publisher.Clear();
+
+ m_Affiliation.album = "";
+ m_Affiliation.genres.Clear();
+ m_Affiliation.playlist = "";
+
+ m_Description.description = "";
+ m_Description.long_description = "";
+ m_Description.icon_uri = "";
+ m_ExtraInfo.album_arts.Clear();
+ m_ExtraInfo.artist_discography_uri = "";
+
+ m_MiscInfo.original_track_number = 0;
+ m_MiscInfo.last_position = 0;
+ m_MiscInfo.last_time = "";
+ m_MiscInfo.play_count = -1;
+ m_MiscInfo.dvdregioncode = 0;
+ m_MiscInfo.toc = "";
+ m_MiscInfo.user_annotation = "";
+
+ m_Recorded.program_title = "";
+ m_Recorded.series_title = "";
+ m_Recorded.episode_number = 0;
+ m_Recorded.episode_count = 0;
+ m_Recorded.episode_season = 0;
+
+ m_Resources.Clear();
+
+ m_XbmcInfo.last_playerstate = "";
+ m_XbmcInfo.date_added = "";
+ m_XbmcInfo.rating = 0.0f;
+ m_XbmcInfo.votes = 0;
+ m_XbmcInfo.artwork.Clear();
+ m_XbmcInfo.unique_identifier = "";
+ m_XbmcInfo.countries.Clear();
+ m_XbmcInfo.user_rating = 0;
+
+ m_Didl = "";
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaObject::ToDidl
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaObject::ToDidl(const NPT_String& filter, NPT_String& didl)
+{
+ return ToDidl(PLT_Didl::ConvertFilterToMask(filter), didl);
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaObject::ToDidl
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaObject::ToDidl(NPT_UInt64 mask, NPT_String& didl)
+{
+ // title is required
+ didl += "<dc:title>";
+ PLT_Didl::AppendXmlEscape(didl, m_Title);
+ didl += "</dc:title>";
+
+ // creator
+ if (mask & PLT_FILTER_MASK_CREATOR) {
+ didl += "<dc:creator>";
+ if (m_Creator.IsEmpty()) m_Creator = "Unknown";
+ PLT_Didl::AppendXmlEscape(didl, m_Creator);
+ didl += "</dc:creator>";
+ }
+
+ // date
+ if ((mask & PLT_FILTER_MASK_DATE) && !m_Date.IsEmpty()) {
+ didl += "<dc:date>";
+ PLT_Didl::AppendXmlEscape(didl, m_Date);
+ didl += "</dc:date>";
+ }
+
+ // artist
+ if (mask & PLT_FILTER_MASK_ARTIST) {
+ // force an empty artist just in case (not DLNA Compliant though)
+ //if (m_People.artists.GetItemCount() == 0) m_People.artists.Add("");
+ m_People.artists.ToDidl(didl, "artist");
+ }
+
+ // actor
+ if (mask & PLT_FILTER_MASK_ACTOR) {
+ m_People.actors.ToDidl(didl, "actor");
+ }
+
+ // actor
+ if (mask & PLT_FILTER_MASK_AUTHOR) {
+ m_People.authors.ToDidl(didl, "author");
+ }
+
+ // director
+ if (mask & PLT_FILTER_MASK_DIRECTOR) {
+ m_People.directors.ToDidl(didl, "director");
+ }
+
+ // publisher
+ if (mask & PLT_FILTER_MASK_PUBLISHER) {
+ // Add unknown publisher
+ if (m_People.publisher.GetItemCount() == 0)
+ m_People.publisher.Add("Unknown");
+
+ for (NPT_List<NPT_String>::Iterator it =
+ m_People.publisher.GetFirstItem(); it; ++it) {
+ didl += "<dc:publisher>";
+ PLT_Didl::AppendXmlEscape(didl, (*it));
+ didl += "</dc:publisher>";
+ }
+ }
+
+ // album
+ if ((mask & PLT_FILTER_MASK_ALBUM) && !m_Affiliation.album.IsEmpty()) {
+ didl += "<upnp:album>";
+ PLT_Didl::AppendXmlEscape(didl, m_Affiliation.album);
+ didl += "</upnp:album>";
+ }
+
+ // genre
+ if (mask & PLT_FILTER_MASK_GENRE) {
+ // Add unknown genre
+ if (m_Affiliation.genres.GetItemCount() == 0)
+ m_Affiliation.genres.Add("Unknown");
+
+ for (NPT_List<NPT_String>::Iterator it =
+ m_Affiliation.genres.GetFirstItem(); it; ++it) {
+ didl += "<upnp:genre>";
+ PLT_Didl::AppendXmlEscape(didl, (*it));
+ didl += "</upnp:genre>";
+ }
+ }
+
+ // album art URI
+ if ((mask & PLT_FILTER_MASK_ALBUMARTURI) && m_ExtraInfo.album_arts.GetItemCount()) {
+ for (NPT_List<PLT_AlbumArtInfo>::Iterator iter = m_ExtraInfo.album_arts.GetFirstItem();
+ iter;
+ iter++) {
+ didl += "<upnp:albumArtURI";
+ if (!(*iter).dlna_profile.IsEmpty()) {
+ didl += " dlna:profileID=\"";
+ PLT_Didl::AppendXmlEscape(didl, (*iter).dlna_profile);
+ didl += "\"";
+ }
+ didl += ">";
+ PLT_Didl::AppendXmlEscape(didl, (*iter).uri);
+ didl += "</upnp:albumArtURI>";
+ }
+ }
+
+ // description
+ if ((mask & PLT_FILTER_MASK_DESCRIPTION) && !m_Description.description.IsEmpty()) {
+ didl += "<dc:description>";
+ PLT_Didl::AppendXmlEscape(didl, m_Description.description);
+ didl += "</dc:description>";
+ }
+
+ // long description
+ if ((mask & PLT_FILTER_MASK_LONGDESCRIPTION) && !m_Description.long_description.IsEmpty()) {
+ didl += "<upnp:longDescription>";
+ PLT_Didl::AppendXmlEscape(didl, m_Description.long_description);
+ didl += "</upnp:longDescription>";
+ }
+
+ // icon
+ if ((mask & PLT_FILTER_MASK_ICON) && !m_Description.icon_uri.IsEmpty()) {
+ didl += "<upnp:icon>";
+ PLT_Didl::AppendXmlEscape(didl, m_Description.icon_uri);
+ didl += "</upnp:icon>";
+ }
+
+ // rating
+ if ((mask & PLT_FILTER_MASK_RATING) && !m_Description.rating.IsEmpty()) {
+ didl += "<upnp:rating>";
+ PLT_Didl::AppendXmlEscape(didl, m_Description.rating);
+ didl += "</upnp:rating>";
+ }
+
+ // original track number
+ if ((mask & PLT_FILTER_MASK_ORIGINALTRACK) && m_MiscInfo.original_track_number > 0) {
+ didl += "<upnp:originalTrackNumber>";
+ didl += NPT_String::FromInteger(m_MiscInfo.original_track_number);
+ didl += "</upnp:originalTrackNumber>";
+ }
+
+ // last playback position
+ if (mask & PLT_FILTER_MASK_LASTPOSITION && m_MiscInfo.last_position > 0) {
+ didl += "<upnp:lastPlaybackPosition>";
+ didl += NPT_String::FromInteger(m_MiscInfo.last_position);
+ didl += "</upnp:lastPlaybackPosition>";
+ }
+
+ // last playback datetime
+ if (mask & PLT_FILTER_MASK_LASTPLAYBACK && !m_MiscInfo.last_time.IsEmpty()) {
+ didl += "<upnp:lastPlaybackTime>";
+ PLT_Didl::AppendXmlEscape(didl, m_MiscInfo.last_time);
+ didl += "</upnp:lastPlaybackTime>";
+ }
+
+ // playcount
+ if (mask & PLT_FILTER_MASK_PLAYCOUNT && m_MiscInfo.play_count > -1) {
+ didl += "<upnp:playbackCount>";
+ didl += NPT_String::FromInteger(m_MiscInfo.play_count);
+ didl += "</upnp:playbackCount>";
+ }
+
+ // program title
+ if (mask & PLT_FILTER_MASK_PROGRAMTITLE && !m_Recorded.program_title.IsEmpty()) {
+ didl += "<upnp:programTitle>";
+ PLT_Didl::AppendXmlEscape(didl, m_Recorded.program_title);
+ didl += "</upnp:programTitle>";
+ }
+
+ // series title
+ if ((mask & PLT_FILTER_MASK_SERIESTITLE) && !m_Recorded.series_title.IsEmpty()) {
+ didl += "<upnp:seriesTitle>";
+ PLT_Didl::AppendXmlEscape(didl, m_Recorded.series_title);
+ didl += "</upnp:seriesTitle>";
+ }
+
+ // episode number
+ if ((mask & PLT_FILTER_MASK_EPISODE) && m_Recorded.episode_number > 0) {
+ didl += "<upnp:episodeNumber>";
+ didl += NPT_String::FromInteger(m_Recorded.episode_number);
+ didl += "</upnp:episodeNumber>";
+ }
+
+ // episode count
+ if ((mask & PLT_FILTER_MASK_EPISODE_COUNT) && m_Recorded.episode_count > 0) {
+ didl += "<upnp:episodeCount>";
+ didl += NPT_String::FromInteger(m_Recorded.episode_count);
+ didl += "</upnp:episodeCount>";
+ }
+
+ // episode count
+ if ((mask & PLT_FILTER_MASK_EPISODE_SEASON)) {
+ didl += "<upnp:episodeSeason>";
+ didl += NPT_String::FromInteger(m_Recorded.episode_season);
+ didl += "</upnp:episodeSeason>";
+ }
+
+ if ((mask & PLT_FILTER_MASK_TOC) && !m_MiscInfo.toc.IsEmpty()) {
+ didl += "<upnp:toc>";
+ PLT_Didl::AppendXmlEscape(didl, m_MiscInfo.toc);
+ didl += "</upnp:toc>";
+ }
+
+ // resource
+ if (mask & PLT_FILTER_MASK_RES) {
+ for (NPT_Cardinal i=0; i<m_Resources.GetItemCount(); i++) {
+ didl += "<res";
+
+ if ((mask & PLT_FILTER_MASK_RES_DURATION) && m_Resources[i].m_Duration != (NPT_UInt32)-1) {
+ didl += " duration=\"";
+ didl += PLT_Didl::FormatTimeStamp(m_Resources[i].m_Duration);
+ didl += "\"";
+ }
+
+ if ((mask & PLT_FILTER_MASK_RES_SIZE) && m_Resources[i].m_Size != (NPT_LargeSize)-1) {
+ didl += " size=\"";
+ didl += NPT_String::FromIntegerU(m_Resources[i].m_Size);
+ didl += "\"";
+ }
+
+ if ((mask & PLT_FILTER_MASK_RES_PROTECTION) && !m_Resources[i].m_Protection.IsEmpty()) {
+ didl += " protection=\"";
+ PLT_Didl::AppendXmlEscape(didl, m_Resources[i].m_Protection);
+ didl += "\"";
+ }
+
+ if ((mask & PLT_FILTER_MASK_RES_RESOLUTION) && !m_Resources[i].m_Resolution.IsEmpty()) {
+ didl += " resolution=\"";
+ PLT_Didl::AppendXmlEscape(didl, m_Resources[i].m_Resolution);
+ didl += "\"";
+ }
+
+ if ((mask & PLT_FILTER_MASK_RES_BITRATE) && m_Resources[i].m_Bitrate != (NPT_Size)-1) {
+ didl += " bitrate=\"";
+ didl += NPT_String::FromIntegerU(m_Resources[i].m_Bitrate);
+ didl += "\"";
+ }
+
+ if ((mask & PLT_FILTER_MASK_RES_BITSPERSAMPLE) && m_Resources[i].m_BitsPerSample != (NPT_Size)-1) {
+ didl += " bitsPerSample=\"";
+ didl += NPT_String::FromIntegerU(m_Resources[i].m_BitsPerSample);
+ didl += "\"";
+ }
+
+ if ((mask & PLT_FILTER_MASK_RES_SAMPLEFREQUENCY) && m_Resources[i].m_SampleFrequency != (NPT_Size)-1) {
+ didl += " sampleFrequency=\"";
+ didl += NPT_String::FromIntegerU(m_Resources[i].m_SampleFrequency);
+ didl += "\"";
+ }
+
+ if ((mask & PLT_FILTER_MASK_RES_NRAUDIOCHANNELS) && m_Resources[i].m_NbAudioChannels != (NPT_Size)-1) {
+ didl += " nrAudioChannels=\"";
+ didl += NPT_String::FromIntegerU(m_Resources[i].m_NbAudioChannels);
+ didl += "\"";
+ }
+
+ didl += " protocolInfo=\"";
+ PLT_Didl::AppendXmlEscape(didl, m_Resources[i].m_ProtocolInfo.ToString());
+ didl += "\"";
+ /* adding custom data */
+ NPT_List<NPT_Map<NPT_String, NPT_String>::Entry*>::Iterator entry = m_Resources[i].m_CustomData.GetEntries().GetFirstItem();
+ while (entry)
+ {
+ didl += " ";
+ PLT_Didl::AppendXmlEscape(didl, (*entry)->GetKey());
+ didl += "=\"";
+ PLT_Didl::AppendXmlEscape(didl, (*entry)->GetValue());
+ didl += "\"";
+
+ entry++;
+ }
+
+ didl += ">";
+ PLT_Didl::AppendXmlEscape(didl, m_Resources[i].m_Uri);
+ didl += "</res>";
+ }
+ }
+
+ //sec resources related
+ for (NPT_Cardinal i = 0; i < m_SecResources.GetItemCount(); i++) {
+ didl += "<sec:";
+ PLT_Didl::AppendXmlEscape(didl, m_SecResources[i].name);
+
+ NPT_List<NPT_Map<NPT_String, NPT_String>::Entry*>::Iterator entry = m_SecResources[i].attributes.GetEntries().GetFirstItem();
+ while (entry)
+ {
+ didl += " sec:";
+ PLT_Didl::AppendXmlEscape(didl, (*entry)->GetKey());
+ didl += "=\"";
+ PLT_Didl::AppendXmlEscape(didl, (*entry)->GetValue());
+ didl += "\"";
+
+ entry++;
+ }
+
+ didl += ">";
+ PLT_Didl::AppendXmlEscape(didl, m_SecResources[i].value);
+
+ didl += "</sec:";
+ PLT_Didl::AppendXmlEscape(didl, m_SecResources[i].name);
+ didl += ">";
+ }
+
+ // xbmc dateadded
+ if ((mask & PLT_FILTER_MASK_XBMC_DATEADDED) && !m_XbmcInfo.date_added.IsEmpty()) {
+ didl += "<xbmc:dateadded>";
+ PLT_Didl::AppendXmlEscape(didl, m_XbmcInfo.date_added);
+ didl += "</xbmc:dateadded>";
+ }
+
+ // xbmc rating
+ if (mask & PLT_FILTER_MASK_XBMC_RATING) {
+ didl += "<xbmc:rating>";
+ didl += NPT_String::Format("%.1f", m_XbmcInfo.rating);
+ didl += "</xbmc:rating>";
+ }
+
+ // xbmc votes
+ if (mask & PLT_FILTER_MASK_XBMC_VOTES && m_XbmcInfo.votes != 0) {
+ didl += "<xbmc:votes>";
+ didl += NPT_String::Format("%i", m_XbmcInfo.votes);
+ didl += "</xbmc:votes>";
+ }
+
+ // xbmc artwork
+ if (mask & PLT_FILTER_MASK_XBMC_ARTWORK) {
+ m_XbmcInfo.artwork.ToDidl(didl, "artwork");
+ }
+
+ // xbmc unique identifier
+ if (mask & PLT_FILTER_MASK_XBMC_UNIQUE_IDENTIFIER && !m_XbmcInfo.unique_identifier.IsEmpty()) {
+ didl += "<xbmc:uniqueidentifier>";
+ PLT_Didl::AppendXmlEscape(didl, m_XbmcInfo.unique_identifier);
+ didl += "</xbmc:uniqueidentifier>";
+ }
+
+ // country
+ if (mask & PLT_FILTER_MASK_XBMC_COUNTRY) {
+ for (NPT_List<NPT_String>::Iterator it =
+ m_XbmcInfo.countries.GetFirstItem(); it; ++it) {
+ didl += "<xbmc:country>";
+ PLT_Didl::AppendXmlEscape(didl, (*it));
+ didl += "</xbmc:country>";
+ }
+ }
+
+ // user rating
+ if (mask & PLT_FILTER_MASK_XBMC_USERRATING) {
+ didl += "<xbmc:userrating>";
+ didl += NPT_String::FromInteger(m_XbmcInfo.user_rating);
+ didl += "</xbmc:userrating>";
+ }
+
+ // xbmc last playback state
+ if (mask & PLT_FILTER_MASK_XBMC_LASTPLAYERSTATE && !m_XbmcInfo.last_playerstate.IsEmpty()) {
+ didl += "<xbmc:lastPlayerState>";
+ PLT_Didl::AppendXmlEscape(didl, m_XbmcInfo.last_playerstate);
+ didl += "</xbmc:lastPlayerState>";
+ }
+
+ // class is required
+ didl += "<upnp:class";
+ if (!m_ObjectClass.friendly_name.IsEmpty()) {
+ didl += " name=\"" + m_ObjectClass.friendly_name+"\"";
+ }
+ didl += ">";
+ PLT_Didl::AppendXmlEscape(didl, m_ObjectClass.type);
+ didl += "</upnp:class>";
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaObject::FromDidl
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaObject::FromDidl(NPT_XmlElementNode* entry)
+{
+ NPT_String str, xml;
+ NPT_Array<NPT_XmlElementNode*> children;
+ NPT_Result res;
+
+ // check if item is restricted (is default true?)
+ if (NPT_SUCCEEDED(PLT_XmlHelper::GetAttribute(entry, "restricted", str, "", 5))) {
+ m_Restricted = PLT_Service::IsTrue(str);
+ }
+
+ // read non-required elements
+ PLT_XmlHelper::GetChildText(entry, "creator", m_Creator, didl_namespace_dc, 256);
+ PLT_XmlHelper::GetChildText(entry, "date", m_Date, didl_namespace_dc, 256);
+
+ // parse date and make sure it's valid
+ NPT_String parsed_date;
+ for (int format=0; format<=NPT_DateTime::FORMAT_RFC_1036; format++) {
+ NPT_DateTime date;
+ if (NPT_SUCCEEDED(date.FromString(m_Date, (NPT_DateTime::Format)format))) {
+ parsed_date = date.ToString((NPT_DateTime::Format)format);
+ break;
+ }
+ }
+ m_Date = parsed_date;
+
+ res = PLT_XmlHelper::GetAttribute(entry, "id", m_ObjectID);
+ NPT_CHECK_SEVERE(res);
+
+ res = PLT_XmlHelper::GetAttribute(entry, "parentID", m_ParentID);
+ NPT_CHECK_SEVERE(res);
+
+ PLT_XmlHelper::GetAttribute(entry, "refID", m_ReferenceID);
+
+ res = PLT_XmlHelper::GetChildText(entry, "title", m_Title, didl_namespace_dc);
+ NPT_CHECK_SEVERE(res);
+
+ res = PLT_XmlHelper::GetChildText(entry, "class", m_ObjectClass.type, didl_namespace_upnp);
+ NPT_CHECK_SEVERE(res);
+
+ // DLNA 7.3.17.3 max bytes for dc:title and upnp:class is 256 bytes
+ m_Title = m_Title.SubString(0, 256);
+ m_ObjectClass.type = m_ObjectClass.type.SubString(0, 256);
+
+ children.Clear();
+ PLT_XmlHelper::GetChildren(entry, children, "artist", didl_namespace_upnp);
+ m_People.artists.FromDidl(children);
+
+ children.Clear();
+ PLT_XmlHelper::GetChildren(entry, children, "author", didl_namespace_upnp);
+ m_People.authors.FromDidl(children);
+
+ children.Clear();
+ PLT_XmlHelper::GetChildren(entry, children, "actor", didl_namespace_upnp);
+ m_People.actors.FromDidl(children);
+
+ children.Clear();
+ PLT_XmlHelper::GetChildren(entry, children, "director", didl_namespace_upnp);
+ m_People.directors.FromDidl(children);
+
+ children.Clear();
+ PLT_XmlHelper::GetChildren(entry, children, "publisher", didl_namespace_dc);
+ for (NPT_Cardinal i=0; i<children.GetItemCount(); i++) {
+ if (children[i]->GetText()) {
+ m_People.publisher.Add(*children[i]->GetText());
+ }
+ }
+
+ PLT_XmlHelper::GetChildText(entry, "album", m_Affiliation.album, didl_namespace_upnp, 256);
+ PLT_XmlHelper::GetChildText(entry, "programTitle", m_Recorded.program_title, didl_namespace_upnp);
+ PLT_XmlHelper::GetChildText(entry, "seriesTitle", m_Recorded.series_title, didl_namespace_upnp);
+ PLT_XmlHelper::GetChildText(entry, "episodeNumber", str, didl_namespace_upnp);
+ NPT_UInt32 value;
+ if (NPT_FAILED(str.ToInteger(value))) value = 0;
+ m_Recorded.episode_number = value;
+ PLT_XmlHelper::GetChildText(entry, "episodeCount", str, didl_namespace_upnp);
+ if (NPT_FAILED(str.ToInteger(value))) value = 0;
+ m_Recorded.episode_count = value;
+ PLT_XmlHelper::GetChildText(entry, "episodeSeason", str, didl_namespace_upnp);
+ if (NPT_FAILED(str.ToInteger(value))) value = -1;
+ m_Recorded.episode_season = value;
+
+ children.Clear();
+ PLT_XmlHelper::GetChildren(entry, children, "genre", didl_namespace_upnp);
+ for (NPT_Cardinal i=0; i<children.GetItemCount(); i++) {
+ if (children[i]->GetText()) {
+ m_Affiliation.genres.Add(children[i]->GetText()->SubString(0, 256));
+ }
+ }
+
+ PLT_XmlHelper::GetChildText(entry, "description", m_Description.description, didl_namespace_dc);
+ PLT_XmlHelper::GetChildText(entry, "longDescription", m_Description.long_description, didl_namespace_upnp);
+ PLT_XmlHelper::GetChildText(entry, "icon", m_Description.icon_uri, didl_namespace_upnp);
+ PLT_XmlHelper::GetChildText(entry, "rating", m_Description.rating, didl_namespace_upnp);
+ PLT_XmlHelper::GetChildText(entry, "toc", m_MiscInfo.toc, didl_namespace_upnp);
+
+ // album arts
+ children.Clear();
+ PLT_XmlHelper::GetChildren(entry, children, "albumArtURI", didl_namespace_upnp);
+ for (NPT_Cardinal i=0; i<children.GetItemCount(); i++) {
+ if (children[i]->GetText()) {
+ PLT_AlbumArtInfo info;
+ info.uri = children[i]->GetText()->SubString(0, 1024);
+ PLT_XmlHelper::GetAttribute(children[i], "profileID", info.dlna_profile, didl_namespace_dlna);
+ m_ExtraInfo.album_arts.Add(info);
+ }
+ }
+
+ PLT_XmlHelper::GetChildText(entry, "originalTrackNumber", str, didl_namespace_upnp);
+ if (NPT_FAILED(str.ToInteger(value))) value = 0;
+ m_MiscInfo.original_track_number = value;
+
+ PLT_XmlHelper::GetChildText(entry, "lastPlaybackPosition", str, didl_namespace_upnp);
+ if (NPT_FAILED(PLT_Didl::ParseTimeStamp(str, value))) {
+ // fall back to raw integer parsing
+ if (NPT_FAILED(str.ToInteger(value))) value = 0;
+ }
+ m_MiscInfo.last_position = value;
+
+ PLT_XmlHelper::GetChildText(entry, "lastPlaybackTime", m_MiscInfo.last_time, didl_namespace_upnp, 256);
+ NPT_String parsed_last_time;
+ for (int format=0; format<=NPT_DateTime::FORMAT_RFC_1036; format++) {
+ NPT_DateTime date;
+ if (NPT_SUCCEEDED(date.FromString(m_MiscInfo.last_time, (NPT_DateTime::Format)format))) {
+ parsed_last_time = date.ToString((NPT_DateTime::Format)format);
+ break;
+ }
+ }
+ m_MiscInfo.last_time = parsed_last_time;
+
+ PLT_XmlHelper::GetChildText(entry, "playbackCount", str, didl_namespace_upnp);
+ if (NPT_FAILED(str.ToInteger(value))) value = -1;
+ m_MiscInfo.play_count = value;
+
+ children.Clear();
+ PLT_XmlHelper::GetChildren(entry, children, "res");
+ for (NPT_Cardinal i=0; i<children.GetItemCount(); i++) {
+ PLT_MediaItemResource resource;
+
+ // extract url
+ if (children[i]->GetText() == NULL) {
+ NPT_LOG_WARNING_1("No resource text found in: %s", (const char*)PLT_XmlHelper::Serialize(*children[i]));
+ } else {
+ resource.m_Uri = children[i]->GetText()->SubString(0, 1024);
+
+ // basic uri validation, ignoring scheme (could be rtsp)
+ NPT_HttpUrl url(resource.m_Uri, true);
+ if (!url.IsValid()) {
+ NPT_LOG_WARNING_1("Invalid resource uri: %s", (const char*)resource.m_Uri);
+ continue;
+ }
+ }
+
+ // extract protocol info
+ NPT_String protocol_info;
+ res = PLT_XmlHelper::GetAttribute(children[i], "protocolInfo", protocol_info, "", 256);
+ if (NPT_FAILED(res)) {
+ NPT_LOG_WARNING_1("No protocol info found in: %s", (const char*)PLT_XmlHelper::Serialize(*children[i]));
+ } else {
+ resource.m_ProtocolInfo = PLT_ProtocolInfo(protocol_info);
+ if (!resource.m_ProtocolInfo.IsValid()) {
+ NPT_LOG_WARNING_1("Invalid resource protocol info: %s", (const char*)protocol_info);
+ }
+ }
+
+ // extract known attributes
+ PLT_XmlHelper::GetAttribute(children[i], "protection", resource.m_Protection, "", 256);
+ PLT_XmlHelper::GetAttribute(children[i], "resolution", resource.m_Resolution, "", 256);
+
+ if (NPT_SUCCEEDED(PLT_XmlHelper::GetAttribute(children[i], "size", str, "", 256))) {
+ if (NPT_FAILED(str.ToInteger64(resource.m_Size))) resource.m_Size = (NPT_Size)-1;
+ }
+
+ if (NPT_SUCCEEDED(PLT_XmlHelper::GetAttribute(children[i], "duration", str, "", 256))) {
+ if (NPT_FAILED(PLT_Didl::ParseTimeStamp(str, resource.m_Duration))) {
+ // if error while converting, ignore and set to -1 to indicate we don't know the duration
+ resource.m_Duration = (NPT_UInt32)-1;
+ PLT_XmlHelper::RemoveAttribute(children[i], "duration");
+ } else {
+ // DLNA: reformat duration in case it was not compliant
+ str = PLT_Didl::FormatTimeStamp(resource.m_Duration);
+ PLT_XmlHelper::SetAttribute(children[i], "duration", str);
+ }
+ }
+ m_Resources.Add(resource);
+ }
+
+ PLT_XmlHelper::GetChildText(entry, "lastPlayerState", m_XbmcInfo.last_playerstate, didl_namespace_xbmc, 2048);
+
+ PLT_XmlHelper::GetChildText(entry, "dateadded", m_XbmcInfo.date_added, didl_namespace_xbmc, 256);
+ // parse date and make sure it's valid
+ for (int format=0; format<=NPT_DateTime::FORMAT_RFC_1036; format++) {
+ NPT_DateTime date;
+ if (NPT_SUCCEEDED(date.FromString(m_XbmcInfo.date_added, (NPT_DateTime::Format)format))) {
+ parsed_date = date.ToString((NPT_DateTime::Format)format);
+ break;
+ }
+ }
+ m_XbmcInfo.date_added = parsed_date;
+
+ PLT_XmlHelper::GetChildText(entry, "rating", str, didl_namespace_xbmc);
+ NPT_Float floatValue;
+ if (NPT_FAILED(str.ToFloat(floatValue))) floatValue = 0.0;
+ m_XbmcInfo.rating = floatValue;
+
+ PLT_XmlHelper::GetChildText(entry, "votes", str, didl_namespace_xbmc, 256);
+ NPT_Int32 intValue;
+ if (NPT_FAILED(str.ToInteger(intValue))) intValue = 0;
+ m_XbmcInfo.votes = intValue;
+
+ children.Clear();
+ PLT_XmlHelper::GetChildren(entry, children, "artwork", didl_namespace_xbmc);
+ m_XbmcInfo.artwork.FromDidl(children);
+
+ PLT_XmlHelper::GetChildText(entry, "uniqueidentifier", m_XbmcInfo.unique_identifier, didl_namespace_xbmc, 256);
+
+ // re serialize the entry didl as a we might need to pass it to a renderer
+ // we may have modified the tree to "fix" issues, so as not to break a renderer
+ // (don't write xml prefix as this didl could be part of a larger document)
+ //res = PLT_XmlHelper::Serialize(*entry, xml, false);
+ m_Didl = "";
+ res = ToDidl(PLT_FILTER_MASK_ALL, m_Didl);
+ NPT_CHECK_SEVERE(res);
+
+ m_Didl = didl_header + m_Didl + didl_footer;
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaObjectList::PLT_MediaObjectList
++---------------------------------------------------------------------*/
+PLT_MediaObjectList::PLT_MediaObjectList()
+{
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaObjectList::~PLT_MediaObjectList
++---------------------------------------------------------------------*/
+PLT_MediaObjectList::~PLT_MediaObjectList()
+{
+ Apply(NPT_ObjectDeleter<PLT_MediaObject>());
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaItem::PLT_MediaItem
++---------------------------------------------------------------------*/
+PLT_MediaItem::PLT_MediaItem()
+{
+ Reset();
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaItem::~PLT_MediaItem
++---------------------------------------------------------------------*/
+PLT_MediaItem::~PLT_MediaItem()
+{
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaItem::ToDidl
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaItem::ToDidl(const NPT_String& filter, NPT_String& didl)
+{
+ return PLT_MediaObject::ToDidl(filter, didl);
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaItem::ToDidl
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaItem::ToDidl(NPT_UInt64 mask, NPT_String& didl)
+{
+ didl += "<item id=\"";
+
+ PLT_Didl::AppendXmlEscape(didl, m_ObjectID);
+ didl += "\" parentID=\"";
+ PLT_Didl::AppendXmlEscape(didl, m_ParentID);
+
+ if ((mask & PLT_FILTER_MASK_REFID) && !m_ReferenceID.IsEmpty()) {
+ didl += "\" refID=\"";
+ PLT_Didl::AppendXmlEscape(didl, m_ReferenceID);
+ }
+
+ didl += "\" restricted=\"";
+ didl += m_Restricted?"1\"":"0\"";
+
+ didl += ">";
+
+ NPT_CHECK_SEVERE(PLT_MediaObject::ToDidl(mask, didl));
+
+ /* close tag */
+ didl += "</item>";
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaItem::FromDidl
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaItem::FromDidl(NPT_XmlElementNode* entry)
+{
+ /* reset first */
+ Reset();
+
+ if (entry->GetTag().Compare("item", true) != 0) {
+ NPT_CHECK_SEVERE(NPT_ERROR_INTERNAL);
+ }
+
+ NPT_Result result = PLT_MediaObject::FromDidl(entry);
+
+ return result;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaContainer::PLT_MediaContainer
++---------------------------------------------------------------------*/
+PLT_MediaContainer::PLT_MediaContainer()
+{
+ Reset();
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaContainer::~PLT_MediaContainer
++---------------------------------------------------------------------*/
+PLT_MediaContainer::~PLT_MediaContainer(void)
+{
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaContainer::Reset
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaContainer::Reset()
+{
+ m_SearchClasses.Clear();
+ m_Searchable = false;
+ m_ChildrenCount = -1;
+ m_ContainerUpdateID = 0;
+
+ return PLT_MediaObject::Reset();
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaContainer::ToDidl
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaContainer::ToDidl(const NPT_String& filter, NPT_String& didl)
+{
+ return PLT_MediaObject::ToDidl(filter, didl);
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaContainer::ToDidl
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaContainer::ToDidl(NPT_UInt64 mask, NPT_String& didl)
+{
+ // container id property
+ didl += "<container id=\"";
+ PLT_Didl::AppendXmlEscape(didl, m_ObjectID);
+
+ // parent id property
+ didl += "\" parentID=\"";
+ PLT_Didl::AppendXmlEscape(didl, m_ParentID);
+
+ // ref id
+ if ((mask & PLT_FILTER_MASK_REFID) && !m_ReferenceID.IsEmpty()) {
+ didl += "\" refID=\"";
+ PLT_Didl::AppendXmlEscape(didl, m_ReferenceID);
+ }
+
+ // restricted property
+ didl += "\" restricted=\"";
+ didl += m_Restricted?"1\"":"0\"";
+
+ // searchable property
+ if (mask & PLT_FILTER_MASK_SEARCHABLE) {
+ didl += " searchable=\"";
+ didl += m_Searchable?"1\"":"0\"";
+ }
+
+ // childcount property
+ if ((mask & PLT_FILTER_MASK_CHILDCOUNT) && m_ChildrenCount != -1) {
+ didl += " childCount=\"";
+ didl += NPT_String::FromInteger(m_ChildrenCount);
+ didl += "\"";
+ }
+
+ didl += ">";
+
+ if ((mask & PLT_FILTER_MASK_SEARCHCLASS) && m_SearchClasses.GetItemCount()) {
+ NPT_List<PLT_SearchClass>::Iterator search_class = m_SearchClasses.GetFirstItem();
+ while (search_class) {
+ didl += "<upnp:searchClass includeDerived=\"";
+ didl += (*search_class).include_derived?"1\"":"0\"";
+
+ // frienly name is any
+ if (!(*search_class).friendly_name.IsEmpty()) {
+ didl += " name=\"" + (*search_class).friendly_name + "\"";
+ }
+ didl += ">";
+ didl += (*search_class).type;
+ didl += "</upnp:searchClass>";
+
+ ++search_class;
+ }
+ }
+
+ NPT_CHECK_SEVERE(PLT_MediaObject::ToDidl(mask, didl));
+
+ /* close tag */
+ didl += "</container>";
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaContainer::FromDidl
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaContainer::FromDidl(NPT_XmlElementNode* entry)
+{
+ NPT_String str;
+
+ /* reset first */
+ Reset();
+
+ // check entry type
+ if (entry->GetTag().Compare("Container", true) != 0)
+ return NPT_ERROR_INTERNAL;
+
+ // check if item is searchable (is default true?)
+ if (NPT_SUCCEEDED(PLT_XmlHelper::GetAttribute(entry, "searchable", str, "", 5))) {
+ m_Searchable = PLT_Service::IsTrue(str);
+ }
+
+ // look for childCount
+ if (NPT_SUCCEEDED(PLT_XmlHelper::GetAttribute(entry, "childCount", str, "", 256))) {
+ NPT_UInt32 count;
+ NPT_CHECK_SEVERE(str.ToInteger(count));
+ m_ChildrenCount = count;
+ }
+
+ // upnp:searchClass child elements
+ NPT_Array<NPT_XmlElementNode*> children;
+ PLT_XmlHelper::GetChildren(entry, children, "upnp:searchClass");
+
+ for (NPT_Cardinal i=0; i<children.GetItemCount(); i++) {
+ PLT_SearchClass search_class;
+
+ // extract url
+ if (children[i]->GetText() == NULL) {
+ NPT_LOG_WARNING_1("No searchClass text found in: %s",
+ (const char*)PLT_XmlHelper::Serialize(*children[i]));
+ continue;
+ }
+
+ // DLNA 7.3.17.4
+ search_class.type = children[i]->GetText()->SubString(0, 256);
+
+ // extract optional attribute name
+ PLT_XmlHelper::GetAttribute(children[i], "name", search_class.friendly_name);
+
+ // includeDerived property
+ if (NPT_FAILED(PLT_XmlHelper::GetAttribute(children[i], "includeDerived", str))) {
+ NPT_LOG_WARNING_1("No required attribute searchClass@includeDerived found in: %s",
+ (const char*)PLT_XmlHelper::Serialize(*children[i]));
+ continue;
+ }
+
+ search_class.include_derived = PLT_Service::IsTrue(str);
+ m_SearchClasses.Add(search_class);
+ }
+
+ return PLT_MediaObject::FromDidl(entry);
+}
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.h b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.h
new file mode 100644
index 0000000..3a13967
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.h
@@ -0,0 +1,348 @@
+/*****************************************************************
+|
+| Platinum - AV Media Item
+|
+| Copyright (c) 2004-2010, Plutinosoft, LLC.
+| All rights reserved.
+| http://www.plutinosoft.com
+|
+| This program is free software; you can redistribute it and/or
+| modify it under the terms of the GNU General Public License
+| as published by the Free Software Foundation; either version 2
+| of the License, or (at your option) any later version.
+|
+| OEMs, ISVs, VARs and other distributors that combine and
+| distribute commercially licensed software with Platinum software
+| and do not wish to distribute the source code for the commercially
+| licensed software under version 2, or (at your option) any later
+| version, of the GNU General Public License (the "GPL") must enter
+| into a commercial license agreement with Plutinosoft, LLC.
+| licensing@plutinosoft.com
+|
+| This program is distributed in the hope that it will be useful,
+| but WITHOUT ANY WARRANTY; without even the implied warranty of
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+| GNU General Public License for more details.
+|
+| You should have received a copy of the GNU General Public License
+| along with this program; see the file LICENSE.txt. If not, write to
+| the Free Software Foundation, Inc.,
+| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+| http://www.gnu.org/licenses/gpl-2.0.html
+|
+****************************************************************/
+
+/** @file
+ UPnP AV Media Object reprensentation.
+ */
+
+#ifndef _PLT_MEDIA_ITEM_H_
+#define _PLT_MEDIA_ITEM_H_
+
+/*----------------------------------------------------------------------
+| includes
++---------------------------------------------------------------------*/
+#include "Neptune.h"
+#include "PltHttp.h"
+#include "PltProtocolInfo.h"
+
+/*----------------------------------------------------------------------
+| typedefs
++---------------------------------------------------------------------*/
+/**
+ The PLT_ObjectClass struct is used to assign a type to a PLT_MediaObject.
+ */
+typedef struct {
+ NPT_String type;
+ NPT_String friendly_name;
+} PLT_ObjectClass;
+
+typedef struct {
+ NPT_String type;
+ NPT_String friendly_name;
+ bool include_derived;
+} PLT_SearchClass;
+
+typedef struct {
+ NPT_String name;
+ NPT_String role;
+} PLT_PersonRole;
+
+class PLT_PersonRoles : public NPT_List<PLT_PersonRole>
+{
+public:
+ NPT_Result Add(const NPT_String& name, const NPT_String& role = "");
+ NPT_Result ToDidl(NPT_String& didl, const NPT_String& tag);
+ NPT_Result FromDidl(const NPT_Array<NPT_XmlElementNode*>& nodes);
+};
+
+typedef struct {
+ NPT_String allowed_use; // (CSV)
+ NPT_String validity_start;
+ NPT_String validity_end;
+ NPT_String remaining_time;
+ NPT_String usage_info;
+ NPT_String rights_info_uri;
+ NPT_String content_info_uri;
+} PLT_Constraint;
+
+typedef struct {
+ PLT_PersonRoles artists;
+ PLT_PersonRoles actors;
+ PLT_PersonRoles authors;
+ NPT_String producer; //TODO: can be multiple
+ PLT_PersonRoles directors;
+ NPT_List<NPT_String> publisher;
+ NPT_String contributor; // should match m_Creator (dc:creator) //TODO: can be multiple
+} PLT_PeopleInfo;
+
+typedef struct {
+ NPT_List<NPT_String> genres;
+ NPT_String album; //TODO: can be multiple
+ NPT_String playlist; // dc:title of the playlist item the content belongs too //TODO: can be multiple
+} PLT_AffiliationInfo;
+
+typedef struct {
+ NPT_String description;
+ NPT_String long_description;
+ NPT_String icon_uri;
+ NPT_String region;
+ NPT_String rating;
+ NPT_String rights; //TODO: can be multiple
+ NPT_String date;
+ NPT_String language;
+} PLT_Description;
+
+typedef struct {
+ NPT_String uri;
+ NPT_String dlna_profile;
+} PLT_AlbumArtInfo;
+
+typedef struct {
+ NPT_List<PLT_AlbumArtInfo> album_arts;
+ NPT_String artist_discography_uri;
+ NPT_String lyrics_uri;
+ NPT_List<NPT_String> relations; // dc:relation
+} PLT_ExtraInfo;
+
+typedef struct {
+ NPT_UInt32 dvdregioncode;
+ NPT_UInt32 original_track_number;
+ NPT_String toc;
+ NPT_String user_annotation; //TODO: can be multiple
+ NPT_UInt32 last_position;
+ NPT_String last_time;
+ NPT_Int32 play_count;
+} PLT_MiscInfo;
+
+typedef struct {
+ NPT_UInt64 total;
+ NPT_UInt64 used;
+ NPT_UInt64 free;
+ NPT_UInt64 max_partition;
+ NPT_UInt64 medium;
+} PLT_StorageInfo;
+
+typedef struct {
+ NPT_String program_title;
+ NPT_String series_title;
+ NPT_UInt32 episode_number;
+ NPT_UInt32 episode_count;
+ NPT_UInt32 episode_season;
+} PLT_RecordedInfo;
+
+typedef struct {
+ NPT_String type;
+ NPT_String url;
+} PLT_Artwork;
+
+class PLT_Artworks : public NPT_List<PLT_Artwork>
+{
+public:
+ NPT_Result Add(const NPT_String& type, const NPT_String& url);
+ NPT_Result ToDidl(NPT_String& didl, const NPT_String& tag);
+ NPT_Result FromDidl(const NPT_Array<NPT_XmlElementNode*>& nodes);
+};
+
+typedef struct {
+ NPT_String last_playerstate;
+ NPT_String date_added;
+ NPT_Float rating;
+ NPT_Int32 votes;
+ PLT_Artworks artwork;
+ NPT_String unique_identifier;
+ NPT_List<NPT_String> countries;
+ NPT_Int32 user_rating;
+} PLT_XbmcInfo;
+
+typedef struct {
+ NPT_String name;
+ NPT_Map<NPT_String, NPT_String> attributes;
+ NPT_String value;
+} PLT_SecResource;
+
+/*----------------------------------------------------------------------
+| PLT_MediaItemResource
++---------------------------------------------------------------------*/
+class PLT_MediaItemResource
+{
+public:
+ PLT_MediaItemResource();
+ ~PLT_MediaItemResource() {}
+
+ NPT_String m_Uri;
+ PLT_ProtocolInfo m_ProtocolInfo;
+ NPT_UInt32 m_Duration; /* seconds */
+ NPT_LargeSize m_Size;
+ NPT_String m_Protection;
+ NPT_UInt32 m_Bitrate; /* bytes/seconds */
+ NPT_UInt32 m_BitsPerSample;
+ NPT_UInt32 m_SampleFrequency;
+ NPT_UInt32 m_NbAudioChannels;
+ NPT_String m_Resolution;
+ NPT_UInt32 m_ColorDepth;
+ /* to add custom data to resource, that are not standard one, or are only
+ proper for some type of devices (UPnP)*/
+ NPT_Map<NPT_String, NPT_String> m_CustomData;
+};
+
+/*----------------------------------------------------------------------
+| PLT_MediaObject
++---------------------------------------------------------------------*/
+/**
+ The PLT_MediaObject class is any data entity that can be returned by a
+ ContentDirectory Service from a browsing or searching action. This is the
+ base class from which PLT_MediaItem and PLT_MediaContainer derive.
+ */
+class PLT_MediaObject
+{
+protected:
+ NPT_IMPLEMENT_DYNAMIC_CAST(PLT_MediaObject)
+
+ PLT_MediaObject() : m_Restricted(true) {}
+
+public:
+ virtual ~PLT_MediaObject() {}
+
+ bool IsContainer() { return m_ObjectClass.type.StartsWith("object.container"); }
+
+ static const char* GetUPnPClass(const char* filename,
+ const PLT_HttpRequestContext* context = NULL);
+
+ virtual NPT_Result Reset();
+ virtual NPT_Result ToDidl(const NPT_String& filter, NPT_String& didl);
+ virtual NPT_Result ToDidl(NPT_UInt64 mask, NPT_String& didl);
+ virtual NPT_Result FromDidl(NPT_XmlElementNode* entry);
+
+public:
+ /* common properties */
+ PLT_ObjectClass m_ObjectClass;
+ NPT_String m_ObjectID;
+ NPT_String m_ParentID;
+ NPT_String m_ReferenceID;
+
+ /* metadata */
+ NPT_String m_Title;
+ NPT_String m_Creator;
+ NPT_String m_Date;
+ PLT_PeopleInfo m_People;
+ PLT_AffiliationInfo m_Affiliation;
+ PLT_Description m_Description;
+ PLT_RecordedInfo m_Recorded;
+
+ /* properties */
+ bool m_Restricted;
+
+ /* extras */
+ PLT_ExtraInfo m_ExtraInfo;
+
+ /* miscellaneous info */
+ PLT_MiscInfo m_MiscInfo;
+
+ /* resources related */
+ NPT_Array<PLT_MediaItemResource> m_Resources;
+
+ /* sec resources related */
+ NPT_Array<PLT_SecResource> m_SecResources;
+
+ /* XBMC specific */
+ PLT_XbmcInfo m_XbmcInfo;
+
+ /* original DIDL for Control Points to pass to a renderer when invoking SetAVTransportURI */
+ NPT_String m_Didl;
+};
+
+/*----------------------------------------------------------------------
+| PLT_MediaItem
++---------------------------------------------------------------------*/
+/**
+ The PLT_MediaItem class represents a first-level class derived directly from
+ PLT_MediaObject. It most often represents a single piece of AV data.
+ */
+class PLT_MediaItem : public PLT_MediaObject
+{
+public:
+ NPT_IMPLEMENT_DYNAMIC_CAST_D(PLT_MediaItem, PLT_MediaObject)
+
+ PLT_MediaItem();
+ ~PLT_MediaItem() override;
+
+ // PLT_MediaObject methods
+ NPT_Result ToDidl(const NPT_String& filter, NPT_String& didl) override;
+ NPT_Result ToDidl(NPT_UInt64 mask, NPT_String& didl) override;
+ NPT_Result FromDidl(NPT_XmlElementNode* entry) override;
+};
+
+/*----------------------------------------------------------------------
+| PLT_MediaContainer
++---------------------------------------------------------------------*/
+/**
+ The PLT_MediaContainer class represents a first-level class derived directly
+ from PLT_MediaObject. A PLT_MediaContainer represents a collection of
+ PLT_MediaObject instances.
+ */
+class PLT_MediaContainer : public PLT_MediaObject
+{
+public:
+ NPT_IMPLEMENT_DYNAMIC_CAST_D(PLT_MediaContainer, PLT_MediaObject)
+
+ PLT_MediaContainer();
+ ~PLT_MediaContainer() override;
+
+ // PLT_MediaObject methods
+ NPT_Result Reset() override;
+ NPT_Result ToDidl(const NPT_String& filter, NPT_String& didl) override;
+ NPT_Result ToDidl(NPT_UInt64 mask, NPT_String& didl) override;
+ NPT_Result FromDidl(NPT_XmlElementNode* entry) override;
+
+public:
+ NPT_List<PLT_SearchClass> m_SearchClasses;
+
+ /* properties */
+ bool m_Searchable;
+
+ /* container info related */
+ NPT_Int32 m_ChildrenCount;
+ NPT_UInt32 m_ContainerUpdateID;
+};
+
+/*----------------------------------------------------------------------
+| PLT_MediaObjectList
++---------------------------------------------------------------------*/
+/**
+ The PLT_MediaObjectList class is a list of PLT_MediaObject instances.
+ */
+class PLT_MediaObjectList : public NPT_List<PLT_MediaObject*>
+{
+public:
+ PLT_MediaObjectList();
+
+protected:
+ virtual ~PLT_MediaObjectList(void);
+ friend class NPT_Reference<PLT_MediaObjectList>;
+};
+
+typedef NPT_Reference<PLT_MediaObjectList> PLT_MediaObjectListReference;
+typedef NPT_Reference<PLT_MediaObject> PLT_MediaObjectReference;
+
+#endif /* _PLT_MEDIA_ITEM_H_ */
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaServer.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaServer.cpp
new file mode 100644
index 0000000..8686aa9
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaServer.cpp
@@ -0,0 +1,711 @@
+/*****************************************************************
+|
+| Platinum - AV Media Server Device
+|
+| Copyright (c) 2004-2010, Plutinosoft, LLC.
+| All rights reserved.
+| http://www.plutinosoft.com
+|
+| This program is free software; you can redistribute it and/or
+| modify it under the terms of the GNU General Public License
+| as published by the Free Software Foundation; either version 2
+| of the License, or (at your option) any later version.
+|
+| OEMs, ISVs, VARs and other distributors that combine and
+| distribute commercially licensed software with Platinum software
+| and do not wish to distribute the source code for the commercially
+| licensed software under version 2, or (at your option) any later
+| version, of the GNU General Public License (the "GPL") must enter
+| into a commercial license agreement with Plutinosoft, LLC.
+| licensing@plutinosoft.com
+|
+| This program is distributed in the hope that it will be useful,
+| but WITHOUT ANY WARRANTY; without even the implied warranty of
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+| GNU General Public License for more details.
+|
+| You should have received a copy of the GNU General Public License
+| along with this program; see the file LICENSE.txt. If not, write to
+| the Free Software Foundation, Inc.,
+| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+| http://www.gnu.org/licenses/gpl-2.0.html
+|
+****************************************************************/
+
+/*----------------------------------------------------------------------
+| includes
++---------------------------------------------------------------------*/
+#include "PltUPnP.h"
+#include "PltMediaServer.h"
+#include "PltMediaItem.h"
+#include "PltService.h"
+#include "PltTaskManager.h"
+#include "PltHttpServer.h"
+#include "PltDidl.h"
+
+NPT_SET_LOCAL_LOGGER("platinum.media.server")
+
+/*----------------------------------------------------------------------
+| forward references
++---------------------------------------------------------------------*/
+extern NPT_UInt8 MS_ConnectionManagerSCPD[];
+extern NPT_UInt8 MS_ContentDirectorywSearchSCPD[];
+
+const char* BrowseFlagsStr[] = {
+ "BrowseMetadata",
+ "BrowseDirectChildren"
+};
+
+/*----------------------------------------------------------------------
+| PLT_MediaServer::PLT_MediaServer
++---------------------------------------------------------------------*/
+PLT_MediaServer::PLT_MediaServer(const char* friendly_name,
+ bool show_ip /* = false */,
+ const char* uuid /* = NULL */,
+ NPT_UInt16 port /* = 0 */,
+ bool port_rebind /* = false */) :
+ PLT_DeviceHost("/DeviceDescription.xml",
+ uuid,
+ "urn:schemas-upnp-org:device:MediaServer:1",
+ friendly_name,
+ show_ip,
+ port,
+ port_rebind),
+ m_Delegate(NULL)
+{
+ m_ModelDescription = "Plutinosoft AV Media Server Device";
+ m_ModelName = "AV Media Server Device";
+ m_ModelURL = "http://www.plutinosoft.com/platinum";
+ m_DlnaDoc = "DMS-1.50";
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaServer::~PLT_MediaServer
++---------------------------------------------------------------------*/
+PLT_MediaServer::~PLT_MediaServer()
+{
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaServer::SetupServices
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaServer::SetupServices()
+{
+ NPT_Reference<PLT_Service> service;
+
+ {
+ service = new PLT_Service(
+ this,
+ "urn:schemas-upnp-org:service:ContentDirectory:1",
+ "urn:upnp-org:serviceId:ContentDirectory",
+ "ContentDirectory");
+ NPT_CHECK_FATAL(service->SetSCPDXML((const char*) MS_ContentDirectorywSearchSCPD));
+ NPT_CHECK_FATAL(AddService(service.AsPointer()));
+
+ service->SetStateVariable("ContainerUpdateIDs", "");
+ service->SetStateVariableRate("ContainerUpdateIDs", NPT_TimeInterval(2.));
+ service->SetStateVariable("SystemUpdateID", "0");
+ service->SetStateVariableRate("SystemUpdateID", NPT_TimeInterval(2.));
+ service->SetStateVariable("SearchCapability", "@id,@refID,dc:title,upnp:class,upnp:genre,upnp:artist,upnp:author,upnp:author@role,upnp:album,dc:creator,res@size,res@duration,res@protocolInfo,res@protection,dc:publisher,dc:language,upnp:originalTrackNumber,dc:date,upnp:producer,upnp:rating,upnp:actor,upnp:director,upnp:toc,dc:description,microsoft:userRatingInStars,microsoft:userEffectiveRatingInStars,microsoft:userRating,microsoft:userEffectiveRating,microsoft:serviceProvider,microsoft:artistAlbumArtist,microsoft:artistPerformer,microsoft:artistConductor,microsoft:authorComposer,microsoft:authorOriginalLyricist,microsoft:authorWriter,upnp:userAnnotation,upnp:channelName,upnp:longDescription,upnp:programTitle");
+ service->SetStateVariable("SortCapability", "dc:title,upnp:genre,upnp:album,dc:creator,res@size,res@duration,res@bitrate,dc:publisher,dc:language,upnp:originalTrackNumber,dc:date,upnp:producer,upnp:rating,upnp:actor,upnp:director,upnp:toc,dc:description,microsoft:year,microsoft:userRatingInStars,microsoft:userEffectiveRatingInStars,microsoft:userRating,microsoft:userEffectiveRating,microsoft:serviceProvider,microsoft:artistAlbumArtist,microsoft:artistPerformer,microsoft:artistConductor,microsoft:authorComposer,microsoft:authorOriginalLyricist,microsoft:authorWriter,microsoft:sourceUrl,upnp:userAnnotation,upnp:channelName,upnp:longDescription,upnp:programTitle");
+
+ service.Detach();
+ service = NULL;
+ }
+
+ {
+ service = new PLT_Service(
+ this,
+ "urn:schemas-upnp-org:service:ConnectionManager:1",
+ "urn:upnp-org:serviceId:ConnectionManager",
+ "ConnectionManager");
+ NPT_CHECK_FATAL(service->SetSCPDXML((const char*) MS_ConnectionManagerSCPD));
+ NPT_CHECK_FATAL(AddService(service.AsPointer()));
+
+ service->SetStateVariable("CurrentConnectionIDs", "0");
+ service->SetStateVariable("SinkProtocolInfo", "");
+ service->SetStateVariable("SourceProtocolInfo", "http-get:*:*:*");
+
+ service.Detach();
+ service = NULL;
+ }
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaServer::UpdateSystemUpdateID
++---------------------------------------------------------------------*/
+void
+PLT_MediaServer::UpdateSystemUpdateID(NPT_UInt32 update)
+{
+ NPT_COMPILER_UNUSED(update);
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaServer::UpdateContainerUpdateID
++---------------------------------------------------------------------*/
+void PLT_MediaServer::UpdateContainerUpdateID(const char* id, NPT_UInt32 update)
+{
+ NPT_COMPILER_UNUSED(id);
+ NPT_COMPILER_UNUSED(update);
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaServer::OnAction
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaServer::OnAction(PLT_ActionReference& action,
+ const PLT_HttpRequestContext& context)
+{
+ /* parse the action name */
+ NPT_String name = action->GetActionDesc().GetName();
+
+ // ContentDirectory
+ if (name.Compare("Browse", true) == 0) {
+ return OnBrowse(action, context);
+ }
+ if (name.Compare("Search", true) == 0) {
+ return OnSearch(action, context);
+ }
+ if (name.Compare("UpdateObject", true) == 0) {
+ return OnUpdate(action, context);
+ }
+ if (name.Compare("GetSystemUpdateID", true) == 0) {
+ return OnGetSystemUpdateID(action, context);
+ }
+ if (name.Compare("GetSortCapabilities", true) == 0) {
+ return OnGetSortCapabilities(action, context);
+ }
+ if (name.Compare("GetSearchCapabilities", true) == 0) {
+ return OnGetSearchCapabilities(action, context);
+ }
+
+ // ConnectionMananger
+ if (name.Compare("GetCurrentConnectionIDs", true) == 0) {
+ return OnGetCurrentConnectionIDs(action, context);
+ }
+ if (name.Compare("GetProtocolInfo", true) == 0) {
+ return OnGetProtocolInfo(action, context);
+ }
+ if (name.Compare("GetCurrentConnectionInfo", true) == 0) {
+ return OnGetCurrentConnectionInfo(action, context);
+ }
+
+ action->SetError(401,"No Such Action.");
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_FileMediaServer::ProcessHttpGetRequest
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaServer::ProcessHttpGetRequest(NPT_HttpRequest& request,
+ const NPT_HttpRequestContext& context,
+ NPT_HttpResponse& response)
+{
+ /* Try to handle file request */
+ if (m_Delegate) return m_Delegate->ProcessFileRequest(request, context, response);
+
+ return NPT_ERROR_NO_SUCH_ITEM;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaServer::OnGetCurrentConnectionIDs
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaServer::OnGetCurrentConnectionIDs(PLT_ActionReference& action,
+ const PLT_HttpRequestContext& context)
+{
+ NPT_COMPILER_UNUSED(context);
+
+ return action->SetArgumentsOutFromStateVariable();
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaServer::OnGetProtocolInfo
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaServer::OnGetProtocolInfo(PLT_ActionReference& action,
+ const PLT_HttpRequestContext& context)
+{
+ NPT_COMPILER_UNUSED(context);
+
+ return action->SetArgumentsOutFromStateVariable();
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaServer::OnGetCurrentConnectionInfo
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaServer::OnGetCurrentConnectionInfo(PLT_ActionReference& action,
+ const PLT_HttpRequestContext& context)
+{
+ NPT_COMPILER_UNUSED(context);
+
+ if (NPT_FAILED(action->VerifyArgumentValue("ConnectionID", "0"))) {
+ action->SetError(706,"No Such Connection.");
+ return NPT_FAILURE;
+ }
+
+ if (NPT_FAILED(action->SetArgumentValue("RcsID", "-1"))){
+ return NPT_FAILURE;
+ }
+ if (NPT_FAILED(action->SetArgumentValue("AVTransportID", "-1"))) {
+ return NPT_FAILURE;
+ }
+ if (NPT_FAILED(action->SetArgumentValue("ProtocolInfo", "http-get:*:*:*"))) {
+ return NPT_FAILURE;
+ }
+ if (NPT_FAILED(action->SetArgumentValue("PeerConnectionManager", "/"))) {
+ return NPT_FAILURE;
+ }
+ if (NPT_FAILED(action->SetArgumentValue("PeerConnectionID", "-1"))) {
+ return NPT_FAILURE;
+ }
+ if (NPT_FAILED(action->SetArgumentValue("Direction", "Output"))) {
+ return NPT_FAILURE;
+ }
+ if (NPT_FAILED(action->SetArgumentValue("Status", "Unknown"))) {
+ return NPT_FAILURE;
+ }
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaServer::OnGetSortCapabilities
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaServer::OnGetSortCapabilities(PLT_ActionReference& action,
+ const PLT_HttpRequestContext& context)
+{
+ NPT_COMPILER_UNUSED(context);
+
+ return action->SetArgumentsOutFromStateVariable();
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaServer::OnGetSearchCapabilities
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaServer::OnGetSearchCapabilities(PLT_ActionReference& action,
+ const PLT_HttpRequestContext& context)
+{
+ NPT_COMPILER_UNUSED(context);
+
+ return action->SetArgumentsOutFromStateVariable();
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaServer::OnGetSystemUpdateID
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaServer::OnGetSystemUpdateID(PLT_ActionReference& action,
+ const PLT_HttpRequestContext& context)
+{
+ NPT_COMPILER_UNUSED(context);
+
+ return action->SetArgumentsOutFromStateVariable();
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaServer::ParseBrowseFlag
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaServer::ParseBrowseFlag(const char* str, BrowseFlags& flag)
+{
+ if (NPT_String::Compare(str, BrowseFlagsStr[0], true) == 0) {
+ flag = BROWSEMETADATA;
+ return NPT_SUCCESS;
+ }
+ if (NPT_String::Compare(str, BrowseFlagsStr[1], true) == 0) {
+ flag = BROWSEDIRECTCHILDREN;
+ return NPT_SUCCESS;
+ }
+ return NPT_FAILURE;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaServer::ParseSort
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaServer::ParseSort(const NPT_String& sort, NPT_List<NPT_String>& list)
+{
+ // reset output params first
+ list.Clear();
+
+ // easy out
+ if (sort.GetLength() == 0 || sort == "*") return NPT_SUCCESS;
+
+ list = sort.Split(",");
+
+ // verify each property has a namespace
+ NPT_List<NPT_String>::Iterator property = list.GetFirstItem();
+ while (property) {
+ NPT_List<NPT_String> parsed_property = (*property).Split(":");
+ if (parsed_property.GetItemCount() != 2)
+ parsed_property = (*property).Split("@");
+ if (parsed_property.GetItemCount() != 2 ||
+ (!(*property).StartsWith("-") && !(*property).StartsWith("+"))) {
+ NPT_LOG_WARNING_1("Invalid SortCriteria property %s", (*property).GetChars());
+ return NPT_FAILURE;
+ }
+ property++;
+ }
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaServer::ParseTagList
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaServer::ParseTagList(const NPT_String& updates, NPT_Map<NPT_String,NPT_String>& tags)
+{
+ // reset output params first
+ tags.Clear();
+
+ NPT_List<NPT_String> split = updates.Split(",");
+ NPT_XmlNode* node = NULL;
+ NPT_XmlElementNode* didl_partial = NULL;
+ NPT_XmlParser parser;
+
+ // as these are single name value pairs, separated by commas we wrap in a tag
+ // to create a valid tree
+ NPT_String xml("<TagValueList>");
+ for (NPT_List<NPT_String>::Iterator entry = split.GetFirstItem(); entry; entry++) {
+ NPT_String& element = (*entry);
+ if (element.IsEmpty())
+ xml.Append("<empty>empty</empty>");
+ else
+ xml.Append(element);
+ }
+ xml.Append("</TagValueList>");
+
+ NPT_LOG_FINE("Parsing TagList...");
+ NPT_CHECK_LABEL_SEVERE(parser.Parse(xml, node), cleanup);
+ if (!node || !node->AsElementNode()) {
+ NPT_LOG_SEVERE("Invalid node type");
+ goto cleanup;
+ }
+
+ didl_partial = node->AsElementNode();
+ if (didl_partial->GetTag().Compare("TagValueList", true)) {
+ NPT_LOG_SEVERE("Invalid node tag");
+ goto cleanup;
+ }
+
+ for (NPT_List<NPT_XmlNode*>::Iterator children = didl_partial->GetChildren().GetFirstItem(); children; children++) {
+ NPT_XmlElementNode* child = (*children)->AsElementNode();
+ if (!child) continue;
+ const NPT_String *txt = child->GetText();
+ tags[child->GetTag()] = txt ? txt->GetChars() : "";
+ }
+
+ return NPT_SUCCESS;
+
+cleanup:
+ if (node) delete node;
+ return NPT_FAILURE;
+}
+
+
+/*----------------------------------------------------------------------
+| PLT_MediaServer::OnBrowse
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaServer::OnBrowse(PLT_ActionReference& action,
+ const PLT_HttpRequestContext& context)
+{
+ NPT_Result res;
+ NPT_String object_id;
+ NPT_String browse_flag_val;
+ NPT_String filter;
+ NPT_String start;
+ NPT_String count;
+ NPT_String sort;
+ NPT_List<NPT_String> sort_list;
+
+ if (NPT_FAILED(action->GetArgumentValue("ObjectId", object_id)) ||
+ NPT_FAILED(action->GetArgumentValue("BrowseFlag", browse_flag_val)) ||
+ NPT_FAILED(action->GetArgumentValue("Filter", filter)) ||
+ NPT_FAILED(action->GetArgumentValue("StartingIndex", start)) ||
+ NPT_FAILED(action->GetArgumentValue("RequestedCount", count)) ||
+ NPT_FAILED(action->GetArgumentValue("SortCriteria", sort))) {
+ NPT_LOG_WARNING("Missing arguments");
+ action->SetError(402, "Invalid args");
+ return NPT_SUCCESS;
+ }
+
+ /* extract flag */
+ BrowseFlags flag;
+ if (NPT_FAILED(ParseBrowseFlag(browse_flag_val, flag))) {
+ /* error */
+ NPT_LOG_WARNING_1("BrowseFlag value not allowed (%s)", (const char*)browse_flag_val);
+ action->SetError(402, "Invalid args");
+ return NPT_SUCCESS;
+ }
+
+ /* convert index and counts to int */
+ NPT_UInt32 starting_index, requested_count;
+ if (NPT_FAILED(start.ToInteger(starting_index)) ||
+ NPT_FAILED(count.ToInteger(requested_count)) ||
+ PLT_Didl::ConvertFilterToMask(filter) == 0) {
+ NPT_LOG_WARNING_3("Invalid arguments (%s, %s, %s)",
+ start.GetChars(), count.GetChars(), filter.GetChars());
+ action->SetError(402, "Invalid args");
+ return NPT_FAILURE;
+ }
+
+ /* parse sort criteria for validation */
+ if (NPT_FAILED(ParseSort(sort, sort_list))) {
+ NPT_LOG_WARNING_1("Unsupported or invalid sort criteria error (%s)",
+ sort.GetChars());
+ action->SetError(709, "Unsupported or invalid sort criteria error");
+ return NPT_FAILURE;
+ }
+
+ NPT_LOG_FINE_6("Processing %s from %s with id=\"%s\", filter=\"%s\", start=%d, count=%d",
+ (const char*)browse_flag_val,
+ (const char*)context.GetRemoteAddress().GetIpAddress().ToString(),
+ (const char*)object_id,
+ (const char*)filter,
+ starting_index,
+ requested_count);
+
+ /* Invoke the browse function */
+ if (flag == BROWSEMETADATA) {
+ res = OnBrowseMetadata(
+ action,
+ object_id,
+ filter,
+ starting_index,
+ requested_count,
+ sort,
+ context);
+ } else {
+ res = OnBrowseDirectChildren(
+ action,
+ object_id,
+ filter,
+ starting_index,
+ requested_count,
+ sort,
+ context);
+ }
+
+ if (NPT_FAILED(res) && (action->GetErrorCode() == 0)) {
+ action->SetError(800, "Internal error");
+ }
+
+ return res;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaServer::OnSearch
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaServer::OnSearch(PLT_ActionReference& action,
+ const PLT_HttpRequestContext& context)
+{
+ NPT_COMPILER_UNUSED(context);
+
+ NPT_Result res;
+ NPT_String container_id;
+ NPT_String search;
+ NPT_String filter;
+ NPT_String start;
+ NPT_String count;
+ NPT_String sort;
+ NPT_List<NPT_String> sort_list;
+
+ if (NPT_FAILED(action->GetArgumentValue("ContainerId", container_id)) ||
+ NPT_FAILED(action->GetArgumentValue("SearchCriteria", search)) ||
+ NPT_FAILED(action->GetArgumentValue("Filter", filter)) ||
+ NPT_FAILED(action->GetArgumentValue("StartingIndex", start)) ||
+ NPT_FAILED(action->GetArgumentValue("RequestedCount", count)) ||
+ NPT_FAILED(action->GetArgumentValue("SortCriteria", sort))) {
+ NPT_LOG_WARNING("Missing arguments");
+ action->SetError(402, "Invalid args");
+ return NPT_SUCCESS;
+ }
+
+ /* convert index and counts to int */
+ NPT_UInt32 starting_index, requested_count;
+ if (NPT_FAILED(start.ToInteger(starting_index)) ||
+ NPT_FAILED(count.ToInteger(requested_count))) {
+ NPT_LOG_WARNING_2("Invalid arguments (%s, %s)",
+ start.GetChars(), count.GetChars());
+ action->SetError(402, "Invalid args");
+ return NPT_FAILURE;
+ }
+
+ /* parse sort criteria */
+ if (NPT_FAILED(ParseSort(sort, sort_list))) {
+ NPT_LOG_WARNING_1("Unsupported or invalid sort criteria error (%s)",
+ sort.GetChars());
+ action->SetError(709, "Unsupported or invalid sort criteria error");
+ return NPT_FAILURE;
+ }
+
+ NPT_LOG_INFO_5("Processing Search from %s with id=\"%s\", search=\"%s\", start=%d, count=%d",
+ (const char*)context.GetRemoteAddress().GetIpAddress().ToString(),
+ (const char*)container_id,
+ (const char*)search,
+ starting_index,
+ requested_count);
+
+ if (search.IsEmpty() || search == "*") {
+ res = OnBrowseDirectChildren(
+ action,
+ container_id,
+ filter,
+ starting_index,
+ requested_count,
+ sort,
+ context);
+ } else {
+ res = OnSearchContainer(
+ action,
+ container_id,
+ search,
+ filter,
+ starting_index,
+ requested_count,
+ sort,
+ context);
+ }
+
+ if (NPT_FAILED(res) && (action->GetErrorCode() == 0)) {
+ action->SetError(800, "Internal error");
+ }
+
+ return res;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaServer::OnUpdate
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaServer::OnUpdate(PLT_ActionReference& action,
+ const PLT_HttpRequestContext& context)
+{
+ if (!m_Delegate)
+ return NPT_ERROR_NOT_IMPLEMENTED;
+
+ int err;
+ const char* msg = NULL;
+
+ NPT_String object_id, current_xml, new_xml;
+ NPT_Map<NPT_String,NPT_String> curr_values;
+ NPT_Map<NPT_String,NPT_String> new_values;
+
+ NPT_CHECK_LABEL(action->GetArgumentValue("ObjectID", object_id), args);
+ NPT_CHECK_LABEL(object_id.IsEmpty(),args);
+ NPT_CHECK_LABEL(action->GetArgumentValue("CurrentTagValue", current_xml), args);
+ NPT_CHECK_LABEL(action->GetArgumentValue("NewTagValue", new_xml), args);
+
+ if (NPT_FAILED(ParseTagList(current_xml, curr_values))) {
+ err = 702;
+ msg = "Invalid currentTagvalue";
+ goto failure;
+ }
+ if (NPT_FAILED(ParseTagList(new_xml, new_values))) {
+ err = 703;
+ msg = "Invalid newTagValue";
+ goto failure;
+ }
+
+ if (curr_values.GetEntryCount() != new_values.GetEntryCount()) {
+ err = 706;
+ msg = "Paramater mismatch";
+ goto failure;
+ }
+
+ return m_Delegate->OnUpdateObject(action, object_id, curr_values, new_values, context);
+
+args:
+ err = 402;
+ msg = "Invalid args";
+
+failure:
+ NPT_LOG_WARNING_1("%s", msg);
+ action->SetError(err, msg);
+ return NPT_FAILURE;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaServer::OnBrowseMetadata
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaServer::OnBrowseMetadata(PLT_ActionReference& action,
+ const char* object_id,
+ const char* filter,
+ NPT_UInt32 starting_index,
+ NPT_UInt32 requested_count,
+ const char* sort_criteria,
+ const PLT_HttpRequestContext& context)
+{
+ if (m_Delegate) {
+ return m_Delegate->OnBrowseMetadata(action,
+ object_id,
+ filter,
+ starting_index,
+ requested_count,
+ sort_criteria,
+ context);
+ }
+ return NPT_ERROR_NOT_IMPLEMENTED;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaServer::OnBrowseDirectChildren
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaServer::OnBrowseDirectChildren(PLT_ActionReference& action,
+ const char* object_id,
+ const char* filter,
+ NPT_UInt32 starting_index,
+ NPT_UInt32 requested_count,
+ const char* sort_criteria,
+ const PLT_HttpRequestContext& context)
+{
+ if (m_Delegate) {
+ return m_Delegate->OnBrowseDirectChildren(action,
+ object_id,
+ filter,
+ starting_index,
+ requested_count,
+ sort_criteria,
+ context);
+ }
+ return NPT_ERROR_NOT_IMPLEMENTED;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaServer::OnSearchContainer
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaServer::OnSearchContainer(PLT_ActionReference& action,
+ const char* object_id,
+ const char* search_criteria,
+ const char* filter,
+ NPT_UInt32 starting_index,
+ NPT_UInt32 requested_count,
+ const char* sort_criteria,
+ const PLT_HttpRequestContext& context)
+{
+ if (m_Delegate) {
+ return m_Delegate->OnSearchContainer(action,
+ object_id,
+ search_criteria,
+ filter,
+ starting_index,
+ requested_count,
+ sort_criteria,
+ context);
+ }
+ return NPT_ERROR_NOT_IMPLEMENTED;
+}
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaServer.h b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaServer.h
new file mode 100644
index 0000000..d35d8d8
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaServer.h
@@ -0,0 +1,196 @@
+/*****************************************************************
+|
+| Platinum - AV Media Server Device
+|
+| Copyright (c) 2004-2010, Plutinosoft, LLC.
+| All rights reserved.
+| http://www.plutinosoft.com
+|
+| This program is free software; you can redistribute it and/or
+| modify it under the terms of the GNU General Public License
+| as published by the Free Software Foundation; either version 2
+| of the License, or (at your option) any later version.
+|
+| OEMs, ISVs, VARs and other distributors that combine and
+| distribute commercially licensed software with Platinum software
+| and do not wish to distribute the source code for the commercially
+| licensed software under version 2, or (at your option) any later
+| version, of the GNU General Public License (the "GPL") must enter
+| into a commercial license agreement with Plutinosoft, LLC.
+| licensing@plutinosoft.com
+|
+| This program is distributed in the hope that it will be useful,
+| but WITHOUT ANY WARRANTY; without even the implied warranty of
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+| GNU General Public License for more details.
+|
+| You should have received a copy of the GNU General Public License
+| along with this program; see the file LICENSE.txt. If not, write to
+| the Free Software Foundation, Inc.,
+| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+| http://www.gnu.org/licenses/gpl-2.0.html
+|
+****************************************************************/
+
+/** @file
+ UPnP AV Media Server.
+ */
+
+#ifndef _PLT_MEDIA_SERVER_H_
+#define _PLT_MEDIA_SERVER_H_
+
+/*----------------------------------------------------------------------
+| includes
++---------------------------------------------------------------------*/
+#include "Neptune.h"
+#include "PltDeviceHost.h"
+#include "PltMediaItem.h"
+
+/*----------------------------------------------------------------------
+| constants
++---------------------------------------------------------------------*/
+#define MAX_PATH_LENGTH 1024
+
+/*----------------------------------------------------------------------
+| PLT_MediaServerDelegate
++---------------------------------------------------------------------*/
+/**
+ The PLT_MediaServerDelegate class is an interface for delegating the handling
+ of the required UPnP AV ContentDirectory service actions. It also handles
+ resource HTTP requests (downloading).
+ */
+class PLT_MediaServerDelegate
+{
+public:
+ PLT_MediaServerDelegate() {}
+ virtual ~PLT_MediaServerDelegate() {}
+
+ virtual NPT_Result OnBrowseMetadata(PLT_ActionReference& /*action*/,
+ const char* /*object_id*/,
+ const char* /*filter*/,
+ NPT_UInt32 /*starting_index*/,
+ NPT_UInt32 /*requested_count*/,
+ const char* /*sort_criteria*/,
+ const PLT_HttpRequestContext& /*context*/) = 0;
+ virtual NPT_Result OnBrowseDirectChildren(PLT_ActionReference& /*action*/,
+ const char* /*object_id*/,
+ const char* /*filter*/,
+ NPT_UInt32 /*starting_index*/,
+ NPT_UInt32 /*requested_count*/,
+ const char* /*sort_criteria*/,
+ const PLT_HttpRequestContext& /*context*/) = 0;
+ virtual NPT_Result OnSearchContainer(PLT_ActionReference& /*action*/,
+ const char* /*container_id*/,
+ const char* /*search_criteria*/,
+ const char* /*filter*/,
+ NPT_UInt32 /*starting_index*/,
+ NPT_UInt32 /*requested_count*/,
+ const char* /*sort_criteria*/,
+ const PLT_HttpRequestContext& /*context*/) = 0;
+ virtual NPT_Result OnUpdateObject(PLT_ActionReference& /*action*/,
+ const char* /*object_id*/,
+ NPT_Map<NPT_String,NPT_String>& /*current_vals*/,
+ NPT_Map<NPT_String,NPT_String>& /*new_vals*/,
+ const PLT_HttpRequestContext& /*context*/) = 0;
+
+ virtual NPT_Result ProcessFileRequest(NPT_HttpRequest& /*request*/,
+ const NPT_HttpRequestContext& /*context*/,
+ NPT_HttpResponse& /*response*/) = 0;
+};
+
+/*----------------------------------------------------------------------
+| PLT_MediaServer
++---------------------------------------------------------------------*/
+/**
+ The PLT_MediaServer class implements the base class for a UPnP AV
+ Media Server device.
+ */
+class PLT_MediaServer : public PLT_DeviceHost
+{
+public:
+ /* BrowseFlags */
+ enum BrowseFlags {
+ BROWSEMETADATA,
+ BROWSEDIRECTCHILDREN
+ };
+
+ // class methods
+ static NPT_Result ParseBrowseFlag(const char* str, BrowseFlags& flag);
+ static NPT_Result ParseSort(const NPT_String& sort, NPT_List<NPT_String>& list);
+ static NPT_Result ParseTagList(const NPT_String& updates, NPT_Map<NPT_String,NPT_String>& tags);
+
+ // constructor
+ PLT_MediaServer(const char* friendly_name,
+ bool show_ip = false,
+ const char* uuid = NULL,
+ NPT_UInt16 port = 0,
+ bool port_rebind = false);
+
+ // methods
+ virtual void SetDelegate(PLT_MediaServerDelegate* delegate) { m_Delegate = delegate; }
+ PLT_MediaServerDelegate* GetDelegate() { return m_Delegate; }
+ virtual void UpdateSystemUpdateID(NPT_UInt32 update);
+ virtual void UpdateContainerUpdateID(const char* id, NPT_UInt32 update);
+
+protected:
+ ~PLT_MediaServer() override;
+
+ // PLT_DeviceHost methods
+ NPT_Result SetupServices() override;
+ NPT_Result OnAction(PLT_ActionReference& action,
+ const PLT_HttpRequestContext& context) override;
+ NPT_Result ProcessHttpGetRequest(NPT_HttpRequest& request,
+ const NPT_HttpRequestContext& context,
+ NPT_HttpResponse& response) override;
+
+ // ConnectionManager
+ virtual NPT_Result OnGetCurrentConnectionIDs(PLT_ActionReference& action,
+ const PLT_HttpRequestContext& context);
+ virtual NPT_Result OnGetProtocolInfo(PLT_ActionReference& action,
+ const PLT_HttpRequestContext& context);
+ virtual NPT_Result OnGetCurrentConnectionInfo(PLT_ActionReference& action,
+ const PLT_HttpRequestContext& context);
+
+ // ContentDirectory
+ virtual NPT_Result OnGetSortCapabilities(PLT_ActionReference& action,
+ const PLT_HttpRequestContext& context);
+ virtual NPT_Result OnGetSearchCapabilities(PLT_ActionReference& action,
+ const PLT_HttpRequestContext& context);
+ virtual NPT_Result OnGetSystemUpdateID(PLT_ActionReference& action,
+ const PLT_HttpRequestContext& context);
+ virtual NPT_Result OnBrowse(PLT_ActionReference& action,
+ const PLT_HttpRequestContext& context);
+ virtual NPT_Result OnSearch(PLT_ActionReference& action,
+ const PLT_HttpRequestContext& context);
+ virtual NPT_Result OnUpdate(PLT_ActionReference& action,
+ const PLT_HttpRequestContext& context);
+
+ // overridable methods
+ virtual NPT_Result OnBrowseMetadata(PLT_ActionReference& action,
+ const char* object_id,
+ const char* filter,
+ NPT_UInt32 starting_index,
+ NPT_UInt32 requested_count,
+ const char* sort_criteria,
+ const PLT_HttpRequestContext& context);
+ virtual NPT_Result OnBrowseDirectChildren(PLT_ActionReference& action,
+ const char* object_id,
+ const char* filter,
+ NPT_UInt32 starting_index,
+ NPT_UInt32 requested_count,
+ const char* sort_criteria,
+ const PLT_HttpRequestContext& context);
+ virtual NPT_Result OnSearchContainer(PLT_ActionReference& action,
+ const char* container_id,
+ const char* search_criteria,
+ const char* filter,
+ NPT_UInt32 starting_index,
+ NPT_UInt32 requested_count,
+ const char* sort_criteria,
+ const PLT_HttpRequestContext& context);
+
+private:
+ PLT_MediaServerDelegate* m_Delegate;
+};
+
+#endif /* _PLT_MEDIA_SERVER_H_ */
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.cpp
new file mode 100644
index 0000000..794b56b
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.cpp
@@ -0,0 +1,578 @@
+/*****************************************************************
+|
+| Platinum - Synchronous Media Browser
+|
+| Copyright (c) 2004-2010, Plutinosoft, LLC.
+| All rights reserved.
+| http://www.plutinosoft.com
+|
+| This program is free software; you can redistribute it and/or
+| modify it under the terms of the GNU General Public License
+| as published by the Free Software Foundation; either version 2
+| of the License, or (at your option) any later version.
+|
+| OEMs, ISVs, VARs and other distributors that combine and
+| distribute commercially licensed software with Platinum software
+| and do not wish to distribute the source code for the commercially
+| licensed software under version 2, or (at your option) any later
+| version, of the GNU General Public License (the "GPL") must enter
+| into a commercial license agreement with Plutinosoft, LLC.
+| licensing@plutinosoft.com
+|
+| This program is distributed in the hope that it will be useful,
+| but WITHOUT ANY WARRANTY; without even the implied warranty of
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+| GNU General Public License for more details.
+|
+| You should have received a copy of the GNU General Public License
+| along with this program; see the file LICENSE.txt. If not, write to
+| the Free Software Foundation, Inc.,
+| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+| http://www.gnu.org/licenses/gpl-2.0.html
+|
+****************************************************************/
+
+/*----------------------------------------------------------------------
+| includes
++---------------------------------------------------------------------*/
+#include "PltSyncMediaBrowser.h"
+#include <algorithm>
+
+NPT_SET_LOCAL_LOGGER("platinum.media.server.syncbrowser")
+
+/*----------------------------------------------------------------------
+| PLT_SyncMediaBrowser::PLT_SyncMediaBrowser
++---------------------------------------------------------------------*/
+PLT_SyncMediaBrowser::PLT_SyncMediaBrowser(PLT_CtrlPointReference& ctrlPoint,
+ bool use_cache /* = false */,
+ PLT_MediaContainerChangesListener* listener /* = NULL */) :
+ PLT_MediaBrowser(ctrlPoint),
+ m_ContainerListener(listener),
+ m_UseCache(use_cache)
+{
+ SetDelegate(this);
+}
+
+/*----------------------------------------------------------------------
+| PLT_SyncMediaBrowser::~PLT_SyncMediaBrowser
++---------------------------------------------------------------------*/
+PLT_SyncMediaBrowser::~PLT_SyncMediaBrowser()
+{
+}
+
+/* Blocks forever waiting for a response from a request
+ * It is expected the request to succeed or to timeout and return an error eventually
+ */
+/*----------------------------------------------------------------------
+| PLT_SyncMediaBrowser::WaitForResponse
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_SyncMediaBrowser::WaitForResponse(NPT_SharedVariable& shared_var)
+{
+ return shared_var.WaitUntilEquals(1, 30000);
+}
+
+/*----------------------------------------------------------------------
+| PLT_SyncMediaBrowser::OnDeviceAdded
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_SyncMediaBrowser::OnDeviceAdded(PLT_DeviceDataReference& device)
+{
+ NPT_String uuid = device->GetUUID();
+
+ // test if it's a media server
+ PLT_Service* service;
+ if (NPT_SUCCEEDED(device->FindServiceByType("urn:schemas-upnp-org:service:ContentDirectory:*", service))) {
+ NPT_AutoLock lock(m_MediaServers);
+ m_MediaServers.Put(uuid, device);
+ }
+
+ return PLT_MediaBrowser::OnDeviceAdded(device);
+}
+
+/*----------------------------------------------------------------------
+| PLT_SyncMediaBrowser::OnDeviceRemoved
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_SyncMediaBrowser::OnDeviceRemoved(PLT_DeviceDataReference& device)
+{
+ NPT_String uuid = device->GetUUID();
+
+ // Remove from our list of servers first if found
+ {
+ NPT_AutoLock lock(m_MediaServers);
+ m_MediaServers.Erase(uuid);
+ }
+
+ // clear cache for that device
+ if (m_UseCache) m_Cache.Clear(device.AsPointer()->GetUUID());
+
+ return PLT_MediaBrowser::OnDeviceRemoved(device);
+}
+
+/*----------------------------------------------------------------------
+| PLT_SyncMediaBrowser::Find
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_SyncMediaBrowser::Find(const char* ip, PLT_DeviceDataReference& device)
+{
+ NPT_AutoLock lock(m_MediaServers);
+ const NPT_List<PLT_DeviceMapEntry*>::Iterator it =
+ m_MediaServers.GetEntries().Find(PLT_DeviceMapFinderByIp(ip));
+ if (it) {
+ device = (*it)->GetValue();
+ return NPT_SUCCESS;
+ }
+ return NPT_FAILURE;
+}
+
+static void OnResult(NPT_Result res,
+ PLT_DeviceDataReference& device,
+ PLT_BrowseInfo* info,
+ void* userdata)
+{
+ NPT_COMPILER_UNUSED(device);
+
+ if (!userdata) return;
+
+ PLT_BrowseDataReference* data = (PLT_BrowseDataReference*) userdata;
+ (*data)->res = res;
+ if (NPT_SUCCEEDED(res) && info) {
+ (*data)->info = *info;
+ }
+ (*data)->shared_var.SetValue(1);
+ delete data;
+}
+
+/*----------------------------------------------------------------------
+| PLT_SyncMediaBrowser::OnBrowseResult
++---------------------------------------------------------------------*/
+void
+PLT_SyncMediaBrowser::OnBrowseResult(NPT_Result res,
+ PLT_DeviceDataReference& device,
+ PLT_BrowseInfo* info,
+ void* userdata)
+{
+ OnResult(res, device, info, userdata);
+}
+
+/*----------------------------------------------------------------------
+| PLT_SyncMediaBrowser::OnSearchResult
++---------------------------------------------------------------------*/
+void
+PLT_SyncMediaBrowser::OnSearchResult(NPT_Result res,
+ PLT_DeviceDataReference& device,
+ PLT_BrowseInfo* info,
+ void* userdata)
+{
+ OnResult(res, device, info, userdata);
+}
+
+/*----------------------------------------------------------------------
+| PLT_SyncMediaBrowser::OnGetSearchCapabilitiesResult
++---------------------------------------------------------------------*/
+void
+PLT_SyncMediaBrowser::OnGetSearchCapabilitiesResult(NPT_Result res,
+ PLT_DeviceDataReference& device,
+ NPT_String searchCapabilities,
+ void* userdata)
+{
+ NPT_COMPILER_UNUSED(device);
+
+ if (!userdata) return;
+
+ PLT_CapabilitiesDataReference* data = (PLT_CapabilitiesDataReference*) userdata;
+ (*data)->res = res;
+ if (NPT_SUCCEEDED(res)) {
+ (*data)->capabilities = searchCapabilities;
+ }
+ (*data)->shared_var.SetValue(1);
+ delete data;
+}
+
+/*----------------------------------------------------------------------
+| PLT_SyncMediaBrowser::OnGetSortCapabilitiesResult
++---------------------------------------------------------------------*/
+void
+PLT_SyncMediaBrowser::OnGetSortCapabilitiesResult(NPT_Result res,
+ PLT_DeviceDataReference& device,
+ NPT_String sortCapabilities,
+ void* userdata)
+{
+ NPT_COMPILER_UNUSED(device);
+
+ if (!userdata) return;
+
+ PLT_CapabilitiesDataReference* data = (PLT_CapabilitiesDataReference*) userdata;
+ (*data)->res = res;
+ if (NPT_SUCCEEDED(res)) {
+ (*data)->capabilities = sortCapabilities;
+ }
+ (*data)->shared_var.SetValue(1);
+ delete data;
+}
+
+/*----------------------------------------------------------------------
+| PLT_SyncMediaBrowser::OnMSStateVariablesChanged
++---------------------------------------------------------------------*/
+void
+PLT_SyncMediaBrowser::OnMSStateVariablesChanged(PLT_Service* service,
+ NPT_List<PLT_StateVariable*>* vars)
+{
+ NPT_AutoLock lock(m_MediaServers);
+
+ PLT_DeviceDataReference device;
+ const NPT_List<PLT_DeviceMapEntry*>::Iterator it =
+ m_MediaServers.GetEntries().Find(PLT_DeviceMapFinderByUUID(service->GetDevice()->GetUUID()));
+ if (!it) return; // device with this service has gone away
+
+ device = (*it)->GetValue();
+ PLT_StateVariable* var = PLT_StateVariable::Find(*vars, "ContainerUpdateIDs");
+ if (var) {
+ // variable found, parse value
+ NPT_String value = var->GetValue();
+ NPT_String item_id, update_id;
+ int index;
+
+ while (value.GetLength()) {
+ // look for container id
+ index = value.Find(',');
+ if (index < 0) break;
+ item_id = value.Left(index);
+ value = value.SubString(index+1);
+
+ // look for update id
+ if (value.GetLength()) {
+ index = value.Find(',');
+ update_id = (index<0)?value:value.Left(index);
+ value = (index < 0) ? "" : value.SubString(index + 1).GetChars();
+
+ // clear cache for that device
+ if (m_UseCache) m_Cache.Clear(device->GetUUID(), item_id);
+
+ // notify listener
+ if (m_ContainerListener) m_ContainerListener->OnContainerChanged(device, item_id, update_id);
+ }
+ }
+ }
+}
+
+/*----------------------------------------------------------------------
+| PLT_SyncMediaBrowser::BrowseSync
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_SyncMediaBrowser::BrowseSync(PLT_BrowseDataReference& browse_data,
+ PLT_DeviceDataReference& device,
+ const char* object_id,
+ NPT_Int32 index,
+ NPT_Int32 count,
+ bool browse_metadata,
+ const char* filter,
+ const char* sort)
+{
+ NPT_Result res;
+
+ browse_data->shared_var.SetValue(0);
+ browse_data->info.si = index;
+
+ // send off the browse packet. Note that this will
+ // not block. There is a call to WaitForResponse in order
+ // to block until the response comes back.
+ res = PLT_MediaBrowser::Browse(device,
+ (const char*)object_id,
+ index,
+ count,
+ browse_metadata,
+ filter,
+ sort,
+ new PLT_BrowseDataReference(browse_data));
+ NPT_CHECK_SEVERE(res);
+
+ return WaitForResponse(browse_data->shared_var);
+}
+
+/*----------------------------------------------------------------------
+| PLT_SyncMediaBrowser::SearchSync
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_SyncMediaBrowser::SearchSync(PLT_BrowseDataReference& browse_data,
+ PLT_DeviceDataReference& device,
+ const char* container_id,
+ const char* search_criteria,
+ NPT_Int32 index,
+ NPT_Int32 count,
+ const char* filter)
+{
+ NPT_Result res;
+
+ browse_data->shared_var.SetValue(0);
+ browse_data->info.si = index;
+
+ // send off the search packet. Note that this will
+ // not block. There is a call to WaitForResponse in order
+ // to block until the response comes back.
+ res = PLT_MediaBrowser::Search(device,
+ container_id,
+ search_criteria,
+ index,
+ count,
+ filter,
+ new PLT_BrowseDataReference(browse_data));
+ NPT_CHECK_SEVERE(res);
+
+ return WaitForResponse(browse_data->shared_var);
+}
+
+/*----------------------------------------------------------------------
+| PLT_SyncMediaBrowser::GetSearchCapabilitiesSync
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_SyncMediaBrowser::GetSearchCapabilitiesSync(PLT_DeviceDataReference& device,
+ NPT_String& searchCapabilities)
+{
+ NPT_Result res;
+
+ PLT_CapabilitiesDataReference capabilities_data(new PLT_CapabilitiesData(), true);
+ capabilities_data->shared_var.SetValue(0);
+
+ // send of the GetSearchCapabilities packet. Note that this will
+ // not block. There is a call to WaitForResponse in order
+ // to block until the response comes back.
+ res = PLT_MediaBrowser::GetSearchCapabilities(device,
+ new PLT_CapabilitiesDataReference(capabilities_data));
+ NPT_CHECK_SEVERE(res);
+
+ res = WaitForResponse(capabilities_data->shared_var);
+ NPT_CHECK_LABEL_WARNING(res, done);
+
+ if (NPT_FAILED(capabilities_data->res)) {
+ res = capabilities_data->res;
+ NPT_CHECK_LABEL_WARNING(res, done);
+ }
+
+ searchCapabilities = capabilities_data->capabilities;
+
+done:
+ return res;
+}
+
+/*----------------------------------------------------------------------
+| PLT_SyncMediaBrowser::GetSortCapabilitiesSync
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_SyncMediaBrowser::GetSortCapabilitiesSync(PLT_DeviceDataReference& device,
+ NPT_String& sortCapabilities)
+{
+ NPT_Result res;
+
+ PLT_CapabilitiesDataReference capabilities_data(new PLT_CapabilitiesData(), true);
+ capabilities_data->shared_var.SetValue(0);
+
+ // send of the GetSortCapabilities packet. Note that this will
+ // not block. There is a call to WaitForResponse in order
+ // to block until the response comes back.
+ res = PLT_MediaBrowser::GetSortCapabilities(device,
+ new PLT_CapabilitiesDataReference(capabilities_data));
+ NPT_CHECK_SEVERE(res);
+
+ res = WaitForResponse(capabilities_data->shared_var);
+ NPT_CHECK_LABEL_WARNING(res, done);
+
+ if (NPT_FAILED(capabilities_data->res)) {
+ res = capabilities_data->res;
+ NPT_CHECK_LABEL_WARNING(res, done);
+ }
+
+ sortCapabilities = capabilities_data->capabilities;
+
+done:
+ return res;
+}
+
+/*----------------------------------------------------------------------
+| PLT_SyncMediaBrowser::BrowseSync
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_SyncMediaBrowser::BrowseSync(PLT_DeviceDataReference& device,
+ const char* object_id,
+ PLT_MediaObjectListReference& list,
+ bool metadata, /* = false */
+ NPT_Int32 start, /* = 0 */
+ NPT_Cardinal max_results /* = 0 */)
+{
+ NPT_Result res = NPT_FAILURE;
+ NPT_Int32 index = start;
+ NPT_UInt32 count = 0;
+
+ // only cache metadata or if starting from 0 and asking for maximum
+ bool cache = m_UseCache && (metadata || (start == 0 && max_results == 0));
+
+ // reset output params
+ list = NULL;
+
+ // look into cache first
+ if (cache && NPT_SUCCEEDED(m_Cache.Get(device->GetUUID(), object_id, list))) return NPT_SUCCESS;
+
+ do {
+ PLT_BrowseDataReference browse_data(new PLT_BrowseData());
+
+ // send off the browse packet. Note that this will
+ // not block. There is a call to WaitForResponse in order
+ // to block until the response comes back.
+ res = BrowseSync(
+ browse_data,
+ device,
+ (const char*)object_id,
+ index,
+ metadata?1:200, // DLNA recommendations for browsing children is no more than 30 at a time
+ metadata);
+ NPT_CHECK_LABEL_WARNING(res, done);
+
+ if (NPT_FAILED(browse_data->res)) {
+ res = browse_data->res;
+ NPT_CHECK_LABEL_WARNING(res, done);
+ }
+
+ // server returned no more, bail now
+ if (browse_data->info.nr == 0)
+ break;
+
+ if (browse_data->info.nr != browse_data->info.items->GetItemCount()) {
+ NPT_LOG_WARNING_2("Server returned unexpected number of items (%d vs %d)",
+ browse_data->info.nr, browse_data->info.items->GetItemCount());
+ }
+ count += std::max<NPT_UInt32>(browse_data->info.nr, browse_data->info.items->GetItemCount());
+
+ if (list.IsNull()) {
+ list = browse_data->info.items;
+ } else {
+ list->Add(*browse_data->info.items);
+ // clear the list items so that the data inside is not
+ // cleaned up by PLT_MediaItemList dtor since we copied
+ // each pointer into the new list.
+ browse_data->info.items->Clear();
+ }
+
+ // stop now if our list contains exactly what the server said it had.
+ // Note that the server could return 0 if it didn't know how many items were
+ // available. In this case we have to continue browsing until
+ // nothing is returned back by the server.
+ // Unless we were told to stop after reaching a certain amount to avoid
+ // length delays
+ // (some servers may return a total matches out of whack at some point too)
+ if ((browse_data->info.tm && browse_data->info.tm <= count) ||
+ (max_results && count >= max_results))
+ break;
+
+ // ask for the next chunk of entries
+ index = count;
+ } while(1);
+
+done:
+ // cache the result
+ if (cache && NPT_SUCCEEDED(res) && !list.IsNull() && list->GetItemCount()) {
+ m_Cache.Put(device->GetUUID(), object_id, list);
+ }
+
+ // clear entire cache data for device if failed, the device could be gone
+ if (NPT_FAILED(res) && cache) m_Cache.Clear(device->GetUUID());
+
+ return res;
+}
+
+/*----------------------------------------------------------------------
+| PLT_SyncMediaBrowser::SearchSync
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_SyncMediaBrowser::SearchSync(PLT_DeviceDataReference& device,
+ const char* container_id,
+ const char* search_criteria,
+ PLT_MediaObjectListReference& list,
+ NPT_Int32 start, /* = 0 */
+ NPT_Cardinal max_results /* = 0 */)
+{
+ NPT_Result res = NPT_FAILURE;
+ NPT_Int32 index = start;
+ NPT_UInt32 count = 0;
+
+ // reset output params
+ list = NULL;
+
+ do {
+ PLT_BrowseDataReference browse_data(new PLT_BrowseData(), true);
+
+ // send off the search packet. Note that this will
+ // not block. There is a call to WaitForResponse in order
+ // to block until the response comes back.
+ res = SearchSync(
+ browse_data,
+ device,
+ container_id,
+ search_criteria,
+ index,
+ 200); // DLNA recommendations for browsing children is no more than 30 at a time
+
+ NPT_CHECK_LABEL_WARNING(res, done);
+
+ if (NPT_FAILED(browse_data->res)) {
+ res = browse_data->res;
+ NPT_CHECK_LABEL_WARNING(res, done);
+ }
+
+ // server returned no more, bail now
+ if (browse_data->info.nr == 0)
+ break;
+
+ if (browse_data->info.nr != browse_data->info.items->GetItemCount()) {
+ NPT_LOG_WARNING_2("Server returned unexpected number of items (%d vs %d)",
+ browse_data->info.nr, browse_data->info.items->GetItemCount());
+ }
+ count += std::max<NPT_UInt32>(browse_data->info.nr, browse_data->info.items->GetItemCount());
+
+ if (list.IsNull()) {
+ list = browse_data->info.items;
+ } else {
+ list->Add(*browse_data->info.items);
+ // clear the list items so that the data inside is not
+ // cleaned up by PLT_MediaItemList dtor since we copied
+ // each pointer into the new list.
+ browse_data->info.items->Clear();
+ }
+
+ // stop now if our list contains exactly what the server said it had.
+ // Note that the server could return 0 if it didn't know how many items were
+ // available. In this case we have to continue browsing until
+ // nothing is returned back by the server.
+ // Unless we were told to stop after reaching a certain amount to avoid
+ // length delays
+ // (some servers may return a total matches out of whack at some point too)
+ if ((browse_data->info.tm && browse_data->info.tm <= count) ||
+ (max_results && count >= max_results))
+ break;
+
+ // ask for the next chunk of entries
+ index = count;
+ } while(1);
+
+done:
+ return res;
+}
+
+/*----------------------------------------------------------------------
+| PLT_SyncMediaBrowser::IsCached
++---------------------------------------------------------------------*/
+bool
+PLT_SyncMediaBrowser::IsCached(const char* uuid, const char* object_id)
+{
+ NPT_AutoLock lock(m_MediaServers);
+ const NPT_List<PLT_DeviceMapEntry*>::Iterator it =
+ m_MediaServers.GetEntries().Find(PLT_DeviceMapFinderByUUID(uuid));
+ if (!it) {
+ m_Cache.Clear(uuid);
+ return false; // device with this service has gone away
+ }
+
+ PLT_MediaObjectListReference list;
+ return NPT_SUCCEEDED(m_Cache.Get(uuid, object_id, list))?true:false;
+}
+
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.h b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.h
new file mode 100644
index 0000000..6da21cb
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.h
@@ -0,0 +1,218 @@
+/*****************************************************************
+|
+| Platinum - Synchronous Media Browser
+|
+| Copyright (c) 2004-2010, Plutinosoft, LLC.
+| All rights reserved.
+| http://www.plutinosoft.com
+|
+| This program is free software; you can redistribute it and/or
+| modify it under the terms of the GNU General Public License
+| as published by the Free Software Foundation; either version 2
+| of the License, or (at your option) any later version.
+|
+| OEMs, ISVs, VARs and other distributors that combine and
+| distribute commercially licensed software with Platinum software
+| and do not wish to distribute the source code for the commercially
+| licensed software under version 2, or (at your option) any later
+| version, of the GNU General Public License (the "GPL") must enter
+| into a commercial license agreement with Plutinosoft, LLC.
+| licensing@plutinosoft.com
+|
+| This program is distributed in the hope that it will be useful,
+| but WITHOUT ANY WARRANTY; without even the implied warranty of
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+| GNU General Public License for more details.
+|
+| You should have received a copy of the GNU General Public License
+| along with this program; see the file LICENSE.txt. If not, write to
+| the Free Software Foundation, Inc.,
+| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+| http://www.gnu.org/licenses/gpl-2.0.html
+|
+****************************************************************/
+
+/** @file
+ UPnP AV Media Controller synchronous implementation.
+ */
+
+#ifndef _PLT_SYNC_MEDIA_BROWSER_
+#define _PLT_SYNC_MEDIA_BROWSER_
+
+/*----------------------------------------------------------------------
+| includes
++---------------------------------------------------------------------*/
+#include "Neptune.h"
+#include "PltCtrlPoint.h"
+#include "PltMediaBrowser.h"
+#include "PltMediaCache.h"
+
+/*----------------------------------------------------------------------
+| types
++---------------------------------------------------------------------*/
+typedef NPT_Map<NPT_String, PLT_DeviceDataReference> PLT_DeviceMap;
+typedef NPT_Map<NPT_String, PLT_DeviceDataReference>::Entry PLT_DeviceMapEntry;
+
+typedef struct PLT_BrowseData {
+ NPT_SharedVariable shared_var;
+ NPT_Result res;
+ PLT_BrowseInfo info;
+} PLT_BrowseData;
+
+typedef NPT_Reference<PLT_BrowseData> PLT_BrowseDataReference;
+
+typedef struct PLT_CapabilitiesData {
+ NPT_SharedVariable shared_var;
+ NPT_Result res;
+ NPT_String capabilities;
+} PLT_CapabilitiesData;
+
+typedef NPT_Reference<PLT_CapabilitiesData> PLT_CapabilitiesDataReference;
+
+// explicitely specify res otherwise WMP won't return a URL!
+#define PLT_DEFAULT_FILTER "dc:date,dc:description,upnp:longDescription,upnp:genre,res,res@duration,res@size,upnp:albumArtURI,upnp:rating,upnp:lastPlaybackPosition,upnp:lastPlaybackTime,upnp:playbackCount,upnp:originalTrackNumber,upnp:episodeNumber,upnp:programTitle,upnp:seriesTitle,upnp:album,upnp:artist,upnp:author,upnp:director,dc:publisher,searchable,childCount,dc:title,dc:creator,upnp:actor,res@resolution,upnp:episodeCount,upnp:episodeSeason,xbmc:lastPlayerState,xbmc:dateadded,xbmc:rating,xbmc:votes,xbmc:artwork,xbmc:uniqueidentifier,xbmc:country,xbmc:userrating"
+
+/*----------------------------------------------------------------------
+| PLT_MediaContainerListener
++---------------------------------------------------------------------*/
+class PLT_MediaContainerChangesListener
+{
+public:
+ virtual ~PLT_MediaContainerChangesListener() {}
+ virtual void OnContainerChanged(PLT_DeviceDataReference& device,
+ const char* item_id,
+ const char* update_id) = 0;
+};
+
+/*----------------------------------------------------------------------
+| PLT_SyncMediaBrowser
++---------------------------------------------------------------------*/
+class PLT_SyncMediaBrowser : public PLT_MediaBrowser,
+ public PLT_MediaBrowserDelegate
+{
+public:
+ PLT_SyncMediaBrowser(PLT_CtrlPointReference& ctrlPoint,
+ bool use_cache = false,
+ PLT_MediaContainerChangesListener* listener = NULL);
+ ~PLT_SyncMediaBrowser() override;
+
+ // PLT_MediaBrowser methods
+ NPT_Result OnDeviceAdded(PLT_DeviceDataReference& device) override;
+ NPT_Result OnDeviceRemoved(PLT_DeviceDataReference& device) override;
+
+ // PLT_MediaBrowserDelegate methods
+ void OnMSStateVariablesChanged(PLT_Service* service,
+ NPT_List<PLT_StateVariable*>* vars) override;
+ void OnBrowseResult(NPT_Result res,
+ PLT_DeviceDataReference& device,
+ PLT_BrowseInfo* info,
+ void* userdata) override;
+ void OnSearchResult(NPT_Result res,
+ PLT_DeviceDataReference& device,
+ PLT_BrowseInfo* info,
+ void* userdata) override;
+ void OnGetSearchCapabilitiesResult(NPT_Result res,
+ PLT_DeviceDataReference& device,
+ NPT_String searchCapabilities,
+ void* userdata) override;
+ void OnGetSortCapabilitiesResult(NPT_Result res,
+ PLT_DeviceDataReference& device,
+ NPT_String sortCapabilities,
+ void* userdata) override;
+
+ // methods
+ void SetContainerListener(PLT_MediaContainerChangesListener* listener) {
+ m_ContainerListener = listener;
+ }
+ NPT_Result BrowseSync(PLT_DeviceDataReference& device,
+ const char* id,
+ PLT_MediaObjectListReference& list,
+ bool metadata = false,
+ NPT_Int32 start = 0,
+ NPT_Cardinal max_results = 0); // 0 means all
+
+ NPT_Result SearchSync(PLT_DeviceDataReference& device,
+ const char* container_id,
+ const char* search_criteria,
+ PLT_MediaObjectListReference& list,
+ NPT_Int32 start = 0,
+ NPT_Cardinal max_results = 0); // 0 means all
+
+ NPT_Result GetSearchCapabilitiesSync(PLT_DeviceDataReference& device,
+ NPT_String& searchCapabilities);
+
+ NPT_Result GetSortCapabilitiesSync(PLT_DeviceDataReference& device,
+ NPT_String& sortCapabilities);
+
+ const NPT_Lock<PLT_DeviceMap>& GetMediaServersMap() const { return m_MediaServers; }
+ bool IsCached(const char* uuid, const char* object_id);
+
+protected:
+ NPT_Result BrowseSync(PLT_BrowseDataReference& browse_data,
+ PLT_DeviceDataReference& device,
+ const char* object_id,
+ NPT_Int32 index,
+ NPT_Int32 count,
+ bool browse_metadata = false,
+ const char* filter = PLT_DEFAULT_FILTER,
+ const char* sort = "");
+
+ NPT_Result SearchSync(PLT_BrowseDataReference& browse_data,
+ PLT_DeviceDataReference& device,
+ const char* container_id,
+ const char* search_criteria,
+ NPT_Int32 index,
+ NPT_Int32 count,
+ const char* filter = PLT_DEFAULT_FILTER); // explicitely specify res otherwise WMP won't return a URL!
+
+private:
+ NPT_Result Find(const char* ip, PLT_DeviceDataReference& device);
+ NPT_Result WaitForResponse(NPT_SharedVariable& shared_var);
+
+private:
+ NPT_Lock<PLT_DeviceMap> m_MediaServers;
+ PLT_MediaContainerChangesListener* m_ContainerListener;
+ bool m_UseCache;
+ PLT_MediaCache<PLT_MediaObjectListReference,NPT_String> m_Cache;
+};
+
+/*----------------------------------------------------------------------
+| PLT_DeviceMapFinderByIp
++---------------------------------------------------------------------*/
+class PLT_DeviceMapFinderByIp
+{
+public:
+ // methods
+ PLT_DeviceMapFinderByIp(const char* ip) : m_IP(ip) {}
+
+ bool operator()(const PLT_DeviceMapEntry* const& entry) const {
+ const PLT_DeviceDataReference& device = entry->GetValue();
+ return (device->GetURLBase().GetHost() == m_IP);
+ }
+
+private:
+ // members
+ NPT_String m_IP;
+};
+
+/*----------------------------------------------------------------------
+| PLT_DeviceFinderByUUID
++---------------------------------------------------------------------*/
+class PLT_DeviceMapFinderByUUID
+{
+public:
+ // methods
+ PLT_DeviceMapFinderByUUID(const char* uuid) : m_UUID(uuid) {}
+
+ bool operator()(const PLT_DeviceMapEntry* const& entry) const {
+ PLT_DeviceDataReference device = entry->GetValue();
+ return device->GetUUID() == m_UUID;
+ }
+
+private:
+ // members
+ NPT_String m_UUID;
+};
+
+#endif /* _PLT_SYNC_MEDIA_BROWSER_ */
+
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/process_scpds.sh b/lib/libUPnP/Platinum/Source/Devices/MediaServer/process_scpds.sh
new file mode 100644
index 0000000..bba4bc8
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/process_scpds.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+set -x
+
+# abort on any errors
+set -e
+
+# ContentDirectory
+../../../Targets/x86-unknown-cygwin/Debug/TextToHeader.exe -v MS_ContentDirectorySCPD -h ContentDirectory ContentDirectorySCPD.xml ContentDirectorySCPD.cpp
+
+# ContentDirectory with Search
+../../../Targets/x86-unknown-cygwin/Debug/TextToHeader.exe -v MS_ContentDirectorywSearchSCPD -h ContentDirectory ContentDirectorywSearchSCPD.xml ContentDirectorywSearchSCPD.cpp
+
+# ConnectionManager
+../../../Targets/x86-unknown-cygwin/Debug/TextToHeader.exe -v MS_ConnectionManagerSCPD -h ConnectionManager ConnectionManagerSCPD.xml ConnectionManagerSCPD.cpp \ No newline at end of file