wolfhece 2.1.120__py3-none-any.whl → 2.1.122__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -26,6 +26,7 @@ from enum import Enum
26
26
  import logging
27
27
  import wx
28
28
  from typing import Union, Literal
29
+ from pathlib import Path
29
30
 
30
31
  from .PyTranslate import _
31
32
  from .drawing_obj import Element_To_Draw
@@ -1722,7 +1723,7 @@ class crosssections(Element_To_Draw):
1722
1723
  mygenprofiles:dict
1723
1724
 
1724
1725
  def __init__(self,
1725
- myfile,
1726
+ myfile:str = '',
1726
1727
  format:typing.Literal['2000','2022','vecz','sxy']='2022',
1727
1728
  dirlaz:typing.Union[str, xyz_laz_grids] =r'D:\OneDrive\OneDrive - Universite de Liege\Crues\2021-07 Vesdre\CSC - Convention - ARNE\Data\LAZ_Vesdre\2023',
1728
1729
  mapviewer = None,
@@ -1754,9 +1755,12 @@ class crosssections(Element_To_Draw):
1754
1755
 
1755
1756
  if format in ['2000','2022','sxy']:
1756
1757
  self.filename=myfile
1757
- f=open(myfile,'r')
1758
- lines=f.read().splitlines()
1759
- f.close()
1758
+ if Path(myfile).exists() and myfile!='':
1759
+ f=open(myfile,'r')
1760
+ lines=f.read().splitlines()
1761
+ f.close()
1762
+ else:
1763
+ lines=[]
1760
1764
 
1761
1765
  self.myprofiles={}
1762
1766
  self.mygenprofiles={}
@@ -1768,214 +1772,215 @@ class crosssections(Element_To_Draw):
1768
1772
  self.sorted = {}
1769
1773
  self.plotted = False
1770
1774
 
1771
- if format=='2000':
1772
- self.format='2000'
1773
- lines.pop(0)
1774
- nameprev=''
1775
- index=0
1776
- for curline in lines:
1777
- vals=curline.split('\t')
1778
- name=vals[0]
1779
-
1780
- if name!=nameprev:
1781
- #création d'un nouveau dictionnaire
1782
- self.myprofiles[name]={}
1783
- curdict=self.myprofiles[name]
1775
+ if len(lines)>0:
1776
+ if format=='2000':
1777
+ self.format='2000'
1778
+ lines.pop(0)
1779
+ nameprev=''
1780
+ index=0
1781
+ for curline in lines:
1782
+ vals=curline.split('\t')
1783
+ name=vals[0]
1784
+
1785
+ if name!=nameprev:
1786
+ #création d'un nouveau dictionnaire
1787
+ self.myprofiles[name]={}
1788
+ curdict=self.myprofiles[name]
1789
+ curdict['index']=index
1790
+ index+=1
1791
+ curdict['cs']=profile(name=name,parent=self)
1792
+ cursect:profile
1793
+ cursect=curdict['cs']
1794
+
1795
+ x=float(vals[1])
1796
+ y=float(vals[2])
1797
+ type=vals[3]
1798
+ z=float(vals[4])
1799
+
1800
+ curvertex=wolfvertex(x,y,z)
1801
+ cursect.add_vertex(curvertex)
1802
+ if type=='LEFT':
1803
+ if cursect.bankleft is None:
1804
+ cursect.bankleft=wolfvertex(x,y,z)
1805
+ curdict['left']=cursect.bankleft
1806
+ else:
1807
+ logging.debug(name)
1808
+ elif type=='BED':
1809
+ if cursect.bed is None:
1810
+ cursect.bed=wolfvertex(x,y,z)
1811
+ curdict['bed']=cursect.bed
1812
+ else:
1813
+ logging.debug(name)
1814
+ elif type=='RIGHT':
1815
+ if cursect.bankright is None:
1816
+ cursect.bankright=wolfvertex(x,y,z)
1817
+ curdict['right']=cursect.bankright
1818
+ else:
1819
+ logging.debug(name)
1820
+
1821
+ nameprev=name
1822
+ elif format=='2022':
1823
+ self.format='2022'
1824
+ lines.pop(0)
1825
+ nameprev=''
1826
+ index=0
1827
+ for curline in lines:
1828
+ vals=curline.split('\t')
1829
+
1830
+ if vals[0].find('.')>0:
1831
+ name=vals[0].split('.')[0]
1832
+ xpos=1
1833
+ ypos=xpos+1
1834
+ zpos=ypos+1
1835
+ labelpos=zpos+1
1836
+ else:
1837
+ name=vals[0]
1838
+ xpos=2
1839
+ ypos=xpos+1
1840
+ zpos=ypos+1
1841
+ labelpos=zpos+1
1842
+
1843
+ if name!=nameprev:
1844
+ #création d'un nouveau dictionnaire
1845
+ self.myprofiles[name]={}
1846
+ curdict=self.myprofiles[name]
1847
+ curdict['index']=index
1848
+ index+=1
1849
+ curdict['cs']=profile(name=name,parent=self)
1850
+ cursect:profile
1851
+ cursect=curdict['cs']
1852
+
1853
+ x=float(vals[xpos].replace(',','.'))
1854
+ y=float(vals[ypos].replace(',','.'))
1855
+ z=float(vals[zpos].replace(',','.'))
1856
+
1857
+ curvertex=wolfvertex(x,y,z)
1858
+ cursect.add_vertex(curvertex)
1859
+
1860
+ type=''
1861
+ type=vals[labelpos]
1862
+
1863
+ if type=='HBG':
1864
+ if cursect.bankleft is None:
1865
+ cursect.bankleft=wolfvertex(x,y,z)
1866
+ curdict['left']=cursect.bankleft
1867
+ else:
1868
+ logging.debug(name)
1869
+ elif type=='TWG':
1870
+ if cursect.bed is None:
1871
+ cursect.bed=wolfvertex(x,y,z)
1872
+ curdict['bed']=cursect.bed
1873
+ else:
1874
+ logging.debug(name)
1875
+ elif type=='HBD':
1876
+ if cursect.bankright is None:
1877
+ cursect.bankright=wolfvertex(x,y,z)
1878
+ curdict['right']=cursect.bankright
1879
+ else:
1880
+ logging.debug(name)
1881
+
1882
+ nameprev=name
1883
+ elif format=='vecz' or format=='zones':
1884
+
1885
+ if isinstance(myfile, Zones):
1886
+ self.filename=myfile.filename
1887
+ tmpzones=myfile
1888
+ elif isinstance(myfile, str):
1889
+ self.filename=myfile
1890
+ tmpzones=Zones(myfile, find_minmax=False)
1891
+
1892
+ curzone:zone
1893
+ curvec:vector
1894
+ curzone=tmpzones.myzones[0]
1895
+ index=0
1896
+ for curvec in curzone.myvectors:
1897
+
1898
+ self.myprofiles[curvec.myname]={}
1899
+ curdict=self.myprofiles[curvec.myname]
1900
+
1784
1901
  curdict['index']=index
1902
+ curdict['left']=None
1903
+ curdict['bed']=None
1904
+ curdict['right']=None
1905
+
1785
1906
  index+=1
1786
- curdict['cs']=profile(name=name,parent=self)
1907
+ curdict['cs']=profile(name=curvec.myname,parent=self)
1787
1908
  cursect:profile
1788
1909
  cursect=curdict['cs']
1789
1910
 
1790
- x=float(vals[1])
1791
- y=float(vals[2])
1792
- type=vals[3]
1793
- z=float(vals[4])
1911
+ cursect.myvertices = curvec.myvertices
1794
1912
 
1795
- curvertex=wolfvertex(x,y,z)
1796
- cursect.add_vertex(curvertex)
1797
- if type=='LEFT':
1798
- if cursect.bankleft is None:
1799
- cursect.bankleft=wolfvertex(x,y,z)
1800
- curdict['left']=cursect.bankleft
1801
- else:
1802
- print(name)
1803
- elif type=='BED':
1804
- if cursect.bed is None:
1805
- cursect.bed=wolfvertex(x,y,z)
1806
- curdict['bed']=cursect.bed
1807
- else:
1808
- print(name)
1809
- elif type=='RIGHT':
1810
- if cursect.bankright is None:
1811
- cursect.bankright=wolfvertex(x,y,z)
1812
- curdict['right']=cursect.bankright
1813
- else:
1814
- print(name)
1815
-
1816
- nameprev=name
1817
- elif format=='2022':
1818
- self.format='2022'
1819
- lines.pop(0)
1820
- nameprev=''
1821
- index=0
1822
- for curline in lines:
1823
- vals=curline.split('\t')
1824
-
1825
- if vals[0].find('.')>0:
1826
- name=vals[0].split('.')[0]
1827
- xpos=1
1828
- ypos=xpos+1
1829
- zpos=ypos+1
1830
- labelpos=zpos+1
1831
- else:
1832
- name=vals[0]
1833
- xpos=2
1834
- ypos=xpos+1
1835
- zpos=ypos+1
1836
- labelpos=zpos+1
1837
-
1838
- if name!=nameprev:
1839
- #création d'un nouveau dictionnaire
1840
- self.myprofiles[name]={}
1841
- curdict=self.myprofiles[name]
1842
- curdict['index']=index
1913
+ elif format=='sxy':
1914
+ self.format='sxy'
1915
+ nbpotsect = int(lines[0])
1916
+ index=1
1917
+ for i in range(nbpotsect):
1918
+ vals=lines[index].split(',')
1919
+ nbrel=int(vals[0])
1843
1920
  index+=1
1921
+ sz = np.asarray([np.float64(cursz) for k in range(index,index+nbrel) for cursz in lines[k].split(',') ]).reshape([nbrel,2],order='C')
1922
+ self.mygenprofiles[i+1]=sz
1923
+ index+=nbrel
1924
+
1925
+ nbsect = int(lines[index])
1926
+ # o linked position in a 2D array (i, j) (integer,integer) (optional)
1927
+ # o datum (float) – added to the Z_min of the raw cross section (optional)
1928
+ # o boolean value indicating whether the relative datum must be added (logical)
1929
+ # o boolean value indicating whether it is a real or synthetic section (logical)
1930
+ # o ID of the cross section to which this line relates (integer)
1931
+ # o pair of coordinates of the left end point (float, float)
1932
+ # o pair of coordinates of the right end point (float, float)
1933
+ # o pair of coordinates of the minor bed (float, float) (optional)
1934
+ # o pair of coordinates of the left bank in local reference (float, float) (optional)
1935
+ # o pair of coordinates of the right bank in local reference (float, float) (optional)
1936
+ # o boolean value indicating whether an attachment point has been defined (optional)
1937
+ # # 2,2,0,#FALSE#,#TRUE#,16,222075.5,110588.5,222331.5,110777.5,99999,99999,99999,99999,99999,99999,#FALSE#
1938
+ # 2,2,0,#FALSE#,#TRUE#,17,222131.6,110608.2,222364.4,110667.9,99999,99999,99999,99999,99999,99999,#FALSE#
1939
+ index+=1
1940
+ #création d'un nouveau dictionnaire
1941
+ for i in range(nbsect):
1942
+ name=str(i+1)
1943
+ vals=lines[index].split(',')
1944
+ index+=1
1945
+
1946
+ posi = int(vals[0])
1947
+ posj = int(vals[1])
1948
+ zdatum = float(vals[2])
1949
+ add_zdatum=vals[3]=='#TRUE#'
1950
+ real_sect=vals[4]=='#TRUE#'
1951
+ id = int(vals[5])
1952
+ startx=float(vals[6])
1953
+ starty=float(vals[7])
1954
+ endx=float(vals[8])
1955
+ endy=float(vals[9])
1956
+ beds=float(vals[10])
1957
+ bedz=float(vals[11])
1958
+ lbs=float(vals[12])
1959
+ lbz=float(vals[13])
1960
+ rbs=float(vals[14])
1961
+ rbz=float(vals[15])
1962
+ attached=vals[16]=='#TRUE#'
1963
+
1964
+ curdict=self.myprofiles[name]={}
1965
+ curdict['index']=id
1844
1966
  curdict['cs']=profile(name=name,parent=self)
1845
1967
  cursect:profile
1846
1968
  cursect=curdict['cs']
1847
1969
 
1848
- x=float(vals[xpos].replace(',','.'))
1849
- y=float(vals[ypos].replace(',','.'))
1850
- z=float(vals[zpos].replace(',','.'))
1970
+ cursect.zdatum = zdatum
1971
+ cursect.add_zdatum = add_zdatum
1851
1972
 
1852
- curvertex=wolfvertex(x,y,z)
1853
- cursect.add_vertex(curvertex)
1973
+ cursect.set_sz(self.mygenprofiles[id],[[startx,starty],[endx,endy]])
1854
1974
 
1855
- type=''
1856
- type=vals[labelpos]
1857
-
1858
- if type=='HBG':
1859
- if cursect.bankleft is None:
1860
- cursect.bankleft=wolfvertex(x,y,z)
1975
+ if lbs!=99999:
1976
+ cursect.bankleft=wolfvertex(lbs,lbz)
1861
1977
  curdict['left']=cursect.bankleft
1862
- else:
1863
- print(name)
1864
- elif type=='TWG':
1865
- if cursect.bed is None:
1866
- cursect.bed=wolfvertex(x,y,z)
1978
+ if beds!=99999:
1979
+ cursect.bed=wolfvertex(beds,bedz)
1867
1980
  curdict['bed']=cursect.bed
1868
- else:
1869
- print(name)
1870
- elif type=='HBD':
1871
- if cursect.bankright is None:
1872
- cursect.bankright=wolfvertex(x,y,z)
1981
+ if rbs!=99999:
1982
+ cursect.bankright=wolfvertex(rbs,rbz)
1873
1983
  curdict['right']=cursect.bankright
1874
- else:
1875
- print(name)
1876
-
1877
- nameprev=name
1878
- elif format=='vecz' or format=='zones':
1879
-
1880
- if isinstance(myfile, Zones):
1881
- self.filename=myfile.filename
1882
- tmpzones=myfile
1883
- elif isinstance(myfile, str):
1884
- self.filename=myfile
1885
- tmpzones=Zones(myfile, find_minmax=False)
1886
-
1887
- curzone:zone
1888
- curvec:vector
1889
- curzone=tmpzones.myzones[0]
1890
- index=0
1891
- for curvec in curzone.myvectors:
1892
-
1893
- self.myprofiles[curvec.myname]={}
1894
- curdict=self.myprofiles[curvec.myname]
1895
-
1896
- curdict['index']=index
1897
- curdict['left']=None
1898
- curdict['bed']=None
1899
- curdict['right']=None
1900
-
1901
- index+=1
1902
- curdict['cs']=profile(name=curvec.myname,parent=self)
1903
- cursect:profile
1904
- cursect=curdict['cs']
1905
-
1906
- cursect.myvertices = curvec.myvertices
1907
-
1908
- elif format=='sxy':
1909
- self.format='sxy'
1910
- nbpotsect = int(lines[0])
1911
- index=1
1912
- for i in range(nbpotsect):
1913
- vals=lines[index].split(',')
1914
- nbrel=int(vals[0])
1915
- index+=1
1916
- sz = np.asarray([np.float64(cursz) for k in range(index,index+nbrel) for cursz in lines[k].split(',') ]).reshape([nbrel,2],order='C')
1917
- self.mygenprofiles[i+1]=sz
1918
- index+=nbrel
1919
-
1920
- nbsect = int(lines[index])
1921
- # o linked position in a 2D array (i, j) (integer,integer) (optional)
1922
- # o datum (float) – added to the Z_min of the raw cross section (optional)
1923
- # o boolean value indicating whether the relative datum must be added (logical)
1924
- # o boolean value indicating whether it is a real or synthetic section (logical)
1925
- # o ID of the cross section to which this line relates (integer)
1926
- # o pair of coordinates of the left end point (float, float)
1927
- # o pair of coordinates of the right end point (float, float)
1928
- # o pair of coordinates of the minor bed (float, float) (optional)
1929
- # o pair of coordinates of the left bank in local reference (float, float) (optional)
1930
- # o pair of coordinates of the right bank in local reference (float, float) (optional)
1931
- # o boolean value indicating whether an attachment point has been defined (optional)
1932
- # # 2,2,0,#FALSE#,#TRUE#,16,222075.5,110588.5,222331.5,110777.5,99999,99999,99999,99999,99999,99999,#FALSE#
1933
- # 2,2,0,#FALSE#,#TRUE#,17,222131.6,110608.2,222364.4,110667.9,99999,99999,99999,99999,99999,99999,#FALSE#
1934
- index+=1
1935
- #création d'un nouveau dictionnaire
1936
- for i in range(nbsect):
1937
- name=str(i+1)
1938
- vals=lines[index].split(',')
1939
- index+=1
1940
-
1941
- posi = int(vals[0])
1942
- posj = int(vals[1])
1943
- zdatum = float(vals[2])
1944
- add_zdatum=vals[3]=='#TRUE#'
1945
- real_sect=vals[4]=='#TRUE#'
1946
- id = int(vals[5])
1947
- startx=float(vals[6])
1948
- starty=float(vals[7])
1949
- endx=float(vals[8])
1950
- endy=float(vals[9])
1951
- beds=float(vals[10])
1952
- bedz=float(vals[11])
1953
- lbs=float(vals[12])
1954
- lbz=float(vals[13])
1955
- rbs=float(vals[14])
1956
- rbz=float(vals[15])
1957
- attached=vals[16]=='#TRUE#'
1958
-
1959
- curdict=self.myprofiles[name]={}
1960
- curdict['index']=id
1961
- curdict['cs']=profile(name=name,parent=self)
1962
- cursect:profile
1963
- cursect=curdict['cs']
1964
-
1965
- cursect.zdatum = zdatum
1966
- cursect.add_zdatum = add_zdatum
1967
-
1968
- cursect.set_sz(self.mygenprofiles[id],[[startx,starty],[endx,endy]])
1969
-
1970
- if lbs!=99999:
1971
- cursect.bankleft=wolfvertex(lbs,lbz)
1972
- curdict['left']=cursect.bankleft
1973
- if beds!=99999:
1974
- cursect.bed=wolfvertex(beds,bedz)
1975
- curdict['bed']=cursect.bed
1976
- if rbs!=99999:
1977
- cursect.bankright=wolfvertex(rbs,rbz)
1978
- curdict['right']=cursect.bankright
1979
1984
 
1980
1985
  self.verif_bed()
1981
1986
  self.find_minmax(True)
@@ -1992,7 +1997,7 @@ class crosssections(Element_To_Draw):
1992
1997
  self.cloud_all.myprop.filled=True
1993
1998
  self.cloud_all.myprop.width=4
1994
1999
 
1995
- def add(self, newprofile):
2000
+ def add(self, newprofile:profile | vector):
1996
2001
 
1997
2002
  if isinstance(newprofile, profile):
1998
2003
  curvec = newprofile
@@ -2381,7 +2386,7 @@ class crosssections(Element_To_Draw):
2381
2386
  self.filename = filename
2382
2387
 
2383
2388
  if self.filename is None:
2384
- print(_('No Filename -- Retry !'))
2389
+ logging.error(_('No Filename -- Retry !'))
2385
2390
  return
2386
2391
 
2387
2392
  if self.filename.endswith('.vecz'):
@@ -2494,14 +2499,22 @@ class crosssections(Element_To_Draw):
2494
2499
  return len(mysorted)
2495
2500
 
2496
2501
  def find_minmax(self, update:bool=False):
2502
+
2503
+ if len(self.myprofiles)==0:
2504
+ self.xmin = 0
2505
+ self.ymin = 0
2506
+ self.xmax = 0
2507
+ self.ymax = 0
2508
+ return
2509
+
2497
2510
  if update:
2498
2511
  for idx,vect in self.myprofiles.items():
2499
2512
  vect['cs'].find_minmax(only_firstlast = True)
2500
2513
 
2501
- self.xmin=min(vect['cs'].xmin for idx,vect in self.myprofiles.items())
2502
- self.ymin=min(vect['cs'].ymin for idx,vect in self.myprofiles.items())
2503
- self.xmax=max(vect['cs'].xmax for idx,vect in self.myprofiles.items())
2504
- self.ymax=max(vect['cs'].ymax for idx,vect in self.myprofiles.items())
2514
+ self.xmin = min(vect['cs'].xmin for idx,vect in self.myprofiles.items())
2515
+ self.ymin = min(vect['cs'].ymin for idx,vect in self.myprofiles.items())
2516
+ self.xmax = max(vect['cs'].xmax for idx,vect in self.myprofiles.items())
2517
+ self.ymax = max(vect['cs'].ymax for idx,vect in self.myprofiles.items())
2505
2518
 
2506
2519
  def plot(self, sx=None, sy=None, xmin=None, ymin=None, xmax=None, ymax=None, size=None):
2507
2520
  """ Plotting cross-sections """
@@ -2548,7 +2561,8 @@ class Interpolator():
2548
2561
 
2549
2562
  """
2550
2563
 
2551
- def __init__(self,vec1:vector,vec2:vector,supports:list,ds=1.) -> None:
2564
+ def __init__(self, vec1:vector, vec2:vector,
2565
+ supports:list[vector], ds=1.) -> None:
2552
2566
 
2553
2567
  self.interpolants=[]
2554
2568
 
@@ -2637,11 +2651,13 @@ class Interpolator():
2637
2651
  i1=myls.intersection(s1)
2638
2652
  if i1.geom_type=='MultiPoint':
2639
2653
  i1=i1.geoms[0]
2654
+ logging.debug('MultiPoint -- use first point or debug')
2640
2655
 
2641
2656
  #section aval
2642
2657
  i2=myls.intersection(s2)
2643
2658
  if i2.geom_type=='MultiPoint':
2644
2659
  i2=i2.geoms[0]
2660
+ logging.debug('MultiPoint -- use first point or debug')
2645
2661
 
2646
2662
  #Les distances, sur les sections, sont calculées en projetant l'intersection du vecteur support et des sections
2647
2663
  sect1[k]=s1.project(i1)
@@ -2731,7 +2747,7 @@ class Interpolator():
2731
2747
  # a=1
2732
2748
 
2733
2749
  for curalong in range(nbi+1):
2734
- print(str(curalong))
2750
+ logging.debug(str(curalong))
2735
2751
 
2736
2752
  #interpolation 3D sur les 2 supports
2737
2753
  l1 = cursupl.interpolate(sloc,True,True)
@@ -3039,6 +3055,7 @@ class Interpolators():
3039
3055
  """
3040
3056
 
3041
3057
  self.mybanks = [curv for curzone in banks.myzones for curv in curzone.myvectors]
3058
+
3042
3059
  cs.set_zones()
3043
3060
  self.mycs = cs.myzones
3044
3061
 
@@ -3048,26 +3065,36 @@ class Interpolators():
3048
3065
  zonecs = self.mycs.myzones[0]
3049
3066
 
3050
3067
  if zonecs.myvectors[0].up is not None:
3051
-
3068
+ # Les sections ont été triées sur base d'un vecteur support
3069
+ # On les traite dans l'ordre du tri
3052
3070
  cs1:profile
3053
3071
  cs1=cs.get_upstream()['cs']
3054
3072
 
3055
3073
  while cs1.down is not cs1:
3056
3074
  cs2=cs1.down
3057
3075
 
3058
- print('{} - {}'.format(cs1.myname,cs2.myname))
3076
+ logging.info('{} - {}'.format(cs1.myname,cs2.myname))
3059
3077
 
3060
3078
  myinterp=Interpolator(cs1,cs2,self.mybanks,ds)
3061
- self.myinterp.append(myinterp)
3079
+
3080
+ if len(myinterp.interpolants)>0:
3081
+ self.myinterp.append(myinterp)
3082
+ else:
3083
+ logging.error('No interpolation found between {} and {}'.format(cs1.myname,cs2.myname))
3084
+
3062
3085
  cs1=cs2
3063
3086
  else:
3087
+ # Les sections n'ont pas été triées --> on les traite dans l'ordre
3064
3088
  for i in range(zonecs.nbvectors-1):
3065
3089
  cs1=zonecs.myvectors[i]
3066
3090
  cs2=zonecs.myvectors[i+1]
3067
3091
 
3068
- print('{} - {}'.format(cs1.myname,cs2.myname))
3092
+ logging.info('{} - {}'.format(cs1.myname,cs2.myname))
3069
3093
  myinterp=Interpolator(cs1,cs2,self.mybanks,ds)
3070
- self.myinterp.append(myinterp)
3094
+ if len(myinterp.interpolants)>0:
3095
+ self.myinterp.append(myinterp)
3096
+ else:
3097
+ logging.error('No interpolation found between {} and {}'.format(cs1.myname,cs2.myname))
3071
3098
 
3072
3099
  self.add_interpolators(cs.myzones.parent)
3073
3100