Thursday, November 30, 2006

【投稿】睡姿

两名游客在惠州的一个公园内午睡

点击在新窗口中浏览此图片


拍摄者 / 朱细聪

Tuesday, November 28, 2006

【置顶】博客杂志第二期出街

抓拍城市第二期博客杂志发行,点击下载。第二期比第一期从内容上丰富了很多,共有63个页码,比第一期差不多增加了三倍,文件量大概是6M,没有明显的增加。

抓拍城市在2005年一共存在了10个月,我会慢慢地把这十个月的内容全都做成flash杂志,把过去落下的功课补上。

本期主要内容:

1,一个城市和它的对日情绪,用文字&图片详细记录了去年4月份发生在深圳的反日大游行,包括一些打砸抢场面。

2,柬埔寨的地雷之痛,这是去年春节去柬埔寨,在暹粒街头发现了大量被地雷炸伤的人,回来就做了这个专题。

3,黄酒世家的往昔与梦想,讲述浙江绍兴农村酿酒的故事。

……还有许多内容,请

下载文件 (已下载 41 次)


Saturday, November 25, 2006

【美女】深圳欲制造环姐

点击在新窗口中浏览此图片
5号选手马端

环球国际小姐深圳赛区晋级选手出炉。她们将参加8月8日-20日在上海杭州举行的环姐中国赛区总决赛,如果再次晋级的话,将参于在阿尔巴尼亚的全球角逐。中国是首次参加环姐比赛,展示的图片不是现场图片,是抓拍城市的资料图片,分别为获得深圳赛区亚军的冯路畅和季军的马端。

点击在新窗口中浏览此图片
12号选手冯路畅


Friday, November 24, 2006

Thursday, November 16, 2006

“MySQLicious” solution

In this solution, the schema has got just one table, it is denormalized.
This type is called “MySQLicious solution” because MySQLicious imports del.icio.us data into a table with this structure.
Intersection (AND)

Query for “search+webservice+semweb”:
SELECT *
FROM `delicious`
WHERE tags LIKE "%search%"
AND tags LIKE "%webservice%"
AND tags LIKE "%semweb%"
Union (OR)

Query for “search|webservice|semweb”:

SELECT *
FROM `delicious`
WHERE tags LIKE "%search%"
OR tags LIKE "%webservice%"
OR tags LIKE "%semweb%"
Minus

Query for “search+webservice-semweb”
SELECT *
FROM `delicious`
WHERE tags LIKE "%search%"
AND tags LIKE "%webservice%"
AND tags NOT LIKE "%semweb%"
Conclusion

The advantages of this solution:

* just one table
* the queries are very straightforward
* one can also achieve results via fulltextsearch. That might be a little faster.
* I guess the queries are pretty fast (also referring to a blog entry of Peter Cooper: section “Denormalize! Denormalize! Denormalize!”) quite slow according to good arguments. Fulltext search would speed up a bit. I did some performance tests to prove that.
* In my follow up post I dealt with MySQL fulltext concerning tagging.

Disadvantages:

* You have a limit on the number of tags per bookmark. Normally you use a 256byte field in your DB (VARCHAR). Otherwise, if you took a text field or similar, the query times would slow down, I suppose
* If you paid attention (as Patrice did) you notice that LIKE "%search" will also find tags with “websearch”. If you alter the query to LIKE " %search% " you end up having a messy solution: You have to add a space to the beginning of the tags value to make this work.

“Scuttle” solution

Scuttle organizes its data in two tables. That table “scCategories” is the “tag”-table and has got a foreign key to the “bookmark”-table. database structure of scuttle
Intersection (AND)

Query for “bookmark+webservice+semweb”:
SELECT b.*
FROM scBookmarks b, scCategories c
WHERE c.bId = b.bId
AND (c.category IN ('bookmark', 'webservice', 'semweb'))
GROUP BY b.bId
HAVING COUNT( b.bId )=3

First, all bookmark-tag combinations are searched, where the tag is “bookmark”, “webservice” or “semweb” (c.category IN ('bookmark', 'webservice', 'semweb')), then just the bookmarks that have got all three tags searched for are taken into account (HAVING COUNT(b.bId)=3).
Union (OR)

