summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorLeyla Farazha <leyla@lindenlab.com>2010-01-05 15:57:09 -0800
committerLeyla Farazha <leyla@lindenlab.com>2010-01-05 15:57:09 -0800
commitab3dbd647e78cff67ce7ffe85bb6fbc5c5461312 (patch)
treec173a561457b6fb0195194cb21fa0d24c15e9589 /indra/newview
parentdb6069e249b509e1551a76f438d795cbb9f992fa (diff)
parentcffe23df08bb0066c936efe667f60e90e0f89fd0 (diff)
Merge
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/lldateutil.cpp7
-rw-r--r--indra/newview/llfloaterworldmap.cpp67
-rw-r--r--indra/newview/llfloaterworldmap.h5
-rw-r--r--indra/newview/llviewermenu.cpp14
-rw-r--r--indra/newview/skins/default/textures/widgets/Linden_Dollar_Background.pngbin9506 -> 56298 bytes
-rw-r--r--indra/newview/skins/default/xui/en/floater_about_land.xml45
-rw-r--r--indra/newview/skins/default/xui/en/floater_pay_object.xml31
-rw-r--r--indra/newview/skins/default/xui/en/floater_preview_notecard.xml6
-rw-r--r--indra/newview/skins/default/xui/en/floater_tools.xml2
-rw-r--r--indra/newview/skins/default/xui/en/menu_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/en/menu_inventory_add.xml2
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_roles.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_main_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_people.xml6
-rw-r--r--indra/newview/tests/lldateutil_test.cpp10
16 files changed, 100 insertions, 103 deletions
diff --git a/indra/newview/lldateutil.cpp b/indra/newview/lldateutil.cpp
index 10b7935caf..abb2fdeb9a 100644
--- a/indra/newview/lldateutil.cpp
+++ b/indra/newview/lldateutil.cpp
@@ -44,15 +44,18 @@ static S32 DAYS_PER_MONTH_LEAP[] =
static S32 days_from_month(S32 year, S32 month)
{
+ llassert_always(1 <= month);
+ llassert_always(month <= 12);
+
if (year % 4 == 0
&& year % 100 != 0)
{
// leap year
- return DAYS_PER_MONTH_LEAP[month];
+ return DAYS_PER_MONTH_LEAP[month - 1];
}
else
{
- return DAYS_PER_MONTH_NOLEAP[month];
+ return DAYS_PER_MONTH_NOLEAP[month - 1];
}
}
diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp
index 98f9171237..0781d8ed06 100644
--- a/indra/newview/llfloaterworldmap.cpp
+++ b/indra/newview/llfloaterworldmap.cpp
@@ -100,8 +100,6 @@ enum EPanDirection
// Values in pixels per region
static const F32 ZOOM_MAX = 128.f;
-static const F32 SIM_COORD_DEFAULT = 128.f;
-
//---------------------------------------------------------------------------
// Globals
//---------------------------------------------------------------------------
@@ -189,7 +187,8 @@ LLFloaterWorldMap::LLFloaterWorldMap(const LLSD& key)
mInventory(NULL),
mInventoryObserver(NULL),
mFriendObserver(NULL),
- mCompletingRegionName(""),
+ mCompletingRegionName(),
+ mCompletingRegionPos(),
mWaitingForTracker(FALSE),
mIsClosing(FALSE),
mSetToUserPosition(TRUE),
@@ -205,7 +204,6 @@ LLFloaterWorldMap::LLFloaterWorldMap(const LLSD& key)
mCommitCallbackRegistrar.add("WMap.AvatarCombo", boost::bind(&LLFloaterWorldMap::onAvatarComboCommit, this));
mCommitCallbackRegistrar.add("WMap.Landmark", boost::bind(&LLFloaterWorldMap::onLandmarkComboCommit, this));
mCommitCallbackRegistrar.add("WMap.SearchResult", boost::bind(&LLFloaterWorldMap::onCommitSearchResult, this));
- mCommitCallbackRegistrar.add("WMap.CommitLocation", boost::bind(&LLFloaterWorldMap::onCommitLocation, this));
mCommitCallbackRegistrar.add("WMap.GoHome", boost::bind(&LLFloaterWorldMap::onGoHome, this));
mCommitCallbackRegistrar.add("WMap.Teleport", boost::bind(&LLFloaterWorldMap::onClickTeleportBtn, this));
mCommitCallbackRegistrar.add("WMap.ShowTarget", boost::bind(&LLFloaterWorldMap::onShowTargetBtn, this));
@@ -664,10 +662,6 @@ void LLFloaterWorldMap::updateLocation()
S32 agent_y = llround( (F32)fmod( agentPos.mdV[VY], (F64)REGION_WIDTH_METERS ) );
S32 agent_z = llround( (F32)agentPos.mdV[VZ] );
- childSetValue("spin x", LLSD(agent_x) );
- childSetValue("spin y", LLSD(agent_y) );
- childSetValue("spin z", LLSD(agent_z) );
-
// Set the current SLURL
mSLURL = LLSLURL::buildSLURL(agent_sim_name, agent_x, agent_y, agent_z);
}
@@ -699,9 +693,6 @@ void LLFloaterWorldMap::updateLocation()
F32 region_x = (F32)fmod( pos_global.mdV[VX], (F64)REGION_WIDTH_METERS );
F32 region_y = (F32)fmod( pos_global.mdV[VY], (F64)REGION_WIDTH_METERS );
- childSetValue("spin x", LLSD(region_x) );
- childSetValue("spin y", LLSD(region_y) );
- childSetValue("spin z", LLSD((F32)pos_global.mdV[VZ]) );
// simNameFromPosGlobal can fail, so don't give the user an invalid SLURL
if ( gotSimName )
@@ -733,9 +724,11 @@ void LLFloaterWorldMap::trackURL(const std::string& region_name, S32 x_coord, S3
{
// fill in UI based on URL
gFloaterWorldMap->childSetValue("location", region_name);
- childSetValue("spin x", LLSD((F32)x_coord));
- childSetValue("spin y", LLSD((F32)y_coord));
- childSetValue("spin z", LLSD((F32)z_coord));
+
+ // Save local coords to highlight position after region global
+ // position is returned.
+ gFloaterWorldMap->mCompletingRegionPos.set(
+ (F32)x_coord, (F32)y_coord, (F32)z_coord);
// pass sim name to combo box
gFloaterWorldMap->mCompletingRegionName = region_name;
@@ -899,18 +892,6 @@ void LLFloaterWorldMap::clearLocationSelection(BOOL clear_ui)
{
list->operateOnAll(LLCtrlListInterface::OP_DELETE);
}
- if (!childHasKeyboardFocus("spin x"))
- {
- childSetValue("spin x", SIM_COORD_DEFAULT);
- }
- if (!childHasKeyboardFocus("spin y"))
- {
- childSetValue("spin y", SIM_COORD_DEFAULT);
- }
- if (!childHasKeyboardFocus("spin z"))
- {
- childSetValue("spin z", 0);
- }
LLWorldMap::getInstance()->cancelTracking();
mCompletingRegionName = "";
}
@@ -1466,21 +1447,6 @@ void LLFloaterWorldMap::updateSims(bool found_null_sim)
}
}
-void LLFloaterWorldMap::onCommitLocation()
-{
- LLTracker::ETrackingStatus tracking_status = LLTracker::getTrackingStatus();
- if ( LLTracker::TRACKING_LOCATION == tracking_status)
- {
- LLVector3d pos_global = LLTracker::getTrackedPositionGlobal();
- F64 local_x = childGetValue("spin x");
- F64 local_y = childGetValue("spin y");
- F64 local_z = childGetValue("spin z");
- pos_global.mdV[VX] += -fmod(pos_global.mdV[VX], 256.0) + local_x;
- pos_global.mdV[VY] += -fmod(pos_global.mdV[VY], 256.0) + local_y;
- pos_global.mdV[VZ] = local_z;
- trackLocation(pos_global);
- }
-}
void LLFloaterWorldMap::onCommitSearchResult()
{
@@ -1503,12 +1469,19 @@ void LLFloaterWorldMap::onCommitSearchResult()
if (info->isName(sim_name))
{
LLVector3d pos_global = info->getGlobalOrigin();
- F64 local_x = childGetValue("spin x");
- F64 local_y = childGetValue("spin y");
- F64 local_z = childGetValue("spin z");
- pos_global.mdV[VX] += local_x;
- pos_global.mdV[VY] += local_y;
- pos_global.mdV[VZ] = local_z;
+
+ const F64 SIM_COORD_DEFAULT = 128.0;
+ LLVector3 pos_local(SIM_COORD_DEFAULT, SIM_COORD_DEFAULT, 0.0f);
+
+ // Did this value come from a trackURL() request?
+ if (!mCompletingRegionPos.isExactlyZero())
+ {
+ pos_local = mCompletingRegionPos;
+ mCompletingRegionPos.clear();
+ }
+ pos_global.mdV[VX] += (F64)pos_local.mV[VX];
+ pos_global.mdV[VY] += (F64)pos_local.mV[VY];
+ pos_global.mdV[VZ] = (F64)pos_local.mV[VZ];
childSetValue("location", sim_name);
trackLocation(pos_global);
diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h
index 7feebb583d..00f5e788fb 100644
--- a/indra/newview/llfloaterworldmap.h
+++ b/indra/newview/llfloaterworldmap.h
@@ -148,7 +148,6 @@ protected:
void updateSearchEnabled();
void onLocationFocusChanged( LLFocusableElement* ctrl );
void onLocationCommit();
- void onCommitLocation();
void onCommitSearchResult();
void cacheLandmarkPosition();
@@ -170,6 +169,10 @@ private:
LLFriendObserver* mFriendObserver;
std::string mCompletingRegionName;
+ // Local position from trackURL() request, used to select final
+ // position once region lookup complete.
+ LLVector3 mCompletingRegionPos;
+
std::string mLastRegionName;
BOOL mWaitingForTracker;
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index bd589b5485..149b7a6d65 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -5859,8 +5859,12 @@ void confirm_replace_attachment(S32 option, void* user_data)
}
}
-bool callback_attachment_drop(const LLSD& notification, const LLSD& response)
+void callback_attachment_drop(const LLSD& notification, const LLSD& response)
{
+ // Ensure user confirmed the drop
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option != 0) return;
+
// Called when the user clicked on an object attached to them
// and selected "Drop".
LLUUID object_id = notification["payload"]["object_id"].asUUID();
@@ -5869,7 +5873,7 @@ bool callback_attachment_drop(const LLSD& notification, const LLSD& response)
if (!object)
{
llwarns << "handle_drop_attachment() - no object to drop" << llendl;
- return true;
+ return;
}
LLViewerObject *parent = (LLViewerObject*)object->getParent();
@@ -5886,13 +5890,13 @@ bool callback_attachment_drop(const LLSD& notification, const LLSD& response)
if (!object)
{
llwarns << "handle_detach() - no object to detach" << llendl;
- return true;
+ return;
}
if (object->isAvatar())
{
llwarns << "Trying to detach avatar from avatar." << llendl;
- return true;
+ return;
}
// reselect the object
@@ -5900,7 +5904,7 @@ bool callback_attachment_drop(const LLSD& notification, const LLSD& response)
LLSelectMgr::getInstance()->sendDropAttachment();
- return true;
+ return;
}
class LLAttachmentDrop : public view_listener_t
diff --git a/indra/newview/skins/default/textures/widgets/Linden_Dollar_Background.png b/indra/newview/skins/default/textures/widgets/Linden_Dollar_Background.png
index a1d602f6f0..61f9b076ce 100644
--- a/indra/newview/skins/default/textures/widgets/Linden_Dollar_Background.png
+++ b/indra/newview/skins/default/textures/widgets/Linden_Dollar_Background.png
Binary files differ
diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml
index cc955369e2..33fdd923ad 100644
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -110,7 +110,7 @@
</text>
<line_editor
follows="left|top"
- height="16"
+ height="23"
layout="topleft"
left_pad="2"
max_length="63"
@@ -145,7 +145,7 @@
layout="topleft"
left="10"
name="LandType"
- top="84"
+ top_pad="5"
width="100">
Type:
</text>
@@ -192,7 +192,7 @@
layout="topleft"
left="10"
name="Owner:"
- top="124"
+ top_pad="5"
width="100">
Owner:
</text>
@@ -202,7 +202,7 @@
follows="left|top"
height="16"
layout="topleft"
- left_pad="5"
+ left_pad="2"
name="OwnerText"
width="240">
Leyla Linden
@@ -232,6 +232,7 @@
layout="topleft"
left="10"
name="Group:"
+ top_pad="7"
width="100">
Group:
</text>
@@ -240,10 +241,11 @@
enabled="false"
follows="left|top"
height="16"
- left_pad="5"
+ left_pad="2"
layout="topleft"
name="GroupText"
- width="240" />
+ width="240">
+Leyla Linden </text>
<button
follows="right"
height="16"
@@ -267,10 +269,10 @@
height="23"
label="Allow Deed to Group"
layout="topleft"
- left="96"
+ left="108"
name="check deed"
tool_tip="A group officer can deed this land to the group, so it will be supported by the group&apos;s land allocation."
- top="164"
+ top_pad="3"
width="146" />
<button
enabled="false"
@@ -289,7 +291,7 @@
height="16"
label="Owner Makes Contribution With Deed"
layout="topleft"
- left="96"
+ left="108"
name="check contrib"
tool_tip="When the land is deeded to the group, the former owner contributes enough land allocation to support it."
width="199" />
@@ -352,7 +354,7 @@
layout="topleft"
left_delta="-199"
name="For sale to"
- top_delta="6"
+ top_delta="2"
width="186">
For sale to: [BUYER]
</text>
@@ -364,7 +366,7 @@
layout="topleft"
left_delta="0"
name="Sell with landowners objects in parcel."
- top_pad="8"
+ top_pad="0"
width="186">
Objects included in sale
</text>
@@ -389,6 +391,7 @@
right="-10"
name="Cancel Land Sale"
left_pad="5"
+ top_pad="-10"
width="145" />
<text
type="string"
@@ -422,7 +425,7 @@
layout="topleft"
left="10"
name="PriceLabel"
- top="288"
+ top_pad="5"
width="100">
Area:
</text>
@@ -470,7 +473,7 @@
layout="topleft"
left_delta="82"
name="Buy Land..."
- top="328"
+ top_pad="7"
width="100" />
<button
enabled="true"
@@ -480,7 +483,7 @@
layout="topleft"
left="10"
name="Scripts..."
- top="352"
+ top_pad="1"
width="100" />
<button
enabled="false"
@@ -490,7 +493,7 @@
layout="topleft"
right="-10"
name="Buy For Group..."
- top="352"
+ top_delta="0"
width="180" />
<button
enabled="false"
@@ -510,7 +513,7 @@
layout="topleft"
right="-10"
name="Abandon Land..."
- top="328"
+ top_pad="-47"
width="180" />
<button
follows="left|top"
@@ -519,7 +522,7 @@
layout="topleft"
left_delta="0"
name="Reclaim Land..."
- top_delta="-50"
+ top_delta="-48"
width="180" />
<button
enabled="false"
@@ -530,7 +533,7 @@
left_delta="0"
name="Linden Sale..."
tool_tip="Land must be owned, set content, and not already for auction."
- top_pad="4"
+ top_pad="2"
width="180" />
</panel>
<panel
@@ -2022,7 +2025,7 @@ Only large parcels can be listed in search.
multi_select="true"
name="AccessList"
tool_tip="([LISTED] listed, [MAX] max)"
- width="240" />
+ width="230" />
<button
follows="bottom"
height="23"
@@ -2047,7 +2050,7 @@ Only large parcels can be listed in search.
follows="top|right"
height="170"
width="240"
- left_pad="8">
+ left_pad="2">
<text
type="string"
length="1"
@@ -2071,7 +2074,7 @@ Only large parcels can be listed in search.
multi_select="true"
name="BannedList"
tool_tip="([LISTED] listed, [MAX] max)"
- width="240" />
+ width="230" />
<button
follows="bottom"
height="23"
diff --git a/indra/newview/skins/default/xui/en/floater_pay_object.xml b/indra/newview/skins/default/xui/en/floater_pay_object.xml
index 1946920a9c..455018f467 100644
--- a/indra/newview/skins/default/xui/en/floater_pay_object.xml
+++ b/indra/newview/skins/default/xui/en/floater_pay_object.xml
@@ -30,25 +30,25 @@
type="string"
length="1"
follows="left|top"
- font="SansSerif"
height="16"
layout="topleft"
left_pad="7"
+ top_delta="3"
name="payee_name"
- width="210">
- [FIRST] [LAST]
+ width="184">
+ Ericacita Moostopolison
</text>
<text
type="string"
length="1"
follows="left|top"
halign="left"
- height="16"
+ height="14"
layout="topleft"
- left="30"
+ left="34"
name="object_name_label"
top_pad="0"
- width="150">
+ width="180">
Via object:
</text>
<icon
@@ -59,20 +59,21 @@
name="icon_object"
tool_tip="Objects"
top_pad="0"
- left="30"
+ left="10"
/>
<text
type="string"
length="1"
follows="left|top"
- font="SansSerif"
- height="18"
+ height="16"
layout="topleft"
- left_pad="5"
+ left_pad="7"
name="object_name_text"
- top_delta="0"
- width="210">
- ...
+ top_delta="3"
+ use_ellipses="true"
+ word_wrap="false"
+ width="188">
+ My awesome object with a really damn long name
</text>
<button
height="23"
@@ -112,7 +113,7 @@
type="string"
length="1"
follows="left|top"
- height="18"
+ height="14"
layout="topleft"
left="25"
name="amount text"
@@ -123,7 +124,7 @@
<line_editor
border_style="line"
follows="left|top|right"
- height="19"
+ height="21"
top_pad="0"
layout="topleft"
left="120"
diff --git a/indra/newview/skins/default/xui/en/floater_preview_notecard.xml b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
index 06dbdc9539..ead5b8c8f2 100644
--- a/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
+++ b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
@@ -11,15 +11,15 @@
min_width="234"
name="preview notecard"
help_topic="preview_notecard"
- title="NOTE:"
+ title="NOTECARD:"
width="400">
<floater.string
name="no_object">
- Unable to find object containing this note.
+ Unable to find object containing this notecard.
</floater.string>
<floater.string
name="not_allowed">
- You do not have permission to view this note.
+ You do not have permission to view this notecard.
</floater.string>
<floater.string
name="Title">
diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml
index e55453f772..a1e190fc5e 100644
--- a/indra/newview/skins/default/xui/en/floater_tools.xml
+++ b/indra/newview/skins/default/xui/en/floater_tools.xml
@@ -2675,7 +2675,7 @@ even though the user gets a free copy.
height="18"
layout="topleft"
left="10"
- use_ellipsis="true"
+ use_ellipses="true"
read_only="true"
name="media_info"
width="180" />
diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml
index d29dfa7034..1e10467148 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory.xml
@@ -85,7 +85,7 @@
parameter="lsl" />
</menu_item_call>
<menu_item_call
- label="New Note"
+ label="New Notecard"
layout="topleft"
name="New Note">
<menu_item_call.on_click
diff --git a/indra/newview/skins/default/xui/en/menu_inventory_add.xml b/indra/newview/skins/default/xui/en/menu_inventory_add.xml
index b07a8bb512..5ad099e2d9 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory_add.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory_add.xml
@@ -71,7 +71,7 @@
parameter="lsl" />
</menu_item_call>
<menu_item_call
- label="New Note"
+ label="New Notecard"
layout="topleft"
name="New Note">
<menu_item_call.on_click
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 4e495bab3f..58e9d39807 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -307,7 +307,7 @@
<menu_item_separator
layout="topleft" />
<menu_item_call
- label="Buy Land"
+ label="Buy This Land"
layout="topleft"
name="Buy Land">
<menu_item_call.on_click
diff --git a/indra/newview/skins/default/xui/en/panel_group_roles.xml b/indra/newview/skins/default/xui/en/panel_group_roles.xml
index 9548119d58..a5bab3232c 100644
--- a/indra/newview/skins/default/xui/en/panel_group_roles.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_roles.xml
@@ -258,7 +258,7 @@ things in this group. There&apos;s a broad variety of Abilities.
name="static"
top_pad="5"
width="300">
- Assigned Members
+ Assigned Roles
</text>
<scroll_list
draw_stripes="true"
diff --git a/indra/newview/skins/default/xui/en/panel_main_inventory.xml b/indra/newview/skins/default/xui/en/panel_main_inventory.xml
index 4353b306cd..d7792696e7 100644
--- a/indra/newview/skins/default/xui/en/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_main_inventory.xml
@@ -262,7 +262,7 @@ halign="center"
parameter="lsl" />
</menu_item_call>
<menu_item_call
- label="New Note"
+ label="New Notecard"
layout="topleft"
name="New Note">
<menu_item_call.on_click
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index 08a10553a8..adf22f825f 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -400,7 +400,7 @@ background_visible="true"
layout="topleft"
name="group_info_btn"
tool_tip="Show group information"
- width="110" />
+ width="102" />
<button
follows="bottom|left"
top="4"
@@ -410,7 +410,7 @@ background_visible="true"
layout="topleft"
name="chat_btn"
tool_tip="Open chat session"
- width="110" />
+ width="102" />
<button
follows="bottom|left"
top="4"
@@ -420,6 +420,6 @@ background_visible="true"
layout="topleft"
name="group_call_btn"
tool_tip="Call this group"
- width="110" />
+ width="102" />
</panel>
</panel>
diff --git a/indra/newview/tests/lldateutil_test.cpp b/indra/newview/tests/lldateutil_test.cpp
index 142a5eb5e6..7ba82fbd2c 100644
--- a/indra/newview/tests/lldateutil_test.cpp
+++ b/indra/newview/tests/lldateutil_test.cpp
@@ -179,4 +179,14 @@ namespace tut
LLDateUtil::ageFromDate("12/31/2009", mNow),
"Joined today" );
}
+
+ template<> template<>
+ void dateutil_object_t::test<5>()
+ {
+ set_test_name("2010 rollover");
+ LLDate now(std::string("2010-01-04T12:00:00Z"));
+ ensure_equals("days",
+ LLDateUtil::ageFromDate("12/13/2009", now),
+ "3 weeks old" );
+ }
}