Simplification et reactivation du WebServer (pour fournir la conf Control)
|
|
@ -9,6 +9,7 @@
|
|||
<OutputType>WinExe</OutputType>
|
||||
<RootNamespace>DMX2</RootNamespace>
|
||||
<AssemblyName>DMX-2.0</AssemblyName>
|
||||
<ReleaseVersion>2.0</ReleaseVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
|
|
@ -78,41 +79,9 @@
|
|||
<LogicalName>style.gtkrc</LogicalName>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="html\page.html">
|
||||
<LogicalName>page.html</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="html\js\jquery-ui.js">
|
||||
<LogicalName>js.jquery-ui.js</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="html\css\theme\jquery-ui.css">
|
||||
<LogicalName>css.theme.jquery-ui.css</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="html\css\theme\images\ui-bg_glass_100_f6f6f6_1x400.png">
|
||||
<LogicalName>css.theme.images.ui-bg_glass_100_f6f6f6_1x400.png</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="html\css\theme\images\ui-bg_flat_10_000000_40x100.png">
|
||||
<LogicalName>css.theme.images.ui-bg_flat_10_000000_40x100.png</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="html\js\jquery-1.9.1.js">
|
||||
<LogicalName>js.jquery-1.9.1.js</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="html\css\theme\images\ui-bg_diagonals-thick_18_b81900_40x40.png">
|
||||
<LogicalName>css.theme.images.ui-bg_diagonals-thick_18_b81900_40x40.png</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="html\css\theme\images\ui-bg_diagonals-thick_20_666666_40x40.png">
|
||||
<LogicalName>css.theme.images.ui-bg_diagonals-thick_20_666666_40x40.png</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="html\css\theme\images\ui-bg_highlight-soft_100_eeeeee_1x100.png">
|
||||
<LogicalName>css.theme.images.ui-bg_highlight-soft_100_eeeeee_1x100.png</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="html\css\theme\images\ui-bg_glass_100_fdf5ce_1x400.png">
|
||||
<LogicalName>css.theme.images.ui-bg_glass_100_fdf5ce_1x400.png</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="html\css\theme\images\ui-bg_glass_65_ffffff_1x400.png">
|
||||
<LogicalName>css.theme.images.ui-bg_glass_65_ffffff_1x400.png</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="html\if.js">
|
||||
<LogicalName>if.js</LogicalName>
|
||||
<EmbeddedResource Include="..\loupiottes.js">
|
||||
<Link>loupiottes.js</Link>
|
||||
<LogicalName>loupiottes.js</LogicalName>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
@ -167,6 +136,7 @@
|
|||
<Compile Include="SeqSonUI.cs" />
|
||||
<Compile Include="gtk-gui\DMX2.SeqSonUI.cs" />
|
||||
<Compile Include="OSCServer.cs" />
|
||||
<Compile Include="WebServer.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<ProjectExtensions>
|
||||
|
|
@ -180,18 +150,4 @@
|
|||
</Properties>
|
||||
</MonoDevelop>
|
||||
</ProjectExtensions>
|
||||
<ItemGroup>
|
||||
<Folder Include="html\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="html\js\jquery-ui-1.10.3.custom.js" />
|
||||
<None Include="html\css\theme\images\animated-overlay.gif" />
|
||||
<None Include="html\css\theme\images\ui-bg_gloss-wave_35_f6a828_500x100.png" />
|
||||
<None Include="html\css\theme\images\ui-bg_highlight-soft_75_ffe45c_1x100.png" />
|
||||
<None Include="html\css\theme\images\ui-icons_228ef1_256x240.png" />
|
||||
<None Include="html\css\theme\images\ui-icons_222222_256x240.png" />
|
||||
<None Include="html\css\theme\images\ui-icons_ef8c08_256x240.png" />
|
||||
<None Include="html\css\theme\images\ui-icons_ffd27a_256x240.png" />
|
||||
<None Include="html\css\theme\images\ui-icons_ffffff_256x240.png" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -26,7 +26,7 @@ namespace DMX2
|
|||
public static void Main (string[] args)
|
||||
{
|
||||
bool fullscreen = false;
|
||||
//WebServer ws = null; bool webserv = false;
|
||||
WebServer ws = null; bool webserv = true;
|
||||
OSCServer osc = null;
|
||||
bool oscEn = true;
|
||||
System.IO.FileInfo openfile = null;
|
||||
|
|
@ -46,9 +46,9 @@ namespace DMX2
|
|||
case "noosc":
|
||||
oscEn = false;
|
||||
break;
|
||||
/*case "ws":
|
||||
webserv = true;
|
||||
break; */
|
||||
case "nows":
|
||||
webserv = false;
|
||||
break;
|
||||
default:
|
||||
if (System.IO.File.Exists (arg))
|
||||
openfile = new System.IO.FileInfo (arg);
|
||||
|
|
@ -56,7 +56,7 @@ namespace DMX2
|
|||
}
|
||||
}
|
||||
|
||||
//if(webserv) ws = new WebServer();
|
||||
if(webserv) ws = new WebServer();
|
||||
if (oscEn)
|
||||
osc = new OSCServer ();
|
||||
|
||||
|
|
|
|||
|
|
@ -174,7 +174,9 @@ namespace DMX2
|
|||
mplayerProcess.StandardInput.WriteLine ("volume 0 1");
|
||||
mplayerProcess.StandardInput.WriteLine ("loadfile \"{0}\" 0", curfile);
|
||||
mplayerProcess.StandardInput.WriteLine ("get_time_length");
|
||||
mplayerProcess.StandardInput.WriteLine ("pausing seek 0 2");
|
||||
//mplayerProcess.StandardInput.WriteLine ("pausing seek 0 2");
|
||||
mplayerProcess.StandardInput.WriteLine ("pause");
|
||||
mplayerProcess.StandardInput.WriteLine ("seek 0 2");
|
||||
mplayerProcess.StandardInput.WriteLine ("volume {0} 1", volume);
|
||||
Paused = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,9 +35,9 @@ namespace DMX2
|
|||
|
||||
public WebServer ()
|
||||
{
|
||||
using (System.IO.Stream stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("page.html"))
|
||||
/*using (System.IO.Stream stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("page.html"))
|
||||
using (System.IO.TextReader reader = new System.IO.StreamReader(stream))
|
||||
page = reader.ReadToEnd();
|
||||
page = reader.ReadToEnd();*/
|
||||
|
||||
resources = new List<string>(System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceNames());
|
||||
|
||||
|
|
@ -57,82 +57,23 @@ namespace DMX2
|
|||
|
||||
Console.WriteLine (context.Request.RawUrl);
|
||||
|
||||
string responseString = GetResponse (context);
|
||||
// Pour les resources, on les renvoie si elles existent
|
||||
if (context.Request.Url.LocalPath.StartsWith ("/res/")) {
|
||||
string res = context.Request.Url.LocalPath.Remove(0,5).Replace('/','.');
|
||||
if(resources.Contains(res))
|
||||
using (System.IO.Stream stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(res))
|
||||
|
||||
{
|
||||
byte[] buff = new byte[1024]; int l;
|
||||
while( (l=stream.Read(buff,0,buff.Length))>0){
|
||||
context.Response.OutputStream.Write(buff,0,l);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
string res = context.Request.Url.LocalPath.Remove(0,1).Replace('/','.');
|
||||
if(resources.Contains(res))
|
||||
using (System.IO.Stream stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(res))
|
||||
{
|
||||
|
||||
byte[] buffer = System.Text.Encoding.UTF8.GetBytes (responseString);
|
||||
context.Response.ContentLength64 = buffer.Length;
|
||||
context.Response.OutputStream.Write (buffer, 0, buffer.Length);
|
||||
|
||||
byte[] buff = new byte[1024]; int l;
|
||||
while( (l=stream.Read(buff,0,buff.Length))>0){
|
||||
context.Response.OutputStream.Write(buff,0,l);
|
||||
}
|
||||
}
|
||||
|
||||
context.Response.OutputStream.Close ();
|
||||
}
|
||||
} catch {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
string GetResponse (HttpListenerContext ctx)
|
||||
{
|
||||
HttpListenerRequest req = ctx.Request;
|
||||
// Pas de conduite chargée, on renvoi un simple message
|
||||
if (Conduite.Courante == null) return "<html><body>Pas de conduite</body></html>";
|
||||
|
||||
|
||||
int circuit, univ, dimmer, val;
|
||||
|
||||
// En fonction du http://xxxxxx:yyyy/?id=
|
||||
switch (req.QueryString["id"]) {
|
||||
default: // Par défaut, on renvoie la page
|
||||
|
||||
string univlist = ""; int i = 0;
|
||||
foreach (UniversDMX univers in Conduite.Courante.Patches)
|
||||
univlist = univlist + string.Format("<option value=\"{0}\">{1}</option>",i++,univers.Nom);
|
||||
string data = page.Replace("<UNIVLIST>",univlist);
|
||||
return data;
|
||||
|
||||
case "2" :
|
||||
// id=2 > controle d'un dimmer
|
||||
if(!int.TryParse(req.QueryString["univ"],out univ)) return "NOK";
|
||||
if(!int.TryParse(req.QueryString["dimmer"],out dimmer)) return "NOK";
|
||||
if(!int.TryParse(req.QueryString["val"],out val)) return "NOK";
|
||||
if(univ<0 || univ>= Conduite.Courante.Patches.Count) return "NOK";
|
||||
if(dimmer<=0 || dimmer > 512) return "NOK";
|
||||
if(val <0 || val > 255) return "NOK";
|
||||
Conduite.Courante.Patches[univ].AllumageForce = dimmer-1;
|
||||
Conduite.Courante.Patches[univ].AllumageForceVal = val;
|
||||
return "OK";
|
||||
|
||||
case "3":
|
||||
|
||||
// id=3 > controle d'un circuit
|
||||
if(!int.TryParse(req.QueryString["circuit"],out circuit)) return "NOK";
|
||||
if(!int.TryParse(req.QueryString["val"],out val)) return "NOK";
|
||||
if(circuit<=0 || circuit> Conduite.Courante.Circuits.Count) return "NOK";
|
||||
if(val <0 || val > 255) return "NOK";
|
||||
Conduite.Courante.CircuitTelecomande = Conduite.Courante.Circuits[circuit-1];
|
||||
Conduite.Courante.CircuitTelecomandeVal = val;
|
||||
return "OK";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#region IDisposable implementation
|
||||
public void Dispose ()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ namespace Stetic
|
|||
} else {
|
||||
int sz;
|
||||
int sy;
|
||||
global::Gtk.Icon.SizeLookup (size, out sz, out sy);
|
||||
global::Gtk.Icon.SizeLookup (size, out sz, out sy);
|
||||
try {
|
||||
return Gtk.IconTheme.Default.LoadIcon (name, sz, 0);
|
||||
} catch (System.Exception) {
|
||||
|
|
@ -105,8 +105,12 @@ namespace Stetic
|
|||
pmap.DrawRectangle (gc, false, 0, 0, (sz - 1), (sz - 1));
|
||||
gc.SetLineAttributes (3, Gdk.LineStyle.Solid, Gdk.CapStyle.Round, Gdk.JoinStyle.Round);
|
||||
gc.RgbFgColor = new Gdk.Color (255, 0, 0);
|
||||
pmap.DrawLine (gc, (sz / 4), (sz / 4), ((sz - 1) - (sz / 4)), ((sz - 1) - (sz / 4)));
|
||||
pmap.DrawLine (gc, ((sz - 1) - (sz / 4)), (sz / 4), (sz / 4), ((sz - 1) - (sz / 4)));
|
||||
pmap.DrawLine (gc, (sz / 4), (sz / 4), ((sz - 1)
|
||||
- (sz / 4)), ((sz - 1)
|
||||
- (sz / 4)));
|
||||
pmap.DrawLine (gc, ((sz - 1)
|
||||
- (sz / 4)), (sz / 4), (sz / 4), ((sz - 1)
|
||||
- (sz / 4)));
|
||||
return Gdk.Pixbuf.FromDrawable (pmap, pmap.Colormap, 0, 0, 0, 0, sz, sz);
|
||||
}
|
||||
}
|
||||
|
|
@ -117,6 +121,7 @@ namespace Stetic
|
|||
internal class BinContainer
|
||||
{
|
||||
private Gtk.Widget child;
|
||||
|
||||
private Gtk.UIManager uimanager;
|
||||
|
||||
public static BinContainer Attach (Gtk.Bin bin)
|
||||
|
|
@ -158,7 +163,8 @@ namespace Stetic
|
|||
if ((this.uimanager != null)) {
|
||||
Gtk.Widget w;
|
||||
w = this.child.Toplevel;
|
||||
if (((w != null) && typeof(Gtk.Window).IsInstanceOfType (w))) {
|
||||
if (((w != null)
|
||||
&& typeof(Gtk.Window).IsInstanceOfType (w))) {
|
||||
((Gtk.Window)(w)).AddAccelGroup (this.uimanager.AccelGroup);
|
||||
this.uimanager = null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<target-gtk-version>2.12</target-gtk-version>
|
||||
</configuration>
|
||||
<import>
|
||||
<widget-library name="../bin/Release/DMX-2.0.exe" internal="true" />
|
||||
<widget-library name="../bin/Debug/DMX-2.0.exe" internal="true" />
|
||||
</import>
|
||||
<icon-factory>
|
||||
<icon-set id="tirettes">
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 418 B |
|
Before Width: | Height: | Size: 312 B |
|
Before Width: | Height: | Size: 205 B |
|
Before Width: | Height: | Size: 262 B |
|
Before Width: | Height: | Size: 348 B |
|
Before Width: | Height: | Size: 207 B |
|
Before Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 278 B |
|
Before Width: | Height: | Size: 328 B |
|
Before Width: | Height: | Size: 6.8 KiB |
|
Before Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 6.2 KiB |
7
DMX-2.0/html/css/theme/jquery-ui.css
vendored
|
|
@ -1,47 +0,0 @@
|
|||
loadedInterfaceName = "Loupiottes";
|
||||
|
||||
interfaceOrientation = "landscape";
|
||||
|
||||
pages = [[
|
||||
{
|
||||
"name": "refresh",
|
||||
"type": "Button",
|
||||
"bounds": [.6, .9, .2, .1],
|
||||
"startingValue": 0,
|
||||
"isLocal": true,
|
||||
"mode": "contact",
|
||||
"ontouchstart": "interfaceManager.refreshInterface()",
|
||||
"stroke": "#aaa",
|
||||
"label": "refrsh",
|
||||
},
|
||||
|
||||
{
|
||||
"name":"master",
|
||||
"type":"Slider",
|
||||
"bounds": [.05, .1, .1, .8],
|
||||
"isVertical" : true,
|
||||
"address" : "/master",
|
||||
"min":0,"max":101,
|
||||
},
|
||||
|
||||
{
|
||||
"name":"masters1",
|
||||
"type":"Slider",
|
||||
"bounds": [.20, .1, .1, .8],
|
||||
"isVertical" : true,
|
||||
"address" : "/seq/1/master",
|
||||
"min":0,"max":101,
|
||||
},
|
||||
|
||||
{
|
||||
"name":"ml1",
|
||||
"type":"MultiSlider",
|
||||
"bounds": [.30, .1, .5, .8],
|
||||
"isVertical" : true,
|
||||
"address" : "/seq/1/circuit",
|
||||
"min":0,"max":256,
|
||||
"numberOfSliders" : 10,
|
||||
},
|
||||
]
|
||||
|
||||
];
|
||||
9597
DMX-2.0/html/js/jquery-1.9.1.js
vendored
1639
DMX-2.0/html/js/jquery-ui-1.10.3.custom.js
vendored
10827
DMX-2.0/html/js/jquery-ui.js
vendored
|
|
@ -1,158 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
|
||||
<link rel="stylesheet" href="/res/css/theme/jquery-ui.css">
|
||||
<script src="/res/js/jquery-1.9.1.js"></script>
|
||||
<script src="/res/js/jquery-ui.js"></script>
|
||||
<script type="text/javascript">
|
||||
function hop(code)
|
||||
{
|
||||
A=parseInt(this.dimmer.value)+parseInt(code);
|
||||
A=Math.min(A,512);
|
||||
A=Math.max(A,1);
|
||||
this.dimmer.value=A;
|
||||
B=$( "#slider").slider( "value" );
|
||||
trans1(form.univ.value,form.dimmer.value,B);
|
||||
}
|
||||
|
||||
function hop2(code)
|
||||
{
|
||||
A=parseInt(this.circuit.value)+parseInt(code);
|
||||
A=Math.max(A,1);
|
||||
this.circuit.value=A;
|
||||
B=$( "#slider2").slider( "value" );
|
||||
trans2(form2.circuit.value,B);
|
||||
}
|
||||
|
||||
function Balckout()
|
||||
{
|
||||
$( "#slider2").slider( "value",0 );
|
||||
//B=$( "#slider2").slider( "value" );
|
||||
//trans2(form2.circuit.value,B);
|
||||
}
|
||||
|
||||
function Full()
|
||||
{
|
||||
$( "#slider2").slider( "value",255 );
|
||||
//B=$( "#slider2").slider( "value" );
|
||||
//trans2(form2.circuit.value,B);
|
||||
}
|
||||
|
||||
function remplir()
|
||||
{
|
||||
$( "#slider" ).slider({
|
||||
orientation: "horizontal",
|
||||
max: 255,
|
||||
value: 0,
|
||||
slide: refreshSwatch,
|
||||
change: refreshSwatch
|
||||
});
|
||||
$( "#slider2" ).slider({
|
||||
orientation: "horizontal",
|
||||
max: 255,
|
||||
value: 0,
|
||||
slide: refreshSwatch2,
|
||||
change: refreshSwatch2
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function refreshSwatch()
|
||||
{
|
||||
B=$( "#slider").slider( "value" );
|
||||
trans1(form.univ.value,form.dimmer.value,B);
|
||||
}
|
||||
|
||||
function refreshSwatch2()
|
||||
{
|
||||
B=$( "#slider2").slider( "value" );
|
||||
trans2(form2.circuit.value,B);
|
||||
}
|
||||
|
||||
function trans1(univ,dimmer,val)
|
||||
{
|
||||
texte = file('/page.html?id=2&univ='+escape(univ)+'&dimmer='+escape(dimmer)+'&val='+escape(val));
|
||||
}
|
||||
function trans2(circuit,val)
|
||||
{
|
||||
texte = file('/page.html?id=3&circuit='+escape(circuit)+'&val='+escape(val));
|
||||
}
|
||||
|
||||
|
||||
function file(fichier)
|
||||
{
|
||||
|
||||
xhr_object = new XMLHttpRequest();
|
||||
xhr_object.open("GET", fichier, false);
|
||||
xhr_object.send(null);
|
||||
if(xhr_object.readyState == 4) return(xhr_object.responseText);
|
||||
else return(false);
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body bgcolor="#FFFFBB">
|
||||
<h1>Commande</h1>
|
||||
<span id="toto">
|
||||
<div id="univers">
|
||||
<form name="form">
|
||||
<table border="0">
|
||||
<tr>
|
||||
<th>
|
||||
<label>Univers</label>
|
||||
</th><td>
|
||||
<select name="univ">
|
||||
<UNIVLIST>
|
||||
</select>
|
||||
</td></tr><tr>
|
||||
<th rowspan="3" >
|
||||
<label>Dimmer</label>
|
||||
</th><td>
|
||||
<input type="button" value="C+" Onclick="hop('100')"><input type="button" value="D+" Onclick="hop('10')">
|
||||
<input type="button" value="U+" Onclick="hop('1')">
|
||||
</td>
|
||||
</tr> <tr>
|
||||
<td><input type="text" name="dimmer" id="dimmer" value="1" size="5" /></td>
|
||||
</tr><tr>
|
||||
<td><input type="button" value="C-" Onclick="hop('-100')"><input type="button" value="D-" Onclick="hop('-10')">
|
||||
<input type="button" value="U-" Onclick="hop('-1')"></td>
|
||||
</tr><tr><td> </td></tr><tr>
|
||||
<td colspan="2">
|
||||
<div id="slider"></div>
|
||||
<td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
<div id="circuits">
|
||||
|
||||
<form name="form2">
|
||||
<table border="0">
|
||||
<tr>
|
||||
<th rowspan="3" >
|
||||
<label>Circuit</label>
|
||||
</th><td>
|
||||
<input type="button" value="C+" Onclick="hop2('100')"><input type="button" value="D+" Onclick="hop2('10')">
|
||||
<input type="button" value="U+" Onclick="hop2('1')" >
|
||||
</td></tr><tr>
|
||||
<td><input type="text" name="circuit" id="circuit" value="1" size="5" /></td>
|
||||
</tr><tr>
|
||||
<td><input type="button" value="C-" Onclick="hop2('-100')"><input type="button" value="D-" Onclick="hop2('-10')">
|
||||
<input type="button" value="U-" Onclick="hop2('-1')" >
|
||||
</tr><tr><td> </td> </tr><tr>
|
||||
<td colspan="2">
|
||||
<div id="slider2"></div>
|
||||
<td>
|
||||
</tr>
|
||||
<tr><td align="left"><input type="button" value="Blackout" Onclick="Balckout()"></td>
|
||||
|
||||
<td align="right"><input type="button" value="Full" Onclick="Full()"></td></tr>
|
||||
</table>
|
||||
<script>remplir();</script>
|
||||
</form>
|
||||
</div>
|
||||
</span>
|
||||
|
||||
</body>
|
||||
</html>
|
||||