Query for “bookmark|webservice|semweb”:
Just leave out the HAVING clause and you have union:
SELECT b.*
FROM scBookmarks b, scCategories c
WHERE c.bId = b.bId
AND (c.category IN ('bookmark', 'webservice', 'semweb'))
GROUP BY b.bId
Minus (Exclusion)

Query for “bookmark+webservice-semweb”, that is: bookmark AND webservice AND NOT semweb.
SELECT b. *
FROM scBookmarks b, scCategories c
WHERE b.bId = c.bId
AND (c.category IN ('bookmark', 'webservice'))
AND b.bId NOT
IN (SELECT b.bId FROM scBookmarks b, scCategories c WHERE b.bId = c.bId AND c.category = 'semweb')
GROUP BY b.bId
HAVING COUNT( b.bId ) =2

Leaving out the HAVING COUNT leads to the Query for “bookmark|webservice-semweb”.
Credits go to Rhomboid for helping me out with this query.
Conclusion

I guess the main advantage of this solution is that it is more normalized than the first solution, and that you can have unlimited number of tags per bookmark.
“Toxi” solution


Toxi came up with a three-table structure. Via the table “tagmap” the bookmarks and the tags are n-to-m related. Each tag can be used together with different bookmarks and vice versa. This DB-schema is also used by wordpress.
The queries are quite the same as in the “scuttle” solution.
Intersection (AND)

Query for “bookmark+webservice+semweb”
SELECT b.*
FROM tagmap bt, bookmark b, tag t
WHERE bt.tag_id = t.tag_id
AND (t.name IN ('bookmark', 'webservice', 'semweb'))
AND b.id = bt.bookmark_id
GROUP BY b.id
HAVING COUNT( b.id )=3
Union (OR)

Query for “bookmark|webservice|semweb”
SELECT b.*
FROM tagmap bt, bookmark b, tag t
WHERE bt.tag_id = t.tag_id
AND (t.name IN ('bookmark', 'webservice', 'semweb'))
AND b.id = bt.bookmark_id
GROUP BY b.id
Minus (Exclusion)

Query for “bookmark+webservice-semweb”, that is: bookmark AND webservice AND NOT semweb.

SELECT b. *
FROM bookmark b, tagmap bt, tag t
WHERE b.id = bt.bookmark_id
AND bt.tag_id = t.tag_id
AND (t.name IN ('Programming', 'Algorithms'))
AND b.id NOT IN (SELECT b.id FROM bookmark b, tagmap bt, tag t WHERE b.id = bt.bookmark_id AND bt.tag_id = t.tag_id AND t.name = 'Python')
GROUP BY b.id
HAVING COUNT( b.id ) =2
Leaving out the HAVING COUNT leads to the Query for “bookmark|webservice-semweb”.
Credits go to Rhomboid for helping me out with this query.
Conclusion

The advantages of this solution:

* You can save extra information on each tag (description, tag hierarchy, …)
* This is the most normalized solution (that is, if you go for 3NF: take this one :-)

Disadvantages:

* When altering or deleting bookmarks you can end up with tag-orphans.

If you want to have more complicated queries like (bookmarks OR bookmark) AND (webservice or WS) AND NOT (semweb or semanticweb) the queries tend to become very complicated. In these cases I suggest the following query/computation process:

1. Run a query for each tag appearing in your “tag-query”: SELECT b.id FROM tagmap bt, bookmark b, tag t WHERE bt.tag_id = t.tag_id AND b.id = bt.bookmark_id AND t.name = "semweb"
2. Put each id-set from the result into an array (that is: in your favourite coding language). You could cache this arrays if you want..
3. Constrain the arrays with union or intersection or whatever.

In this way, you can also do queries like (del.icio.us|delicious)+(semweb|semantic_web)-search. This type of queries (that is: the brackets) cannot be done by using the denormalized “MySQLicious solution”.
This is the most flexible data structure and I guess it should scale pretty good (that is: if you do some caching).

Update May, 2006. This arcticle got quite some attention. I wasn’t really prepared for that! It seems people keep referring to it and even some new sites that allow tagging give credit to my articles. I think the real credit goes to the contributers of the different schemas: MySQLicious, scuttle, Toxi and to all the contributors of the comments (be sure to read them!)

P.S. Thanks to Toxi for sending me the queries for the three-table-schema, Benjamin Reitzammer for pointing me to a loughing meme article (a good reference for tag queries) and powerlinux for pointing me to scuttle.

