本文实例为大家分享了Android实现3D云标签效果的具体代码,供大家参考,具体内容如下
一、自定义View
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
public class TagCloudView extends RelativeLayout {
RelativeLayout navigation_bar;
TextView mTextView1;
private final float TOUCH_SCALE_FACTOR = .8f;
private float tspeed;
private TagCloud mTagCloud;
private float mAngleX = 0 ;
private float mAngleY = 0 ;
private float centerX, centerY;
private float radius;
private Context mContext;
private List<TextView> mTextView;
private List<RelativeLayout.LayoutParams> mParams;
private int shiftLeft;
float dowx = 0 ;
float dowy = 0 ;
float cutx= 100 ;
float cuty= 100 ;
public TagCloudView(Context mContext, int width, int height, List<Tag> tagList) {
this (mContext, width, height, tagList, 6 , 34 , 1 );
}
public TagCloudView(Context mContext, int width, int height, List<Tag> tagList,
int textSi*, int textSizeMax, int scrollSpeed) {
super (mContext);
this .mContext= mContext;
tspeed = scrollSpeed;
centerX = width / 2 ;
centerY = height / 2 ;
radius = Math.min(centerX * 0 .95f , centerY * 0 .95f );
shiftLeft = ( int )(Math.min(centerX * 0 .15f , centerY * 0 .15f ));
mTagCloud = new TagCloud(tagList, ( int ) radius , textSi*, textSizeMax);
float [] tempColor1 = { 0 .9412f, 0 .7686f, 0 .2f, 1 }; //rgb Alpha
//{1f,0f,0f,1} red {0.3882f,0.21568f,0.0f,1} orange
//{0.9412f,0.7686f,0.2f,1} light orange
float [] tempColor2 = {1f,0f,0f, 1 }; //rgb Alpha
//{0f,0f,1f,1} blue {0.1294f,0.1294f,0.1294f,1} grey
//{0.9412f,0.7686f,0.2f,1} light orange
mTagCloud.setTagColor1(tempColor1); //higher color
mTagCloud.setTagColor2(tempColor2); //lower color
mTagCloud.setRadius(( int ) radius);
mTagCloud.create( true );
mTagCloud.setAngleX(mAngleX);
mTagCloud.setAngleY(mAngleY);
mTagCloud.update();
mTextView = new ArrayList<TextView>();
mParams = new ArrayList<RelativeLayout.LayoutParams>();
Iterator<?> it=mTagCloud.iterator();
Tag tempTag;
int i= 0 ;
//取出每个数据放到TexView里
while (it.hasNext()){
tempTag= (Tag) it.next();
tempTag.setParamNo(i);
mTextView.add( new TextView( this .mContext));
mTextView.get(i).setText(tempTag.getText());
mParams.add( new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
mParams.get(i).addRule(RelativeLayout.ALIGN_PARENT_LEFT);
mParams.get(i).addRule(RelativeLayout.ALIGN_PARENT_TOP);
mParams.get(i).setMargins(( int ) (centerX -shiftLeft + tempTag.getLoc2DX()),( int ) (centerY + tempTag.getLoc2DY()), 0 , 0 );
mTextView.get(i).setLayoutParams(mParams.get(i));
mTextView.get(i).setSingleLine( true );
int mergedColor = Color.argb(( int )(tempTag.getAlpha() * 255 ), ( int ) (tempTag.getColorR() * 255 ), ( int ) (tempTag.getColorG() * 255 ),( int ) (tempTag.getColorB() * 255 ));
mTextView.get(i).setTextColor(mergedColor);
mTextView.get(i).setTextSize(( int )(tempTag.getTextSize() * tempTag.getScale()));
addView(mTextView.get(i));
mTextView.get(i).setOnClickListener(OnTagClickListener(tempTag.getUrl()));
//设置每个TexView有自己指定的标签为自己的位置,以便后期操作
mTextView.get(i).setTag(i);
i++;
}
/** 用来自动播放的*/
new Timer().schedule( new TimerTask() {
@Override
public void run() {
handler.sendEmptyMessage( 1 );
}
}, 0 , 200 );
}
@SuppressLint ( "HandlerLeak" )
Handler handler= new Handler(){
@Override
public void handleMessage(Message msg) {
super .handleMessage(msg);
mAngleX = (cuty/radius) *tspeed * TOUCH_SCALE_FACTOR;
mAngleY = (-cutx/radius) *tspeed * TOUCH_SCALE_FACTOR;
changPosition();
}
};
@Override
protected void onDraw(Canvas canvas){
super .onDraw(canvas);
}
/**
* 触发事件
*/
@Override
public boolean onTouchEvent(MotionEvent e) {
switch (e.getAction()) {
case MotionEvent.ACTION_DOWN:
dowx=e.getX();
dowy=e.getY();
break ;
case MotionEvent.ACTION_UP:
float upx=e.getX();
float upy=e.getY();
cutx=upx-dowx;
cuty=upy-dowy;
break ;
case MotionEvent.ACTION_MOVE:
mAngleX = (cuty/radius) *tspeed * TOUCH_SCALE_FACTOR;
mAngleY = (-cutx/radius) *tspeed * TOUCH_SCALE_FACTOR;
changPosition();
break ;
}
return true ;
}
/**
* 改变位置
*/
private void changPosition(){
mTagCloud.setAngleX(mAngleX);
mTagCloud.setAngleY(mAngleY);
mTagCloud.update();
Iterator<?> it=mTagCloud.iterator();
Tag tempTag;
while (it.hasNext()){
tempTag= (Tag) it.next();
mParams.get(tempTag.getParamNo()).setMargins(
( int ) (centerX -shiftLeft + tempTag.getLoc2DX()),
( int ) (centerY + tempTag.getLoc2DY()),
0 ,
0 );
mTextView.get(tempTag.getParamNo()).setTextSize(( int )(tempTag.getTextSize() * tempTag.getScale()));
int mergedColor = Color.argb( ( int ) (tempTag.getAlpha() * 255 ),
( int ) (tempTag.getColorR() * 255 ),
( int ) (tempTag.getColorG() * 255 ),
( int ) (tempTag.getColorB() * 255 ));
mTextView.get(tempTag.getParamNo()).setTextColor(mergedColor);
mTextView.get(tempTag.getParamNo()).bringToFront();
}
}
/**
* 点击事件
* @param url
* @return
*/
View.OnClickListener OnTagClickListener( final String url){
return new View.OnClickListener(){
@Override
public void onClick(View v) {
}
};
}
}
|
二、自定义迭代器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
|
/**
* 自定义的迭代器
* @author Administrator
*
*/
public class TagCloud implements Iterable<Object>{
private List<Tag> tagCloud;
private int radius;
private static final int DEFAULT_RADIUS = 3 ;
private static final int TEXT_SIZE_MAX = 30 , TEXT_SIZE_MIN= 4 ;
private static final float [] DEFAULT_COLOR1= { 0 .886f, 0 .725f, 0 .188f, 1f};
private static final float [] DEFAULT_COLOR2= { 0 .3f, 0 .3f, 0 .3f, 1f};
private float [] tagColor1;
private float [] tagColor2;
private int textSizeMax, textSi*;
private float sin_mAngleX,cos_mAngleX,sin_mAngleY,cos_mAngleY,sin_mAngleZ,cos_mAngleZ;
private float mAngleZ= 0 ;
private float mAngleX = 0 ;
private float mAngleY = 0 ;
private int size= 0 ;
private int smallest,largest;
private boolean distrEven = true ;
public TagCloud(){
this ( new ArrayList<Tag>());
}
public TagCloud(List<Tag> tags){
this (tags,DEFAULT_RADIUS);
}
public TagCloud(List<Tag> tags, int radius){
this ( tags, radius, DEFAULT_COLOR1, DEFAULT_COLOR2, TEXT_SIZE_MIN, TEXT_SIZE_MAX);
}
public TagCloud(List<Tag> tags, int radius, int textSi*, int textSizeMax){
this ( tags, radius, DEFAULT_COLOR1, DEFAULT_COLOR2, textSi*, textSizeMax);
}
public TagCloud(List<Tag> tags, int radius, float [] tagColor1, float [] tagColor2){
this ( tags, radius, tagColor1, tagColor2, TEXT_SIZE_MIN, TEXT_SIZE_MAX);
}
public TagCloud(List<Tag> tags, int radius, float [] tagColor1, float [] tagColor2,
int textSi*, int textSizeMax){
this .tagCloud=tags;
this .radius = radius;
this .tagColor1 = tagColor1;
this .tagColor2 = tagColor2;
this .textSizeMax = textSizeMax;
this .textSi* = textSi*;
}
/**
* 重写的方法
*/
@Override
public Iterator iterator() {
return tagCloud.iterator();
}
/**
* 创建
* @param distrEven
*/
public void create( boolean distrEven){
this .distrEven =distrEven;
positionAll(distrEven);
sineCosine( mAngleX, mAngleY, mAngleZ);
updateAll();
smallest = 9999 ;
largest = 0 ;
for ( int i= 0 ; i< tagCloud.size(); i++){
int j = tagCloud.get(i).getPopularity();
largest = Math.max(largest, j);
smallest = Math.min(smallest, j);
}
Tag tempTag;
for ( int i= 0 ; i< tagCloud.size(); i++){
tempTag = tagCloud.get(i);
int j = tempTag.getPopularity();
float percentage = ( smallest == largest ) ? 1 .0f : (( float )j-smallest) / (( float )largest-smallest);
float [] tempColor = getColorFromGradient( percentage ); //(rgb Alpha)
int tempTextSize = getTextSizeGradient( percentage );
tempTag.setColorR(tempColor[ 0 ]);
tempTag.setColorG(tempColor[ 1 ]);
tempTag.setColorB(tempColor[ 2 ]);
tempTag.setTextSize(tempTextSize);
}
this .size= tagCloud.size();
}
/**
* create创建完,就需要update
*/
public void update(){
if ( Math.abs(mAngleX) > . 1 || Math.abs(mAngleY) > . 1 ){
sineCosine( mAngleX, mAngleY, mAngleZ);
updateAll();
}
}
/**
* 计算每个Tag的
* @param distrEven 是否根据字计算位置 true为是,否则字有覆盖的
*/
private void positionAll( boolean distrEven){
double phi = 0 ;
double theta = 0 ;
int max = tagCloud.size();
for ( int i= 1 ; i<max+ 1 ; i++){
if (distrEven){
phi = Math.acos(- 1.0 + ( 2.0 *i - 1.0 )/max);
theta = Math.sqrt(max*Math.PI) * phi;
} else {
phi = Math.random()*(Math.PI);
theta = Math.random()*( 2 * Math.PI);
}
tagCloud.get(i- 1 ).setLocX(( int )( (radius * Math.cos(theta) * Math.sin(phi))));
tagCloud.get(i- 1 ).setLocY(( int )(radius * Math.sin(theta) * Math.sin(phi)));
tagCloud.get(i- 1 ).setLocZ(( int )(radius * Math.cos(phi)));
}
}
/**
* 更新所有的Tag位置
*/
private void updateAll(){
int max = tagCloud.size();
for ( int j= 0 ; j<max; j++){
float rx1 = (tagCloud.get(j).getLocX());
float ry1 = (tagCloud.get(j).getLocY()) * cos_mAngleX +
tagCloud.get(j).getLocZ() * -sin_mAngleX;
float rz1 = (tagCloud.get(j).getLocY()) * sin_mAngleX +
tagCloud.get(j).getLocZ() * cos_mAngleX;
float rx2 = rx1 * cos_mAngleY + rz1 * sin_mAngleY;
float ry2 = ry1;
float rz2 = rx1 * -sin_mAngleY + rz1 * cos_mAngleY;
float rx3 = rx2 * cos_mAngleZ + ry2 * -sin_mAngleZ;
float ry3 = rx2 * sin_mAngleZ + ry2 * cos_mAngleZ;
float rz3 = rz2;
tagCloud.get(j).setLocX(rx3);
tagCloud.get(j).setLocY(ry3);
tagCloud.get(j).setLocZ(rz3);
int diameter = 2 * radius;
float per = diameter / (diameter+rz3);
tagCloud.get(j).setLoc2DX(( int )(rx3 * per));
tagCloud.get(j).setLoc2DY(( int )(ry3 * per));
tagCloud.get(j).setScale(per);
tagCloud.get(j).setAlpha(per / 2 );
}
//给Tag排序
Collections.sort(tagCloud);
}
/**
* 计算字体颜色
* @param perc
* @return
*/
private float [] getColorFromGradient( float perc){
float [] tempRGB = new float [ 4 ];
tempRGB[ 0 ] = ( perc * ( tagColor1[ 0 ] ) ) + ( ( 1 -perc) * ( tagColor2[ 0 ] ) );
tempRGB[ 1 ] = ( perc * ( tagColor1[ 1 ] ) ) + ( ( 1 -perc) * ( tagColor2[ 1 ] ) );
tempRGB[ 2 ] = ( perc * ( tagColor1[ 2 ] ) ) + ( ( 1 -perc) * ( tagColor2[ 2 ] ) );
tempRGB[ 3 ] = 1 ;
return tempRGB;
}
/**
* 计算字体的大小
* @param perc
* @return
*/
private int getTextSizeGradient( float perc){
int size;
size = ( int )( perc*textSizeMax + ( 1 -perc)*textSi* );
return size;
}
/**
* 计算圆形的x y z坐标
* @param mAngleX
* @param mAngleY
* @param mAngleZ
*/
private void sineCosine( float mAngleX, float mAngleY, float mAngleZ) {
double degToRad = (Math.PI / 180 );
sin_mAngleX= ( float ) Math.sin( mAngleX * degToRad);
cos_mAngleX= ( float ) Math.cos( mAngleX * degToRad);
sin_mAngleY= ( float ) Math.sin( mAngleY * degToRad);
cos_mAngleY= ( float ) Math.cos( mAngleY * degToRad);
sin_mAngleZ= ( float ) Math.sin( mAngleZ * degToRad);
cos_mAngleZ= ( float ) Math.cos( mAngleZ * degToRad);
}
/**
* 以下是get set方法
* @return
*/
public int getRadius() {
return radius;
}
public void setRadius( int radius) {
this .radius = radius;
}
public float [] getTagColor1() {
return tagColor1;
}
public void setTagColor1( float [] tagColor) {
this .tagColor1 = tagColor;
}
public float [] getTagColor2() {
return tagColor2;
}
public void setTagColor2( float [] tagColor2) {
this .tagColor2 = tagColor2;
}
public float getRvalue( float [] color) {
if (color.length> 0 )
return color[ 0 ];
else
return 0 ;
}
public float getGvalue( float [] color) {
if (color.length> 0 )
return color[ 1 ];
else
return 0 ; }
public float getBvalue( float [] color) {
if (color.length> 0 )
return color[ 2 ];
else
return 0 ; }
public float getAlphaValue( float [] color) {
if (color.length >= 4 )
return color[ 3 ];
else
return 0 ;
}
public float getAngleX() {
return mAngleX;
}
public void setAngleX( float mAngleX) {
this .mAngleX = mAngleX;
}
public float getAngleY() {
return mAngleY;
}
public void setAngleY( float mAngleY) {
this .mAngleY = mAngleY;
}
public int getSize() {
return size;
}
}
|
三、自定义数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
/**
* Comparable接口 可以自定义排序方式
* @author Administrator
*
*/
public class Tag implements Comparable<Tag>{
private String text, url;
private int popularity;
private int textSize;
private float locX, locY, locZ;
private float loc2DX, loc2DY;
private float scale;
private float colorR, colorG, colorB, alpha;
private static final int DEFAULT_POPULARITY = 1 ;
private int paramNo;
public Tag(String text, int popularity) {
this (text, 0f, 0f, 0f, 1 .0f, popularity, "" );
}
public Tag(String text, int popularity, String url) {
this (text, 0f, 0f, 0f, 1 .0f, popularity, url);
}
public Tag(String text, float locX, float locY, float locZ) {
this (text, locX, locY, locZ, 1 .0f, DEFAULT_POPULARITY, "" );
}
public Tag(String text, float locX, float locY, float locZ, float scale) {
this (text, locX, locY, locZ, scale, DEFAULT_POPULARITY, "" );
}
public Tag(String text, float locX, float locY, float locZ, float scale, int popularity,
String url) {
this .text = text;
this .locX = locX;
this .locY = locY;
this .locZ = locZ;
this .loc2DX = 0 ;
this .loc2DY= 0 ;
this .colorR= 0 .5f;
this .colorG= 0 .5f;
this .colorB= 0 .5f;
this .alpha = 1 .0f;
this .scale = scale;
this .popularity= popularity;
this .url = url;
}
@Override
public int compareTo(Tag another) {
//排序方式
return ( int )(another.locZ - locZ);
}
public float getLocX() {
return locX;
}
public void setLocX( float locX) {
this .locX = locX;
}
public float getLocY() {
return locY;
}
public void setLocY( float locY) {
this .locY = locY;
}
public float getLocZ() {
return locZ;
}
public void setLocZ( float locZ) {
this .locZ = locZ;
}
public float getScale() {
return scale;
}
public void setScale( float scale) {
this .scale = scale;
}
public String getText() {
return text;
}
public void setText(String text) {
this .text = text;
}
public float getColorR() {
return colorR;
}
public void setColorR( float colorR) {
this .colorR = colorR;
}
public float getColorG() {
return colorG;
}
public void setColorG( float colorG) {
this .colorG = colorG;
}
public float getColorB() {
return colorB;
}
public void setColorB( float colorB) {
this .colorB = colorB;
}
public float getAlpha() {
return alpha;
}
public void setAlpha( float alpha) {
this .alpha = alpha;
}
public int getPopularity() {
return popularity;
}
public void setPopularity( int popularity) {
this .popularity = popularity;
}
public int getTextSize() {
return textSize;
}
public void setTextSize( int textSize) {
this .textSize = textSize;
}
public float getLoc2DX() {
return loc2DX;
}
public void setLoc2DX( float loc2dx) {
loc2DX = loc2dx;
}
public float getLoc2DY() {
return loc2DY;
}
public void setLoc2DY( float loc2dy) {
loc2DY = loc2dy;
}
public int getParamNo() {
return paramNo;
}
public void setParamNo( int paramNo) {
this .paramNo = paramNo;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this .url = url;
}
}
|
四、调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
private TagCloudView mTagCloudView;
public void onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
this .requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
Display display = getWindowManager().getDefaultDisplay();
@SuppressWarnings ( "deprecation" )
int width = display.getWidth();
@SuppressWarnings ( "deprecation" )
int height = display.getHeight();
List<Tag> myTagList= createTags();
mTagCloudView = new TagCloudView( this , width, height, myTagList );
setContentView(mTagCloudView);
mTagCloudView.requestFocus();
mTagCloudView.setFocusableInTouchMode( true );
}
private List<Tag> createTags(){
List<Tag> tempList = new ArrayList<Tag>();
tempList.add( new Tag( "Google" , 7 , "http://www.google.com" ));
tempList.add( new Tag( "Yahoo" , 3 , "www.yahoo.com" ));
tempList.add( new Tag( "CNN" , 4 , "www.cnn.com" ));
tempList.add( new Tag( "MSNBC" , 5 , "www.msnbc.com" ));
tempList.add( new Tag( "CNBC" , 5 , "www.CNBC.com" ));
tempList.add( new Tag( "Facebook" , 7 , "www.facebook.com" ));
tempList.add( new Tag( "Youtube" , 3 , "www.youtube.com" ));
tempList.add( new Tag( "BlogSpot" , 5 , "www.blogspot.com" ));
tempList.add( new Tag( "Bing" , 3 , "www.bing.com" ));
tempList.add( new Tag( "Wikipedia" , 8 , "www.wikipedia.com" ));
tempList.add( new Tag( "Twitter" , 5 , "www.twitter.com" ));
tempList.add( new Tag( "Msn" , 1 , "www.msn.com" ));
tempList.add( new Tag( "Amazon" , 3 , "www.amazon.com" ));
tempList.add( new Tag( "Ebay" , 7 , "www.ebay.com" ));
tempList.add( new Tag( "LinkedIn" , 5 , "www.linkedin.com" ));
tempList.add( new Tag( "Live" , 7 , "www.live.com" ));
tempList.add( new Tag( "Microsoft" , 3 , "www.microsoft.com" ));
tempList.add( new Tag( "Flicker" , 1 , "www.flicker.com" ));
tempList.add( new Tag( "Apple" , 5 , "www.apple.com" ));
tempList.add( new Tag( "Paypal" , 5 , "www.paypal.com" ));
tempList.add( new Tag( "Craigslist" , 7 , "www.craigslist.com" ));
tempList.add( new Tag( "Imdb" , 2 , "www.imdb.com" ));
tempList.add( new Tag( "Ask" , 4 , "www.ask.com" ));
tempList.add( new Tag( "Weibo" , 1 , "www.weibo.com" ));
tempList.add( new Tag( "Tagin!" , 8 , "http://scyp.idrc.ocad.ca/projects/tagin" ));
tempList.add( new Tag( "Shiftehfar" , 8 , "www.shiftehfar.org" ));
tempList.add( new Tag( "Soso" , 5 , "www.google.com" ));
tempList.add( new Tag( "XVideos" , 3 , "www.xvideos.com" ));
tempList.add( new Tag( "BBC" , 5 , "www.bbc.co.uk" ));
return tempList;
}
|
源码下载地址点击打开链接
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/mingyue_1128/article/details/38583009