|
You can't get the Windows user password. What would be the point of security, then? You must either prompt for credentials (not uncommon; even Windows does this, though it uses DPAPI to store them for later use - don't consider rolling your own; and I'll tell you why in a second) or connect to a Web Service on the LAN (part of a Windows domain) using the default credential cache (see CredentialCache.DefaultCredentials , which includes the Windows identity for authentication like IE would when connecting on an intranet).
Besides, do not use BASIC authentication and send the domain passwords - of all passwords especially - in clear text to the unsecured web service! If you must use BASIC authentication, connect to a web service entirely over SSL (using https://, if available). Otherwise, a simple sniffer will pick up domain passwords and next thing you know you're fired, your companies bankrupt, and your sys admin executes you.
If you want articles on DPAPI and how to use it (though you probably won't need it if you use CredentialCache.DefaultCredentials ), read How To: Create a DPAPI Library[^].
You should also check out the Web Service Enhancements (WSE) 2.0 package from Microsoft at http://msdn.microsoft.com/webservices/building/wse[^]. This provides many, many options for industry-standard, SOAP-based (i.e., not tied to the wire protocol like HTTP authentication) authentication, encryption, digital signatures, and routing.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I am trying to fetch the font information using following code
private void Form1_Load(object sender, System.EventArgs e)
{
IntPtr hdc = Win32API.GetDC(this.Handle);
try
{
LOGFONT lf = CreateLogFont("");
int ret = 0;
try
{
ret = Win32API.EnumFontFamiliesEx
(hdc, ref lf, new Win32API.EnumFontFamExProc(this.callback), 0, 0);
}
catch
{
System.Diagnostics.Trace.WriteLine("Excetion Happend!");
}
System.Diagnostics.Trace.WriteLine("EnumFontFamiliesEx = " + ret.ToString());
}
finally
{
Win32API.ReleaseDC(IntPtr.Zero, hdc);
}
}
private int cnt = 0;
private int callback(
ref ENUMLOGFONTEXDV lpelfe,
ref NEWTEXTMETRICEX lpntme,
uint FontType,
IntPtr lParam
)
{
try
{
++cnt;
string header = "no." + (cnt).ToString() + "::";
System.Diagnostics.Trace.WriteLine(header + lpelfe.elfEnumLogfontEx.elfLogFont.lfFaceName);
System.Diagnostics.Trace.WriteLine(header + lpelfe.elfEnumLogfontEx.elfLogFont.lfCharSet);
}
catch
{
System.Diagnostics.Trace.WriteLine("What happend?");
}
return cnt;
}
private const byte DEFAULT_CHARSET = 1;
private const byte SHIFTJIS_CHARSET = 128;
private const byte JOHAB_CHARSET = 130;
private const byte EASTEUROPE_CHARSET = 238;
private const byte DEFAULT_PITCH = 0;
private const byte FIXED_PITCH = 1;
private const byte VARIABLE_PITCH = 2;
private const byte FF_DONTCARE = (0 << 4);
private const byte FF_ROMAN = (1 << 4);
private const byte FF_SWISS = (2 << 4);
private const byte FF_MODERN = (3 << 4);
private const byte FF_SCRIPT = (4 << 4);
private const byte FF_DECORATIVE = (5 << 4);
public static LOGFONT CreateLogFont(string fontname)
{
LOGFONT lf = new LOGFONT();
lf.lfHeight = 0;
lf.lfWidth = 0;
lf.lfEscapement = 0;
lf.lfOrientation = 0;
lf.lfWeight = 0;
lf.lfItalic = 0;
lf.lfUnderline = 0;
lf.lfStrikeOut = 0;
lf.lfCharSet = SHIFTJIS_CHARSET;
//lf.lfCharSet = DEFAULT_CHARSET;
lf.lfOutPrecision = 0;
lf.lfClipPrecision = 0;
lf.lfQuality = 0;
lf.lfPitchAndFamily = (?_?) ;
lf.lfFaceName = "";
return lf;
}
it works well, but I am not able to toy with "lfPitchAndFamily", I want to fetch font names according to font family name and pitch.
Please guide
ps: what I found is InstalledFontCollection class in .NET Framework Developer's Guide does not give the list of all (installed) fonts . Please refer following link if you are interested
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/_gdiplus_enumerating_installed_fonts_usecsharp.asp
|
|
|
|
|
If you read about the LOGFONT structure in the Platform SDK (in the Windows GDI) section, it tells you that the first two low-order bits are the pitch and the 6 remaining high-order bits. You can define these as consts or enums (I like enums for consts, depending on what I'm doing since it organizes code a little better but still amounts to an actual constant value being compiled into IL):
public enum Pitch : byte
{
Default = 0x00,
Fixed = 0x01,
Variable = 0x02
}
public enum Family : byte
{
DontCare = 0x00,
Roman = 0x10,
Swiss = 0x20,
Modern = 0x30,
Script = 0x40,
Decorative = 0x50
} So, to use them assign lfPitchAndFamily to something like (byte)(Pitch.Variable | Family.Roman) . When this compiles, this will be 0x12 .
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
(byte)(Pitch.Variable | Family.Roman) gives compile time error
((byte)Pitch.Variable | (byte)Family.Roman) works, but still it pics up all font names not only from the Roman family but also from all the families
|
|
|
|
|
Sorry 'bout that. Wasn't really thinking much about it.
If that's not working the way you expect it, I'd seriously take another look at the code surrounding EnumFontFamilies(Ex) . Be sure to read the docs in the Platform SDK if you haven't already.
Here's an example I threw together quick that works fine:
using System;
using System.Runtime.InteropServices;
class EnumFonts
{
static void Main(string[] args)
{
string family = null;
if (args.Length > 0) family = args[0];
IntPtr hdc = GetDC(IntPtr.Zero);
try
{
EnumFontFamilies(hdc, family,
new EnumFontFamProc(Callback), IntPtr.Zero);
}
catch (Exception ex)
{
Console.Error.WriteLine("There was an error enumerating the " +
"font families: " + ex.Message);
}
finally
{
ReleaseDC(IntPtr.Zero, hdc);
}
}
static IntPtr Callback(ref ENUMLOGFONT font, ref NEWTEXTMETRIC metric,
int fontType, IntPtr lParam)
{
Console.WriteLine(font.FullName);
return new IntPtr(1);
}
[DllImport("user32.dll")]
static extern IntPtr GetDC(IntPtr hWnd);
[DllImport("user32.dll")]
static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);
[DllImport("gdi32.dll", CharSet=CharSet.Auto)]
static extern IntPtr EnumFontFamilies(
IntPtr hdc,
string family,
EnumFontFamProc proc,
IntPtr lParam);
delegate IntPtr EnumFontFamProc(
ref ENUMLOGFONT font,
ref NEWTEXTMETRIC metric,
[MarshalAs(UnmanagedType.U4)] int fontType,
IntPtr lParam);
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
struct LOGFONT
{
public int Height;
public int Width;
public int Escapement;
public int Orientation;
public int Weight;
public byte Italic;
public byte Underline;
public byte StrikeOut;
public byte CharSet;
public byte OutPrecision;
public byte ClipPrecision;
public byte Quality;
public byte PitchAndFamily;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)]
public string FaceName;
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
struct ENUMLOGFONT
{
public LOGFONT LogFont;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=64)]
public string FullName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)]
public string Style;
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
struct NEWTEXTMETRIC
{
public int Height;
public int Ascent;
public int Descent;
public int InternalLeading;
public int ExternalLeading;
public int AveCharWidth;
public int MaxCharWidth;
public int Weight;
public int Overhang;
public int DigitizedAspectX;
public int DigitizedAspectY;
public char FirstChar;
public char Lastchar;
public char DefaultChar;
public char BreakChar;
public byte Italic;
public byte Underlined;
public byte StruckOut;
public byte PitchAndFamily;
public byte CharSet;
[MarshalAs(UnmanagedType.U4)] public int Flags;
[MarshalAs(UnmanagedType.SysUInt)] public IntPtr SizeEM;
[MarshalAs(UnmanagedType.SysUInt)] public IntPtr CellHeight;
[MarshalAs(UnmanagedType.SysUInt)] public IntPtr AvgWidth;
}
}
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Thanks for the reply.
I checked the code on my machine, unforutnately it fails to fetch all fonts.
According to MSDN documentation use of the EnumFontFamiliesEx function is recommended.
in my code only the lfPitchAndFont part is not working, but it collects all fonts from all families.
if you wish i can send that snippet.
regards
|
|
|
|
|
It's only recommended. The problem with EnumFontFamiliesEx is that the EnumFontFamExProc uses a complex nesting of structs that may have problems marshaling. If you continue to use that, I would recommend flattening the structs (in unmanaged code, a struct is just a deign-time layout; in memory its just contiguous bits).
Define "is not working". That isn't very technical, nor do it help me understand what exactly isn't working.
Honestly, if you enumerate all fonts, OR the family type and whatever else together, and check the condition of lfPitchAndFont , that's really all you should have to do. When I use my code snippet, the LOTFONT data does reflect different lfPitchAndFont field values, so filtering by that field should work just fine.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
sorry for the ambiguity of 'not working', let me explain it please.
In case of "EnumFontFamilies", the total fonts fetched = 170, many of the charsets remain un fetched,
e.g. (only one record)
Verdana, PitchAndFamily:34, Char Set
where as in case of "EnumFontFamiliesEx", it fetches 467 fonts and if the device context of the screen is taken ( GetDC(IntPtr.Zero)) 934 fonts are fetched.
e.g. (mutliple records, depending on CharSet )
Verdana, PitchAndFamily No:34, CharSet No
Verdana, PitchAndFamily No:34, CharSet No:161
Verdana, PitchAndFamily No:34, CharSet No:162
Verdana, PitchAndFamily No:34, CharSet No:186
Verdana, PitchAndFamily No:34, CharSet No:238
Verdana, PitchAndFamily No:34, CharSet No:204
Verdana, PitchAndFamily No:34, CharSet No:163
The difference is huge, more over this is been tested on multiple machines.
its confusing....
|
|
|
|
|
If you look at the function signatures and read the documentation, it's because EnumFontFamilies enumerates only font families while EnumFontFamiliesEx enumerates font families and character sets and takes a pointer (use ref in C#) to a LOGFONT where there are three members that determine what is enumerated, including all character sets for a LOGFONT . There's the difference. They can do the same thing, but only EnumFontFamiliesEx can enumerate character sets for a given font family as well, which you may or may not need.
It's all documented in the Platform SDK.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Yes you are very correct.
I read the documentation on multiple occasions and what is expected to happen (in case of lfPichAndFont) is not happening. I need to enumerate charactor sets too as I am working on multilingual system. Depending on the selected language, I want to add relevent fonts in-side the RTF header.
really thanks for your patient and contineous support.
regards
|
|
|
|
|
As MSDN says:Must be set to zero for all language versions of the operating system. If you want to filter your results, you'll need to do what I mentioned before: enumerate all font families and character sets and manually filter the results by comparing the LOGFONT.lfPitchAndFamily field against what you want (using the code I posted earlier). Putting a value in this field and passing the address of the struct to EnumFontFamiliesEx will not work, as MSDN states. Manual filtering is your only option in this case.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hi All,
I have what appears to be a simple problem, but cannot for the life of me work out how to do this efficiently... can someone please help.
I am building up strings programatically, which I then want to evaluate as boolean. Not my ideal way of doing it, but Im stuck with it for legacy reasons.
ie. (much simplified example - actually many lines of code)
string sToConvert = "true && true && false";
I want to evaluate this string and get the boolean value from it - in this case false.
ie. something like this
bool bConverted = Convert.ToBoolean(sToConvert); // this does not work
Can anyone think of an easy way of doing this in C# ? I have got it working with by compiling it into code with System.CodeDom.Compiler and then evaluating it, but it seems really inefficient and slow.
Any help would be appreciated.
|
|
|
|
|
I don't know if this will be helpful or not, but if the string is always made of 'true' and 'false' in the string maybe you could do something like
string sToConvert = "true && true && false";
bool bConverted = sToConvert.IndexOf("false") == -1? true : false
|
|
|
|
|
good idea, thanks. Unfortunately the string could be slightly more complicated.
ie. string sToConvert = "(true && true) || (false && true)";
|
|
|
|
|
This might be a bit overpowered but right now I can't come up with an easier way:
You could create the sourcecode for a class with an "Evaluate()" method, add the expression to the code and then use classes from the System.CodeDom namespace to compile the sourcecode.
The class stub code could look similar to this:
string clsSrc = "public class Evaluator {";
clsSrc += " public static bool Evaluate() {";
clsSrc += " return "+expressionToEval+";";
clsSrc += "} }"; with expressionToEval being a string holding your expression.
Stuff this into ICodeCompiler.CompileAssemblyFromSource() .
The new assembly can be created in memory, so that you don't have to write to disk.
Then you'd call the method either using reflection or by defining an interface that your dynamically created class implements and calling the interface method and that's it.
mav
|
|
|
|
|
Mav's idea would work, but if you have to do this a lot you'll consume a heck of a lot of memory since assemblies can't be unloaded from a domain (the domain can be unloaded, though, so long as it's a different domain).
The best way is to write (or find; we did for our flagship app) a string tokenizer. If all you're handling is booleans, this would even be easier to write. You have only two operands: 'true' and 'false'. You have only 2 operators: '&&' and '||'. Your parens act only to push and pop the values in a certain order. The rest of this is a text-book case of stack manipulation, like many college courses will use for writing simple calculators (RPN calculators).
A quick search on google (for a link to show you) resulted in a very nice page with a Java calculator implementing what's discussed in the page that even shows the evaluation stack. See http://www.math.ubc.ca/~cass/courses/m266-99a/rpn/docs/ca.html[^] for details.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
A quick question, will all of your true false values be anded together? If this is the case, you can do something as simple as below:
string str = "true && true && false && true";
bool b = str.IndexOf("false") > 0 ? false : true;
MessageBox.Show(b.ToString());
- Nick Parker My Blog | My Articles
|
|
|
|
|
I want to cut some area from a image.How to do it?
|
|
|
|
|
There's many examples of image manipulation in .NET. I suggest you try searching for examples, like Microsoft FotoVision[^].
If you want to clip the area, create a Graphics object for the control using Control.CreateGrahpics . Or, better yet, handle the Paint event and get it from PaintEventArgs.Graphics . Then call SetClip to set the clipping region (the portions that would be drawn). Then call Graphics.DrawImage to draw the image. The clipping region will not be drawn.
If you want to copy a portion of the image into the clipboard and then delete it from the original image, that gets a bit more complicated. Not only must you implement what is above, you must also invert the clipping region (there are methods to do this) and draw that portion of the image into another image using the Graphics object for an Image , using Graphics.FromImage . This draw that clipped portion of the image into another image. You can then take tha Image and use, IIRC, Clipboard.SetDataObject(myClippedImage) , which may work. If not, adding image types to the clipboard (or for drag and drop operations, which basically amounts to the same thing) is very complicated and should be discussed in a different thread.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I do a user control,then I use it in my webapplication.I use the method that Image.FromFile(string strFilePath) in my user control.When I run the programm at ohter client to IE.exe, the method that Image.FromFile(string strFilePath) is fail. Because the file at local machine(WebApplication Server machine).How to do it?
|
|
|
|
|
It's really difficult to understand your question; it makes little sense.
You're saying that you're trying to create an image from the same file in two different applications using Image.FromFile ? Or are you saying that your web application is trying to access an image using Image.FromFile ? What path is it trying to access (remember that ASP.NET is only local to the server - it has no way to access the path on the client; that would be a severe security hole even if it were possible).
And if an exception is thrown, please be specific. Saying "[it] fail[s]" doesn't help. What's the exception type? What's the exception message? You must be specific when asking questions in a forum or newsgroup. We don't know your code and can't magically determine the specific problem could be with such a broad explanation of what you're doing.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
HI~
I have written a class, say class1, which implement an interface, say interface1 in project 1.
Then I wrote another class, say class2, which implement an interface, say interface2 in project 2. The code of interface2 is 100% the same as interface1.
Then I compile project 1 and got the a dll of class1 and a dll of interface1.
Afterthat, I compile project2 and build a dll of class2. Then I copy the the dll of class2 to project 1 and use it. That means the class2 dll using the dll of interface1.
In fact, although the code of two interfaces is the same, but the version or whatever still different(i.e dll of interface1 is different from dll of interface2). However, the class2 still can use the dll of interface1 without any runtime error. It is incrediable!
Does anyone know why? I don't know it well...
Thanks
|
|
|
|
|
The DLLs are just assemblies. And of course code in one assembly can use code in another it would be fairly pointless if it couldn't - no code reuability, no third party components etc. Every application would be huge because all code would have to be compiled into each application, rather than have applications share assemblies.
Class2 can use anything in the first assembly (where interface1 is) that is declared public . Or, if it derives from anything in the first assembly, the protected items in the base class es/interface s also.
I don't know if I've explained very well as I am having difficulty working out where you are coming from with your original post. Anyway, I hope it helps
"If a man empties his purse into his head, no man can take it away from him, for an investment in knowledge pays the best interest." -- Joseph E. O'Donnell
The Second EuroCPian Event will be in Brussels on the 4th of September
Can't manage to P/Invoke that Win32 API in .NET? Why not do interop the wiki way!
|
|
|
|
|
Hello everyone, I have a problem that I have been banging my head against the wall for the past few days trying to figure out...I am writing a remote assistance service and I want to send a file(a .jpg) using tcp/ip blocking sockets. I have used MANY other peoples source code, but still the file never arrives or I get ugly unhandled exceptions...I finally found one that sort of works...It sends a snapshot of the users screen ONE time, after that the client gives me a "connection reset by software on your remote host", I have included the client and server methods that are running in a seperate continuous thread...your help is MUCH appreciated.
P.S. sorry for the bad formatting.
<---Client source snippet--->
public static void BeginSnapShotSend()
{
ScreenCapture SC = new ScreenCapture();
try
{
// get the remote IP address...
IPHostEntry IPHost = Dns.Resolve("localhost");
IPAddress[] ip = IPHost.AddressList;
int iPortNo = System.Convert.ToInt32(443);
//create the end point
IPEndPoint ipEnd = new IPEndPoint (ip[0],iPortNo);
//connect to the remote host...
PicConnect.Connect ( ipEnd );
nfs = new NetworkStream(PicConnect) ;
}
catch (SocketException SE)
{
System.Windows.Forms.MessageBox.Show(SE.ToString());
return;
}
while (true)
{
SC.CaptureScreenToFile("sc.jpg", ImageFormat.Jpeg);
Thread.Sleep(1000);
try
{
FileStream fin = new FileStream("sc.jpg",FileMode.Open , FileAccess.Read) ;
//Get the Length of the file requested
//and set various variables
long total=fin.Length;
long rdby=0;
int len=0;
byte[] buffed = new byte[4096];
//Open the file requested for download
//One way of transfer over sockets is Using a NetworkStream
//It provides some useful ways to transfer data
byte[] m_sbuf = System.Text.Encoding.UTF8.GetBytes("fsize"+" "+total.ToString());
PicConnect.Send(m_sbuf);
Thread.Sleep(1000);
//lock the Thread here
while(rdby<total&&nfs.canwrite)
{
="" read="" from="" the="" file="" (len="" contains="" number="" of="" bytes="" read)
="" len="fin.Read(buffed,0,buffed.Length)" ;
="" write="" on="" socket
="" nfs.write(buffed,="" 0,="" len);
="" increase="" counter
="" rdby="rdby+len" ;=""
="" }="" display="" a="" message="" showing="" sucessful="" transfer
="" fin.close()="" }
="" catch(exception="" ed)
="" {="" system.windows.forms.messagebox.show("a="" exception="" occured="" in="" transfer"+ed.tostring())="" ;
="" return;
="" }
<---server="" snippet---="">
public void raptwm()
{
IPAddress ipAdress = IPAddress.Any;
IPEndPoint Enp = new IPEndPoint(ipAdress, 443);
Socket ListenTehCliPic = new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp);
ListenTehCliPic.Bind(Enp);
ListenTehCliPic.Listen(0);
Socket WorkWitTehCli = ListenTehCliPic.Accept();
NetworkStream nfs = new NetworkStream(WorkWitTehCli);
ListenTehCliPic.Close();
while (true)
{
bool done =false ;
bool check= false ;
long size=0 ;
long rby=0 ;
while(!done)
{
//declare a buffer
byte[] rce = new byte[2048];
//Recive a Sever Message
waitagain:
int i = WorkWitTehCli.Receive(rce,rce.Length,0) ;
//Convert it to string
string sm = System.Text.Encoding.ASCII.GetString(rce);
if(sm.StartsWith("fsize"))
{
string sizeoffile = sm.Remove(0,6);
//store the File Size
size=Int64.Parse(sizeoffile);
done=true ;
check=true ;
}
else
{
goto waitagain;
}
}
//The File Size has been received the continue
done=false;
//Make a File with the same name as the File that is being downloaded
//Also open a Network Stream to the Server
FileStream fout = new FileStream("sc.jpg", FileMode.OpenOrCreate , FileAccess.Write);
byte[] buffer = new byte[4096] ;
while(!done&&check)
{
try
{
long v=0 ;
//loop till the Full bytes have been read
while(rby<size)
{
="" read="" from="" the="" network="" stream
="" int="" i="nfs.Read(buffer,0,buffer.Length)" ;
="" if(i="">0)
{
//Some checking done to detremine the number of Bytes to be written
if(i>=4096&&(size-rby)>=4096)
{
v=4096 ;
}
else if(i<4096 &&(size-rby)>=4096)
{
v= i;
}
else
{
v=(size-rby) ;
}
//Write the Bytes received to the File
fout.Write(buffer,0,(int)v) ;
rby=rby+v ;
}
}
fout.Close() ;
done=true;
Thread.Sleep(100);
pictureBox1.Image = Image.FromFile("sc.jpg");
}
catch(Exception ed)
{
MessageBox.Show(MW,"A Exception occured in file transfer"+ed.ToString());
}
}
}
}
|
|
|
|
|
I have yet to figure out what everyone's infatuation with writing a VNC-like application in C# is. This is really not a good idea, mind you.
Not only are there already clients that do this installed in Windows (NetMeeting is standard in Win98 and Win2K and newer, or some form of it; Windows XP already has remote assistance that's very flexible) but you can even use some of the APIs like NetMeeting to integrate into your own application.
The true remote desktops don't use an entire screenshot, but a virtual frame buffer. Consider this: when a region is invalidated in Windows, it sends the WM_PAINT message with an HRGN that specifies what needs to be repainted (in .NET, this corresponds to the Paint event and the PaintEventArgs.ClipRectangle property). This may be an entire window or just a portion of it. But the entire screen is not drawn each time. By using a virtual frame buffer you take advantage of this (requiring much less bandwidth). Only the bits for the newly drawn portion are transferred across the wire.
It's this approach - if you're intent on reinventing the wheel (there's lots of "wheels" already, many very heavily tested) - you should look into. Unfortunately, .NET is too high level for such a task. Even if you do manage to P/Invoke all the native APIs you'll need an declare all the structs and consts, you'll incur performance penalties because of marshaling. You could, of course, write a Managed C++ assembly that alliviate most of these problems (mixing unmanaged and managed code to make such functionality accessible to other .NET assemblies written in any language).
What you're currently doing will have problems like you're seeing. Far too much bandwidth is required and will most likely require more time to transfer than your current refresh time, creating a large bottleneck that won't go away and will eventually cause timeouts (pretty quickly). The more lag on the wire, the faster timeouts will start occuring.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|