Wednesday, November 15, 2006

Tuesday, November 14, 2006

【通知】速告地址

拍成都宽窄巷子的小黑,拍顺德波伏街的懒人谷,拍上海虹口的都市醉汉,速速告知你们的联系地址,以便发放杂志刊用后的稿费。

Monday, November 13, 2006

【专栏】真假傻逼

朋友问,难道你还去SSW论坛潜水?这可太让人鄙视了。我忙不迭的回答,只是偶尔去看看,偶尔看看。就像我现在抽烟一样,偶尔抽抽。没办法,5年的习惯了。

因为有人转贴了和菜头的一张帖子,这让我在SSW论坛又翻看了几天的回帖,题为“过骠悍人生,做刚样男子”的帖子是和菜头应韩白之争而写的,他在帖子里说得很明白了,韩骂粗口是小事,白烨利用国家资源炒作私书,甚至利用美国几千条人命的悲剧炒作一本市场化的书才是大大值得批判的恶心事。SSW论坛的有些人看不到这两者的区别,还在那里义愤填膺:不许骂粗口!粗口有那么可怕吗,逼&操就真的引发礼崩乐坏了吗,想想清楚,是什么在阻止社会朝文明社会发展,不是粗口,不是“你妈逼”;而是公共资源被少数人占用,是公平规则被一些人践踏。SSW论坛的一些人真是晕了头。韩寒吵架白吵了。写了那么多,有些人只看到了其中的粗口。

陆天明帮白烨说话,陆川帮陆天明说话,高晓松帮陆川说话,因为他们是朋友关系,父子关系,在粗口和腐败面前选择批判价值,脑子有点拐不过来,可以理解。有些跟韩,白两边都没啥关系的人,本身就站在局外的人,也只看到了粗口,不见腐败,只好认为是理解能力有问题的糊涂蛋了。

突然想起来,以前在SSW论坛吵架,有个声音一直没有停止过:不许人身攻击,人身攻击的帖子利马删除,哪怕这个帖子很有价值。把脏水连带孩子一起倒掉,这等蠢事就是有些人在做。而且更绝的是,他们自己制定规则,自己来打破。他们反对人身攻击,结果自己到最后的时候,却开始了人生攻击,揭发别人搞女网友,却揭到自己的盟友上去了,真是有趣了。

国人就是怕被骂粗口,被骂一句“傻逼”就立马火爆三丈,好像真的傻了逼了一样。我在网上也被骂过傻逼,在东南亚游走的时候也被骂过fuck you,但那又怎么样呢。你难道真的像和菜头一样去买他的物理地址吗。被骂傻逼没关系,没有任何损失,走开就是了。如果在现实生活中利益被人侵占而无动于衷,那才是真的傻逼。譬如房地产维权之类的,和我一起买那个楼的很多人,明明被房地产商强奸了,还试图跟地产商讲和,地产商给点蝇头小利就和他们签了补充协议,要不就是到处看看有没有人集体找律师而他可以搭顺风车一起告。这样的人才是真傻逼。而往往是这些人,如果被骂一句“傻逼”的话,却了不得了,跟挖祖坟了似的。

其实,挖了祖坟又如何呢,地壳运动山崩海裂,有多少人的祖坟被挖被移被灭呢,难道你跟大自然去叫板??

Saturday, November 11, 2006

Thursday, November 09, 2006

【专栏】贱民之贱嗖嗖

出版达人老六创作了一个绕口令:山上有个贱嗖嗖 山下有个嗖嗖贱 有天俩人下山来比贱 不知道是嗖嗖贱比贱嗖嗖贱 还是贱嗖嗖比嗖嗖贱贱。”如果要说比贱,那谁不能跟印度贱民比。

有很多中国人去过印度,最有名的是唐僧玄奘法师,第二有名的是法显,也是个法师,晋朝人,他回来之后,在他的游记里提到贱民,说这些人很受歧视,如果要上街的话,他得敲一个随身携带的梆子,提醒路人甲乙丙丁注意闪避,以免看到他。也就是说,在1500年前的笈多王朝,一个普通印度人走在路上,一不小心看到了贱民,倒霉程度跟踩到一堆狗屎是一样的,恶心又懊悔。1500多年以后,另外一个大学问家金克木也去了印度,他看到的贱民已经不用敲梆子了,在路上走的时候,只需要有一只手时刻放在额头上,保持随时敬礼的姿势,依然是卑微而渺小。千年沧桑白云苍狗,民主改道,共和降临,对于贱民,他们只是去掉了一个梆子。

