Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
mpim-sw
libcdi
Commits
37d3a775
Commit
37d3a775
authored
Aug 15, 2013
by
Uwe Schulzweida
Browse files
made gridtype GRID_REFERENCE part of GRID_UNSTRUCTED and removed it
parent
9948e509
Changes
12
Hide whitespace changes
Inline
Side-by-side
ChangeLog
View file @
37d3a775
...
...
@@ -3,6 +3,11 @@
* Version 1.6.2 released
* using CGRIBEX library version 1.6.2
2013-08-15 Uwe Schulzweida <Uwe.Schulzweida@zmaw.de>
* made gridtype GRID_REFERENCE part of GRID_UNSTRUCTED
* removed gridtype GRID_REFERENCE
2013-08-12 Uwe Schulzweida <Uwe.Schulzweida@zmaw.de>
* GRIB2: added support for level type Lake Bottom (grib level type 162)
...
...
NEWS
View file @
37d3a775
...
...
@@ -4,6 +4,7 @@ CDI NEWS
Version 1.6.2 (26 September 2013):
New features:
* made gridtype GRID_REFERENCE part of GRID_UNSTRUCTED
* GRIB2: added support for level type Lake Bottom (grib level type 162)
* GRIB2: added support for level type Bottom Of Sediment Layer (grib level type 163)
* GRIB2: added support for level type Bottom Of Thermally Active Sediment Layer (grib level type 164)
...
...
app/printinfo.h
View file @
37d3a775
...
...
@@ -276,28 +276,37 @@ void printGridInfo(int vlistID)
nd
=
gridInqGMEnd
(
gridID
);
fprintf
(
stdout
,
"size : dim = %d nd = %d ni = %d
\n
"
,
gridsize
,
nd
,
ni
);
}
else
if
(
gridtype
==
GRID_REFERENCE
)
{
int
number
,
position
;
number
=
gridInqNumber
(
gridID
);
position
=
gridInqPosition
(
gridID
);
fprintf
(
stdout
,
"size : dim = %d
\n
"
,
gridsize
);
fprintf
(
stdout
,
"%*s"
,
nbyte0
,
""
);
fprintf
(
stdout
,
"grid : number = %d position = %d
\n
"
,
number
,
position
);
if
(
gridInqReference
(
gridID
,
NULL
)
)
{
char
reference_link
[
8192
];
gridInqReference
(
gridID
,
reference_link
);
fprintf
(
stdout
,
"%*s"
,
nbyte0
,
""
);
fprintf
(
stdout
,
"path : %s
\n
"
,
reference_link
);
}
}
else
if
(
gridtype
==
GRID_CURVILINEAR
||
gridtype
==
GRID_UNSTRUCTURED
)
{
int
number
=
gridInqNumber
(
gridID
);
int
position
=
gridInqPosition
(
gridID
);
if
(
gridtype
==
GRID_CURVILINEAR
)
fprintf
(
stdout
,
"size : dim = %d nx = %d ny = %d
\n
"
,
gridsize
,
xsize
,
ysize
);
fprintf
(
stdout
,
"size : dim = %d nx = %d ny = %d"
,
gridsize
,
xsize
,
ysize
);
else
fprintf
(
stdout
,
"size : dim = %d nvertex = %d
\n
"
,
gridsize
,
gridInqNvertex
(
gridID
));
fprintf
(
stdout
,
"size : dim = %d"
,
gridsize
);
if
(
gridtype
==
GRID_UNSTRUCTURED
&&
gridInqNvertex
(
gridID
)
>
0
)
fprintf
(
stdout
,
" nvertex = %d
\n
"
,
gridInqNvertex
(
gridID
));
fprintf
(
stdout
,
"
\n
"
);
if
(
gridtype
==
GRID_UNSTRUCTURED
)
{
if
(
number
>
0
)
{
fprintf
(
stdout
,
"%*s"
,
nbyte0
,
""
);
fprintf
(
stdout
,
"grid : number = %d position = %d
\n
"
,
number
,
position
);
}
if
(
gridInqReference
(
gridID
,
NULL
)
)
{
char
reference_link
[
8192
];
gridInqReference
(
gridID
,
reference_link
);
fprintf
(
stdout
,
"%*s"
,
nbyte0
,
""
);
fprintf
(
stdout
,
"path : %s
\n
"
,
reference_link
);
}
}
if
(
gridInqXvals
(
gridID
,
NULL
)
&&
gridInqYvals
(
gridID
,
NULL
)
)
{
...
...
doc/tex/c_grid.tex
View file @
37d3a775
...
...
@@ -18,8 +18,7 @@ The function {\tt gridCreate} creates a horizontal Grid.
The type of the grid, one of the set of predefined
{
\CDI
}
grid types.
The valid
{
\CDI
}
grid types are
{
\tt
GRID
\_
GENERIC
}
,
{
\tt
GRID
\_
GAUSSIAN
}
,
{
\tt
GRID
\_
LONLAT
}
,
{
\tt
GRID
\_
LCC
}
,
{
\tt
GRID
\_
SPECTRAL
}
,
{
\tt
GRID
\_
GME
}
,
{
\tt
GRID
\_
CURVILINEAR
}
,
{
\tt
GRID
\_
UNSTRUCTURED
}
and
{
\tt
GRID
\_
REFERENCE
}
.
{
\tt
GRID
\_
GME
}
,
{
\tt
GRID
\_
CURVILINEAR
}
and
{
\tt
GRID
\_
UNSTRUCTURED
}
and.
\item
[{\tt size}]
Number of gridpoints.
...
...
@@ -126,7 +125,7 @@ Grid ID, from a previous call to {\htmlref{\tt gridCreate}{gridCreate}}.
one of the set of predefined
{
\CDI
}
grid types.
The valid
{
\CDI
}
grid types are
{
\tt
GRID
\_
GENERIC
}
,
{
\tt
GRID
\_
GAUSSIAN
}
,
{
\tt
GRID
\_
LONLAT
}
,
{
\tt
GRID
\_
LCC
}
,
{
\tt
GRID
\_
SPECTRAL
}
,
{
\tt
GRID
\_
GME
}
,
{
\tt
GRID
\_
CURVILINEAR
}
,
{
\tt
GRID
\_
UNSTRUCTURED
}
and
{
\tt
GRID
\_
REFERENCE
}
.
{
\tt
GRID
\_
CURVILINEAR
}
and
{
\tt
GRID
\_
UNSTRUCTURED
}
.
...
...
doc/tex/f_grid.tex
View file @
37d3a775
...
...
@@ -18,8 +18,7 @@ The function {\tt gridCreate} creates a horizontal Grid.
The type of the grid, one of the set of predefined
{
\CDI
}
grid types.
The valid
{
\CDI
}
grid types are
{
\tt
GRID
\_
GENERIC
}
,
{
\tt
GRID
\_
GAUSSIAN
}
,
{
\tt
GRID
\_
LONLAT
}
,
{
\tt
GRID
\_
LCC
}
,
{
\tt
GRID
\_
SPECTRAL
}
,
{
\tt
GRID
\_
GME
}
,
{
\tt
GRID
\_
CURVILINEAR
}
,
{
\tt
GRID
\_
UNSTRUCTURED
}
and
{
\tt
GRID
\_
REFERENCE
}
.
{
\tt
GRID
\_
GME
}
,
{
\tt
GRID
\_
CURVILINEAR
}
and
{
\tt
GRID
\_
UNSTRUCTURED
}
and.
\item
[{\tt size}]
Number of gridpoints.
...
...
@@ -126,7 +125,7 @@ Grid ID, from a previous call to {\htmlref{\tt gridCreate}{gridCreate}}.
one of the set of predefined
{
\CDI
}
grid types.
The valid
{
\CDI
}
grid types are
{
\tt
GRID
\_
GENERIC
}
,
{
\tt
GRID
\_
GAUSSIAN
}
,
{
\tt
GRID
\_
LONLAT
}
,
{
\tt
GRID
\_
LCC
}
,
{
\tt
GRID
\_
SPECTRAL
}
,
{
\tt
GRID
\_
GME
}
,
{
\tt
GRID
\_
CURVILINEAR
}
,
{
\tt
GRID
\_
UNSTRUCTURED
}
and
{
\tt
GRID
\_
REFERENCE
}
.
{
\tt
GRID
\_
CURVILINEAR
}
and
{
\tt
GRID
\_
UNSTRUCTURED
}
.
...
...
src/cdi.h
View file @
37d3a775
...
...
@@ -134,8 +134,7 @@ extern "C" {
#define GRID_LCC2 12
/* Lambert Conformal Conic (PROJ) */
#define GRID_LAEA 13
/* Lambert Azimuthal Equal Area */
#define GRID_SINUSOIDAL 14
/* Sinusoidal */
#define GRID_REFERENCE 15
/* Grid reference number */
#define GRID_PROJECTION 16
/* Projected coordiantes */
#define GRID_PROJECTION 15
/* Projected coordiantes */
/* ZAXIS types */
...
...
src/cdi.inc
View file @
37d3a775
...
...
@@ -223,10 +223,8 @@
PARAMETER
(
GRID_LAEA
=
13
)
INTEGER
GRID_SINUSOIDAL
PARAMETER
(
GRID_SINUSOIDAL
=
14
)
INTEGER
GRID_REFERENCE
PARAMETER
(
GRID_REFERENCE
=
15
)
INTEGER
GRID_PROJECTION
PARAMETER
(
GRID_PROJECTION
=
1
6
)
PARAMETER
(
GRID_PROJECTION
=
1
5
)
!
!
ZAXIS
types
!
...
...
src/gribapi.h
View file @
37d3a775
...
...
@@ -40,7 +40,7 @@
#define GRIB2_GTYPE_LCC 30
/* Lambert conformal */
#define GRIB2_GTYPE_SPECTRAL 50
/* spherical harmonics */
#define GRIB2_GTYPE_GME 100
/* hexagonal GME grid */
#define GRIB2_GTYPE_
NUMBER
101
/* General Unstructured Grid */
#define GRIB2_GTYPE_
UNSTRUCTURED
101
/* General Unstructured Grid */
const
char
*
gribapiLibraryVersion
(
void
);
void
gribContainersNew
(
stream_t
*
streamptr
);
...
...
src/grid.c
View file @
37d3a775
...
...
@@ -41,8 +41,7 @@ char *Grids[] = {
/* 12 */
"lcc2"
,
/* 13 */
"laea"
,
/* 14 */
"sinusoidal"
,
/* 15 */
"reference"
,
/* 16 */
"projection"
,
/* 15 */
"projection"
,
};
...
...
@@ -348,8 +347,7 @@ void gridGenYvals(int gridtype, int ysize, double yfirst, double ylast, double y
@Item gridtype The type of the grid, one of the set of predefined CDI grid types.
The valid CDI grid types are @func{GRID_GENERIC}, @func{GRID_GAUSSIAN},
@func{GRID_LONLAT}, @func{GRID_LCC}, @func{GRID_SPECTRAL},
@func{GRID_GME}, @func{GRID_CURVILINEAR}, @func{GRID_UNSTRUCTURED} and
@func{GRID_REFERENCE}.
@func{GRID_GME}, @func{GRID_CURVILINEAR} and @func{GRID_UNSTRUCTURED} and.
@Item size Number of gridpoints.
@Description
...
...
@@ -959,7 +957,7 @@ The function @func{gridInqType} returns the type of a Grid.
one of the set of predefined CDI grid types.
The valid CDI grid types are @func{GRID_GENERIC}, @func{GRID_GAUSSIAN},
@func{GRID_LONLAT}, @func{GRID_LCC}, @func{GRID_SPECTRAL}, @func{GRID_GME},
@func{GRID_CURVILINEAR}
,
@func{GRID_UNSTRUCTURED}
and @func{GRID_REFERENCE}
.
@func{GRID_CURVILINEAR}
and
@func{GRID_UNSTRUCTURED}.
@EndFunction
*/
...
...
@@ -2792,6 +2790,20 @@ int gridGenerate(grid_t grid)
grid
.
lcc_lat1
,
grid
.
lcc_lat2
,
grid
.
lcc_xinc
,
grid
.
lcc_yinc
,
grid
.
lcc_projflag
,
grid
.
lcc_scanflag
);
if
(
grid
.
type
==
GRID_UNSTRUCTURED
)
{
int
number
=
grid
.
number
;
int
position
=
grid
.
position
;
if
(
position
<
0
)
position
=
0
;
if
(
number
>
0
)
{
gridDefNumber
(
gridID
,
number
);
gridDefPosition
(
gridID
,
position
);
}
if
(
grid
.
uuid
[
0
]
!=
0
)
gridDefUUID
(
gridID
,
grid
.
uuid
);
if
(
grid
.
reference
)
gridDefReference
(
gridID
,
grid
.
reference
);
}
if
(
grid
.
type
==
GRID_PROJECTION
)
{
gridptr
->
name
=
strdup
(
grid
.
name
);
...
...
@@ -2850,14 +2862,6 @@ int gridGenerate(grid_t grid)
gridDefGMEni3
(
gridID
,
grid
.
ni3
);
break
;
}
case
GRID_REFERENCE
:
{
gridDefNumber
(
gridID
,
grid
.
number
);
gridDefPosition
(
gridID
,
grid
.
position
);
gridDefUUID
(
gridID
,
grid
.
uuid
);
if
(
grid
.
reference
)
gridDefReference
(
gridID
,
grid
.
reference
);
break
;
}
/*
case GRID_GENERIC:
{
...
...
@@ -3503,6 +3507,31 @@ void gridPrintKernel(grid_t * gridptr, int opt, FILE *fp)
if
(
ysize
>
0
)
fprintf
(
fp
,
"ysize = %d
\n
"
,
ysize
);
}
if
(
type
==
GRID_UNSTRUCTURED
)
{
int
number
=
gridInqNumber
(
gridID
);
int
position
=
gridInqPosition
(
gridID
);
// const unsigned char *d;
if
(
number
>
0
)
{
fprintf
(
fp
,
"number = %d
\n
"
,
number
);
if
(
position
>=
0
)
fprintf
(
fp
,
"position = %d
\n
"
,
position
);
}
/*
gridInqUUID(gridID, uuidOfHGrid);
d = (unsigned char *) &uuidOfHGrid;
fprintf(fp, "uuid = %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7],
d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
*/
if
(
gridInqReference
(
gridID
,
NULL
)
)
{
char
reference_link
[
8192
];
gridInqReference
(
gridID
,
reference_link
);
fprintf
(
fp
,
"path = %s
\n
"
,
reference_link
);
}
}
if
(
type
==
GRID_LAEA
)
{
double
a
=
0
,
lon_0
=
0
,
lat_0
=
0
;
...
...
@@ -3705,26 +3734,6 @@ void gridPrintKernel(grid_t * gridptr, int opt, FILE *fp)
fprintf
(
fp
,
"ni = %d
\n
"
,
gridptr
->
ni
);
break
;
}
case
GRID_REFERENCE
:
{
// const unsigned char *d;
fprintf
(
fp
,
"number = %d
\n
"
,
gridInqNumber
(
gridID
));
fprintf
(
fp
,
"position = %d
\n
"
,
gridInqPosition
(
gridID
));
/*
gridInqUUID(gridID, uuidOfHGrid);
d = (unsigned char *) &uuidOfHGrid;
fprintf(fp, "uuid = %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7],
d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
*/
if
(
gridInqReference
(
gridID
,
NULL
)
)
{
char
reference_link
[
8192
];
gridInqReference
(
gridID
,
reference_link
);
fprintf
(
fp
,
"path = %s
\n
"
,
reference_link
);
}
break
;
}
default:
{
fprintf
(
stderr
,
"Unsupported grid type: %s
\n
"
,
gridNamePtr
(
type
));
...
...
src/pio_util.c
View file @
37d3a775
...
...
@@ -292,7 +292,6 @@ cdiPioQueryVarDims(int varShape[3], int vlistID, int varID)
case
GRID_GME
:
case
GRID_CURVILINEAR
:
case
GRID_UNSTRUCTURED
:
case
GRID_REFERENCE
:
xabort
(
"unimplemented grid type: %d"
,
gridType
);
break
;
}
...
...
src/stream_cdf.c
View file @
37d3a775
...
...
@@ -5825,7 +5825,7 @@ void define_all_grids(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nva
if
(
number_of_grid_used
!=
UNDEFID
&&
(
grid
.
type
==
UNDEFID
||
grid
.
type
==
GRID_GENERIC
)
)
{
grid
.
type
=
GRID_
REFERENCE
;
grid
.
type
=
GRID_
UNSTRUCTURED
;
grid
.
number
=
number_of_grid_used
;
}
...
...
@@ -5945,8 +5945,7 @@ void define_all_grids(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nva
#endif
ncvars
[
ncvarid
].
gridID
=
varDefGrid
(
vlistID
,
grid
,
1
);
if
(
uuidOfHGrid
[
0
]
!=
0
&&
(
grid
.
type
==
GRID_UNSTRUCTURED
||
grid
.
type
==
GRID_REFERENCE
)
)
if
(
uuidOfHGrid
[
0
]
!=
0
&&
grid
.
type
==
GRID_UNSTRUCTURED
)
gridDefUUID
(
ncvars
[
ncvarid
].
gridID
,
uuidOfHGrid
);
if
(
ncvars
[
ncvarid
].
chunked
)
...
...
src/stream_gribapi.c
View file @
37d3a775
...
...
@@ -50,21 +50,21 @@ int gribapiGetGridType(grib_handle *gh)
switch
(
gribgridtype
)
{
case
GRIB2_GTYPE_LATLON
:
{
GRIB_CHECK
(
grib_get_long
(
gh
,
"Ni"
,
&
lpar
),
0
);
if
(
lpar
==
(
long
)
GRIB_MISSING_LONG
)
break
;
}
case
GRIB2_GTYPE_LATLON_ROT
:
{
gridtype
=
GRID_LONLAT
;
break
;
}
case
GRIB2_GTYPE_LCC
:
{
gridtype
=
GRID_LCC
;
break
;
}
case
GRIB2_GTYPE_GAUSSIAN
:
{
GRIB_CHECK
(
grib_get_long
(
gh
,
"Ni"
,
&
lpar
),
0
);
if
(
lpar
==
(
long
)
GRIB_MISSING_LONG
)
gridtype
=
GRID_GAUSSIAN_REDUCED
;
else
gridtype
=
GRID_GAUSSIAN
;
break
;
}
case
GRIB2_GTYPE_SPECTRAL
:
{
gridtype
=
GRID_SPECTRAL
;
break
;
}
case
GRIB2_GTYPE_GME
:
{
gridtype
=
GRID_GME
;
break
;
}
case
GRIB2_GTYPE_
NUMBER
:
{
gridtype
=
GRID_
REFERENCE
;
break
;
}
case
GRIB2_GTYPE_LATLON
:
{
GRIB_CHECK
(
grib_get_long
(
gh
,
"Ni"
,
&
lpar
),
0
);
if
(
lpar
==
(
long
)
GRIB_MISSING_LONG
)
break
;
}
case
GRIB2_GTYPE_LATLON_ROT
:
{
gridtype
=
GRID_LONLAT
;
break
;
}
case
GRIB2_GTYPE_LCC
:
{
gridtype
=
GRID_LCC
;
break
;
}
case
GRIB2_GTYPE_GAUSSIAN
:
{
GRIB_CHECK
(
grib_get_long
(
gh
,
"Ni"
,
&
lpar
),
0
);
if
(
lpar
==
(
long
)
GRIB_MISSING_LONG
)
gridtype
=
GRID_GAUSSIAN_REDUCED
;
else
gridtype
=
GRID_GAUSSIAN
;
break
;
}
case
GRIB2_GTYPE_SPECTRAL
:
{
gridtype
=
GRID_SPECTRAL
;
break
;
}
case
GRIB2_GTYPE_GME
:
{
gridtype
=
GRID_GME
;
break
;
}
case
GRIB2_GTYPE_
UNSTRUCTURED
:
{
gridtype
=
GRID_
UNSTRUCTURED
;
break
;
}
}
}
...
...
@@ -589,7 +589,7 @@ void gribapiGetGrid(grib_handle *gh, grid_t *grid)
break
;
}
case
GRID_
REFERENCE
:
case
GRID_
UNSTRUCTURED
:
{
char
uuid
[
17
];
char
reference_link
[
8192
];
...
...
@@ -601,11 +601,13 @@ void gribapiGetGrid(grib_handle *gh, grid_t *grid)
{
grid
->
number
=
lpar
;
if
(
grib_get_long
(
gh
,
"numberOfGridInReference"
,
&
lpar
)
==
0
)
grid
->
position
=
lpar
;
/*
if ( grib_get_string(gh, "gridDescriptionFile", reference_link, &len) == 0 )
{
if ( strncmp(reference_link, "file://", 7) == 0 )
grid->reference = strdupx(reference_link);
}
*/
len
=
(
size_t
)
16
;
if
(
grib_get_bytes
(
gh
,
"uuidOfHGrid"
,
(
unsigned
char
*
)
uuid
,
&
len
)
==
0
)
{
...
...
@@ -2207,7 +2209,6 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int ljpeg, i
{
int
gridtype
;
int
status
;
char
uuid
[
17
];
static
short
lwarn
=
TRUE
;
size_t
len
;
char
*
mesg
;
...
...
@@ -2215,7 +2216,7 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int ljpeg, i
gridtype
=
gridInqType
(
gridID
);
if
(
editionNumber
<=
1
)
if
(
gridtype
==
GRID_GME
||
gridtype
==
GRID_
REFERENCE
)
if
(
gridtype
==
GRID_GME
||
gridtype
==
GRID_
UNSTRUCTURED
)
gridtype
=
-
1
;
if
(
gridtype
==
GRID_GENERIC
)
...
...
@@ -2544,21 +2545,26 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int ljpeg, i
break
;
}
case
GRID_
REFERENCE
:
case
GRID_
UNSTRUCTURED
:
{
static
int
warning
=
1
;
status
=
grib_set_long
(
gh
,
"gridDefinitionTemplateNumber"
,
GRIB2_GTYPE_
NUMBER
);
status
=
grib_set_long
(
gh
,
"gridDefinitionTemplateNumber"
,
GRIB2_GTYPE_
UNSTRUCTURED
);
if
(
status
!=
0
&&
warning
)
{
warning
=
0
;
Warning
(
"Can't write reference grid!"
);
Warning
(
"gridDefinitionTemplateNumber %d not found (grib2/template.3.%d.def)!"
,
GRIB2_GTYPE_
NUMBER
,
GRIB2_GTYPE_
NUMBER
);
GRIB2_GTYPE_
UNSTRUCTURED
,
GRIB2_GTYPE_
UNSTRUCTURED
);
}
else
{
GRIB_CHECK
(
grib_set_long
(
gh
,
"numberOfGridUsed"
,
gridInqNumber
(
gridID
)),
0
);
GRIB_CHECK
(
grib_set_long
(
gh
,
"numberOfGridInReference"
,
gridInqPosition
(
gridID
)),
0
);
char
uuid
[
17
];
int
position
=
gridInqPosition
(
gridID
);
int
number
=
gridInqNumber
(
gridID
);
if
(
position
<
0
)
position
=
0
;
if
(
number
<
0
)
number
=
0
;
GRIB_CHECK
(
grib_set_long
(
gh
,
"numberOfGridUsed"
,
number
),
0
);
GRIB_CHECK
(
grib_set_long
(
gh
,
"numberOfGridInReference"
,
position
),
0
);
len
=
16
;
if
(
grib_set_bytes
(
gh
,
"uuidOfHGrid"
,
(
unsigned
char
*
)
gridInqUUID
(
gridID
,
uuid
),
&
len
)
!=
0
)
Warning
(
"Can't write UUID!"
);
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment