1 : /******************************************************************************
2 : * $Id: ogr_featurestyle.h 19442 2010-04-18 00:02:37Z mloskot $
3 : *
4 : * Project: OpenGIS Simple Features Reference Implementation
5 : * Purpose: Define of Feature Representation
6 : * Author: Stephane Villeneuve, stephane.v@videtron.ca
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 1999, Frank Warmerdam
10 : *
11 : * Permission is hereby granted, free of charge, to any person obtaining a
12 : * copy of this software and associated documentation files (the "Software"),
13 : * to deal in the Software without restriction, including without limitation
14 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 : * and/or sell copies of the Software, and to permit persons to whom the
16 : * Software is furnished to do so, subject to the following conditions:
17 : *
18 : * The above copyright notice and this permission notice shall be included
19 : * in all copies or substantial portions of the Software.
20 : *
21 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 : * DEALINGS IN THE SOFTWARE.
28 : ****************************************************************************/
29 :
30 : #ifndef OGR_FEATURESTYLE_INCLUDE
31 : #define OGR_FEATURESTYLE_INCLUDE
32 :
33 : #include "cpl_conv.h"
34 : #include "cpl_string.h"
35 : #include "ogr_core.h"
36 :
37 : class OGRFeature;
38 :
39 : /**
40 : * \file ogr_featurestyle.h
41 : *
42 : * Simple feature style classes.
43 : */
44 :
45 : /*
46 : * All OGRStyleTool param lists are defined in ogr_core.h.
47 : */
48 :
49 : typedef enum ogr_style_type
50 : {
51 : OGRSTypeString,
52 : OGRSTypeDouble,
53 : OGRSTypeInteger,
54 : OGRSTypeBoolean
55 : } OGRSType;
56 :
57 : typedef struct ogr_style_param
58 : {
59 : int eParam;
60 : const char *pszToken;
61 : GBool bGeoref;
62 : OGRSType eType;
63 : } OGRStyleParamId;
64 :
65 :
66 : typedef struct ogr_style_value
67 : {
68 : char *pszValue;
69 : double dfValue;
70 : int nValue; // Used for both integer and boolean types
71 : GBool bValid;
72 : OGRSTUnitId eUnit;
73 : } OGRStyleValue;
74 :
75 :
76 : //Everytime a pszStyleString gived in parameter is NULL,
77 : // the StyleString defined in the Mgr will be use.
78 : /**
79 : * This class represents a style table
80 : */
81 : class CPL_DLL OGRStyleTable
82 : {
83 : private:
84 : char **m_papszStyleTable;
85 :
86 : CPLString osLastRequestedStyleName;
87 : int iNextStyle;
88 :
89 : public:
90 : OGRStyleTable();
91 : ~OGRStyleTable();
92 : GBool AddStyle(const char *pszName,const char *pszStyleString);
93 : GBool RemoveStyle(const char *pszName);
94 : GBool ModifyStyle(const char *pszName, const char *pszStyleString);
95 :
96 : GBool SaveStyleTable(const char *pszFilename);
97 : GBool LoadStyleTable(const char *pszFilename);
98 : const char *Find(const char *pszStyleString);
99 : GBool IsExist(const char *pszName);
100 : const char *GetStyleName(const char *pszName);
101 : void Print(FILE *fpOut);
102 : void Clear();
103 : OGRStyleTable *Clone();
104 : void ResetStyleStringReading();
105 : const char *GetNextStyle();
106 : const char *GetLastStyleName();
107 : };
108 :
109 :
110 : class OGRStyleTool;
111 :
112 : /**
113 : * This class represents a style manager
114 : */
115 : class CPL_DLL OGRStyleMgr
116 : {
117 : private:
118 : OGRStyleTable *m_poDataSetStyleTable;
119 : char *m_pszStyleString;
120 :
121 : public:
122 : OGRStyleMgr(OGRStyleTable *poDataSetStyleTable = NULL);
123 : ~OGRStyleMgr();
124 :
125 : GBool SetFeatureStyleString(OGRFeature *,const char *pszStyleString=NULL,
126 : GBool bNoMatching = FALSE);
127 : /*it will set in the gived feature the pszStyleString with
128 : the style or will set the style name found in
129 : dataset StyleTable (if bNoMatching == FALSE)*/
130 :
131 : const char *InitFromFeature(OGRFeature *);
132 : GBool InitStyleString(const char *pszStyleString = NULL);
133 :
134 : const char *GetStyleName(const char *pszStyleString= NULL);
135 : const char *GetStyleByName(const char *pszStyleName);
136 :
137 : GBool AddStyle(const char *pszStyleName, const char *pszStyleString=NULL);
138 :
139 : const char *GetStyleString(OGRFeature * = NULL);
140 :
141 : GBool AddPart(OGRStyleTool *);
142 : GBool AddPart(const char *);
143 :
144 : int GetPartCount(const char *pszStyleString = NULL);
145 : OGRStyleTool *GetPart(int hPartId, const char *pszStyleString = NULL);
146 :
147 : /*It could have a reference counting processus for the OGRStyleTable, if
148 : needed */
149 :
150 : OGRStyleTable *GetDataSetStyleTable(){return m_poDataSetStyleTable;}
151 :
152 : OGRStyleTool *CreateStyleToolFromStyleString(const char *pszStyleString);
153 :
154 : };
155 :
156 : /**
157 : * This class represents a style tool
158 : */
159 : class CPL_DLL OGRStyleTool
160 : {
161 : private:
162 : GBool m_bModified;
163 : GBool m_bParsed;
164 : double m_dfScale;
165 : OGRSTUnitId m_eUnit;
166 : OGRSTClassId m_eClassId;
167 : char *m_pszStyleString;
168 :
169 : virtual GBool Parse() = 0;
170 :
171 : protected:
172 : GBool Parse(const OGRStyleParamId* pasStyle,
173 : OGRStyleValue* pasValue,
174 : int nCount);
175 :
176 : public:
177 :
178 : OGRStyleTool(){}
179 : OGRStyleTool(OGRSTClassId eClassId);
180 : virtual ~OGRStyleTool();
181 :
182 : GBool GetRGBFromString(const char *pszColor, int &nRed, int &nGreen,
183 : int &nBlue, int &nTransparence);
184 : int GetSpecificId(const char *pszId, const char *pszWanted);
185 :
186 186 : GBool IsStyleModified() {return m_bModified;}
187 175 : void StyleModified() {m_bModified = TRUE;}
188 :
189 291 : GBool IsStyleParsed() {return m_bParsed;}
190 100 : void StyleParsed() {m_bParsed = TRUE;}
191 :
192 : OGRSTClassId GetType();
193 :
194 : void SetInternalInputUnitFromParam(char *pszString);
195 :
196 : void SetUnit(OGRSTUnitId,double dfScale = 1.0); //the dfScale will be
197 : //used if we are working with Ground Unit ( ground = paper * scale);
198 :
199 210 : OGRSTUnitId GetUnit(){return m_eUnit;}
200 :
201 : /* It's existe two way to set the parameters in the Style, with generic
202 : methodes (using a defined enumeration) or with the reel method specific
203 : for Each style tools.*/
204 :
205 : virtual const char *GetStyleString() = 0;
206 : void SetStyleString(const char *pszStyleString);
207 : const char *GetStyleString(const OGRStyleParamId *pasStyleParam ,
208 : OGRStyleValue *pasStyleValue, int nSize);
209 :
210 : const char *GetParamStr(const OGRStyleParamId &sStyleParam ,
211 : OGRStyleValue &sStyleValue,
212 : GBool &bValueIsNull);
213 :
214 : int GetParamNum(const OGRStyleParamId &sStyleParam ,
215 : OGRStyleValue &sStyleValue,
216 : GBool &bValueIsNull);
217 :
218 : double GetParamDbl(const OGRStyleParamId &sStyleParam ,
219 : OGRStyleValue &sStyleValue,
220 : GBool &bValueIsNull);
221 :
222 : void SetParamStr(const OGRStyleParamId &sStyleParam ,
223 : OGRStyleValue &sStyleValue,
224 : const char *pszParamString);
225 :
226 : void SetParamNum(const OGRStyleParamId &sStyleParam ,
227 : OGRStyleValue &sStyleValue,
228 : int nParam);
229 :
230 : void SetParamDbl(const OGRStyleParamId &sStyleParam ,
231 : OGRStyleValue &sStyleValue,
232 : double dfParam);
233 :
234 : double ComputeWithUnit(double, OGRSTUnitId);
235 : int ComputeWithUnit(int , OGRSTUnitId);
236 :
237 : };
238 :
239 : /**
240 : * This class represents a style pen
241 : */
242 : class CPL_DLL OGRStylePen : public OGRStyleTool
243 : {
244 : private:
245 :
246 : OGRStyleValue *m_pasStyleValue;
247 :
248 : GBool Parse();
249 :
250 : public:
251 :
252 : OGRStylePen();
253 : virtual ~OGRStylePen();
254 :
255 : /**********************************************************************/
256 : /* Explicit fct for all parameters defined in the Drawing tools Pen */
257 : /**********************************************************************/
258 :
259 : const char *Color(GBool &bDefault){return GetParamStr(OGRSTPenColor,bDefault);}
260 : void SetColor(const char *pszColor){SetParamStr(OGRSTPenColor,pszColor);}
261 : double Width(GBool &bDefault){return GetParamDbl(OGRSTPenWidth,bDefault);}
262 : void SetWidth(double dfWidth){SetParamDbl(OGRSTPenWidth,dfWidth);}
263 : const char *Pattern(GBool &bDefault){return (const char *)GetParamStr(OGRSTPenPattern,bDefault);}
264 : void SetPattern(const char *pszPattern){SetParamStr(OGRSTPenPattern,pszPattern);}
265 : const char *Id(GBool &bDefault){return GetParamStr(OGRSTPenId,bDefault);}
266 : void SetId(const char *pszId){SetParamStr(OGRSTPenId,pszId);}
267 : double PerpendicularOffset(GBool &bDefault){return GetParamDbl(OGRSTPenPerOffset,bDefault);}
268 : void SetPerpendicularOffset(double dfPerp){SetParamDbl(OGRSTPenPerOffset,dfPerp);}
269 : const char *Cap(GBool &bDefault){return GetParamStr(OGRSTPenCap,bDefault);}
270 : void SetCap(const char *pszCap){SetParamStr(OGRSTPenCap,pszCap);}
271 : const char *Join(GBool &bDefault){return GetParamStr(OGRSTPenJoin,bDefault);}
272 : void SetJoin(const char *pszJoin){SetParamStr(OGRSTPenJoin,pszJoin);}
273 : int Priority(GBool &bDefault){return GetParamNum(OGRSTPenPriority,bDefault);}
274 : void SetPriority(int nPriority){SetParamNum(OGRSTPenPriority,nPriority);}
275 :
276 : /*****************************************************************/
277 :
278 : const char *GetParamStr(OGRSTPenParam eParam, GBool &bValueIsNull);
279 : int GetParamNum(OGRSTPenParam eParam,GBool &bValueIsNull);
280 : double GetParamDbl(OGRSTPenParam eParam,GBool &bValueIsNull);
281 : void SetParamStr(OGRSTPenParam eParam, const char *pszParamString);
282 : void SetParamNum(OGRSTPenParam eParam, int nParam);
283 : void SetParamDbl(OGRSTPenParam eParam, double dfParam);
284 : const char *GetStyleString();
285 : };
286 :
287 : /**
288 : * This class represents a style brush
289 : */
290 : class CPL_DLL OGRStyleBrush : public OGRStyleTool
291 : {
292 : private:
293 :
294 : OGRStyleValue *m_pasStyleValue;
295 :
296 : GBool Parse();
297 :
298 : public:
299 :
300 : OGRStyleBrush();
301 : virtual ~OGRStyleBrush();
302 :
303 : /* Explicit fct for all parameters defined in the Drawing tools Brush */
304 :
305 : const char *ForeColor(GBool &bDefault){return GetParamStr(OGRSTBrushFColor,bDefault);}
306 : void SetForeColor(const char *pszColor){SetParamStr(OGRSTBrushFColor,pszColor);}
307 : const char *BackColor(GBool &bDefault){return GetParamStr(OGRSTBrushBColor,bDefault);}
308 : void SetBackColor(const char *pszColor){SetParamStr(OGRSTBrushBColor,pszColor);}
309 : const char *Id(GBool &bDefault){ return GetParamStr(OGRSTBrushId,bDefault);}
310 : void SetId(const char *pszId){SetParamStr(OGRSTBrushId,pszId);}
311 : double Angle(GBool &bDefault){return GetParamDbl(OGRSTBrushAngle,bDefault);}
312 : void SetAngle(double dfAngle){SetParamDbl(OGRSTBrushAngle,dfAngle );}
313 : double Size(GBool &bDefault){return GetParamDbl(OGRSTBrushSize,bDefault);}
314 : void SetSize(double dfSize){SetParamDbl(OGRSTBrushSize,dfSize );}
315 : double SpacingX(GBool &bDefault){return GetParamDbl(OGRSTBrushDx,bDefault);}
316 : void SetSpacingX(double dfX){SetParamDbl(OGRSTBrushDx,dfX );}
317 : double SpacingY(GBool &bDefault){return GetParamDbl(OGRSTBrushDy,bDefault);}
318 : void SetSpacingY(double dfY){SetParamDbl(OGRSTBrushDy,dfY );}
319 : int Priority(GBool &bDefault){ return GetParamNum(OGRSTBrushPriority,bDefault);}
320 : void SetPriority(int nPriority){ SetParamNum(OGRSTBrushPriority,nPriority);}
321 :
322 :
323 : /*****************************************************************/
324 :
325 : const char *GetParamStr(OGRSTBrushParam eParam, GBool &bValueIsNull);
326 : int GetParamNum(OGRSTBrushParam eParam,GBool &bValueIsNull);
327 : double GetParamDbl(OGRSTBrushParam eParam,GBool &bValueIsNull);
328 : void SetParamStr(OGRSTBrushParam eParam, const char *pszParamString);
329 : void SetParamNum(OGRSTBrushParam eParam, int nParam);
330 : void SetParamDbl(OGRSTBrushParam eParam, double dfParam);
331 : const char *GetStyleString();
332 : };
333 :
334 : /**
335 : * This class represents a style symbol
336 : */
337 : class CPL_DLL OGRStyleSymbol : public OGRStyleTool
338 : {
339 : private:
340 :
341 : OGRStyleValue *m_pasStyleValue;
342 :
343 : GBool Parse();
344 :
345 : public:
346 :
347 : OGRStyleSymbol();
348 : virtual ~OGRStyleSymbol();
349 :
350 : /*****************************************************************/
351 : /* Explicit fct for all parameters defined in the Drawing tools */
352 : /*****************************************************************/
353 :
354 : const char *Id(GBool &bDefault){return GetParamStr(OGRSTSymbolId,bDefault);}
355 : void SetId(const char *pszId){ SetParamStr(OGRSTSymbolId,pszId);}
356 : double Angle(GBool &bDefault){ return GetParamDbl(OGRSTSymbolAngle,bDefault);}
357 : void SetAngle(double dfAngle){SetParamDbl(OGRSTSymbolAngle,dfAngle );}
358 : const char *Color(GBool &bDefault){return GetParamStr(OGRSTSymbolColor,bDefault);}
359 : void SetColor(const char *pszColor){SetParamStr(OGRSTSymbolColor,pszColor);}
360 : double Size(GBool &bDefault){ return GetParamDbl(OGRSTSymbolSize,bDefault);}
361 : void SetSize(double dfSize){ SetParamDbl(OGRSTSymbolSize,dfSize );}
362 : double SpacingX(GBool &bDefault){return GetParamDbl(OGRSTSymbolDx,bDefault);}
363 : void SetSpacingX(double dfX){SetParamDbl(OGRSTSymbolDx,dfX );}
364 : double SpacingY(GBool &bDefault){return GetParamDbl(OGRSTSymbolDy,bDefault);}
365 : void SetSpacingY(double dfY){SetParamDbl(OGRSTSymbolDy,dfY );}
366 : double Step(GBool &bDefault){return GetParamDbl(OGRSTSymbolStep,bDefault);}
367 : void SetStep(double dfStep){SetParamDbl(OGRSTSymbolStep,dfStep );}
368 : double Offset(GBool &bDefault){return GetParamDbl(OGRSTSymbolOffset,bDefault);}
369 : void SetOffset(double dfOffset){SetParamDbl(OGRSTSymbolOffset,dfOffset );}
370 : double Perp(GBool &bDefault){return GetParamDbl(OGRSTSymbolPerp,bDefault);}
371 : void SetPerp(double dfPerp){SetParamDbl(OGRSTSymbolPerp,dfPerp );}
372 : int Priority(GBool &bDefault){return GetParamNum(OGRSTSymbolPriority,bDefault);}
373 : void SetPriority(int nPriority){SetParamNum(OGRSTSymbolPriority,nPriority);}
374 : const char *FontName(GBool &bDefault)
375 : {return GetParamStr(OGRSTSymbolFontName,bDefault);}
376 : void SetFontName(const char *pszFontName)
377 : {SetParamStr(OGRSTSymbolFontName,pszFontName);}
378 : const char *OColor(GBool &bDefault){return GetParamStr(OGRSTSymbolOColor,bDefault);}
379 : void SetOColor(const char *pszColor){SetParamStr(OGRSTSymbolOColor,pszColor);}
380 :
381 : /*****************************************************************/
382 :
383 : const char *GetParamStr(OGRSTSymbolParam eParam, GBool &bValueIsNull);
384 : int GetParamNum(OGRSTSymbolParam eParam,GBool &bValueIsNull);
385 : double GetParamDbl(OGRSTSymbolParam eParam,GBool &bValueIsNull);
386 : void SetParamStr(OGRSTSymbolParam eParam, const char *pszParamString);
387 : void SetParamNum(OGRSTSymbolParam eParam, int nParam);
388 : void SetParamDbl(OGRSTSymbolParam eParam, double dfParam);
389 : const char *GetStyleString();
390 : };
391 :
392 : /**
393 : * This class represents a style label
394 : */
395 : class CPL_DLL OGRStyleLabel : public OGRStyleTool
396 : {
397 : private:
398 :
399 : OGRStyleValue *m_pasStyleValue;
400 :
401 : GBool Parse();
402 :
403 : public:
404 :
405 : OGRStyleLabel();
406 : virtual ~OGRStyleLabel();
407 :
408 : /*****************************************************************/
409 : /* Explicit fct for all parameters defined in the Drawing tools */
410 : /*****************************************************************/
411 :
412 : const char *FontName(GBool &bDefault){return GetParamStr(OGRSTLabelFontName,bDefault);}
413 : void SetFontName(const char *pszFontName){SetParamStr(OGRSTLabelFontName,pszFontName);}
414 : double Size(GBool &bDefault){return GetParamDbl(OGRSTLabelSize,bDefault);}
415 : void SetSize(double dfSize){SetParamDbl(OGRSTLabelSize,dfSize);}
416 : const char *TextString(GBool &bDefault){return GetParamStr(OGRSTLabelTextString,bDefault);}
417 : void SetTextString(const char *pszTextString){SetParamStr(OGRSTLabelTextString,pszTextString);}
418 : double Angle(GBool &bDefault){return GetParamDbl(OGRSTLabelAngle,bDefault);}
419 : void SetAngle(double dfAngle){SetParamDbl(OGRSTLabelAngle,dfAngle);}
420 : const char *ForeColor(GBool &bDefault){return GetParamStr(OGRSTLabelFColor,bDefault);}
421 : void SetForColor(const char *pszForColor){SetParamStr(OGRSTLabelFColor,pszForColor);}
422 : const char *BackColor(GBool &bDefault){return GetParamStr(OGRSTLabelBColor,bDefault);}
423 : void SetBackColor(const char *pszBackColor){SetParamStr(OGRSTLabelBColor,pszBackColor);}
424 : const char *Placement(GBool &bDefault){return GetParamStr(OGRSTLabelPlacement,bDefault);}
425 : void SetPlacement(const char *pszPlacement){SetParamStr(OGRSTLabelPlacement,pszPlacement);}
426 : int Anchor(GBool &bDefault){return GetParamNum(OGRSTLabelAnchor,bDefault);}
427 : void SetAnchor(int nAnchor){SetParamNum(OGRSTLabelAnchor,nAnchor);}
428 : double SpacingX(GBool &bDefault){return GetParamDbl(OGRSTLabelDx,bDefault);}
429 : void SetSpacingX(double dfX){SetParamDbl(OGRSTLabelDx,dfX);}
430 : double SpacingY(GBool &bDefault){return GetParamDbl(OGRSTLabelDy,bDefault);}
431 : void SetSpacingY(double dfY){SetParamDbl(OGRSTLabelDy,dfY);}
432 : double Perp(GBool &bDefault){return GetParamDbl(OGRSTLabelPerp,bDefault);}
433 : void SetPerp(double dfPerp){SetParamDbl(OGRSTLabelPerp,dfPerp);}
434 : GBool Bold(GBool &bDefault){return GetParamNum(OGRSTLabelBold,bDefault);}
435 : void SetBold(GBool bBold){SetParamNum(OGRSTLabelBold,bBold);}
436 : GBool Italic(GBool &bDefault){return GetParamNum(OGRSTLabelItalic,bDefault);}
437 : void SetItalic(GBool bItalic){SetParamNum(OGRSTLabelItalic,bItalic);}
438 : GBool Underline(GBool &bDefault){return GetParamNum(OGRSTLabelUnderline,bDefault);}
439 : void SetUnderline(GBool bUnderline){SetParamNum(OGRSTLabelUnderline,bUnderline);}
440 : int Priority(GBool &bDefault){return GetParamNum(OGRSTLabelPriority,bDefault);}
441 : void SetPriority(int nPriority){SetParamNum(OGRSTLabelPriority,nPriority);}
442 : GBool Strikeout(GBool &bDefault){return GetParamNum(OGRSTLabelStrikeout,bDefault);}
443 : void SetStrikeout(GBool bStrikeout){SetParamNum(OGRSTLabelStrikeout,bStrikeout);}
444 : double Stretch(GBool &bDefault){return GetParamDbl(OGRSTLabelStretch,bDefault);}
445 : void SetStretch(double dfStretch){SetParamDbl(OGRSTLabelStretch,dfStretch);}
446 : const char *AdjustmentHor(GBool &bDefault){return GetParamStr(OGRSTLabelAdjHor,bDefault);}
447 : void SetAdjustmentHor(const char *pszAdjustmentHor){SetParamStr(OGRSTLabelAdjHor,pszAdjustmentHor);}
448 : const char *AdjustmentVert(GBool &bDefault){return GetParamStr(OGRSTLabelAdjVert,bDefault);}
449 : void SetAdjustmentVert(const char *pszAdjustmentVert){SetParamStr(OGRSTLabelAdjHor,pszAdjustmentVert);}
450 : const char *ShadowColor(GBool &bDefault){return GetParamStr(OGRSTLabelHColor,bDefault);}
451 : void SetShadowColor(const char *pszShadowColor){SetParamStr(OGRSTLabelHColor,pszShadowColor);}
452 : const char *OutlineColor(GBool &bDefault){return GetParamStr(OGRSTLabelOColor,bDefault);}
453 : void SetOutlineColor(const char *pszOutlineColor){SetParamStr(OGRSTLabelOColor,pszOutlineColor);}
454 :
455 : /*****************************************************************/
456 :
457 : const char *GetParamStr(OGRSTLabelParam eParam, GBool &bValueIsNull);
458 : int GetParamNum(OGRSTLabelParam eParam,GBool &bValueIsNull);
459 : double GetParamDbl(OGRSTLabelParam eParam,GBool &bValueIsNull);
460 : void SetParamStr(OGRSTLabelParam eParam, const char *pszParamString);
461 : void SetParamNum(OGRSTLabelParam eParam, int nParam);
462 : void SetParamDbl(OGRSTLabelParam eParam, double dfParam);
463 : const char *GetStyleString();
464 : };
465 :
466 : #endif /* OGR_FEATURESTYLE_INCLUDE */
|