又过了五十年,不变的依然是贱民们在社会底层泥猪疥狗般的卑微生活。在阿格拉开往瓦拉纳西的火车上,我碰到一个贱民,他和他的老婆带着六个孩子蜷缩在车厢连接处的狭小空间里,相互依偎,看不出本色的脏布衣服和他黑乎乎的皮肤裹挟在一起,脏孩子们,像五子登科年画那般挂满了他的身体,如果不是他们的眼睛特别黑亮,还以为是列车员丢弃在车厢里的一堆废弃衣物。这厮会说英语,我就跟他爆破音严重得厉害的英语聊了一会,大概很久没有跟衣着光鲜的人士聊天了,他显得很高兴。这显然激发了他的顽皮劲儿,在我给另外一个锡克族大汉拍照的时候,他把他黝黑的脑袋挤进了我的取景框里,这个冒失的行为让那个大胡子锡克人很生气,大声训斥了他一声,贱民马上像被烫着了的蜥蜴一样,“哧溜”一声,重新缩回到车厢角落,变成一堆废弃衣物模样。

印度的种姓制度早已在五十多年前被法律废除,慈善达人甘地给他们取了个新名字叫哈里真(神的子民),不再叫“贱民”这个带有歧视性称呼,但这又怎么样呢,我们也在建议废除“民工”这个歧视性称呼,但煤矿依然要爆炸,薪水照旧要拖欠,世界就是这样,无论在哪里,都有骄奢者的嘴脸可以欣赏,都有卑微者的身影可以收藏。

Tuesday, November 07, 2006

【卖稿】电视没法看


“这个世界越来越快了……”,每天我打开网站新闻页的时候,我总有这样的感叹。微处理器的运算速度每18个月会翻一番;股票市场上的地产版块高歌猛进;上海出了磁悬浮后火车也越跑越快,以后深圳到北京睡一觉就到;流水线上工人的手指迅疾如群鸡啄米;周围亲朋离婚的速度同样和全球化的进程一样,越来越让人晕眩……根据爱因斯坦的理论,当速度快到一定程度后,会发生空间扭曲,这个时候,你会像纽约时报的专栏作家托马斯·弗里德曼一样发现世界是平的。
最好的一个例子就是美剧的传播速度,美国电视连续剧从来没有像今天这么火过,我最近迷上了看《越狱》,现在演到第二季了,美国人民刚刚看完的剧情,马上会通过互联网传送到太平洋的这边,期间经过数码录制、语音翻译、校对、调整时间轴、制作BT种子、上传、下载……时间差是一个晚上,《越狱》构思巧妙,非常抓人,我都感觉我的心是跟美国人民一起跳动的。上个月美国那边有个重要的棒球比赛,《越狱》停了一个月,把我撂一边了,急得我想托人给布什打电话,投诉他们的广电总局怎么一点都不急呢。
几年前,有个朋友看《流星花园》也是这般着急,那时候网络分布式点对点传输(BT)技术没有成熟,只能跑去租碟铺租《流星花园》的光盘看,一张光盘好几集,好几天出一张。去租碟铺次数多了,老板见他都熟了,“哎呀,不好意思,今天只来了5集,你过几天来吧,我先给你留着”。并劝慰我朋友不要着急,“现在台湾的观众也只看到了第九集,在大三通没有实现之前,你能看到第六集已经不错了,再说人家做光碟的也不容易嘛!用卫星电视偷摸收看,看完之后还要连夜用光碟刻录出来,再通过分销渠道到我这儿,速度已经相当快了!”结果,大三通没盼来,倒是BT技术来了。
我家的电视机有七十多个频道,每个频道里都充斥了美容广告清宫戏假模假式的武打片,我实在没有勇气让遥控器在它们身上停留一秒钟。花了钱安装了有线电视,尽是这些垃圾,还不能退货,逼得我只好到电脑上去看电视剧,互联网的好处就是,永远有一批热血沸腾的高素质精英义工在为网民免费服务,让我们能免费看到优秀美国电视连续剧,既练英语听力又欣赏编剧近乎完美的创作能力。这事儿根本没妨碍什么人,可就是有人不乐意,他们认为这种美国人的文化产品的泛滥,是一种文化侵略的具体表现,文化产品传播速度越来越畅通,说明文化侵略的步伐越来越急促。文化何辜,要被冠以侵略之名,人家的电视剧拍的就是比中国的好看,若要说侵略,那也是我们主动请来的。

Monday, November 06, 2006

Simple caching

The GridView has a property named EmptyDataText that allows you to specify the text to display when there are no records.



Hope this helps.

mariano p. szklanny | developer :: Patterns & Practices | Web Client Software Factory Team


--------------------------------------------------------------------------------



I usually use asp:panel controls -- put the GridView in one, and a message with "Sorry, no records" in the other, and then hide/show depending on what's in the dataset.






--------------------------------------------------------------------------------


Thanks everyone for the help! It’s all working perfectly, although I do have one last issue I can’t figure out:



Super simple: how do you respond in a gridview when 0 results are returned? I just get a blank space—not even the headers show up. Is there a standard tag that lets me simply post “Sorry, no records were found!” or something?



MS



I agree … remember too you can easily set priority (e.g. NotRemovable, for hi-pri items) and also set dependencies, so it’s easy to build a “tree” of cache-related items.



-Brian




Mike,



They are right. It would be easier to invalidate the cache using Cache.



Also thinking about it some more, Cache is better about handling large amounts of data. Holding large amounts of data in Application state can fill up server memory which can cause paging. Cache manages the memory issue by flushing items that are close to expiration when memory becomes scarce.



Cache it should be.



Take a look at How To : Add Items to the Cache http://windowssdk.msdn.microsoft.com/en-gb/library/18c1wd61.aspx.



-Ian Bennett




Ok, instead of using the Cache object, I would use Application state. Something like:



DataSet playerData = null;



if (Application["Players"] == null)

{

// FILL playerData WITH DATA...

Application["Players"] = playerData;

}

else

{

playerData = (DataSet)Application["Players"];

}



// NOW DO SOMETHING WITH playerData



Hope this helps.



-Ian Bennett




Across all pages… let’s suppose it’s a list of active football players and a ton of people are hitting that page…. And the list only changes every day, but the query to get that list is really expensive for whatever reason. That’s what I’m getting at here.



MS




What’s the desired scope the cache, meaning do you want it cached for each user, for all users, etc.? Do you want to share the cache across pages?



-Ian Bennett



Hey guys,



I’m trying to cache an array of values—not too many, maybe 100 strings in one array. But let’s assume the query to the database takes 30 seconds and the data won’t change more than once/day. What’s the best way to do this? I’m looking into online examples but they are all way too advanced (caching data sources, using sql dependencies, etc.)



All I want to do is build this array during Page_Load and store it for one day (60*60*24 seconds):



protected void Page_Load(object sender, EventArgs e)

{

if (not_cached)

// load the connection to the database, run the query (which returns a vector so an array can store it)

else

// use cache



// store results in a string array

whatever[]

}



MS

Sharing Master Pages between multiple web projects

The vdir method works good. We also create a base page and deploy it in the GAC that has utility classes for the master page.



http://strangeworld:8081 has more details and a working example.




--------------------------------------------------------------------------------




Storing the master page in the GAC was not a tested/supported scenario. It seems to work, but considering it wasn’t a tested scenario, I wouldn’t recommend it. (VSWhidbey 569807):



1. Scott's article about copying the precompiled dll to the application directory works.

http://weblogs.asp.net/scottgu/archive/2005/08/28/423888.aspx



2. This kb about creating virtual directory underneath the application and point to the shared master page, user control or sitemap would also be recommended and supported way.



324785 How to ahare ASP.NET pages and user controls between applications by http://support.microsoft.com/?id=324785






--------------------------------------------------------------------------------



There was another post about this a little while ago on the list, there appears to be a rather convoluted option based on the GAC described here



http://weblogs.asp.net/dwahlin/archive/2005/11/16/430779.aspx





Samuel




--------------------------------------------------------------------------------


Hi,



is there a way to share a master page between different web projects? I would like to have something like a link that we can add to every project (the same feature that is available in other project types), so updates will be propagated to all referencing projects.



Unfortunately, the source control system (CVS) does not support creating linked files. Any other techniques we could use to facilitate this?



thx,



- patrick





Patrick Schuler

How to retrieve the full name of the logged in User

You have to add the reference to System.DirectoryServices to your Project before using it.



Nuno Silva

Application Development Consultant




--------------------------------------------------------------------------------



System.DirectoryServices



Berkay


--------------------------------------------------------------------------------


Hi Berkay Meşe,



Thanks for immediate response to my query.



Can you please let me know the namespace for DirectoryEntry and DirectoryServices?



Note : I am using .Net Framework 1.1 for developing this application .





Regards

Sukesh


--------------------------------------------------------------------------------




string[] sUser;
sUser = Context.User.Identity.Name.ToString().Split(new Char[]{'\\'}, 2);

string Domain_Slash_User = Context.User.Identity.Name;
string Domain_Slash_Machine = Domain_Slash_User.Replace(@"\",@"/");
string queryString = @"WinNT://" + Domain_Slash_Machine;



DirectoryEntry obDirEntry = new DirectoryEntry(queryString);
System.DirectoryServices.PropertyCollection coll = obDirEntry.Properties;



object obVal = coll["FullName"].Value;
txtAlias.Text = obVal.ToString();



Berkay Meşe|Technology Solutions Professional|Application Platform
É90(212)-3265441È90(533)-6893610 šberkay.mese@microsoft.com

Try New Cool Features Of Biztalk Server






--------------------------------------------------------------------------------

Hi,



I am using Windows authentication for retrieving the alias and using the following code



private string [] sUser;

sUser = Context.User.Identity.Name.ToString().Split(new Char[]{'\\'}, 2);

txtAlias.Text = sUser[1];



Can anybody help me on how to retrieve the full name of the logged in User?



Regards

Sukesh

firstOne

Have a good start.

Saturday, November 04, 2006

【人物】拉琴老人和他的学校

显然,阿和在梁祝这个曲目上,还没有做到圆润两字,在半弓切弦的时候,显得有点手忙脚乱。但这并不妨碍他在全弓到底一脸沉醉的样子。行人从他身边匆匆而过,阿成和的琴匣半敞,里面有一些零星的钱。他说他爱文艺,喜欢历史,现在在蔡屋围一带拉琴卖艺,没事了就去附近的书城转一下,里面有个乐器行,有一把小提琴卖700多,阿成和看上它了,准备年底回家之前买了它。我想他只是说说而已。

点击在新窗口中浏览此图片

阿成和特别喜欢小孩,每逢有儿童经过他身边,他总是把提亲从肩上卸下来,连琴弓一起递给那些小孩,来,拉一下,而那些父母在这个时候,走得更急促了,把自己的孩子拉得跌跌撞撞,似乎离这个光头老汉越远越好。阿老汉显得很无奈,他说,我就是喜欢孩子,没办法,有一次,有个小孩过来跟我在路边学琴,被他父母看到了,拉过来就狠打了一顿,我要是有权力,都想把这种父母杀了,留着有什么用,他们教出来的孩子有什么用。老汉那张长得酷似蒋介石的脸,突然现出凶相来。

阿成和喜欢小孩到什么程度,他一直说一句话,为了孩子我把工作都丢了,他以前是西宁一个国营企业的司机,为了挣钱,他辞了铁饭碗工作,买了个卡车去跑运输,在八十年代这是不可想像的事情,结果车翻货亡,背上债务一直潦倒至今。他的梦想也就破灭,到如今依然是一个梦想,为孩子建一个学校的蓝图在记忆里已经模糊不清。

点击在新窗口中浏览此图片

未完


Thursday, November 02, 2006

【北头】没听说过的城中村

点击在新窗口中浏览此图片

深圳有个南头,不料还有个北头村,位于前海路,南新路,深南路的包夹地带,村口的对联是:北揽九州云气万丈高楼傲南山,头迎改革春风千亩蚝田泛金浪。一看这个对联就是改革既得利益者的口气,也能看出这里的村民以前是养蚝为生的。不多说了,看图。

点击在新窗口中浏览此图片

点击在新窗口中浏览此图片

点击在新窗口中浏览此图片

点击在新窗口中浏览此图片

点击在新窗口中浏览此图片

点击在新窗口中浏览此图片

点击在新窗口中浏览此图片

点击在新窗口中浏览此图片

点击在新窗口中浏览此图片

点击在新窗口中浏览此图片