From 910a1d704e35d5789e4a8c34efa89ed8d7f3bf9d Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Tue, 6 Nov 2018 17:11:22 +0200
Subject: SL-10001 Fixed position parameters trembling at the top of the page
 when moving

---
 indra/newview/llmanip.cpp | 71 ++++++++++++++++++++++++++---------------------
 1 file changed, 40 insertions(+), 31 deletions(-)

diff --git a/indra/newview/llmanip.cpp b/indra/newview/llmanip.cpp
index 8567180dd6..1dc03123eb 100644
--- a/indra/newview/llmanip.cpp
+++ b/indra/newview/llmanip.cpp
@@ -431,7 +431,6 @@ void LLManip::renderXYZ(const LLVector3 &vec)
 {
 	const S32 PAD = 10;
 	std::string feedback_string;
-	LLVector3 camera_pos = LLViewerCamera::getInstance()->getOrigin() + LLViewerCamera::getInstance()->getAtAxis();
 	S32 window_center_x = gViewerWindow->getWorldViewRectScaled().getWidth() / 2;
 	S32 window_center_y = gViewerWindow->getWorldViewRectScaled().getHeight() / 2;
 	S32 vertical_offset = window_center_y - VERTICAL_OFFSET;
@@ -451,37 +450,47 @@ void LLManip::renderXYZ(const LLVector3 &vec)
 			235,
 			PAD * 2 + 10, 
 			LLColor4(0.f, 0.f, 0.f, 0.7f) );
-	}
-	gGL.popMatrix();
-
-	gViewerWindow->setup3DRender();
 
-	{
-		LLFontGL* font = LLFontGL::getFontSansSerif();
-		LLLocale locale(LLLocale::USER_LOCALE);
-		LLGLDepthTest gls_depth(GL_FALSE);
-		// render drop shadowed text
-		feedback_string = llformat("X: %.3f", vec.mV[VX]);
-		hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *font, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -102.f + 1.f, (F32)vertical_offset - 1.f, LLColor4::black, FALSE);
-
-		feedback_string = llformat("Y: %.3f", vec.mV[VY]);
-		hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *font, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -27.f + 1.f, (F32)vertical_offset - 1.f, LLColor4::black, FALSE);
-		
-		feedback_string = llformat("Z: %.3f", vec.mV[VZ]);
-		hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *font, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, 48.f + 1.f, (F32)vertical_offset - 1.f, LLColor4::black, FALSE);
-
-		// render text on top
-		feedback_string = llformat("X: %.3f", vec.mV[VX]);
-		hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *font, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -102.f, (F32)vertical_offset, LLColor4(1.f, 0.5f, 0.5f, 1.f), FALSE);
-
-		gGL.diffuseColor3f(0.5f, 1.f, 0.5f);
-		feedback_string = llformat("Y: %.3f", vec.mV[VY]);
-		hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *font, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -27.f, (F32)vertical_offset, LLColor4(0.5f, 1.f, 0.5f, 1.f), FALSE);
-		
-		gGL.diffuseColor3f(0.5f, 0.5f, 1.f);
-		feedback_string = llformat("Z: %.3f", vec.mV[VZ]);
-		hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *font, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, 48.f, (F32)vertical_offset, LLColor4(0.5f, 0.5f, 1.f, 1.f), FALSE);
-	}
+        LLFontGL* font = LLFontGL::getFontSansSerif();
+        LLLocale locale(LLLocale::USER_LOCALE);
+        LLGLDepthTest gls_depth(GL_FALSE);
+
+        // render drop shadowed text (manually because of bigger 'distance')
+        F32 right_x;
+        feedback_string = llformat("X: %.3f", vec.mV[VX]);
+        font->render(utf8str_to_wstring(feedback_string), 0, window_center_x - 102.f + 1.f, window_center_y + vertical_offset - 2.f, LLColor4::black,
+            LLFontGL::LEFT, LLFontGL::BASELINE,
+            LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, 1000, &right_x);
+
+        feedback_string = llformat("Y: %.3f", vec.mV[VY]);
+        font->render(utf8str_to_wstring(feedback_string), 0, window_center_x - 27.f + 1.f, window_center_y + vertical_offset - 2.f, LLColor4::black,
+            LLFontGL::LEFT, LLFontGL::BASELINE,
+            LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, 1000, &right_x);
+
+        feedback_string = llformat("Z: %.3f", vec.mV[VZ]);
+        font->render(utf8str_to_wstring(feedback_string), 0, window_center_x + 48.f + 1.f, window_center_y + vertical_offset - 2.f, LLColor4::black,
+            LLFontGL::LEFT, LLFontGL::BASELINE,
+            LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, 1000, &right_x);
+
+        // render text on top
+        feedback_string = llformat("X: %.3f", vec.mV[VX]);
+        font->render(utf8str_to_wstring(feedback_string), 0, window_center_x - 102.f, window_center_y + vertical_offset, LLColor4(1.f, 0.5f, 0.5f, 1.f),
+            LLFontGL::LEFT, LLFontGL::BASELINE,
+            LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, 1000, &right_x);
+
+        feedback_string = llformat("Y: %.3f", vec.mV[VY]);
+        font->render(utf8str_to_wstring(feedback_string), 0, window_center_x - 27.f, window_center_y + vertical_offset, LLColor4(0.5f, 1.f, 0.5f, 1.f),
+            LLFontGL::LEFT, LLFontGL::BASELINE,
+            LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, 1000, &right_x);
+
+        feedback_string = llformat("Z: %.3f", vec.mV[VZ]);
+        font->render(utf8str_to_wstring(feedback_string), 0, window_center_x + 48.f, window_center_y + vertical_offset, LLColor4(0.5f, 0.5f, 1.f, 1.f),
+            LLFontGL::LEFT, LLFontGL::BASELINE,
+            LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, 1000, &right_x);
+    }
+    gGL.popMatrix();
+
+    gViewerWindow->setup3DRender();
 }
 
 void LLManip::renderTickText(const LLVector3& pos, const std::string& text, const LLColor4 &color)
-- 
cgit v1.2.3


From 88956491c819525fa07c1d347056f6a6900b4881 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Wed, 7 Nov 2018 18:21:16 +0200
Subject: SL-9414 Inconsistent hover vs click action when viewed through
 transparent prims

---
 indra/newview/lltoolpie.cpp | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index 5082e16685..d8f63b9332 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -112,8 +112,22 @@ BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask)
 	mMouseDownX = x;
 	mMouseDownY = y;
 
-	//left mouse down always picks transparent (but see handleMouseUp)
-	mPick = gViewerWindow->pickImmediate(x, y, TRUE, FALSE);
+
+	mPick = gViewerWindow->pickImmediate(x, y, FALSE, FALSE);
+	LLViewerObject *object = mPick.getObject();
+	LLViewerObject *parent = object ? object->getRootEdit() : NULL;
+	if (!object
+		|| object->isAttachment()
+		|| object->getClickAction() == CLICK_ACTION_DISABLED
+		|| (!useClickAction(mask, object, parent) && !object->flagHandleTouch() && !(parent && parent->flagHandleTouch())))
+	{
+		// Unless we are hovering over actionable visible object
+		// left mouse down always picks transparent (but see handleMouseUp).
+		// Also see LLToolPie::handleHover() - priorities are a bit different there.
+		// Todo: we need a more consistent set of rules to work with
+		mPick = gViewerWindow->pickImmediate(x, y, TRUE /*transparent*/, FALSE);
+	}
+
 	mPick.mKeyMask = mask;
 
 	mMouseButtonDown = true;
-- 
cgit v1.2.3


From 592d455cef5ea8be31aef66195c2fc64fc7bbb1f Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Fri, 9 Nov 2018 16:44:06 +0200
Subject: SL-10018 FIXED Viewer crashes when clicking on a link of a folder in
 Inventory

---
 indra/newview/llinventorypanel.cpp | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 45dbb446eb..3992b506e9 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -1163,6 +1163,11 @@ void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& it
 			LLFolderViewModelItemInventory* fve_listener = static_cast<LLFolderViewModelItemInventory*>(folder_item->getViewModelItem());
 			if (fve_listener && (fve_listener->getInventoryType() == LLInventoryType::IT_CATEGORY))
 			{
+				if (fve_listener->getInventoryObject() && fve_listener->getInventoryObject()->getIsLinkType())
+				{
+					return;
+				}
+
 				if(prev_folder_item)
 				{
 					LLFolderBridge* prev_bridge = (LLFolderBridge*)prev_folder_item->getViewModelItem();
-- 
cgit v1.2.3


From 2d222309500a667cd8880172daa8f3d2088596b6 Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Mon, 12 Nov 2018 15:31:19 +0200
Subject: SL-9935 Include full win10 build number in Help > About Second Life
 and logs

---
 indra/llcommon/llsys.cpp | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index 1ef6c538ba..1f8d558fbe 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -268,10 +268,32 @@ LLOSInfo::LLOSInfo() :
 		}
 	}
 
+	S32 ubr = 0; // Windows 10 Update Build Revision, can be retrieved from a registry
+	if (mMajorVer == 10)
+	{
+		DWORD cbData(sizeof(DWORD));
+		DWORD data(0);
+		HKEY key;
+		BOOL ret_code = RegOpenKeyExW(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"), 0, KEY_READ, &key);
+		if (ERROR_SUCCESS == ret_code)
+		{
+			ret_code = RegQueryValueExW(key, L"UBR", 0, NULL, reinterpret_cast<LPBYTE>(&data), &cbData);
+			if (ERROR_SUCCESS == ret_code)
+			{
+				ubr = data;
+			}
+		}
+	}
+
 	mOSString = mOSStringSimple;
 	if (mBuild > 0)
 	{
-		mOSString += llformat("(Build %d)", mBuild);
+		mOSString += llformat("(Build %d", mBuild);
+		if (ubr > 0)
+		{
+			mOSString += llformat(".%d", ubr);
+		}
+		mOSString += ")";
 	}
 
 	LLStringUtil::trim(mOSStringSimple);
-- 
cgit v1.2.3


From 5356e8b81a4c79bd9725ba4e6409b1b76083f463 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Mon, 12 Nov 2018 17:24:03 +0200
Subject: SL-10043 FIXED Viewer crashes when double-clicking 'For sale' parcel
 icon on World map in some cases

---
 indra/newview/llworldmapview.cpp | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp
index 707fe76cef..b88631a71b 100644
--- a/indra/newview/llworldmapview.cpp
+++ b/indra/newview/llworldmapview.cpp
@@ -1751,9 +1751,12 @@ BOOL LLWorldMapView::handleDoubleClick( S32 x, S32 y, MASK mask )
 		case MAP_ITEM_LAND_FOR_SALE_ADULT:
 			{
 				LLVector3d pos_global = viewPosToGlobal(x, y);
-				LLSimInfo* info = LLWorldMap::getInstance()->simInfoFromPosGlobal(pos_global);
-				LLFloaterReg::hideInstance("world_map");
-				LLFloaterReg::showInstance("search", LLSD().with("category", "land").with("query", info->getName()));
+				std::string sim_name;
+				if (LLWorldMap::getInstance()->simNameFromPosGlobal(pos_global, sim_name))
+				{
+					LLFloaterReg::hideInstance("world_map");
+					LLFloaterReg::showInstance("search", LLSD().with("category", "land").with("query", sim_name));
+				}
 				break;
 			}
 		case MAP_ITEM_CLASSIFIED:
-- 
cgit v1.2.3


From 31be136d4056e02cbf5c377f3544235debb7376b Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Tue, 13 Nov 2018 20:00:47 +0200
Subject: SL-10042 Fixed hang in inventory floater

---
 indra/newview/llfloateravatarpicker.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index c5561fe011..33099db1b9 100644
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -812,7 +812,7 @@ bool LLFloaterAvatarPicker::isSelectBtnEnabled()
 {
 	bool ret_val = visibleItemsSelected();
 
-	if ( ret_val )
+	if ( ret_val && !isMinimized())
 	{
 		std::string acvtive_panel_name;
 		LLScrollListCtrl* list =  NULL;
-- 
cgit v1.2.3


From e867e619dbb62b4c9ebc1d358c6fea048f87190c Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Thu, 15 Nov 2018 00:27:26 +0200
Subject: build fix

---
 indra/newview/lltoolpie.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index 5cfb2026e0..1b76d249cb 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -111,7 +111,7 @@ BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask)
     mMouseOutsideSlop = FALSE;
 	mMouseDownX = x;
 	mMouseDownY = y;
-	LLTimer pick_timer;.
+	LLTimer pick_timer;
 	BOOL pick_rigged = false; //gSavedSettings.getBOOL("AnimatedObjectsAllowLeftClick");
 	mPick = gViewerWindow->pickImmediate(x, y, FALSE, pick_rigged);
 	LLViewerObject *object = mPick.getObject();
-- 
cgit v1.2.3


From ab0d3f09d7a356eae758de03d533fabb3a380da1 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Wed, 14 Nov 2018 17:15:11 +0200
Subject: SL-9975 All offline inventory offers from scripted objects are lost

---
 indra/newview/llimprocessing.cpp | 32 +++++++++++++++++++++++++-------
 1 file changed, 25 insertions(+), 7 deletions(-)

diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp
index e76b3d118e..d59c301210 100644
--- a/indra/newview/llimprocessing.cpp
+++ b/indra/newview/llimprocessing.cpp
@@ -854,15 +854,33 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
             }
             else // IM_TASK_INVENTORY_OFFERED
             {
-                if (sizeof(S8) != binary_bucket_size)
+                if (offline == IM_OFFLINE && session_id.isNull() && aux_id.notNull() && binary_bucket_size > sizeof(S8)* 5)
                 {
-                    LL_WARNS("Messaging") << "Malformed inventory offer from object" << LL_ENDL;
-                    delete info;
-                    break;
+                    // cap received offline message
+                    std::string str_bucket = ll_safe_string((char*)binary_bucket, binary_bucket_size);
+                    typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+                    boost::char_separator<char> sep("|", "", boost::keep_empty_tokens);
+                    tokenizer tokens(str_bucket, sep);
+                    tokenizer::iterator iter = tokens.begin();
+
+                    info->mType = (LLAssetType::EType)(atoi((*(iter++)).c_str()));
+                    // Note There is more elements in 'tokens' ...
+
+                    info->mObjectID = LLUUID::null;
+                    info->mFromObject = TRUE;
+                }
+                else
+                {
+                    if (sizeof(S8) != binary_bucket_size)
+                    {
+                        LL_WARNS("Messaging") << "Malformed inventory offer from object" << LL_ENDL;
+                        delete info;
+                        break;
+                    }
+                    info->mType = (LLAssetType::EType) binary_bucket[0];
+                    info->mObjectID = LLUUID::null;
+                    info->mFromObject = TRUE;
                 }
-                info->mType = (LLAssetType::EType) binary_bucket[0];
-                info->mObjectID = LLUUID::null;
-                info->mFromObject = TRUE;
             }
 
             info->mIM = dialog;
-- 
cgit v1.2.3


From 6e934b1dba3928559e8eea619910cb61df3d2472 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Thu, 15 Nov 2018 15:14:00 +0200
Subject: SL-9782 Fixed The Stand button doesn't lay anymore on the lower bar

---
 indra/newview/llmoveview.cpp | 16 ----------------
 indra/newview/llmoveview.h   |  2 --
 2 files changed, 18 deletions(-)

diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp
index 301487b994..19f238d99a 100644
--- a/indra/newview/llmoveview.cpp
+++ b/indra/newview/llmoveview.cpp
@@ -702,11 +702,9 @@ void LLPanelStandStopFlying::updatePosition()
 {
 	if (mAttached) return;
 
-	S32 y_pos = 0;
 	S32 bottom_tb_center = 0;
 	if (LLToolBar* toolbar_bottom = gToolBarView->getToolbar(LLToolBarEnums::TOOLBAR_BOTTOM))
 	{
-		y_pos = toolbar_bottom->getRect().getHeight();
 		bottom_tb_center = toolbar_bottom->getRect().getCenterX();
 	}
 
@@ -716,20 +714,6 @@ void LLPanelStandStopFlying::updatePosition()
 		left_tb_width = toolbar_left->getRect().getWidth();
 	}
 
-	if (!mStateManagementButtons.get()) // Obsolete?!!
-	{
-		LLPanel* panel_ssf_container = gToolBarView->getChild<LLPanel>("state_management_buttons_container");
-		if (panel_ssf_container)
-		{
-			mStateManagementButtons = panel_ssf_container->getHandle();
-		}
-	}
-
-	if(LLPanel* panel_ssf_container = mStateManagementButtons.get())
-	{
-		panel_ssf_container->setOrigin(0, y_pos);
-	}
-
 	if (gToolBarView != NULL && gToolBarView->getToolbar(LLToolBarEnums::TOOLBAR_LEFT)->hasButtons())
 	{
 		S32 x_pos = bottom_tb_center - getRect().getWidth() / 2 - left_tb_width;
diff --git a/indra/newview/llmoveview.h b/indra/newview/llmoveview.h
index 4a31f2a814..e8b9a6fdb2 100644
--- a/indra/newview/llmoveview.h
+++ b/indra/newview/llmoveview.h
@@ -172,8 +172,6 @@ private:
 	 */
 	LLHandle<LLPanel> mOriginalParent;
 
-	LLHandle<LLPanel> mStateManagementButtons;
-
 	/**
 	 * True if the panel is currently attached to the movement controls floater.
 	 * 
-- 
cgit v1.2.3


From cd3608e661c3e2cab0fab25e11647ae8ee8285bd Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Fri, 16 Nov 2018 15:53:52 +0200
Subject: SL-10023 FIXED Dragging mouse on World map sometimes causes cursor
 jump to the center of the screen

---
 indra/llwindow/llopenglview-objc.mm | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index c8c086d705..8923ea6458 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -322,6 +322,10 @@ attributedStringInfo getSegments(NSAttributedString *str)
 
 - (void) mouseDown:(NSEvent *)theEvent
 {
+    NSPoint mPoint = [theEvent locationInWindow];
+    mMousePos[0] = mPoint.x;
+    mMousePos[1] = mPoint.y;
+
     // Apparently people still use this?
     if ([theEvent modifierFlags] & NSCommandKeyMask &&
         !([theEvent modifierFlags] & NSControlKeyMask) &&
-- 
cgit v1.2.3


From e0072664237b6ac0cae45577b436e5a25800e2f1 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Mon, 19 Nov 2018 17:24:06 +0200
Subject: SL-5366 FIXED Chinese characters are not displaying correctly in TOS
 loading text

---
 indra/newview/skins/default/xui/zh/floater_tos.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/skins/default/xui/zh/floater_tos.xml b/indra/newview/skins/default/xui/zh/floater_tos.xml
index 4cac07cd21..2f02316fc0 100644
--- a/indra/newview/skins/default/xui/zh/floater_tos.xml
+++ b/indra/newview/skins/default/xui/zh/floater_tos.xml
@@ -4,7 +4,7 @@
 		http://secondlife.com/app/tos/
 	</floater.string>
 	<floater.string name="loading_url">
-		data:text/html,%3Chtml%3E%3Chead%3E%3C/head%3E%3Cbody text=%22000000%22%3E%3Ch2%3E 正在載入 %3Ca%20target%3D%22_external%22%20href%3D%22http%3A//secondlife.com/app/tos/%22%3ETerms%20of%20Service%3C/a%3E...%3C/h2%3E %3C/body%3E %3C/html%3E
+		data:text/html;charset=utf-8,%3Chtml%3E%3Chead%3E%3C/head%3E%3Cbody text=%22000000%22%3E%3Ch2%3E 正在載入 %3Ca%20target%3D%22_external%22%20href%3D%22http%3A//secondlife.com/app/tos/%22%3ETerms%20of%20Service%3C/a%3E...%3C/h2%3E %3C/body%3E %3C/html%3E
 	</floater.string>
 	<text name="tos_heading">
 		請閱讀並遵守Second Life使用條款、隱私政策、服務條款,包括同意在發生爭議時接受仲裁並放棄採取集體或群體求訴的規定。 繼續登入[SECOND_LIFE]前,你必須同意這些條款。
-- 
cgit v1.2.3


From a72a4cb394fcce65b10126d631b270acf6009eb4 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Fri, 16 Nov 2018 17:42:31 +0200
Subject: SL-4730 Reduce bias trashing

---
 indra/newview/llviewertexture.cpp | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index d5aa249883..d2157f33cf 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -474,6 +474,7 @@ void LLViewerTexture::initClass()
 // tuning params
 const F32 discard_bias_delta = .25f;
 const F32 discard_delta_time = 0.5f;
+const F32 GPU_MEMORY_CHECK_WAIT_TIME = 1.0f;
 // non-const (used externally
 F32 texmem_lower_bound_scale = 0.85f;
 F32 texmem_middle_bound_scale = 0.925f;
@@ -483,12 +484,12 @@ static LLTrace::BlockTimerStatHandle FTM_TEXTURE_MEMORY_CHECK("Memory Check");
 //static 
 bool LLViewerTexture::isMemoryForTextureLow()
 {
-	const F32 WAIT_TIME = 1.0f; //second
 	static LLFrameTimer timer;
+	static bool low_mem = false;
 
-	if(timer.getElapsedTimeF32() < WAIT_TIME) //call this once per second.
+	if(timer.getElapsedTimeF32() < GPU_MEMORY_CHECK_WAIT_TIME) //call this once per second.
 	{
-		return false;
+		return low_mem;
 	}
 	timer.reset();
 
@@ -497,7 +498,7 @@ bool LLViewerTexture::isMemoryForTextureLow()
 	const S32Megabytes MIN_FREE_TEXTURE_MEMORY(20); //MB Changed to 20 MB per MAINT-6882
 	const S32Megabytes MIN_FREE_MAIN_MEMORY(100); //MB	
 
-	bool low_mem = false;
+	low_mem = false;
 	if (gGLManager.mHasATIMemInfo)
 	{
 		S32 meminfo[4];
@@ -572,10 +573,14 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity
 			sEvaluationTimer.reset();
 		}
 	}
-	else if(sEvaluationTimer.getElapsedTimeF32() > discard_delta_time && isMemoryForTextureLow())
+	else if(isMemoryForTextureLow())
 	{
-		sDesiredDiscardBias += discard_bias_delta;
-		sEvaluationTimer.reset();
+		// Note: isMemoryForTextureLow() uses 1s delay, make sure we waited enough for it to restore
+		if (sEvaluationTimer.getElapsedTimeF32() > GPU_MEMORY_CHECK_WAIT_TIME)
+		{
+			sDesiredDiscardBias += discard_bias_delta;
+			sEvaluationTimer.reset();
+		}
 	}
 	else if (sDesiredDiscardBias > 0.0f &&
 			 sBoundTextureMemory < sMaxBoundTextureMemory * texmem_lower_bound_scale &&
-- 
cgit v1.2.3


From ca9d39c6c7f0acd2cf6f8a6e894d09dcf8e6a353 Mon Sep 17 00:00:00 2001
From: Cinder <cinder@sdf.org>
Date: Thu, 25 Aug 2016 13:42:37 -0500
Subject: SL-3404 Don't send ParcelPropertiesRequest on every cursor position
 change

---
 doc/contributions.txt       |  1 +
 indra/newview/lltoolpie.cpp | 10 ++++------
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/doc/contributions.txt b/doc/contributions.txt
index a09b6aff43..88b2a77393 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -371,6 +371,7 @@ Cinder Roxley
     STORM-2116
     STORM-2127
     STORM-2144
+    SL-3404
 Clara Young
 Coaldust Numbers
     VWR-1095
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index 1b76d249cb..697db01d11 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -870,13 +870,11 @@ static bool needs_tooltip(LLSelectNode* nodep)
 
 BOOL LLToolPie::handleTooltipLand(std::string line, std::string tooltip_msg)
 {
-	LLViewerParcelMgr::getInstance()->setHoverParcel( mHoverPick.mPosGlobal );
-	// 
-	//  Do not show hover for land unless prefs are set to allow it.
-	// 
-	
+	//  Do not show hover for land unless prefs are set to allow it. 
 	if (!gSavedSettings.getBOOL("ShowLandHoverTip")) return TRUE; 
-	
+
+	LLViewerParcelMgr::getInstance()->setHoverParcel( mHoverPick.mPosGlobal );
+
 	// Didn't hit an object, but since we have a land point we
 	// must be hovering over land.
 	
-- 
cgit v1.2.3


From 803b75a718833ccf236f00b425faff4eaf0f29cb Mon Sep 17 00:00:00 2001
From: callum_linden <callum@lindenlab.com>
Date: Wed, 18 Oct 2017 18:36:10 -0700
Subject: First version that builds with a dummy BugSplay call in llapp.cpp

---
 autobuild.xml                      | 42 ++++++++++++++++++++++++++++++++++++++
 indra/cmake/Copy3rdPartyLibs.cmake |  3 +++
 indra/cmake/bugsplat.cmake         | 20 ++++++++++++++++++
 indra/llcommon/CMakeLists.txt      |  3 +++
 indra/llcommon/llapp.cpp           | 12 +++++++++++
 indra/newview/viewer_manifest.py   | 19 ++++++++++++-----
 6 files changed, 94 insertions(+), 5 deletions(-)
 create mode 100644 indra/cmake/bugsplat.cmake

diff --git a/autobuild.xml b/autobuild.xml
index f8daa6a418..e12f7cbc1d 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -225,6 +225,48 @@
         <key>version</key>
         <string>1.57</string>
       </map>
+      <key>bugsplat</key>
+      <map>
+        <key>copyright</key>
+        <string>Copyright 2003-2017, BugSplat</string>
+        <key>description</key>
+        <string>Bugsplat crash reporting package</string>
+        <key>license</key>
+        <string>Proprietary</string>
+        <key>license_file</key>
+        <string>LICENSES/BUGSPLAT_LICENSE.txt</string>
+        <key>name</key>
+        <string>bugsplat</string>
+        <key>platforms</key>
+        <map>
+          <key>windows</key>
+          <map>
+            <key>archive</key>
+            <map>
+              <key>hash</key>
+              <string>f01c3cbeeeedf9efaf111c7b51fc3e5b</string>
+              <key>url</key>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/9929/48024/bugsplat-3.5.0.5-windows-509917.tar.bz2</string>
+            </map>
+            <key>name</key>
+            <string>windows</string>
+          </map>
+          <key>windows64</key>
+          <map>
+            <key>archive</key>
+            <map>
+              <key>hash</key>
+              <string>6878c5ac26ee1a7b8126d1c9f052e059</string>
+              <key>url</key>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/9928/48018/bugsplat-3.5.0.5-windows64-509917.tar.bz2</string>
+            </map>
+            <key>name</key>
+            <string>windows64</string>
+          </map>
+        </map>
+        <key>version</key>
+        <string>3.5.0.5</string>
+      </map>
       <key>chardet</key>
       <map>
         <key>copyright</key>
diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake
index 5ccbe7d1d8..9238d232b8 100644
--- a/indra/cmake/Copy3rdPartyLibs.cmake
+++ b/indra/cmake/Copy3rdPartyLibs.cmake
@@ -39,6 +39,9 @@ if(WINDOWS)
         libeay32.dll
         glod.dll
         libhunspell.dll
+        BugSplat64.dll
+        BugSplatRc64.dll
+        BsSndRpt64.exe
         )
 
     if (FMODEX)
diff --git a/indra/cmake/bugsplat.cmake b/indra/cmake/bugsplat.cmake
new file mode 100644
index 0000000000..6805465023
--- /dev/null
+++ b/indra/cmake/bugsplat.cmake
@@ -0,0 +1,20 @@
+include(Prebuilt)
+
+set(BUGSPLAT_FIND_QUIETLY ON)
+set(BUGSPLAT_FIND_REQUIRED ON)
+
+if (USESYSTEMLIBS)
+  include(FindBUGSPLAT)
+else (USESYSTEMLIBS)
+  use_prebuilt_binary(bugsplat)
+  if (WINDOWS)
+    set(BUGSPLAT_LIBRARIES 
+      ${ARCH_PREBUILT_DIRS_RELEASE}/bugsplat64.lib
+      )
+  elseif (DARWIN)
+
+  else (WINDOWS)
+
+  endif (WINDOWS)
+  set(BUGSPLAT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/bugsplat)
+endif (USESYSTEMLIBS)
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index d9eb13d65a..50e262ae7a 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -13,6 +13,7 @@ include(GoogleBreakpad)
 include(Copy3rdPartyLibs)
 include(ZLIB)
 include(URIPARSER)
+include(BUGSPLAT)
 
 include_directories(
     ${EXPAT_INCLUDE_DIRS}
@@ -21,6 +22,7 @@ include_directories(
     ${ZLIB_INCLUDE_DIRS}
     ${BREAKPAD_INCLUDE_DIRECTORIES}
     ${URIPARSER_INCLUDE_DIRS}
+    ${BUGSPLAT_INCLUDE_DIR}
     )
 
 # add_executable(lltreeiterators lltreeiterators.cpp)
@@ -291,6 +293,7 @@ target_link_libraries(
     ${BOOST_SYSTEM_LIBRARY}
     ${GOOGLE_PERFTOOLS_LIBRARIES}
     ${URIPARSER_LIBRARIES}
+    ${BUGSPLAT_LIBRARIES}
     )
 
 if (DARWIN)
diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index 6cc9e804d4..9dd9fc3c70 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -50,6 +50,10 @@
 #include "stringize.h"
 #include "llcleanup.h"
 
+#include "BugSplat.h"
+
+MiniDmpSender *mpSender;
+
 //
 // Signal handling
 //
@@ -151,6 +155,14 @@ void LLApp::commonCtor()
 	// (this is used to avoid allocating memory in the crash handler)
 	memset(mMinidumpPath, 0, MAX_MINDUMP_PATH_LENGTH);
 	mCrashReportPipeStr = L"\\\\.\\pipe\\LLCrashReporterPipe";
+
+
+	static const wchar_t *bugdb_name = L"second_life_callum_test";
+	static const wchar_t *app_name = L"SecondLifeViewer";
+	static const wchar_t *app_version = L"1.0.0";
+	mpSender = new MiniDmpSender((const __wchar_t *)bugdb_name, (const __wchar_t *)app_name, (const __wchar_t *)app_version, NULL);
+
+
 }
 
 LLApp::LLApp(LLErrorThread *error_thread) :
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 71e348db3f..7292f715b7 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -448,6 +448,11 @@ class WindowsManifest(ViewerManifest):
             # Hunspell
             self.path("libhunspell.dll")
 
+            # BugSplat
+            self.path("BsSndRpt64.exe")
+            self.path("BugSplat64.dll")
+            self.path("BugSplatRc64.dll")
+
             # For google-perftools tcmalloc allocator.
             try:
                 if self.args['configuration'].lower() == 'debug':
@@ -457,7 +462,6 @@ class WindowsManifest(ViewerManifest):
             except:
                 print "Skipping libtcmalloc_minimal.dll"
 
-
         self.path(src="licenses-win32.txt", dst="licenses.txt")
         self.path("featuretable.txt")
         self.path("ca-bundle.crt")
@@ -571,10 +575,15 @@ class WindowsManifest(ViewerManifest):
             self.path("zh-CN.pak")
             self.path("zh-TW.pak")
 
-            with self.prefix(src=os.path.join(os.pardir, 'packages', 'bin', 'release'), dst="llplugin"):
-                self.path("libvlc.dll")
-                self.path("libvlccore.dll")
-                self.path("plugins/")
+        with self.prefix(src=os.path.join(os.pardir, 'packages', 'bin', 'release'), dst="llplugin"):
+            self.path("libvlc.dll")
+            self.path("libvlccore.dll")
+            self.path("plugins/")
+
+        with self.prefix(src=os.path.join(os.pardir, 'packages', 'lib', 'release'), dst=""):
+            self.path("BsSndRpt64.exe")
+            self.path("BugSplat64.dll")
+            self.path("BugSplatRc64.dll")
 
         # pull in the crash logger and updater from other projects
         # tag:"crash-logger" here as a cue to the exporter
-- 
cgit v1.2.3


From e75b16f3584b76df706a470395383abf680eb87f Mon Sep 17 00:00:00 2001
From: callum_linden <callum@lindenlab.com>
Date: Thu, 19 Oct 2017 11:34:36 -0700
Subject: First pass at adding BugSplat code to viewer and turning off existing
 (Google Breakpad) exception handling

---
 indra/llcommon/llapp.cpp | 76 +++++++++++++++++++++++++++++++++++++++---------
 indra/llcommon/llapp.h   | 10 ++++++-
 2 files changed, 72 insertions(+), 14 deletions(-)

diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index 9dd9fc3c70..ea4a0fb59c 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -49,10 +49,20 @@
 #include "google_breakpad/exception_handler.h"
 #include "stringize.h"
 #include "llcleanup.h"
-
 #include "BugSplat.h"
 
-MiniDmpSender *mpSender;
+// TESTING ONLY - REMOVE FOR PRODUCTION
+// (Want to only invoke BugSplat crash reporting in the same way we did for Breakpad - for Release viewers
+// but need to test here in a ReleaseWithDebugInfo environment)
+#if BUGSPLAT_ENABLED
+#define LL_SEND_CRASH_REPORTS 1
+#endif
+
+// BugSplat crash reporting tool - http://bugsplat.com
+#if BUGSPLAT_ENABLED
+bool BugSplatExceptionCallback(unsigned int nCode, void* lpVal1, void* lpVal2);
+MiniDmpSender *gBugSplatSender;
+#endif
 
 //
 // Signal handling
@@ -155,14 +165,6 @@ void LLApp::commonCtor()
 	// (this is used to avoid allocating memory in the crash handler)
 	memset(mMinidumpPath, 0, MAX_MINDUMP_PATH_LENGTH);
 	mCrashReportPipeStr = L"\\\\.\\pipe\\LLCrashReporterPipe";
-
-
-	static const wchar_t *bugdb_name = L"second_life_callum_test";
-	static const wchar_t *app_name = L"SecondLifeViewer";
-	static const wchar_t *app_version = L"1.0.0";
-	mpSender = new MiniDmpSender((const __wchar_t *)bugdb_name, (const __wchar_t *)app_name, (const __wchar_t *)app_version, NULL);
-
-
 }
 
 LLApp::LLApp(LLErrorThread *error_thread) :
@@ -397,6 +399,42 @@ void EnableCrashingOnCrashes()
 }
 #endif
 
+#if BUGSPLAT_ENABLED
+bool BugSplatExceptionCallback(unsigned int nCode, void* lpVal1, void* lpVal2)
+{
+	switch (nCode)
+	{
+		case MDSCB_EXCEPTIONCODE:
+		{
+			EXCEPTION_RECORD *p = (EXCEPTION_RECORD *)lpVal1;
+			DWORD code = p ? p->ExceptionCode : 0;
+
+			// create some files in the %temp% directory and attach them
+			wchar_t cmdString[2 * MAX_PATH];
+			wchar_t filePath[MAX_PATH];
+			wchar_t tempPath[MAX_PATH];
+			GetTempPathW(MAX_PATH, tempPath);
+
+			wsprintf(filePath, L"%sfile1.txt", tempPath);
+			wsprintf(cmdString, L"echo Exception Code = 0x%08x > %s", code, filePath);
+			_wsystem(cmdString);
+			gBugSplatSender->sendAdditionalFile((const __wchar_t *)filePath);
+
+			wsprintf(filePath, L"%sfile2.txt", tempPath);
+			wchar_t buf[_MAX_PATH];
+			gBugSplatSender->getMinidumpPath((__wchar_t *)buf, _MAX_PATH);
+
+			wsprintf(cmdString, L"echo Crash reporting is so clutch!  minidump path = %s > %s", buf, filePath);
+			_wsystem(cmdString);
+			gBugSplatSender->sendAdditionalFile((const __wchar_t *)filePath);
+		}
+		break;
+	}
+
+	return false;
+}
+#endif
+
 void LLApp::setupErrorHandling(bool second_instance)
 {
 	// Error handling is done by starting up an error handling thread, which just sleeps and
@@ -405,6 +443,17 @@ void LLApp::setupErrorHandling(bool second_instance)
 #if LL_WINDOWS
 
 #if LL_SEND_CRASH_REPORTS
+
+#if BUGSPLAT_ENABLED
+	// TODOCP: populate these fields correctly
+	static const wchar_t *bugdb_name = L"second_life_callum_test";
+	static const wchar_t *app_name = L"SecondLifeViewer";
+	static const wchar_t *app_version = L"1.0.0";
+	gBugSplatSender = new MiniDmpSender((const __wchar_t *)bugdb_name, (const __wchar_t *)app_name, (const __wchar_t *)app_version, NULL);
+
+	gBugSplatSender->setCallback(BugSplatExceptionCallback);
+#else
+
 	EnableCrashingOnCrashes();
 
 	// This sets a callback to handle w32 signals to the console window.
@@ -466,8 +515,9 @@ void LLApp::setupErrorHandling(bool second_instance)
 			mExceptionHandler->set_handle_debug_exceptions(true);
 		}
 	}
-#endif
-#else
+#endif  // BUGSPLAT_ENABLED
+#endif	// LL_SEND_CRASH_REPORTS
+#else	// not LL_WINDOWS
 	//
 	// Start up signal handling.
 	//
@@ -528,7 +578,7 @@ void LLApp::setupErrorHandling(bool second_instance)
 	}
 #endif
 
-#endif
+#endif // LL_WINDOWS
 	startErrorThread();
 }
 
diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h
index acd829d864..5a4b7f13df 100644
--- a/indra/llcommon/llapp.h
+++ b/indra/llcommon/llapp.h
@@ -30,6 +30,7 @@
 #include <map>
 #include "llrun.h"
 #include "llsd.h"
+
 // Forward declarations
 template <typename Type> class LLAtomic32;
 typedef LLAtomic32<U32> LLAtomicU32;
@@ -39,6 +40,14 @@ class LLLiveFile;
 #include <signal.h>
 #endif
 
+// first version of Bugsplat (http://bugsplat.com) crash reporting tool
+// is only supported on Windows - macOS to follow.
+#define BUGSPLAT_ENABLED LL_WINDOWS
+
+#if BUGSPLAT_ENABLED
+class __declspec(dllexport) MiniDmpSender;
+#endif
+
 typedef void (*LLAppErrorHandler)();
 
 #if !LL_WINDOWS
@@ -316,7 +325,6 @@ private:
 	
 	google_breakpad::ExceptionHandler * mExceptionHandler;
 
-
 #if !LL_WINDOWS
 	friend void default_unix_signal_handler(int signum, siginfo_t *info, void *);
 #endif
-- 
cgit v1.2.3


From 6cbb00fe85df8cb01c3a979dbdf2c0354e7bfa4d Mon Sep 17 00:00:00 2001
From: callum_linden <callum@lindenlab.com>
Date: Thu, 19 Oct 2017 18:35:00 -0700
Subject: Differentiate between 32/64 bit windows builds for build systewm
 (BugsSplat enforces specifc names that vary across bitness)

---
 autobuild.xml                    |  8 ++++----
 indra/cmake/bugsplat.cmake       |  2 +-
 indra/newview/viewer_manifest.py | 16 ++++++++--------
 3 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index e12f7cbc1d..ee052de5e6 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -244,9 +244,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>f01c3cbeeeedf9efaf111c7b51fc3e5b</string>
+              <string>2710e051eb1b12dba574f470834baa9e</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/9929/48024/bugsplat-3.5.0.5-windows-509917.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/9992/49191/bugsplat-3.5.0.5-windows-509980.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -256,9 +256,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>6878c5ac26ee1a7b8126d1c9f052e059</string>
+              <string>f2bb37c69f35522e49aae547d3408fd8</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/9928/48018/bugsplat-3.5.0.5-windows64-509917.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/9991/49185/bugsplat-3.5.0.5-windows64-509980.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
diff --git a/indra/cmake/bugsplat.cmake b/indra/cmake/bugsplat.cmake
index 6805465023..e993979902 100644
--- a/indra/cmake/bugsplat.cmake
+++ b/indra/cmake/bugsplat.cmake
@@ -9,7 +9,7 @@ else (USESYSTEMLIBS)
   use_prebuilt_binary(bugsplat)
   if (WINDOWS)
     set(BUGSPLAT_LIBRARIES 
-      ${ARCH_PREBUILT_DIRS_RELEASE}/bugsplat64.lib
+      ${ARCH_PREBUILT_DIRS_RELEASE}/bugsplat.lib
       )
   elseif (DARWIN)
 
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 7292f715b7..4e69597b61 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -449,9 +449,14 @@ class WindowsManifest(ViewerManifest):
             self.path("libhunspell.dll")
 
             # BugSplat
-            self.path("BsSndRpt64.exe")
-            self.path("BugSplat64.dll")
-            self.path("BugSplatRc64.dll")
+            if(self.address_size == 64):
+                self.path("BsSndRpt64.exe")
+                self.path("BugSplat64.dll")
+                self.path("BugSplatRc64.dll")
+            else:
+                self.path("BsSndRpt.exe")
+                self.path("BugSplat.dll")
+                self.path("BugSplatRc.dll")
 
             # For google-perftools tcmalloc allocator.
             try:
@@ -580,11 +585,6 @@ class WindowsManifest(ViewerManifest):
             self.path("libvlccore.dll")
             self.path("plugins/")
 
-        with self.prefix(src=os.path.join(os.pardir, 'packages', 'lib', 'release'), dst=""):
-            self.path("BsSndRpt64.exe")
-            self.path("BugSplat64.dll")
-            self.path("BugSplatRc64.dll")
-
         # pull in the crash logger and updater from other projects
         # tag:"crash-logger" here as a cue to the exporter
         self.path(src='../win_crash_logger/%s/windows-crash-logger.exe' % self.args['configuration'],
-- 
cgit v1.2.3


From 0ee774c39f3c689f998dae19d04af11981abd684 Mon Sep 17 00:00:00 2001
From: callum_linden <callum@lindenlab.com>
Date: Mon, 23 Oct 2017 11:37:06 -0700
Subject: Missed a place in the Copy3rdPartyLibs.cmake file (thank Windows
 Find) that needs to differentiate between 32 and 64 bit Windows builds

---
 indra/cmake/Copy3rdPartyLibs.cmake | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake
index 9238d232b8..eaf1e31fce 100644
--- a/indra/cmake/Copy3rdPartyLibs.cmake
+++ b/indra/cmake/Copy3rdPartyLibs.cmake
@@ -39,11 +39,20 @@ if(WINDOWS)
         libeay32.dll
         glod.dll
         libhunspell.dll
-        BugSplat64.dll
-        BugSplatRc64.dll
-        BsSndRpt64.exe
         )
 
+    # Filenames are different for 32/64 bit BugSplat file and we don't
+    # have any control over them so need to branch.
+    if(ADDRESS_SIZE EQUAL 32)
+        set(release_files ${release_files} BugSplat.dll)
+        set(release_files ${release_files} BugSplatRc.dll)
+        set(release_files ${release_files} BsSndRpt.exe)
+    else(ADDRESS_SIZE EQUAL 32)
+        set(release_files ${release_files} BugSplat64.dll)
+        set(release_files ${release_files} BugSplatRc64.dll)
+        set(release_files ${release_files} BsSndRpt64.exe)
+    endif(ADDRESS_SIZE EQUAL 32)
+
     if (FMODEX)
 
         if(ADDRESS_SIZE EQUAL 32)
-- 
cgit v1.2.3


From d359dca06518d778c0f115afec8c759ca026de47 Mon Sep 17 00:00:00 2001
From: callum_linden <callum@lindenlab.com>
Date: Tue, 24 Oct 2017 14:28:43 -0700
Subject: painfully add in the path to the second life log file that we also
 send - painful because of string <--> wstring issues

---
 indra/llcommon/llapp.cpp | 26 +++++---------------------
 1 file changed, 5 insertions(+), 21 deletions(-)

diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index ea4a0fb59c..6ea1700ea8 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -406,27 +406,11 @@ bool BugSplatExceptionCallback(unsigned int nCode, void* lpVal1, void* lpVal2)
 	{
 		case MDSCB_EXCEPTIONCODE:
 		{
-			EXCEPTION_RECORD *p = (EXCEPTION_RECORD *)lpVal1;
-			DWORD code = p ? p->ExceptionCode : 0;
-
-			// create some files in the %temp% directory and attach them
-			wchar_t cmdString[2 * MAX_PATH];
-			wchar_t filePath[MAX_PATH];
-			wchar_t tempPath[MAX_PATH];
-			GetTempPathW(MAX_PATH, tempPath);
-
-			wsprintf(filePath, L"%sfile1.txt", tempPath);
-			wsprintf(cmdString, L"echo Exception Code = 0x%08x > %s", code, filePath);
-			_wsystem(cmdString);
-			gBugSplatSender->sendAdditionalFile((const __wchar_t *)filePath);
-
-			wsprintf(filePath, L"%sfile2.txt", tempPath);
-			wchar_t buf[_MAX_PATH];
-			gBugSplatSender->getMinidumpPath((__wchar_t *)buf, _MAX_PATH);
-
-			wsprintf(cmdString, L"echo Crash reporting is so clutch!  minidump path = %s > %s", buf, filePath);
-			_wsystem(cmdString);
-			gBugSplatSender->sendAdditionalFile((const __wchar_t *)filePath);
+			// send the main viewer log file (Clearly a temporary hack since we don't have access to the gDir*** set of functions in newview
+			const std::string appdata = std::string(getenv("APPDATA"));
+			const std::string logfile = appdata + "\\SecondLife\\logs\\Secondlife.log";
+			const std::wstring wide_logfile(logfile.begin(), logfile.end());
+			gBugSplatSender->sendAdditionalFile((const __wchar_t *)wide_logfile.c_str());
 		}
 		break;
 	}
-- 
cgit v1.2.3


From 2e3c5ac88a434ee437bc3e68b321d5bd0bcd7cc9 Mon Sep 17 00:00:00 2001
From: callum_linden <callum@lindenlab.com>
Date: Tue, 24 Oct 2017 16:13:23 -0700
Subject: Add in real SL viewer name and version

---
 indra/llcommon/CMakeLists.txt | 10 +++++++++-
 indra/llcommon/llapp.cpp      | 14 +++++++++++---
 2 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 50e262ae7a..9c5481a977 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -14,6 +14,7 @@ include(Copy3rdPartyLibs)
 include(ZLIB)
 include(URIPARSER)
 include(BUGSPLAT)
+include(BuildVersion)
 
 include_directories(
     ${EXPAT_INCLUDE_DIRS}
@@ -255,7 +256,14 @@ set(llcommon_HEADER_FILES
     )
 
 set_source_files_properties(${llcommon_HEADER_FILES}
-                            PROPERTIES HEADER_FILE_ONLY TRUE)
+                            PROPERTIES HEADER_FILE_ONLY TRUE
+							)
+
+# bring in version information for BugSplat crash reporting
+set_source_files_properties(${llcommon_SOURCE_FILES}
+                            PROPERTIES
+							COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}" # see BuildVersion.cmake
+							)
 
 list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES})
 
diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index 6ea1700ea8..3e652dbdb5 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -431,9 +431,17 @@ void LLApp::setupErrorHandling(bool second_instance)
 #if BUGSPLAT_ENABLED
 	// TODOCP: populate these fields correctly
 	static const wchar_t *bugdb_name = L"second_life_callum_test";
-	static const wchar_t *app_name = L"SecondLifeViewer";
-	static const wchar_t *app_version = L"1.0.0";
-	gBugSplatSender = new MiniDmpSender((const __wchar_t *)bugdb_name, (const __wchar_t *)app_name, (const __wchar_t *)app_version, NULL);
+
+	// build (painfully) the app/channel name
+	#define stringize_inner(x) L#x
+	#define stringize_outer(x) stringize_inner(x)
+	std::wstring app_name(stringize_outer(LL_VIEWER_CHANNEL));
+
+	// build in real app version now we leveraged CMake to build in BuildVersion.cmake into LLCommon
+	wchar_t version_string[MAX_STRING];
+	wsprintf(version_string, L"%d.%d.%d.%d", LL_VIEWER_VERSION_MAJOR, LL_VIEWER_VERSION_MINOR, LL_VIEWER_VERSION_PATCH, LL_VIEWER_VERSION_BUILD);
+
+	gBugSplatSender = new MiniDmpSender((const __wchar_t *)bugdb_name, (const __wchar_t *)app_name.c_str(), (const __wchar_t *)version_string, NULL);
 
 	gBugSplatSender->setCallback(BugSplatExceptionCallback);
 #else
-- 
cgit v1.2.3


From 508e754eb4501b9c3fbfbfde52ca7ae8ed0f06b7 Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Thu, 14 Dec 2017 18:12:22 -0500
Subject: fix tab character coding style violation

---
 indra/llcommon/CMakeLists.txt | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 9c5481a977..c8e44d7ba4 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -257,13 +257,13 @@ set(llcommon_HEADER_FILES
 
 set_source_files_properties(${llcommon_HEADER_FILES}
                             PROPERTIES HEADER_FILE_ONLY TRUE
-							)
+                            )
 
 # bring in version information for BugSplat crash reporting
 set_source_files_properties(${llcommon_SOURCE_FILES}
                             PROPERTIES
-							COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}" # see BuildVersion.cmake
-							)
+                            COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}" # see BuildVersion.cmake
+                            )
 
 list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES})
 
-- 
cgit v1.2.3


From 2fb39cb45f9ef502e9ea23df096fa5b3f2f806fa Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 10 May 2018 15:05:55 -0400
Subject: SL-821: Update to bugsplat build 515327

---
 autobuild.xml | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 75b19709bc..25bc8d8af9 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -239,14 +239,26 @@
         <string>bugsplat</string>
         <key>platforms</key>
         <map>
+          <key>darwin64</key>
+          <map>
+            <key>archive</key>
+            <map>
+              <key>hash</key>
+              <string>9a14b64569c998fb7ef6e3bb690eda29</string>
+              <key>url</key>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/17916/122458/bugsplat-1.0.2.515327-darwin64-515327.tar.bz2</string>
+            </map>
+            <key>name</key>
+            <string>darwin64</string>
+          </map>
           <key>windows</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>2710e051eb1b12dba574f470834baa9e</string>
+              <string>90d85d1ac17f0049c8c48110e790a61f</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/9992/49191/bugsplat-3.5.0.5-windows-509980.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/17918/122472/bugsplat-3.5.0.5.515327-windows-515327.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -256,16 +268,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>f2bb37c69f35522e49aae547d3408fd8</string>
+              <string>9af7c080ebf0b961d7a4ccac7a303508</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/9991/49185/bugsplat-3.5.0.5-windows64-509980.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/17917/122466/bugsplat-3.5.0.5.515327-windows64-515327.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>3.5.0.5</string>
+        <string>1.0.2.515327</string>
       </map>
       <key>chardet</key>
       <map>
-- 
cgit v1.2.3


From 3de5bab17459ed5bf0494d7bd2a531c473e20b7e Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 11 May 2018 16:00:20 -0400
Subject: SL-821: Move BugSplat includes/libs from llcommon to newview.

No C++ source in llcommon references any of the BugSplat code.
---
 indra/llcommon/CMakeLists.txt | 3 ---
 indra/newview/CMakeLists.txt  | 3 +++
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index c8e44d7ba4..4eba1d5451 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -13,7 +13,6 @@ include(GoogleBreakpad)
 include(Copy3rdPartyLibs)
 include(ZLIB)
 include(URIPARSER)
-include(BUGSPLAT)
 include(BuildVersion)
 
 include_directories(
@@ -23,7 +22,6 @@ include_directories(
     ${ZLIB_INCLUDE_DIRS}
     ${BREAKPAD_INCLUDE_DIRECTORIES}
     ${URIPARSER_INCLUDE_DIRS}
-    ${BUGSPLAT_INCLUDE_DIR}
     )
 
 # add_executable(lltreeiterators lltreeiterators.cpp)
@@ -301,7 +299,6 @@ target_link_libraries(
     ${BOOST_SYSTEM_LIBRARY}
     ${GOOGLE_PERFTOOLS_LIBRARIES}
     ${URIPARSER_LIBRARIES}
-    ${BUGSPLAT_LIBRARIES}
     )
 
 if (DARWIN)
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 6b16713add..1fd0af0558 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -4,6 +4,7 @@ project(viewer)
 
 include(00-Common)
 include(Boost)
+include(bugsplat)
 include(BuildPackagesInfo)
 include(BuildVersion)
 include(CMakeCopyIfDifferent)
@@ -91,6 +92,7 @@ include_directories(
     ${LIBS_PREBUILT_DIR}/include/collada/1.4
     ${LLAPPEARANCE_INCLUDE_DIRS}
     ${CMAKE_CURRENT_SOURCE_DIR}
+    ${BUGSPLAT_INCLUDE_DIR}
     )
 
 include_directories(SYSTEM
@@ -1976,6 +1978,7 @@ target_link_libraries(${VIEWER_BINARY_NAME}
     ${LLPHYSICS_LIBRARIES}
     ${LLPHYSICSEXTENSIONS_LIBRARIES}
     ${LLAPPEARANCE_LIBRARIES}
+    ${BUGSPLAT_LIBRARIES}
     )
 
 set(ARTWORK_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE PATH
-- 
cgit v1.2.3


From 78b8a0c3e44d7ae0931da7ea6064a12bd3d77b8c Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 11 May 2018 17:04:24 -0400
Subject: SL-821: Use one self.path() call for everything under "llplugin".

---
 indra/newview/viewer_manifest.py | 195 ++++++++++++++++++++-------------------
 1 file changed, 98 insertions(+), 97 deletions(-)

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 437769726d..3375d4e071 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -605,103 +605,104 @@ class WindowsManifest(ViewerManifest):
         self.path("ca-bundle.crt")
 
         # Media plugins - CEF
-        with self.prefix(src='../media_plugins/cef/%s' % self.args['configuration'], dst="llplugin"):
-            self.path("media_plugin_cef.dll")
-
-        # Media plugins - LibVLC
-        with self.prefix(src='../media_plugins/libvlc/%s' % self.args['configuration'], dst="llplugin"):
-            self.path("media_plugin_libvlc.dll")
-
-        # Media plugins - Example (useful for debugging - not shipped with release viewer)
-        if self.channel_type() != 'release':
-            with self.prefix(src='../media_plugins/example/%s' % self.args['configuration'], dst="llplugin"):
-                self.path("media_plugin_example.dll")
-
-        # CEF runtime files - debug
-        # CEF runtime files - not debug (release, relwithdebinfo etc.)
-        config = 'debug' if self.args['configuration'].lower() == 'debug' else 'release'
-        with self.prefix(src=os.path.join(pkgdir, 'bin', config), dst="llplugin"):
-            self.path("chrome_elf.dll")
-            self.path("d3dcompiler_43.dll")
-            self.path("d3dcompiler_47.dll")
-            self.path("libcef.dll")
-            self.path("libEGL.dll")
-            self.path("libGLESv2.dll")
-            self.path("dullahan_host.exe")
-            self.path("natives_blob.bin")
-            self.path("snapshot_blob.bin")
-            self.path("widevinecdmadapter.dll")
-
-        # MSVC DLLs needed for CEF and have to be in same directory as plugin
-        with self.prefix(src=os.path.join(os.pardir, 'sharedlibs', 'Release'), dst="llplugin"):
-            self.path("msvcp120.dll")
-            self.path("msvcr120.dll")
-
-        # CEF files common to all configurations
-        with self.prefix(src=os.path.join(pkgdir, 'resources'), dst="llplugin"):
-            self.path("cef.pak")
-            self.path("cef_100_percent.pak")
-            self.path("cef_200_percent.pak")
-            self.path("cef_extensions.pak")
-            self.path("devtools_resources.pak")
-            self.path("icudtl.dat")
-
-        with self.prefix(src=os.path.join(pkgdir, 'resources', 'locales'), dst=os.path.join('llplugin', 'locales')):
-            self.path("am.pak")
-            self.path("ar.pak")
-            self.path("bg.pak")
-            self.path("bn.pak")
-            self.path("ca.pak")
-            self.path("cs.pak")
-            self.path("da.pak")
-            self.path("de.pak")
-            self.path("el.pak")
-            self.path("en-GB.pak")
-            self.path("en-US.pak")
-            self.path("es-419.pak")
-            self.path("es.pak")
-            self.path("et.pak")
-            self.path("fa.pak")
-            self.path("fi.pak")
-            self.path("fil.pak")
-            self.path("fr.pak")
-            self.path("gu.pak")
-            self.path("he.pak")
-            self.path("hi.pak")
-            self.path("hr.pak")
-            self.path("hu.pak")
-            self.path("id.pak")
-            self.path("it.pak")
-            self.path("ja.pak")
-            self.path("kn.pak")
-            self.path("ko.pak")
-            self.path("lt.pak")
-            self.path("lv.pak")
-            self.path("ml.pak")
-            self.path("mr.pak")
-            self.path("ms.pak")
-            self.path("nb.pak")
-            self.path("nl.pak")
-            self.path("pl.pak")
-            self.path("pt-BR.pak")
-            self.path("pt-PT.pak")
-            self.path("ro.pak")
-            self.path("ru.pak")
-            self.path("sk.pak")
-            self.path("sl.pak")
-            self.path("sr.pak")
-            self.path("sv.pak")
-            self.path("sw.pak")
-            self.path("ta.pak")
-            self.path("te.pak")
-            self.path("th.pak")
-            self.path("tr.pak")
-            self.path("uk.pak")
-            self.path("vi.pak")
-            self.path("zh-CN.pak")
-            self.path("zh-TW.pak")
-
-            with self.prefix(src=os.path.join(pkgdir, 'bin', 'release'), dst="llplugin"):
+        with self.prefix(dst="llplugin"):
+            with self.prefix(src='../media_plugins/cef/%s' % self.args['configuration']):
+                self.path("media_plugin_cef.dll")
+
+            # Media plugins - LibVLC
+            with self.prefix(src='../media_plugins/libvlc/%s' % self.args['configuration']):
+                self.path("media_plugin_libvlc.dll")
+
+            # Media plugins - Example (useful for debugging - not shipped with release viewer)
+            if self.channel_type() != 'release':
+                with self.prefix(src='../media_plugins/example/%s' % self.args['configuration']):
+                    self.path("media_plugin_example.dll")
+
+            # CEF runtime files - debug
+            # CEF runtime files - not debug (release, relwithdebinfo etc.)
+            config = 'debug' if self.args['configuration'].lower() == 'debug' else 'release'
+            with self.prefix(src=os.path.join(pkgdir, 'bin', config)):
+                self.path("chrome_elf.dll")
+                self.path("d3dcompiler_43.dll")
+                self.path("d3dcompiler_47.dll")
+                self.path("libcef.dll")
+                self.path("libEGL.dll")
+                self.path("libGLESv2.dll")
+                self.path("dullahan_host.exe")
+                self.path("natives_blob.bin")
+                self.path("snapshot_blob.bin")
+                self.path("widevinecdmadapter.dll")
+
+            # MSVC DLLs needed for CEF and have to be in same directory as plugin
+            with self.prefix(src=os.path.join(os.pardir, 'sharedlibs', 'Release')):
+                self.path("msvcp120.dll")
+                self.path("msvcr120.dll")
+
+            # CEF files common to all configurations
+            with self.prefix(src=os.path.join(pkgdir, 'resources')):
+                self.path("cef.pak")
+                self.path("cef_100_percent.pak")
+                self.path("cef_200_percent.pak")
+                self.path("cef_extensions.pak")
+                self.path("devtools_resources.pak")
+                self.path("icudtl.dat")
+
+            with self.prefix(src=os.path.join(pkgdir, 'resources', 'locales'), dst='locales'):
+                self.path("am.pak")
+                self.path("ar.pak")
+                self.path("bg.pak")
+                self.path("bn.pak")
+                self.path("ca.pak")
+                self.path("cs.pak")
+                self.path("da.pak")
+                self.path("de.pak")
+                self.path("el.pak")
+                self.path("en-GB.pak")
+                self.path("en-US.pak")
+                self.path("es-419.pak")
+                self.path("es.pak")
+                self.path("et.pak")
+                self.path("fa.pak")
+                self.path("fi.pak")
+                self.path("fil.pak")
+                self.path("fr.pak")
+                self.path("gu.pak")
+                self.path("he.pak")
+                self.path("hi.pak")
+                self.path("hr.pak")
+                self.path("hu.pak")
+                self.path("id.pak")
+                self.path("it.pak")
+                self.path("ja.pak")
+                self.path("kn.pak")
+                self.path("ko.pak")
+                self.path("lt.pak")
+                self.path("lv.pak")
+                self.path("ml.pak")
+                self.path("mr.pak")
+                self.path("ms.pak")
+                self.path("nb.pak")
+                self.path("nl.pak")
+                self.path("pl.pak")
+                self.path("pt-BR.pak")
+                self.path("pt-PT.pak")
+                self.path("ro.pak")
+                self.path("ru.pak")
+                self.path("sk.pak")
+                self.path("sl.pak")
+                self.path("sr.pak")
+                self.path("sv.pak")
+                self.path("sw.pak")
+                self.path("ta.pak")
+                self.path("te.pak")
+                self.path("th.pak")
+                self.path("tr.pak")
+                self.path("uk.pak")
+                self.path("vi.pak")
+                self.path("zh-CN.pak")
+                self.path("zh-TW.pak")
+
+            with self.prefix(src=os.path.join(pkgdir, 'bin', 'release')):
                 self.path("libvlc.dll")
                 self.path("libvlccore.dll")
                 self.path("plugins/")
-- 
cgit v1.2.3


From ed891c60de4169fa8ef4cc19e953e389cc4df60e Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 17 May 2018 05:33:14 -0400
Subject: SL-821: Add LL_TO_WSTRING() macro to llpreprocessor.h.

Also use existing LL_TO_STRING() macro to stringize LL_VIEWER_CHANNEL in
llversioninfo.cpp and its tests.
---
 indra/llcommon/llpreprocessor.h            | 2 ++
 indra/newview/llversioninfo.cpp            | 7 ++-----
 indra/newview/tests/llversioninfo_test.cpp | 6 ++----
 3 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h
index 2879038c36..ef015fdce4 100644
--- a/indra/llcommon/llpreprocessor.h
+++ b/indra/llcommon/llpreprocessor.h
@@ -198,6 +198,8 @@
 
 #define LL_TO_STRING_HELPER(x) #x
 #define LL_TO_STRING(x) LL_TO_STRING_HELPER(x)
+#define LL_TO_WSTRING_HELPER(x) L#x
+#define LL_TO_WSTRING(x) LL_TO_WSTRING_HELPER(x)
 #define LL_FILE_LINENO_MSG(msg) __FILE__ "(" LL_TO_STRING(__LINE__) ") : " msg
 #define LL_GLUE_IMPL(x, y) x##y
 #define LL_GLUE_TOKENS(x, y) LL_GLUE_IMPL(x, y)
diff --git a/indra/newview/llversioninfo.cpp b/indra/newview/llversioninfo.cpp
index 375dce485d..4e07223784 100644
--- a/indra/newview/llversioninfo.cpp
+++ b/indra/newview/llversioninfo.cpp
@@ -101,14 +101,11 @@ namespace
 {
 	// LL_VIEWER_CHANNEL is a macro defined on the compiler command line. The
 	// macro expands to the string name of the channel, but without quotes. We
-	// need to turn it into a quoted string. This macro trick does that.
-#define stringize_inner(x) #x
-#define stringize_outer(x) stringize_inner(x)
-
+	// need to turn it into a quoted string. LL_TO_STRING() does that.
 	/// Storage of the channel name the viewer is using.
 	//  The channel name is set by hardcoded constant, 
 	//  or by calling LLVersionInfo::resetChannel()
-	std::string sWorkingChannelName(stringize_outer(LL_VIEWER_CHANNEL));
+	std::string sWorkingChannelName(LL_TO_STRING(LL_VIEWER_CHANNEL));
 
 	// Storage for the "version and channel" string.
 	// This will get reset too.
diff --git a/indra/newview/tests/llversioninfo_test.cpp b/indra/newview/tests/llversioninfo_test.cpp
index 2f7a4e9601..58f0469552 100644
--- a/indra/newview/tests/llversioninfo_test.cpp
+++ b/indra/newview/tests/llversioninfo_test.cpp
@@ -33,10 +33,8 @@
 
 // LL_VIEWER_CHANNEL is a macro defined on the compiler command line. The
 // macro expands to the string name of the channel, but without quotes. We
-// need to turn it into a quoted string. This macro trick does that.
-#define stringize_inner(x) #x
-#define stringize_outer(x) stringize_inner(x)
-#define ll_viewer_channel stringize_outer(LL_VIEWER_CHANNEL)
+// need to turn it into a quoted string. LL_TO_STRING() does that.
+#define ll_viewer_channel LL_TO_STRING(LL_VIEWER_CHANNEL)
 
 namespace tut
 {
-- 
cgit v1.2.3


From c09d9c12e79fde83a87b2394c88b32e568271eda Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 17 May 2018 05:45:36 -0400
Subject: SL-821: Add WSTRINGIZE() and DEWSTRINGIZE() macros for wide strings.

Streamline convenience overload stringize(std::wstring); make convenience
overload wstringize(std::string) symmetrically convert from UTF-8 string.

Also eliminate STRINGIZE() et al. dependency on Boost.Phoenix: use lambdas
instead.

Using lambdas instead of template expansion necessitates reordering some code
in wrapllerrs.h.
---
 indra/llcommon/stringize.h        | 52 ++++++++++++++++++++++-----------------
 indra/llcommon/tests/wrapllerrs.h | 14 +++++------
 2 files changed, 36 insertions(+), 30 deletions(-)

diff --git a/indra/llcommon/stringize.h b/indra/llcommon/stringize.h
index a5a90d7297..38dd198ad3 100644
--- a/indra/llcommon/stringize.h
+++ b/indra/llcommon/stringize.h
@@ -30,7 +30,6 @@
 #define LL_STRINGIZE_H
 
 #include <sstream>
-#include <boost/phoenix/phoenix.hpp>
 #include <llstring.h>
 
 /**
@@ -53,12 +52,7 @@ std::basic_string<CHARTYPE> gstringize(const T& item)
  */
 inline std::string stringize(const std::wstring& item)
 {
-    LL_WARNS() << "WARNING:  Possible narrowing" << LL_ENDL;
-    
-    std::string s;
-    
-    s = wstring_to_utf8str(item);
-    return gstringize<char>(s);
+    return wstring_to_utf8str(item);
 }
 
 /**
@@ -76,7 +70,10 @@ std::string stringize(const T& item)
  */
 inline std::wstring wstringize(const std::string& item)
 {
-    return gstringize<wchar_t>(item.c_str());
+    // utf8str_to_wstring() returns LLWString, which isn't necessarily the
+    // same as std::wstring
+    LLWString s(utf8str_to_wstring(item));
+    return std::wstring(s.begin(), s.end());
 }
 
 /**
@@ -91,10 +88,10 @@ std::wstring wstringize(const T& item)
 /**
  * stringize_f(functor)
  */
-template <typename Functor>
-std::string stringize_f(Functor const & f)
+template <typename CHARTYPE, typename Functor>
+std::basic_string<CHARTYPE> stringize_f(Functor const & f)
 {
-    std::ostringstream out;
+    std::basic_ostringstream<CHARTYPE> out;
     f(out);
     return out.str();
 }
@@ -108,31 +105,37 @@ std::string stringize_f(Functor const & f)
  * return out.str();
  * @endcode
  */
-#define STRINGIZE(EXPRESSION) (stringize_f(boost::phoenix::placeholders::arg1 << EXPRESSION))
+#define STRINGIZE(EXPRESSION) (stringize_f<char>([&](std::ostream& out){ out << EXPRESSION; }))
 
+/**
+ * WSTRINGIZE() is the wstring equivalent of STRINGIZE()
+ */
+#define WSTRINGIZE(EXPRESSION) (stringize_f<wchar_t>([&](std::wostream& out){ out << EXPRESSION; }))
 
 /**
  * destringize(str)
  * defined for symmetry with stringize
- * *NOTE - this has distinct behavior from boost::lexical_cast<T> regarding
+ * @NOTE - this has distinct behavior from boost::lexical_cast<T> regarding
  * leading/trailing whitespace and handling of bad_lexical_cast exceptions
+ * @NOTE - no need for dewstringize(), since passing std::wstring will Do The
+ * Right Thing
  */
-template <typename T>
-T destringize(std::string const & str)
+template <typename T, typename CHARTYPE>
+T destringize(std::basic_string<CHARTYPE> const & str)
 {
-	T val;
-    std::istringstream in(str);
-	in >> val;
+    T val;
+    std::basic_istringstream<CHARTYPE> in(str);
+    in >> val;
     return val;
 }
 
 /**
  * destringize_f(str, functor)
  */
-template <typename Functor>
-void destringize_f(std::string const & str, Functor const & f)
+template <typename CHARTYPE, typename Functor>
+void destringize_f(std::basic_string<CHARTYPE> const & str, Functor const & f)
 {
-    std::istringstream in(str);
+    std::basic_istringstream<CHARTYPE> in(str);
     f(in);
 }
 
@@ -143,8 +146,11 @@ void destringize_f(std::string const & str, Functor const & f)
  * std::istringstream in(str);
  * in >> item1 >> item2 >> item3 ... ;
  * @endcode
+ * @NOTE - once we get generic lambdas, we shouldn't need DEWSTRINGIZE() any
+ * more since DESTRINGIZE() should do the right thing with a std::wstring. But
+ * until then, the lambda we pass must accept the right std::basic_istream.
  */
-#define DESTRINGIZE(STR, EXPRESSION) (destringize_f((STR), (boost::phoenix::placeholders::arg1 >> EXPRESSION)))
-
+#define DESTRINGIZE(STR, EXPRESSION) (destringize_f((STR), [&](std::istream& in){in >> EXPRESSION;}))
+#define DEWSTRINGIZE(STR, EXPRESSION) (destringize_f((STR), [&](std::wistream& in){in >> EXPRESSION;}))
 
 #endif /* ! defined(LL_STRINGIZE_H) */
diff --git a/indra/llcommon/tests/wrapllerrs.h b/indra/llcommon/tests/wrapllerrs.h
index 9a4bbbd630..08fbf19b1c 100644
--- a/indra/llcommon/tests/wrapllerrs.h
+++ b/indra/llcommon/tests/wrapllerrs.h
@@ -109,6 +109,12 @@ public:
         mMessages.push_back(message);
     }
 
+    friend inline
+    std::ostream& operator<<(std::ostream& out, const CaptureLogRecorder& log)
+    {
+        return log.streamto(out);
+    }
+
     /// Don't assume the message we want is necessarily the LAST log message
     /// emitted by the underlying code; search backwards through all messages
     /// for the sought string.
@@ -126,7 +132,7 @@ public:
 
         throw tut::failure(STRINGIZE("failed to find '" << search
                                      << "' in captured log messages:\n"
-                                     << boost::ref(*this)));
+                                     << *this));
     }
 
     std::ostream& streamto(std::ostream& out) const
@@ -200,10 +206,4 @@ private:
 	LLError::RecorderPtr mRecorder;
 };
 
-inline
-std::ostream& operator<<(std::ostream& out, const CaptureLogRecorder& log)
-{
-    return log.streamto(out);
-}
-
 #endif /* ! defined(LL_WRAPLLERRS_H) */
-- 
cgit v1.2.3


From c5f618d096f05bdff91a5d384c46e26840f5a771 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 17 May 2018 06:53:42 -0400
Subject: SL-821: Move Windows BugSplat engagement from llcommon to newview.

Use WSTRINGIZE(), LL_TO_WSTRING(), wstringize() to produce required wide
strings. Use a lambda for callback that sends log file; use LLDir, if set, to
find the log file.

Introduce BUGSPLAT CMake variable to allow suppressing BugSplat.
Make BUGSPLAT CMake variable set LL_BUGSPLAT for C++ compilations.

Set viewer version macros on llappviewerwin32.cpp, llappviewerlinux.cpp and
llappdelegate-objc.mm -- because BugSplat needs the viewer version data, and
because the macOS BugSplat hook is engaged in an Objective-C++ function we
override in the app delegate.
---
 indra/cmake/CMakeLists.txt         |  1 +
 indra/cmake/bugsplat.cmake         | 46 +++++++++++++++++------------
 indra/llcommon/CMakeLists.txt      | 10 +------
 indra/llcommon/llapp.cpp           | 60 ++------------------------------------
 indra/llcommon/llapp.h             | 10 +------
 indra/newview/CMakeLists.txt       | 23 ++++++++++++++-
 indra/newview/llappviewerwin32.cpp | 49 ++++++++++++++++++++++++++++---
 7 files changed, 101 insertions(+), 98 deletions(-)

diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt
index 4a3ebe4835..84e1c5d6fd 100644
--- a/indra/cmake/CMakeLists.txt
+++ b/indra/cmake/CMakeLists.txt
@@ -12,6 +12,7 @@ set(cmake_SOURCE_FILES
     Audio.cmake
     BerkeleyDB.cmake
     Boost.cmake
+    bugsplat.cmake
     BuildVersion.cmake
     CEFPlugin.cmake
     CEFPlugin.cmake
diff --git a/indra/cmake/bugsplat.cmake b/indra/cmake/bugsplat.cmake
index e993979902..a7f4194905 100644
--- a/indra/cmake/bugsplat.cmake
+++ b/indra/cmake/bugsplat.cmake
@@ -1,20 +1,30 @@
-include(Prebuilt)
+# BUGSPLAT can be set when launching the make using the argument -DBUGSPLAT:BOOL=ON
+# When building using proprietary binaries though (i.e. having access to LL private servers),
+# we always build with BUGSPLAT.
+# Open source devs should use the -DBUGSPLAT:BOOL=ON then if they want to
+# build with BugSplat, whether they are using USESYSTEMLIBS or not.
+if (INSTALL_PROPRIETARY)
+  set(BUGSPLAT ON CACHE BOOL "Using BugSplat crash reporting library.")
+endif (INSTALL_PROPRIETARY)
 
-set(BUGSPLAT_FIND_QUIETLY ON)
-set(BUGSPLAT_FIND_REQUIRED ON)
+if (BUGSPLAT)
+  if (USESYSTEMLIBS)
+    set(BUGSPLAT_FIND_QUIETLY ON)
+    set(BUGSPLAT_FIND_REQUIRED ON)
+    include(FindBUGSPLAT)
+  else (USESYSTEMLIBS)
+    include(Prebuilt)
+    use_prebuilt_binary(bugsplat)
+    if (WINDOWS)
+      set(BUGSPLAT_LIBRARIES 
+        ${ARCH_PREBUILT_DIRS_RELEASE}/bugsplat.lib
+        )
+    elseif (DARWIN)
+      find_library(BUGSPLAT_LIBRARIES BugsplatMac
+        PATHS "${ARCH_PREBUILT_DIRS_RELEASE}")
+    else (WINDOWS)
 
-if (USESYSTEMLIBS)
-  include(FindBUGSPLAT)
-else (USESYSTEMLIBS)
-  use_prebuilt_binary(bugsplat)
-  if (WINDOWS)
-    set(BUGSPLAT_LIBRARIES 
-      ${ARCH_PREBUILT_DIRS_RELEASE}/bugsplat.lib
-      )
-  elseif (DARWIN)
-
-  else (WINDOWS)
-
-  endif (WINDOWS)
-  set(BUGSPLAT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/bugsplat)
-endif (USESYSTEMLIBS)
+    endif (WINDOWS)
+    set(BUGSPLAT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/bugsplat)
+  endif (USESYSTEMLIBS)
+endif (BUGSPLAT)
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 4eba1d5451..d9eb13d65a 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -13,7 +13,6 @@ include(GoogleBreakpad)
 include(Copy3rdPartyLibs)
 include(ZLIB)
 include(URIPARSER)
-include(BuildVersion)
 
 include_directories(
     ${EXPAT_INCLUDE_DIRS}
@@ -254,14 +253,7 @@ set(llcommon_HEADER_FILES
     )
 
 set_source_files_properties(${llcommon_HEADER_FILES}
-                            PROPERTIES HEADER_FILE_ONLY TRUE
-                            )
-
-# bring in version information for BugSplat crash reporting
-set_source_files_properties(${llcommon_SOURCE_FILES}
-                            PROPERTIES
-                            COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}" # see BuildVersion.cmake
-                            )
+                            PROPERTIES HEADER_FILE_ONLY TRUE)
 
 list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES})
 
diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index 3e652dbdb5..6cc9e804d4 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -49,20 +49,6 @@
 #include "google_breakpad/exception_handler.h"
 #include "stringize.h"
 #include "llcleanup.h"
-#include "BugSplat.h"
-
-// TESTING ONLY - REMOVE FOR PRODUCTION
-// (Want to only invoke BugSplat crash reporting in the same way we did for Breakpad - for Release viewers
-// but need to test here in a ReleaseWithDebugInfo environment)
-#if BUGSPLAT_ENABLED
-#define LL_SEND_CRASH_REPORTS 1
-#endif
-
-// BugSplat crash reporting tool - http://bugsplat.com
-#if BUGSPLAT_ENABLED
-bool BugSplatExceptionCallback(unsigned int nCode, void* lpVal1, void* lpVal2);
-MiniDmpSender *gBugSplatSender;
-#endif
 
 //
 // Signal handling
@@ -399,26 +385,6 @@ void EnableCrashingOnCrashes()
 }
 #endif
 
-#if BUGSPLAT_ENABLED
-bool BugSplatExceptionCallback(unsigned int nCode, void* lpVal1, void* lpVal2)
-{
-	switch (nCode)
-	{
-		case MDSCB_EXCEPTIONCODE:
-		{
-			// send the main viewer log file (Clearly a temporary hack since we don't have access to the gDir*** set of functions in newview
-			const std::string appdata = std::string(getenv("APPDATA"));
-			const std::string logfile = appdata + "\\SecondLife\\logs\\Secondlife.log";
-			const std::wstring wide_logfile(logfile.begin(), logfile.end());
-			gBugSplatSender->sendAdditionalFile((const __wchar_t *)wide_logfile.c_str());
-		}
-		break;
-	}
-
-	return false;
-}
-#endif
-
 void LLApp::setupErrorHandling(bool second_instance)
 {
 	// Error handling is done by starting up an error handling thread, which just sleeps and
@@ -427,25 +393,6 @@ void LLApp::setupErrorHandling(bool second_instance)
 #if LL_WINDOWS
 
 #if LL_SEND_CRASH_REPORTS
-
-#if BUGSPLAT_ENABLED
-	// TODOCP: populate these fields correctly
-	static const wchar_t *bugdb_name = L"second_life_callum_test";
-
-	// build (painfully) the app/channel name
-	#define stringize_inner(x) L#x
-	#define stringize_outer(x) stringize_inner(x)
-	std::wstring app_name(stringize_outer(LL_VIEWER_CHANNEL));
-
-	// build in real app version now we leveraged CMake to build in BuildVersion.cmake into LLCommon
-	wchar_t version_string[MAX_STRING];
-	wsprintf(version_string, L"%d.%d.%d.%d", LL_VIEWER_VERSION_MAJOR, LL_VIEWER_VERSION_MINOR, LL_VIEWER_VERSION_PATCH, LL_VIEWER_VERSION_BUILD);
-
-	gBugSplatSender = new MiniDmpSender((const __wchar_t *)bugdb_name, (const __wchar_t *)app_name.c_str(), (const __wchar_t *)version_string, NULL);
-
-	gBugSplatSender->setCallback(BugSplatExceptionCallback);
-#else
-
 	EnableCrashingOnCrashes();
 
 	// This sets a callback to handle w32 signals to the console window.
@@ -507,9 +454,8 @@ void LLApp::setupErrorHandling(bool second_instance)
 			mExceptionHandler->set_handle_debug_exceptions(true);
 		}
 	}
-#endif  // BUGSPLAT_ENABLED
-#endif	// LL_SEND_CRASH_REPORTS
-#else	// not LL_WINDOWS
+#endif
+#else
 	//
 	// Start up signal handling.
 	//
@@ -570,7 +516,7 @@ void LLApp::setupErrorHandling(bool second_instance)
 	}
 #endif
 
-#endif // LL_WINDOWS
+#endif
 	startErrorThread();
 }
 
diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h
index 5a4b7f13df..acd829d864 100644
--- a/indra/llcommon/llapp.h
+++ b/indra/llcommon/llapp.h
@@ -30,7 +30,6 @@
 #include <map>
 #include "llrun.h"
 #include "llsd.h"
-
 // Forward declarations
 template <typename Type> class LLAtomic32;
 typedef LLAtomic32<U32> LLAtomicU32;
@@ -40,14 +39,6 @@ class LLLiveFile;
 #include <signal.h>
 #endif
 
-// first version of Bugsplat (http://bugsplat.com) crash reporting tool
-// is only supported on Windows - macOS to follow.
-#define BUGSPLAT_ENABLED LL_WINDOWS
-
-#if BUGSPLAT_ENABLED
-class __declspec(dllexport) MiniDmpSender;
-#endif
-
 typedef void (*LLAppErrorHandler)();
 
 #if !LL_WINDOWS
@@ -325,6 +316,7 @@ private:
 	
 	google_breakpad::ExceptionHandler * mExceptionHandler;
 
+
 #if !LL_WINDOWS
 	friend void default_unix_signal_handler(int signum, siginfo_t *info, void *);
 #endif
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 1fd0af0558..2592b532c4 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1354,6 +1354,11 @@ if (DARWIN)
 
   # This should be compiled with the viewer.
   LIST(APPEND viewer_SOURCE_FILES llappdelegate-objc.mm)
+  set_source_files_properties(
+    llappdelegate-objc.mm
+    PROPERTIES
+    COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}"
+    )
 
   find_library(AGL_LIBRARY AGL)
   find_library(APPKIT_LIBRARY AppKit)
@@ -1366,6 +1371,7 @@ if (DARWIN)
     ${AGL_LIBRARY}
     ${IOKIT_LIBRARY}
     ${COREAUDIO_LIBRARY}
+    ${BUGSPLAT_LIBRARIES}
     )
 
   # Add resource files to the project.
@@ -1393,6 +1399,11 @@ endif (DARWIN)
 
 if (LINUX)
     LIST(APPEND viewer_SOURCE_FILES llappviewerlinux.cpp)
+    set_source_files_properties(
+      llappviewerlinux.cpp
+      PROPERTIES
+      COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}"
+      )
     LIST(APPEND viewer_SOURCE_FILES llappviewerlinux_api_dbus.cpp)
     SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed")
 
@@ -1409,6 +1420,11 @@ if (WINDOWS)
          llappviewerwin32.cpp
          llwindebug.cpp
          )
+    set_source_files_properties(
+      llappviewerwin32.cpp
+      PROPERTIES
+      COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}"
+      )
 
     list(APPEND viewer_HEADER_FILES
          llappviewerwin32.h
@@ -1692,6 +1708,11 @@ if (SDL_FOUND)
     )
 endif (SDL_FOUND)
 
+if (BUGSPLAT)
+  set_property(TARGET ${VIEWER_BINARY_NAME}
+    PROPERTY COMPILE_DEFINITIONS "LL_BUGSPLAT")
+endif (BUGSPLAT)
+
 # add package files
 file(GLOB EVENT_HOST_SCRIPT_GLOB_LIST
      ${CMAKE_CURRENT_SOURCE_DIR}/../viewer_components/*.py)
@@ -1790,7 +1811,7 @@ if (WINDOWS)
            ${SHARED_LIB_STAGING_DIR}/Debug/fmodexL.dll
           )
     endif (FMODEX)
-    
+
     add_custom_command(
       OUTPUT  ${CMAKE_CFG_INTDIR}/copy_touched.bat
       COMMAND ${PYTHON_EXECUTABLE}
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 48b3a1c485..8a014c55d7 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -66,8 +66,18 @@
 #endif
 
 #include "stringize.h"
+#include "lldir.h"
 
 #include <exception>
+
+// Bugsplat (http://bugsplat.com) crash reporting tool
+#ifdef LL_BUGSPLAT
+#include "BugSplat.h"
+
+// FIXME: need a production BugSplat database name
+static const wchar_t *bugdb_name = L"second_life_callum_test";
+#endif
+
 namespace
 {
     void (*gOldTerminateHandler)() = NULL;
@@ -495,15 +505,46 @@ bool LLAppViewerWin32::init()
 	LLWinDebug::instance();
 #endif
 
-#if LL_WINDOWS
 #if LL_SEND_CRASH_REPORTS
-
+#if ! defined(LL_BUGSPLAT)
 
 	LLAppViewer* pApp = LLAppViewer::instance();
 	pApp->initCrashReporting();
 
-#endif
-#endif
+#else // LL_BUGSPLAT
+
+	std::wstring version_string(WSTRINGIZE(LL_VIEWER_VERSION_MAJOR << '.' <<
+										   LL_VIEWER_VERSION_MINOR << '.' <<
+										   LL_VIEWER_VERSION_PATCH << '.' <<
+										   LL_VIEWER_VERSION_BUILD));
+
+	auto sender = new MiniDmpSender(
+		bugdb_name, LL_TO_WSTRING(LL_VIEWER_CHANNEL), version_string.c_str(), nullptr);
+	sender->setCallback(
+		[sender](unsigned int nCode, void* lpVal1, void* lpVal2)
+		{
+			// If we haven't yet initialized LLDir, don't bother trying to
+			// find our log file.
+			// Alternatively -- if we might encounter trouble trying to query
+			// LLDir during crash cleanup -- consider making gDirUtilp an
+			// LLPounceable, and attach a callback that stores the pathname to
+			// the log file here.
+			if (nCode == MDSCB_EXCEPTIONCODE && gDirUtilp)
+			{
+				// send the main viewer log file
+				// widen to wstring, then pass c_str()
+				sender->sendAdditionalFile(
+					wstringize(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log")).c_str());
+			}
+
+			return false;
+		});
+
+	LL_INFOS() << "Engaged BugSplat(" << LL_TO_STRING(LL_VIEWER_CHANNEL)
+			   << version_string << ')' << LL_ENDL;
+
+#endif // LL_BUGSPLAT
+#endif // LL_SEND_CRASH_REPORTS
 
 	bool success = LLAppViewer::init();
 
-- 
cgit v1.2.3


From cd21556aef547dbb031e363d3a9b9f1893be4d08 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 17 May 2018 10:58:59 -0400
Subject: SL-821: Convert wstrings to strings of __wchar_t for BugSplat API.

---
 indra/newview/llappviewerwin32.cpp | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 8a014c55d7..91c6f08000 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -76,7 +76,14 @@
 
 // FIXME: need a production BugSplat database name
 static const wchar_t *bugdb_name = L"second_life_callum_test";
-#endif
+
+// MiniDmpSender's constructor is defined to accept __wchar_t* instead of
+// plain wchar_t*.
+inline std::basic_string<__wchar_t> wunder(const std::wstring& str)
+{
+    return { str.begin(), str.end() };
+}
+#endif // LL_BUGSPLAT
 
 namespace
 {
@@ -518,8 +525,12 @@ bool LLAppViewerWin32::init()
 										   LL_VIEWER_VERSION_PATCH << '.' <<
 										   LL_VIEWER_VERSION_BUILD));
 
+	// have to convert normal wide strings to strings of __wchar_t
 	auto sender = new MiniDmpSender(
-		bugdb_name, LL_TO_WSTRING(LL_VIEWER_CHANNEL), version_string.c_str(), nullptr);
+		wunder(bugdb_name).c_str(),
+		wunder(LL_TO_WSTRING(LL_VIEWER_CHANNEL)).c_str(),
+		wunder(version_string).c_str(),
+		nullptr);
 	sender->setCallback(
 		[sender](unsigned int nCode, void* lpVal1, void* lpVal2)
 		{
@@ -532,16 +543,17 @@ bool LLAppViewerWin32::init()
 			if (nCode == MDSCB_EXCEPTIONCODE && gDirUtilp)
 			{
 				// send the main viewer log file
-				// widen to wstring, then pass c_str()
+				// widen to wstring, convert to __wchar_t, then pass c_str()
 				sender->sendAdditionalFile(
-					wstringize(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log")).c_str());
+					wunder(wstringize(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log"))).c_str());
 			}
 
 			return false;
 		});
 
+	// engage stringize() overload that converts from wstring
 	LL_INFOS() << "Engaged BugSplat(" << LL_TO_STRING(LL_VIEWER_CHANNEL)
-			   << version_string << ')' << LL_ENDL;
+			   << stringize(version_string) << ')' << LL_ENDL;
 
 #endif // LL_BUGSPLAT
 #endif // LL_SEND_CRASH_REPORTS
-- 
cgit v1.2.3


From 800b47ec230d1d2a6781dce5ba9816d10a37e91e Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 17 May 2018 15:02:26 -0400
Subject: SL-821: Use classic-C BugSplat callback and static dumb pointer.

BugSplat has no business introducing a new C++ API based on classic-C function
pointers without even a generic pass-through user data pointer!
---
 indra/newview/llappviewerwin32.cpp | 65 ++++++++++++++++++++++----------------
 1 file changed, 38 insertions(+), 27 deletions(-)

diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 91c6f08000..5f3bf14bc2 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -74,14 +74,43 @@
 #ifdef LL_BUGSPLAT
 #include "BugSplat.h"
 
-// FIXME: need a production BugSplat database name
-static const wchar_t *bugdb_name = L"second_life_callum_test";
-
-// MiniDmpSender's constructor is defined to accept __wchar_t* instead of
-// plain wchar_t*.
-inline std::basic_string<__wchar_t> wunder(const std::wstring& str)
+namespace
 {
-    return { str.begin(), str.end() };
+    // FIXME: need a production BugSplat database name
+    static const wchar_t *bugdb_name = L"second_life_callum_test";
+
+    // MiniDmpSender's constructor is defined to accept __wchar_t* instead of
+    // plain wchar_t*.
+    inline std::basic_string<__wchar_t> wunder(const std::wstring& str)
+    {
+        return { str.begin(), str.end() };
+    }
+
+    // Irritatingly, MiniDmpSender::setCallback() is defined to accept a
+    // classic-C function pointer instead of an arbitrary C++ callable. In the
+    // latter case, we could pass a lambda that binds our MiniDmpSender
+    // pointer. As things stand, we must define an actual function and store
+    // the pointer statically.
+    static MiniDmpSender *sBugSplatSender = nullptr;
+
+    bool bugsplatSendLog(UINT nCode, LPVOID lpVal1, LPVOID lpVal2)
+    {
+        // If we haven't yet initialized LLDir, don't bother trying to
+        // find our log file.
+        // Alternatively -- if we might encounter trouble trying to query
+        // LLDir during crash cleanup -- consider making gDirUtilp an
+        // LLPounceable, and attach a callback that stores the pathname to
+        // the log file here.
+        if (nCode == MDSCB_EXCEPTIONCODE && gDirUtilp)
+        {
+            // send the main viewer log file
+            // widen to wstring, convert to __wchar_t, then pass c_str()
+            sBugSplatSender->sendAdditionalFile(
+                wunder(wstringize(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log"))).c_str());
+        }
+
+        return false;
+    }
 }
 #endif // LL_BUGSPLAT
 
@@ -526,30 +555,12 @@ bool LLAppViewerWin32::init()
 										   LL_VIEWER_VERSION_BUILD));
 
 	// have to convert normal wide strings to strings of __wchar_t
-	auto sender = new MiniDmpSender(
+	sBugSplatSender = new MiniDmpSender(
 		wunder(bugdb_name).c_str(),
 		wunder(LL_TO_WSTRING(LL_VIEWER_CHANNEL)).c_str(),
 		wunder(version_string).c_str(),
 		nullptr);
-	sender->setCallback(
-		[sender](unsigned int nCode, void* lpVal1, void* lpVal2)
-		{
-			// If we haven't yet initialized LLDir, don't bother trying to
-			// find our log file.
-			// Alternatively -- if we might encounter trouble trying to query
-			// LLDir during crash cleanup -- consider making gDirUtilp an
-			// LLPounceable, and attach a callback that stores the pathname to
-			// the log file here.
-			if (nCode == MDSCB_EXCEPTIONCODE && gDirUtilp)
-			{
-				// send the main viewer log file
-				// widen to wstring, convert to __wchar_t, then pass c_str()
-				sender->sendAdditionalFile(
-					wunder(wstringize(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log"))).c_str());
-			}
-
-			return false;
-		});
+	sBugSplatSender->setCallback(bugsplatSendLog);
 
 	// engage stringize() overload that converts from wstring
 	LL_INFOS() << "Engaged BugSplat(" << LL_TO_STRING(LL_VIEWER_CHANNEL)
-- 
cgit v1.2.3


From 4562773abcfe14425478889e2fea02da205013e1 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 21 May 2018 13:03:43 -0400
Subject: SL-821: Reorder CMakeLists.txt includes to resolve interdependencies.

---
 indra/newview/CMakeLists.txt | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 2592b532c4..d28791485c 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -3,6 +3,10 @@
 project(viewer)
 
 include(00-Common)
+# DON'T move Linking.cmake to its place in the alphabetized list below: it
+# sets variables on which the 3p .cmake files depend.
+include(Linking)
+
 include(Boost)
 include(bugsplat)
 include(BuildPackagesInfo)
@@ -38,7 +42,6 @@ include(LLUI)
 include(LLVFS)
 include(LLWindow)
 include(LLXML)
-include(Linking)
 include(NDOF)
 include(NVAPI)
 include(OPENAL)
-- 
cgit v1.2.3


From 881bdec4b356ede32b0d0896334f7d6addac6c54 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 21 May 2018 13:07:44 -0400
Subject: SL-821: Introduce macOS BugSplat initialization.

---
 indra/newview/llappdelegate-objc.mm | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm
index aebae4c434..2fa8319260 100644
--- a/indra/newview/llappdelegate-objc.mm
+++ b/indra/newview/llappdelegate-objc.mm
@@ -25,6 +25,9 @@
  */
 
 #import "llappdelegate-objc.h"
+#if defined(LL_BUGSPLAT)
+#import BugsplatMac;
+#endif
 #include "llwindowmacosx-objc.h"
 #include <Carbon/Carbon.h> // Used for Text Input Services ("Safe" API - it's supported)
 
@@ -64,6 +67,11 @@
 	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(languageUpdated) name:@"NSTextInputContextKeyboardSelectionDidChangeNotification" object:nil];
 
  //   [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self andSelector:@selector(handleGetURLEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL];
+
+#if defined(LL_BUGSPLAT)
+	// https://www.bugsplat.com/docs/platforms/os-x#initialization
+	[[BugsplatStartupManager sharedManager] start];
+#endif
 }
 
 - (void) handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent {
-- 
cgit v1.2.3


From 3a885e9cb7bb86e82036b217e2aaf2d96106be43 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 21 May 2018 13:29:16 -0400
Subject: SL-821: Use @import, not #import.

---
 indra/newview/llappdelegate-objc.mm | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm
index 2fa8319260..e8b4272e51 100644
--- a/indra/newview/llappdelegate-objc.mm
+++ b/indra/newview/llappdelegate-objc.mm
@@ -26,7 +26,7 @@
 
 #import "llappdelegate-objc.h"
 #if defined(LL_BUGSPLAT)
-#import BugsplatMac;
+@import BugsplatMac;
 #endif
 #include "llwindowmacosx-objc.h"
 #include <Carbon/Carbon.h> // Used for Text Input Services ("Safe" API - it's supported)
-- 
cgit v1.2.3


From 6f878571ec65d15f9e06af39375cc0251e4d1e2d Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 21 May 2018 13:54:39 -0400
Subject: SL-821: Add -fmodules to llappdelegate-objc.mm compile switches.

The BugsplatMac package is built as a module requiring @import. Using @import
requires Objective-C++ module support, which requires the -fmodules switch.
---
 indra/newview/CMakeLists.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index d28791485c..3501fdf800 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1361,6 +1361,7 @@ if (DARWIN)
     llappdelegate-objc.mm
     PROPERTIES
     COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}"
+    COMPILE_FLAGS "-fmodules"
     )
 
   find_library(AGL_LIBRARY AGL)
-- 
cgit v1.2.3


From 170d5201ff97b4110fa9cc2a9a80234de53e12d8 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 21 May 2018 14:13:11 -0400
Subject: SL-821: Need -fcxx-modules for C++ module support, vs. classic C.

---
 indra/newview/CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 3501fdf800..7638a74bc1 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1361,7 +1361,7 @@ if (DARWIN)
     llappdelegate-objc.mm
     PROPERTIES
     COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}"
-    COMPILE_FLAGS "-fmodules"
+    COMPILE_FLAGS "-fmodules -fcxx-modules"
     )
 
   find_library(AGL_LIBRARY AGL)
-- 
cgit v1.2.3


From 670943de5a3bf4e7053c3afea0fda722e958f136 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 21 May 2018 15:02:17 -0400
Subject: SL-804, SL-824: Update to bugsplat build 515598

---
 autobuild.xml | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 25bc8d8af9..fea35ac731 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -244,9 +244,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>9a14b64569c998fb7ef6e3bb690eda29</string>
+              <string>84ef190d0bc6cd3b535d8c625f324ba6</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/17916/122458/bugsplat-1.0.2.515327-darwin64-515327.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18354/126844/bugsplat-1.0.2.515598-darwin64-515598.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -256,9 +256,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>90d85d1ac17f0049c8c48110e790a61f</string>
+              <string>12625f3b3da813f10ec5b8e7eb84fe2d</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/17918/122472/bugsplat-3.5.0.5.515327-windows-515327.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18356/126857/bugsplat-3.5.0.5.515598-windows-515598.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -268,16 +268,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>9af7c080ebf0b961d7a4ccac7a303508</string>
+              <string>0f88af634e5da368334ad6da7014b2ce</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/17917/122466/bugsplat-3.5.0.5.515327-windows64-515327.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18355/126855/bugsplat-3.5.0.5.515598-windows64-515598.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.0.2.515327</string>
+        <string>1.0.2.515598</string>
       </map>
       <key>chardet</key>
       <map>
-- 
cgit v1.2.3


From 199c688e211125ae1b404425d9a8bd3bc036ea50 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 22 May 2018 11:52:00 -0400
Subject: SL-821: Copy BugsplatMac.framework into target application bundle.

---
 indra/newview/viewer_manifest.py | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 3375d4e071..d1a56c2230 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -1005,13 +1005,15 @@ open "%s" --args "$@"
                         os.path.basename(Info_plist),
                         "Info.plist")
 
-                    # CEF framework goes inside viewer_app/Contents/Frameworks.
-                    # Remember where we parked this car.
                     with self.prefix(src="", dst="Frameworks"):
+                        # CEF framework goes inside viewer_app/Contents/Frameworks.
                         CEF_framework = "Chromium Embedded Framework.framework"
                         self.path2basename(relpkgdir, CEF_framework)
+                        # Remember where we parked this car.
                         CEF_framework = self.dst_path_of(CEF_framework)
 
+                        self.path2basename(relpkgdir, "BugsplatMac.framework")
+
                     with self.prefix(dst="MacOS"):
                         # CMake constructs the Second Life executable in the
                         # MacOS directory belonging to the top-level Second
-- 
cgit v1.2.3


From 48534c1badcd2f63dee2ee0106a109b93604827c Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 22 May 2018 12:00:20 -0400
Subject: SL-821: Add macOS rpath to Mac viewer executable for BugsplatMac.

The BugsplatMac framework is stamped with @rpath/BugsplatMac.framework/etc.,
so that's the dependency stamped into our viewer executable. To support that
lookup, direct CMake to add an appropriate RPATH to the executable.
---
 indra/newview/CMakeLists.txt | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 7638a74bc1..954d5ce9ed 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1361,9 +1361,16 @@ if (DARWIN)
     llappdelegate-objc.mm
     PROPERTIES
     COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}"
+    # BugsplatMac is a module, imported with @import. That language feature
+    # demands these switches.
     COMPILE_FLAGS "-fmodules -fcxx-modules"
     )
 
+  # from https://stackoverflow.com/a/43551534
+  set(CMAKE_MACOSX_RPATH 1)
+  # From Contents/MacOS/SecondLife, look in Contents/Frameworks
+  set(CMAKE_INSTALL_RPATH "@loader_path/../Frameworks")
+
   find_library(AGL_LIBRARY AGL)
   find_library(APPKIT_LIBRARY AppKit)
   find_library(COCOA_LIBRARY Cocoa)
-- 
cgit v1.2.3


From 96dfab228ebce44287f66255ceb041e7f9d929b1 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 23 May 2018 04:54:09 -0400
Subject: SL-824: Update to bugsplat build 515654

---
 autobuild.xml | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index fea35ac731..a3f5a83856 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -244,9 +244,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>84ef190d0bc6cd3b535d8c625f324ba6</string>
+              <string>a834c6f8bafd4cb8e4a744510211237a</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18354/126844/bugsplat-1.0.2.515598-darwin64-515598.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18458/127802/bugsplat-1.0.2.515654-darwin64-515654.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -256,9 +256,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>12625f3b3da813f10ec5b8e7eb84fe2d</string>
+              <string>b8e47c5a20394e1add436e92fee9e356</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18356/126857/bugsplat-3.5.0.5.515598-windows-515598.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18461/127812/bugsplat-3.5.0.5.515654-windows-515654.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -268,16 +268,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>0f88af634e5da368334ad6da7014b2ce</string>
+              <string>2f026674ed4ff8db34674af3cbd2072a</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18355/126855/bugsplat-3.5.0.5.515598-windows64-515598.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18462/127815/bugsplat-3.5.0.5.515654-windows64-515654.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.0.2.515598</string>
+        <string>1.0.2.515654</string>
       </map>
       <key>chardet</key>
       <map>
-- 
cgit v1.2.3


From 78dbccf14a7b2a454c3def823087955e0f7ac767 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 23 May 2018 06:42:23 -0400
Subject: SL-824: Update to bugsplat build 515657

---
 autobuild.xml | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index a3f5a83856..e9ad39b921 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -244,9 +244,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>a834c6f8bafd4cb8e4a744510211237a</string>
+              <string>c1f7431195bd5cb3cba724abdcc50104</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18458/127802/bugsplat-1.0.2.515654-darwin64-515654.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18470/127908/bugsplat-1.0.2.515657-darwin64-515657.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -256,9 +256,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>b8e47c5a20394e1add436e92fee9e356</string>
+              <string>57832de6e3ba7eef7ac5f4e947277723</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18461/127812/bugsplat-3.5.0.5.515654-windows-515654.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18472/127922/bugsplat-3.5.0.5.515657-windows-515657.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -268,16 +268,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>2f026674ed4ff8db34674af3cbd2072a</string>
+              <string>2ccc3aec7861e79e32e31e12807127b1</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18462/127815/bugsplat-3.5.0.5.515654-windows64-515654.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18471/127916/bugsplat-3.5.0.5.515657-windows64-515657.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.0.2.515654</string>
+        <string>1.0.2.515657</string>
       </map>
       <key>chardet</key>
       <map>
-- 
cgit v1.2.3


From 07ebe236a1d92fe87641d681ce7f656519498f3e Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 23 May 2018 11:31:13 -0400
Subject: SL-824: Update to bugsplat build 515662

---
 autobuild.xml | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index e9ad39b921..5254530fa1 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -244,9 +244,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>c1f7431195bd5cb3cba724abdcc50104</string>
+              <string>2ef055fe7ec22c64394095ad8d7ab34e</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18470/127908/bugsplat-1.0.2.515657-darwin64-515657.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18481/127993/bugsplat-1.0.2.515662-darwin64-515662.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -256,9 +256,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>57832de6e3ba7eef7ac5f4e947277723</string>
+              <string>84b73bc8141b5d19a8dafabfe27eee93</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18472/127922/bugsplat-3.5.0.5.515657-windows-515657.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18483/128007/bugsplat-3.5.0.5.515662-windows-515662.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -268,16 +268,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>2ccc3aec7861e79e32e31e12807127b1</string>
+              <string>bd44b033c07b417b675c3511fee468e2</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18471/127916/bugsplat-3.5.0.5.515657-windows64-515657.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18482/128001/bugsplat-3.5.0.5.515662-windows64-515662.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.0.2.515657</string>
+        <string>1.0.2.515662</string>
       </map>
       <key>chardet</key>
       <map>
-- 
cgit v1.2.3


From 43716d580049bb026904133f0804e8c8d1f519aa Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 23 May 2018 15:48:58 -0400
Subject: SL-821: Try again to add -rpath to Mac executable for BugSplat.

---
 indra/newview/CMakeLists.txt | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 6065a08524..9e8a68224b 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1368,11 +1368,6 @@ if (DARWIN)
     COMPILE_FLAGS "-fmodules -fcxx-modules"
     )
 
-  # from https://stackoverflow.com/a/43551534
-  set(CMAKE_MACOSX_RPATH 1)
-  # From Contents/MacOS/SecondLife, look in Contents/Frameworks
-  set(CMAKE_INSTALL_RPATH "@loader_path/../Frameworks")
-
   find_library(AGL_LIBRARY AGL)
   find_library(APPKIT_LIBRARY AppKit)
   find_library(COCOA_LIBRARY Cocoa)
@@ -1937,8 +1932,8 @@ else (WINDOWS)
 endif (WINDOWS)
 
 # *NOTE: - this list is very sensitive to ordering, test carefully on all
-# platforms if you change the releative order of the entries here.
-# In particular, cmake 2.6.4 (when buidling with linux/makefile generators)
+# platforms if you change the relative order of the entries here.
+# In particular, cmake 2.6.4 (when building with linux/makefile generators)
 # appears to sometimes de-duplicate redundantly listed dependencies improperly.
 # To work around this, higher level modules should be listed before the modules
 # that they depend upon. -brad
@@ -2101,11 +2096,16 @@ if (DARWIN)
   set(MACOSX_BUNDLE_COPYRIGHT "Copyright © Linden Research, Inc. 2007")
   set(MACOSX_BUNDLE_NSMAIN_NIB_FILE "SecondLife.nib")
   set(MACOSX_BUNDLE_NSPRINCIPAL_CLASS "NSApplication")
+
+  # https://blog.kitware.com/upcoming-in-cmake-2-8-12-osx-rpath-support/
+  set(CMAKE_MACOSX_RPATH 1)
   
   set_target_properties(
     ${VIEWER_BINARY_NAME}
     PROPERTIES
     OUTPUT_NAME "${product}"
+    # From Contents/MacOS/SecondLife, look in Contents/Frameworks
+    INSTALL_RPATH "@loader_path/../Frameworks"
     MACOSX_BUNDLE_INFO_PLIST
     "${CMAKE_CURRENT_SOURCE_DIR}/Info-SecondLife.plist"
     )
-- 
cgit v1.2.3


From b247c4e42434715459df93b5cbf6adb15d3c4cc4 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 24 May 2018 08:48:00 -0400
Subject: SL-821: Force the Mac -rpath linker switch using LINK_FLAGS property
 instead of the INSTALL_RPATH CMake property, which _should_ have worked.

---
 indra/newview/CMakeLists.txt | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 9e8a68224b..c67f365767 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -2106,6 +2106,9 @@ if (DARWIN)
     OUTPUT_NAME "${product}"
     # From Contents/MacOS/SecondLife, look in Contents/Frameworks
     INSTALL_RPATH "@loader_path/../Frameworks"
+    # SIGH, as of 2018-05-24 (cmake 3.11.1) the INSTALL_RPATH property simply
+    # does not work. Try this:
+    LINK_FLAGS "-rpath @loader_path/../Frameworks"
     MACOSX_BUNDLE_INFO_PLIST
     "${CMAKE_CURRENT_SOURCE_DIR}/Info-SecondLife.plist"
     )
-- 
cgit v1.2.3


From 63fe7d802aad177107ef8e3bc0c9b7ea5118ad61 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 25 May 2018 12:09:50 -0400
Subject: SL-821, SL-826: Use BUGSPLAT_DB from environment on Windows and Mac.

On TeamCity, set BUGSPLAT_DB from build-secrets.

Use the presence of $BUGSPLAT_DB, rather than a new CMake BUGSPLAT option, to
control whether CMake searches for BugSplat -- and passes LL_BUGSPLAT into C++.

When BUGSPLAT_DB is present, make viewer_manifest.py set "BugSplat DB" in
build_data.json, and "BugsplatServerURL" in Mac Info.plist.

Make llappviewerwin32.cpp read "BugSplat DB" from build_data.json.

Add placeholders for Mac hooks to suppress BugSplat prompt and send
SecondLife.log.
---
 build.sh                            | 20 ++++++---
 indra/cmake/bugsplat.cmake          | 16 +++----
 indra/newview/CMakeLists.txt        |  4 +-
 indra/newview/llappdelegate-objc.mm | 19 ++++++++
 indra/newview/llappviewerwin32.cpp  | 87 +++++++++++++++++++++++++++----------
 indra/newview/viewer_manifest.py    | 12 +++++
 6 files changed, 114 insertions(+), 44 deletions(-)

diff --git a/build.sh b/build.sh
index bb8d66599b..7e44c6fee3 100755
--- a/build.sh
+++ b/build.sh
@@ -95,17 +95,23 @@ pre_build()
     && [ -r "$master_message_template_checkout/message_template.msg" ] \
     && template_verifier_master_url="-DTEMPLATE_VERIFIER_MASTER_URL=file://$master_message_template_checkout/message_template.msg"
 
-    # nat 2016-12-20: disable HAVOK on Mac until we get a 64-bit Mac build.
     RELEASE_CRASH_REPORTING=ON
     HAVOK=ON
     SIGNING=()
-    if [ "$arch" == "Darwin" ]
-    then
-         if [ "$variant" == "Release" ]
-         then SIGNING=("-DENABLE_SIGNING:BOOL=YES" \
-                       "-DSIGNING_IDENTITY:STRING=Developer ID Application: Linden Research, Inc.")
-         fi
+    if [ "$arch" == "Darwin" -a "$variant" == "Release" ]
+    then SIGNING=("-DENABLE_SIGNING:BOOL=YES" \
+                  "-DSIGNING_IDENTITY:STRING=Developer ID Application: Linden Research, Inc.")
+    fi
+
+    # don't spew credentials into build log
+    bugsplat_sh="$build_secrets_checkout/bugsplat/bugsplat.sh"
+    set +x
+    if [ -r "$bugsplat_sh" ]
+    then # show that we're doing this, just not the contents
+         echo source "$bugsplat_sh"
+         source "$bugsplat_sh"
     fi
+    set -x
 
     "$autobuild" configure --quiet -c $variant -- \
      -DPACKAGE:BOOL=ON \
diff --git a/indra/cmake/bugsplat.cmake b/indra/cmake/bugsplat.cmake
index a7f4194905..4db9068b49 100644
--- a/indra/cmake/bugsplat.cmake
+++ b/indra/cmake/bugsplat.cmake
@@ -1,13 +1,7 @@
-# BUGSPLAT can be set when launching the make using the argument -DBUGSPLAT:BOOL=ON
-# When building using proprietary binaries though (i.e. having access to LL private servers),
-# we always build with BUGSPLAT.
-# Open source devs should use the -DBUGSPLAT:BOOL=ON then if they want to
-# build with BugSplat, whether they are using USESYSTEMLIBS or not.
-if (INSTALL_PROPRIETARY)
-  set(BUGSPLAT ON CACHE BOOL "Using BugSplat crash reporting library.")
-endif (INSTALL_PROPRIETARY)
-
-if (BUGSPLAT)
+# BugSplat is engaged by setting environment variable BUGSPLAT_DB to the
+# target BugSplat database name prior to running CMake (and during autobuild
+# build).
+if (DEFINED ENV{BUGSPLAT_DB})
   if (USESYSTEMLIBS)
     set(BUGSPLAT_FIND_QUIETLY ON)
     set(BUGSPLAT_FIND_REQUIRED ON)
@@ -27,4 +21,4 @@ if (BUGSPLAT)
     endif (WINDOWS)
     set(BUGSPLAT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/bugsplat)
   endif (USESYSTEMLIBS)
-endif (BUGSPLAT)
+endif (DEFINED ENV{BUGSPLAT_DB})
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index c67f365767..cf275ef4b5 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1715,10 +1715,10 @@ if (SDL_FOUND)
     )
 endif (SDL_FOUND)
 
-if (BUGSPLAT)
+if (DEFINED ENV{BUGSPLAT_DB})
   set_property(TARGET ${VIEWER_BINARY_NAME}
     PROPERTY COMPILE_DEFINITIONS "LL_BUGSPLAT")
-endif (BUGSPLAT)
+endif (DEFINED ENV{BUGSPLAT_DB})
 
 # add package files
 file(GLOB EVENT_HOST_SCRIPT_GLOB_LIST
diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm
index e8b4272e51..8e1ad169c9 100644
--- a/indra/newview/llappdelegate-objc.mm
+++ b/indra/newview/llappdelegate-objc.mm
@@ -70,6 +70,8 @@
 
 #if defined(LL_BUGSPLAT)
 	// https://www.bugsplat.com/docs/platforms/os-x#initialization
+//	[BugsplatStartupManager sharedManager].autoSubmitCrashReport = YES;
+//	[BugsplatStartupManager sharedManager].askUserDetails = NO;
 	[[BugsplatStartupManager sharedManager] start];
 #endif
 }
@@ -187,4 +189,21 @@
     return true;
 }
 
+#if 0 // defined(LL_BUGSPLAT)
+
+@implementation BugsplatStartupManagerDelegate
+
+- (BugsplatAttachment *)attachmentForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager {
+    NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@"example" withExtension:@"json"];
+    NSData *data = [NSData dataWithContentsOfURL:fileURL];
+    
+    BugsplatAttachment *attachment = 
+        [[BugsplatAttachment alloc] initWithFilename:@"example.json"
+                                      attachmentData:data
+                                         contentType:@"application/json"];
+    return attachment;
+}
+
+#endif // LL_BUGSPLAT
+
 @end
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 5f3bf14bc2..f9df2b88ed 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -68,29 +68,30 @@
 #include "stringize.h"
 #include "lldir.h"
 
+#include <fstream>
 #include <exception>
 
 // Bugsplat (http://bugsplat.com) crash reporting tool
 #ifdef LL_BUGSPLAT
 #include "BugSplat.h"
+#include "reader.h" // JsonCpp
 
 namespace
 {
-    // FIXME: need a production BugSplat database name
-    static const wchar_t *bugdb_name = L"second_life_callum_test";
-
     // MiniDmpSender's constructor is defined to accept __wchar_t* instead of
-    // plain wchar_t*.
+    // plain wchar_t*. It would be nice if, when wchar_t is the same as
+    // __wchar_t, this whole function would optimize away. However, we use it
+    // only for the arguments to make exactly one call to initialize BugSplat.
     inline std::basic_string<__wchar_t> wunder(const std::wstring& str)
     {
         return { str.begin(), str.end() };
     }
 
     // Irritatingly, MiniDmpSender::setCallback() is defined to accept a
-    // classic-C function pointer instead of an arbitrary C++ callable. In the
-    // latter case, we could pass a lambda that binds our MiniDmpSender
-    // pointer. As things stand, we must define an actual function and store
-    // the pointer statically.
+    // classic-C function pointer instead of an arbitrary C++ callable. If it
+    // did accept a modern callable, we could pass a lambda that binds our
+    // MiniDmpSender pointer. As things stand, though, we must define an
+    // actual function and store the pointer statically.
     static MiniDmpSender *sBugSplatSender = nullptr;
 
     bool bugsplatSendLog(UINT nCode, LPVOID lpVal1, LPVOID lpVal2)
@@ -549,22 +550,60 @@ bool LLAppViewerWin32::init()
 
 #else // LL_BUGSPLAT
 
-	std::wstring version_string(WSTRINGIZE(LL_VIEWER_VERSION_MAJOR << '.' <<
-										   LL_VIEWER_VERSION_MINOR << '.' <<
-										   LL_VIEWER_VERSION_PATCH << '.' <<
-										   LL_VIEWER_VERSION_BUILD));
-
-	// have to convert normal wide strings to strings of __wchar_t
-	sBugSplatSender = new MiniDmpSender(
-		wunder(bugdb_name).c_str(),
-		wunder(LL_TO_WSTRING(LL_VIEWER_CHANNEL)).c_str(),
-		wunder(version_string).c_str(),
-		nullptr);
-	sBugSplatSender->setCallback(bugsplatSendLog);
-
-	// engage stringize() overload that converts from wstring
-	LL_INFOS() << "Engaged BugSplat(" << LL_TO_STRING(LL_VIEWER_CHANNEL)
-			   << stringize(version_string) << ')' << LL_ENDL;
+	if (gDirUtilp)
+	{
+		LL_WARNS() << "Can't initialize BugSplat, gDirUtilp not yet set" << LL_ENDL;
+	}
+	else
+	{
+		std::string build_data_fname(
+			gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "build_data.json"));
+		std::ifstream inf(build_data_fname.c_str());
+		if (! inf.open())
+		{
+			LL_WARNS() << "Can't initialize BugSplat, can't read '" << build_data_fname
+					   << "'" << LL_ENDL;
+		}
+		else
+		{
+			Json::Reader reader;
+			Json::Value build_data;
+			if (! reader.parse(inf, build_data, false)) // don't collect comments
+			{
+				LL_WARNS() << "Can't initialize BugSplat, can't parse '" << build_data_fname
+						   << "': " << reader.getFormattedErrorMessages() << LL_ENDL;
+			}
+			else
+			{
+				Json::Value BugSplat_DB = build_data["BugSplat DB"];
+				if (! BugSplat_DB)
+				{
+					LL_WARNS() << "Can't initialize BugSplat, no 'BugSplat DB' entry in '"
+							   << build_data_fname "'" << LL_ENDL;
+				}
+				else
+				{
+					// Got BugSplat_DB, onward!
+					std::wstring version_string(WSTRINGIZE(LL_VIEWER_VERSION_MAJOR << '.' <<
+														   LL_VIEWER_VERSION_MINOR << '.' <<
+														   LL_VIEWER_VERSION_PATCH << '.' <<
+														   LL_VIEWER_VERSION_BUILD));
+
+					// have to convert normal wide strings to strings of __wchar_t
+					sBugSplatSender = new MiniDmpSender(
+						wunder(BugSplat_DB).c_str(),
+						wunder(LL_TO_WSTRING(LL_VIEWER_CHANNEL)).c_str(),
+						wunder(version_string).c_str(),
+						nullptr);
+					sBugSplatSender->setCallback(bugsplatSendLog);
+
+					// engage stringize() overload that converts from wstring
+					LL_INFOS() << "Engaged BugSplat(" << LL_TO_STRING(LL_VIEWER_CHANNEL)
+							   << stringize(version_string) << ')' << LL_ENDL;
+				} // got BugSplat_DB
+			} // parsed build_data.json
+		} // opened build_data.json
+	}  // gDirUtilp set
 
 #endif // LL_BUGSPLAT
 #endif // LL_SEND_CRASH_REPORTS
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 1fa948f89e..68ad1db14d 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -186,6 +186,11 @@ class ViewerManifest(LLManifest):
                             "Address Size":self.address_size,
                             "Update Service":"https://update.secondlife.com/update",
                             }
+            try:
+                build_data_dict["BugSplat DB"] = os.environ["BUGSPLAT_DB"]
+            except KeyError:
+                # skip the assignment if there's no BUGSPLAT_DB variable
+                pass
             build_data_dict = self.finish_build_data_dict(build_data_dict)
             with open(os.path.join(os.pardir,'build_data.json'), 'w') as build_data_handle:
                 json.dump(build_data_dict,build_data_handle)
@@ -1001,6 +1006,13 @@ open "%s" --args "$@"
                     # runs the executable, instead of launching the app)
                     Info["CFBundleExecutable"] = "Second Life"
                     Info["CFBundleIconFile"] = viewer_icon
+                    try:
+                        # https://www.bugsplat.com/docs/platforms/os-x#configuration
+                        Info["BugsplatServerURL"] = \
+                            "https://{BUGSPLAT_DB}.bugsplatsoftware.com/".format(**os.environ)
+                    except KeyError:
+                        # skip the assignment if there's no BUGSPLAT_DB variable
+                        pass
                     self.put_in_file(
                         plistlib.writePlistToString(Info),
                         os.path.basename(Info_plist),
-- 
cgit v1.2.3


From 8781b36d7ee5d6532fb6534caa595166ad00f04d Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 25 May 2018 16:08:00 -0400
Subject: SL-821: export BUGSPLAT_DB when loaded so child processes can detect.

Produce CMake message when BugSplat is engaged so we can detect in build log.

Don't try to copy BugSplat DLLs when NOT engaged.
---
 build.sh                           | 5 +++++
 indra/cmake/Copy3rdPartyLibs.cmake | 8 +++++---
 indra/cmake/bugsplat.cmake         | 2 ++
 3 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/build.sh b/build.sh
index 7e44c6fee3..cf18c3f541 100755
--- a/build.sh
+++ b/build.sh
@@ -110,6 +110,11 @@ pre_build()
     then # show that we're doing this, just not the contents
          echo source "$bugsplat_sh"
          source "$bugsplat_sh"
+         # important: we test this and use its value in [grand-]child processes
+         if [ -n "${BUGSPLAT_DB:-}" ]
+         then echo export BUGSPLAT_DB
+              export BUGSPLAT_DB
+         fi
     fi
     set -x
 
diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake
index 7f708bc27a..c9519b0e1d 100644
--- a/indra/cmake/Copy3rdPartyLibs.cmake
+++ b/indra/cmake/Copy3rdPartyLibs.cmake
@@ -51,15 +51,17 @@ if(WINDOWS)
 
     # Filenames are different for 32/64 bit BugSplat file and we don't
     # have any control over them so need to branch.
-    if(ADDRESS_SIZE EQUAL 32)
+    if (DEFINED ENV{BUGSPLAT_DB})
+      if(ADDRESS_SIZE EQUAL 32)
         set(release_files ${release_files} BugSplat.dll)
         set(release_files ${release_files} BugSplatRc.dll)
         set(release_files ${release_files} BsSndRpt.exe)
-    else(ADDRESS_SIZE EQUAL 32)
+      else(ADDRESS_SIZE EQUAL 32)
         set(release_files ${release_files} BugSplat64.dll)
         set(release_files ${release_files} BugSplatRc64.dll)
         set(release_files ${release_files} BsSndRpt64.exe)
-    endif(ADDRESS_SIZE EQUAL 32)
+      endif(ADDRESS_SIZE EQUAL 32)
+    endif (DEFINED ENV{BUGSPLAT_DB})
 
     if (FMODEX)
 
diff --git a/indra/cmake/bugsplat.cmake b/indra/cmake/bugsplat.cmake
index 4db9068b49..eb5808b1fb 100644
--- a/indra/cmake/bugsplat.cmake
+++ b/indra/cmake/bugsplat.cmake
@@ -3,10 +3,12 @@
 # build).
 if (DEFINED ENV{BUGSPLAT_DB})
   if (USESYSTEMLIBS)
+    message(STATUS "Looking for system BugSplat")
     set(BUGSPLAT_FIND_QUIETLY ON)
     set(BUGSPLAT_FIND_REQUIRED ON)
     include(FindBUGSPLAT)
   else (USESYSTEMLIBS)
+    message(STATUS "Engaging autobuild BugSplat")
     include(Prebuilt)
     use_prebuilt_binary(bugsplat)
     if (WINDOWS)
-- 
cgit v1.2.3


From 3ca76065b0beeaf276078b4bc28b8e0c6295a4fc Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 25 May 2018 19:02:53 -0400
Subject: SL-823: Fix minor compile errors in code to read build_data.json.

---
 indra/newview/llappviewerwin32.cpp | 32 ++++++++++++++++++++++++--------
 1 file changed, 24 insertions(+), 8 deletions(-)

diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index f9df2b88ed..b7ad28448b 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -79,14 +79,29 @@
 namespace
 {
     // MiniDmpSender's constructor is defined to accept __wchar_t* instead of
-    // plain wchar_t*. It would be nice if, when wchar_t is the same as
-    // __wchar_t, this whole function would optimize away. However, we use it
-    // only for the arguments to make exactly one call to initialize BugSplat.
+    // plain wchar_t*. That said, wunder() returns std::basic_string<__wchar_t>,
+    // NOT plain __wchar_t*, despite the apparent convenience. Calling
+    // wunder(something).c_str() as an argument expression is fine: that
+    // std::basic_string instance will survive until the function returns.
+    // Calling c_str() on a std::basic_string local to wunder() would be
+    // Undefined Behavior: we'd be left with a pointer into a destroyed
+    // std::basic_string instance.
+
+    // It would be nice if, when wchar_t is the same as __wchar_t, this whole
+    // function would optimize away. However, we use it only for the arguments
+    // to make exactly one call to initialize BugSplat.
     inline std::basic_string<__wchar_t> wunder(const std::wstring& str)
     {
         return { str.begin(), str.end() };
     }
 
+    // when what we have in hand is a std::string, convert from UTF-8 using
+    // specific wstringize() overload
+    inline std::basic_string<__wchar_t> wunder(const std::string& str)
+    {
+        return wunder(wstringize(str));
+    }
+
     // Irritatingly, MiniDmpSender::setCallback() is defined to accept a
     // classic-C function pointer instead of an arbitrary C++ callable. If it
     // did accept a modern callable, we could pass a lambda that binds our
@@ -107,7 +122,7 @@ namespace
             // send the main viewer log file
             // widen to wstring, convert to __wchar_t, then pass c_str()
             sBugSplatSender->sendAdditionalFile(
-                wunder(wstringize(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log"))).c_str());
+                wunder(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log")).c_str());
         }
 
         return false;
@@ -559,7 +574,7 @@ bool LLAppViewerWin32::init()
 		std::string build_data_fname(
 			gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "build_data.json"));
 		std::ifstream inf(build_data_fname.c_str());
-		if (! inf.open())
+		if (! inf.is_open())
 		{
 			LL_WARNS() << "Can't initialize BugSplat, can't read '" << build_data_fname
 					   << "'" << LL_ENDL;
@@ -570,8 +585,9 @@ bool LLAppViewerWin32::init()
 			Json::Value build_data;
 			if (! reader.parse(inf, build_data, false)) // don't collect comments
 			{
+				// gah, the typo is baked into their API
 				LL_WARNS() << "Can't initialize BugSplat, can't parse '" << build_data_fname
-						   << "': " << reader.getFormattedErrorMessages() << LL_ENDL;
+						   << "': " << reader.getFormatedErrorMessages() << LL_ENDL;
 			}
 			else
 			{
@@ -579,7 +595,7 @@ bool LLAppViewerWin32::init()
 				if (! BugSplat_DB)
 				{
 					LL_WARNS() << "Can't initialize BugSplat, no 'BugSplat DB' entry in '"
-							   << build_data_fname "'" << LL_ENDL;
+							   << build_data_fname << "'" << LL_ENDL;
 				}
 				else
 				{
@@ -591,7 +607,7 @@ bool LLAppViewerWin32::init()
 
 					// have to convert normal wide strings to strings of __wchar_t
 					sBugSplatSender = new MiniDmpSender(
-						wunder(BugSplat_DB).c_str(),
+						wunder(BugSplat_DB.asString()).c_str(),
 						wunder(LL_TO_WSTRING(LL_VIEWER_CHANNEL)).c_str(),
 						wunder(version_string).c_str(),
 						nullptr);
-- 
cgit v1.2.3


From a5c17472fb3bbd2bc6fe188c450d2123963b5d6e Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Sat, 26 May 2018 08:44:57 -0400
Subject: SL-823: Fix typo in code that sets up BugSplat.

---
 indra/newview/llappviewerwin32.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index f9df2b88ed..c2cbce493c 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -550,7 +550,7 @@ bool LLAppViewerWin32::init()
 
 #else // LL_BUGSPLAT
 
-	if (gDirUtilp)
+	if (! gDirUtilp)
 	{
 		LL_WARNS() << "Can't initialize BugSplat, gDirUtilp not yet set" << LL_ENDL;
 	}
-- 
cgit v1.2.3


From 0fedc97f3f9bb83e93624343072c9b3dd62c63ae Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Wed, 30 May 2018 10:32:47 -0400
Subject: always run tests

---
 build.sh | 1 -
 1 file changed, 1 deletion(-)

diff --git a/build.sh b/build.sh
index cf18c3f541..1196cb3813 100755
--- a/build.sh
+++ b/build.sh
@@ -125,7 +125,6 @@ pre_build()
      -DRELEASE_CRASH_REPORTING:BOOL="$RELEASE_CRASH_REPORTING" \
      -DVIEWER_CHANNEL:STRING="${viewer_channel}" \
      -DGRID:STRING="\"$viewer_grid\"" \
-     -DLL_TESTS:BOOL="$run_tests" \
      -DTEMPLATE_VERIFIER_OPTIONS:STRING="$template_verifier_options" $template_verifier_master_url \
      "${SIGNING[@]}" \
     || fatal "$variant configuration failed"
-- 
cgit v1.2.3


From 837ca22924a4fc3ade6d592bc75c7921a6f4e668 Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Wed, 30 May 2018 10:36:23 -0400
Subject: set shell nullglob option

so that when a glob has no expansion you don't get the glob back (
*.sh expands to empty rather than to "*.sh")
---
 build.sh | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/build.sh b/build.sh
index 1196cb3813..b85e254c15 100755
--- a/build.sh
+++ b/build.sh
@@ -204,6 +204,8 @@ then
     exit 1
 fi
 
+shopt -s nullglob # if nothing matches a glob, expand to nothing
+
 initialize_build # provided by master buildscripts build.sh
 
 begin_section "autobuild initialize"
-- 
cgit v1.2.3


From d2fa5a53e8b91bd0aba10ab3917c722dc360b610 Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Wed, 30 May 2018 13:14:43 -0400
Subject: remove unused UNATTENDED cmake variable that generates warnings

---
 build.sh                     |  1 -
 indra/cmake/Variables.cmake  |  1 -
 indra/newview/CMakeLists.txt | 26 ++++++++++++--------------
 3 files changed, 12 insertions(+), 16 deletions(-)

diff --git a/build.sh b/build.sh
index b85e254c15..efe96a0a6a 100755
--- a/build.sh
+++ b/build.sh
@@ -120,7 +120,6 @@ pre_build()
 
     "$autobuild" configure --quiet -c $variant -- \
      -DPACKAGE:BOOL=ON \
-     -DUNATTENDED:BOOL=ON \
      -DHAVOK:BOOL="$HAVOK" \
      -DRELEASE_CRASH_REPORTING:BOOL="$RELEASE_CRASH_REPORTING" \
      -DVIEWER_CHANNEL:STRING="${viewer_channel}" \
diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake
index bd69c49856..b913d6398e 100644
--- a/indra/cmake/Variables.cmake
+++ b/indra/cmake/Variables.cmake
@@ -209,7 +209,6 @@ set(SIGNING_IDENTITY "" CACHE STRING "Specifies the signing identity to use, if
 
 set(VERSION_BUILD "0" CACHE STRING "Revision number passed in from the outside")
 set(USESYSTEMLIBS OFF CACHE BOOL "Use libraries from your system rather than Linden-supplied prebuilt libraries.")
-set(UNATTENDED OFF CACHE BOOL "Should be set to ON for building with VC Express editions.")
 
 set(USE_PRECOMPILED_HEADERS ON CACHE BOOL "Enable use of precompiled header directives where supported.")
 
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index cf275ef4b5..6b3db36efe 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1853,23 +1853,21 @@ if (WINDOWS)
 
     add_dependencies(${VIEWER_BINARY_NAME}
       SLPlugin
-   windows-crash-logger
+      windows-crash-logger
     )
 
     # sets the 'working directory' for debugging from visual studio.
-    if (NOT UNATTENDED)
-        add_custom_command(
-            TARGET ${VIEWER_BINARY_NAME} POST_BUILD
-            COMMAND ${CMAKE_SOURCE_DIR}/tools/vstool/vstool.exe
-            ARGS
-              --solution
-              ${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}.sln
-              --workingdir
-              ${VIEWER_BINARY_NAME}
-              "${CMAKE_CURRENT_SOURCE_DIR}"
-            COMMENT "Setting the ${VIEWER_BINARY_NAME} working directory for debugging."
-            )
-    endif (NOT UNATTENDED)
+    add_custom_command(
+        TARGET ${VIEWER_BINARY_NAME} POST_BUILD
+        COMMAND ${CMAKE_SOURCE_DIR}/tools/vstool/vstool.exe
+        ARGS
+          --solution
+          ${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}.sln
+          --workingdir
+          ${VIEWER_BINARY_NAME}
+          "${CMAKE_CURRENT_SOURCE_DIR}"
+        COMMENT "Setting the ${VIEWER_BINARY_NAME} working directory for debugging."
+        )
 
     if (PACKAGE)
       add_custom_command(
-- 
cgit v1.2.3


From 5caeacb3f6cf677cbec265ee6de733697dbf30ec Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 14 Jun 2018 10:55:38 -0400
Subject: SL-821: Create macOS symbol-file archive while packaging.

---
 indra/newview/viewer_manifest.py | 67 +++++++++++++++++++++++++++++++---------
 1 file changed, 53 insertions(+), 14 deletions(-)

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 68ad1db14d..8f2d04e9b8 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -26,19 +26,20 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 $/LicenseInfo$
 """
-import sys
-import os
-import os.path
-import shutil
 import errno
 import json
+import os
+import os.path
 import plistlib
 import random
 import re
+import shutil
 import stat
 import subprocess
+import sys
 import tarfile
 import time
+import zipfile
 
 viewer_dir = os.path.dirname(__file__)
 # Add indra/lib/python to our path so we don't have to muck with PYTHONPATH.
@@ -903,6 +904,9 @@ class DarwinManifest(ViewerManifest):
         launcher_app, launcher_icon = "Second Life Launcher.app", "secondlife.icns"
         viewer_app,   viewer_icon   = "Second Life Viewer.app",   "secondlife.icns"
 
+        # capture the path to the directory containing toplevel_app
+        parentdir = os.path.join(self.get_dst_prefix(), os.pardir)
+
         # copy over the build result (this is a no-op if run within the xcode script)
         self.path(os.path.join(self.args['configuration'], toplevel_app), dst="")
 
@@ -914,10 +918,12 @@ class DarwinManifest(ViewerManifest):
         # top-level Second Life application is only a container
         with self.prefix(src="", dst="Contents"):  # everything goes in Contents
             # top-level Info.plist is as generated by CMake
-            Info_plist = "Info.plist"
-            ## This self.path() call reports 0 files... skip?
-            self.path(Info_plist)
-            Info_plist = self.dst_path_of(Info_plist)
+            Info_plist = self.dst_path_of("Info.plist")
+            # except we twiddle these entries
+            Info = plistlib.readPlist(Info_plist)
+            Info["CFBundleGetInfoString"] = self.channel()
+            Info["CFBundleShortVersionString"] = '.'.join(self.args['version'])
+            plistlib.writePlist(Info, Info_plist)
 
             # the one file in top-level MacOS directory is the trampoline to
             # our nested launcher_app
@@ -1046,14 +1052,47 @@ open "%s" --args "$@"
                             # now do it, only without relativizing paths
                             os.rename(fromwhere, towhere)
 
-                        # NOTE: the -S argument to strip causes it to keep
-                        # enough info for annotated backtraces (i.e. function
-                        # names in the crash log). 'strip' with no arguments
-                        # yields a slightly smaller binary but makes crash
-                        # logs mostly useless. This may be desirable for the
-                        # final release. Or not.
                         if ("package" in self.args['actions'] or 
                             "unpacked" in self.args['actions']):
+                            # only if we're engaging BugSplat
+                            if "BUGSPLAT_DB" in os.environ:
+                                # Create a symbol archive BEFORE stripping the
+                                # binary.
+                                self.run_command(['dsymutil', os.path.join(here, 'Second Life')])
+                                # This should produce a Second Life.dSYM bundle directory.
+                                try:
+                                    # Now pretend we're Xcode making a .xcarchive file.
+                                    # Put it as a sibling of the top-level .app.
+                                    # From "Dave" at BugSplat support:
+                                    # "More from our Mac lead: I think zipping
+                                    # a folder containing the binary and
+                                    # symbols would be sufficient. Assuming
+                                    # symbol files are created with CMake. I'm
+                                    # not sure if CMake strips symbols into
+                                    # separate files at build time, and if so
+                                    # they're in a supported format."
+                                    xcarchive = os.path.join(parentdir,
+                                                             'Second Life.xcarchive.zip')
+                                    with zipfile.ZipFile(xcarchive, 'w',
+                                                         compression=zipfile.ZIP_DEFLATED) as zf:
+                                        print "Creating {}".format(xcarchive)
+                                        for base, dirs, files in os.walk(here):
+                                            for fn in files:
+                                                fullfn = os.path.join(base, fn)
+                                                relfn = os.path.relpath(fullfn, here)
+                                                print "  {}".format(relfn)
+                                                zf.write(fullfn, relfn)
+                                finally:
+                                    # Whether or not we were able to create the
+                                    # .xcarchive file, clean up the .dSYM bundle
+                                    shutil.rmtree(os.path.join(here, 'Second Life.dSYM'))
+
+                            # NOTE: the -S argument to strip causes it to keep
+                            # enough info for annotated backtraces (i.e. function
+                            # names in the crash log). 'strip' with no arguments
+                            # yields a slightly smaller binary but makes crash
+                            # logs mostly useless. This may be desirable for the
+                            # final release. Or not.
                             self.run_command(
                                 ['strip', '-S', self.dst_path_of('Second Life')])
 
-- 
cgit v1.2.3


From ab9a3db37f132c4d2d2b28005e28b2c0a347af98 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 14 Jun 2018 10:56:28 -0400
Subject: SL-821: Update to bugsplat build 516433

---
 autobuild.xml | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index fff03df2fe..f46fcea751 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -244,9 +244,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>2ef055fe7ec22c64394095ad8d7ab34e</string>
+              <string>e041aadbee147406fe76b58a5653be66</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18481/127993/bugsplat-1.0.2.515662-darwin64-515662.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/19728/137997/bugsplat-1.0.2.516433-darwin64-516433.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -256,9 +256,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>84b73bc8141b5d19a8dafabfe27eee93</string>
+              <string>812b38ca75f7401890e4984d55b5f333</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18483/128007/bugsplat-3.5.0.5.515662-windows-515662.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/19729/138004/bugsplat-3.5.0.5.516433-windows-516433.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -268,16 +268,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>bd44b033c07b417b675c3511fee468e2</string>
+              <string>6916a9ce5d74c5cacf8353254c3a0dd3</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18482/128001/bugsplat-3.5.0.5.515662-windows64-515662.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/19730/138011/bugsplat-3.5.0.5.516433-windows64-516433.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.0.2.515662</string>
+        <string>1.0.2.516433</string>
       </map>
       <key>chardet</key>
       <map>
@@ -1746,7 +1746,7 @@
           <key>darwin</key>
           <map>
             <key>archive</key>
-            <map>              
+            <map>
               <key>hash</key>
               <string>3855bd40f950e3c22739ae8f3ee2afc9</string>
               <key>url</key>
@@ -1759,10 +1759,10 @@
           <map>
             <key>archive</key>
             <map>
-              <key>hash</key>              
+              <key>hash</key>
               <string>d1521becaf21bf7233173722af63f57d</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/15257/98440/kdu-7.10.4.513518-darwin64-513518.tar.bz2</string>              
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/15257/98440/kdu-7.10.4.513518-darwin64-513518.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -1771,10 +1771,10 @@
           <map>
             <key>archive</key>
             <map>
-              <key>hash</key>              
+              <key>hash</key>
               <string>43d7a6a69a54534a736f132e9c81795b</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/15255/98451/kdu-7.10.4.513518-linux-513518.tar.bz2</string>              
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/15255/98451/kdu-7.10.4.513518-linux-513518.tar.bz2</string>
             </map>
             <key>name</key>
             <string>linux</string>
@@ -1806,11 +1806,11 @@
           <key>windows64</key>
           <map>
             <key>archive</key>
-            <map>              
+            <map>
               <key>hash</key>
               <string>da3b1ea90797b189d80ab5d50fdf05d4</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/15260/98469/kdu-7.10.4.513518-windows64-513518.tar.bz2</string>              
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/15260/98469/kdu-7.10.4.513518-windows64-513518.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
-- 
cgit v1.2.3


From ac2604a039bb9477cf9102dfccd77619a6061d7a Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 14 Jun 2018 11:31:17 -0400
Subject: SL-821: Avoid Breakpad (and signal handling in general) for BugSplat.

Pass LL_BUGSPLAT into llapp.cpp compile to be able to detect that.
---
 indra/llcommon/CMakeLists.txt |  5 +++++
 indra/llcommon/llapp.cpp      | 23 ++++++++++++++++-------
 2 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index d9eb13d65a..8977acb873 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -255,6 +255,11 @@ set(llcommon_HEADER_FILES
 set_source_files_properties(${llcommon_HEADER_FILES}
                             PROPERTIES HEADER_FILE_ONLY TRUE)
 
+if (DEFINED ENV{BUGSPLAT_DB})
+  set_source_files_properties(llapp.cpp
+    PROPERTIES COMPILE_DEFINITIONS "LL_BUGSPLAT")
+endif (DEFINED ENV{BUGSPLAT_DB})
+
 list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES})
 
 if(LLCOMMON_LINK_SHARED)
diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index 6cc9e804d4..421af3006e 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -392,7 +392,7 @@ void LLApp::setupErrorHandling(bool second_instance)
 
 #if LL_WINDOWS
 
-#if LL_SEND_CRASH_REPORTS
+#if LL_SEND_CRASH_REPORTS && ! defined(LL_BUGSPLAT)
 	EnableCrashingOnCrashes();
 
 	// This sets a callback to handle w32 signals to the console window.
@@ -454,8 +454,15 @@ void LLApp::setupErrorHandling(bool second_instance)
 			mExceptionHandler->set_handle_debug_exceptions(true);
 		}
 	}
-#endif
-#else
+#endif // LL_SEND_CRASH_REPORTS && ! defined(LL_BUGSPLAT)
+#else  // ! LL_WINDOWS
+
+#if defined(LL_BUGSPLAT)
+	// Don't install our own signal handlers -- BugSplat needs to hook them,
+	// or it's completely ineffectual.
+	bool installHandler = false;
+
+#else // ! LL_BUGSPLAT
 	//
 	// Start up signal handling.
 	//
@@ -463,9 +470,11 @@ void LLApp::setupErrorHandling(bool second_instance)
 	// thread, asynchronous signals can be delivered to any thread (in theory)
 	//
 	setup_signals();
-	
+
 	// Add google breakpad exception handler configured for Darwin/Linux.
 	bool installHandler = true;
+#endif // ! LL_BUGSPLAT
+
 #if LL_DARWIN
 	// For the special case of Darwin, we do not want to install the handler if
 	// the process is being debugged as the app will exit with value ABRT (6) if
@@ -498,7 +507,7 @@ void LLApp::setupErrorHandling(bool second_instance)
 		// installing the handler.
 		installHandler = true;
 	}
-	#endif
+	#endif // ! LL_RELEASE_FOR_DOWNLOAD
 
 	if(installHandler && (mExceptionHandler == 0))
 	{
@@ -514,9 +523,9 @@ void LLApp::setupErrorHandling(bool second_instance)
 		google_breakpad::MinidumpDescriptor desc(mDumpPath);
 	    mExceptionHandler = new google_breakpad::ExceptionHandler(desc, NULL, unix_minidump_callback, NULL, true, -1);
 	}
-#endif
+#endif // LL_LINUX
 
-#endif
+#endif // ! LL_WINDOWS
 	startErrorThread();
 }
 
-- 
cgit v1.2.3


From 0c32e329962454f3d3c44835f79b6e4159b4177d Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 14 Jun 2018 12:30:38 -0400
Subject: SL-821: Update to viewer-manager build 516441

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index f46fcea751..493720069b 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3314,9 +3314,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>4aefe12a3825d1b4b8370986d84792a2</string>
+              <string>3919570e9edecac56c1ef2d334370dc5</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/15295/98583/viewer_manager-1.0.513540-darwin64-513540.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/19742/138074/viewer_manager-1.0.516441-darwin64-516441.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3338,9 +3338,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>db96bc8a83e6577d31657586100bfc35</string>
+              <string>39add158bc6c4f975d7e17db34db8981</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/15298/98589/viewer_manager-1.0.513540-windows-513540.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/19744/138154/viewer_manager-1.0.516441-windows-516441.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3351,7 +3351,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>1.0.513540</string>
+        <string>1.0.516441</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From 8cfc16c81598d5511de486fefe5b884dab4887d7 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 14 Jun 2018 12:50:21 -0400
Subject: SL-821: Update to bugsplat build 516443

---
 autobuild.xml | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 493720069b..49b977bb6b 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -244,9 +244,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>e041aadbee147406fe76b58a5653be66</string>
+              <string>4a304f23c1a43dfd207837eb5673053a</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/19728/137997/bugsplat-1.0.2.516433-darwin64-516433.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/19746/138164/bugsplat-1.0.2.516443-darwin64-516443.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -256,9 +256,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>812b38ca75f7401890e4984d55b5f333</string>
+              <string>689ec5b71de416b2205dad46905c71f6</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/19729/138004/bugsplat-3.5.0.5.516433-windows-516433.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/19748/138180/bugsplat-3.5.0.5.516443-windows-516443.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -268,16 +268,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>6916a9ce5d74c5cacf8353254c3a0dd3</string>
+              <string>e49753b9b15fa06f078131d2d3a6f029</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/19730/138011/bugsplat-3.5.0.5.516433-windows64-516433.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/19747/138174/bugsplat-3.5.0.5.516443-windows64-516443.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.0.2.516433</string>
+        <string>1.0.2.516443</string>
       </map>
       <key>chardet</key>
       <map>
-- 
cgit v1.2.3


From 6cda0ecc964e4bcc989c97df7b4bc61b78e91592 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 14 Jun 2018 13:22:20 -0400
Subject: SL-821: Rename macOS Second Life executable to match the channel
 name.

This requires fixing CFBundleExecutable as well.
---
 indra/newview/viewer_manifest.py | 90 +++++++++++++++++++++++-----------------
 1 file changed, 52 insertions(+), 38 deletions(-)

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 8f2d04e9b8..4d6df04156 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -1005,34 +1005,7 @@ open "%s" --args "$@"
 
                 # -------------------- nested viewer_app ---------------------
                 with self.prefix(dst=os.path.join(viewer_app, "Contents")):
-                    # Info.plist is just like top-level one...
-                    Info = plistlib.readPlist(Info_plist)
-                    # except for these replacements:
-                    # (CFBundleExecutable may be moot: SL_Launcher directly
-                    # runs the executable, instead of launching the app)
-                    Info["CFBundleExecutable"] = "Second Life"
-                    Info["CFBundleIconFile"] = viewer_icon
-                    try:
-                        # https://www.bugsplat.com/docs/platforms/os-x#configuration
-                        Info["BugsplatServerURL"] = \
-                            "https://{BUGSPLAT_DB}.bugsplatsoftware.com/".format(**os.environ)
-                    except KeyError:
-                        # skip the assignment if there's no BUGSPLAT_DB variable
-                        pass
-                    self.put_in_file(
-                        plistlib.writePlistToString(Info),
-                        os.path.basename(Info_plist),
-                        "Info.plist")
-
-                    with self.prefix(src="", dst="Frameworks"):
-                        # CEF framework goes inside viewer_app/Contents/Frameworks.
-                        CEF_framework = "Chromium Embedded Framework.framework"
-                        self.path2basename(relpkgdir, CEF_framework)
-                        # Remember where we parked this car.
-                        CEF_framework = self.dst_path_of(CEF_framework)
-
-                        self.path2basename(relpkgdir, "BugsplatMac.framework")
-
+                    # defer Info.plist until after MacOS
                     with self.prefix(dst="MacOS"):
                         # CMake constructs the Second Life executable in the
                         # MacOS directory belonging to the top-level Second
@@ -1040,25 +1013,39 @@ open "%s" --args "$@"
                         here = self.get_dst_prefix()
                         relbase = os.path.realpath(os.path.dirname(Info_plist))
                         self.cmakedirs(here)
-                        for f in os.listdir(toplevel_MacOS):
-                            if f == os.path.basename(trampoline):
-                                # don't move the trampoline script we just made!
-                                continue
+                        # don't move the trampoline script we just made!
+                        executables = [f for f in os.listdir(toplevel_MacOS)
+                                       if f != os.path.basename(trampoline)]
+                        if not executables:
+                            raise ManifestError("Couldn't find viewer executable in {}!"
+                                                .format(toplevel_MacOS))
+                        for f in executables:
                             fromwhere = os.path.join(toplevel_MacOS, f)
-                            towhere   = os.path.join(here, f)
+                            towhere   = self.dst_path_of(f)
                             print "Moving %s => %s" % \
                                   (self.relpath(fromwhere, relbase),
                                    self.relpath(towhere, relbase))
                             # now do it, only without relativizing paths
                             os.rename(fromwhere, towhere)
 
+                        # Pick the biggest of the executables as the real viewer.
+                        # Make (size, filename) pairs; sort by size; pick the
+                        # last pair; take the filename entry from that.
+                        SecondLife = sorted((os.path.getsize(self.dst_path_of(f)), f)
+                                            for f in executables)[-1][1]
+                        # now rename it to match the channel name
+                        exename = self.channel()
+                        exepath = self.dst_path_of(exename)
+                        print "{} => {}".format(SecondLife, exename)
+                        os.rename(self.dst_path_of(SecondLife), exepath)
+
                         if ("package" in self.args['actions'] or 
                             "unpacked" in self.args['actions']):
                             # only if we're engaging BugSplat
                             if "BUGSPLAT_DB" in os.environ:
                                 # Create a symbol archive BEFORE stripping the
                                 # binary.
-                                self.run_command(['dsymutil', os.path.join(here, 'Second Life')])
+                                self.run_command(['dsymutil', exepath])
                                 # This should produce a Second Life.dSYM bundle directory.
                                 try:
                                     # Now pretend we're Xcode making a .xcarchive file.
@@ -1072,7 +1059,7 @@ open "%s" --args "$@"
                                     # separate files at build time, and if so
                                     # they're in a supported format."
                                     xcarchive = os.path.join(parentdir,
-                                                             'Second Life.xcarchive.zip')
+                                                             exename + '.xcarchive.zip')
                                     with zipfile.ZipFile(xcarchive, 'w',
                                                          compression=zipfile.ZIP_DEFLATED) as zf:
                                         print "Creating {}".format(xcarchive)
@@ -1085,7 +1072,7 @@ open "%s" --args "$@"
                                 finally:
                                     # Whether or not we were able to create the
                                     # .xcarchive file, clean up the .dSYM bundle
-                                    shutil.rmtree(os.path.join(here, 'Second Life.dSYM'))
+                                    shutil.rmtree(self.dst_path_of(exename + '.dSYM'))
 
                             # NOTE: the -S argument to strip causes it to keep
                             # enough info for annotated backtraces (i.e. function
@@ -1093,8 +1080,35 @@ open "%s" --args "$@"
                             # yields a slightly smaller binary but makes crash
                             # logs mostly useless. This may be desirable for the
                             # final release. Or not.
-                            self.run_command(
-                                ['strip', '-S', self.dst_path_of('Second Life')])
+                            self.run_command(['strip', '-S', exepath])
+
+                    # Info.plist is just like top-level one...
+                    Info = plistlib.readPlist(Info_plist)
+                    # except for these replacements:
+                    # (CFBundleExecutable may be moot: SL_Launcher directly
+                    # runs the executable, instead of launching the app)
+                    Info["CFBundleExecutable"] = exename
+                    Info["CFBundleIconFile"] = viewer_icon
+                    try:
+                        # https://www.bugsplat.com/docs/platforms/os-x#configuration
+                        Info["BugsplatServerURL"] = \
+                            "https://{BUGSPLAT_DB}.bugsplatsoftware.com/".format(**os.environ)
+                    except KeyError:
+                        # skip the assignment if there's no BUGSPLAT_DB variable
+                        pass
+                    self.put_in_file(
+                        plistlib.writePlistToString(Info),
+                        os.path.basename(Info_plist),
+                        "Info.plist")
+
+                    with self.prefix(src="", dst="Frameworks"):
+                        # CEF framework goes inside viewer_app/Contents/Frameworks.
+                        CEF_framework = "Chromium Embedded Framework.framework"
+                        self.path2basename(relpkgdir, CEF_framework)
+                        # Remember where we parked this car.
+                        CEF_framework = self.dst_path_of(CEF_framework)
+
+                        self.path2basename(relpkgdir, "BugsplatMac.framework")
 
                     with self.prefix(dst="Resources"):
                         # defer cross-platform file copies until we're in the right
-- 
cgit v1.2.3


From 1378547bb6a077fbed594ae7b92289dac5942183 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 14 Jun 2018 14:25:03 -0400
Subject: SL-821: Defend macOS packaging against multiple viewer_manifest runs

---
 indra/newview/viewer_manifest.py | 51 +++++++++++++++++++++++-----------------
 1 file changed, 29 insertions(+), 22 deletions(-)

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 4d6df04156..80370be109 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -27,6 +27,7 @@ Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 $/LicenseInfo$
 """
 import errno
+import glob
 import json
 import os
 import os.path
@@ -1016,28 +1017,34 @@ open "%s" --args "$@"
                         # don't move the trampoline script we just made!
                         executables = [f for f in os.listdir(toplevel_MacOS)
                                        if f != os.path.basename(trampoline)]
-                        if not executables:
-                            raise ManifestError("Couldn't find viewer executable in {}!"
-                                                .format(toplevel_MacOS))
-                        for f in executables:
-                            fromwhere = os.path.join(toplevel_MacOS, f)
-                            towhere   = self.dst_path_of(f)
-                            print "Moving %s => %s" % \
-                                  (self.relpath(fromwhere, relbase),
-                                   self.relpath(towhere, relbase))
-                            # now do it, only without relativizing paths
-                            os.rename(fromwhere, towhere)
-
-                        # Pick the biggest of the executables as the real viewer.
-                        # Make (size, filename) pairs; sort by size; pick the
-                        # last pair; take the filename entry from that.
-                        SecondLife = sorted((os.path.getsize(self.dst_path_of(f)), f)
-                                            for f in executables)[-1][1]
-                        # now rename it to match the channel name
-                        exename = self.channel()
-                        exepath = self.dst_path_of(exename)
-                        print "{} => {}".format(SecondLife, exename)
-                        os.rename(self.dst_path_of(SecondLife), exepath)
+                        if executables:
+                            # there are still executables in toplevel_MacOS
+                            for f in executables:
+                                fromwhere = os.path.join(toplevel_MacOS, f)
+                                towhere   = self.dst_path_of(f)
+                                print "Moving %s => %s" % \
+                                      (self.relpath(fromwhere, relbase),
+                                       self.relpath(towhere, relbase))
+                                # now do it, only without relativizing paths
+                                os.rename(fromwhere, towhere)
+
+                            # Pick the biggest of the executables as the real viewer.
+                            # Make (size, filename) pairs; sort by size; pick the
+                            # last pair; take the filename entry from that.
+                            SecondLife = sorted((os.path.getsize(self.dst_path_of(f)), f)
+                                                for f in executables)[-1][1]
+                            # now rename it to match the channel name
+                            exename = self.channel()
+                            exepath = self.dst_path_of(exename)
+                            print "{} => {}".format(SecondLife, exename)
+                            os.rename(self.dst_path_of(SecondLife), exepath)
+
+                        else:
+                            # executables already located 'here' -- pick the
+                            # biggest, as above
+                            exepath = sorted((os.path.getsize(f), f)
+                                             for f in glob.glob(os.path.join(here, '*')))[-1][1]
+                            exename = os.path.basename(exepath)
 
                         if ("package" in self.args['actions'] or 
                             "unpacked" in self.args['actions']):
-- 
cgit v1.2.3


From 67f6625c56406604197507c842496f031eb0986f Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 14 Jun 2018 17:03:25 -0400
Subject: SL-821: Continue changing macOS executable to match channel name.

Set our CMake 'product' variable to VIEWER_CHANNEL. This probably has far-
reaching implications, but it seems the expedient way to keep everything self-
consistent. Use ${product} in the DARWIN VIEWER_EXE_GLOBS used for Breakpad
symbol dumping instead of hardcoding 'Second Life'.

The Breakpad symbol dumping stanza was enclosed in nested (but not indented)
conditions. To these we add another condition: don't bother if we're using
BugSplat. Unify all three into a single horrendous outermost expression.

Fix the MACOSX_BUNDLE_INFO_STRING, and hence CFBundleGetInfoString, to
VIEWER_CHANNEL as well.

Our CMake MACOSX_BUNDLE_SHORT_VERSION_STRING was never used before -- we were
erroneously using MACOSX_BUNDLE_LONG_VERSION_STRING in the Info-SecondLife.plist
template even for CFBundleShortVersionString. Looks like a classic copy/paste
error. Fix that; also use four-part version number instead of three-part.

With those two changes, we shouldn't need to patch the top-level Info.plist in
viewer_manifest.py any more.

viewer_manifest.py still needs to move the viewer executable(s) to the
embedded viewer app bundle, but it no longer needs to rename the real
executable to the channel name since we've already dealt with that in CMake
land. This lets us unify the code that picks the biggest of those executables
in the first and second viewer_manifest.py runs.
---
 indra/newview/CMakeLists.txt        | 20 ++++++-------
 indra/newview/Info-SecondLife.plist |  2 +-
 indra/newview/viewer_manifest.py    | 59 ++++++++++++++-----------------------
 3 files changed, 33 insertions(+), 48 deletions(-)

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index ba261c8e91..5648e3eb02 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -2082,16 +2082,18 @@ if (LINUX)
 endif (LINUX)
 
 if (DARWIN)
-  # These all get set with PROPERTIES
-  set(product "Second Life")
+  # These all get set with PROPERTIES. It's not that the property names are
+  # magically known to CMake -- it's that these names are referenced in the
+  # Info-SecondLife.plist file in the configure_file() directive below.
+  set(product "${VIEWER_CHANNEL}")
   # this is the setting for the Python wrapper, see SL-322 and WRAPPER line in Info-SecondLife.plist
   set(MACOSX_WRAPPER_EXECUTABLE_NAME "SL_Launcher")
-  set(MACOSX_BUNDLE_INFO_STRING "Second Life Viewer")
+  set(MACOSX_BUNDLE_INFO_STRING "${VIEWER_CHANNEL}")
   set(MACOSX_BUNDLE_ICON_FILE "secondlife.icns")
   set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.secondlife.indra.viewer")
   set(MACOSX_BUNDLE_LONG_VERSION_STRING "${VIEWER_CHANNEL} ${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}")
   set(MACOSX_BUNDLE_BUNDLE_NAME "SecondLife")
-  set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${VIEWER_SHORT_VERSION}")
+  set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}")
   set(MACOSX_BUNDLE_BUNDLE_VERSION "${VIEWER_SHORT_VERSION}${VIEWER_MACOSX_PHASE}${VIEWER_REVISION}")
   set(MACOSX_BUNDLE_COPYRIGHT "Copyright © Linden Research, Inc. 2007")
   set(MACOSX_BUNDLE_NSMAIN_NIB_FILE "SecondLife.nib")
@@ -2179,7 +2181,7 @@ if (INSTALL)
   include(${CMAKE_CURRENT_SOURCE_DIR}/ViewerInstall.cmake)
 endif (INSTALL)
 
-if (PACKAGE)
+if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND NOT DEFINED ENV{BUGSPLAT_DB})
   set(SYMBOL_SEARCH_DIRS "")
   # Note that the path to VIEWER_SYMBOL_FILE must match that in ../../build.sh
   if (WINDOWS)
@@ -2198,8 +2200,8 @@ if (PACKAGE)
     list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/mac_crash_logger/${CMAKE_CFG_INTDIR}")
     list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/gstreamer010/${CMAKE_CFG_INTDIR}")
     set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-darwin-$ENV{AUTOBUILD_ADDRSIZE}.tar.bz2")
-    set(VIEWER_EXE_GLOBS "'Second Life' SLPlugin mac-crash-logger")
-    set(VIEWER_EXE_GLOBS "'Second Life' mac-crash-logger")
+    set(VIEWER_EXE_GLOBS "'${product}' SLPlugin mac-crash-logger")
+    set(VIEWER_EXE_GLOBS "'${product}' mac-crash-logger")
     set(VIEWER_LIB_GLOB "*.dylib")
   endif (DARWIN)
   if (LINUX)
@@ -2211,7 +2213,6 @@ if (PACKAGE)
     set(VIEWER_COPY_MANIFEST copy_l_viewer_manifest)
   endif (LINUX)
 
-  if(RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING)
   if(CMAKE_CFG_INTDIR STREQUAL ".")
       set(LLBUILD_CONFIG ${CMAKE_BUILD_TYPE})
   else(CMAKE_CFG_INTDIR STREQUAL ".")
@@ -2238,8 +2239,7 @@ if (PACKAGE)
     add_dependencies(generate_breakpad_symbols "${VIEWER_COPY_MANIFEST}")
   endif (WINDOWS OR LINUX)
   add_dependencies(llpackage generate_breakpad_symbols)
-  endif(RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING)
-endif (PACKAGE)
+endif ()
 
 if (LL_TESTS)
   # To add a viewer unit test, just add the test .cpp file below
diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist
index af4cf26ac6..8aabd6818b 100644
--- a/indra/newview/Info-SecondLife.plist
+++ b/indra/newview/Info-SecondLife.plist
@@ -21,7 +21,7 @@
 	<key>CFBundlePackageType</key>
 	<string>APPL</string>
 	<key>CFBundleShortVersionString</key>
-	<string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string>
+	<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
 	<key>CFBundleSignature</key>
 	<string>????</string>
 	<key>CFBundleVersion</key>
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 80370be109..49dc732457 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -27,7 +27,6 @@ Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 $/LicenseInfo$
 """
 import errno
-import glob
 import json
 import os
 import os.path
@@ -920,11 +919,6 @@ class DarwinManifest(ViewerManifest):
         with self.prefix(src="", dst="Contents"):  # everything goes in Contents
             # top-level Info.plist is as generated by CMake
             Info_plist = self.dst_path_of("Info.plist")
-            # except we twiddle these entries
-            Info = plistlib.readPlist(Info_plist)
-            Info["CFBundleGetInfoString"] = self.channel()
-            Info["CFBundleShortVersionString"] = '.'.join(self.args['version'])
-            plistlib.writePlist(Info, Info_plist)
 
             # the one file in top-level MacOS directory is the trampoline to
             # our nested launcher_app
@@ -1014,37 +1008,28 @@ open "%s" --args "$@"
                         here = self.get_dst_prefix()
                         relbase = os.path.realpath(os.path.dirname(Info_plist))
                         self.cmakedirs(here)
-                        # don't move the trampoline script we just made!
-                        executables = [f for f in os.listdir(toplevel_MacOS)
-                                       if f != os.path.basename(trampoline)]
-                        if executables:
-                            # there are still executables in toplevel_MacOS
-                            for f in executables:
-                                fromwhere = os.path.join(toplevel_MacOS, f)
-                                towhere   = self.dst_path_of(f)
-                                print "Moving %s => %s" % \
-                                      (self.relpath(fromwhere, relbase),
-                                       self.relpath(towhere, relbase))
-                                # now do it, only without relativizing paths
-                                os.rename(fromwhere, towhere)
-
-                            # Pick the biggest of the executables as the real viewer.
-                            # Make (size, filename) pairs; sort by size; pick the
-                            # last pair; take the filename entry from that.
-                            SecondLife = sorted((os.path.getsize(self.dst_path_of(f)), f)
-                                                for f in executables)[-1][1]
-                            # now rename it to match the channel name
-                            exename = self.channel()
-                            exepath = self.dst_path_of(exename)
-                            print "{} => {}".format(SecondLife, exename)
-                            os.rename(self.dst_path_of(SecondLife), exepath)
-
-                        else:
-                            # executables already located 'here' -- pick the
-                            # biggest, as above
-                            exepath = sorted((os.path.getsize(f), f)
-                                             for f in glob.glob(os.path.join(here, '*')))[-1][1]
-                            exename = os.path.basename(exepath)
+                        for f in os.listdir(toplevel_MacOS):
+                            if f == os.path.basename(trampoline):
+                                # don't move the trampoline script we just made!
+                                continue
+                            fromwhere = os.path.join(toplevel_MacOS, f)
+                            towhere   = self.dst_path_of(f)
+                            print "Moving %s => %s" % \
+                                  (self.relpath(fromwhere, relbase),
+                                   self.relpath(towhere, relbase))
+                            # now do it, only without relativizing paths
+                            os.rename(fromwhere, towhere)
+
+                        # Pick the biggest of the executables as the real viewer.
+                        # Make (basename, fullpath) pairs; for each pair,
+                        # expand to (size, basename, fullpath) triples; sort
+                        # by size; pick the last triple; take the basename and
+                        # fullpath from that.
+                        _, exename, exepath = \
+                            sorted((os.path.getsize(path), name, path)
+                                   for name, path in
+                                   ((name, os.path.join(here, name))
+                                    for name in os.listdir(here)))[-1]
 
                         if ("package" in self.args['actions'] or 
                             "unpacked" in self.args['actions']):
-- 
cgit v1.2.3


From 9b7640d70ae820a954634ecf0dae43dfb33c0d3a Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 14 Jun 2018 18:19:54 -0400
Subject: SL-821: Remove VSTool invocation to unbreak Windows TeamCity builds.

---
 indra/newview/CMakeLists.txt | 15 ---------------
 1 file changed, 15 deletions(-)

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 23337ddbfb..f7b30007c9 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1827,21 +1827,6 @@ if (WINDOWS)
    windows-crash-logger
     )
 
-    # sets the 'working directory' for debugging from visual studio.
-    if (NOT UNATTENDED)
-        add_custom_command(
-            TARGET ${VIEWER_BINARY_NAME} POST_BUILD
-            COMMAND ${CMAKE_SOURCE_DIR}/tools/vstool/vstool.exe
-            ARGS
-              --solution
-              ${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}.sln
-              --workingdir
-              ${VIEWER_BINARY_NAME}
-              "${CMAKE_CURRENT_SOURCE_DIR}"
-            COMMENT "Setting the ${VIEWER_BINARY_NAME} working directory for debugging."
-            )
-    endif (NOT UNATTENDED)
-
     if (PACKAGE)
       add_custom_command(
         OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/event_host.tar.bz2
-- 
cgit v1.2.3


From 16776975e708f881c4e806c8b9a82f0f270636a7 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 14 Jun 2018 18:25:17 -0400
Subject: SL-821: Merge removal of VSTool.exe invocation from CMake.

---
 indra/newview/CMakeLists.txt | 70 ++++++++++++++++++++++++++++++++++----------
 1 file changed, 55 insertions(+), 15 deletions(-)

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index f7b30007c9..ad65301d4d 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -3,7 +3,12 @@
 project(viewer)
 
 include(00-Common)
+# DON'T move Linking.cmake to its place in the alphabetized list below: it
+# sets variables on which the 3p .cmake files depend.
+include(Linking)
+
 include(Boost)
+include(bugsplat)
 include(BuildPackagesInfo)
 include(BuildVersion)
 include(CMakeCopyIfDifferent)
@@ -37,7 +42,6 @@ include(LLUI)
 include(LLVFS)
 include(LLWindow)
 include(LLXML)
-include(Linking)
 include(NDOF)
 include(NVAPI)
 include(OPENAL)
@@ -91,6 +95,7 @@ include_directories(
     ${LIBS_PREBUILT_DIR}/include/collada/1.4
     ${LLAPPEARANCE_INCLUDE_DIRS}
     ${CMAKE_CURRENT_SOURCE_DIR}
+    ${BUGSPLAT_INCLUDE_DIR}
     )
 
 include_directories(SYSTEM
@@ -530,6 +535,7 @@ set(viewer_SOURCE_FILES
     llscriptfloater.cpp
     llscrollingpanelparam.cpp
     llscrollingpanelparambase.cpp
+    llsculptidsize.cpp
     llsearchcombobox.cpp
     llsearchhistory.cpp
     llsecapi.cpp
@@ -1143,6 +1149,7 @@ set(viewer_HEADER_FILES
     llscriptruntimeperms.h
     llscrollingpanelparam.h
     llscrollingpanelparambase.h
+    llsculptidsize.h
     llsearchcombobox.h
     llsearchhistory.h
     llsecapi.h
@@ -1354,6 +1361,14 @@ if (DARWIN)
 
   # This should be compiled with the viewer.
   LIST(APPEND viewer_SOURCE_FILES llappdelegate-objc.mm)
+  set_source_files_properties(
+    llappdelegate-objc.mm
+    PROPERTIES
+    COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}"
+    # BugsplatMac is a module, imported with @import. That language feature
+    # demands these switches.
+    COMPILE_FLAGS "-fmodules -fcxx-modules"
+    )
 
   find_library(AGL_LIBRARY AGL)
   find_library(APPKIT_LIBRARY AppKit)
@@ -1366,6 +1381,7 @@ if (DARWIN)
     ${AGL_LIBRARY}
     ${IOKIT_LIBRARY}
     ${COREAUDIO_LIBRARY}
+    ${BUGSPLAT_LIBRARIES}
     )
 
   # Add resource files to the project.
@@ -1393,6 +1409,11 @@ endif (DARWIN)
 
 if (LINUX)
     LIST(APPEND viewer_SOURCE_FILES llappviewerlinux.cpp)
+    set_source_files_properties(
+      llappviewerlinux.cpp
+      PROPERTIES
+      COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}"
+      )
     LIST(APPEND viewer_SOURCE_FILES llappviewerlinux_api_dbus.cpp)
     SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed")
 
@@ -1409,6 +1430,11 @@ if (WINDOWS)
          llappviewerwin32.cpp
          llwindebug.cpp
          )
+    set_source_files_properties(
+      llappviewerwin32.cpp
+      PROPERTIES
+      COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}"
+      )
 
     list(APPEND viewer_HEADER_FILES
          llappviewerwin32.h
@@ -1691,6 +1717,11 @@ if (SDL_FOUND)
     )
 endif (SDL_FOUND)
 
+if (DEFINED ENV{BUGSPLAT_DB})
+  set_property(TARGET ${VIEWER_BINARY_NAME}
+    PROPERTY COMPILE_DEFINITIONS "LL_BUGSPLAT")
+endif (DEFINED ENV{BUGSPLAT_DB})
+
 # add package files
 file(GLOB EVENT_HOST_SCRIPT_GLOB_LIST
      ${CMAKE_CURRENT_SOURCE_DIR}/../viewer_components/*.py)
@@ -1789,7 +1820,7 @@ if (WINDOWS)
            ${SHARED_LIB_STAGING_DIR}/Debug/fmodexL.dll
           )
     endif (FMODEX)
-    
+
     add_custom_command(
       OUTPUT  ${CMAKE_CFG_INTDIR}/copy_touched.bat
       COMMAND ${PYTHON_EXECUTABLE}
@@ -1824,7 +1855,7 @@ if (WINDOWS)
 
     add_dependencies(${VIEWER_BINARY_NAME}
       SLPlugin
-   windows-crash-logger
+      windows-crash-logger
     )
 
     if (PACKAGE)
@@ -1888,8 +1919,8 @@ else (WINDOWS)
 endif (WINDOWS)
 
 # *NOTE: - this list is very sensitive to ordering, test carefully on all
-# platforms if you change the releative order of the entries here.
-# In particular, cmake 2.6.4 (when buidling with linux/makefile generators)
+# platforms if you change the relative order of the entries here.
+# In particular, cmake 2.6.4 (when building with linux/makefile generators)
 # appears to sometimes de-duplicate redundantly listed dependencies improperly.
 # To work around this, higher level modules should be listed before the modules
 # that they depend upon. -brad
@@ -1962,6 +1993,7 @@ target_link_libraries(${VIEWER_BINARY_NAME}
     ${LLPHYSICS_LIBRARIES}
     ${LLPHYSICSEXTENSIONS_LIBRARIES}
     ${LLAPPEARANCE_LIBRARIES}
+    ${BUGSPLAT_LIBRARIES}
     )
 
 set(ARTWORK_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE PATH
@@ -2037,25 +2069,35 @@ if (LINUX)
 endif (LINUX)
 
 if (DARWIN)
-  # These all get set with PROPERTIES
-  set(product "Second Life")
+  # These all get set with PROPERTIES. It's not that the property names are
+  # magically known to CMake -- it's that these names are referenced in the
+  # Info-SecondLife.plist file in the configure_file() directive below.
+  set(product "${VIEWER_CHANNEL}")
   # this is the setting for the Python wrapper, see SL-322 and WRAPPER line in Info-SecondLife.plist
   set(MACOSX_WRAPPER_EXECUTABLE_NAME "SL_Launcher")
-  set(MACOSX_BUNDLE_INFO_STRING "Second Life Viewer")
+  set(MACOSX_BUNDLE_INFO_STRING "${VIEWER_CHANNEL}")
   set(MACOSX_BUNDLE_ICON_FILE "secondlife.icns")
   set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.secondlife.indra.viewer")
   set(MACOSX_BUNDLE_LONG_VERSION_STRING "${VIEWER_CHANNEL} ${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}")
   set(MACOSX_BUNDLE_BUNDLE_NAME "SecondLife")
-  set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${VIEWER_SHORT_VERSION}")
+  set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}")
   set(MACOSX_BUNDLE_BUNDLE_VERSION "${VIEWER_SHORT_VERSION}${VIEWER_MACOSX_PHASE}${VIEWER_REVISION}")
   set(MACOSX_BUNDLE_COPYRIGHT "Copyright © Linden Research, Inc. 2007")
   set(MACOSX_BUNDLE_NSMAIN_NIB_FILE "SecondLife.nib")
   set(MACOSX_BUNDLE_NSPRINCIPAL_CLASS "NSApplication")
+
+  # https://blog.kitware.com/upcoming-in-cmake-2-8-12-osx-rpath-support/
+  set(CMAKE_MACOSX_RPATH 1)
   
   set_target_properties(
     ${VIEWER_BINARY_NAME}
     PROPERTIES
     OUTPUT_NAME "${product}"
+    # From Contents/MacOS/SecondLife, look in Contents/Frameworks
+    INSTALL_RPATH "@loader_path/../Frameworks"
+    # SIGH, as of 2018-05-24 (cmake 3.11.1) the INSTALL_RPATH property simply
+    # does not work. Try this:
+    LINK_FLAGS "-rpath @loader_path/../Frameworks"
     MACOSX_BUNDLE_INFO_PLIST
     "${CMAKE_CURRENT_SOURCE_DIR}/Info-SecondLife.plist"
     )
@@ -2126,7 +2168,7 @@ if (INSTALL)
   include(${CMAKE_CURRENT_SOURCE_DIR}/ViewerInstall.cmake)
 endif (INSTALL)
 
-if (PACKAGE)
+if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND NOT DEFINED ENV{BUGSPLAT_DB})
   set(SYMBOL_SEARCH_DIRS "")
   # Note that the path to VIEWER_SYMBOL_FILE must match that in ../../build.sh
   if (WINDOWS)
@@ -2145,8 +2187,8 @@ if (PACKAGE)
     list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/mac_crash_logger/${CMAKE_CFG_INTDIR}")
     list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/gstreamer010/${CMAKE_CFG_INTDIR}")
     set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-darwin-$ENV{AUTOBUILD_ADDRSIZE}.tar.bz2")
-    set(VIEWER_EXE_GLOBS "'Second Life' SLPlugin mac-crash-logger")
-    set(VIEWER_EXE_GLOBS "'Second Life' mac-crash-logger")
+    set(VIEWER_EXE_GLOBS "'${product}' SLPlugin mac-crash-logger")
+    set(VIEWER_EXE_GLOBS "'${product}' mac-crash-logger")
     set(VIEWER_LIB_GLOB "*.dylib")
   endif (DARWIN)
   if (LINUX)
@@ -2158,7 +2200,6 @@ if (PACKAGE)
     set(VIEWER_COPY_MANIFEST copy_l_viewer_manifest)
   endif (LINUX)
 
-  if(RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING)
   if(CMAKE_CFG_INTDIR STREQUAL ".")
       set(LLBUILD_CONFIG ${CMAKE_BUILD_TYPE})
   else(CMAKE_CFG_INTDIR STREQUAL ".")
@@ -2185,8 +2226,7 @@ if (PACKAGE)
     add_dependencies(generate_breakpad_symbols "${VIEWER_COPY_MANIFEST}")
   endif (WINDOWS OR LINUX)
   add_dependencies(llpackage generate_breakpad_symbols)
-  endif(RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING)
-endif (PACKAGE)
+endif ()
 
 if (LL_TESTS)
   # To add a viewer unit test, just add the test .cpp file below
-- 
cgit v1.2.3


From 786f80b9426742f0c9fe964ce54168b7005d92c8 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 14 Jun 2018 19:03:17 -0400
Subject: SL-821: When using BugSplat, don't try to upload Breakpad symbols.

With BugSplat, the Breakpad symbol files aren't generated; attempting to post
them to codeticket will fail the build.
---
 build.sh | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/build.sh b/build.sh
index efe96a0a6a..56ec57818c 100755
--- a/build.sh
+++ b/build.sh
@@ -114,6 +114,8 @@ pre_build()
          if [ -n "${BUGSPLAT_DB:-}" ]
          then echo export BUGSPLAT_DB
               export BUGSPLAT_DB
+              echo RELEASE_CRASH_REPORTING=OFF
+              RELEASE_CRASH_REPORTING=OFF
          fi
     fi
     set -x
-- 
cgit v1.2.3


From 24e71a45ae68cd15d62f58eea7f318fbc5f33912 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 14 Jun 2018 21:11:36 -0400
Subject: SL-821: Update bugsplat to codeticket version 516501.

---
 autobuild.xml | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 49b977bb6b..285449fa5a 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -244,9 +244,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>4a304f23c1a43dfd207837eb5673053a</string>
+              <string>45d772624651dd2ec256ebc4be5fdb5e</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/19746/138164/bugsplat-1.0.2.516443-darwin64-516443.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/19829/138853/bugsplat-1.0.2.516501-darwin64-516501.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -256,9 +256,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>689ec5b71de416b2205dad46905c71f6</string>
+              <string>7fca1d1d04b8e926a6afd14fff206ff0</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/19748/138180/bugsplat-3.5.0.5.516443-windows-516443.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/19831/138867/bugsplat-3.5.0.5.516501-windows-516501.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -268,16 +268,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>e49753b9b15fa06f078131d2d3a6f029</string>
+              <string>dc760b8760e6f8a8d27de3a9d7adf5c1</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/19747/138174/bugsplat-3.5.0.5.516443-windows64-516443.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/19830/138860/bugsplat-3.5.0.5.516501-windows64-516501.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.0.2.516443</string>
+        <string>1.0.2.516501</string>
       </map>
       <key>chardet</key>
       <map>
-- 
cgit v1.2.3


From bb757b937c6cde205c59a80e83d8f970523edeeb Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 15 Jun 2018 11:28:01 -0400
Subject: SL-820: gDirUtilp is never nullptr.

It might point to an uninitialized LLDir, but that's a whole separate problem,
one that wouldn't be detected by checking for nullptr. If we hit that, time to
change to an LLSingleton.
---
 indra/newview/llappviewerwin32.cpp | 79 +++++++++++++++++---------------------
 1 file changed, 36 insertions(+), 43 deletions(-)

diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 4701e7bbed..3efc94d7b5 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -565,61 +565,54 @@ bool LLAppViewerWin32::init()
 
 #else // LL_BUGSPLAT
 
-	if (! gDirUtilp)
+	std::string build_data_fname(
+		gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "build_data.json"));
+	std::ifstream inf(build_data_fname.c_str());
+	if (! inf.is_open())
 	{
-		LL_WARNS() << "Can't initialize BugSplat, gDirUtilp not yet set" << LL_ENDL;
+		LL_WARNS() << "Can't initialize BugSplat, can't read '" << build_data_fname
+				   << "'" << LL_ENDL;
 	}
 	else
 	{
-		std::string build_data_fname(
-			gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "build_data.json"));
-		std::ifstream inf(build_data_fname.c_str());
-		if (! inf.is_open())
+		Json::Reader reader;
+		Json::Value build_data;
+		if (! reader.parse(inf, build_data, false)) // don't collect comments
 		{
-			LL_WARNS() << "Can't initialize BugSplat, can't read '" << build_data_fname
-					   << "'" << LL_ENDL;
+			// gah, the typo is baked into their API
+			LL_WARNS() << "Can't initialize BugSplat, can't parse '" << build_data_fname
+					   << "': " << reader.getFormatedErrorMessages() << LL_ENDL;
 		}
 		else
 		{
-			Json::Reader reader;
-			Json::Value build_data;
-			if (! reader.parse(inf, build_data, false)) // don't collect comments
+			Json::Value BugSplat_DB = build_data["BugSplat DB"];
+			if (! BugSplat_DB)
 			{
-				// gah, the typo is baked into their API
-				LL_WARNS() << "Can't initialize BugSplat, can't parse '" << build_data_fname
-						   << "': " << reader.getFormatedErrorMessages() << LL_ENDL;
+				LL_WARNS() << "Can't initialize BugSplat, no 'BugSplat DB' entry in '"
+						   << build_data_fname << "'" << LL_ENDL;
 			}
 			else
 			{
-				Json::Value BugSplat_DB = build_data["BugSplat DB"];
-				if (! BugSplat_DB)
-				{
-					LL_WARNS() << "Can't initialize BugSplat, no 'BugSplat DB' entry in '"
-							   << build_data_fname << "'" << LL_ENDL;
-				}
-				else
-				{
-					// Got BugSplat_DB, onward!
-					std::wstring version_string(WSTRINGIZE(LL_VIEWER_VERSION_MAJOR << '.' <<
-														   LL_VIEWER_VERSION_MINOR << '.' <<
-														   LL_VIEWER_VERSION_PATCH << '.' <<
-														   LL_VIEWER_VERSION_BUILD));
-
-					// have to convert normal wide strings to strings of __wchar_t
-					sBugSplatSender = new MiniDmpSender(
-						wunder(BugSplat_DB.asString()).c_str(),
-						wunder(LL_TO_WSTRING(LL_VIEWER_CHANNEL)).c_str(),
-						wunder(version_string).c_str(),
-						nullptr);
-					sBugSplatSender->setCallback(bugsplatSendLog);
-
-					// engage stringize() overload that converts from wstring
-					LL_INFOS() << "Engaged BugSplat(" << LL_TO_STRING(LL_VIEWER_CHANNEL)
-							   << stringize(version_string) << ')' << LL_ENDL;
-				} // got BugSplat_DB
-			} // parsed build_data.json
-		} // opened build_data.json
-	}  // gDirUtilp set
+				// Got BugSplat_DB, onward!
+				std::wstring version_string(WSTRINGIZE(LL_VIEWER_VERSION_MAJOR << '.' <<
+													   LL_VIEWER_VERSION_MINOR << '.' <<
+													   LL_VIEWER_VERSION_PATCH << '.' <<
+													   LL_VIEWER_VERSION_BUILD));
+
+				// have to convert normal wide strings to strings of __wchar_t
+				sBugSplatSender = new MiniDmpSender(
+					wunder(BugSplat_DB.asString()).c_str(),
+					wunder(LL_TO_WSTRING(LL_VIEWER_CHANNEL)).c_str(),
+					wunder(version_string).c_str(),
+					nullptr);
+				sBugSplatSender->setCallback(bugsplatSendLog);
+
+				// engage stringize() overload that converts from wstring
+				LL_INFOS() << "Engaged BugSplat(" << LL_TO_STRING(LL_VIEWER_CHANNEL)
+						   << stringize(version_string) << ')' << LL_ENDL;
+			} // got BugSplat_DB
+		} // parsed build_data.json
+	} // opened build_data.json
 
 #endif // LL_BUGSPLAT
 #endif // LL_SEND_CRASH_REPORTS
-- 
cgit v1.2.3


From f26ba0f0eccce2e6b66554dc1132ff29e6d0f3b1 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 15 Jun 2018 11:45:03 -0400
Subject: SL-820: Make bugsplat.cmake and its symbols conditional.

---
 indra/newview/CMakeLists.txt | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index ad65301d4d..d9c267324b 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -8,7 +8,9 @@ include(00-Common)
 include(Linking)
 
 include(Boost)
-include(bugsplat)
+if (DEFINED ENV{BUGSPLAT_DB})
+  include(bugsplat)
+endif (DEFINED ENV{BUGSPLAT_DB})
 include(BuildPackagesInfo)
 include(BuildVersion)
 include(CMakeCopyIfDifferent)
@@ -95,8 +97,13 @@ include_directories(
     ${LIBS_PREBUILT_DIR}/include/collada/1.4
     ${LLAPPEARANCE_INCLUDE_DIRS}
     ${CMAKE_CURRENT_SOURCE_DIR}
+    )
+
+if (DEFINED ENV{BUGSPLAT_DB})
+  include_directories(
     ${BUGSPLAT_INCLUDE_DIR}
     )
+endif (DEFINED ENV{BUGSPLAT_DB})
 
 include_directories(SYSTEM
     ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
@@ -1381,9 +1388,14 @@ if (DARWIN)
     ${AGL_LIBRARY}
     ${IOKIT_LIBRARY}
     ${COREAUDIO_LIBRARY}
-    ${BUGSPLAT_LIBRARIES}
     )
 
+  if (DEFINED ENV{BUGSPLAT_DB})
+    list(APPEND viewer_LIBRARIES
+      ${BUGSPLAT_LIBRARIES}
+      )
+  endif (DEFINED ENV{BUGSPLAT_DB})
+
   # Add resource files to the project.
   set(viewer_RESOURCE_FILES
     secondlife.icns
@@ -1993,8 +2005,13 @@ target_link_libraries(${VIEWER_BINARY_NAME}
     ${LLPHYSICS_LIBRARIES}
     ${LLPHYSICSEXTENSIONS_LIBRARIES}
     ${LLAPPEARANCE_LIBRARIES}
+    )
+
+if (DEFINED ENV{BUGSPLAT_DB})
+  target_link_libraries(${VIEWER_BINARY_NAME}
     ${BUGSPLAT_LIBRARIES}
     )
+endif (DEFINED ENV{BUGSPLAT_DB})
 
 set(ARTWORK_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE PATH
     "Path to artwork files.")
-- 
cgit v1.2.3


From 448e82f39c472c82620bb52e0644e258b363d562 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 15 Jun 2018 16:48:20 -0400
Subject: SL-821: Try to add SecondLife.log file to Mac BugSplat crash report.

Introduce new header file llappviewermacosx-for-objc.h to publish for
llappdelegate-objc.mm and other Objective-C++ consumers the free functions in
llappviewermacosx.cpp they consume. These were never before declared in any
header file. Apparently, to date, we've been trusting to luck that
Objective-C++ will infer the correct signature from calls -- and that the
calls are correct with respect to the function definitions.  :-P

This gives us a place to introduce a new getLogFilePathname() function to
query LLDir. (We don't simply #include "lldir.h" because of the pervasive use
of BOOL in viewer headers; BOOL means something very different in Objective-C++.)
---
 indra/newview/llappdelegate-objc.mm        | 17 +++++++++------
 indra/newview/llappviewermacosx-for-objc.h | 34 ++++++++++++++++++++++++++++++
 indra/newview/llappviewermacosx.cpp        |  6 ++++++
 3 files changed, 51 insertions(+), 6 deletions(-)
 create mode 100644 indra/newview/llappviewermacosx-for-objc.h

diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm
index 8e1ad169c9..ad5398721b 100644
--- a/indra/newview/llappdelegate-objc.mm
+++ b/indra/newview/llappdelegate-objc.mm
@@ -29,6 +29,7 @@
 @import BugsplatMac;
 #endif
 #include "llwindowmacosx-objc.h"
+#include "llappviewermacosx-for-objc.h"
 #include <Carbon/Carbon.h> // Used for Text Input Services ("Safe" API - it's supported)
 
 @implementation LLAppDelegate
@@ -189,18 +190,22 @@
     return true;
 }
 
-#if 0 // defined(LL_BUGSPLAT)
+#if defined(LL_BUGSPLAT)
 
 @implementation BugsplatStartupManagerDelegate
 
 - (BugsplatAttachment *)attachmentForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager {
-    NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@"example" withExtension:@"json"];
-    NSData *data = [NSData dataWithContentsOfURL:fileURL];
-    
+    std::string logfile = getLogFilePathname();
+    NSString *ns_logfile = [NSString stringWithCString:logfile->c_str()
+                                              encoding:NSUTF8StringEncoding];
+    NSData *data = [NSData dataWithContentsOfFile:ns_logfile];
+
+    // Apologies for the hard-coded log-file basename, but I do not know the
+    // incantation for "$(basename "$logfile")" in this language.
     BugsplatAttachment *attachment = 
-        [[BugsplatAttachment alloc] initWithFilename:@"example.json"
+        [[BugsplatAttachment alloc] initWithFilename:@"SecondLife.log"
                                       attachmentData:data
-                                         contentType:@"application/json"];
+                                         contentType:@"text/plain"];
     return attachment;
 }
 
diff --git a/indra/newview/llappviewermacosx-for-objc.h b/indra/newview/llappviewermacosx-for-objc.h
new file mode 100644
index 0000000000..ef5d90bfef
--- /dev/null
+++ b/indra/newview/llappviewermacosx-for-objc.h
@@ -0,0 +1,34 @@
+/**
+ * @file   llappviewermacosx-for-objc.h
+ * @author Nat Goodspeed
+ * @date   2018-06-15
+ * @brief  llappviewermacosx.h publishes the C++ API for
+ *         llappviewermacosx.cpp, just as
+ *         llappviewermacosx-objc.h publishes the Objective-C++ API for
+ *         llappviewermacosx-objc.mm.
+ *
+ *         This header is intended to publish for Objective-C++ consumers a
+ *         subset of the C++ API presented by llappviewermacosx.cpp. It's a
+ *         subset because, if an Objective-C++ consumer were to #include
+ *         the full llappviewermacosx.h, we would almost surely run into
+ *         trouble due to the discrepancy between Objective-C++'s BOOL versus
+ *         classic Microsoft/Linden BOOL.
+ * 
+ * $LicenseInfo:firstyear=2018&license=viewerlgpl$
+ * Copyright (c) 2018, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_LLAPPVIEWERMACOSX_FOR_OBJC_H)
+#define LL_LLAPPVIEWERMACOSX_FOR_OBJC_H
+
+#include <string>
+
+bool initViewer();
+void handleUrl(const char* url_utf8);
+bool pumpMainLoop();
+void handleQuit();
+void cleanupViewer();
+std::string getLogFilePathname();
+
+#endif /* ! defined(LL_LLAPPVIEWERMACOSX_FOR_OBJC_H) */
diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp
index d472f8926b..cdbdb23d9a 100644
--- a/indra/newview/llappviewermacosx.cpp
+++ b/indra/newview/llappviewermacosx.cpp
@@ -36,6 +36,7 @@
 #include "llappviewermacosx-objc.h"
 
 #include "llappviewermacosx.h"
+#include "llappviewermacosx-for-objc.h"
 #include "llwindowmacosx-objc.h"
 #include "llcommandlineparser.h"
 
@@ -147,6 +148,11 @@ void cleanupViewer()
 	gViewerAppPtr = NULL;
 }
 
+std::string getLogFilePathname()
+{
+    return gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log");
+}
+
 int main( int argc, char **argv ) 
 {
 	// Store off the command line args for use later.
-- 
cgit v1.2.3


From 1d7687efb2bb8785b6a2a2f620d05fe1cb84f922 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 15 Jun 2018 17:58:00 -0400
Subject: SL-821: Fix up Objective-C++ syntax errors.

---
 indra/newview/llappdelegate-objc.mm | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm
index ad5398721b..008203fd32 100644
--- a/indra/newview/llappdelegate-objc.mm
+++ b/indra/newview/llappdelegate-objc.mm
@@ -190,13 +190,15 @@
     return true;
 }
 
+@end
+
 #if defined(LL_BUGSPLAT)
 
 @implementation BugsplatStartupManagerDelegate
 
 - (BugsplatAttachment *)attachmentForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager {
     std::string logfile = getLogFilePathname();
-    NSString *ns_logfile = [NSString stringWithCString:logfile->c_str()
+    NSString *ns_logfile = [NSString stringWithCString:logfile.c_str()
                                               encoding:NSUTF8StringEncoding];
     NSData *data = [NSData dataWithContentsOfFile:ns_logfile];
 
@@ -209,6 +211,6 @@
     return attachment;
 }
 
-#endif // LL_BUGSPLAT
-
 @end
+
+#endif // LL_BUGSPLAT
-- 
cgit v1.2.3


From b889c15cddccdfa5dd164388a566e4c63bbdf6f3 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 18 Jun 2018 12:57:12 -0400
Subject: SL-821: Fix BugSplat attachment method override per BugSplat support.

The example code on the BugSplat documentation page
https://www.bugsplat.com/docs/platforms/os-x#configuration
omits certain essential Objective-C++ boilerplate incantations. Adding them
at least compiles successfully.
---
 indra/newview/llappdelegate-objc.mm | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm
index 008203fd32..11a4b5d48e 100644
--- a/indra/newview/llappdelegate-objc.mm
+++ b/indra/newview/llappdelegate-objc.mm
@@ -194,7 +194,11 @@
 
 #if defined(LL_BUGSPLAT)
 
-@implementation BugsplatStartupManagerDelegate
+// per Geoff at BugSplat support
+@interface AppDelegate : NSObject <NSApplicationDelegate, BugsplatStartupManagerDelegate>
+@end
+
+@implementation AppDelegate
 
 - (BugsplatAttachment *)attachmentForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager {
     std::string logfile = getLogFilePathname();
-- 
cgit v1.2.3


From 6e790fc27d22e80527789cf8e783be6c90a23505 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 18 Jun 2018 16:38:49 -0400
Subject: SL-821: Add logging in the macOS BugSplat attachment override.

---
 indra/newview/llappdelegate-objc.mm        | 4 ++++
 indra/newview/llappviewermacosx-for-objc.h | 1 +
 indra/newview/llappviewermacosx.cpp        | 5 +++++
 3 files changed, 10 insertions(+)

diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm
index 11a4b5d48e..2c2302ecfb 100644
--- a/indra/newview/llappdelegate-objc.mm
+++ b/indra/newview/llappdelegate-objc.mm
@@ -202,9 +202,12 @@
 
 - (BugsplatAttachment *)attachmentForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager {
     std::string logfile = getLogFilePathname();
+    infos("Reached attachmentForBugsplatStartupManager with:");
+    infos(logfile);
     NSString *ns_logfile = [NSString stringWithCString:logfile.c_str()
                                               encoding:NSUTF8StringEncoding];
     NSData *data = [NSData dataWithContentsOfFile:ns_logfile];
+    infos("Read logfile");
 
     // Apologies for the hard-coded log-file basename, but I do not know the
     // incantation for "$(basename "$logfile")" in this language.
@@ -212,6 +215,7 @@
         [[BugsplatAttachment alloc] initWithFilename:@"SecondLife.log"
                                       attachmentData:data
                                          contentType:@"text/plain"];
+    infos("returning attachment");
     return attachment;
 }
 
diff --git a/indra/newview/llappviewermacosx-for-objc.h b/indra/newview/llappviewermacosx-for-objc.h
index ef5d90bfef..e45cb85861 100644
--- a/indra/newview/llappviewermacosx-for-objc.h
+++ b/indra/newview/llappviewermacosx-for-objc.h
@@ -30,5 +30,6 @@ bool pumpMainLoop();
 void handleQuit();
 void cleanupViewer();
 std::string getLogFilePathname();
+void infos(const std::string& message);
 
 #endif /* ! defined(LL_LLAPPVIEWERMACOSX_FOR_OBJC_H) */
diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp
index cdbdb23d9a..562e7ebfde 100644
--- a/indra/newview/llappviewermacosx.cpp
+++ b/indra/newview/llappviewermacosx.cpp
@@ -153,6 +153,11 @@ std::string getLogFilePathname()
     return gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log");
 }
 
+void infos(const std::string& message)
+{
+    LL_INFOS() << message << LL_ENDL;
+}
+
 int main( int argc, char **argv ) 
 {
 	// Store off the command line args for use later.
-- 
cgit v1.2.3


From c9898f1b69a53cd5d3e7bb49f77a764dde43772e Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 19 Jun 2018 09:37:28 -0400
Subject: SL-821: Try again to override BugSplat Obj-C methods.

---
 indra/newview/llappdelegate-objc.mm | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm
index 2c2302ecfb..68b803c367 100644
--- a/indra/newview/llappdelegate-objc.mm
+++ b/indra/newview/llappdelegate-objc.mm
@@ -27,6 +27,9 @@
 #import "llappdelegate-objc.h"
 #if defined(LL_BUGSPLAT)
 @import BugsplatMac;
+// derived from BugsplatMac's BugsplatTester/AppDelegate.m
+@interface LLAppDelegate () <BugsplatStartupManagerDelegate>
+@end
 #endif
 #include "llwindowmacosx-objc.h"
 #include "llappviewermacosx-for-objc.h"
@@ -190,15 +193,14 @@
     return true;
 }
 
-@end
-
 #if defined(LL_BUGSPLAT)
 
-// per Geoff at BugSplat support
-@interface AppDelegate : NSObject <NSApplicationDelegate, BugsplatStartupManagerDelegate>
-@end
-
-@implementation AppDelegate
+- (NSString *)applicationLogForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager
+{
+//  return NSStringFromSelector(_cmd);
+    infos("Reached applicationLogForBugsplatStartupManager");
+    return @"[contents of SecondLife.log]";
+}
 
 - (BugsplatAttachment *)attachmentForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager {
     std::string logfile = getLogFilePathname();
@@ -219,6 +221,6 @@
     return attachment;
 }
 
-@end
-
 #endif // LL_BUGSPLAT
+
+@end
-- 
cgit v1.2.3


From 3376b2acfbea2f6d2d8f79ecf890702e1ab60ae3 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 19 Jun 2018 13:34:08 -0400
Subject: SL-821: Another Objective-C++ magic incantation from BugSplat
 support.

---
 indra/newview/llappdelegate-objc.mm | 1 +
 1 file changed, 1 insertion(+)

diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm
index 68b803c367..2ee294e1e6 100644
--- a/indra/newview/llappdelegate-objc.mm
+++ b/indra/newview/llappdelegate-objc.mm
@@ -76,6 +76,7 @@
 	// https://www.bugsplat.com/docs/platforms/os-x#initialization
 //	[BugsplatStartupManager sharedManager].autoSubmitCrashReport = YES;
 //	[BugsplatStartupManager sharedManager].askUserDetails = NO;
+    [BugsplatStartupManager sharedManager].delegate = self;
 	[[BugsplatStartupManager sharedManager] start];
 #endif
 }
-- 
cgit v1.2.3


From d26c931ae2c5d33adc5fc20842b7be838a2822b4 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 19 Jun 2018 15:08:56 -0400
Subject: SL-821: Send the SecondLife.log from the previous (crashed) run.

Also clean up log messages.
---
 indra/newview/llappdelegate-objc.mm        | 16 +++++++++++-----
 indra/newview/llappviewermacosx-for-objc.h |  2 +-
 indra/newview/llappviewermacosx.cpp        |  4 ++--
 3 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm
index 2ee294e1e6..4510f4070f 100644
--- a/indra/newview/llappdelegate-objc.mm
+++ b/indra/newview/llappdelegate-objc.mm
@@ -196,21 +196,27 @@
 
 #if defined(LL_BUGSPLAT)
 
+#if 0
+// Apparently this override method only contributes the User Description field
+// of BugSplat's All Crashes table. Despite the method name, it would seem to
+// be a bad place to try to stuff all of SecondLife.log.
 - (NSString *)applicationLogForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager
 {
 //  return NSStringFromSelector(_cmd);
     infos("Reached applicationLogForBugsplatStartupManager");
     return @"[contents of SecondLife.log]";
 }
+#endif
 
 - (BugsplatAttachment *)attachmentForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager {
-    std::string logfile = getLogFilePathname();
-    infos("Reached attachmentForBugsplatStartupManager with:");
-    infos(logfile);
+    // We get the *old* log file pathname (for SecondLife.old) because it's on
+    // the run *following* the crash that BugsplatStartupManager notices that
+    // the previous run crashed and calls this override. By that time, we've
+    // already renamed SecondLife.log to SecondLife.old.
+    std::string logfile = getOldLogFilePathname();
     NSString *ns_logfile = [NSString stringWithCString:logfile.c_str()
                                               encoding:NSUTF8StringEncoding];
     NSData *data = [NSData dataWithContentsOfFile:ns_logfile];
-    infos("Read logfile");
 
     // Apologies for the hard-coded log-file basename, but I do not know the
     // incantation for "$(basename "$logfile")" in this language.
@@ -218,7 +224,7 @@
         [[BugsplatAttachment alloc] initWithFilename:@"SecondLife.log"
                                       attachmentData:data
                                          contentType:@"text/plain"];
-    infos("returning attachment");
+    infos("attachmentForBugsplatStartupManager: attaching " + logfile);
     return attachment;
 }
 
diff --git a/indra/newview/llappviewermacosx-for-objc.h b/indra/newview/llappviewermacosx-for-objc.h
index e45cb85861..c439297611 100644
--- a/indra/newview/llappviewermacosx-for-objc.h
+++ b/indra/newview/llappviewermacosx-for-objc.h
@@ -29,7 +29,7 @@ void handleUrl(const char* url_utf8);
 bool pumpMainLoop();
 void handleQuit();
 void cleanupViewer();
-std::string getLogFilePathname();
+std::string getOldLogFilePathname();
 void infos(const std::string& message);
 
 #endif /* ! defined(LL_LLAPPVIEWERMACOSX_FOR_OBJC_H) */
diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp
index 562e7ebfde..d014e992f9 100644
--- a/indra/newview/llappviewermacosx.cpp
+++ b/indra/newview/llappviewermacosx.cpp
@@ -148,9 +148,9 @@ void cleanupViewer()
 	gViewerAppPtr = NULL;
 }
 
-std::string getLogFilePathname()
+std::string getOldLogFilePathname()
 {
-    return gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log");
+    return gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.old");
 }
 
 void infos(const std::string& message)
-- 
cgit v1.2.3


From f6e7893a6e34190e8080d289a5f89d7f9c47d583 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 28 Jun 2018 12:39:42 -0400
Subject: MAINT-8797: Resurrect BugSplat crash reporting on Windows.

The Breakpad symbol-file upload in the viewer's build.sh was failing on
BugSplat builds since we weren't generating Breakpad symbol files. That upload
was conditional on RELEASE_CRASH_REPORTING, so my first approach was to set
RELEASE_CRASH_REPORTING=OFF for BugSplat builds. Unfortunately that symbol
also propagates down into C++ compiles, and in llappviewerwin32.cpp, both
Breakpad and BugSplat crash reporting is conditional on it. So that change
inadvertently turned off the C++ logic to engage BugSplat.

Stop forcing RELEASE_CRASH_REPORTING=OFF for BugSplat builds. Instead, make
the Breakpad symbol-file upload check the BUGSPLAT_DB variable as well.

Add #pragma messages to llappviewerwin32.cpp so we can detect whether it's
being built for Breakpad or BugSplat or neither.
---
 build.sh                           | 6 +++---
 indra/newview/llappviewerwin32.cpp | 6 ++++--
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/build.sh b/build.sh
index 56ec57818c..d531c0b046 100755
--- a/build.sh
+++ b/build.sh
@@ -114,8 +114,6 @@ pre_build()
          if [ -n "${BUGSPLAT_DB:-}" ]
          then echo export BUGSPLAT_DB
               export BUGSPLAT_DB
-              echo RELEASE_CRASH_REPORTING=OFF
-              RELEASE_CRASH_REPORTING=OFF
          fi
     fi
     set -x
@@ -428,7 +426,9 @@ then
       if [ "$last_built_variant" = "Release" ]
       then
           # nat 2016-12-22: without RELEASE_CRASH_REPORTING, we have no symbol file.
-          if [ "${RELEASE_CRASH_REPORTING:-}" != "OFF" ]
+          # Likewise, BUGSPLAT_DB suppresses generating the symbol file.
+          if [ "${RELEASE_CRASH_REPORTING:-}" != "OFF" \
+               -a -z "${BUGSPLAT_DB:-}" ]
           then
               # Upload crash reporter file
               # These names must match the set of VIEWER_SYMBOL_FILE in indra/newview/CMakeLists.txt
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 3efc94d7b5..247b94db3e 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -559,11 +559,13 @@ bool LLAppViewerWin32::init()
 
 #if LL_SEND_CRASH_REPORTS
 #if ! defined(LL_BUGSPLAT)
+#pragma message("Building without BugSplat")
 
 	LLAppViewer* pApp = LLAppViewer::instance();
 	pApp->initCrashReporting();
 
 #else // LL_BUGSPLAT
+#pragma message("Building with BugSplat")
 
 	std::string build_data_fname(
 		gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "build_data.json"));
@@ -579,7 +581,7 @@ bool LLAppViewerWin32::init()
 		Json::Value build_data;
 		if (! reader.parse(inf, build_data, false)) // don't collect comments
 		{
-			// gah, the typo is baked into their API
+			// gah, the typo is baked into Json::Reader API
 			LL_WARNS() << "Can't initialize BugSplat, can't parse '" << build_data_fname
 					   << "': " << reader.getFormatedErrorMessages() << LL_ENDL;
 		}
@@ -609,7 +611,7 @@ bool LLAppViewerWin32::init()
 
 				// engage stringize() overload that converts from wstring
 				LL_INFOS() << "Engaged BugSplat(" << LL_TO_STRING(LL_VIEWER_CHANNEL)
-						   << stringize(version_string) << ')' << LL_ENDL;
+						   << ' ' << stringize(version_string) << ')' << LL_ENDL;
 			} // got BugSplat_DB
 		} // parsed build_data.json
 	} // opened build_data.json
-- 
cgit v1.2.3


From cd52724ef8f8a19ebe28c73f39a582b56fb58093 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 28 Jun 2018 21:49:07 -0400
Subject: DRTVWR-447: Suppress BugSplat UI; auto-fill certain BugSplat data.

Direct BugSplat to send crash reports without prompting, on both Windows and
Mac.

Add a mechanism by which code called after LL_ERRS() can retrieve the fatal
log message string. (How did the crash logger extract that for Linden crash
logging?)

Add that fatal message to crash reports on Windows. But as BugsplatMac is
engaged only on the run _after_ the crash, we no longer have that message in
memory.

Also add user name and region location to Windows crash reports. On Mac, (a)
we don't have the information from the previous run and (b) BugsplatMac
doesn't provide an API to attach that information to the crash report.

Add Mac logging to indicate the success or failure of sending the crash
report. Add Windows logging to indicate we're about to send.
---
 indra/llcommon/llerror.cpp                 | 33 ++++++++++++-------
 indra/llcommon/llerrorcontrol.h            |  3 ++
 indra/newview/llappdelegate-objc.mm        | 34 +++++++++++++------
 indra/newview/llappviewermacosx-for-objc.h |  2 ++
 indra/newview/llappviewermacosx.cpp        | 12 +++++++
 indra/newview/llappviewerwin32.cpp         | 53 +++++++++++++++++++++---------
 6 files changed, 101 insertions(+), 36 deletions(-)

diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index f31a054139..b5e7e81f21 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -377,6 +377,7 @@ namespace
 	public:
 		std::ostringstream messageStream;
 		bool messageStreamInUse;
+		std::string mFatalMessage;
 
 		void addCallSite(LLError::CallSite&);
 		void invalidateCallSites();
@@ -670,11 +671,16 @@ namespace LLError
 		s->mCrashFunction = f;
 	}
 
-    FatalFunction getFatalFunction()
-    {
+	FatalFunction getFatalFunction()
+	{
 		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
-        return s->mCrashFunction;
-    }
+		return s->mCrashFunction;
+	}
+
+	std::string getFatalMessage()
+	{
+		return Globals::getInstance()->mFatalMessage;
+	}
 
 	void setTimeFunction(TimeFunction f)
 	{
@@ -1194,7 +1200,7 @@ namespace LLError
 		{
 			writeToRecorders(site, "error", true, true, true, false, false);
 		}
-		
+
 		std::ostringstream message_stream;
 
 		if (site.mPrintOnce)
@@ -1219,14 +1225,19 @@ namespace LLError
 				s->mUniqueLogMessages[message] = 1;
 			}
 		}
-		
+
 		message_stream << message;
-		
-		writeToRecorders(site, message_stream.str());
-		
-		if (site.mLevel == LEVEL_ERROR  &&  s->mCrashFunction)
+		std::string message_line(message_stream.str());
+
+		writeToRecorders(site, message_line);
+
+		if (site.mLevel == LEVEL_ERROR)
 		{
-			s->mCrashFunction(message_stream.str());
+			g->mFatalMessage = message_line;
+			if (s->mCrashFunction)
+			{
+				s->mCrashFunction(message_line);
+			}
 		}
 	}
 }
diff --git a/indra/llcommon/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h
index caf2ba72c2..ddbcdc94a0 100644
--- a/indra/llcommon/llerrorcontrol.h
+++ b/indra/llcommon/llerrorcontrol.h
@@ -102,6 +102,9 @@ namespace LLError
 	LL_COMMON_API FatalFunction getFatalFunction();
 		// Retrieve the previously-set FatalFunction
 
+	LL_COMMON_API std::string getFatalMessage();
+		// Retrieve the message last passed to FatalFunction, if any
+
 	/// temporarily override the FatalFunction for the duration of a
 	/// particular scope, e.g. for unit tests
 	class LL_COMMON_API OverrideFatalFunction
diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm
index 4510f4070f..82e49540a4 100644
--- a/indra/newview/llappdelegate-objc.mm
+++ b/indra/newview/llappdelegate-objc.mm
@@ -74,9 +74,9 @@
 
 #if defined(LL_BUGSPLAT)
 	// https://www.bugsplat.com/docs/platforms/os-x#initialization
-//	[BugsplatStartupManager sharedManager].autoSubmitCrashReport = YES;
-//	[BugsplatStartupManager sharedManager].askUserDetails = NO;
-    [BugsplatStartupManager sharedManager].delegate = self;
+	[BugsplatStartupManager sharedManager].autoSubmitCrashReport = YES;
+	[BugsplatStartupManager sharedManager].askUserDetails = NO;
+	[BugsplatStartupManager sharedManager].delegate = self;
 	[[BugsplatStartupManager sharedManager] start];
 #endif
 }
@@ -196,17 +196,20 @@
 
 #if defined(LL_BUGSPLAT)
 
-#if 0
-// Apparently this override method only contributes the User Description field
-// of BugSplat's All Crashes table. Despite the method name, it would seem to
-// be a bad place to try to stuff all of SecondLife.log.
 - (NSString *)applicationLogForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager
 {
-//  return NSStringFromSelector(_cmd);
     infos("Reached applicationLogForBugsplatStartupManager");
-    return @"[contents of SecondLife.log]";
+    // Apparently this override method only contributes the User Description
+    // field of BugSplat's All Crashes table. Despite the method name, it
+    // would seem to be a bad place to try to stuff all of SecondLife.log.
+    return [NSString stringWithCString:getFatalMessage().c_str()
+                              encoding:NSUTF8StringEncoding];
+}
+
+- (void)bugsplatStartupManagerWillSendCrashReport:(BugsplatStartupManager *)bugsplatStartupManager
+{
+    infos("Reached bugsplatStartupManagerWillSendCrashReport");
 }
-#endif
 
 - (BugsplatAttachment *)attachmentForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager {
     // We get the *old* log file pathname (for SecondLife.old) because it's on
@@ -228,6 +231,17 @@
     return attachment;
 }
 
+- (void)bugsplatStartupManagerDidFinishSendingCrashReport:(BugsplatStartupManager *)bugsplatStartupManager
+{
+    infos("Sent crash report to BugSplat");
+}
+
+- (void)bugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager didFailWithError:(NSError *)error
+{
+    // TODO: message string from NSError
+    infos("Could not send crash report to BugSplat");
+}
+
 #endif // LL_BUGSPLAT
 
 @end
diff --git a/indra/newview/llappviewermacosx-for-objc.h b/indra/newview/llappviewermacosx-for-objc.h
index c439297611..ac85d7e8c3 100644
--- a/indra/newview/llappviewermacosx-for-objc.h
+++ b/indra/newview/llappviewermacosx-for-objc.h
@@ -30,6 +30,8 @@ bool pumpMainLoop();
 void handleQuit();
 void cleanupViewer();
 std::string getOldLogFilePathname();
+std::string getFatalMessage();
+std::string getAgentFullname();
 void infos(const std::string& message);
 
 #endif /* ! defined(LL_LLAPPVIEWERMACOSX_FOR_OBJC_H) */
diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp
index d014e992f9..c3a3c3284a 100644
--- a/indra/newview/llappviewermacosx.cpp
+++ b/indra/newview/llappviewermacosx.cpp
@@ -45,6 +45,8 @@
 #include "llmd5.h"
 #include "llfloaterworldmap.h"
 #include "llurldispatcher.h"
+#include "llerrorcontrol.h"
+#include "llvoavatarself.h"         // for gAgentAvatarp->getFullname()
 #include <ApplicationServices/ApplicationServices.h>
 #ifdef LL_CARBON_CRASH_HANDLER
 #include <Carbon/Carbon.h>
@@ -153,6 +155,16 @@ std::string getOldLogFilePathname()
     return gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.old");
 }
 
+std::string getFatalMessage()
+{
+    return LLError::getFatalMessage();
+}
+
+std::string getAgentFullname()
+{
+    return gAgentAvatarp? gAgentAvatarp->getFullname() : std::string();
+}
+
 void infos(const std::string& message)
 {
     LL_INFOS() << message << LL_ENDL;
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 247b94db3e..1e135fa229 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -67,6 +67,7 @@
 
 #include "stringize.h"
 #include "lldir.h"
+#include "llerrorcontrol.h"
 
 #include <fstream>
 #include <exception>
@@ -74,7 +75,10 @@
 // Bugsplat (http://bugsplat.com) crash reporting tool
 #ifdef LL_BUGSPLAT
 #include "BugSplat.h"
-#include "reader.h" // JsonCpp
+#include "reader.h"                 // JsonCpp
+#include "llagent.h"                // for agent location
+#include "llviewerregion.h"
+#include "llvoavatarself.h"         // for agent name
 
 namespace
 {
@@ -85,7 +89,8 @@ namespace
     // std::basic_string instance will survive until the function returns.
     // Calling c_str() on a std::basic_string local to wunder() would be
     // Undefined Behavior: we'd be left with a pointer into a destroyed
-    // std::basic_string instance.
+    // std::basic_string instance. But we can do that with a macro...
+    #define WCSTR(string) wunder(string).c_str()
 
     // It would be nice if, when wchar_t is the same as __wchar_t, this whole
     // function would optimize away. However, we use it only for the arguments
@@ -111,19 +116,35 @@ namespace
 
     bool bugsplatSendLog(UINT nCode, LPVOID lpVal1, LPVOID lpVal2)
     {
-        // If we haven't yet initialized LLDir, don't bother trying to
-        // find our log file.
-        // Alternatively -- if we might encounter trouble trying to query
-        // LLDir during crash cleanup -- consider making gDirUtilp an
-        // LLPounceable, and attach a callback that stores the pathname to
-        // the log file here.
-        if (nCode == MDSCB_EXCEPTIONCODE && gDirUtilp)
+        if (nCode == MDSCB_EXCEPTIONCODE)
         {
             // send the main viewer log file
             // widen to wstring, convert to __wchar_t, then pass c_str()
             sBugSplatSender->sendAdditionalFile(
-                wunder(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log")).c_str());
-        }
+                WCSTR(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log")));
+
+            if (gAgentAvatarp)
+            {
+                // user name, when we have it
+                sBugSplatSender->setDefaultUserName(WCSTR(gAgentAvatarp->getFullname()));
+            }
+
+            // LL_ERRS message, when there is one
+            sBugSplatSender->setDefaultUserDescription(WCSTR(LLError::getFatalMessage()));
+
+            if (gAgent.getRegion())
+            {
+                // region location, when we have it
+                LLVector3 loc = gAgent.getPositionAgent();
+                sBugSplatSender->resetAppIdentifier(
+                    WCSTR(STRINGIZE(gAgent.getRegion()->getName()
+                                    << '/' << loc.mV[0]
+                                    << '/' << loc.mV[1]
+                                    << '/' << loc.mV[2])));
+            }
+
+            LL_INFOS() << "Sending crash report to BugSplat." << LL_ENDL;
+        } // MDSCB_EXCEPTIONCODE
 
         return false;
     }
@@ -603,10 +624,12 @@ bool LLAppViewerWin32::init()
 
 				// have to convert normal wide strings to strings of __wchar_t
 				sBugSplatSender = new MiniDmpSender(
-					wunder(BugSplat_DB.asString()).c_str(),
-					wunder(LL_TO_WSTRING(LL_VIEWER_CHANNEL)).c_str(),
-					wunder(version_string).c_str(),
-					nullptr);
+					WCSTR(BugSplat_DB.asString()),
+					WCSTR(LL_TO_WSTRING(LL_VIEWER_CHANNEL)),
+					WCSTR(version_string),
+					nullptr,              // szAppIdentifier -- set later
+					MDSF_NONINTERACTIVE | // automatically submit report without prompting
+					MDSF_PREVENTHIJACKING); // disallow swiping Exception filter
 				sBugSplatSender->setCallback(bugsplatSendLog);
 
 				// engage stringize() overload that converts from wstring
-- 
cgit v1.2.3


From 93ea0d7026dcb7a9aec3bd4f8615eb62da159a02 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 29 Jun 2018 17:08:48 -0400
Subject: MAINT-8822: Revamp the LLManifest.prefix() calling convention.

The way prefix("path_fragment") or prefix(src="path_fragment") has always
worked is that unless you explicitly specify dst="", it adds "path_fragment"
to the source AND dest prefix stacks!

The most recent refactoring of viewer_manifest.py failed to copy CEF because
it involved prefix(src="../some lengthy path fragment") -- forgetting to
specify dst="" -- which added "../some lengthy path fragment" to the dest
prefix stack -- which put it outside the viewer install staging area
altogether.

Having been bitten too many times by forgetting to add prefix(dst=""), we
remove the necessity. The prefix() src=, build= and dst= prefix stacks are now
completely independent. Add src_dst= keyword argument for when you DO want to
add the same path fragment to both the source and dest prefix stacks.
("Explicit is better than implicit.")

Change all existing calls accordingly.

Now that the build prefix stack no longer tracks the src prefix stack, we were
failing to pick up some things from the build area because NOBODY ever used
build=, relying entirely on src= to point both to stuff in the source tree and
stuff in the build tree. Try to use build= appropriately.

If that proves too confusing, we might eliminate the separate build and
artwork (!) prefix stacks entirely, requiring callers to reset the src stack
explicitly when switching back and forth.
---
 indra/lib/python/indra/util/llmanifest.py |  32 ++++++---
 indra/newview/viewer_manifest.py          | 107 +++++++++++++++---------------
 2 files changed, 77 insertions(+), 62 deletions(-)

diff --git a/indra/lib/python/indra/util/llmanifest.py b/indra/lib/python/indra/util/llmanifest.py
index 598261e3d7..4c3d3fc217 100755
--- a/indra/lib/python/indra/util/llmanifest.py
+++ b/indra/lib/python/indra/util/llmanifest.py
@@ -375,7 +375,7 @@ class LLManifest(object):
         in the file list by path()."""
         self.excludes.append(glob)
 
-    def prefix(self, src='', build=None, dst=None):
+    def prefix(self, src='', build='', dst='', src_dst=None):
         """
         Usage:
 
@@ -385,8 +385,21 @@ class LLManifest(object):
         For the duration of the 'with' block, pushes a prefix onto the stack.
         Within that block, all relevant method calls (esp. to path()) will
         prefix paths with the entire prefix stack. Source and destination
-        prefixes can be different, though if only one is provided they are
-        both equal. To specify a no-op, use an empty string, not None.
+        prefixes are independent; if omitted (or passed as the empty string),
+        the prefix has no effect. Thus:
+
+        with self.prefix(src='foo'):
+            # no effect on dst
+
+        with self.prefix(dst='bar'):
+            # no effect on src
+
+        If you want to set both at once, use src_dst:
+
+        with self.prefix(src_dst='subdir'):
+            # same as self.prefix(src='subdir', dst='subdir')
+            # Passing src_dst makes any src or dst argument in the same
+            # parameter list irrelevant.
 
         Also supports the older (pre-Python-2.5) syntax:
 
@@ -400,10 +413,9 @@ class LLManifest(object):
         returned True specifically so that the caller could indent the
         relevant block of code with 'if', just for aesthetic purposes.
         """
-        if dst is None:
-            dst = src
-        if build is None:
-            build = src
+        if src_dst is not None:
+            src = src_dst
+            dst = src_dst
         self.src_prefix.append(src)
         self.artwork_prefix.append(src)
         self.build_prefix.append(build)
@@ -609,7 +621,6 @@ class LLManifest(object):
 
     def process_file(self, src, dst):
         if self.includes(src, dst):
-#            print src, "=>", dst
             for action in self.actions:
                 methodname = action + "_action"
                 method = getattr(self, methodname, None)
@@ -677,7 +688,11 @@ class LLManifest(object):
         # Don't recopy file if it's up-to-date.
         # If we seem to be not not overwriting files that have been
         # updated, set the last arg to False, but it will take longer.
+##      reldst = (dst[len(self.dst_prefix[0]):]
+##                if dst.startswith(self.dst_prefix[0])
+##                else dst).lstrip(r'\/')
         if os.path.exists(dst) and filecmp.cmp(src, dst, True):
+##          print "{} (skipping, {} exists)".format(src, reldst)
             return
         # only copy if it's not excluded
         if self.includes(src, dst):
@@ -687,6 +702,7 @@ class LLManifest(object):
                 if err.errno != errno.ENOENT:
                     raise
 
+##          print "{} => {}".format(src, reldst)
             shutil.copy2(src, dst)
 
     def ccopytree(self, src, dst):
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 49dc732457..35cd7db161 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -64,7 +64,7 @@ class ViewerManifest(LLManifest):
         self.path(src="../../etc/message.xml", dst="app_settings/message.xml")
 
         if self.is_packaging_viewer():
-            with self.prefix(src="app_settings"):
+            with self.prefix(src_dst="app_settings"):
                 self.exclude("logcontrol.xml")
                 self.exclude("logcontrol-dev.xml")
                 self.path("*.ini")
@@ -86,7 +86,7 @@ class ViewerManifest(LLManifest):
             
                 # ... and the included spell checking dictionaries
                 pkgdir = os.path.join(self.args['build'], os.pardir, 'packages')
-                with self.prefix(src=pkgdir,dst=""):
+                with self.prefix(build=pkgdir):
                     self.path("dictionaries")
 
                 # include the extracted packages information (see BuildPackagesInfo.cmake)
@@ -130,20 +130,20 @@ class ViewerManifest(LLManifest):
                                  src="environment")
 
 
-            with self.prefix(src="character"):
+            with self.prefix(src_dst="character"):
                 self.path("*.llm")
                 self.path("*.xml")
                 self.path("*.tga")
 
             # Include our fonts
-            with self.prefix(src="fonts"):
+            with self.prefix(src_dst="fonts"):
                 self.path("*.ttf")
                 self.path("*.txt")
 
             # skins
-            with self.prefix(src="skins"):
+            with self.prefix(src_dst="skins"):
                     # include the entire textures directory recursively
-                    with self.prefix(src="*/textures"):
+                    with self.prefix(src_dst="*/textures"):
                             self.path("*/*.tga")
                             self.path("*/*.j2c")
                             self.path("*/*.jpg")
@@ -171,7 +171,7 @@ class ViewerManifest(LLManifest):
 
 
             # local_assets dir (for pre-cached textures)
-            with self.prefix(src="local_assets"):
+            with self.prefix(src_dst="local_assets"):
                 self.path("*.j2c")
                 self.path("*.tga")
 
@@ -494,19 +494,19 @@ class WindowsManifest(ViewerManifest):
             # Find secondlife-bin.exe in the 'configuration' dir, then rename it to the result of final_exe.
             self.path(src='%s/secondlife-bin.exe' % self.args['configuration'], dst=self.final_exe())
 
-            with self.prefix(src=os.path.join(pkgdir, "VMP"), dst=""):
+            with self.prefix(build=os.path.join(pkgdir, "VMP")):
                 # include the compiled launcher scripts so that it gets included in the file_list
                 self.path('SL_Launcher.exe')
                 #IUM is not normally executed directly, just imported.  No exe needed.
                 self.path("InstallerUserMessage.py")
 
-            with self.prefix(src=self.icon_path(), dst="vmp_icons"):
-                self.path("secondlife.ico")
-
-            #VMP  Tkinter icons
-            with self.prefix("vmp_icons"):
-                self.path("*.png")
-                self.path("*.gif")
+            with self.prefix(dst="vmp_icons"):
+                with self.prefix(src=self.icon_path()):
+                    self.path("secondlife.ico")
+                #VMP  Tkinter icons
+                with self.prefix(src="vmp_icons"):
+                    self.path("*.png")
+                    self.path("*.gif")
 
             #before, we only needed llbase at build time.  With VMP, we need it at run time.
             with self.prefix(src=os.path.join(pkgdir, "lib", "python", "llbase"), dst="llbase"):
@@ -519,8 +519,7 @@ class WindowsManifest(ViewerManifest):
                            "slplugin.exe")
         
         # Get shared libs from the shared libs staging directory
-        with self.prefix(src=os.path.join(os.pardir, 'sharedlibs', self.args['configuration']),
-                       dst=""):
+        with self.prefix(build=os.path.join(os.pardir, 'sharedlibs', self.args['configuration'])):
 
             # Get llcommon and deps. If missing assume static linkage and continue.
             try:
@@ -608,27 +607,27 @@ class WindowsManifest(ViewerManifest):
         self.path(src="licenses-win32.txt", dst="licenses.txt")
         self.path("featuretable.txt")
 
-        with self.prefix(src=pkgdir,dst=""):
+        with self.prefix(build=pkgdir):
             self.path("ca-bundle.crt")
 
         # Media plugins - CEF
         with self.prefix(dst="llplugin"):
-            with self.prefix(src='../media_plugins/cef/%s' % self.args['configuration']):
+            with self.prefix(build='../media_plugins/cef/%s' % self.args['configuration']):
                 self.path("media_plugin_cef.dll")
 
             # Media plugins - LibVLC
-            with self.prefix(src='../media_plugins/libvlc/%s' % self.args['configuration']):
+            with self.prefix(build='../media_plugins/libvlc/%s' % self.args['configuration']):
                 self.path("media_plugin_libvlc.dll")
 
             # Media plugins - Example (useful for debugging - not shipped with release viewer)
             if self.channel_type() != 'release':
-                with self.prefix(src='../media_plugins/example/%s' % self.args['configuration']):
+                with self.prefix(build='../media_plugins/example/%s' % self.args['configuration']):
                     self.path("media_plugin_example.dll")
 
             # CEF runtime files - debug
             # CEF runtime files - not debug (release, relwithdebinfo etc.)
             config = 'debug' if self.args['configuration'].lower() == 'debug' else 'release'
-            with self.prefix(src=os.path.join(pkgdir, 'bin', config)):
+            with self.prefix(build=os.path.join(pkgdir, 'bin', config)):
                 self.path("chrome_elf.dll")
                 self.path("d3dcompiler_43.dll")
                 self.path("d3dcompiler_47.dll")
@@ -641,12 +640,12 @@ class WindowsManifest(ViewerManifest):
                 self.path("widevinecdmadapter.dll")
 
             # MSVC DLLs needed for CEF and have to be in same directory as plugin
-            with self.prefix(src=os.path.join(os.pardir, 'sharedlibs', 'Release')):
+            with self.prefix(build=os.path.join(os.pardir, 'sharedlibs', 'Release')):
                 self.path("msvcp120.dll")
                 self.path("msvcr120.dll")
 
             # CEF files common to all configurations
-            with self.prefix(src=os.path.join(pkgdir, 'resources')):
+            with self.prefix(build=os.path.join(pkgdir, 'resources')):
                 self.path("cef.pak")
                 self.path("cef_100_percent.pak")
                 self.path("cef_200_percent.pak")
@@ -654,7 +653,7 @@ class WindowsManifest(ViewerManifest):
                 self.path("devtools_resources.pak")
                 self.path("icudtl.dat")
 
-            with self.prefix(src=os.path.join(pkgdir, 'resources', 'locales'), dst='locales'):
+            with self.prefix(build=os.path.join(pkgdir, 'resources', 'locales'), dst='locales'):
                 self.path("am.pak")
                 self.path("ar.pak")
                 self.path("bg.pak")
@@ -709,7 +708,7 @@ class WindowsManifest(ViewerManifest):
                 self.path("zh-CN.pak")
                 self.path("zh-TW.pak")
 
-            with self.prefix(src=os.path.join(pkgdir, 'bin', 'release')):
+            with self.prefix(build=os.path.join(pkgdir, 'bin', 'release')):
                 self.path("libvlc.dll")
                 self.path("libvlccore.dll")
                 self.path("plugins/")
@@ -916,7 +915,7 @@ class DarwinManifest(ViewerManifest):
 
         # -------------------- top-level Second Life.app ---------------------
         # top-level Second Life application is only a container
-        with self.prefix(src="", dst="Contents"):  # everything goes in Contents
+        with self.prefix(dst="Contents"):  # everything goes in Contents
             # top-level Info.plist is as generated by CMake
             Info_plist = self.dst_path_of("Info.plist")
 
@@ -945,10 +944,10 @@ open "%s" --args "$@"
             # rather than relsymlinkf().
             self.symlinkf(os.path.join("Resources", viewer_app, "Contents", "Frameworks"))
 
-            with self.prefix(src="", dst="Resources"):
+            with self.prefix(dst="Resources"):
                 # top-level Resources directory should be pretty sparse
                 # need .icns file referenced by top-level Info.plist
-                with self.prefix(src=self.icon_path(), dst="") :
+                with self.prefix(src=self.icon_path()) :
                     self.path(toplevel_icon)
 
                 # ------------------- nested launcher_app --------------------
@@ -968,15 +967,15 @@ open "%s" --args "$@"
                         #this copies over the python wrapper script,
                         #associated utilities and required libraries, see
                         #SL-321, SL-322, SL-323
-                        with self.prefix(src=os.path.join(pkgdir, "VMP"), dst=""):
+                        with self.prefix(build=os.path.join(pkgdir, "VMP")):
                             self.path("SL_Launcher")
                             self.path("*.py")
                             # certifi will be imported by requests; this is
                             # our custom version to get our ca-bundle.crt
                             self.path("certifi")
-                        with self.prefix(src=os.path.join(pkgdir, "lib", "python"), dst=""):
+                        with self.prefix(build=os.path.join(pkgdir, "lib", "python")):
                             # llbase provides our llrest service layer and llsd decoding
-                            with self.prefix("llbase"):
+                            with self.prefix(build="llbase", dst="llbase"):
                                 # (Why is llbase treated specially here? What
                                 # DON'T we want to copy out of lib/python/llbase?)
                                 self.path("*.py")
@@ -989,12 +988,12 @@ open "%s" --args "$@"
 
                     # launcher_app/Contents/Resources
                     with self.prefix(dst="Resources"):
-                        with self.prefix(src=self.icon_path(), dst="") :
+                        with self.prefix(src=self.icon_path()) :
                             self.path(launcher_icon)
                             with self.prefix(dst="vmp_icons"):
                                 self.path("secondlife.ico")
                         #VMP Tkinter icons
-                        with self.prefix("vmp_icons"):
+                        with self.prefix(src_dst="vmp_icons"):
                             self.path("*.png")
                             self.path("*.gif")
 
@@ -1093,7 +1092,7 @@ open "%s" --args "$@"
                         os.path.basename(Info_plist),
                         "Info.plist")
 
-                    with self.prefix(src="", dst="Frameworks"):
+                    with self.prefix(dst="Frameworks"):
                         # CEF framework goes inside viewer_app/Contents/Frameworks.
                         CEF_framework = "Chromium Embedded Framework.framework"
                         self.path2basename(relpkgdir, CEF_framework)
@@ -1107,21 +1106,21 @@ open "%s" --args "$@"
                         # nested Resources directory
                         super(DarwinManifest, self).construct()
 
-                        with self.prefix(src=self.icon_path(), dst="") :
+                        with self.prefix(src=self.icon_path()) :
                             self.path(viewer_icon)
 
-                        with self.prefix(src=relpkgdir, dst=""):
+                        with self.prefix(build=relpkgdir):
                             self.path("libndofdev.dylib")
                             self.path("libhunspell-1.3.0.dylib")   
 
-                        with self.prefix("cursors_mac"):
+                        with self.prefix(src_dst="cursors_mac"):
                             self.path("*.tif")
 
                         self.path("licenses-mac.txt", dst="licenses.txt")
                         self.path("featuretable_mac.txt")
                         self.path("SecondLife.nib")
 
-                        with self.prefix(src=pkgdir,dst=""):
+                        with self.prefix(build=pkgdir):
                             self.path("ca-bundle.crt")
 
                         self.path("SecondLife.nib")
@@ -1331,10 +1330,10 @@ open "%s" --args "$@"
                                                "media_plugin_libvlc.dylib")
 
                             # copy LibVLC dynamic libraries
-                            with self.prefix(src=relpkgdir, dst="lib"):
+                            with self.prefix(build=relpkgdir, dst="lib"):
                                 self.path( "libvlc*.dylib*" )
                                 # copy LibVLC plugins folder
-                                with self.prefix(src='plugins', dst=""):
+                                with self.prefix(build='plugins'):
                                     self.path( "*.dylib" )
                                     self.path( "plugins.dat" )
 
@@ -1527,24 +1526,24 @@ class LinuxManifest(ViewerManifest):
         debpkgdir = os.path.join(pkgdir, "lib", "debug")
 
         self.path("licenses-linux.txt","licenses.txt")
-        with self.prefix("linux_tools", dst=""):
+        with self.prefix("linux_tools"):
             self.path("client-readme.txt","README-linux.txt")
             self.path("client-readme-voice.txt","README-linux-voice.txt")
             self.path("client-readme-joystick.txt","README-linux-joystick.txt")
             self.path("wrapper.sh","secondlife")
-            with self.prefix(src="", dst="etc"):
+            with self.prefix(dst="etc"):
                 self.path("handle_secondlifeprotocol.sh")
                 self.path("register_secondlifeprotocol.sh")
                 self.path("refresh_desktop_app_entry.sh")
                 self.path("launch_url.sh")
             self.path("install.sh")
 
-        with self.prefix(src="", dst="bin"):
+        with self.prefix(dst="bin"):
             self.path("secondlife-bin","do-not-directly-run-secondlife-bin")
             self.path("../linux_crash_logger/linux-crash-logger","linux-crash-logger.bin")
             self.path2basename("../llplugin/slplugin", "SLPlugin") 
             #this copies over the python wrapper script, associated utilities and required libraries, see SL-321, SL-322 and SL-323
-            with self.prefix(src="../viewer_components/manager", dst=""):
+            with self.prefix(src="../viewer_components/manager"):
                 self.path("SL_Launcher")
                 self.path("*.py")
             with self.prefix(src=os.path.join("lib", "python", "llbase"), dst="llbase"):
@@ -1557,22 +1556,22 @@ class LinuxManifest(ViewerManifest):
         # Get the icons based on the channel type
         icon_path = self.icon_path()
         print "DEBUG: icon_path '%s'" % icon_path
-        with self.prefix(src=icon_path, dst="") :
+        with self.prefix(src=icon_path) :
             self.path("secondlife_256.png","secondlife_icon.png")
-            with self.prefix(src="",dst="res-sdl") :
+            with self.prefix(dst="res-sdl") :
                 self.path("secondlife_256.BMP","ll_icon.BMP")
 
         # plugins
-        with self.prefix(src="../media_plugins", dst="bin/llplugin"):
+        with self.prefix(build="../media_plugins", dst="bin/llplugin"):
             self.path("gstreamer010/libmedia_plugin_gstreamer010.so",
                       "libmedia_plugin_gstreamer.so")
             self.path2basename("libvlc", "libmedia_plugin_libvlc.so")
 
-        with self.prefix(src=os.path.join(pkgdir, 'lib', 'vlc', 'plugins'), dst="bin/llplugin/vlc/plugins"):
+        with self.prefix(build=os.path.join(pkgdir, 'lib', 'vlc', 'plugins'), dst="bin/llplugin/vlc/plugins"):
             self.path( "plugins.dat" )
             self.path( "*/*.so" )
 
-        with self.prefix(src=os.path.join(pkgdir, 'lib' ), dst="lib"):
+        with self.prefix(build=os.path.join(pkgdir, 'lib' ), dst="lib"):
             self.path( "libvlc*.so*" )
 
         # llcommon
@@ -1581,7 +1580,7 @@ class LinuxManifest(ViewerManifest):
 
         self.path("featuretable_linux.txt")
 
-        with self.prefix(src=pkgdir,dst=""):
+        with self.prefix(build=pkgdir):
             self.path("ca-bundle.crt")
 
     def package_finish(self):
@@ -1637,7 +1636,7 @@ class Linux_i686_Manifest(LinuxManifest):
         relpkgdir = os.path.join(pkgdir, "lib", "release")
         debpkgdir = os.path.join(pkgdir, "lib", "debug")
 
-        with self.prefix(relpkgdir, dst="lib"):
+        with self.prefix(build=relpkgdir, dst="lib"):
             self.path("libapr-1.so")
             self.path("libapr-1.so.0")
             self.path("libapr-1.so.0.4.5")
@@ -1699,9 +1698,9 @@ class Linux_i686_Manifest(LinuxManifest):
 
 
         # Vivox runtimes
-        with self.prefix(src=relpkgdir, dst="bin"):
+        with self.prefix(build=relpkgdir, dst="bin"):
             self.path("SLVoice")
-        with self.prefix(src=relpkgdir, dst="lib"):
+        with self.prefix(build=relpkgdir, dst="lib"):
             self.path("libortp.so")
             self.path("libsndfile.so.1")
             #self.path("libvivoxoal.so.1") # no - we'll re-use the viewer's own OpenAL lib
-- 
cgit v1.2.3


From bbadee86c104609cc47be20297470bd7abab8008 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Sat, 30 Jun 2018 10:01:11 -0400
Subject: MAINT-8822: Give LLManifest.prefix() (suppressed) debugging output.

---
 indra/lib/python/indra/util/llmanifest.py | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/indra/lib/python/indra/util/llmanifest.py b/indra/lib/python/indra/util/llmanifest.py
index 4c3d3fc217..974ac18e34 100755
--- a/indra/lib/python/indra/util/llmanifest.py
+++ b/indra/lib/python/indra/util/llmanifest.py
@@ -421,25 +421,34 @@ class LLManifest(object):
         self.build_prefix.append(build)
         self.dst_prefix.append(dst)
 
+##      self.display_stacks()
+
         # The above code is unchanged from the original implementation. What's
         # new is the return value. We're going to return an instance of
         # PrefixManager that binds this LLManifest instance and Does The Right
         # Thing on exit.
         return self.PrefixManager(self)
 
+    def display_stacks(self):
+        width = 1 + max(len(stack) for stack in self.PrefixManager.stacks)
+        for stack in self.PrefixManager.stacks:
+            print "{} {}".format((stack + ':').ljust(width),
+                                 os.path.join(*getattr(self, stack)))
+
     class PrefixManager(object):
+        # stack attributes we manage in this LLManifest (sub)class
+        # instance
+        stacks = ("src_prefix", "artwork_prefix", "build_prefix", "dst_prefix")
+
         def __init__(self, manifest):
             self.manifest = manifest
-            # stack attributes we manage in this LLManifest (sub)class
-            # instance
-            stacks = ("src_prefix", "artwork_prefix", "build_prefix", "dst_prefix")
             # If the caller wrote:
             # with self.prefix(...):
             # as intended, then bind the state of each prefix stack as it was
             # just BEFORE the call to prefix(). Since prefix() appended an
             # entry to each prefix stack, capture len()-1.
             self.prevlen = { stack: len(getattr(self.manifest, stack)) - 1
-                             for stack in stacks }
+                             for stack in self.stacks }
 
         def __nonzero__(self):
             # If the caller wrote:
@@ -472,6 +481,8 @@ class LLManifest(object):
                 # truncate that list back to 'prevlen'
                 del getattr(self.manifest, stack)[prevlen:]
 
+##          self.manifest.display_stacks()
+
     def end_prefix(self, descr=None):
         """Pops a prefix off the stack.  If given an argument, checks
         the argument against the top of the stack.  If the argument
-- 
cgit v1.2.3


From 3e66dc9f193e4641041dd9ac4da1cf7ff7440ec0 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Sat, 30 Jun 2018 10:08:35 -0400
Subject: MAINT-8822: Revert viewer_manifest to using src= instead of build=.

Turns out that having multiple (source, build, artwork) prefix stacks isn't
such a good idea after all. Many of our LLManifest.path() directives use
wildcards -- and if _any files_ match the specified wildcard from a prefix
stack other than what you had in mind, viewer_manifest will silently,
cheerfully do the Wrong Thing.

There is a good reason why all existing LLManifest.prefix() calls exclusively
used src= and/or dst= instead of build=.
---
 indra/newview/viewer_manifest.py | 52 ++++++++++++++++++++--------------------
 1 file changed, 26 insertions(+), 26 deletions(-)

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 35cd7db161..e1374b0518 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -86,7 +86,7 @@ class ViewerManifest(LLManifest):
             
                 # ... and the included spell checking dictionaries
                 pkgdir = os.path.join(self.args['build'], os.pardir, 'packages')
-                with self.prefix(build=pkgdir):
+                with self.prefix(src=pkgdir):
                     self.path("dictionaries")
 
                 # include the extracted packages information (see BuildPackagesInfo.cmake)
@@ -494,7 +494,7 @@ class WindowsManifest(ViewerManifest):
             # Find secondlife-bin.exe in the 'configuration' dir, then rename it to the result of final_exe.
             self.path(src='%s/secondlife-bin.exe' % self.args['configuration'], dst=self.final_exe())
 
-            with self.prefix(build=os.path.join(pkgdir, "VMP")):
+            with self.prefix(src=os.path.join(pkgdir, "VMP")):
                 # include the compiled launcher scripts so that it gets included in the file_list
                 self.path('SL_Launcher.exe')
                 #IUM is not normally executed directly, just imported.  No exe needed.
@@ -519,7 +519,7 @@ class WindowsManifest(ViewerManifest):
                            "slplugin.exe")
         
         # Get shared libs from the shared libs staging directory
-        with self.prefix(build=os.path.join(os.pardir, 'sharedlibs', self.args['configuration'])):
+        with self.prefix(src=os.path.join(os.pardir, 'sharedlibs', self.args['configuration'])):
 
             # Get llcommon and deps. If missing assume static linkage and continue.
             try:
@@ -607,27 +607,27 @@ class WindowsManifest(ViewerManifest):
         self.path(src="licenses-win32.txt", dst="licenses.txt")
         self.path("featuretable.txt")
 
-        with self.prefix(build=pkgdir):
+        with self.prefix(src=pkgdir):
             self.path("ca-bundle.crt")
 
         # Media plugins - CEF
         with self.prefix(dst="llplugin"):
-            with self.prefix(build='../media_plugins/cef/%s' % self.args['configuration']):
+            with self.prefix(src='../media_plugins/cef/%s' % self.args['configuration']):
                 self.path("media_plugin_cef.dll")
 
             # Media plugins - LibVLC
-            with self.prefix(build='../media_plugins/libvlc/%s' % self.args['configuration']):
+            with self.prefix(src='../media_plugins/libvlc/%s' % self.args['configuration']):
                 self.path("media_plugin_libvlc.dll")
 
             # Media plugins - Example (useful for debugging - not shipped with release viewer)
             if self.channel_type() != 'release':
-                with self.prefix(build='../media_plugins/example/%s' % self.args['configuration']):
+                with self.prefix(src='../media_plugins/example/%s' % self.args['configuration']):
                     self.path("media_plugin_example.dll")
 
             # CEF runtime files - debug
             # CEF runtime files - not debug (release, relwithdebinfo etc.)
             config = 'debug' if self.args['configuration'].lower() == 'debug' else 'release'
-            with self.prefix(build=os.path.join(pkgdir, 'bin', config)):
+            with self.prefix(src=os.path.join(pkgdir, 'bin', config)):
                 self.path("chrome_elf.dll")
                 self.path("d3dcompiler_43.dll")
                 self.path("d3dcompiler_47.dll")
@@ -640,12 +640,12 @@ class WindowsManifest(ViewerManifest):
                 self.path("widevinecdmadapter.dll")
 
             # MSVC DLLs needed for CEF and have to be in same directory as plugin
-            with self.prefix(build=os.path.join(os.pardir, 'sharedlibs', 'Release')):
+            with self.prefix(src=os.path.join(os.pardir, 'sharedlibs', 'Release')):
                 self.path("msvcp120.dll")
                 self.path("msvcr120.dll")
 
             # CEF files common to all configurations
-            with self.prefix(build=os.path.join(pkgdir, 'resources')):
+            with self.prefix(src=os.path.join(pkgdir, 'resources')):
                 self.path("cef.pak")
                 self.path("cef_100_percent.pak")
                 self.path("cef_200_percent.pak")
@@ -653,7 +653,7 @@ class WindowsManifest(ViewerManifest):
                 self.path("devtools_resources.pak")
                 self.path("icudtl.dat")
 
-            with self.prefix(build=os.path.join(pkgdir, 'resources', 'locales'), dst='locales'):
+            with self.prefix(src=os.path.join(pkgdir, 'resources', 'locales'), dst='locales'):
                 self.path("am.pak")
                 self.path("ar.pak")
                 self.path("bg.pak")
@@ -708,7 +708,7 @@ class WindowsManifest(ViewerManifest):
                 self.path("zh-CN.pak")
                 self.path("zh-TW.pak")
 
-            with self.prefix(build=os.path.join(pkgdir, 'bin', 'release')):
+            with self.prefix(src=os.path.join(pkgdir, 'bin', 'release')):
                 self.path("libvlc.dll")
                 self.path("libvlccore.dll")
                 self.path("plugins/")
@@ -967,15 +967,15 @@ open "%s" --args "$@"
                         #this copies over the python wrapper script,
                         #associated utilities and required libraries, see
                         #SL-321, SL-322, SL-323
-                        with self.prefix(build=os.path.join(pkgdir, "VMP")):
+                        with self.prefix(src=os.path.join(pkgdir, "VMP")):
                             self.path("SL_Launcher")
                             self.path("*.py")
                             # certifi will be imported by requests; this is
                             # our custom version to get our ca-bundle.crt
                             self.path("certifi")
-                        with self.prefix(build=os.path.join(pkgdir, "lib", "python")):
+                        with self.prefix(src=os.path.join(pkgdir, "lib", "python")):
                             # llbase provides our llrest service layer and llsd decoding
-                            with self.prefix(build="llbase", dst="llbase"):
+                            with self.prefix(src="llbase", dst="llbase"):
                                 # (Why is llbase treated specially here? What
                                 # DON'T we want to copy out of lib/python/llbase?)
                                 self.path("*.py")
@@ -1109,7 +1109,7 @@ open "%s" --args "$@"
                         with self.prefix(src=self.icon_path()) :
                             self.path(viewer_icon)
 
-                        with self.prefix(build=relpkgdir):
+                        with self.prefix(src=relpkgdir):
                             self.path("libndofdev.dylib")
                             self.path("libhunspell-1.3.0.dylib")   
 
@@ -1120,7 +1120,7 @@ open "%s" --args "$@"
                         self.path("featuretable_mac.txt")
                         self.path("SecondLife.nib")
 
-                        with self.prefix(build=pkgdir):
+                        with self.prefix(src=pkgdir):
                             self.path("ca-bundle.crt")
 
                         self.path("SecondLife.nib")
@@ -1330,10 +1330,10 @@ open "%s" --args "$@"
                                                "media_plugin_libvlc.dylib")
 
                             # copy LibVLC dynamic libraries
-                            with self.prefix(build=relpkgdir, dst="lib"):
+                            with self.prefix(src=relpkgdir, dst="lib"):
                                 self.path( "libvlc*.dylib*" )
                                 # copy LibVLC plugins folder
-                                with self.prefix(build='plugins'):
+                                with self.prefix(src='plugins'):
                                     self.path( "*.dylib" )
                                     self.path( "plugins.dat" )
 
@@ -1562,16 +1562,16 @@ class LinuxManifest(ViewerManifest):
                 self.path("secondlife_256.BMP","ll_icon.BMP")
 
         # plugins
-        with self.prefix(build="../media_plugins", dst="bin/llplugin"):
+        with self.prefix(src="../media_plugins", dst="bin/llplugin"):
             self.path("gstreamer010/libmedia_plugin_gstreamer010.so",
                       "libmedia_plugin_gstreamer.so")
             self.path2basename("libvlc", "libmedia_plugin_libvlc.so")
 
-        with self.prefix(build=os.path.join(pkgdir, 'lib', 'vlc', 'plugins'), dst="bin/llplugin/vlc/plugins"):
+        with self.prefix(src=os.path.join(pkgdir, 'lib', 'vlc', 'plugins'), dst="bin/llplugin/vlc/plugins"):
             self.path( "plugins.dat" )
             self.path( "*/*.so" )
 
-        with self.prefix(build=os.path.join(pkgdir, 'lib' ), dst="lib"):
+        with self.prefix(src=os.path.join(pkgdir, 'lib' ), dst="lib"):
             self.path( "libvlc*.so*" )
 
         # llcommon
@@ -1580,7 +1580,7 @@ class LinuxManifest(ViewerManifest):
 
         self.path("featuretable_linux.txt")
 
-        with self.prefix(build=pkgdir):
+        with self.prefix(src=pkgdir):
             self.path("ca-bundle.crt")
 
     def package_finish(self):
@@ -1636,7 +1636,7 @@ class Linux_i686_Manifest(LinuxManifest):
         relpkgdir = os.path.join(pkgdir, "lib", "release")
         debpkgdir = os.path.join(pkgdir, "lib", "debug")
 
-        with self.prefix(build=relpkgdir, dst="lib"):
+        with self.prefix(src=relpkgdir, dst="lib"):
             self.path("libapr-1.so")
             self.path("libapr-1.so.0")
             self.path("libapr-1.so.0.4.5")
@@ -1698,9 +1698,9 @@ class Linux_i686_Manifest(LinuxManifest):
 
 
         # Vivox runtimes
-        with self.prefix(build=relpkgdir, dst="bin"):
+        with self.prefix(src=relpkgdir, dst="bin"):
             self.path("SLVoice")
-        with self.prefix(build=relpkgdir, dst="lib"):
+        with self.prefix(src=relpkgdir, dst="lib"):
             self.path("libortp.so")
             self.path("libsndfile.so.1")
             #self.path("libvivoxoal.so.1") # no - we'll re-use the viewer's own OpenAL lib
-- 
cgit v1.2.3


From 20907dbb72789de6eb539345dffcc62dcdb915e2 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Sun, 1 Jul 2018 21:07:44 -0400
Subject: DRTVWR-447: Update to viewer-manager build 517331

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 285449fa5a..6b6910b09e 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3314,9 +3314,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>3919570e9edecac56c1ef2d334370dc5</string>
+              <string>78e3b5f51554a186f8a62c0161f549d5</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/19742/138074/viewer_manager-1.0.516441-darwin64-516441.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/21002/152053/viewer_manager-1.0.517331-darwin64-517331.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3338,9 +3338,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>39add158bc6c4f975d7e17db34db8981</string>
+              <string>ccf1e6ba7811897f7d88af2a6fddceb0</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/19744/138154/viewer_manager-1.0.516441-windows-516441.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/21003/152060/viewer_manager-1.0.517331-windows-517331.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3351,7 +3351,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>1.0.516441</string>
+        <string>1.0.517331</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From 07d7e48f4157929b607c4183929aa02b8391444c Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 10 Jul 2018 14:01:19 -0400
Subject: DRTVWR-447: Use absolute path prefixes for CEF components.

viewer_manifest.py had LLManifest.prefix() calls starting with '..' (or
os.pardir, same thing) which failed with new prefix() calling conventions.
Explicitly starting with os.path.join(self.args['build'], os.pardir, etc.)
where applicable works much better.
---
 indra/newview/viewer_manifest.py | 28 +++++++++++++++-------------
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index e1374b0518..ad6ba3ddff 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -221,8 +221,7 @@ class ViewerManifest(LLManifest):
         return self.channel().replace(CHANNEL_VENDOR_BASE, "").strip()
 
     def channel_type(self): # returns 'release', 'beta', 'project', or 'test'
-        global CHANNEL_VENDOR_BASE
-        channel_qualifier=self.channel().replace(CHANNEL_VENDOR_BASE, "").lower().strip()
+        channel_qualifier=self.channel_variant().lower()
         if channel_qualifier.startswith('release'):
             channel_type='release'
         elif channel_qualifier.startswith('beta'):
@@ -519,7 +518,8 @@ class WindowsManifest(ViewerManifest):
                            "slplugin.exe")
         
         # Get shared libs from the shared libs staging directory
-        with self.prefix(src=os.path.join(os.pardir, 'sharedlibs', self.args['configuration'])):
+        with self.prefix(src=os.path.join(self.args['build'], os.pardir,
+                                          'sharedlibs', self.args['configuration'])):
 
             # Get llcommon and deps. If missing assume static linkage and continue.
             try:
@@ -612,17 +612,18 @@ class WindowsManifest(ViewerManifest):
 
         # Media plugins - CEF
         with self.prefix(dst="llplugin"):
-            with self.prefix(src='../media_plugins/cef/%s' % self.args['configuration']):
-                self.path("media_plugin_cef.dll")
+            with self.prefix(src=os.path.join(self.args['build'], os.pardir, 'media_plugins')):
+                with self.prefix(src=os.path.join('cef', self.args['configuration'])):
+                    self.path("media_plugin_cef.dll")
 
-            # Media plugins - LibVLC
-            with self.prefix(src='../media_plugins/libvlc/%s' % self.args['configuration']):
-                self.path("media_plugin_libvlc.dll")
+                # Media plugins - LibVLC
+                with self.prefix(src=os.path.join('libvlc', self.args['configuration'])):
+                    self.path("media_plugin_libvlc.dll")
 
-            # Media plugins - Example (useful for debugging - not shipped with release viewer)
-            if self.channel_type() != 'release':
-                with self.prefix(src='../media_plugins/example/%s' % self.args['configuration']):
-                    self.path("media_plugin_example.dll")
+                # Media plugins - Example (useful for debugging - not shipped with release viewer)
+                if self.channel_type() != 'release':
+                    with self.prefix(src=os.path.join('example', self.args['configuration'])):
+                        self.path("media_plugin_example.dll")
 
             # CEF runtime files - debug
             # CEF runtime files - not debug (release, relwithdebinfo etc.)
@@ -640,7 +641,8 @@ class WindowsManifest(ViewerManifest):
                 self.path("widevinecdmadapter.dll")
 
             # MSVC DLLs needed for CEF and have to be in same directory as plugin
-            with self.prefix(src=os.path.join(os.pardir, 'sharedlibs', 'Release')):
+            with self.prefix(src=os.path.join(self.args['build'], os.pardir,
+                                              'sharedlibs', 'Release')):
                 self.path("msvcp120.dll")
                 self.path("msvcr120.dll")
 
-- 
cgit v1.2.3


From 62eecd87a5610aae41cff6dc6ebcc81e7bcb474f Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 10 Jul 2018 17:47:00 -0400
Subject: SL-932: Attach user's settings.xml file to Windows crash reports.

It is not obvious whether the BugsplatMac attachment API even supports
multiple file attachments. I've contacted BugSplat support.
---
 indra/newview/llappviewerwin32.cpp | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 1e135fa229..adb3a2bbe2 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -123,6 +123,9 @@ namespace
             sBugSplatSender->sendAdditionalFile(
                 WCSTR(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log")));
 
+            sBugSplatSender->sendAdditionalFile(
+                WCSTR(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "settings.xml")));
+
             if (gAgentAvatarp)
             {
                 // user name, when we have it
-- 
cgit v1.2.3


From 66d083967ec25b5c46424689624b2aa366a2ae6b Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 11 Jul 2018 16:01:48 -0400
Subject: DRTVWR-447: Add more diagnostic logging to Windows BugSplat crash.

---
 indra/newview/llappviewerwin32.cpp | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index adb3a2bbe2..5c7cb5b9c6 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -116,24 +116,38 @@ namespace
 
     bool bugsplatSendLog(UINT nCode, LPVOID lpVal1, LPVOID lpVal2)
     {
+        // When BugSplat intercepts a crash, logging seems to stop?!
+        // Maybe because our test crashes use LL_ERROR(). Try writing a
+        // special log file "by hand."
+        std::ofstream log(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "BugSplat.log"),
+                          std::ios_base::app);
+        log << "Entered bugsplatSendLog() callback\n";
         if (nCode == MDSCB_EXCEPTIONCODE)
         {
             // send the main viewer log file
             // widen to wstring, convert to __wchar_t, then pass c_str()
             sBugSplatSender->sendAdditionalFile(
                 WCSTR(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log")));
+            log << "Attached " << gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log") << '\n';
 
             sBugSplatSender->sendAdditionalFile(
                 WCSTR(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "settings.xml")));
+            log << "Attached " << gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "settings.xml") << '\n';
 
             if (gAgentAvatarp)
             {
                 // user name, when we have it
                 sBugSplatSender->setDefaultUserName(WCSTR(gAgentAvatarp->getFullname()));
+                log << "Set default user name to '" << gAgentAvatarp->getFullname() << "'\n";
+            }
+            else
+            {
+                log << "gAgentAvatarp is nullptr\n";
             }
 
             // LL_ERRS message, when there is one
             sBugSplatSender->setDefaultUserDescription(WCSTR(LLError::getFatalMessage()));
+            log << "Set default user description to '" << LLError::getFatalMessage() << "'\n";
 
             if (gAgent.getRegion())
             {
@@ -144,10 +158,25 @@ namespace
                                     << '/' << loc.mV[0]
                                     << '/' << loc.mV[1]
                                     << '/' << loc.mV[2])));
+                log << "Set app identifier to '"
+                    << gAgent.getRegion()->getName()
+                    << '/' << loc.mV[0]
+                    << '/' << loc.mV[1]
+                    << '/' << log.mV[2]
+                    << "'\n";
+            }
+            else
+            {
+                log "gAgent.getRegion() is nullptr\n";
             }
 
             LL_INFOS() << "Sending crash report to BugSplat." << LL_ENDL;
+            log << "Sending crash report to BugSplat.\n";
         } // MDSCB_EXCEPTIONCODE
+        else
+        {
+            log << "nCode != MDSCB_EXCEPTIONCODE\n";
+        }
 
         return false;
     }
-- 
cgit v1.2.3


From 869d2f1fb2ed59e65dd9cb8b75a9ea560dbeab2d Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 11 Jul 2018 18:26:27 -0400
Subject: DRTVWR-447: Fix silly typos

---
 indra/newview/llappviewerwin32.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 5c7cb5b9c6..43b25699ca 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -162,12 +162,12 @@ namespace
                     << gAgent.getRegion()->getName()
                     << '/' << loc.mV[0]
                     << '/' << loc.mV[1]
-                    << '/' << log.mV[2]
+                    << '/' << loc.mV[2]
                     << "'\n";
             }
             else
             {
-                log "gAgent.getRegion() is nullptr\n";
+                log << "gAgent.getRegion() is nullptr\n";
             }
 
             LL_INFOS() << "Sending crash report to BugSplat." << LL_ENDL;
-- 
cgit v1.2.3


From c7616af624f784e6226f530f6a21b3541ba730cc Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 11 Jul 2018 21:52:03 -0400
Subject: DRTVWR-447: Diagnostically try naively widening BugSplat metadata.

---
 indra/newview/llappviewerwin32.cpp | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 43b25699ca..b78d6bdc62 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -104,7 +104,11 @@ namespace
     // specific wstringize() overload
     inline std::basic_string<__wchar_t> wunder(const std::string& str)
     {
-        return wunder(wstringize(str));
+//      return wunder(wstringize(str));
+        // Is wstringize(const std::string&) doing the right thing? Try
+        // widening each character individually -- which works only for 8-bit
+        // characters, of course -- just diagnostically.
+        return { str.begin(), str.end() };
     }
 
     // Irritatingly, MiniDmpSender::setCallback() is defined to accept a
-- 
cgit v1.2.3


From b883ffaa750630ce15bd133c3ddd1f39896fee02 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 12 Jul 2018 14:45:14 -0400
Subject: DRTVWR-447: More diagnostic logging for BugSplat metadata strings.

---
 indra/newview/llappviewerwin32.cpp | 55 ++++++++++++++++++++++++++++++--------
 1 file changed, 44 insertions(+), 11 deletions(-)

diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index b78d6bdc62..43a61c3857 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -70,6 +70,7 @@
 #include "llerrorcontrol.h"
 
 #include <fstream>
+#include <iomanip>
 #include <exception>
 
 // Bugsplat (http://bugsplat.com) crash reporting tool
@@ -111,6 +112,38 @@ namespace
         return { str.begin(), str.end() };
     }
 
+    // can only be used in a context in which 'log' is a valid std::ostream
+    #define WVCSTR(string) wview(log, WCSTR(string))
+
+    const __wchar_t* wview(std::ostream& out, const __wchar_t* wstr)
+    {
+        const size_t maxlen = 50;
+        char buffer[maxlen];
+        size_t size;
+        // Classic-C loop to calculate size; also forcibly narrow each
+        // __wchar_t to plain char into 'buffer'.
+        for (size = 0; size < (maxlen - 1) && wstr[size]; ++size)
+            buffer[size] = char(wstr[size]);
+        buffer[size] = '\0';
+        // Log the length, show the plain chars
+        out << "(length " << size << ") '" << buffer << "' ";
+        // Now dump the memory pointed to by wstr as raw bytes.
+        char oldfill = out.fill();
+        out << std::hex << std::setfill('0') << std::setw(2);
+        unsigned char* bytes = reinterpret_cast<unsigned char*>(wstr);
+        // Increment by one __wchar_t so we display the final nul character;
+        // remember to multiply by the number of bytes in a __wchar_t.
+        for (size_t b = 0; b < ((size + 1) * sizeof(__wchar_t)); ++b)
+        {
+            // To display as hex, need to convert each byte to int -- if we engage
+            // the operator<<(ostream&, char) overload, we'll just get characters.
+            out << int(bytes[b]);
+        }
+        out << std::dec << std::setfill(oldfill) << std::setw(0);
+        out << '\n';
+        return wstr;
+    }
+
     // Irritatingly, MiniDmpSender::setCallback() is defined to accept a
     // classic-C function pointer instead of an arbitrary C++ callable. If it
     // did accept a modern callable, we could pass a lambda that binds our
@@ -131,18 +164,18 @@ namespace
             // send the main viewer log file
             // widen to wstring, convert to __wchar_t, then pass c_str()
             sBugSplatSender->sendAdditionalFile(
-                WCSTR(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log")));
-            log << "Attached " << gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log") << '\n';
+                WVCSTR(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log")));
+            log << "sendAdditionalFile('" << gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log") << "')\n";
 
             sBugSplatSender->sendAdditionalFile(
-                WCSTR(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "settings.xml")));
-            log << "Attached " << gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "settings.xml") << '\n';
+                WVCSTR(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "settings.xml")));
+            log << "sendAdditionalFile('" << gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "settings.xml") << "')\n";
 
             if (gAgentAvatarp)
             {
                 // user name, when we have it
-                sBugSplatSender->setDefaultUserName(WCSTR(gAgentAvatarp->getFullname()));
-                log << "Set default user name to '" << gAgentAvatarp->getFullname() << "'\n";
+                sBugSplatSender->setDefaultUserName(WVCSTR(gAgentAvatarp->getFullname()));
+                log << "setDefaultUserName('" << gAgentAvatarp->getFullname() << "')\n";
             }
             else
             {
@@ -150,24 +183,24 @@ namespace
             }
 
             // LL_ERRS message, when there is one
-            sBugSplatSender->setDefaultUserDescription(WCSTR(LLError::getFatalMessage()));
-            log << "Set default user description to '" << LLError::getFatalMessage() << "'\n";
+            sBugSplatSender->setDefaultUserDescription(WVCSTR(LLError::getFatalMessage()));
+            log << "setDefaultUserDescription('" << LLError::getFatalMessage() << "')\n";
 
             if (gAgent.getRegion())
             {
                 // region location, when we have it
                 LLVector3 loc = gAgent.getPositionAgent();
                 sBugSplatSender->resetAppIdentifier(
-                    WCSTR(STRINGIZE(gAgent.getRegion()->getName()
+                    WVCSTR(STRINGIZE(gAgent.getRegion()->getName()
                                     << '/' << loc.mV[0]
                                     << '/' << loc.mV[1]
                                     << '/' << loc.mV[2])));
-                log << "Set app identifier to '"
+                log << "resetAppIdentifier('"
                     << gAgent.getRegion()->getName()
                     << '/' << loc.mV[0]
                     << '/' << loc.mV[1]
                     << '/' << loc.mV[2]
-                    << "'\n";
+                    << "')\n";
             }
             else
             {
-- 
cgit v1.2.3


From 3888d1862a79ab927d118087b2ce662f15e27f41 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 12 Jul 2018 16:07:06 -0400
Subject: DRTVWR-447: For want of a 'const', the build was lost.

---
 indra/newview/llappviewerwin32.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 43a61c3857..d2854c6b47 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -130,7 +130,7 @@ namespace
         // Now dump the memory pointed to by wstr as raw bytes.
         char oldfill = out.fill();
         out << std::hex << std::setfill('0') << std::setw(2);
-        unsigned char* bytes = reinterpret_cast<unsigned char*>(wstr);
+        const unsigned char* bytes = reinterpret_cast<const unsigned char*>(wstr);
         // Increment by one __wchar_t so we display the final nul character;
         // remember to multiply by the number of bytes in a __wchar_t.
         for (size_t b = 0; b < ((size + 1) * sizeof(__wchar_t)); ++b)
-- 
cgit v1.2.3


From a77f2e277fa9ea913cf9db3d39c61eb61f67ec11 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 13 Jul 2018 14:11:53 -0400
Subject: DRTVWR-447: Update to bugsplat build 517815

---
 autobuild.xml | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 6b6910b09e..259bb47789 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -244,9 +244,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>45d772624651dd2ec256ebc4be5fdb5e</string>
+              <string>647e3a9e4756d973ac5a400c39f29dcb</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/19829/138853/bugsplat-1.0.2.516501-darwin64-516501.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/21750/161045/bugsplat-1.0.2.517815-darwin64-517815.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -256,9 +256,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>7fca1d1d04b8e926a6afd14fff206ff0</string>
+              <string>f2a702e7be9ba378e61ec106a490bae1</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/19831/138867/bugsplat-3.5.0.5.516501-windows-516501.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/21752/161057/bugsplat-3.5.0.5.517815-windows-517815.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -268,16 +268,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>dc760b8760e6f8a8d27de3a9d7adf5c1</string>
+              <string>4678f8867652112d0cd873aba72d26e9</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/19830/138860/bugsplat-3.5.0.5.516501-windows64-516501.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/21751/161056/bugsplat-3.5.0.5.517815-windows64-517815.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.0.2.516501</string>
+        <string>1.0.2.517815</string>
       </map>
       <key>chardet</key>
       <map>
-- 
cgit v1.2.3


From 93ab8c216dc05a25f99a5f1bf17dded4b534819f Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 13 Jul 2018 16:45:00 -0400
Subject: DRTVWR-447: Update to bugsplat build 517820

---
 autobuild.xml | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 259bb47789..bc9e9ebad0 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -244,9 +244,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>647e3a9e4756d973ac5a400c39f29dcb</string>
+              <string>20f9bd631a30174aab36c765f0bec4a3</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/21750/161045/bugsplat-1.0.2.517815-darwin64-517815.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/21761/161237/bugsplat-1.0.2.517820-darwin64-517820.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -256,9 +256,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>f2a702e7be9ba378e61ec106a490bae1</string>
+              <string>63d7e171ae80da71ac8378ae68cfb1d8</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/21752/161057/bugsplat-3.5.0.5.517815-windows-517815.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/21763/161251/bugsplat-3.6.0.4.517820-windows-517820.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -268,16 +268,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>4678f8867652112d0cd873aba72d26e9</string>
+              <string>c1c68518b4457a093ef703e0c6376772</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/21751/161056/bugsplat-3.5.0.5.517815-windows64-517815.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/21762/161246/bugsplat-3.6.0.4.517820-windows64-517820.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.0.2.517815</string>
+        <string>1.0.2.517820</string>
       </map>
       <key>chardet</key>
       <map>
-- 
cgit v1.2.3


From 234ca77f19e53de1c02f8a641530ba89c90f1298 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Sat, 14 Jul 2018 08:52:58 -0400
Subject: DRTVWR-447: Revert BugSplat diagnostic logging; add platform tag.

---
 indra/newview/llappviewerwin32.cpp | 86 +++++---------------------------------
 1 file changed, 11 insertions(+), 75 deletions(-)

diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index d2854c6b47..adb340d40e 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -70,7 +70,6 @@
 #include "llerrorcontrol.h"
 
 #include <fstream>
-#include <iomanip>
 #include <exception>
 
 // Bugsplat (http://bugsplat.com) crash reporting tool
@@ -95,7 +94,7 @@ namespace
 
     // It would be nice if, when wchar_t is the same as __wchar_t, this whole
     // function would optimize away. However, we use it only for the arguments
-    // to make exactly one call to initialize BugSplat.
+    // to the BugSplat API -- a handful of calls.
     inline std::basic_string<__wchar_t> wunder(const std::wstring& str)
     {
         return { str.begin(), str.end() };
@@ -105,43 +104,7 @@ namespace
     // specific wstringize() overload
     inline std::basic_string<__wchar_t> wunder(const std::string& str)
     {
-//      return wunder(wstringize(str));
-        // Is wstringize(const std::string&) doing the right thing? Try
-        // widening each character individually -- which works only for 8-bit
-        // characters, of course -- just diagnostically.
-        return { str.begin(), str.end() };
-    }
-
-    // can only be used in a context in which 'log' is a valid std::ostream
-    #define WVCSTR(string) wview(log, WCSTR(string))
-
-    const __wchar_t* wview(std::ostream& out, const __wchar_t* wstr)
-    {
-        const size_t maxlen = 50;
-        char buffer[maxlen];
-        size_t size;
-        // Classic-C loop to calculate size; also forcibly narrow each
-        // __wchar_t to plain char into 'buffer'.
-        for (size = 0; size < (maxlen - 1) && wstr[size]; ++size)
-            buffer[size] = char(wstr[size]);
-        buffer[size] = '\0';
-        // Log the length, show the plain chars
-        out << "(length " << size << ") '" << buffer << "' ";
-        // Now dump the memory pointed to by wstr as raw bytes.
-        char oldfill = out.fill();
-        out << std::hex << std::setfill('0') << std::setw(2);
-        const unsigned char* bytes = reinterpret_cast<const unsigned char*>(wstr);
-        // Increment by one __wchar_t so we display the final nul character;
-        // remember to multiply by the number of bytes in a __wchar_t.
-        for (size_t b = 0; b < ((size + 1) * sizeof(__wchar_t)); ++b)
-        {
-            // To display as hex, need to convert each byte to int -- if we engage
-            // the operator<<(ostream&, char) overload, we'll just get characters.
-            out << int(bytes[b]);
-        }
-        out << std::dec << std::setfill(oldfill) << std::setw(0);
-        out << '\n';
-        return wstr;
+        return wunder(wstringize(str));
     }
 
     // Irritatingly, MiniDmpSender::setCallback() is defined to accept a
@@ -153,67 +116,40 @@ namespace
 
     bool bugsplatSendLog(UINT nCode, LPVOID lpVal1, LPVOID lpVal2)
     {
-        // When BugSplat intercepts a crash, logging seems to stop?!
-        // Maybe because our test crashes use LL_ERROR(). Try writing a
-        // special log file "by hand."
-        std::ofstream log(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "BugSplat.log"),
-                          std::ios_base::app);
-        log << "Entered bugsplatSendLog() callback\n";
         if (nCode == MDSCB_EXCEPTIONCODE)
         {
             // send the main viewer log file
             // widen to wstring, convert to __wchar_t, then pass c_str()
             sBugSplatSender->sendAdditionalFile(
-                WVCSTR(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log")));
-            log << "sendAdditionalFile('" << gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log") << "')\n";
+                WCSTR(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log")));
 
             sBugSplatSender->sendAdditionalFile(
-                WVCSTR(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "settings.xml")));
-            log << "sendAdditionalFile('" << gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "settings.xml") << "')\n";
+                WCSTR(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "settings.xml")));
+
+            // We don't have an email address for any user. Hijack this
+            // metadata field for the platform identifier.
+            sBugSplatSender->setDefaultUserEmail(WCSTR(STRINGIZE("Windows" << ADDRESS_SIZE)));
 
             if (gAgentAvatarp)
             {
                 // user name, when we have it
-                sBugSplatSender->setDefaultUserName(WVCSTR(gAgentAvatarp->getFullname()));
-                log << "setDefaultUserName('" << gAgentAvatarp->getFullname() << "')\n";
-            }
-            else
-            {
-                log << "gAgentAvatarp is nullptr\n";
+                sBugSplatSender->setDefaultUserName(WCSTR(gAgentAvatarp->getFullname()));
             }
 
             // LL_ERRS message, when there is one
-            sBugSplatSender->setDefaultUserDescription(WVCSTR(LLError::getFatalMessage()));
-            log << "setDefaultUserDescription('" << LLError::getFatalMessage() << "')\n";
+            sBugSplatSender->setDefaultUserDescription(WCSTR(LLError::getFatalMessage()));
 
             if (gAgent.getRegion())
             {
                 // region location, when we have it
                 LLVector3 loc = gAgent.getPositionAgent();
                 sBugSplatSender->resetAppIdentifier(
-                    WVCSTR(STRINGIZE(gAgent.getRegion()->getName()
+                    WCSTR(STRINGIZE(gAgent.getRegion()->getName()
                                     << '/' << loc.mV[0]
                                     << '/' << loc.mV[1]
                                     << '/' << loc.mV[2])));
-                log << "resetAppIdentifier('"
-                    << gAgent.getRegion()->getName()
-                    << '/' << loc.mV[0]
-                    << '/' << loc.mV[1]
-                    << '/' << loc.mV[2]
-                    << "')\n";
-            }
-            else
-            {
-                log << "gAgent.getRegion() is nullptr\n";
             }
-
-            LL_INFOS() << "Sending crash report to BugSplat." << LL_ENDL;
-            log << "Sending crash report to BugSplat.\n";
         } // MDSCB_EXCEPTIONCODE
-        else
-        {
-            log << "nCode != MDSCB_EXCEPTIONCODE\n";
-        }
 
         return false;
     }
-- 
cgit v1.2.3


From c11ecfddff7e8769ad9b0c0a6f039193c031b8a3 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 17 Jul 2018 14:42:35 -0400
Subject: DRTVWR-447: Force rebuild with new BUGSPLAT_DB value.

---
 indra/llappearance/lllocaltextureobject.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/indra/llappearance/lllocaltextureobject.cpp b/indra/llappearance/lllocaltextureobject.cpp
index f49cf21512..3f564ec3de 100644
--- a/indra/llappearance/lllocaltextureobject.cpp
+++ b/indra/llappearance/lllocaltextureobject.cpp
@@ -210,4 +210,3 @@ void LLLocalTextureObject::setBakedReady(BOOL ready)
 {
 	mIsBakedReady = ready;
 }
-
-- 
cgit v1.2.3


From 96ef1b5801ecb77a083274fb316b3b5463c0413e Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 17 Jul 2018 17:13:03 -0400
Subject: DRTVWR-447: Update to bugsplat build 517942

---
 autobuild.xml | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index bc9e9ebad0..3600def516 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -244,9 +244,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>20f9bd631a30174aab36c765f0bec4a3</string>
+              <string>da552cd81847f31046115917c325589f</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/21761/161237/bugsplat-1.0.2.517820-darwin64-517820.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/21916/162865/bugsplat-1.0.2.517942-darwin64-517942.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -256,9 +256,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>63d7e171ae80da71ac8378ae68cfb1d8</string>
+              <string>fc3014230ef81e1cdbc7506030fc01de</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/21763/161251/bugsplat-3.6.0.4.517820-windows-517820.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/21918/162879/bugsplat-3.6.0.4.517942-windows-517942.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -268,16 +268,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>c1c68518b4457a093ef703e0c6376772</string>
+              <string>8565ac0b9f521fa71bf503b31257dc2b</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/21762/161246/bugsplat-3.6.0.4.517820-windows64-517820.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/21917/162874/bugsplat-3.6.0.4.517942-windows64-517942.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.0.2.517820</string>
+        <string>1.0.2.517942</string>
       </map>
       <key>chardet</key>
       <map>
-- 
cgit v1.2.3


From d8dacc844ad5ffd97be42360b688bbf5cc23c50d Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 18 Jul 2018 09:53:09 -0400
Subject: DRTVWR-447: Update to bugsplat build 517972

---
 autobuild.xml | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 3600def516..281be39396 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -244,9 +244,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>da552cd81847f31046115917c325589f</string>
+              <string>0da51341172a14f06c323e240dd238f5</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/21916/162865/bugsplat-1.0.2.517942-darwin64-517942.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/21954/163369/bugsplat-1.0.2.517972-darwin64-517972.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -256,9 +256,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>fc3014230ef81e1cdbc7506030fc01de</string>
+              <string>d25adf0f2bcdbf59c035def0914fa1d5</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/21918/162879/bugsplat-3.6.0.4.517942-windows-517942.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/21955/163376/bugsplat-3.6.0.4.517972-windows-517972.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -268,16 +268,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>8565ac0b9f521fa71bf503b31257dc2b</string>
+              <string>0a4fc1ddec4ea0ad2d75d5422ef1df2b</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/21917/162874/bugsplat-3.6.0.4.517942-windows64-517942.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/21953/163362/bugsplat-3.6.0.4.517972-windows64-517972.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.0.2.517942</string>
+        <string>1.0.2.517972</string>
       </map>
       <key>chardet</key>
       <map>
-- 
cgit v1.2.3


From f1eb3c1b63b97de2a91c967e5c66f7b25c4963a2 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 18 Jul 2018 20:32:35 -0400
Subject: DRTVWR-447: Temporarily suppress building for BugSplat on Mac.

---
 build.sh | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/build.sh b/build.sh
index d531c0b046..216ce5720a 100755
--- a/build.sh
+++ b/build.sh
@@ -106,7 +106,8 @@ pre_build()
     # don't spew credentials into build log
     bugsplat_sh="$build_secrets_checkout/bugsplat/bugsplat.sh"
     set +x
-    if [ -r "$bugsplat_sh" ]
+    # HACK: Suppress for Mac until BugSplat fixes the Mac client API
+    if [ -r "$bugsplat_sh" -a "$arch" != "Darwin" ]
     then # show that we're doing this, just not the contents
          echo source "$bugsplat_sh"
          source "$bugsplat_sh"
-- 
cgit v1.2.3


From 59d2bf0622ceb5f6e09e7f850606e0cbcb794cb8 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 2 Aug 2018 16:21:30 -0400
Subject: DRTVWR-447: Merge changesets from newly updated viewer-release.

---
 autobuild.xml                |  64 ++++++++++++++++++++++++---
 indra/newview/CMakeLists.txt | 100 ++++++++++++++++++++++++++++++-------------
 2 files changed, 129 insertions(+), 35 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 1fef5ba725..c9a8a238e3 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -225,6 +225,60 @@
         <key>version</key>
         <string>1.57</string>
       </map>
+      <key>bugsplat</key>
+      <map>
+        <key>copyright</key>
+        <string>Copyright 2003-2017, BugSplat</string>
+        <key>description</key>
+        <string>Bugsplat crash reporting package</string>
+        <key>license</key>
+        <string>Proprietary</string>
+        <key>license_file</key>
+        <string>LICENSES/BUGSPLAT_LICENSE.txt</string>
+        <key>name</key>
+        <string>bugsplat</string>
+        <key>platforms</key>
+        <map>
+          <key>darwin64</key>
+          <map>
+            <key>archive</key>
+            <map>
+              <key>hash</key>
+              <string>0da51341172a14f06c323e240dd238f5</string>
+              <key>url</key>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/21954/163369/bugsplat-1.0.2.517972-darwin64-517972.tar.bz2</string>
+            </map>
+            <key>name</key>
+            <string>darwin64</string>
+          </map>
+          <key>windows</key>
+          <map>
+            <key>archive</key>
+            <map>
+              <key>hash</key>
+              <string>d25adf0f2bcdbf59c035def0914fa1d5</string>
+              <key>url</key>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/21955/163376/bugsplat-3.6.0.4.517972-windows-517972.tar.bz2</string>
+            </map>
+            <key>name</key>
+            <string>windows</string>
+          </map>
+          <key>windows64</key>
+          <map>
+            <key>archive</key>
+            <map>
+              <key>hash</key>
+              <string>0a4fc1ddec4ea0ad2d75d5422ef1df2b</string>
+              <key>url</key>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/21953/163362/bugsplat-3.6.0.4.517972-windows64-517972.tar.bz2</string>
+            </map>
+            <key>name</key>
+            <string>windows64</string>
+          </map>
+        </map>
+        <key>version</key>
+        <string>1.0.2.517972</string>
+      </map>
       <key>chardet</key>
       <map>
         <key>copyright</key>
@@ -3260,9 +3314,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>f45c0a5e7b4601b355e163bf62f5718e</string>
+              <string>78e3b5f51554a186f8a62c0161f549d5</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/20587/147509/viewer_manager-1.0.517052-darwin64-517052.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/21002/152053/viewer_manager-1.0.517331-darwin64-517331.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3284,9 +3338,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>d2443caf062697430071d458a965f611</string>
+              <string>ccf1e6ba7811897f7d88af2a6fddceb0</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/20588/147516/viewer_manager-1.0.517052-windows-517052.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/21003/152060/viewer_manager-1.0.517331-windows-517331.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3297,7 +3351,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>1.0.517052</string>
+        <string>1.0.517331</string>
       </map>
       <key>vlc-bin</key>
       <map>
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 2fc722d4c3..31c4c02d99 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -3,7 +3,14 @@
 project(viewer)
 
 include(00-Common)
+# DON'T move Linking.cmake to its place in the alphabetized list below: it
+# sets variables on which the 3p .cmake files depend.
+include(Linking)
+
 include(Boost)
+if (DEFINED ENV{BUGSPLAT_DB})
+  include(bugsplat)
+endif (DEFINED ENV{BUGSPLAT_DB})
 include(BuildPackagesInfo)
 include(BuildVersion)
 include(CMakeCopyIfDifferent)
@@ -37,7 +44,6 @@ include(LLUI)
 include(LLVFS)
 include(LLWindow)
 include(LLXML)
-include(Linking)
 include(NDOF)
 include(NVAPI)
 include(OPENAL)
@@ -93,6 +99,12 @@ include_directories(
     ${CMAKE_CURRENT_SOURCE_DIR}
     )
 
+if (DEFINED ENV{BUGSPLAT_DB})
+  include_directories(
+    ${BUGSPLAT_INCLUDE_DIR}
+    )
+endif (DEFINED ENV{BUGSPLAT_DB})
+
 include_directories(SYSTEM
     ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
     ${LLXML_SYSTEM_INCLUDE_DIRS}
@@ -1356,6 +1368,14 @@ if (DARWIN)
 
   # This should be compiled with the viewer.
   LIST(APPEND viewer_SOURCE_FILES llappdelegate-objc.mm)
+  set_source_files_properties(
+    llappdelegate-objc.mm
+    PROPERTIES
+    COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}"
+    # BugsplatMac is a module, imported with @import. That language feature
+    # demands these switches.
+    COMPILE_FLAGS "-fmodules -fcxx-modules"
+    )
 
   find_library(AGL_LIBRARY AGL)
   find_library(APPKIT_LIBRARY AppKit)
@@ -1370,6 +1390,12 @@ if (DARWIN)
     ${COREAUDIO_LIBRARY}
     )
 
+  if (DEFINED ENV{BUGSPLAT_DB})
+    list(APPEND viewer_LIBRARIES
+      ${BUGSPLAT_LIBRARIES}
+      )
+  endif (DEFINED ENV{BUGSPLAT_DB})
+
   # Add resource files to the project.
   set(viewer_RESOURCE_FILES
     secondlife.icns
@@ -1395,6 +1421,11 @@ endif (DARWIN)
 
 if (LINUX)
     LIST(APPEND viewer_SOURCE_FILES llappviewerlinux.cpp)
+    set_source_files_properties(
+      llappviewerlinux.cpp
+      PROPERTIES
+      COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}"
+      )
     LIST(APPEND viewer_SOURCE_FILES llappviewerlinux_api_dbus.cpp)
     SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed")
 
@@ -1411,6 +1442,11 @@ if (WINDOWS)
          llappviewerwin32.cpp
          llwindebug.cpp
          )
+    set_source_files_properties(
+      llappviewerwin32.cpp
+      PROPERTIES
+      COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}"
+      )
 
     list(APPEND viewer_HEADER_FILES
          llappviewerwin32.h
@@ -1693,6 +1729,11 @@ if (SDL_FOUND)
     )
 endif (SDL_FOUND)
 
+if (DEFINED ENV{BUGSPLAT_DB})
+  set_property(TARGET ${VIEWER_BINARY_NAME}
+    PROPERTY COMPILE_DEFINITIONS "LL_BUGSPLAT")
+endif (DEFINED ENV{BUGSPLAT_DB})
+
 # add package files
 file(GLOB EVENT_HOST_SCRIPT_GLOB_LIST
      ${CMAKE_CURRENT_SOURCE_DIR}/../viewer_components/*.py)
@@ -1791,7 +1832,7 @@ if (WINDOWS)
            ${SHARED_LIB_STAGING_DIR}/Debug/fmodexL.dll
           )
     endif (FMODEX)
-    
+
     add_custom_command(
       OUTPUT  ${CMAKE_CFG_INTDIR}/copy_touched.bat
       COMMAND ${PYTHON_EXECUTABLE}
@@ -1826,24 +1867,9 @@ if (WINDOWS)
 
     add_dependencies(${VIEWER_BINARY_NAME}
       SLPlugin
-   windows-crash-logger
+      windows-crash-logger
     )
 
-    # sets the 'working directory' for debugging from visual studio.
-    if (NOT UNATTENDED)
-        add_custom_command(
-            TARGET ${VIEWER_BINARY_NAME} POST_BUILD
-            COMMAND ${CMAKE_SOURCE_DIR}/tools/vstool/vstool.exe
-            ARGS
-              --solution
-              ${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}.sln
-              --workingdir
-              ${VIEWER_BINARY_NAME}
-              "${CMAKE_CURRENT_SOURCE_DIR}"
-            COMMENT "Setting the ${VIEWER_BINARY_NAME} working directory for debugging."
-            )
-    endif (NOT UNATTENDED)
-
     if (PACKAGE)
       add_custom_command(
         OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/event_host.tar.bz2
@@ -1905,8 +1931,8 @@ else (WINDOWS)
 endif (WINDOWS)
 
 # *NOTE: - this list is very sensitive to ordering, test carefully on all
-# platforms if you change the releative order of the entries here.
-# In particular, cmake 2.6.4 (when buidling with linux/makefile generators)
+# platforms if you change the relative order of the entries here.
+# In particular, cmake 2.6.4 (when building with linux/makefile generators)
 # appears to sometimes de-duplicate redundantly listed dependencies improperly.
 # To work around this, higher level modules should be listed before the modules
 # that they depend upon. -brad
@@ -1981,6 +2007,12 @@ target_link_libraries(${VIEWER_BINARY_NAME}
     ${LLAPPEARANCE_LIBRARIES}
     )
 
+if (DEFINED ENV{BUGSPLAT_DB})
+  target_link_libraries(${VIEWER_BINARY_NAME}
+    ${BUGSPLAT_LIBRARIES}
+    )
+endif (DEFINED ENV{BUGSPLAT_DB})
+
 set(ARTWORK_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE PATH
     "Path to artwork files.")
 
@@ -2054,8 +2086,10 @@ if (LINUX)
 endif (LINUX)
 
 if (DARWIN)
-  # These all get set with PROPERTIES
-  set(product "Second Life")
+  # These all get set with PROPERTIES. It's not that the property names are
+  # magically known to CMake -- it's that these names are referenced in the
+  # Info-SecondLife.plist file in the configure_file() directive below.
+  set(product "${VIEWER_CHANNEL}")
   # this is the setting for the Python wrapper, see SL-322 and WRAPPER line in Info-SecondLife.plist
   if (PACKAGE)
       set(MACOSX_WRAPPER_EXECUTABLE_NAME "SL_Launcher")
@@ -2063,21 +2097,29 @@ if (DARWIN)
       # force the name of the actual executable to allow running it within Xcode for debugging
       set(MACOSX_WRAPPER_EXECUTABLE_NAME "../Resources/Second Life Viewer.app/Contents/MacOS/Second Life")
   endif (PACKAGE)
-  set(MACOSX_BUNDLE_INFO_STRING "Second Life Viewer")
+  set(MACOSX_BUNDLE_INFO_STRING "${VIEWER_CHANNEL}")
   set(MACOSX_BUNDLE_ICON_FILE "secondlife.icns")
   set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.secondlife.indra.viewer")
   set(MACOSX_BUNDLE_LONG_VERSION_STRING "${VIEWER_CHANNEL} ${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}")
   set(MACOSX_BUNDLE_BUNDLE_NAME "SecondLife")
-  set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${VIEWER_SHORT_VERSION}")
+  set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}")
   set(MACOSX_BUNDLE_BUNDLE_VERSION "${VIEWER_SHORT_VERSION}${VIEWER_MACOSX_PHASE}${VIEWER_REVISION}")
   set(MACOSX_BUNDLE_COPYRIGHT "Copyright © Linden Research, Inc. 2007")
   set(MACOSX_BUNDLE_NSMAIN_NIB_FILE "SecondLife.nib")
   set(MACOSX_BUNDLE_NSPRINCIPAL_CLASS "NSApplication")
+
+  # https://blog.kitware.com/upcoming-in-cmake-2-8-12-osx-rpath-support/
+  set(CMAKE_MACOSX_RPATH 1)
   
   set_target_properties(
     ${VIEWER_BINARY_NAME}
     PROPERTIES
     OUTPUT_NAME "${product}"
+    # From Contents/MacOS/SecondLife, look in Contents/Frameworks
+    INSTALL_RPATH "@loader_path/../Frameworks"
+    # SIGH, as of 2018-05-24 (cmake 3.11.1) the INSTALL_RPATH property simply
+    # does not work. Try this:
+    LINK_FLAGS "-rpath @loader_path/../Frameworks"
     MACOSX_BUNDLE_INFO_PLIST
     "${CMAKE_CURRENT_SOURCE_DIR}/Info-SecondLife.plist"
     )
@@ -2148,7 +2190,7 @@ if (INSTALL)
   include(${CMAKE_CURRENT_SOURCE_DIR}/ViewerInstall.cmake)
 endif (INSTALL)
 
-if (PACKAGE)
+if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND NOT DEFINED ENV{BUGSPLAT_DB})
   set(SYMBOL_SEARCH_DIRS "")
   # Note that the path to VIEWER_SYMBOL_FILE must match that in ../../build.sh
   if (WINDOWS)
@@ -2167,8 +2209,8 @@ if (PACKAGE)
     list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/mac_crash_logger/${CMAKE_CFG_INTDIR}")
     list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/gstreamer010/${CMAKE_CFG_INTDIR}")
     set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-darwin-$ENV{AUTOBUILD_ADDRSIZE}.tar.bz2")
-    set(VIEWER_EXE_GLOBS "'Second Life' SLPlugin mac-crash-logger")
-    set(VIEWER_EXE_GLOBS "'Second Life' mac-crash-logger")
+    set(VIEWER_EXE_GLOBS "'${product}' SLPlugin mac-crash-logger")
+    set(VIEWER_EXE_GLOBS "'${product}' mac-crash-logger")
     set(VIEWER_LIB_GLOB "*.dylib")
   endif (DARWIN)
   if (LINUX)
@@ -2180,7 +2222,6 @@ if (PACKAGE)
     set(VIEWER_COPY_MANIFEST copy_l_viewer_manifest)
   endif (LINUX)
 
-  if(RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING)
   if(CMAKE_CFG_INTDIR STREQUAL ".")
       set(LLBUILD_CONFIG ${CMAKE_BUILD_TYPE})
   else(CMAKE_CFG_INTDIR STREQUAL ".")
@@ -2207,8 +2248,7 @@ if (PACKAGE)
     add_dependencies(generate_breakpad_symbols "${VIEWER_COPY_MANIFEST}")
   endif (WINDOWS OR LINUX)
   add_dependencies(llpackage generate_breakpad_symbols)
-  endif(RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING)
-endif (PACKAGE)
+endif ()
 
 if (LL_TESTS)
   # To add a viewer unit test, just add the test .cpp file below
-- 
cgit v1.2.3


From 3ca8263fb462bb0aba23b8d27d717a961db5bad6 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 15 Aug 2018 16:12:56 -0400
Subject: Backed out changeset 25b55601514d: re-enable building BugSplat on
 Mac.

---
 build.sh | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/build.sh b/build.sh
index 216ce5720a..d531c0b046 100755
--- a/build.sh
+++ b/build.sh
@@ -106,8 +106,7 @@ pre_build()
     # don't spew credentials into build log
     bugsplat_sh="$build_secrets_checkout/bugsplat/bugsplat.sh"
     set +x
-    # HACK: Suppress for Mac until BugSplat fixes the Mac client API
-    if [ -r "$bugsplat_sh" -a "$arch" != "Darwin" ]
+    if [ -r "$bugsplat_sh" ]
     then # show that we're doing this, just not the contents
          echo source "$bugsplat_sh"
          source "$bugsplat_sh"
-- 
cgit v1.2.3


From 0869e86fb1f5dea7322ecca968e9d0192f10eb86 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 15 Aug 2018 16:15:22 -0400
Subject: DRTVWR-447: Update to bugsplat build 518707

---
 autobuild.xml | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index c9a8a238e3..112381e2e3 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -244,9 +244,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>0da51341172a14f06c323e240dd238f5</string>
+              <string>5a576ab1dc1bcadadb45cd944c0c8cb0</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/21954/163369/bugsplat-1.0.2.517972-darwin64-517972.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23031/176476/bugsplat-1.0.4.518707-darwin64-518707.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -256,9 +256,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>d25adf0f2bcdbf59c035def0914fa1d5</string>
+              <string>00f055f5010bb94f6357aef8a9db8049</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/21955/163376/bugsplat-3.6.0.4.517972-windows-517972.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23033/176494/bugsplat-3.6.0.4.518707-windows-518707.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -268,16 +268,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>0a4fc1ddec4ea0ad2d75d5422ef1df2b</string>
+              <string>82707820572cd32f6f6fd10bd3384866</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/21953/163362/bugsplat-3.6.0.4.517972-windows64-517972.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23032/176487/bugsplat-3.6.0.4.518707-windows64-518707.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.0.2.517972</string>
+        <string>1.0.4.518707</string>
       </map>
       <key>chardet</key>
       <map>
-- 
cgit v1.2.3


From 1b2f52257aa84d43cdeec31f1b1424e7ad44fa7f Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 15 Aug 2018 16:38:09 -0400
Subject: DRTVWR-447: Streamline some of the logic around extra packages.

---
 indra/lib/python/indra/util/llmanifest.py | 81 +++++++------------------------
 1 file changed, 17 insertions(+), 64 deletions(-)

diff --git a/indra/lib/python/indra/util/llmanifest.py b/indra/lib/python/indra/util/llmanifest.py
index 974ac18e34..c24e25ba89 100755
--- a/indra/lib/python/indra/util/llmanifest.py
+++ b/indra/lib/python/indra/util/llmanifest.py
@@ -232,16 +232,12 @@ def main():
         print "Option:", opt, "=", args[opt]
 
     # pass in sourceid as an argument now instead of an environment variable
-    try:
-        args['sourceid'] = os.environ["sourceid"]
-    except KeyError:
-        args['sourceid'] = ""
+    args['sourceid'] = os.environ.get("sourceid", "")
 
     # Build base package.
     touch = args.get('touch')
     if touch:
         print 'Creating base package'
-    args['package_id'] = "" # base package has no package ID
     wm = LLManifest.for_platform(args['platform'], args.get('arch'))(args)
     wm.do(*args['actions'])
     # Store package file for later if making touched file.
@@ -251,64 +247,25 @@ def main():
         base_package_file = "" + wm.package_file
 
     # handle multiple packages if set
-    try:
-        additional_packages = os.environ["additional_packages"]
-    except KeyError:
-        additional_packages = ""
+    # ''.split() produces empty list
+    additional_packages = os.environ.get("additional_packages", "").split()
     if additional_packages:
         # Determine destination prefix / suffix for additional packages.
-        base_dest_postfix = args['dest']
-        base_dest_prefix = ""
         base_dest_parts = args['dest'].split(os.sep)
-        if len(base_dest_parts) > 1:
-            base_dest_postfix = base_dest_parts[len(base_dest_parts) - 1]
-            base_dest_prefix = base_dest_parts[0]
-            i = 1
-            while i < len(base_dest_parts) - 1:
-                base_dest_prefix = base_dest_prefix + os.sep + base_dest_parts[i]
-                i = i + 1
+        base_dest_parts.insert(-1, "{}")
+        base_dest_template = os.sep.join(base_dest_parts)
         # Determine touched prefix / suffix for additional packages.
-        base_touch_postfix = ""
-        base_touch_prefix = ""
         if touch:
-            base_touch_postfix = touch
-            base_touch_parts = touch.split('/')
+            base_touch_parts = touch.split(os.sep)
             if "arwin" in args['platform']:
-                if len(base_touch_parts) > 1:
-                    base_touch_postfix = base_touch_parts[len(base_touch_parts) - 1]
-                    base_touch_prefix = base_touch_parts[0]
-                    i = 1
-                    while i < len(base_touch_parts) - 1:
-                        base_touch_prefix = base_touch_prefix + '/' + base_touch_parts[i]
-                        i = i + 1
+                base_touch_parts.insert(-1, "{}")
             else:
-                if len(base_touch_parts) > 2:
-                    base_touch_postfix = base_touch_parts[len(base_touch_parts) - 2] + '/' + base_touch_parts[len(base_touch_parts) - 1]
-                    base_touch_prefix = base_touch_parts[0]
-                    i = 1
-                    while i < len(base_touch_parts) - 2:
-                        base_touch_prefix = base_touch_prefix + '/' + base_touch_parts[i]
-                        i = i + 1
-        # Store base channel name.
-        base_channel_name = args['channel']
-        # Build each additional package.
-        package_id_list = additional_packages.split(" ")
-        args['channel'] = base_channel_name
-        for package_id in package_id_list:
-            try:
-                if package_id + "_viewer_channel_suffix" in os.environ:
-                    args['channel_suffix'] = os.environ[package_id + "_viewer_channel_suffix"]
-                else:
-                    args['channel_suffix'] = None
-                if package_id + "_sourceid" in os.environ:
-                    args['sourceid'] = os.environ[package_id + "_sourceid"]
-                else:
-                    args['sourceid'] = None
-                args['dest'] = base_dest_prefix + os.sep + package_id + os.sep + base_dest_postfix
-            except KeyError:
-                sys.stderr.write("Failed to create package for package_id: %s" % package_id)
-                sys.stderr.flush()
-                continue
+                base_touch_parts.insert(-2, "{}")
+            base_touch_template = os.sep.join(base_touch_parts)
+        for package_id in additional_packages:
+            args['channel_suffix'] = os.environ.get(package_id + "_viewer_channel_suffix")
+            args['sourceid']       = os.environ.get(package_id + "_sourceid")
+            args['dest'] = base_dest_template.format(package_id)
             if touch:
                 print 'Creating additional package for "', package_id, '" in ', args['dest']
             try:
@@ -318,18 +275,14 @@ def main():
                 sys.exit(str(err))
             if touch:
                 print 'Created additional package ', wm.package_file, ' for ', package_id
-                faketouch = base_touch_prefix + '/' + package_id + '/' + base_touch_postfix
-                fp = open(faketouch, 'w')
-                fp.write('set package_file=%s\n' % wm.package_file)
-                fp.close()
+                with open(base_touch_template.format(package_id), 'w') as fp:
+                    fp.write('set package_file=%s\n' % wm.package_file)
     
     # Write out the package file in this format, so that it can easily be called
     # and used in a .bat file - yeah, it sucks, but this is the simplest...
-    touch = args.get('touch')
     if touch:
-        fp = open(touch, 'w')
-        fp.write('set package_file=%s\n' % base_package_file)
-        fp.close()
+        with open(touch, 'w') as fp:
+            fp.write('set package_file=%s\n' % base_package_file)
         print 'touched', touch
     return 0
 
-- 
cgit v1.2.3


From bc5aeae202ba6683cdae363a91d054043dc09949 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 15 Aug 2018 16:41:19 -0400
Subject: DRTVWR-447: Simplify redundant if-key-in-dict-and-value-nonempty
 logic

---
 indra/newview/viewer_manifest.py | 25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index ad6ba3ddff..ea0b3625be 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -108,17 +108,18 @@ class ViewerManifest(LLManifest):
                                         Type='String',
                                         Value=''))
                 settings_install = {}
-                if 'sourceid' in self.args and self.args['sourceid']:
+                sourceid = self.args.get('sourceid')
+                if sourceid:
                     settings_install['sourceid'] = settings_template['sourceid'].copy()
-                    settings_install['sourceid']['Value'] = self.args['sourceid']
-                    print "Set sourceid in settings_install.xml to '%s'" % self.args['sourceid']
+                    settings_install['sourceid']['Value'] = sourceid
+                    print "Set sourceid in settings_install.xml to '%s'" % sourceid
 
-                if 'channel_suffix' in self.args and self.args['channel_suffix']:
+                if self.args.get('channel_suffix'):
                     settings_install['CmdLineChannel'] = settings_template['CmdLineChannel'].copy()
                     settings_install['CmdLineChannel']['Value'] = self.channel_with_pkg_suffix()
                     print "Set CmdLineChannel in settings_install.xml to '%s'" % self.channel_with_pkg_suffix()
 
-                if 'grid' in self.args and self.args['grid']:
+                if self.args.get('grid'):
                     settings_install['CmdLineGridChoice'] = settings_template['CmdLineGridChoice'].copy()
                     settings_install['CmdLineGridChoice']['Value'] = self.grid()
                     print "Set CmdLineGridChoice in settings_install.xml to '%s'" % self.grid()
@@ -212,8 +213,9 @@ class ViewerManifest(LLManifest):
 
     def channel_with_pkg_suffix(self):
         fullchannel=self.channel()
-        if 'channel_suffix' in self.args and self.args['channel_suffix']:
-            fullchannel+=' '+self.args['channel_suffix']
+        channel_suffix = self.args.get('channel_suffix')
+        if channel_suffix:
+            fullchannel+=' '+channel_suffix
         return fullchannel
 
     def channel_variant(self):
@@ -239,11 +241,12 @@ class ViewerManifest(LLManifest):
         if self.channel_type() == 'release':
             suffix=suffix.replace('Release', '').strip()
         # for the base release viewer, suffix will now be null - for any other, append what remains
-        if len(suffix) > 0:
-            suffix = "_"+ ("_".join(suffix.split()))
+        if suffix:
+            suffix = "_".join([''] + suffix.split())
         # the additional_packages mechanism adds more to the installer name (but not to the app name itself)
-        if 'channel_suffix' in self.args and self.args['channel_suffix']:
-            suffix+='_'+("_".join(self.args['channel_suffix'].split()))
+        # ''.split() produces empty list, so suffix only changes if
+        # channel_suffix is non-empty
+        suffix = "_".join([suffix] + self.args.get('channel_suffix', '').split())
         return suffix
 
     def installer_base_name(self):
-- 
cgit v1.2.3


From 64034e83940e717d5aaf1e1f0dac5a9ed59bf835 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 17 Aug 2018 12:25:36 -0400
Subject: SL-824: Update to bugsplat build 518791

---
 autobuild.xml | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 112381e2e3..2862b5f969 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -244,9 +244,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>5a576ab1dc1bcadadb45cd944c0c8cb0</string>
+              <string>86575a3f538024f7aac1564a31bea855</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23031/176476/bugsplat-1.0.4.518707-darwin64-518707.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23157/177907/bugsplat-1.0.4.518791-darwin64-518791.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -256,9 +256,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>00f055f5010bb94f6357aef8a9db8049</string>
+              <string>6dc0debc2cd8497063bf330ef878d673</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23033/176494/bugsplat-3.6.0.4.518707-windows-518707.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23159/177920/bugsplat-3.6.0.4.518791-windows-518791.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -268,16 +268,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>82707820572cd32f6f6fd10bd3384866</string>
+              <string>db243bd98446e6228b8fe9c380981457</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23032/176487/bugsplat-3.6.0.4.518707-windows64-518707.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23158/177917/bugsplat-3.6.0.4.518791-windows64-518791.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.0.4.518707</string>
+        <string>1.0.4.518791</string>
       </map>
       <key>chardet</key>
       <map>
-- 
cgit v1.2.3


From 52fe35737024abc5712bda770801fdeb703881fc Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 17 Aug 2018 14:39:32 -0400
Subject: DRTVWR-447: Use os.path.split(path) instead of path.split(os.sep).

On Windows, where 'path' might be separated either with '/' or '\', the latter
breaks unless all path separators are in fact the os.sep character '\'. While
it would be possible to code something fancy with os.sep and os.altsep,
testing the latter for None, much simpler to let os.path.split() handle it.
---
 indra/lib/python/indra/util/llmanifest.py | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/indra/lib/python/indra/util/llmanifest.py b/indra/lib/python/indra/util/llmanifest.py
index c24e25ba89..611f72269e 100755
--- a/indra/lib/python/indra/util/llmanifest.py
+++ b/indra/lib/python/indra/util/llmanifest.py
@@ -251,17 +251,21 @@ def main():
     additional_packages = os.environ.get("additional_packages", "").split()
     if additional_packages:
         # Determine destination prefix / suffix for additional packages.
-        base_dest_parts = args['dest'].split(os.sep)
+        base_dest_parts = list(os.path.split(args['dest']))
         base_dest_parts.insert(-1, "{}")
-        base_dest_template = os.sep.join(base_dest_parts)
+        base_dest_template = os.path.join(*base_dest_parts)
         # Determine touched prefix / suffix for additional packages.
         if touch:
-            base_touch_parts = touch.split(os.sep)
+            base_touch_parts = list(os.path.split(touch))
+            # Because of the special insert() logic below, we don't just want
+            # [dirpath, basename]; we want [dirpath, directory, basename].
+            # Further split the dirpath and replace it in the list.
+            base_touch_parts[0:1] = os.path.split(base_touch_parts[0])
             if "arwin" in args['platform']:
                 base_touch_parts.insert(-1, "{}")
             else:
                 base_touch_parts.insert(-2, "{}")
-            base_touch_template = os.sep.join(base_touch_parts)
+            base_touch_template = os.path.join(*base_touch_parts)
         for package_id in additional_packages:
             args['channel_suffix'] = os.environ.get(package_id + "_viewer_channel_suffix")
             args['sourceid']       = os.environ.get(package_id + "_sourceid")
-- 
cgit v1.2.3


From 466a72da472182aec129eeb77e2617a627ce2f16 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 17 Aug 2018 14:40:12 -0400
Subject: SL-824: Update to bugsplat build 518798

---
 autobuild.xml | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 2862b5f969..7562f855e9 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -244,9 +244,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>86575a3f538024f7aac1564a31bea855</string>
+              <string>7daaef9f73a799c18f733994aa3f993b</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23157/177907/bugsplat-1.0.4.518791-darwin64-518791.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23170/177964/bugsplat-1.0.4.518798-darwin64-518798.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -256,9 +256,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>6dc0debc2cd8497063bf330ef878d673</string>
+              <string>0621c201b96a324182172ac975550c94</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23159/177920/bugsplat-3.6.0.4.518791-windows-518791.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23172/177978/bugsplat-3.6.0.4.518798-windows-518798.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -268,16 +268,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>db243bd98446e6228b8fe9c380981457</string>
+              <string>1e4bff4a9c05e5ca4d70794dffd010a8</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23158/177917/bugsplat-3.6.0.4.518791-windows64-518791.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23171/177973/bugsplat-3.6.0.4.518798-windows64-518798.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.0.4.518791</string>
+        <string>1.0.4.518798</string>
       </map>
       <key>chardet</key>
       <map>
-- 
cgit v1.2.3


From 9be834b334fb96fb42ef6e40515a6350806388e2 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 17 Aug 2018 16:06:14 -0400
Subject: SL-824: Update to bugsplat build 518806

---
 autobuild.xml | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 7562f855e9..0948635268 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -244,9 +244,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>7daaef9f73a799c18f733994aa3f993b</string>
+              <string>3af12be70ac978c259446ec526851377</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23170/177964/bugsplat-1.0.4.518798-darwin64-518798.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23185/178026/bugsplat-1.0.4.518806-darwin64-518806.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -256,9 +256,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>0621c201b96a324182172ac975550c94</string>
+              <string>ddc029735d9c290539160e3329033b94</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23172/177978/bugsplat-3.6.0.4.518798-windows-518798.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23187/178039/bugsplat-3.6.0.4.518806-windows-518806.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -268,16 +268,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>1e4bff4a9c05e5ca4d70794dffd010a8</string>
+              <string>b0437960d392a99b681adbc88368de12</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23171/177973/bugsplat-3.6.0.4.518798-windows64-518798.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23186/178036/bugsplat-3.6.0.4.518806-windows64-518806.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.0.4.518798</string>
+        <string>1.0.4.518806</string>
       </map>
       <key>chardet</key>
       <map>
-- 
cgit v1.2.3


From de88537d384cbdf1059a6fc21d538c505b21dedc Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Sat, 18 Aug 2018 09:37:07 -0400
Subject: Backed out changeset 599911002a5e: revert to bugsplat build 518798.

---
 autobuild.xml | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 0948635268..7562f855e9 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -244,9 +244,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>3af12be70ac978c259446ec526851377</string>
+              <string>7daaef9f73a799c18f733994aa3f993b</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23185/178026/bugsplat-1.0.4.518806-darwin64-518806.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23170/177964/bugsplat-1.0.4.518798-darwin64-518798.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -256,9 +256,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>ddc029735d9c290539160e3329033b94</string>
+              <string>0621c201b96a324182172ac975550c94</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23187/178039/bugsplat-3.6.0.4.518806-windows-518806.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23172/177978/bugsplat-3.6.0.4.518798-windows-518798.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -268,16 +268,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>b0437960d392a99b681adbc88368de12</string>
+              <string>1e4bff4a9c05e5ca4d70794dffd010a8</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23186/178036/bugsplat-3.6.0.4.518806-windows64-518806.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23171/177973/bugsplat-3.6.0.4.518798-windows64-518798.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.0.4.518806</string>
+        <string>1.0.4.518798</string>
       </map>
       <key>chardet</key>
       <map>
-- 
cgit v1.2.3


From c50df8c4d9d5a221862444e8d608078db33dec97 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Sat, 18 Aug 2018 12:03:57 -0400
Subject: SL-824: Update to bugsplat build 518831

---
 autobuild.xml | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 7562f855e9..f2304d1854 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -244,9 +244,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>7daaef9f73a799c18f733994aa3f993b</string>
+              <string>f72e68cfc7343015cd49d02edc020378</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23170/177964/bugsplat-1.0.4.518798-darwin64-518798.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23219/178251/bugsplat-1.0.4.518831-darwin64-518831.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -256,9 +256,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>0621c201b96a324182172ac975550c94</string>
+              <string>d84272f70f884213a5efabfa70690620</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23172/177978/bugsplat-3.6.0.4.518798-windows-518798.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23220/178260/bugsplat-3.6.0.4.518831-windows-518831.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -268,16 +268,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>1e4bff4a9c05e5ca4d70794dffd010a8</string>
+              <string>6afe20f53e5a3135090bc5422424d5d4</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23171/177973/bugsplat-3.6.0.4.518798-windows64-518798.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23221/178264/bugsplat-3.6.0.4.518831-windows64-518831.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.0.4.518798</string>
+        <string>1.0.4.518831</string>
       </map>
       <key>chardet</key>
       <map>
-- 
cgit v1.2.3


From 7b83e8cdf742f800e0e7e59a9aae0ce870a6cc9b Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 21 Aug 2018 09:51:28 -0400
Subject: SL-824: Update to bugsplat build 518876

---
 autobuild.xml | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index f2304d1854..7b6036f69e 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -244,9 +244,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>f72e68cfc7343015cd49d02edc020378</string>
+              <string>f01caa9aeb4c19f679e60609e6095335</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23219/178251/bugsplat-1.0.4.518831-darwin64-518831.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23285/178722/bugsplat-1.0.5.518876-darwin64-518876.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -256,9 +256,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>d84272f70f884213a5efabfa70690620</string>
+              <string>17f0e6d2fce03ae48ac02ccaebe48f61</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23220/178260/bugsplat-3.6.0.4.518831-windows-518831.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23286/178729/bugsplat-3.6.0.4.518876-windows-518876.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -268,16 +268,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>6afe20f53e5a3135090bc5422424d5d4</string>
+              <string>e963a42106ed0fc8b87974cfce040714</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23221/178264/bugsplat-3.6.0.4.518831-windows64-518831.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23284/178715/bugsplat-3.6.0.4.518876-windows64-518876.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.0.4.518831</string>
+        <string>1.0.5.518876</string>
       </map>
       <key>chardet</key>
       <map>
-- 
cgit v1.2.3


From db970c1a5f4737d1d6c7c6dbb50a16ec7592e6d6 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 21 Aug 2018 19:23:33 -0400
Subject: Don't compare rbegin() iterators, use LLStringUtil::endsWith().

I think the intention of (sDumpDir.rbegin() == mDirDelimiter.rbegin()) was to
test whether sDumpDir endsWith(mDirDelimiter). But those iterators will never
be equal. Instead, use LLStringUtil::endsWith().
---
 indra/llvfs/lldir.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp
index 2069888774..18836e54b0 100644
--- a/indra/llvfs/lldir.cpp
+++ b/indra/llvfs/lldir.cpp
@@ -42,6 +42,7 @@
 
 #include "lldiriterator.h"
 #include "stringize.h"
+#include "llstring.h"
 #include <boost/filesystem.hpp>
 #include <boost/foreach.hpp>
 #include <boost/range/begin.hpp>
@@ -317,9 +318,9 @@ const std::string& LLDir::getChatLogsDir() const
 void LLDir::setDumpDir( const std::string& path )
 {
     LLDir::sDumpDir = path;
-    if (! sDumpDir.empty() && sDumpDir.rbegin() == mDirDelimiter.rbegin() )
+    if (LLStringUtil::endsWith(sDumpDir, mDirDelimiter))
     {
-        sDumpDir.erase(sDumpDir.size() -1);
+        sDumpDir.erase(sDumpDir.size() - mDirDelimiter.size());
     }
 }
 
-- 
cgit v1.2.3


From 87763d964a95bc918e26ae35932a99d56961f159 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 21 Aug 2018 19:26:07 -0400
Subject: MAINT-8917: For BugSplat viewer, don't create dump-UUID directory.

Just put the static_debug_info.log file in the parent logs directory.

Also update that static_debug_info.log file with "FatalMessage" key taken from
LL_ERRS() message string.
---
 indra/newview/llappviewer.cpp | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 687b76c224..3e25b395c4 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -781,12 +781,18 @@ bool LLAppViewer::init()
 	initMaxHeapSize() ;
 	LLCoros::instance().setStackSize(gSavedSettings.getS32("CoroutineStackSize"));
 
+#if LL_BUGSPLAT
+	// MAINT-8917: don't create a dump directory just for the
+	// static_debug_info.log file
+	std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "");
+#else // ! LL_BUGSPLAT
 	// write Google Breakpad minidump files to a per-run dump directory to avoid multiple viewer issues.
 	std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "");
+#endif // ! LL_BUGSPLAT
 	mDumpPath = logdir;
 	setMiniDumpDir(logdir);
 	logdir += gDirUtilp->getDirDelimiter();
-    setDebugFileNames(logdir);
+	setDebugFileNames(logdir);
 
 
 	// Although initLoggingAndGetLastDuration() is the right place to mess with
@@ -2172,6 +2178,12 @@ void errorCallback(const std::string &error_string)
 	//Set the ErrorActivated global so we know to create a marker file
 	gLLErrorActivated = true;
 
+	gDebugInfo["FatalMessage"] = error_string;
+	// We're not already crashing -- we simply *intend* to crash. Since we
+	// haven't actually trashed anything yet, we can afford to write the whole
+	// static info file.
+	LLAppViewer::instance()->writeDebugInfo();
+
 	LLError::crashAndLoop(error_string);
 }
 
-- 
cgit v1.2.3


From 302052700b4605605808b90bed8fb1c5a93ece22 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 21 Aug 2018 19:28:19 -0400
Subject: DRTVWR-447: Add static_debug_info.log file to Windows crash report.

Also use the LLOSInfo information for platform rather than simply Windows32 or
Windows64.
---
 indra/newview/llappviewerwin32.cpp | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index adb340d40e..9f85ca3edf 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -126,9 +126,14 @@ namespace
             sBugSplatSender->sendAdditionalFile(
                 WCSTR(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "settings.xml")));
 
+            sBugSplatSender->sendAdditionalFile(
+                WCSTR(*LLAppViewer::instance()->getStaticDebugFile()));
+
             // We don't have an email address for any user. Hijack this
             // metadata field for the platform identifier.
-            sBugSplatSender->setDefaultUserEmail(WCSTR(STRINGIZE("Windows" << ADDRESS_SIZE)));
+            sBugSplatSender->setDefaultUserEmail(
+                WCSTR(STRINGIZE(LLOSInfo::instance().getOSStringSimple() << " ("
+                                << ADDRESS_SIZE << "-bit)")));
 
             if (gAgentAvatarp)
             {
-- 
cgit v1.2.3


From 7dc014474de0c2d83a3cd314acd9dc0882622299 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 22 Aug 2018 10:48:29 -0400
Subject: DRTVWR-447: Attempt to post BugSplat metadata with Mac crash reports.

Introduce CrashMetadata, an LLSingleton in llappviewermacosx.cpp, declared in
llappviewermacosx-for-objc.h and accessed by the various
BugsplatStartupManagerDelegate override methods. CrashMetadata is populated by
reading the previous (presumably crashed) run's static_debug_info.log file.

This replaces the previous getOldLogFilePathname(), getFatalMessage() and
getAgentFullname() functions. To extend that suite for additional metadata,
not only would we have to keep adding new free functions, but we'd have to
keep rereading the static_debug_info.log file.

Override the new applicationKeyForBugsplatStartupManager,
defaultUserNameForBugsplatStartupManager,
defaultUserEmailForBugsplatStartupManager methods to extract relevant fields
from CrashMetadata. Change applicationLogForBugsplatStartupManager and
attachmentForBugsplatStartupManager to do the same.

Enhance llviewerregion.cpp to update the static_debug_info.log file every
time we enter a new region.
---
 indra/newview/llappdelegate-objc.mm        | 43 ++++++++++++++++++++++------
 indra/newview/llappviewermacosx-for-objc.h | 21 ++++++++++++--
 indra/newview/llappviewermacosx.cpp        | 45 +++++++++++++++++++++++++-----
 indra/newview/llviewerregion.cpp           | 19 +++++++++++++
 4 files changed, 109 insertions(+), 19 deletions(-)

diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm
index 82e49540a4..ba697d0f77 100644
--- a/indra/newview/llappdelegate-objc.mm
+++ b/indra/newview/llappdelegate-objc.mm
@@ -199,10 +199,34 @@
 - (NSString *)applicationLogForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager
 {
     infos("Reached applicationLogForBugsplatStartupManager");
-    // Apparently this override method only contributes the User Description
-    // field of BugSplat's All Crashes table. Despite the method name, it
-    // would seem to be a bad place to try to stuff all of SecondLife.log.
-    return [NSString stringWithCString:getFatalMessage().c_str()
+    // This strangely-named override method contributes the User Description
+    // metadata field.
+    return [NSString stringWithCString:CrashMetadata_instance().fatalMessage.c_str()
+                              encoding:NSUTF8StringEncoding];
+}
+
+- (NSString *)applicationKeyForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager signal:(NSString *)signal exceptionName:(NSString *)exceptionName exceptionReason:(NSString *)exceptionReason {
+    // TODO: exceptionName, exceptionReason
+
+    // Windows sends location within region as well, but that's because
+    // BugSplat for Windows intercepts crashes during the same run, and that
+    // information can be queried once. On the Mac, any metadata we have is
+    // written (and rewritten) to the static_debug_info.log file that we read
+    // at the start of the next viewer run. It seems ridiculously expensive to
+    // rewrite that file on every frame in which the avatar moves.
+    return [NSString stringWithCString:CrashMetadata_instance().regionName.c_str()
+                              encoding:NSUTF8StringEncoding];
+}
+
+- (NSString *)defaultUserNameForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager {
+    return [NSString stringWithCString:CrashMetadata_instance().agentFullname.c_str()
+                              encoding:NSUTF8StringEncoding];
+}
+
+- (NSString *)defaultUserEmailForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager {
+    // Use the email field for OS version, just as we do on Windows, until
+    // BugSplat provides more metadata fields.
+    return [NSString stringWithCString:CrashMetadata_instance().OSInfo.c_str()
                               encoding:NSUTF8StringEncoding];
 }
 
@@ -212,11 +236,12 @@
 }
 
 - (BugsplatAttachment *)attachmentForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager {
-    // We get the *old* log file pathname (for SecondLife.old) because it's on
-    // the run *following* the crash that BugsplatStartupManager notices that
-    // the previous run crashed and calls this override. By that time, we've
-    // already renamed SecondLife.log to SecondLife.old.
-    std::string logfile = getOldLogFilePathname();
+    std::string logfile = CrashMetadata_instance().logFilePathname;
+    // Still to do:
+    // userSettingsPathname
+    // staticDebugPathname
+    // but the BugsplatMac version 1.0.5 BugsplatStartupManagerDelegate API
+    // doesn't yet provide a way to attach more than one file.
     NSString *ns_logfile = [NSString stringWithCString:logfile.c_str()
                                               encoding:NSUTF8StringEncoding];
     NSData *data = [NSData dataWithContentsOfFile:ns_logfile];
diff --git a/indra/newview/llappviewermacosx-for-objc.h b/indra/newview/llappviewermacosx-for-objc.h
index ac85d7e8c3..79da453cbe 100644
--- a/indra/newview/llappviewermacosx-for-objc.h
+++ b/indra/newview/llappviewermacosx-for-objc.h
@@ -29,9 +29,24 @@ void handleUrl(const char* url_utf8);
 bool pumpMainLoop();
 void handleQuit();
 void cleanupViewer();
-std::string getOldLogFilePathname();
-std::string getFatalMessage();
-std::string getAgentFullname();
 void infos(const std::string& message);
 
+// This struct is malleable; it only serves as a way to convey a number of
+// fields from llappviewermacosx.cpp's CrashMetadata_instance() function to the
+// consuming functions in llappdelegate-objc.mm. As long as both those sources
+// are compiled with this same header, the content and order of CrashMetadata
+// can change as needed.
+struct CrashMetadata
+{
+    std::string logFilePathname;
+    std::string userSettingsPathname;
+    std::string staticDebugPathname;
+    std::string OSInfo;
+    std::string agentFullname;
+    std::string regionName;
+    std::string fatalMessage;
+};
+
+CrashMetadata& CrashMetadata_instance();
+
 #endif /* ! defined(LL_LLAPPVIEWERMACOSX_FOR_OBJC_H) */
diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp
index c3a3c3284a..7f7284a796 100644
--- a/indra/newview/llappviewermacosx.cpp
+++ b/indra/newview/llappviewermacosx.cpp
@@ -39,6 +39,7 @@
 #include "llappviewermacosx-for-objc.h"
 #include "llwindowmacosx-objc.h"
 #include "llcommandlineparser.h"
+#include "llsdserialize.h"
 
 #include "llviewernetwork.h"
 #include "llviewercontrol.h"
@@ -53,6 +54,7 @@
 #endif
 #include <vector>
 #include <exception>
+#include <fstream>
 
 #include "lldir.h"
 #include <signal.h>
@@ -150,19 +152,48 @@ void cleanupViewer()
 	gViewerAppPtr = NULL;
 }
 
-std::string getOldLogFilePathname()
+// The BugsplatMac API is structured as a number of different method
+// overrides, each returning a different piece of metadata. But since we
+// obtain such metadata by opening and parsing a file, it seems ridiculous to
+// reopen and reparse it for every individual string desired. What we want is
+// to open and parse the file once, retaining the data for subsequent
+// requests. That's why this is an LLSingleton.
+// Another approach would be to provide a function that simply returns
+// CrashMetadata, storing the struct in LLAppDelegate, but nat doesn't know
+// enough Objective-C++ to code that. We'd still have to detect which of the
+// method overrides is called first so that the results are order-insensitive.
+class CrashMetadataSingleton: public CrashMetadata, public LLSingleton<CrashMetadataSingleton>
 {
-    return gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.old");
-}
+    LLSINGLETON(CrashMetadataSingleton);
+};
 
-std::string getFatalMessage()
+// Populate the fields of our public base-class struct.
+CrashMetadataSingleton::CrashMetadataSingleton()
 {
-    return LLError::getFatalMessage();
+    // Note: we depend on being able to read the static_debug_info.log file
+    // from the *previous* run before we overwrite it with the new one for
+    // *this* run. LLAppViewer initialization must happen in the Right Order.
+    staticDebugPathname = *gViewerAppPtr->getStaticDebugFile();
+    std::ifstream static_file(staticDebugPathname);
+    LLSD info;
+    if (static_file.is_open() &&
+        LLSDSerialize::deserialize(info, static_file, LLSDSerialize::SIZE_UNLIMITED))
+    {
+        logFilePathname      = info["SLLog"].asString();
+        userSettingsPathname = info["SettingsFilename"].asString();
+        OSInfo               = info["OSInfo"].asString();
+        agentFullname        = info["LoginName"].asString();
+        // Translate underscores back to spaces
+        LLStringUtil::replaceChar(agentFullname, '_', ' ');
+        regionName           = info["CurrentRegion"].asString();
+        fatalMessage         = info["FatalMessage"].asString();
+    }
 }
 
-std::string getAgentFullname()
+// Avoid having to compile all of our LLSingleton machinery in Objective-C++.
+CrashMetadata& CrashMetadata_instance()
 {
-    return gAgentAvatarp? gAgentAvatarp->getFullname() : std::string();
+    return CrashMetadataSingleton::instance();
 }
 
 void infos(const std::string& message)
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index b759c2a3ab..ca452fc766 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -44,6 +44,7 @@
 
 #include "llagent.h"
 #include "llagentcamera.h"
+#include "llappviewer.h"
 #include "llavatarrenderinfoaccountant.h"
 #include "llcallingcard.h"
 #include "llcommandhandler.h"
@@ -104,6 +105,18 @@ typedef std::map<std::string, std::string> CapabilityMap;
 
 static void log_capabilities(const CapabilityMap &capmap);
 
+namespace
+{
+
+void newRegionEntry(LLViewerRegion& region)
+{
+    LL_INFOS("LLViewerRegion") << "Entering region [" << region.getName() << "]" << LL_ENDL;
+    gDebugInfo["CurrentRegion"] = region.getName();
+    LLAppViewer::instance()->writeDebugInfo();
+}
+
+} // anonymous namespace
+
 // support for secondlife:///app/region/{REGION} SLapps
 // N.B. this is defined to work exactly like the classic secondlife://{REGION}
 // However, the later syntax cannot support spaces in the region name because
@@ -249,6 +262,9 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
             return; // this error condition is not recoverable.
         }
 
+        // record that we just entered a new region
+        newRegionEntry(*regionp);
+
         // After a few attempts, continue login.  But keep trying to get the caps:
         if (mSeedCapAttempts >= mSeedCapMaxAttemptsBeforeLogin &&
             STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())
@@ -369,6 +385,9 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCompleteCoro(U64 regionHandle)
             break; // this error condition is not recoverable.
         }
 
+        // record that we just entered a new region
+        newRegionEntry(*regionp);
+
         LLSD capabilityNames = LLSD::emptyArray();
         buildCapabilityNames(capabilityNames);
 
-- 
cgit v1.2.3


From 787053ffeb70f4e3d7ade36290ad7e75f1146b74 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 22 Aug 2018 13:26:19 -0400
Subject: DRTVWR-447: Add logging to BugsplatMac override methods.

---
 indra/newview/llappdelegate-objc.mm | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm
index ba697d0f77..66bcf58961 100644
--- a/indra/newview/llappdelegate-objc.mm
+++ b/indra/newview/llappdelegate-objc.mm
@@ -198,10 +198,11 @@
 
 - (NSString *)applicationLogForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager
 {
-    infos("Reached applicationLogForBugsplatStartupManager");
+    std::string fatalMessage(CrashMetadata_instance().fatalMessage);
+    infos("applicationLogForBugsplatStartupManager -> '" + fatalMessage + "'");
     // This strangely-named override method contributes the User Description
     // metadata field.
-    return [NSString stringWithCString:CrashMetadata_instance().fatalMessage.c_str()
+    return [NSString stringWithCString:fatalMessage.c_str()
                               encoding:NSUTF8StringEncoding];
 }
 
@@ -214,25 +215,31 @@
     // written (and rewritten) to the static_debug_info.log file that we read
     // at the start of the next viewer run. It seems ridiculously expensive to
     // rewrite that file on every frame in which the avatar moves.
-    return [NSString stringWithCString:CrashMetadata_instance().regionName.c_str()
+    std::string regionName(CrashMetadata_instance().regionName);
+    infos("applicationKeyForBugsplatStartupManager -> '" + regionName + "'");
+    return [NSString stringWithCString:regionName.c_str()
                               encoding:NSUTF8StringEncoding];
 }
 
 - (NSString *)defaultUserNameForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager {
-    return [NSString stringWithCString:CrashMetadata_instance().agentFullname.c_str()
+    std::string agentFullname(CrashMetadata_instance().agentFullname);
+    infos("defaultUserNameForBugsplatStartupManager -> '" + agentFullname + "'");
+    return [NSString stringWithCString:agentFullname.c_str()
                               encoding:NSUTF8StringEncoding];
 }
 
 - (NSString *)defaultUserEmailForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager {
     // Use the email field for OS version, just as we do on Windows, until
     // BugSplat provides more metadata fields.
-    return [NSString stringWithCString:CrashMetadata_instance().OSInfo.c_str()
+    std::string OSInfo(CrashMetadata_instance().OSInfo);
+    infos("defaultUserEmailForBugsplatStartupManager -> '" + OSInfo + "'");
+    return [NSString stringWithCString:OSInfo.c_str()
                               encoding:NSUTF8StringEncoding];
 }
 
 - (void)bugsplatStartupManagerWillSendCrashReport:(BugsplatStartupManager *)bugsplatStartupManager
 {
-    infos("Reached bugsplatStartupManagerWillSendCrashReport");
+    infos("bugsplatStartupManagerWillSendCrashReport");
 }
 
 - (BugsplatAttachment *)attachmentForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager {
@@ -252,7 +259,7 @@
         [[BugsplatAttachment alloc] initWithFilename:@"SecondLife.log"
                                       attachmentData:data
                                          contentType:@"text/plain"];
-    infos("attachmentForBugsplatStartupManager: attaching " + logfile);
+    infos("attachmentForBugsplatStartupManager attaching " + logfile);
     return attachment;
 }
 
-- 
cgit v1.2.3


From 8d4e6b6df0d21e18a24c8e1d9f6008c2092a24c5 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 22 Aug 2018 16:16:26 -0400
Subject: DRTVWR-447: Additional logging getting metadata for previous run

---
 indra/newview/llappviewer.cpp       |  7 ++-----
 indra/newview/llappviewermacosx.cpp | 33 +++++++++++++++++++++++++--------
 2 files changed, 27 insertions(+), 13 deletions(-)

diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 3e25b395c4..d324a82bf8 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -3051,14 +3051,11 @@ void LLAppViewer::writeDebugInfo(bool isStatic)
         ? getStaticDebugFile()
         : getDynamicDebugFile() );
 
-	LL_INFOS() << "Opening debug file " << *debug_filename << LL_ENDL;
-	llofstream out_file(debug_filename->c_str());
+    LL_INFOS() << "Writing debug file " << *debug_filename << LL_ENDL;
+    llofstream out_file(debug_filename->c_str());
 
     isStatic ?  LLSDSerialize::toPrettyXML(gDebugInfo, out_file)
              :  LLSDSerialize::toPrettyXML(gDebugInfo["Dynamic"], out_file);
-
-
-	out_file.close();
 }
 
 LLSD LLAppViewer::getViewerInfo() const
diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp
index 7f7284a796..77a16f7307 100644
--- a/indra/newview/llappviewermacosx.cpp
+++ b/indra/newview/llappviewermacosx.cpp
@@ -165,6 +165,14 @@ void cleanupViewer()
 class CrashMetadataSingleton: public CrashMetadata, public LLSingleton<CrashMetadataSingleton>
 {
     LLSINGLETON(CrashMetadataSingleton);
+
+    // convenience method to log each metadata field retrieved by constructor
+    std::string get_metadata(const LLSD& info, const LLSD::String& key) const
+    {
+        std::string data(info[key].asString());
+        LL_INFOS() << "  " << key << "='" << data << "'" << LL_ENDL;
+        return data;
+    }
 };
 
 // Populate the fields of our public base-class struct.
@@ -176,17 +184,26 @@ CrashMetadataSingleton::CrashMetadataSingleton()
     staticDebugPathname = *gViewerAppPtr->getStaticDebugFile();
     std::ifstream static_file(staticDebugPathname);
     LLSD info;
-    if (static_file.is_open() &&
-        LLSDSerialize::deserialize(info, static_file, LLSDSerialize::SIZE_UNLIMITED))
+    if (! static_file.is_open())
+    {
+        LL_INFOS() << "Can't open '" << staticDebugPathname
+                   << "'; no metadata about previous run" << LL_ENDL;
+    }
+    else if (! LLSDSerialize::deserialize(info, static_file, LLSDSerialize::SIZE_UNLIMITED))
+    {
+        LL_INFOS() << "Can't parse '" << staticDebugPathname
+                   << "'; no metadata about previous run" << LL_ENDL;
+    }
     {
-        logFilePathname      = info["SLLog"].asString();
-        userSettingsPathname = info["SettingsFilename"].asString();
-        OSInfo               = info["OSInfo"].asString();
-        agentFullname        = info["LoginName"].asString();
+        LL_INFOS() << "Metadata from '" << staticDebugPathname << "':" << LL_ENDL;
+        logFilePathname      = get_metadata(info, "SLLog");
+        userSettingsPathname = get_metadata(info, "SettingsFilename");
+        OSInfo               = get_metadata(info, "OSInfo");
+        agentFullname        = get_metadata(info, "LoginName");
         // Translate underscores back to spaces
         LLStringUtil::replaceChar(agentFullname, '_', ' ');
-        regionName           = info["CurrentRegion"].asString();
-        fatalMessage         = info["FatalMessage"].asString();
+        regionName           = get_metadata(info, "CurrentRegion");
+        fatalMessage         = get_metadata(info, "FatalMessage");
     }
 }
 
-- 
cgit v1.2.3


From afbf243f1a049bdeec6410bcc57350b00d0da169 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 23 Aug 2018 10:27:31 -0400
Subject: DRTVWR-447: Update to bugsplat build 518982

---
 autobuild.xml | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index e88fd04940..ba8d874420 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -244,9 +244,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>f01caa9aeb4c19f679e60609e6095335</string>
+              <string>40a9258f96f2f800489aeb7dee366654</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23285/178722/bugsplat-1.0.5.518876-darwin64-518876.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23472/180173/bugsplat-1.0.6.518982-darwin64-518982.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -256,9 +256,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>17f0e6d2fce03ae48ac02ccaebe48f61</string>
+              <string>735dc6d92fa973e08d280efaa381c452</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23286/178729/bugsplat-3.6.0.4.518876-windows-518876.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23474/180182/bugsplat-3.6.0.4.518982-windows-518982.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -268,16 +268,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>e963a42106ed0fc8b87974cfce040714</string>
+              <string>028c13cc0437c0881ad38b4ac685f794</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23284/178715/bugsplat-3.6.0.4.518876-windows64-518876.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23473/180187/bugsplat-3.6.0.4.518982-windows64-518982.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.0.5.518876</string>
+        <string>1.0.6.518982</string>
       </map>
       <key>chardet</key>
       <map>
-- 
cgit v1.2.3


From e674f11757ab55c5ca7aab4cb1c8e059fa98f466 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 23 Aug 2018 12:31:54 -0400
Subject: DRTVWR-447: Add (some) metadata to Mac crash reports.

This required reordering certain operations during Mac viewer startup. Split
llappviewermacosx.cpp's initViewer() function into constructViewer() (which
instantiates LLAppViewerMacOSX) and initViewer() (which calls
LLAppViewerMacOSX::init()).

llappdelegate-objc.mm's applicationDidFinishLaunching override now calls
[BugsplatStartupManager start] between constructViewer() and initViewer(): we
want constructViewer() to have set up the logging subsystem so we can log the
actions of BugsplatStartupManagerDelegate override methods, but otherwise we
want BugsplatStartupManager in place as early as possible to catch any early
crashes. Besides, initViewer() ends up overwriting the static_debug_info.log
on which we depend for the *previous* run's crash metadata.

Move the code that initializes the pathname of the static_debug_info.log file
from LLAppViewerMacOSX::init() to the LLAppViewerMacOSX() constructor, since
BugsplatStartupManagerDelegate override methods need to read (the previous
run's) file.

Add code to applicationLogForBugsplatStartupManager override to set new
BugsplatMac 1.0.6 properties userName and userEmail.

Don't log empty fields from static_debug_info.log if we couldn't read it.
---
 indra/newview/llappdelegate-objc.mm        | 55 +++++++++++++++++++++++-------
 indra/newview/llappviewer.cpp              | 29 +++++++++-------
 indra/newview/llappviewermacosx-for-objc.h |  1 +
 indra/newview/llappviewermacosx.cpp        | 17 +++++----
 4 files changed, 69 insertions(+), 33 deletions(-)

diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm
index 66bcf58961..f55304f30b 100644
--- a/indra/newview/llappdelegate-objc.mm
+++ b/indra/newview/llappdelegate-objc.mm
@@ -54,6 +54,25 @@
 
 - (void) applicationDidFinishLaunching:(NSNotification *)notification
 {
+	// Call constructViewer() first so our logging subsystem is in place. This
+	// risks missing crashes in the LLAppViewerMacOSX constructor, but for
+	// present purposes it's more important to get the startup sequence
+	// properly logged.
+	// Someday I would like to modify the logging system so that calls before
+	// it's initialized are cached in a std::ostringstream and then, once it's
+	// initialized, "played back" into whatever handlers have been set up.
+	constructViewer();
+
+#if defined(LL_BUGSPLAT)
+	// Engage BugsplatStartupManager *before* calling initViewer() to handle
+	// any crashes during initialization.
+	// https://www.bugsplat.com/docs/platforms/os-x#initialization
+	[BugsplatStartupManager sharedManager].autoSubmitCrashReport = YES;
+	[BugsplatStartupManager sharedManager].askUserDetails = NO;
+	[BugsplatStartupManager sharedManager].delegate = self;
+	[[BugsplatStartupManager sharedManager] start];
+#endif
+
 	frameTimer = nil;
 
 	[self languageUpdated];
@@ -71,14 +90,6 @@
 	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(languageUpdated) name:@"NSTextInputContextKeyboardSelectionDidChangeNotification" object:nil];
 
  //   [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self andSelector:@selector(handleGetURLEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL];
-
-#if defined(LL_BUGSPLAT)
-	// https://www.bugsplat.com/docs/platforms/os-x#initialization
-	[BugsplatStartupManager sharedManager].autoSubmitCrashReport = YES;
-	[BugsplatStartupManager sharedManager].askUserDetails = NO;
-	[BugsplatStartupManager sharedManager].delegate = self;
-	[[BugsplatStartupManager sharedManager] start];
-#endif
 }
 
 - (void) handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent {
@@ -198,11 +209,29 @@
 
 - (NSString *)applicationLogForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager
 {
-    std::string fatalMessage(CrashMetadata_instance().fatalMessage);
-    infos("applicationLogForBugsplatStartupManager -> '" + fatalMessage + "'");
-    // This strangely-named override method contributes the User Description
-    // metadata field.
-    return [NSString stringWithCString:fatalMessage.c_str()
+    CrashMetadata& meta(CrashMetadata_instance());
+    // As of BugsplatMac 1.0.6, userName and userEmail properties are now
+    // exposed by the BugsplatStartupManager. Set them here, since the
+    // defaultUserNameForBugsplatStartupManager and
+    // defaultUserEmailForBugsplatStartupManager methods are called later, for
+    // the *current* run, rather than for the previous crashed run whose crash
+    // report we are about to send.
+    infos("applicationLogForBugsplatStartupManager setting userName = '" +
+          meta.agentFullname + '"');
+    bugsplatStartupManager.userName =
+        [NSString stringWithCString:meta.agentFullname.c_str()
+                           encoding:NSUTF8StringEncoding];
+    // Use the email field for OS version, just as we do on Windows, until
+    // BugSplat provides more metadata fields.
+    infos("applicationLogForBugsplatStartupManager setting userEmail = '" +
+          meta.OSInfo + '"');
+    bugsplatStartupManager.userEmail =
+        [NSString stringWithCString:meta.OSInfo.c_str()
+                           encoding:NSUTF8StringEncoding];
+    // This strangely-named override method's return value contributes the
+    // User Description metadata field.
+    infos("applicationLogForBugsplatStartupManager -> '" + meta.fatalMessage + "'");
+    return [NSString stringWithCString:meta.fatalMessage.c_str()
                               encoding:NSUTF8StringEncoding];
 }
 
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index d324a82bf8..846b937a4e 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -707,6 +707,22 @@ LLAppViewer::LLAppViewer()
 	//
 
 	LLLoginInstance::instance().setPlatformInfo(gPlatform, LLOSInfo::instance().getOSVersionString(), LLOSInfo::instance().getOSStringSimple());
+
+	// Under some circumstances we want to read the static_debug_info.log file
+	// from the previous viewer run between this constructor call and the
+	// init() call, which will overwrite the static_debug_info.log file for
+	// THIS run. So setDebugFileNames() early.
+#if LL_BUGSPLAT
+	// MAINT-8917: don't create a dump directory just for the
+	// static_debug_info.log file
+	std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "");
+#else // ! LL_BUGSPLAT
+	// write Google Breakpad minidump files to a per-run dump directory to avoid multiple viewer issues.
+	std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "");
+#endif // ! LL_BUGSPLAT
+	mDumpPath = logdir;
+	setMiniDumpDir(logdir);
+	setDebugFileNames(logdir);
 }
 
 LLAppViewer::~LLAppViewer()
@@ -781,19 +797,6 @@ bool LLAppViewer::init()
 	initMaxHeapSize() ;
 	LLCoros::instance().setStackSize(gSavedSettings.getS32("CoroutineStackSize"));
 
-#if LL_BUGSPLAT
-	// MAINT-8917: don't create a dump directory just for the
-	// static_debug_info.log file
-	std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "");
-#else // ! LL_BUGSPLAT
-	// write Google Breakpad minidump files to a per-run dump directory to avoid multiple viewer issues.
-	std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "");
-#endif // ! LL_BUGSPLAT
-	mDumpPath = logdir;
-	setMiniDumpDir(logdir);
-	logdir += gDirUtilp->getDirDelimiter();
-	setDebugFileNames(logdir);
-
 
 	// Although initLoggingAndGetLastDuration() is the right place to mess with
 	// setFatalFunction(), we can't query gSavedSettings until after
diff --git a/indra/newview/llappviewermacosx-for-objc.h b/indra/newview/llappviewermacosx-for-objc.h
index 79da453cbe..37e8a3917a 100644
--- a/indra/newview/llappviewermacosx-for-objc.h
+++ b/indra/newview/llappviewermacosx-for-objc.h
@@ -24,6 +24,7 @@
 
 #include <string>
 
+void constructViewer();
 bool initViewer();
 void handleUrl(const char* url_utf8);
 bool pumpMainLoop();
diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp
index 77a16f7307..81f04744f8 100644
--- a/indra/newview/llappviewermacosx.cpp
+++ b/indra/newview/llappviewermacosx.cpp
@@ -86,7 +86,7 @@ static void exceptionTerminateHandler()
 	gOldTerminateHandler(); // call old terminate() handler
 }
 
-bool initViewer()
+void constructViewer()
 {
 	// Set the working dir to <bundle>/Contents/Resources
 	if (chdir(gDirUtilp->getAppRODataDir().c_str()) == -1)
@@ -102,18 +102,20 @@ bool initViewer()
 	gOldTerminateHandler = std::set_terminate(exceptionTerminateHandler);
 
 	gViewerAppPtr->setErrorHandler(LLAppViewer::handleViewerCrash);
+}
 
-	
+bool initViewer()
+{
 	bool ok = gViewerAppPtr->init();
 	if(!ok)
 	{
 		LL_WARNS() << "Application init failed." << LL_ENDL;
 	}
-    else if (!gHandleSLURL.empty())
-    {
-        dispatchUrl(gHandleSLURL);
-        gHandleSLURL = "";
-    }
+	else if (!gHandleSLURL.empty())
+	{
+		dispatchUrl(gHandleSLURL);
+		gHandleSLURL = "";
+	}
 	return ok;
 }
 
@@ -194,6 +196,7 @@ CrashMetadataSingleton::CrashMetadataSingleton()
         LL_INFOS() << "Can't parse '" << staticDebugPathname
                    << "'; no metadata about previous run" << LL_ENDL;
     }
+    else
     {
         LL_INFOS() << "Metadata from '" << staticDebugPathname << "':" << LL_ENDL;
         logFilePathname      = get_metadata(info, "SLLog");
-- 
cgit v1.2.3


From c2178bb6ac139d47eb2bfdf9e85811a6f02810ed Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 24 Aug 2018 09:56:56 -0400
Subject: DRTVWR-447: Introduce explicit CMake BUGSPLAT_DB variable.

Define the CMake cache variable, with empty string as its default.

Make build.sh pass the BUGSPLAT_DB environment variable as a CMake
command-line variable assignment.

Change CMake 'if (DEFINED ENV{BUGSPLAT_DB})' to plain 'if (BUGSPLAT_DB)'.

Make CMake pass new --bugsplat switch to every one of SIX different
invocations of viewer_manifest.py.

Give llmanifest.main() function an argument to allow supplementing the base
set of command-line switches with additional application-specific switches.

In viewer_manifest.py, define new --bugsplat command-line switch and pass to
llmanifest.main(). Instead of consulting os.environ['BUGSPLAT_DB'], consult
self.args['bugsplat'].
---
 build.sh                                  |  1 +
 indra/cmake/Copy3rdPartyLibs.cmake        |  4 +--
 indra/cmake/Variables.cmake               |  1 +
 indra/cmake/bugsplat.cmake                |  9 +++--
 indra/lib/python/indra/util/llmanifest.py | 56 +++++++++++++++++--------------
 indra/llcommon/CMakeLists.txt             |  4 +--
 indra/newview/CMakeLists.txt              | 52 +++++++++++++++-------------
 indra/newview/viewer_manifest.py          | 45 +++++++++++++------------
 8 files changed, 94 insertions(+), 78 deletions(-)

diff --git a/build.sh b/build.sh
index d531c0b046..c38bb6fff4 100755
--- a/build.sh
+++ b/build.sh
@@ -122,6 +122,7 @@ pre_build()
      -DPACKAGE:BOOL=ON \
      -DHAVOK:BOOL="$HAVOK" \
      -DRELEASE_CRASH_REPORTING:BOOL="$RELEASE_CRASH_REPORTING" \
+     -DBUGSPLAT_DB:STRING="${BUGSPLAT_DB:-}" \
      -DVIEWER_CHANNEL:STRING="${viewer_channel}" \
      -DGRID:STRING="\"$viewer_grid\"" \
      -DTEMPLATE_VERIFIER_OPTIONS:STRING="$template_verifier_options" $template_verifier_master_url \
diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake
index c9519b0e1d..dde53835fb 100644
--- a/indra/cmake/Copy3rdPartyLibs.cmake
+++ b/indra/cmake/Copy3rdPartyLibs.cmake
@@ -51,7 +51,7 @@ if(WINDOWS)
 
     # Filenames are different for 32/64 bit BugSplat file and we don't
     # have any control over them so need to branch.
-    if (DEFINED ENV{BUGSPLAT_DB})
+    if (BUGSPLAT_DB)
       if(ADDRESS_SIZE EQUAL 32)
         set(release_files ${release_files} BugSplat.dll)
         set(release_files ${release_files} BugSplatRc.dll)
@@ -61,7 +61,7 @@ if(WINDOWS)
         set(release_files ${release_files} BugSplatRc64.dll)
         set(release_files ${release_files} BsSndRpt64.exe)
       endif(ADDRESS_SIZE EQUAL 32)
-    endif (DEFINED ENV{BUGSPLAT_DB})
+    endif (BUGSPLAT_DB)
 
     if (FMODEX)
 
diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake
index b913d6398e..e49de0a79b 100644
--- a/indra/cmake/Variables.cmake
+++ b/indra/cmake/Variables.cmake
@@ -33,6 +33,7 @@ set(INTEGRATION_TESTS_PREFIX)
 set(LL_TESTS ON CACHE BOOL "Build and run unit and integration tests (disable for build timing runs to reduce variation")
 set(INCREMENTAL_LINK OFF CACHE BOOL "Use incremental linking on win32 builds (enable for faster links on some machines)")
 set(ENABLE_MEDIA_PLUGINS ON CACHE BOOL "Turn off building media plugins if they are imported by third-party library mechanism")
+set(BUGSPLAT_DB "" CACHE STRING "BugSplat database name, if BugSplat crash reporting is desired")
 
 if(LIBS_CLOSED_DIR)
   file(TO_CMAKE_PATH "${LIBS_CLOSED_DIR}" LIBS_CLOSED_DIR)
diff --git a/indra/cmake/bugsplat.cmake b/indra/cmake/bugsplat.cmake
index eb5808b1fb..59644b73ce 100644
--- a/indra/cmake/bugsplat.cmake
+++ b/indra/cmake/bugsplat.cmake
@@ -1,7 +1,6 @@
-# BugSplat is engaged by setting environment variable BUGSPLAT_DB to the
-# target BugSplat database name prior to running CMake (and during autobuild
-# build).
-if (DEFINED ENV{BUGSPLAT_DB})
+# BugSplat is engaged by setting BUGSPLAT_DB to the target BugSplat database
+# name.
+if (BUGSPLAT_DB)
   if (USESYSTEMLIBS)
     message(STATUS "Looking for system BugSplat")
     set(BUGSPLAT_FIND_QUIETLY ON)
@@ -23,4 +22,4 @@ if (DEFINED ENV{BUGSPLAT_DB})
     endif (WINDOWS)
     set(BUGSPLAT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/bugsplat)
   endif (USESYSTEMLIBS)
-endif (DEFINED ENV{BUGSPLAT_DB})
+endif (BUGSPLAT_DB)
diff --git a/indra/lib/python/indra/util/llmanifest.py b/indra/lib/python/indra/util/llmanifest.py
index 611f72269e..c4dcad51b7 100755
--- a/indra/lib/python/indra/util/llmanifest.py
+++ b/indra/lib/python/indra/util/llmanifest.py
@@ -33,13 +33,14 @@ import filecmp
 import fnmatch
 import getopt
 import glob
+import itertools
+import operator
 import os
 import re
 import shutil
+import subprocess
 import sys
 import tarfile
-import errno
-import subprocess
 
 class ManifestError(RuntimeError):
     """Use an exception more specific than generic Python RuntimeError"""
@@ -90,7 +91,7 @@ DEFAULT_SRCTREE = os.path.dirname(sys.argv[0])
 CHANNEL_VENDOR_BASE = 'Second Life'
 RELEASE_CHANNEL = CHANNEL_VENDOR_BASE + ' Release'
 
-ARGUMENTS=[
+BASE_ARGUMENTS=[
     dict(name='actions',
          description="""This argument specifies the actions that are to be taken when the
         script is run.  The meaningful actions are currently:
@@ -108,8 +109,19 @@ ARGUMENTS=[
         Example use: %(name)s --arch=i686
         On Linux this would try to use Linux_i686Manifest.""",
          default=""),
+    dict(name='artwork', description='Artwork directory.', default=DEFAULT_SRCTREE),
     dict(name='build', description='Build directory.', default=DEFAULT_SRCTREE),
     dict(name='buildtype', description='Build type (i.e. Debug, Release, RelWithDebInfo).', default=None),
+    dict(name='bundleid',
+         description="""The Mac OS X Bundle identifier.""",
+         default="com.secondlife.indra.viewer"),
+    dict(name='channel',
+         description="""The channel to use for updates, packaging, settings name, etc.""",
+         default='CHANNEL UNSET'),
+    dict(name='channel_suffix',
+         description="""Addition to the channel for packaging and channel value,
+         but not application name (used internally)""",
+         default=None),
     dict(name='configuration',
          description="""The build configuration used.""",
          default="Release"),
@@ -117,12 +129,6 @@ ARGUMENTS=[
     dict(name='grid',
          description="""Which grid the client will try to connect to.""",
          default=None),
-    dict(name='channel',
-         description="""The channel to use for updates, packaging, settings name, etc.""",
-         default='CHANNEL UNSET'),
-    dict(name='channel_suffix',
-         description="""Addition to the channel for packaging and channel value, but not application name (used internally)""",
-         default=None),
     dict(name='installer_name',
          description=""" The name of the file that the installer should be
         packaged up into. Only used on Linux at the moment.""",
@@ -134,10 +140,14 @@ ARGUMENTS=[
          description="""The current platform, to be used for looking up which
         manifest class to run.""",
          default=get_default_platform),
+    dict(name='signature',
+         description="""This specifies an identity to sign the viewer with, if any.
+        If no value is supplied, the default signature will be used, if any. Currently
+        only used on Mac OS X.""",
+         default=None),
     dict(name='source',
          description='Source directory.',
          default=DEFAULT_SRCTREE),
-    dict(name='artwork', description='Artwork directory.', default=DEFAULT_SRCTREE),
     dict(name='touch',
          description="""File to touch when action is finished. Touch file will
         contain the name of the final package in a form suitable
@@ -145,23 +155,15 @@ ARGUMENTS=[
          default=None),
     dict(name='versionfile',
          description="""The name of a file containing the full version number."""),
-    dict(name='bundleid',
-         description="""The Mac OS X Bundle identifier.""",
-         default="com.secondlife.indra.viewer"),
-    dict(name='signature',
-         description="""This specifies an identity to sign the viewer with, if any.
-        If no value is supplied, the default signature will be used, if any. Currently
-        only used on Mac OS X.""",
-         default=None)
     ]
 
-def usage(srctree=""):
+def usage(arguments, srctree=""):
     nd = {'name':sys.argv[0]}
     print """Usage:
     %(name)s [options] [destdir]
     Options:
     """ % nd
-    for arg in ARGUMENTS:
+    for arg in arguments:
         default = arg['default']
         if hasattr(default, '__call__'):
             default = "(computed value) \"" + str(default(srctree)) + '"'
@@ -172,11 +174,15 @@ def usage(srctree=""):
             default,
             arg['description'] % nd)
 
-def main():
-##  import itertools
+def main(extra=[]):
 ##  print ' '.join((("'%s'" % item) if ' ' in item else item)
 ##                 for item in itertools.chain([sys.executable], sys.argv))
-    option_names = [arg['name'] + '=' for arg in ARGUMENTS]
+    # Supplement our default command-line switches with any desired by
+    # application-specific caller.
+    arguments = list(itertools.chain(BASE_ARGUMENTS, extra))
+    # Alphabetize them by option name in case we display usage.
+    arguments.sort(key=operator.itemgetter('name'))
+    option_names = [arg['name'] + '=' for arg in arguments]
     option_names.append('help')
     options, remainder = getopt.getopt(sys.argv[1:], "", option_names)
 
@@ -199,11 +205,11 @@ def main():
     # early out for help
     if 'help' in args:
         # *TODO: it is a huge hack to pass around the srctree like this
-        usage(args['source'])
+        usage(arguments, srctree=args['source'])
         return
 
     # defaults
-    for arg in ARGUMENTS:
+    for arg in arguments:
         if arg['name'] not in args:
             default = arg['default']
             if hasattr(default, '__call__'):
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 8977acb873..42ad56f1b0 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -255,10 +255,10 @@ set(llcommon_HEADER_FILES
 set_source_files_properties(${llcommon_HEADER_FILES}
                             PROPERTIES HEADER_FILE_ONLY TRUE)
 
-if (DEFINED ENV{BUGSPLAT_DB})
+if (BUGSPLAT_DB)
   set_source_files_properties(llapp.cpp
     PROPERTIES COMPILE_DEFINITIONS "LL_BUGSPLAT")
-endif (DEFINED ENV{BUGSPLAT_DB})
+endif (BUGSPLAT_DB)
 
 list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES})
 
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 31c4c02d99..64a8e15c4b 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -8,9 +8,9 @@ include(00-Common)
 include(Linking)
 
 include(Boost)
-if (DEFINED ENV{BUGSPLAT_DB})
+if (BUGSPLAT_DB)
   include(bugsplat)
-endif (DEFINED ENV{BUGSPLAT_DB})
+endif (BUGSPLAT_DB)
 include(BuildPackagesInfo)
 include(BuildVersion)
 include(CMakeCopyIfDifferent)
@@ -99,11 +99,11 @@ include_directories(
     ${CMAKE_CURRENT_SOURCE_DIR}
     )
 
-if (DEFINED ENV{BUGSPLAT_DB})
+if (BUGSPLAT_DB)
   include_directories(
     ${BUGSPLAT_INCLUDE_DIR}
     )
-endif (DEFINED ENV{BUGSPLAT_DB})
+endif (BUGSPLAT_DB)
 
 include_directories(SYSTEM
     ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
@@ -1390,11 +1390,11 @@ if (DARWIN)
     ${COREAUDIO_LIBRARY}
     )
 
-  if (DEFINED ENV{BUGSPLAT_DB})
+  if (BUGSPLAT_DB)
     list(APPEND viewer_LIBRARIES
       ${BUGSPLAT_LIBRARIES}
       )
-  endif (DEFINED ENV{BUGSPLAT_DB})
+  endif (BUGSPLAT_DB)
 
   # Add resource files to the project.
   set(viewer_RESOURCE_FILES
@@ -1729,10 +1729,10 @@ if (SDL_FOUND)
     )
 endif (SDL_FOUND)
 
-if (DEFINED ENV{BUGSPLAT_DB})
+if (BUGSPLAT_DB)
   set_property(TARGET ${VIEWER_BINARY_NAME}
     PROPERTY COMPILE_DEFINITIONS "LL_BUGSPLAT")
-endif (DEFINED ENV{BUGSPLAT_DB})
+endif (BUGSPLAT_DB)
 
 # add package files
 file(GLOB EVENT_HOST_SCRIPT_GLOB_LIST
@@ -1841,15 +1841,16 @@ if (WINDOWS)
         --actions=copy
         --arch=${ARCH}
         --artwork=${ARTWORK_DIR}
+        "--bugsplat=${BUGSPLAT_DB}"
         --build=${CMAKE_CURRENT_BINARY_DIR}
         --buildtype=${CMAKE_BUILD_TYPE}
+        "--channel=${VIEWER_CHANNEL}"
         --configuration=${CMAKE_CFG_INTDIR}
         --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
         --grid=${GRID}
-        "--channel=${VIEWER_CHANNEL}"
-        --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
         --source=${CMAKE_CURRENT_SOURCE_DIR}
         --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/copy_touched.bat
+        --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
       DEPENDS
         ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
         stage_third_party_libs
@@ -1892,15 +1893,16 @@ if (WINDOWS)
           ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
           --arch=${ARCH}
           --artwork=${ARTWORK_DIR}
+          "--bugsplat=${BUGSPLAT_DB}"
           --build=${CMAKE_CURRENT_BINARY_DIR}
           --buildtype=${CMAKE_BUILD_TYPE}
           "--channel=${VIEWER_CHANNEL}"
-          --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
           --configuration=${CMAKE_CFG_INTDIR}
           --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
           --grid=${GRID}
           --source=${CMAKE_CURRENT_SOURCE_DIR}
           --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/touched.bat
+          --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
         DEPENDS
             ${VIEWER_BINARY_NAME}
             ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
@@ -2007,11 +2009,11 @@ target_link_libraries(${VIEWER_BINARY_NAME}
     ${LLAPPEARANCE_LIBRARIES}
     )
 
-if (DEFINED ENV{BUGSPLAT_DB})
+if (BUGSPLAT_DB)
   target_link_libraries(${VIEWER_BINARY_NAME}
     ${BUGSPLAT_LIBRARIES}
     )
-endif (DEFINED ENV{BUGSPLAT_DB})
+endif (BUGSPLAT_DB)
 
 set(ARTWORK_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE PATH
     "Path to artwork files.")
@@ -2036,15 +2038,16 @@ if (LINUX)
         ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
         --arch=${ARCH}
         --artwork=${ARTWORK_DIR}
+        "--bugsplat=${BUGSPLAT_DB}"
         --build=${CMAKE_CURRENT_BINARY_DIR}
         --buildtype=${CMAKE_BUILD_TYPE}
         "--channel=${VIEWER_CHANNEL}"
-        --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
         --configuration=${CMAKE_CFG_INTDIR}
         --dest=${CMAKE_CURRENT_BINARY_DIR}/packaged
         --grid=${GRID}
         --source=${CMAKE_CURRENT_SOURCE_DIR}
         --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.touched
+        --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
       DEPENDS
         ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
         ${COPY_INPUT_DEPENDENCIES}
@@ -2058,17 +2061,18 @@ if (LINUX)
     COMMAND ${PYTHON_EXECUTABLE}
     ARGS
       ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
-      --arch=${ARCH}
       --actions=copy
+      --arch=${ARCH}
       --artwork=${ARTWORK_DIR}
+      "--bugsplat=${BUGSPLAT_DB}"
       --build=${CMAKE_CURRENT_BINARY_DIR}
       --buildtype=${CMAKE_BUILD_TYPE}
+      "--channel=${VIEWER_CHANNEL}"
       --configuration=${CMAKE_CFG_INTDIR}
       --dest=${CMAKE_CURRENT_BINARY_DIR}/packaged
       --grid=${GRID}
-      "--channel=${VIEWER_CHANNEL}"
-      --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
       --source=${CMAKE_CURRENT_SOURCE_DIR}
+      --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
     DEPENDS
       ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
       ${COPY_INPUT_DEPENDENCIES}
@@ -2137,15 +2141,16 @@ if (DARWIN)
       --actions=copy
       --arch=${ARCH}
       --artwork=${ARTWORK_DIR}
+      "--bugsplat=${BUGSPLAT_DB}"
       --build=${CMAKE_CURRENT_BINARY_DIR}
       --buildtype=${CMAKE_BUILD_TYPE}
+      --bundleid=${MACOSX_BUNDLE_GUI_IDENTIFIER}
+      "--channel=${VIEWER_CHANNEL}"
       --configuration=${CMAKE_CFG_INTDIR}
       --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app
       --grid=${GRID}
-      "--channel=${VIEWER_CHANNEL}"
-      --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
-      --bundleid=${MACOSX_BUNDLE_GUI_IDENTIFIER}
       --source=${CMAKE_CURRENT_SOURCE_DIR}
+      --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
     DEPENDS
       ${VIEWER_BINARY_NAME}
       ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
@@ -2170,15 +2175,16 @@ if (DARWIN)
           ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
           --arch=${ARCH}
           --artwork=${ARTWORK_DIR}
+          "--bugsplat=${BUGSPLAT_DB}"
           --build=${CMAKE_CURRENT_BINARY_DIR}
           --buildtype=${CMAKE_BUILD_TYPE}
+          "--channel=${VIEWER_CHANNEL}"
           --configuration=${CMAKE_CFG_INTDIR}
           --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app
           --grid=${GRID}
-          "--channel=${VIEWER_CHANNEL}"
-          --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
           --source=${CMAKE_CURRENT_SOURCE_DIR}
           --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.touched
+          --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
           ${SIGNING_SETTING}
         DEPENDS
           ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
@@ -2190,7 +2196,7 @@ if (INSTALL)
   include(${CMAKE_CURRENT_SOURCE_DIR}/ViewerInstall.cmake)
 endif (INSTALL)
 
-if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND NOT DEFINED ENV{BUGSPLAT_DB})
+if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND NOT BUGSPLAT_DB)
   set(SYMBOL_SEARCH_DIRS "")
   # Note that the path to VIEWER_SYMBOL_FILE must match that in ../../build.sh
   if (WINDOWS)
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index ea0b3625be..e5f0575e86 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -188,11 +188,10 @@ class ViewerManifest(LLManifest):
                             "Address Size":self.address_size,
                             "Update Service":"https://update.secondlife.com/update",
                             }
-            try:
-                build_data_dict["BugSplat DB"] = os.environ["BUGSPLAT_DB"]
-            except KeyError:
-                # skip the assignment if there's no BUGSPLAT_DB variable
-                pass
+            # Only store this if it's both present and non-empty
+            bugsplat_db = self.args.get('bugsplat')
+            if bugsplat_db:
+                build_data_dict["BugSplat DB"] = bugsplat_db
             build_data_dict = self.finish_build_data_dict(build_data_dict)
             with open(os.path.join(os.pardir,'build_data.json'), 'w') as build_data_handle:
                 json.dump(build_data_dict,build_data_handle)
@@ -589,14 +588,15 @@ class WindowsManifest(ViewerManifest):
             self.path("libhunspell.dll")
 
             # BugSplat
-            if(self.address_size == 64):
-                self.path("BsSndRpt64.exe")
-                self.path("BugSplat64.dll")
-                self.path("BugSplatRc64.dll")
-            else:
-                self.path("BsSndRpt.exe")
-                self.path("BugSplat.dll")
-                self.path("BugSplatRc.dll")
+            if self.args.get('bugsplat'):
+                if(self.address_size == 64):
+                    self.path("BsSndRpt64.exe")
+                    self.path("BugSplat64.dll")
+                    self.path("BugSplatRc64.dll")
+                else:
+                    self.path("BsSndRpt.exe")
+                    self.path("BugSplat.dll")
+                    self.path("BugSplatRc.dll")
 
             # For google-perftools tcmalloc allocator.
             try:
@@ -1038,7 +1038,7 @@ open "%s" --args "$@"
                         if ("package" in self.args['actions'] or 
                             "unpacked" in self.args['actions']):
                             # only if we're engaging BugSplat
-                            if "BUGSPLAT_DB" in os.environ:
+                            if self.args.get('bugsplat'):
                                 # Create a symbol archive BEFORE stripping the
                                 # binary.
                                 self.run_command(['dsymutil', exepath])
@@ -1085,13 +1085,11 @@ open "%s" --args "$@"
                     # runs the executable, instead of launching the app)
                     Info["CFBundleExecutable"] = exename
                     Info["CFBundleIconFile"] = viewer_icon
-                    try:
+                    bugsplat_db = self.args.get('bugsplat')
+                    if bugsplat_db:
                         # https://www.bugsplat.com/docs/platforms/os-x#configuration
                         Info["BugsplatServerURL"] = \
-                            "https://{BUGSPLAT_DB}.bugsplatsoftware.com/".format(**os.environ)
-                    except KeyError:
-                        # skip the assignment if there's no BUGSPLAT_DB variable
-                        pass
+                            "https://{}.bugsplatsoftware.com/".format(bugsplat_db)
                     self.put_in_file(
                         plistlib.writePlistToString(Info),
                         os.path.basename(Info_plist),
@@ -1104,7 +1102,8 @@ open "%s" --args "$@"
                         # Remember where we parked this car.
                         CEF_framework = self.dst_path_of(CEF_framework)
 
-                        self.path2basename(relpkgdir, "BugsplatMac.framework")
+                        if self.args.get('bugsplat'):
+                            self.path2basename(relpkgdir, "BugsplatMac.framework")
 
                     with self.prefix(dst="Resources"):
                         # defer cross-platform file copies until we're in the right
@@ -1727,4 +1726,8 @@ class Linux_x86_64_Manifest(LinuxManifest):
 ################################################################
 
 if __name__ == "__main__":
-    main()
+    extra_arguments = [
+        dict(name='bugsplat', description="""BugSplat database to which to post crashes,
+             if BugSplat crash reporting is desired""", default=''),
+        ]
+    main(extra=extra_arguments)
-- 
cgit v1.2.3


From 3f7c75b8a075a5cd5765b1791a58f5d8e2b164dd Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 27 Aug 2018 13:55:50 -0400
Subject: SL-957: Explicitly pass VIEWER_SYMBOL_FILE from build.sh into CMake
 instead of relying on both indra/newview/CMakeLists.txt and build.sh
 generating the same file pathname.

Make build.sh set VIEWER_SYMBOL_FILE (instead of symbolfile) in pre_build, and
pass it to autobuild configure via -D switch. Then the uploads stanza can just
use VIEWER_SYMBOL_FILE instead of performing its platform-sensitive case
statement right there.

Introduce VIEWER_SYMBOL_FILE CMake cache variable, default empty string.

Make indra/newview/CMakeLists.txt generate_breakpad_symbols logic conditional
on VIEWER_SYMBOL_FILE being non-empty, as well as everything else. Eliminate
local set(VIEWER_SYMBOL_FILE) directives.
---
 build.sh                     | 34 +++++++++++++++++++---------------
 indra/cmake/Variables.cmake  |  1 +
 indra/newview/CMakeLists.txt |  7 ++-----
 3 files changed, 22 insertions(+), 20 deletions(-)

diff --git a/build.sh b/build.sh
index c38bb6fff4..976228cdf1 100755
--- a/build.sh
+++ b/build.sh
@@ -103,6 +103,23 @@ pre_build()
                   "-DSIGNING_IDENTITY:STRING=Developer ID Application: Linden Research, Inc.")
     fi
 
+    if [ "${RELEASE_CRASH_REPORTING:-}" != "OFF" ]
+    then
+        case "$arch" in
+            CYGWIN)
+                symplat="windows"
+                ;;
+            Darwin)
+                symplat="darwin"
+                ;;
+            Linux)
+                symplat="linux"
+                ;;
+        esac
+        # This name is consumed by indra/newview/CMakeLists.txt
+        VIEWER_SYMBOL_FILE="$build_dir/newview/$variant/secondlife-symbols-$symplat-${AUTOBUILD_ADDRSIZE}.tar.bz2"
+    fi
+
     # don't spew credentials into build log
     bugsplat_sh="$build_secrets_checkout/bugsplat/bugsplat.sh"
     set +x
@@ -122,6 +139,7 @@ pre_build()
      -DPACKAGE:BOOL=ON \
      -DHAVOK:BOOL="$HAVOK" \
      -DRELEASE_CRASH_REPORTING:BOOL="$RELEASE_CRASH_REPORTING" \
+     -DVIEWER_SYMBOL_FILE:STRING="${VIEWER_SYMBOL_FILE:-}" \
      -DBUGSPLAT_DB:STRING="${BUGSPLAT_DB:-}" \
      -DVIEWER_CHANNEL:STRING="${viewer_channel}" \
      -DGRID:STRING="\"$viewer_grid\"" \
@@ -245,7 +263,6 @@ initialize_version # provided by buildscripts build.sh; sets version id
 
 # Now run the build
 succeeded=true
-build_processes=
 last_built_variant=
 for variant in $variants
 do
@@ -253,7 +270,6 @@ do
   last_built_variant="$variant"
 
   build_dir=`build_dir_$arch $variant`
-  build_dir_stubs="$build_dir/win_setup/$variant"
 
   begin_section "Initialize $variant Build Directory"
   rm -rf "$build_dir"
@@ -432,19 +448,7 @@ then
                -a -z "${BUGSPLAT_DB:-}" ]
           then
               # Upload crash reporter file
-              # These names must match the set of VIEWER_SYMBOL_FILE in indra/newview/CMakeLists.txt
-              case "$arch" in
-                  CYGWIN)
-                      symbolfile="$build_dir/newview/Release/secondlife-symbols-windows-${AUTOBUILD_ADDRSIZE}.tar.bz2"
-                      ;;
-                  Darwin)
-                      symbolfile="$build_dir/newview/Release/secondlife-symbols-darwin-${AUTOBUILD_ADDRSIZE}.tar.bz2"
-                      ;;
-                  Linux)
-                      symbolfile="$build_dir/newview/Release/secondlife-symbols-linux-${AUTOBUILD_ADDRSIZE}.tar.bz2"
-                      ;;
-              esac
-              python_cmd "$helpers/codeticket.py" addoutput "Symbolfile" "$symbolfile" \
+              python_cmd "$helpers/codeticket.py" addoutput "Symbolfile" "$VIEWER_SYMBOL_FILE" \
                   || fatal "Upload of symbolfile failed"
           fi
 
diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake
index e49de0a79b..2b54cd4155 100644
--- a/indra/cmake/Variables.cmake
+++ b/indra/cmake/Variables.cmake
@@ -33,6 +33,7 @@ set(INTEGRATION_TESTS_PREFIX)
 set(LL_TESTS ON CACHE BOOL "Build and run unit and integration tests (disable for build timing runs to reduce variation")
 set(INCREMENTAL_LINK OFF CACHE BOOL "Use incremental linking on win32 builds (enable for faster links on some machines)")
 set(ENABLE_MEDIA_PLUGINS ON CACHE BOOL "Turn off building media plugins if they are imported by third-party library mechanism")
+set(VIEWER_SYMBOL_FILE "" CACHE STRING "Name of tarball into which to place symbol files")
 set(BUGSPLAT_DB "" CACHE STRING "BugSplat database name, if BugSplat crash reporting is desired")
 
 if(LIBS_CLOSED_DIR)
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 64a8e15c4b..28fa56b54b 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -2196,12 +2196,11 @@ if (INSTALL)
   include(${CMAKE_CURRENT_SOURCE_DIR}/ViewerInstall.cmake)
 endif (INSTALL)
 
-if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND NOT BUGSPLAT_DB)
+# Note that the conventional VIEWER_SYMBOL_FILE is set by ../../build.sh
+if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND NOT BUGSPLAT_DB AND VIEWER_SYMBOL_FILE)
   set(SYMBOL_SEARCH_DIRS "")
-  # Note that the path to VIEWER_SYMBOL_FILE must match that in ../../build.sh
   if (WINDOWS)
     list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
-    set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-windows-$ENV{AUTOBUILD_ADDRSIZE}.tar.bz2")
     # slplugin.exe failing symbols dump - need to debug, might have to do with updated version of google breakpad
     # set(VIEWER_EXE_GLOBS "${VIEWER_BINARY_NAME}${CMAKE_EXECUTABLE_SUFFIX} slplugin.exe")
     set(VIEWER_EXE_GLOBS "${VIEWER_BINARY_NAME}${CMAKE_EXECUTABLE_SUFFIX}")
@@ -2214,14 +2213,12 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND NOT
     list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/llplugin/slplugin/${CMAKE_CFG_INTDIR}")
     list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/mac_crash_logger/${CMAKE_CFG_INTDIR}")
     list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/gstreamer010/${CMAKE_CFG_INTDIR}")
-    set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-darwin-$ENV{AUTOBUILD_ADDRSIZE}.tar.bz2")
     set(VIEWER_EXE_GLOBS "'${product}' SLPlugin mac-crash-logger")
     set(VIEWER_EXE_GLOBS "'${product}' mac-crash-logger")
     set(VIEWER_LIB_GLOB "*.dylib")
   endif (DARWIN)
   if (LINUX)
     list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/packaged")
-    set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-linux-$ENV{AUTOBUILD_ADDRSIZE}.tar.bz2")
     set(VIEWER_EXE_GLOBS "do-not-directly-run-secondlife-bin SLPlugin")
     set(VIEWER_EXE_GLOBS "do-not-directly-run-secondlife-bin")
     set(VIEWER_LIB_GLOB "*${CMAKE_SHARED_MODULE_SUFFIX}*")
-- 
cgit v1.2.3


From b6e22902f350be6cff5b4d941b0fb9d5b9ac890a Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 27 Aug 2018 16:15:31 -0400
Subject: SL-824: Update to bugsplat build 519074

---
 autobuild.xml | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index ba8d874420..905ce411bd 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -244,9 +244,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>40a9258f96f2f800489aeb7dee366654</string>
+              <string>ebb14356ae840d79906f742f6f3f695f</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23472/180173/bugsplat-1.0.6.518982-darwin64-518982.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23627/181379/bugsplat-1.0.6.519074-darwin64-519074.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -256,9 +256,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>735dc6d92fa973e08d280efaa381c452</string>
+              <string>61ece5855ca6bb68e6e24e45b16f34d6</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23474/180182/bugsplat-3.6.0.4.518982-windows-518982.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23630/181394/bugsplat-3.6.0.4.519074-windows-519074.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -268,16 +268,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>028c13cc0437c0881ad38b4ac685f794</string>
+              <string>e9c62bde423c548a8248a91af5897e29</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23473/180187/bugsplat-3.6.0.4.518982-windows64-518982.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23629/181387/bugsplat-3.6.0.4.519074-windows64-519074.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.0.6.518982</string>
+        <string>1.0.6.519074</string>
       </map>
       <key>chardet</key>
       <map>
-- 
cgit v1.2.3


From aaa57c67d617e7761f459f7bdc3dd882ca069b12 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 28 Aug 2018 11:48:52 -0400
Subject: SL-824: Update to bugsplat build 519106

---
 autobuild.xml | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 905ce411bd..806c51205c 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -244,9 +244,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>ebb14356ae840d79906f742f6f3f695f</string>
+              <string>eb7357084addd54e9f19f66ea74720cd</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23627/181379/bugsplat-1.0.6.519074-darwin64-519074.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23677/181687/bugsplat-1.0.6.519106-darwin64-519106.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -256,9 +256,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>61ece5855ca6bb68e6e24e45b16f34d6</string>
+              <string>b9a8dc85dfe365d8f5f621635b6f8e48</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23630/181394/bugsplat-3.6.0.4.519074-windows-519074.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23679/181701/bugsplat-3.6.0.4.519106-windows-519106.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -268,16 +268,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>e9c62bde423c548a8248a91af5897e29</string>
+              <string>f3c0670c4ada369320bdcc4ffcd6a158</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23629/181387/bugsplat-3.6.0.4.519074-windows64-519074.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23678/181694/bugsplat-3.6.0.4.519106-windows64-519106.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.0.6.519074</string>
+        <string>1.0.6.519106</string>
       </map>
       <key>chardet</key>
       <map>
-- 
cgit v1.2.3


From 76f75d8068fabc94f2a9d80054436e945859d8d3 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 28 Aug 2018 16:55:25 -0400
Subject: SL-824: Update to bugsplat build 519145

---
 autobuild.xml | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 806c51205c..b08475baa1 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -244,9 +244,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>eb7357084addd54e9f19f66ea74720cd</string>
+              <string>7a7bd828233e8a2b0e9c022f6219e6e7</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23677/181687/bugsplat-1.0.6.519106-darwin64-519106.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23730/182106/bugsplat-1.0.6.519145-darwin64-519145.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -256,9 +256,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>b9a8dc85dfe365d8f5f621635b6f8e48</string>
+              <string>a3938332a11215e6909d67d1b9be5259</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23679/181701/bugsplat-3.6.0.4.519106-windows-519106.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23732/182120/bugsplat-3.6.0.4.519145-windows-519145.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -268,16 +268,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>f3c0670c4ada369320bdcc4ffcd6a158</string>
+              <string>453d624d87a80779f59cfb1880613d90</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23678/181694/bugsplat-3.6.0.4.519106-windows64-519106.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23731/182115/bugsplat-3.6.0.4.519145-windows64-519145.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.0.6.519106</string>
+        <string>1.0.6.519145</string>
       </map>
       <key>chardet</key>
       <map>
-- 
cgit v1.2.3


From 5ff160f72e8f4eab7a74491a7b848348267a180a Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 30 Aug 2018 12:12:37 -0400
Subject: SL-957: Generate the expected symbols tarball even with BugSplat.

This is a separate step from generating and posting BugSplat symbols, since
BugSplat needs the executable along with the symbols, and we don't need to
consume that space in a symbols tarball.

Move Mac BugSplat symbol generation logic to CMake land, the same general area
where Breakpad symbols are generated. Add stanzas to pack up the usual tarball
for Windows and Mac.

Remove the build.sh test that suppressed uploading the symbols tarball for
BugSplat builds.
---
 build.sh                         |   4 +-
 indra/newview/CMakeLists.txt     | 194 +++++++++++++++++++++++++++------------
 indra/newview/viewer_manifest.py |  35 +------
 3 files changed, 139 insertions(+), 94 deletions(-)

diff --git a/build.sh b/build.sh
index 976228cdf1..d6a6d7aca8 100755
--- a/build.sh
+++ b/build.sh
@@ -443,9 +443,7 @@ then
       if [ "$last_built_variant" = "Release" ]
       then
           # nat 2016-12-22: without RELEASE_CRASH_REPORTING, we have no symbol file.
-          # Likewise, BUGSPLAT_DB suppresses generating the symbol file.
-          if [ "${RELEASE_CRASH_REPORTING:-}" != "OFF" \
-               -a -z "${BUGSPLAT_DB:-}" ]
+          if [ "${RELEASE_CRASH_REPORTING:-}" != "OFF" ]
           then
               # Upload crash reporter file
               python_cmd "$helpers/codeticket.py" addoutput "Symbolfile" "$VIEWER_SYMBOL_FILE" \
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 28fa56b54b..717c835031 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -2128,9 +2128,14 @@ if (DARWIN)
     "${CMAKE_CURRENT_SOURCE_DIR}/Info-SecondLife.plist"
     )
 
+  set(VIEWER_APP_BUNDLE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app")
+  set(VIEWER_APP_EXECUTABLE "${VIEWER_APP_BUNDLE}/Contents/MacOS/${product}")
+  set(VIEWER_APP_DSYM "${VIEWER_APP_EXECUTABLE}.dSYM")
+  set(VIEWER_APP_XCARCHIVE "${VIEWER_APP_BUNDLE}/../${product}.xcarchive.zip")
+
   configure_file(
      "${CMAKE_CURRENT_SOURCE_DIR}/Info-SecondLife.plist"
-     "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app/Contents/Info.plist"
+     "${VIEWER_APP_BUNDLE}/Contents/Info.plist"
     )
 
   add_custom_command(
@@ -2147,7 +2152,7 @@ if (DARWIN)
       --bundleid=${MACOSX_BUNDLE_GUI_IDENTIFIER}
       "--channel=${VIEWER_CHANNEL}"
       --configuration=${CMAKE_CFG_INTDIR}
-      --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app
+      --dest=${VIEWER_APP_BUNDLE}
       --grid=${GRID}
       --source=${CMAKE_CURRENT_SOURCE_DIR}
       --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
@@ -2180,7 +2185,7 @@ if (DARWIN)
           --buildtype=${CMAKE_BUILD_TYPE}
           "--channel=${VIEWER_CHANNEL}"
           --configuration=${CMAKE_CFG_INTDIR}
-          --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app
+          --dest=${VIEWER_APP_BUNDLE}
           --grid=${GRID}
           --source=${CMAKE_CURRENT_SOURCE_DIR}
           --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.touched
@@ -2197,60 +2202,135 @@ if (INSTALL)
 endif (INSTALL)
 
 # Note that the conventional VIEWER_SYMBOL_FILE is set by ../../build.sh
-if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND NOT BUGSPLAT_DB AND VIEWER_SYMBOL_FILE)
-  set(SYMBOL_SEARCH_DIRS "")
-  if (WINDOWS)
-    list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
-    # slplugin.exe failing symbols dump - need to debug, might have to do with updated version of google breakpad
-    # set(VIEWER_EXE_GLOBS "${VIEWER_BINARY_NAME}${CMAKE_EXECUTABLE_SUFFIX} slplugin.exe")
-    set(VIEWER_EXE_GLOBS "${VIEWER_BINARY_NAME}${CMAKE_EXECUTABLE_SUFFIX}")
-    set(VIEWER_LIB_GLOB "*${CMAKE_SHARED_MODULE_SUFFIX}")
-    set(VIEWER_COPY_MANIFEST copy_w_viewer_manifest)
-  endif (WINDOWS)
-  if (DARWIN)
-    list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
-    # *TODO: Generate these search dirs in the cmake files related to each binary.
-    list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/llplugin/slplugin/${CMAKE_CFG_INTDIR}")
-    list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/mac_crash_logger/${CMAKE_CFG_INTDIR}")
-    list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/gstreamer010/${CMAKE_CFG_INTDIR}")
-    set(VIEWER_EXE_GLOBS "'${product}' SLPlugin mac-crash-logger")
-    set(VIEWER_EXE_GLOBS "'${product}' mac-crash-logger")
-    set(VIEWER_LIB_GLOB "*.dylib")
-  endif (DARWIN)
-  if (LINUX)
-    list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/packaged")
-    set(VIEWER_EXE_GLOBS "do-not-directly-run-secondlife-bin SLPlugin")
-    set(VIEWER_EXE_GLOBS "do-not-directly-run-secondlife-bin")
-    set(VIEWER_LIB_GLOB "*${CMAKE_SHARED_MODULE_SUFFIX}*")
-    set(VIEWER_COPY_MANIFEST copy_l_viewer_manifest)
-  endif (LINUX)
-
-  if(CMAKE_CFG_INTDIR STREQUAL ".")
-      set(LLBUILD_CONFIG ${CMAKE_BUILD_TYPE})
-  else(CMAKE_CFG_INTDIR STREQUAL ".")
-      # set LLBUILD_CONFIG to be a shell variable evaluated at build time
-      # reflecting the configuration we are currently building.
-      set(LLBUILD_CONFIG ${CMAKE_CFG_INTDIR})
-  endif(CMAKE_CFG_INTDIR STREQUAL ".")
-  add_custom_command(OUTPUT "${VIEWER_SYMBOL_FILE}"
-    COMMAND "${PYTHON_EXECUTABLE}"
-    ARGS
-      "${CMAKE_CURRENT_SOURCE_DIR}/generate_breakpad_symbols.py"
-      "${LLBUILD_CONFIG}"
-      "${SYMBOL_SEARCH_DIRS}"
-      "${VIEWER_EXE_GLOBS}"
-      "${VIEWER_LIB_GLOB}"
-      "${AUTOBUILD_INSTALL_DIR}/bin/dump_syms"
-      "${VIEWER_SYMBOL_FILE}"
-    DEPENDS generate_breakpad_symbols.py
-        VERBATIM)
-
-  add_custom_target(generate_breakpad_symbols DEPENDS "${VIEWER_SYMBOL_FILE}" "${VIEWER_BINARY_NAME}" "${VIEWER_COPY_MANIFEST}")
-  add_dependencies(generate_breakpad_symbols "${VIEWER_BINARY_NAME}")
-  if (WINDOWS OR LINUX)
-    add_dependencies(generate_breakpad_symbols "${VIEWER_COPY_MANIFEST}")
-  endif (WINDOWS OR LINUX)
-  add_dependencies(llpackage generate_breakpad_symbols)
+if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIEWER_SYMBOL_FILE)
+  if (NOT BUGSPLAT_DB)
+    # Breakpad symbol-file generation
+    set(SYMBOL_SEARCH_DIRS "")
+    if (WINDOWS)
+      list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
+      # slplugin.exe failing symbols dump - need to debug, might have to do with updated version of google breakpad
+      # set(VIEWER_EXE_GLOBS "${VIEWER_BINARY_NAME}${CMAKE_EXECUTABLE_SUFFIX} slplugin.exe")
+      set(VIEWER_EXE_GLOBS "${VIEWER_BINARY_NAME}${CMAKE_EXECUTABLE_SUFFIX}")
+      set(VIEWER_LIB_GLOB "*${CMAKE_SHARED_MODULE_SUFFIX}")
+      set(VIEWER_COPY_MANIFEST copy_w_viewer_manifest)
+    endif (WINDOWS)
+    if (DARWIN)
+      list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
+      # *TODO: Generate these search dirs in the cmake files related to each binary.
+      list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/llplugin/slplugin/${CMAKE_CFG_INTDIR}")
+      list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/mac_crash_logger/${CMAKE_CFG_INTDIR}")
+      list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/gstreamer010/${CMAKE_CFG_INTDIR}")
+      set(VIEWER_EXE_GLOBS "'${product}' SLPlugin mac-crash-logger")
+      set(VIEWER_EXE_GLOBS "'${product}' mac-crash-logger")
+      set(VIEWER_LIB_GLOB "*.dylib")
+    endif (DARWIN)
+    if (LINUX)
+      list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/packaged")
+      set(VIEWER_EXE_GLOBS "do-not-directly-run-secondlife-bin SLPlugin")
+      set(VIEWER_EXE_GLOBS "do-not-directly-run-secondlife-bin")
+      set(VIEWER_LIB_GLOB "*${CMAKE_SHARED_MODULE_SUFFIX}*")
+      set(VIEWER_COPY_MANIFEST copy_l_viewer_manifest)
+    endif (LINUX)
+
+    if(CMAKE_CFG_INTDIR STREQUAL ".")
+        set(LLBUILD_CONFIG ${CMAKE_BUILD_TYPE})
+    else(CMAKE_CFG_INTDIR STREQUAL ".")
+        # set LLBUILD_CONFIG to be a shell variable evaluated at build time
+        # reflecting the configuration we are currently building.
+        set(LLBUILD_CONFIG ${CMAKE_CFG_INTDIR})
+    endif(CMAKE_CFG_INTDIR STREQUAL ".")
+    add_custom_command(OUTPUT "${VIEWER_SYMBOL_FILE}"
+      COMMAND "${PYTHON_EXECUTABLE}"
+      ARGS
+        "${CMAKE_CURRENT_SOURCE_DIR}/generate_breakpad_symbols.py"
+        "${LLBUILD_CONFIG}"
+        "${SYMBOL_SEARCH_DIRS}"
+        "${VIEWER_EXE_GLOBS}"
+        "${VIEWER_LIB_GLOB}"
+        "${AUTOBUILD_INSTALL_DIR}/bin/dump_syms"
+        "${VIEWER_SYMBOL_FILE}"
+      DEPENDS generate_breakpad_symbols.py
+          VERBATIM)
+
+    add_custom_target(generate_symbols DEPENDS "${VIEWER_SYMBOL_FILE}" "${VIEWER_BINARY_NAME}" "${VIEWER_COPY_MANIFEST}")
+    add_dependencies(generate_symbols "${VIEWER_BINARY_NAME}")
+    if (WINDOWS OR LINUX)
+      add_dependencies(generate_symbols "${VIEWER_COPY_MANIFEST}")
+    endif (WINDOWS OR LINUX)
+
+  else (NOT BUGSPLAT_DB)
+    # BugSplat symbol-file generation
+    if (WINDOWS)
+      # Just pack up a tarball containing only the .pdb file for the executable.
+      add_custom_command(OUTPUT "${VIEWER_SYMBOL_FILE}"
+        # Use of 'tar ...j' here assumes VIEWER_SYMBOL_FILE endswith .tar.bz2;
+        # testing a string suffix is painful enough in CMake language that
+        # we'll continue assuming it until forced to generalize.
+        COMMAND "tar"
+        ARGS
+          "cjf"
+          "${VIEWER_SYMBOL_FILE}"
+          "-C"
+          "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}"
+          "secondlife-bin.pdb"
+        DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-bin.pdb"
+        COMMENT "Packing viewer PDB into ${VIEWER_SYMBOL_FILE}"
+        )
+      add_custom_target(generate_symbols DEPENDS "${VIEWER_SYMBOL_FILE}")
+    endif (WINDOWS)
+    if (DARWIN)
+      # Have to run dsymutil first, then pack up the resulting .dSYM directory
+      add_custom_command(OUTPUT "${VIEWER_APP_DSYM}"
+        COMMAND "dsymutil"
+        ARGS
+          "${VIEWER_APP_EXECUTABLE}"
+        DEPENDS "${VIEWER_APP_EXECUTABLE}"
+        COMMENT "Generating ${VIEWER_APP_DSYM}"
+        )
+      add_custom_command(OUTPUT "${VIEWER_SYMBOL_FILE}"
+        # See above comments about "tar ...j"
+        COMMAND "tar"
+        ARGS
+          "cjf"
+          "${VIEWER_SYMBOL_FILE}"
+          "-C"
+          "${VIEWER_APP_DSYM}/.."
+          "${product}.dSYM"
+        DEPENDS "${VIEWER_APP_DSYM}"
+        COMMENT "Packing dSYM into ${VIEWER_SYMBOL_FILE}"
+        )
+      add_custom_command(OUTPUT "${VIEWER_APP_XCARCHIVE}"
+        COMMAND "zip"
+        ARGS
+          "-r"
+          "${VIEWER_APP_XCARCHIVE}"
+          "."
+        WORKING_DIRECTORY "${VIEWER_APP_DSYM}/.."
+        DEPENDS "${VIEWER_APP_DSYM}"
+        COMMENT "Generating xcarchive.zip for upload to BugSplat"
+        )
+      # Have to create a stamp file, and depend on it, to force CMake to run
+      # the cleanup step.
+      add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/dsym.stamp"
+        COMMAND rm -rf "${VIEWER_APP_DSYM}"
+        COMMAND touch "${CMAKE_CURRENT_BINARY_DIR}/dsym.stamp"
+        DEPENDS "${VIEWER_SYMBOL_FILE}" "${VIEWER_APP_XCARCHIVE}"
+        COMMENT "Cleaning up dSYM"
+        )
+      add_custom_target(generate_symbols DEPENDS
+        "${VIEWER_APP_DSYM}"
+        "${VIEWER_SYMBOL_FILE}"
+        "${VIEWER_APP_XCARCHIVE}"
+        "${CMAKE_CURRENT_BINARY_DIR}/dsym.stamp"
+        )
+    endif (DARWIN)
+    if (LINUX)
+      # TBD
+    endif (LINUX)
+  endif (NOT BUGSPLAT_DB)
+
+  # for both BUGSPLAT_DB and Breakpad
+  add_dependencies(llpackage generate_symbols)
 endif ()
 
 if (LL_TESTS)
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index e5f0575e86..f73b444a6e 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -1037,39 +1037,6 @@ open "%s" --args "$@"
 
                         if ("package" in self.args['actions'] or 
                             "unpacked" in self.args['actions']):
-                            # only if we're engaging BugSplat
-                            if self.args.get('bugsplat'):
-                                # Create a symbol archive BEFORE stripping the
-                                # binary.
-                                self.run_command(['dsymutil', exepath])
-                                # This should produce a Second Life.dSYM bundle directory.
-                                try:
-                                    # Now pretend we're Xcode making a .xcarchive file.
-                                    # Put it as a sibling of the top-level .app.
-                                    # From "Dave" at BugSplat support:
-                                    # "More from our Mac lead: I think zipping
-                                    # a folder containing the binary and
-                                    # symbols would be sufficient. Assuming
-                                    # symbol files are created with CMake. I'm
-                                    # not sure if CMake strips symbols into
-                                    # separate files at build time, and if so
-                                    # they're in a supported format."
-                                    xcarchive = os.path.join(parentdir,
-                                                             exename + '.xcarchive.zip')
-                                    with zipfile.ZipFile(xcarchive, 'w',
-                                                         compression=zipfile.ZIP_DEFLATED) as zf:
-                                        print "Creating {}".format(xcarchive)
-                                        for base, dirs, files in os.walk(here):
-                                            for fn in files:
-                                                fullfn = os.path.join(base, fn)
-                                                relfn = os.path.relpath(fullfn, here)
-                                                print "  {}".format(relfn)
-                                                zf.write(fullfn, relfn)
-                                finally:
-                                    # Whether or not we were able to create the
-                                    # .xcarchive file, clean up the .dSYM bundle
-                                    shutil.rmtree(self.dst_path_of(exename + '.dSYM'))
-
                             # NOTE: the -S argument to strip causes it to keep
                             # enough info for annotated backtraces (i.e. function
                             # names in the crash log). 'strip' with no arguments
@@ -1089,7 +1056,7 @@ open "%s" --args "$@"
                     if bugsplat_db:
                         # https://www.bugsplat.com/docs/platforms/os-x#configuration
                         Info["BugsplatServerURL"] = \
-                            "https://{}.bugsplatsoftware.com/".format(bugsplat_db)
+                            "https://{}.bugsplat.com/".format(bugsplat_db)
                     self.put_in_file(
                         plistlib.writePlistToString(Info),
                         os.path.basename(Info_plist),
-- 
cgit v1.2.3


From 34e6d5321df54d99fd91943f49c764849d77bff0 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 30 Aug 2018 14:29:00 -0400
Subject: SL-957: Use cygpath to set up output pathname for cygwin tar.

---
 indra/newview/CMakeLists.txt | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 717c835031..7711488c0f 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -2261,7 +2261,12 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
   else (NOT BUGSPLAT_DB)
     # BugSplat symbol-file generation
     if (WINDOWS)
-      # Just pack up a tarball containing only the .pdb file for the executable.
+      # Just pack up a tarball containing only the .pdb file for the
+      # executable. Because we intend to use cygwin tar, we must render
+      # VIEWER_SYMBOL_FILE in cygwin path syntax.
+      execute_process(COMMAND "cygpath" "-u" "${VIEWER_SYMBOL_FILE}"
+        OUTPUT_VARIABLE VIEWER_SYMBOL_FILE_CYGWIN
+        OUTPUT_STRIP_TRAILING_WHITESPACE)
       add_custom_command(OUTPUT "${VIEWER_SYMBOL_FILE}"
         # Use of 'tar ...j' here assumes VIEWER_SYMBOL_FILE endswith .tar.bz2;
         # testing a string suffix is painful enough in CMake language that
@@ -2269,12 +2274,11 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
         COMMAND "tar"
         ARGS
           "cjf"
-          "${VIEWER_SYMBOL_FILE}"
-          "-C"
-          "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}"
+          "${VIEWER_SYMBOL_FILE_CYGWIN}"
           "secondlife-bin.pdb"
+        WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}"
         DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-bin.pdb"
-        COMMENT "Packing viewer PDB into ${VIEWER_SYMBOL_FILE}"
+        COMMENT "Packing viewer PDB into ${VIEWER_SYMBOL_FILE_CYGWIN}"
         )
       add_custom_target(generate_symbols DEPENDS "${VIEWER_SYMBOL_FILE}")
     endif (WINDOWS)
-- 
cgit v1.2.3


From 29a29db7dd154b694c1ac414ceec8e37cb745335 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 30 Aug 2018 14:52:54 -0400
Subject: SL-957: Try to add enough CMake dependencies to generate Mac symbols.

---
 indra/newview/CMakeLists.txt | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 7711488c0f..36dafa52ed 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -2129,7 +2129,11 @@ if (DARWIN)
     )
 
   set(VIEWER_APP_BUNDLE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app")
-  set(VIEWER_APP_EXECUTABLE "${VIEWER_APP_BUNDLE}/Contents/MacOS/${product}")
+  # VIEWER_APP_EXECUTABLE was originally a prediction of the executable
+  # pathname that would result from running viewer_manifest.py, but CMake
+  # complained that there was no rule to make that executable. Try using the
+  # existing target.
+  set(VIEWER_APP_EXECUTABLE "${VIEWER_BINARY_NAME}")
   set(VIEWER_APP_DSYM "${VIEWER_APP_EXECUTABLE}.dSYM")
   set(VIEWER_APP_XCARCHIVE "${VIEWER_APP_BUNDLE}/../${product}.xcarchive.zip")
 
@@ -2291,6 +2295,8 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
         DEPENDS "${VIEWER_APP_EXECUTABLE}"
         COMMENT "Generating ${VIEWER_APP_DSYM}"
         )
+      add_custom_target(dsym_generate DEPENDS "${VIEWER_APP_DSYM}")
+      add_dependencies(dsym_generate "${VIEWER_APP_EXECUTABLE}")
       add_custom_command(OUTPUT "${VIEWER_SYMBOL_FILE}"
         # See above comments about "tar ...j"
         COMMAND "tar"
@@ -2303,6 +2309,8 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
         DEPENDS "${VIEWER_APP_DSYM}"
         COMMENT "Packing dSYM into ${VIEWER_SYMBOL_FILE}"
         )
+      add_custom_target(dsym_tarball DEPENDS "${VIEWER_SYMBOL_FILE}")
+      add_dependencies(dsym_tarball dsym_generate)
       add_custom_command(OUTPUT "${VIEWER_APP_XCARCHIVE}"
         COMMAND "zip"
         ARGS
@@ -2313,6 +2321,8 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
         DEPENDS "${VIEWER_APP_DSYM}"
         COMMENT "Generating xcarchive.zip for upload to BugSplat"
         )
+      add_custom_target(dsym_xcarchive DEPENDS "${VIEWER_APP_XCARCHIVE}")
+      add_dependencies(dsym_xcarchive dsym_generate)
       # Have to create a stamp file, and depend on it, to force CMake to run
       # the cleanup step.
       add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/dsym.stamp"
@@ -2327,6 +2337,7 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
         "${VIEWER_APP_XCARCHIVE}"
         "${CMAKE_CURRENT_BINARY_DIR}/dsym.stamp"
         )
+      add_dependencies(generate_symbols dsym_tarball dsym_xcarchive)
     endif (DARWIN)
     if (LINUX)
       # TBD
-- 
cgit v1.2.3


From aa6d178b6917af0d933dd2fdcd0c0906285b768b Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 30 Aug 2018 15:19:23 -0400
Subject: SL-957: Delay trying to pack up Windows PDB file until linker done.

---
 indra/newview/CMakeLists.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 36dafa52ed..10210cd918 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -2284,7 +2284,8 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
         DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-bin.pdb"
         COMMENT "Packing viewer PDB into ${VIEWER_SYMBOL_FILE_CYGWIN}"
         )
-      add_custom_target(generate_symbols DEPENDS "${VIEWER_SYMBOL_FILE}")
+      add_custom_target(generate_symbols DEPENDS "${VIEWER_SYMBOL_FILE}" "${VIEWER_BINARY_NAME}")
+      add_dependencies(generate_symbols "${VIEWER_BINARY_NAME}")
     endif (WINDOWS)
     if (DARWIN)
       # Have to run dsymutil first, then pack up the resulting .dSYM directory
-- 
cgit v1.2.3


From 822e3b15e2491ce8f3bd76c5b3ac70be695108e4 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 31 Aug 2018 14:17:00 -0400
Subject: SL-957: Use tar -C instead of changing tar's WORKING_DIRECTORY.

Seems VIEWER_SYMBOL_FILE arrives from build.sh as a relative pathname, so
passing that pathname to tar when we run tar with WORKING_DIRECTORY confuses
it. But if we use tar's -C switch, we can achieve the effect we want (no
leading directory prefixes in the tarball) without WORKING_DIRECTORY. Thing
is, we have to run the desired directory through cygpath first, which is why
we went with WORKING_DIRECTORY in the first place.
---
 indra/newview/CMakeLists.txt | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 10210cd918..a54ee7279c 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -2271,6 +2271,9 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
       execute_process(COMMAND "cygpath" "-u" "${VIEWER_SYMBOL_FILE}"
         OUTPUT_VARIABLE VIEWER_SYMBOL_FILE_CYGWIN
         OUTPUT_STRIP_TRAILING_WHITESPACE)
+      execute_process(COMMAND "cygpath" "-u" "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}"
+        OUTPUT_VARIABLE PARENT_DIRECTORY_CYGWIN
+        OUTPUT_STRIP_TRAILING_WHITESPACE)
       add_custom_command(OUTPUT "${VIEWER_SYMBOL_FILE}"
         # Use of 'tar ...j' here assumes VIEWER_SYMBOL_FILE endswith .tar.bz2;
         # testing a string suffix is painful enough in CMake language that
@@ -2279,8 +2282,9 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
         ARGS
           "cjf"
           "${VIEWER_SYMBOL_FILE_CYGWIN}"
+          "-C"
+          "${PARENT_DIRECTORY_CYGWIN}"
           "secondlife-bin.pdb"
-        WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}"
         DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-bin.pdb"
         COMMENT "Packing viewer PDB into ${VIEWER_SYMBOL_FILE_CYGWIN}"
         )
-- 
cgit v1.2.3


From 392bf44a1f28dfac7583aca551745fe8499e9fe8 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 31 Aug 2018 14:26:32 -0400
Subject: SL-957: Name VIEWER_BINARY_NAME directly, not an assigned variable.

If this theory is correct, setting VIEWER_APP_EXECUTABLE to VIEWER_BINARY_NAME
and then referencing VIEWER_APP_EXECUTABLE instead of VIEWER_BINARY_NAME
confuses CMake as to the filename involved. <eyeroll/>
---
 indra/newview/CMakeLists.txt | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index a54ee7279c..6997a4330f 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -2129,12 +2129,7 @@ if (DARWIN)
     )
 
   set(VIEWER_APP_BUNDLE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app")
-  # VIEWER_APP_EXECUTABLE was originally a prediction of the executable
-  # pathname that would result from running viewer_manifest.py, but CMake
-  # complained that there was no rule to make that executable. Try using the
-  # existing target.
-  set(VIEWER_APP_EXECUTABLE "${VIEWER_BINARY_NAME}")
-  set(VIEWER_APP_DSYM "${VIEWER_APP_EXECUTABLE}.dSYM")
+  set(VIEWER_APP_DSYM "${VIEWER_BINARY_NAME}.dSYM")
   set(VIEWER_APP_XCARCHIVE "${VIEWER_APP_BUNDLE}/../${product}.xcarchive.zip")
 
   configure_file(
@@ -2296,12 +2291,12 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
       add_custom_command(OUTPUT "${VIEWER_APP_DSYM}"
         COMMAND "dsymutil"
         ARGS
-          "${VIEWER_APP_EXECUTABLE}"
-        DEPENDS "${VIEWER_APP_EXECUTABLE}"
+          "${VIEWER_BINARY_NAME}"
+        DEPENDS "${VIEWER_BINARY_NAME}"
         COMMENT "Generating ${VIEWER_APP_DSYM}"
         )
       add_custom_target(dsym_generate DEPENDS "${VIEWER_APP_DSYM}")
-      add_dependencies(dsym_generate "${VIEWER_APP_EXECUTABLE}")
+      add_dependencies(dsym_generate "${VIEWER_BINARY_NAME}")
       add_custom_command(OUTPUT "${VIEWER_SYMBOL_FILE}"
         # See above comments about "tar ...j"
         COMMAND "tar"
-- 
cgit v1.2.3


From 503c2aa9a30ed484d9f41b415af6ec0f9ca93353 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 31 Aug 2018 15:42:58 -0400
Subject: SL-957: Pass an absolute pathname to CMake for VIEWER_SYMBOL_FILE.

---
 build.sh | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/build.sh b/build.sh
index d6a6d7aca8..de7e474479 100755
--- a/build.sh
+++ b/build.sh
@@ -116,8 +116,10 @@ pre_build()
                 symplat="linux"
                 ;;
         esac
-        # This name is consumed by indra/newview/CMakeLists.txt
-        VIEWER_SYMBOL_FILE="$build_dir/newview/$variant/secondlife-symbols-$symplat-${AUTOBUILD_ADDRSIZE}.tar.bz2"
+        # This name is consumed by indra/newview/CMakeLists.txt. Make it
+        # absolute because we've had troubles with relative pathnames.
+        abs_build_dir="$(cd "$build_dir"; pwd)"
+        VIEWER_SYMBOL_FILE="$abs_build_dir/newview/$variant/secondlife-symbols-$symplat-${AUTOBUILD_ADDRSIZE}.tar.bz2"
     fi
 
     # don't spew credentials into build log
-- 
cgit v1.2.3


From 92b64fd59e6ac83bec8c165eb2f1ee31ff5eb059 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 31 Aug 2018 16:04:31 -0400
Subject: SL-957: Try removing quotes from ${VIEWER_BINARY_NAME} in CMake deps.

---
 indra/newview/CMakeLists.txt | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 6997a4330f..bed0132e23 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -2251,8 +2251,8 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
       DEPENDS generate_breakpad_symbols.py
           VERBATIM)
 
-    add_custom_target(generate_symbols DEPENDS "${VIEWER_SYMBOL_FILE}" "${VIEWER_BINARY_NAME}" "${VIEWER_COPY_MANIFEST}")
-    add_dependencies(generate_symbols "${VIEWER_BINARY_NAME}")
+    add_custom_target(generate_symbols DEPENDS "${VIEWER_SYMBOL_FILE}" ${VIEWER_BINARY_NAME} "${VIEWER_COPY_MANIFEST}")
+    add_dependencies(generate_symbols ${VIEWER_BINARY_NAME})
     if (WINDOWS OR LINUX)
       add_dependencies(generate_symbols "${VIEWER_COPY_MANIFEST}")
     endif (WINDOWS OR LINUX)
@@ -2283,20 +2283,20 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
         DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-bin.pdb"
         COMMENT "Packing viewer PDB into ${VIEWER_SYMBOL_FILE_CYGWIN}"
         )
-      add_custom_target(generate_symbols DEPENDS "${VIEWER_SYMBOL_FILE}" "${VIEWER_BINARY_NAME}")
-      add_dependencies(generate_symbols "${VIEWER_BINARY_NAME}")
+      add_custom_target(generate_symbols DEPENDS "${VIEWER_SYMBOL_FILE}" ${VIEWER_BINARY_NAME})
+      add_dependencies(generate_symbols ${VIEWER_BINARY_NAME})
     endif (WINDOWS)
     if (DARWIN)
       # Have to run dsymutil first, then pack up the resulting .dSYM directory
       add_custom_command(OUTPUT "${VIEWER_APP_DSYM}"
         COMMAND "dsymutil"
         ARGS
-          "${VIEWER_BINARY_NAME}"
-        DEPENDS "${VIEWER_BINARY_NAME}"
+          ${VIEWER_BINARY_NAME}
+        DEPENDS ${VIEWER_BINARY_NAME}
         COMMENT "Generating ${VIEWER_APP_DSYM}"
         )
       add_custom_target(dsym_generate DEPENDS "${VIEWER_APP_DSYM}")
-      add_dependencies(dsym_generate "${VIEWER_BINARY_NAME}")
+      add_dependencies(dsym_generate ${VIEWER_BINARY_NAME})
       add_custom_command(OUTPUT "${VIEWER_SYMBOL_FILE}"
         # See above comments about "tar ...j"
         COMMAND "tar"
-- 
cgit v1.2.3


From db76dbba33b6c161486099b20b6f820f0e374ef6 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 31 Aug 2018 16:59:59 -0400
Subject: SL-957: Convert absolute VIEWER_SYMBOL_FILE to native_path.

Thanks Ansariel.
---
 build.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/build.sh b/build.sh
index de7e474479..1f9daa78b2 100755
--- a/build.sh
+++ b/build.sh
@@ -119,7 +119,7 @@ pre_build()
         # This name is consumed by indra/newview/CMakeLists.txt. Make it
         # absolute because we've had troubles with relative pathnames.
         abs_build_dir="$(cd "$build_dir"; pwd)"
-        VIEWER_SYMBOL_FILE="$abs_build_dir/newview/$variant/secondlife-symbols-$symplat-${AUTOBUILD_ADDRSIZE}.tar.bz2"
+        VIEWER_SYMBOL_FILE="$(native_path "$abs_build_dir/newview/$variant/secondlife-symbols-$symplat-${AUTOBUILD_ADDRSIZE}.tar.bz2")"
     fi
 
     # don't spew credentials into build log
-- 
cgit v1.2.3


From 444fbd1b44ae5c48e95030b326c0b14225e87dbe Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 4 Sep 2018 15:37:21 -0400
Subject: SL-957: Try removing redundant add_custom_command() dependency.

---
 indra/newview/CMakeLists.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index bed0132e23..915bfdc39e 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -2292,7 +2292,8 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
         COMMAND "dsymutil"
         ARGS
           ${VIEWER_BINARY_NAME}
-        DEPENDS ${VIEWER_BINARY_NAME}
+##        redundant with add_dependencies() below, and possibly harmful
+##        DEPENDS ${VIEWER_BINARY_NAME}
         COMMENT "Generating ${VIEWER_APP_DSYM}"
         )
       add_custom_target(dsym_generate DEPENDS "${VIEWER_APP_DSYM}")
-- 
cgit v1.2.3


From 150199d542453f6e9a3b6c6e466e778ca5a027d0 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 4 Sep 2018 16:43:34 -0400
Subject: SL-957: Try being more explicit about VIEWER_APP_DSYM full pathname.

---
 indra/newview/CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 915bfdc39e..f3b87cb93c 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -2129,7 +2129,7 @@ if (DARWIN)
     )
 
   set(VIEWER_APP_BUNDLE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app")
-  set(VIEWER_APP_DSYM "${VIEWER_BINARY_NAME}.dSYM")
+  set(VIEWER_APP_DSYM "${VIEWER_APP_BUNDLE}/Contents/MacOS/${product}.dSYM")
   set(VIEWER_APP_XCARCHIVE "${VIEWER_APP_BUNDLE}/../${product}.xcarchive.zip")
 
   configure_file(
-- 
cgit v1.2.3


From d1c6b9820c3c5eda2ca797df104927f4e8f02b24 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 4 Sep 2018 19:28:55 -0400
Subject: SL-957: Try passing dsymutil the full pathname of VIEWER_APP_EXE.

---
 indra/newview/CMakeLists.txt | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index f3b87cb93c..e573b927d7 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -2129,7 +2129,8 @@ if (DARWIN)
     )
 
   set(VIEWER_APP_BUNDLE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app")
-  set(VIEWER_APP_DSYM "${VIEWER_APP_BUNDLE}/Contents/MacOS/${product}.dSYM")
+  set(VIEWER_APP_EXE "${VIEWER_APP_BUNDLE}/Contents/MacOS/${product}")
+  set(VIEWER_APP_DSYM "${VIEWER_APP_EXE}.dSYM")
   set(VIEWER_APP_XCARCHIVE "${VIEWER_APP_BUNDLE}/../${product}.xcarchive.zip")
 
   configure_file(
@@ -2291,9 +2292,7 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
       add_custom_command(OUTPUT "${VIEWER_APP_DSYM}"
         COMMAND "dsymutil"
         ARGS
-          ${VIEWER_BINARY_NAME}
-##        redundant with add_dependencies() below, and possibly harmful
-##        DEPENDS ${VIEWER_BINARY_NAME}
+          ${VIEWER_APP_EXE}
         COMMENT "Generating ${VIEWER_APP_DSYM}"
         )
       add_custom_target(dsym_generate DEPENDS "${VIEWER_APP_DSYM}")
-- 
cgit v1.2.3


From 42931d67a15d9a018f06ec2e5fc8d78549ab4cd8 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 5 Sep 2018 17:27:24 -0400
Subject: SL-957: Don't move viewer executable until final viewer_manifest run.

viewer_manifest is run twice by CMakeLists.txt: once with --actions=copy and
once with the default actions copy and package. The fact that we (try to) move
the Mac viewer executable both times has confused things on a number of
occasions. Currently it's bollixing our attempt to run dsymutil on the
executable so we can package up the Mac symbols for both codeticket and
BugSplat.

Introduce DarwinManifest.is_rearranging() that tests whether either "package"
or "unpacked" is in self.args["actions"], echoing an earlier test. Make
several things conditional on that, notably moving the executable.
---
 indra/newview/viewer_manifest.py | 66 ++++++++++++++++++++++++----------------
 1 file changed, 40 insertions(+), 26 deletions(-)

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index f73b444a6e..d70dbed9e0 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -899,6 +899,12 @@ class DarwinManifest(ViewerManifest):
         # darwin requires full app bundle packaging even for debugging.
         return True
 
+    def is_rearranging(self):
+        # That said, some stuff should still only be performed once.
+        # Are either of these actions in 'actions'? Is the set intersection
+        # non-empty?
+        return bool(set(["package", "unpacked"]).intersection(self.args['actions']))
+
     def construct(self):
         # These are the names of the top-level application and the embedded
         # applications for the VMP and for the actual viewer, respectively.
@@ -926,18 +932,19 @@ class DarwinManifest(ViewerManifest):
 
             # the one file in top-level MacOS directory is the trampoline to
             # our nested launcher_app
-            with self.prefix(dst="MacOS"):
-                toplevel_MacOS = self.get_dst_prefix()
-                trampoline = self.put_in_file("""\
+            if self.is_rearranging():
+                with self.prefix(dst="MacOS"):
+                    toplevel_MacOS = self.get_dst_prefix()
+                    trampoline = self.put_in_file("""\
 #!/bin/bash
 open "%s" --args "$@"
 """ %
-                    # up one directory from MacOS to its sibling Resources directory
-                    os.path.join('$(dirname "$0")', os.pardir, 'Resources', launcher_app),
-                    "SL_Launcher",      # write this file
-                    "trampoline")       # flag to add to list of copied files
-                # Script must be executable
-                self.run_command(["chmod", "+x", trampoline])
+                        # up one directory from MacOS to its sibling Resources directory
+                        os.path.join('$(dirname "$0")', os.pardir, 'Resources', launcher_app),
+                        "SL_Launcher",      # write this file
+                        "trampoline")       # flag to add to list of copied files
+                    # Script must be executable
+                    self.run_command(["chmod", "+x", trampoline])
 
             # Make a symlink to a nested app Frameworks directory that doesn't
             # yet exist. We shouldn't need this; the only things that need
@@ -1018,12 +1025,19 @@ open "%s" --args "$@"
                                 continue
                             fromwhere = os.path.join(toplevel_MacOS, f)
                             towhere   = self.dst_path_of(f)
-                            print "Moving %s => %s" % \
-                                  (self.relpath(fromwhere, relbase),
-                                   self.relpath(towhere, relbase))
-                            # now do it, only without relativizing paths
-                            os.rename(fromwhere, towhere)
-
+                            fromrel   = self.relpath(fromwhere, relbase)
+                            torel     = self.relpath(towhere, relbase)
+                            if not self.is_rearranging():
+                                print "Not yet moving {} => {}".format(fromrel, torel)
+                            else:
+                                print "Moving {} => {}".format(fromrel, torel)
+                                # now do it, only without relativizing paths
+                                os.rename(fromwhere, towhere)
+
+                        # If we haven't yet moved executables, find our viewer
+                        # executable where it was linked, in toplevel_MacOS.
+                        # If we have, find it here.
+                        whichdir = here if self.is_rearranging() else toplevel_MacOS
                         # Pick the biggest of the executables as the real viewer.
                         # Make (basename, fullpath) pairs; for each pair,
                         # expand to (size, basename, fullpath) triples; sort
@@ -1032,11 +1046,10 @@ open "%s" --args "$@"
                         _, exename, exepath = \
                             sorted((os.path.getsize(path), name, path)
                                    for name, path in
-                                   ((name, os.path.join(here, name))
-                                    for name in os.listdir(here)))[-1]
+                                   ((name, os.path.join(whichdir, name))
+                                    for name in os.listdir(whichdir)))[-1]
 
-                        if ("package" in self.args['actions'] or 
-                            "unpacked" in self.args['actions']):
+                        if self.is_rearranging():
                             # NOTE: the -S argument to strip causes it to keep
                             # enough info for annotated backtraces (i.e. function
                             # names in the crash log). 'strip' with no arguments
@@ -1192,13 +1205,14 @@ open "%s" --args "$@"
 
                         # our apps
                         executable_path = {}
-                        for app_bld_dir, app in (("mac_crash_logger", "mac-crash-logger.app"),
-                                                 # plugin launcher
-                                                 (os.path.join("llplugin", "slplugin"), "SLPlugin.app"),
-                                                 ):
-                            self.path2basename(os.path.join(os.pardir,
-                                                            app_bld_dir, self.args['configuration']),
-                                               app)
+                        for app_bld_dir, app in (
+                            ("mac_crash_logger", "mac-crash-logger.app"),
+                            # plugin launcher
+                            (os.path.join("llplugin", "slplugin"), "SLPlugin.app"),
+                            ):
+                            self.path2basename(
+                                os.path.join(os.pardir, app_bld_dir, self.args['configuration']),
+                                app)
                             executable_path[app] = \
                                 self.dst_path_of(os.path.join(app, "Contents", "MacOS"))
 
-- 
cgit v1.2.3


From 137c8db8cc1aa49a306531413e9cba5688cb9990 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 5 Sep 2018 20:33:19 -0400
Subject: SL-957: Previous commit skipped a couple assignments used later.

---
 indra/newview/viewer_manifest.py | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index d70dbed9e0..aa03780e19 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -930,11 +930,13 @@ class DarwinManifest(ViewerManifest):
             # top-level Info.plist is as generated by CMake
             Info_plist = self.dst_path_of("Info.plist")
 
+            toplevel_MacOS = self.dst_path_of("MacOS")
             # the one file in top-level MacOS directory is the trampoline to
             # our nested launcher_app
-            if self.is_rearranging():
+            if not self.is_rearranging():
+                trampoline = ""
+            else:
                 with self.prefix(dst="MacOS"):
-                    toplevel_MacOS = self.get_dst_prefix()
                     trampoline = self.put_in_file("""\
 #!/bin/bash
 open "%s" --args "$@"
-- 
cgit v1.2.3


From c9ad54212ec0bf874177e78e034b30ccd0b93212 Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Tue, 4 Sep 2018 12:39:56 -0400
Subject: use copy_if_different to copy CrashReporter.nib so that it creates
 the directory if needed

---
 indra/mac_crash_logger/CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/mac_crash_logger/CMakeLists.txt b/indra/mac_crash_logger/CMakeLists.txt
index ab20388261..f6c4dfb59d 100644
--- a/indra/mac_crash_logger/CMakeLists.txt
+++ b/indra/mac_crash_logger/CMakeLists.txt
@@ -85,7 +85,7 @@ add_custom_command(
   COMMAND ${CMAKE_COMMAND}
   ARGS
     -E
-    copy_directory
+    copy_if_different
     ${CMAKE_CURRENT_SOURCE_DIR}/CrashReporter.nib
     ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/mac-crash-logger.app/Contents/Resources/CrashReporter.nib
   )
-- 
cgit v1.2.3


From a906ccd478c4aad1780d1f6e9a4a7926ff8934fb Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Wed, 5 Sep 2018 09:12:21 -0400
Subject: remove duplicated EDU definitions

---
 BuildParams | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/BuildParams b/BuildParams
index cb908f1532..c5f96d5ee3 100755
--- a/BuildParams
+++ b/BuildParams
@@ -62,11 +62,6 @@ Linux.additional_packages = ""
 EDU_sourceid = ""
 EDU_viewer_channel_suffix = "edu"
 
-# The EDU package allows us to create a separate release channel whose expirations
-# are synchronized as much as possible with the academic year
-EDU_sourceid = ""
-EDU_viewer_channel_suffix = "edu"
-
 # Notifications - to configure email notices use the TeamCity parameter
 # setting screen for your project or build configuration to set the
 # environment variable 'email' to a space-separated list of email addresses
-- 
cgit v1.2.3


From 49c483eeb350f3620f26ce933007c3d4e9f66d4f Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Wed, 5 Sep 2018 18:07:35 -0400
Subject: add more block structure to TeamCity log output for components

---
 indra/CMakeLists.txt                                |  2 ++
 indra/cmake/00-Common.cmake                         | 21 +++++++++++++++++++++
 indra/cmake/LLAddBuildTest.cmake                    |  4 ++++
 .../llimage_libtest/CMakeLists.txt                  |  3 ++-
 indra/integration_tests/llui_libtest/CMakeLists.txt |  1 +
 indra/linux_crash_logger/CMakeLists.txt             |  4 +++-
 indra/llappearance/CMakeLists.txt                   |  2 ++
 indra/llaudio/CMakeLists.txt                        |  1 +
 indra/llcharacter/CMakeLists.txt                    |  1 +
 indra/llcommon/CMakeLists.txt                       |  2 ++
 indra/llcorehttp/CMakeLists.txt                     |  2 ++
 indra/llcrashlogger/CMakeLists.txt                  |  1 +
 indra/llimage/CMakeLists.txt                        |  1 +
 indra/llimagej2coj/CMakeLists.txt                   |  3 +++
 indra/llinventory/CMakeLists.txt                    |  1 +
 indra/llkdu/CMakeLists.txt                          |  1 +
 indra/llmath/CMakeLists.txt                         |  1 +
 indra/llmessage/CMakeLists.txt                      |  1 +
 indra/llplugin/CMakeLists.txt                       |  1 +
 indra/llplugin/slplugin/CMakeLists.txt              |  3 ++-
 indra/llprimitive/CMakeLists.txt                    |  1 +
 indra/llrender/CMakeLists.txt                       |  2 ++
 indra/llui/CMakeLists.txt                           |  1 +
 indra/llvfs/CMakeLists.txt                          |  1 +
 indra/llwindow/CMakeLists.txt                       |  2 ++
 indra/llxml/CMakeLists.txt                          |  1 +
 indra/mac_crash_logger/CMakeLists.txt               |  1 +
 indra/media_plugins/base/CMakeLists.txt             |  3 ++-
 indra/media_plugins/cef/CMakeLists.txt              |  3 ++-
 indra/media_plugins/example/CMakeLists.txt          |  3 ++-
 indra/media_plugins/gstreamer010/CMakeLists.txt     |  3 ++-
 indra/media_plugins/libvlc/CMakeLists.txt           |  3 ++-
 indra/newview/CMakeLists.txt                        |  7 +++++++
 indra/test/CMakeLists.txt                           |  1 +
 indra/viewer_components/login/CMakeLists.txt        |  1 +
 indra/win_crash_logger/CMakeLists.txt               |  1 +
 36 files changed, 82 insertions(+), 8 deletions(-)

diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt
index a40b2c0846..08d0c7b510 100644
--- a/indra/CMakeLists.txt
+++ b/indra/CMakeLists.txt
@@ -44,6 +44,8 @@ if (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts)
 endif (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts)
 
 add_custom_target(viewer)
+buildscripts_block(viewer)
+
 add_subdirectory(${LIBS_OPEN_PREFIX}llcrashlogger)
 add_subdirectory(${LIBS_OPEN_PREFIX}llplugin)
 add_subdirectory(${LIBS_OPEN_PREFIX}llui)
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
index 40fc706a99..24f6329d10 100644
--- a/indra/cmake/00-Common.cmake
+++ b/indra/cmake/00-Common.cmake
@@ -217,4 +217,25 @@ else (USESYSTEMLIBS)
       )
 endif (USESYSTEMLIBS)
 
+macro (buildscripts_block target_name)
+    # add custom commands to bracket a target build to make logs easier to read
+
+    if (DEFINED ENV{TEAMCITY_BUILDCONF_NAME})
+        add_custom_command(TARGET ${target_name} PRE_BUILD
+            COMMAND echo ARGS "##teamcity[blockOpened name='${target_name}']" VERBATIM
+            )
+        add_custom_command(TARGET ${target_name} POST_BUILD
+            COMMAND echo ARGS "##teamcity[blockClosed name='${target_name}']" VERBATIM
+            )
+    else (DEFINED ENV{TEAMCITY_BUILDCONF_NAME})
+        add_custom_command(TARGET ${target_name} PRE_BUILD
+            COMMAND echo ARGS "################## START ${target_name}" VERBATIM
+            )
+        add_custom_command(TARGET ${target_name} POST_BUILD
+            COMMAND echo ARGS "################## FINISH ${target_name}" VERBATIM
+            )
+    endif (DEFINED ENV{TEAMCITY_BUILDCONF_NAME})
+
+endmacro (buildscripts_block target_name)
+
 endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake
index 024bfe14a1..3b5bc0af7c 100644
--- a/indra/cmake/LLAddBuildTest.cmake
+++ b/indra/cmake/LLAddBuildTest.cmake
@@ -1,4 +1,5 @@
 # -*- cmake -*-
+include(00-Common)
 include(LLTestCommand)
 include(GoogleMock)
 include(Tut)
@@ -104,6 +105,7 @@ INCLUDE(GoogleMock)
 
     # Setup target
     ADD_EXECUTABLE(PROJECT_${project}_TEST_${name} ${${name}_test_SOURCE_FILES})
+    buildscripts_block(PROJECT_${project}_TEST_${name})
     SET_TARGET_PROPERTIES(PROJECT_${project}_TEST_${name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}")
 
     #
@@ -165,6 +167,7 @@ INCLUDE(GoogleMock)
   # Add the test runner target per-project
   # (replaces old _test_ok targets all over the place)
   ADD_CUSTOM_TARGET(${project}_tests ALL DEPENDS ${${project}_TEST_OUTPUT})
+  buildscripts_block(${project}_tests)
   ADD_DEPENDENCIES(${project} ${project}_tests)
 ENDMACRO(LL_ADD_PROJECT_UNIT_TESTS)
 
@@ -212,6 +215,7 @@ FUNCTION(LL_ADD_INTEGRATION_TEST
     message(STATUS "ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files})")
   endif(TEST_DEBUG)
   ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files})
+  buildscripts_block(INTEGRATION_TEST_${testname})
   SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname}
     PROPERTIES
     RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}"
diff --git a/indra/integration_tests/llimage_libtest/CMakeLists.txt b/indra/integration_tests/llimage_libtest/CMakeLists.txt
index 13cf1f7bde..4e23a1fc87 100644
--- a/indra/integration_tests/llimage_libtest/CMakeLists.txt
+++ b/indra/integration_tests/llimage_libtest/CMakeLists.txt
@@ -40,7 +40,8 @@ add_executable(llimage_libtest
     WIN32
     MACOSX_BUNDLE
     ${llimage_libtest_SOURCE_FILES}
-)
+    )
+buildscripts_block(llimage_libtest)
 
 set_target_properties(llimage_libtest
     PROPERTIES
diff --git a/indra/integration_tests/llui_libtest/CMakeLists.txt b/indra/integration_tests/llui_libtest/CMakeLists.txt
index 34e34c7e47..2d21f9af0f 100644
--- a/indra/integration_tests/llui_libtest/CMakeLists.txt
+++ b/indra/integration_tests/llui_libtest/CMakeLists.txt
@@ -56,6 +56,7 @@ set_source_files_properties(${llui_libtest_HEADER_FILES}
 list(APPEND llui_libtest_SOURCE_FILES ${llui_libtest_HEADER_FILES})
 
 add_executable(llui_libtest ${llui_libtest_SOURCE_FILES})
+buildscripts_block(llui_libtest)
 
 # Link with OS-specific libraries for LLWindow dependency
 if (DARWIN)
diff --git a/indra/linux_crash_logger/CMakeLists.txt b/indra/linux_crash_logger/CMakeLists.txt
index 029096df37..165b33fede 100644
--- a/indra/linux_crash_logger/CMakeLists.txt
+++ b/indra/linux_crash_logger/CMakeLists.txt
@@ -55,6 +55,7 @@ list(APPEND linux_crash_logger_SOURCE_FILES
 set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed")
 
 add_executable(linux-crash-logger ${linux_crash_logger_SOURCE_FILES})
+buildscripts_block(linux-crash-logger)
 
 # llcommon uses `clock_gettime' which is provided by librt on linux.
 set(LIBRT_LIBRARY rt)
@@ -78,4 +79,5 @@ target_link_libraries(linux-crash-logger
     )
 
 add_custom_target(linux-crash-logger-target ALL
-                  DEPENDS linux-crash-logger)
+    DEPENDS linux-crash-logger)
+buildscripts_block(linux-crash-logger-target)
diff --git a/indra/llappearance/CMakeLists.txt b/indra/llappearance/CMakeLists.txt
index 20eb4678dd..ad33fed010 100644
--- a/indra/llappearance/CMakeLists.txt
+++ b/indra/llappearance/CMakeLists.txt
@@ -77,6 +77,7 @@ set_source_files_properties(${llappearance_HEADER_FILES}
 list(APPEND llappearance_SOURCE_FILES ${llappearance_HEADER_FILES})
 
 add_library (llappearance ${llappearance_SOURCE_FILES})
+buildscripts_block(llappearance)
 
 target_link_libraries(llappearance
     ${LLCHARACTER_LIBRARIES}
@@ -94,6 +95,7 @@ target_link_libraries(llappearance
 
 if (BUILD_HEADLESS)
   add_library (llappearanceheadless ${llappearance_SOURCE_FILES})
+  buildscripts_block(llappearanceheadless)
   
   target_link_libraries(llappearanceheadless
       ${LLCHARACTER_LIBRARIES}
diff --git a/indra/llaudio/CMakeLists.txt b/indra/llaudio/CMakeLists.txt
index e943dd5d5c..fc81d8c6f2 100644
--- a/indra/llaudio/CMakeLists.txt
+++ b/indra/llaudio/CMakeLists.txt
@@ -77,6 +77,7 @@ set_source_files_properties(${llaudio_HEADER_FILES}
 list(APPEND llaudio_SOURCE_FILES ${llaudio_HEADER_FILES})
 
 add_library (llaudio ${llaudio_SOURCE_FILES})
+buildscripts_block(llaudio)
 target_link_libraries(
     llaudio
     ${LLCOMMON_LIBRARIES}
diff --git a/indra/llcharacter/CMakeLists.txt b/indra/llcharacter/CMakeLists.txt
index a17a5b0aa6..3d0eb09ada 100644
--- a/indra/llcharacter/CMakeLists.txt
+++ b/indra/llcharacter/CMakeLists.txt
@@ -79,6 +79,7 @@ set_source_files_properties(${llcharacter_HEADER_FILES}
 list(APPEND llcharacter_SOURCE_FILES ${llcharacter_HEADER_FILES})
 
 add_library (llcharacter ${llcharacter_SOURCE_FILES})
+buildscripts_block(llcharacter)
 
 target_link_libraries(
     llcharacter
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 42ad56f1b0..0d58a59e3f 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -24,6 +24,7 @@ include_directories(
     )
 
 # add_executable(lltreeiterators lltreeiterators.cpp)
+# buildscripts_block(lltreeiterators)
 # 
 # target_link_libraries(lltreeiterators
 #     ${LLCOMMON_LIBRARIES})
@@ -279,6 +280,7 @@ if(LLCOMMON_LINK_SHARED)
 else(LLCOMMON_LINK_SHARED)
     add_library (llcommon ${llcommon_SOURCE_FILES})
 endif(LLCOMMON_LINK_SHARED)
+buildscripts_block(llcommon)
 
 target_link_libraries(
     llcommon
diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt
index 9dbc6f447e..c42bd7b6b2 100644
--- a/indra/llcorehttp/CMakeLists.txt
+++ b/indra/llcorehttp/CMakeLists.txt
@@ -90,6 +90,7 @@ endif (DARWIN OR LINUX)
 list(APPEND llcorehttp_SOURCE_FILES ${llcorehttp_HEADER_FILES})
 
 add_library (llcorehttp ${llcorehttp_SOURCE_FILES})
+buildscripts_block(llcorehttp)
 target_link_libraries(
   llcorehttp
   ${CURL_LIBRARIES}
@@ -214,6 +215,7 @@ endif (DARWIN)
   add_executable(http_texture_load
                  ${llcorehttp_EXAMPLE_SOURCE_FILES}
                  )
+  buildscripts_block(http_texture_load)
   set_target_properties(http_texture_load
                         PROPERTIES
                         RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}"
diff --git a/indra/llcrashlogger/CMakeLists.txt b/indra/llcrashlogger/CMakeLists.txt
index da23b46b7b..7d7f3f0167 100644
--- a/indra/llcrashlogger/CMakeLists.txt
+++ b/indra/llcrashlogger/CMakeLists.txt
@@ -41,3 +41,4 @@ set_source_files_properties(${llcrashlogger_HEADER_FILES}
 list(APPEND llcrashlogger_SOURCE_FILES ${llcrashlogger_HEADER_FILES})
 
 add_library(llcrashlogger ${llcrashlogger_SOURCE_FILES})
+buildscripts_block(llcrashlogger)
diff --git a/indra/llimage/CMakeLists.txt b/indra/llimage/CMakeLists.txt
index 293ada7548..4b57a77999 100644
--- a/indra/llimage/CMakeLists.txt
+++ b/indra/llimage/CMakeLists.txt
@@ -59,6 +59,7 @@ set_source_files_properties(${llimage_HEADER_FILES}
 list(APPEND llimage_SOURCE_FILES ${llimage_HEADER_FILES})
 
 add_library (llimage ${llimage_SOURCE_FILES})
+buildscripts_block(llimage)
 # Libraries on which this library depends, needed for Linux builds
 # Sort by high-level to low-level
 if (USE_KDU)
diff --git a/indra/llimagej2coj/CMakeLists.txt b/indra/llimagej2coj/CMakeLists.txt
index 97d22cf86a..f05842b721 100644
--- a/indra/llimagej2coj/CMakeLists.txt
+++ b/indra/llimagej2coj/CMakeLists.txt
@@ -29,7 +29,10 @@ set_source_files_properties(${llimagej2coj_HEADER_FILES}
 list(APPEND llimagej2coj_SOURCE_FILES ${llimagej2coj_HEADER_FILES})
 
 add_library (llimagej2coj ${llimagej2coj_SOURCE_FILES})
+buildscripts_block(llimagej2coj)
+
 target_link_libraries(
     llimagej2coj
     ${OPENJPEG_LIBRARIES}
     )
+
diff --git a/indra/llinventory/CMakeLists.txt b/indra/llinventory/CMakeLists.txt
index 68dd00d880..6a5892127d 100644
--- a/indra/llinventory/CMakeLists.txt
+++ b/indra/llinventory/CMakeLists.txt
@@ -60,6 +60,7 @@ set_source_files_properties(${llinventory_HEADER_FILES}
 list(APPEND llinventory_SOURCE_FILES ${llinventory_HEADER_FILES})
 
 add_library (llinventory ${llinventory_SOURCE_FILES})
+buildscripts_block(llinventory)
 
 
 
diff --git a/indra/llkdu/CMakeLists.txt b/indra/llkdu/CMakeLists.txt
index cb0e204e91..59f6d08517 100644
--- a/indra/llkdu/CMakeLists.txt
+++ b/indra/llkdu/CMakeLists.txt
@@ -50,6 +50,7 @@ set_source_files_properties(${llkdu_SOURCE_FILES}
 
 if (USE_KDU)
   add_library (llkdu ${llkdu_SOURCE_FILES})
+  buildscripts_block(llkdu)
 
   target_link_libraries(llkdu
     ${KDU_LIBRARY})
diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt
index 4c8bcdac91..110173add3 100644
--- a/indra/llmath/CMakeLists.txt
+++ b/indra/llmath/CMakeLists.txt
@@ -101,6 +101,7 @@ set_source_files_properties(${llmath_HEADER_FILES}
 list(APPEND llmath_SOURCE_FILES ${llmath_HEADER_FILES})
 
 add_library (llmath ${llmath_SOURCE_FILES})
+buildscripts_block(llmath)
 
 target_link_libraries(llmath
     ${LLCOMMON_LIBRARIES}
diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt
index e0922c0667..ab59c8bb40 100644
--- a/indra/llmessage/CMakeLists.txt
+++ b/indra/llmessage/CMakeLists.txt
@@ -203,6 +203,7 @@ set_source_files_properties(${llmessage_HEADER_FILES}
 list(APPEND llmessage_SOURCE_FILES ${llmessage_HEADER_FILES})
 
 add_library (llmessage ${llmessage_SOURCE_FILES})
+buildscripts_block(llmessage)
 
 if (LINUX)
 target_link_libraries(
diff --git a/indra/llplugin/CMakeLists.txt b/indra/llplugin/CMakeLists.txt
index 5cc129a267..9d79eabbb3 100644
--- a/indra/llplugin/CMakeLists.txt
+++ b/indra/llplugin/CMakeLists.txt
@@ -65,6 +65,7 @@ endif(NOT ADDRESS_SIZE EQUAL 32)
 list(APPEND llplugin_SOURCE_FILES ${llplugin_HEADER_FILES})
 
 add_library (llplugin ${llplugin_SOURCE_FILES})
+buildscripts_block(llplugin)
 
 add_subdirectory(slplugin)
 
diff --git a/indra/llplugin/slplugin/CMakeLists.txt b/indra/llplugin/slplugin/CMakeLists.txt
index 0e5e835777..3a9d661ff6 100644
--- a/indra/llplugin/slplugin/CMakeLists.txt
+++ b/indra/llplugin/slplugin/CMakeLists.txt
@@ -48,7 +48,8 @@ add_executable(SLPlugin
     WIN32
     MACOSX_BUNDLE
     ${SLPlugin_SOURCE_FILES}
-)
+    )
+buildscripts_block(SLPlugin)
 
 if (WINDOWS)
 set_target_properties(SLPlugin
diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt
index dd2e806dda..12c6882844 100644
--- a/indra/llprimitive/CMakeLists.txt
+++ b/indra/llprimitive/CMakeLists.txt
@@ -71,6 +71,7 @@ set_source_files_properties(${llprimitive_HEADER_FILES}
 list(APPEND llprimitive_SOURCE_FILES ${llprimitive_HEADER_FILES})
 
 add_library (llprimitive ${llprimitive_SOURCE_FILES})
+buildscripts_block(llprimitive)
 
 target_link_libraries(llprimitive
     ${LLCOMMON_LIBRARIES}
diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt
index 07a0d8c402..de5f24758c 100644
--- a/indra/llrender/CMakeLists.txt
+++ b/indra/llrender/CMakeLists.txt
@@ -91,6 +91,7 @@ if (BUILD_HEADLESS)
   add_library (llrenderheadless
     ${llrender_SOURCE_FILES}
     )
+  buildscripts_block(llrenderheadless)
 
   set_property(TARGET llrenderheadless
     PROPERTY COMPILE_DEFINITIONS LL_MESA=1 LL_MESA_HEADLESS=1
@@ -110,6 +111,7 @@ if (BUILD_HEADLESS)
 endif (BUILD_HEADLESS)
 
 add_library (llrender ${llrender_SOURCE_FILES})
+buildscripts_block(llrender)
 
 if (SDL_FOUND)
   set_property(TARGET llrender
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index 8054eb3619..41a79d5752 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -269,6 +269,7 @@ set_source_files_properties(llurlentry.cpp
 list(APPEND llui_SOURCE_FILES ${llui_HEADER_FILES})
 
 add_library (llui ${llui_SOURCE_FILES})
+buildscripts_block(llui)
 # Libraries on which this library depends, needed for Linux builds
 # Sort by high-level to low-level
 target_link_libraries(llui
diff --git a/indra/llvfs/CMakeLists.txt b/indra/llvfs/CMakeLists.txt
index 67dce8c073..a9d602d333 100644
--- a/indra/llvfs/CMakeLists.txt
+++ b/indra/llvfs/CMakeLists.txt
@@ -64,6 +64,7 @@ set_source_files_properties(${llvfs_HEADER_FILES}
 list(APPEND llvfs_SOURCE_FILES ${llvfs_HEADER_FILES})
 
 add_library (llvfs ${llvfs_SOURCE_FILES})
+buildscripts_block(llvfs)
 
 set(vfs_BOOST_LIBRARIES
     ${BOOST_FILESYSTEM_LIBRARY}
diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt
index 0743fd899f..d7ab3bfebb 100644
--- a/indra/llwindow/CMakeLists.txt
+++ b/indra/llwindow/CMakeLists.txt
@@ -175,6 +175,7 @@ if (BUILD_HEADLESS)
     ${llwindow_SOURCE_FILES}
     ${llwindowheadless_SOURCE_FILES}
     )
+  buildscripts_block(llwindowheadless)
   set_property(TARGET llwindowheadless
     PROPERTY COMPILE_DEFINITIONS LL_MESA=1 LL_MESA_HEADLESS=1
     )
@@ -191,6 +192,7 @@ endif (llwindow_HEADER_FILES)
     ${llwindow_SOURCE_FILES}
     ${viewer_SOURCE_FILES}
     )
+  buildscripts_block(llwindow)
 
 if (SDL_FOUND)
   set_property(TARGET llwindow
diff --git a/indra/llxml/CMakeLists.txt b/indra/llxml/CMakeLists.txt
index 17400a203e..cb2d0f5c76 100644
--- a/indra/llxml/CMakeLists.txt
+++ b/indra/llxml/CMakeLists.txt
@@ -40,6 +40,7 @@ set_source_files_properties(${llxml_HEADER_FILES}
 list(APPEND llxml_SOURCE_FILES ${llxml_HEADER_FILES})
 
 add_library (llxml ${llxml_SOURCE_FILES})
+buildscripts_block(llxml)
 # Libraries on which this library depends, needed for Linux builds
 # Sort by high-level to low-level
 target_link_libraries( llxml
diff --git a/indra/mac_crash_logger/CMakeLists.txt b/indra/mac_crash_logger/CMakeLists.txt
index f6c4dfb59d..f62bab5673 100644
--- a/indra/mac_crash_logger/CMakeLists.txt
+++ b/indra/mac_crash_logger/CMakeLists.txt
@@ -58,6 +58,7 @@ list(APPEND mac_crash_logger_SOURCE_FILES ${mac_crash_logger_RESOURCE_FILES})
 add_executable(mac-crash-logger
   MACOSX_BUNDLE
   ${mac_crash_logger_SOURCE_FILES})
+buildscripts_block(mac-crash-logger)
 
 set_target_properties(mac-crash-logger
   PROPERTIES
diff --git a/indra/media_plugins/base/CMakeLists.txt b/indra/media_plugins/base/CMakeLists.txt
index 70c81d4023..8ab535e14c 100644
--- a/indra/media_plugins/base/CMakeLists.txt
+++ b/indra/media_plugins/base/CMakeLists.txt
@@ -48,5 +48,6 @@ set(media_plugin_base_HEADER_FILES
 
 add_library(media_plugin_base
     ${media_plugin_base_SOURCE_FILES}
-)
+    )
+buildscripts_block(media_plugin_base)
 
diff --git a/indra/media_plugins/cef/CMakeLists.txt b/indra/media_plugins/cef/CMakeLists.txt
index 5452fd9d1e..dedc47e341 100644
--- a/indra/media_plugins/cef/CMakeLists.txt
+++ b/indra/media_plugins/cef/CMakeLists.txt
@@ -81,7 +81,8 @@ list(APPEND media_plugin_cef_SOURCE_FILES ${media_plugin_cef_HEADER_FILES})
 add_library(media_plugin_cef
     SHARED
     ${media_plugin_cef_SOURCE_FILES}
-)
+    )
+buildscripts_block(media_plugin_cef)
 
 #add_dependencies(media_plugin_cef
 #  ${MEDIA_PLUGIN_BASE_LIBRARIES}
diff --git a/indra/media_plugins/example/CMakeLists.txt b/indra/media_plugins/example/CMakeLists.txt
index 6f5b28b8e9..95d3d5b5a2 100644
--- a/indra/media_plugins/example/CMakeLists.txt
+++ b/indra/media_plugins/example/CMakeLists.txt
@@ -47,7 +47,8 @@ set(media_plugin_example_SOURCE_FILES
 add_library(media_plugin_example
     SHARED
     ${media_plugin_example_SOURCE_FILES}
-)
+    )
+buildscripts_block(media_plugin_example)
 
 target_link_libraries(media_plugin_example
   ${LLPLUGIN_LIBRARIES}
diff --git a/indra/media_plugins/gstreamer010/CMakeLists.txt b/indra/media_plugins/gstreamer010/CMakeLists.txt
index 6d18814b1e..18b4b761cf 100644
--- a/indra/media_plugins/gstreamer010/CMakeLists.txt
+++ b/indra/media_plugins/gstreamer010/CMakeLists.txt
@@ -56,7 +56,8 @@ set(media_plugin_gstreamer010_HEADER_FILES
 add_library(media_plugin_gstreamer010
     SHARED
     ${media_plugin_gstreamer010_SOURCE_FILES}
-)
+    )
+buildscripts_block(media_plugin_gstreamer010)
 
 target_link_libraries(media_plugin_gstreamer010
   ${LLPLUGIN_LIBRARIES}
diff --git a/indra/media_plugins/libvlc/CMakeLists.txt b/indra/media_plugins/libvlc/CMakeLists.txt
index d3e9243069..7946e7ccfc 100644
--- a/indra/media_plugins/libvlc/CMakeLists.txt
+++ b/indra/media_plugins/libvlc/CMakeLists.txt
@@ -48,7 +48,8 @@ set(media_plugin_libvlc_SOURCE_FILES
 add_library(media_plugin_libvlc
     SHARED
     ${media_plugin_libvlc_SOURCE_FILES}
-)
+    )
+buildscripts_block(media_plugin_libvlc)
 
 target_link_libraries(media_plugin_libvlc
   ${LLPLUGIN_LIBRARIES}
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index e573b927d7..560c9d0737 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1722,6 +1722,7 @@ add_executable(${VIEWER_BINARY_NAME}
     MACOSX_BUNDLE
     ${viewer_SOURCE_FILES}
     )
+buildscripts_block(${VIEWER_BINARY_NAME})
 
 if (SDL_FOUND)
   set_property(TARGET ${VIEWER_BINARY_NAME}
@@ -1914,6 +1915,7 @@ if (WINDOWS)
         ${CMAKE_CFG_INTDIR}/touched.bat
         windows-setup-build-all
         )
+      buildscripts_block(llpackage)
         # temporarily disable packaging of event_host until hg subrepos get
         # sorted out on the parabuild cluster...
         #${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/event_host.tar.bz2)
@@ -2253,6 +2255,7 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
           VERBATIM)
 
     add_custom_target(generate_symbols DEPENDS "${VIEWER_SYMBOL_FILE}" ${VIEWER_BINARY_NAME} "${VIEWER_COPY_MANIFEST}")
+    buildscripts_block(generate_symbols)
     add_dependencies(generate_symbols ${VIEWER_BINARY_NAME})
     if (WINDOWS OR LINUX)
       add_dependencies(generate_symbols "${VIEWER_COPY_MANIFEST}")
@@ -2285,6 +2288,7 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
         COMMENT "Packing viewer PDB into ${VIEWER_SYMBOL_FILE_CYGWIN}"
         )
       add_custom_target(generate_symbols DEPENDS "${VIEWER_SYMBOL_FILE}" ${VIEWER_BINARY_NAME})
+      buildscripts_block(generate_symbols)
       add_dependencies(generate_symbols ${VIEWER_BINARY_NAME})
     endif (WINDOWS)
     if (DARWIN)
@@ -2296,6 +2300,7 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
         COMMENT "Generating ${VIEWER_APP_DSYM}"
         )
       add_custom_target(dsym_generate DEPENDS "${VIEWER_APP_DSYM}")
+      buildscripts_block(dsym_generate)
       add_dependencies(dsym_generate ${VIEWER_BINARY_NAME})
       add_custom_command(OUTPUT "${VIEWER_SYMBOL_FILE}"
         # See above comments about "tar ...j"
@@ -2310,6 +2315,7 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
         COMMENT "Packing dSYM into ${VIEWER_SYMBOL_FILE}"
         )
       add_custom_target(dsym_tarball DEPENDS "${VIEWER_SYMBOL_FILE}")
+      buildscripts_block(dsym_tarball)
       add_dependencies(dsym_tarball dsym_generate)
       add_custom_command(OUTPUT "${VIEWER_APP_XCARCHIVE}"
         COMMAND "zip"
@@ -2337,6 +2343,7 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
         "${VIEWER_APP_XCARCHIVE}"
         "${CMAKE_CURRENT_BINARY_DIR}/dsym.stamp"
         )
+      buildscripts_block(generate_symbols)
       add_dependencies(generate_symbols dsym_tarball dsym_xcarchive)
     endif (DARWIN)
     if (LINUX)
diff --git a/indra/test/CMakeLists.txt b/indra/test/CMakeLists.txt
index 8344cead57..11ec2226ea 100644
--- a/indra/test/CMakeLists.txt
+++ b/indra/test/CMakeLists.txt
@@ -81,6 +81,7 @@ set_source_files_properties(${test_HEADER_FILES}
 list(APPEND test_SOURCE_FILES ${test_HEADER_FILES})
 
 add_executable(lltest ${test_SOURCE_FILES})
+buildscripts_block(lltest)
 
 target_link_libraries(lltest
     ${LLDATABASE_LIBRARIES}
diff --git a/indra/viewer_components/login/CMakeLists.txt b/indra/viewer_components/login/CMakeLists.txt
index 3bedeb7292..79706e0df4 100644
--- a/indra/viewer_components/login/CMakeLists.txt
+++ b/indra/viewer_components/login/CMakeLists.txt
@@ -42,6 +42,7 @@ list(APPEND
 add_library(lllogin 
             ${login_SOURCE_FILES}
             )
+buildscripts_block(lllogin)
 
 target_link_libraries(lllogin
     ${LLMESSAGE_LIBRARIES}
diff --git a/indra/win_crash_logger/CMakeLists.txt b/indra/win_crash_logger/CMakeLists.txt
index 144d037a31..9d651fcbc9 100644
--- a/indra/win_crash_logger/CMakeLists.txt
+++ b/indra/win_crash_logger/CMakeLists.txt
@@ -71,6 +71,7 @@ list(APPEND
 find_library(DXGUID_LIBRARY dxguid ${DIRECTX_LIBRARY_DIR})
 
 add_executable(windows-crash-logger WIN32 ${win_crash_logger_SOURCE_FILES})
+buildscripts_block(windows-crash-logger)
 
 target_link_libraries(windows-crash-logger
     ${BREAKPAD_EXCEPTION_HANDLER_LIBRARIES}
-- 
cgit v1.2.3


From bf8f467b02ac5669a59de7b21c693adf816452a3 Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Thu, 6 Sep 2018 10:40:59 -0400
Subject: modify the path command progress message to show fully resolved src
 and dst paths

---
 indra/lib/python/indra/util/llmanifest.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/lib/python/indra/util/llmanifest.py b/indra/lib/python/indra/util/llmanifest.py
index c4dcad51b7..d51718c0a7 100755
--- a/indra/lib/python/indra/util/llmanifest.py
+++ b/indra/lib/python/indra/util/llmanifest.py
@@ -775,13 +775,13 @@ class LLManifest(object):
         return self.path(os.path.join(path, file), file)
 
     def path(self, src, dst=None):
-        sys.stdout.write("Processing %s => %s ... " % (src, dst))
         sys.stdout.flush()
         if src == None:
             raise ManifestError("No source file, dst is " + dst)
         if dst == None:
             dst = src
         dst = os.path.join(self.get_dst_prefix(), dst)
+        sys.stdout.write("Processing %s => %s ... " % (src, dst))
 
         def try_path(src):
             # expand globs
-- 
cgit v1.2.3


From 8725d8e34a0f843860aea1678796c659f9b5f1ef Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Thu, 6 Sep 2018 11:08:33 -0400
Subject: improve error message for unfound files

---
 indra/lib/python/indra/util/llmanifest.py | 26 ++++++++++++--------------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/indra/lib/python/indra/util/llmanifest.py b/indra/lib/python/indra/util/llmanifest.py
index d51718c0a7..6919419953 100755
--- a/indra/lib/python/indra/util/llmanifest.py
+++ b/indra/lib/python/indra/util/llmanifest.py
@@ -50,7 +50,9 @@ class ManifestError(RuntimeError):
 
 class MissingError(ManifestError):
     """You specified a file that doesn't exist"""
-    pass
+    def __init__(self, msg):
+        self.msg = msg
+        super(MissingError, self).__init__(self.msg)
 
 def path_ancestors(path):
     drive, path = os.path.splitdrive(os.path.normpath(path))
@@ -801,22 +803,18 @@ class LLManifest(object):
                     count += self.process_file(src, dst)
             return count
 
-        for pfx in self.get_src_prefix(), self.get_artwork_prefix(), self.get_build_prefix():
+        try_prefixes = [self.get_src_prefix(), self.get_artwork_prefix(), self.get_build_prefix()]
+        tried=[]
+        count=0
+        while not count and try_prefixes: 
+            pfx = try_prefixes.pop(0)
             try:
                 count = try_path(os.path.join(pfx, src))
             except MissingError:
-                # If src isn't a wildcard, and if that file doesn't exist in
-                # this pfx, try next pfx.
-                count = 0
-                continue
-
-            # Here try_path() didn't raise MissingError. Did it process any files?
-            if count:
-                break
-            # Even though try_path() didn't raise MissingError, it returned 0
-            # files. src is probably a wildcard meant for some other pfx. Loop
-            # back to try the next.
-
+                tried.append(pfx)
+                if not try_prefixes:
+                    # no more prefixes left to try
+                    print "unable to find '%s'; looked in:\n  %s" % (src, '\n  '.join(tried))
         print "%d files" % count
 
         # Let caller check whether we processed as many files as expected. In
-- 
cgit v1.2.3


From 10f2101515fe8ba230848cce41faaf7613c9b6d8 Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Thu, 6 Sep 2018 14:32:15 -0400
Subject: make the .app name channel sensitive to match cmake

---
 indra/newview/viewer_manifest.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index aa03780e19..464f7aa3e9 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -910,7 +910,8 @@ class DarwinManifest(ViewerManifest):
         # applications for the VMP and for the actual viewer, respectively.
         # These names, without the .app suffix, determine the flyover text for
         # their corresponding Dock icons.
-        toplevel_app, toplevel_icon = "Second Life.app",          "secondlife.icns"
+        toplevel_app = self.channel()+".app" 
+        toplevel_icon = "secondlife.icns"
         launcher_app, launcher_icon = "Second Life Launcher.app", "secondlife.icns"
         viewer_app,   viewer_icon   = "Second Life Viewer.app",   "secondlife.icns"
 
-- 
cgit v1.2.3


From fa1ad3f4df766e6047c2e819a97261400cd3ab7f Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Thu, 6 Sep 2018 15:15:16 -0400
Subject: make start and end messages for packages more prominentt

---
 indra/lib/python/indra/util/llmanifest.py | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/indra/lib/python/indra/util/llmanifest.py b/indra/lib/python/indra/util/llmanifest.py
index 6919419953..9ab77414be 100755
--- a/indra/lib/python/indra/util/llmanifest.py
+++ b/indra/lib/python/indra/util/llmanifest.py
@@ -245,13 +245,13 @@ def main(extra=[]):
     # Build base package.
     touch = args.get('touch')
     if touch:
-        print 'Creating base package'
+        print '================ Creating base package'
     wm = LLManifest.for_platform(args['platform'], args.get('arch'))(args)
     wm.do(*args['actions'])
     # Store package file for later if making touched file.
     base_package_file = ""
     if touch:
-        print 'Created base package ', wm.package_file
+        print '================ Created base package ', wm.package_file
         base_package_file = "" + wm.package_file
 
     # handle multiple packages if set
@@ -279,14 +279,14 @@ def main(extra=[]):
             args['sourceid']       = os.environ.get(package_id + "_sourceid")
             args['dest'] = base_dest_template.format(package_id)
             if touch:
-                print 'Creating additional package for "', package_id, '" in ', args['dest']
+                print '================ Creating additional package for "', package_id, '" in ', args['dest']
             try:
                 wm = LLManifest.for_platform(args['platform'], args.get('arch'))(args)
                 wm.do(*args['actions'])
             except Exception as err:
                 sys.exit(str(err))
             if touch:
-                print 'Created additional package ', wm.package_file, ' for ', package_id
+                print '================ Created additional package ', wm.package_file, ' for ', package_id
                 with open(base_touch_template.format(package_id), 'w') as fp:
                     fp.write('set package_file=%s\n' % wm.package_file)
     
-- 
cgit v1.2.3


From 050f9ead3b7509a5a03cb41492386414db15e5e0 Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Thu, 6 Sep 2018 15:57:25 -0400
Subject: add markers for non-package uses of viewer_manifest.py

---
 indra/lib/python/indra/util/llmanifest.py | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/indra/lib/python/indra/util/llmanifest.py b/indra/lib/python/indra/util/llmanifest.py
index 9ab77414be..8904e72440 100755
--- a/indra/lib/python/indra/util/llmanifest.py
+++ b/indra/lib/python/indra/util/llmanifest.py
@@ -246,6 +246,8 @@ def main(extra=[]):
     touch = args.get('touch')
     if touch:
         print '================ Creating base package'
+    else:
+        print '================ Starting base copy'
     wm = LLManifest.for_platform(args['platform'], args.get('arch'))(args)
     wm.do(*args['actions'])
     # Store package file for later if making touched file.
@@ -253,6 +255,8 @@ def main(extra=[]):
     if touch:
         print '================ Created base package ', wm.package_file
         base_package_file = "" + wm.package_file
+    else:
+        print '================ Finished base copy'
 
     # handle multiple packages if set
     # ''.split() produces empty list
@@ -280,6 +284,8 @@ def main(extra=[]):
             args['dest'] = base_dest_template.format(package_id)
             if touch:
                 print '================ Creating additional package for "', package_id, '" in ', args['dest']
+            else:
+                print '================ Starting additional copy for "', package_id, '" in ', args['dest']
             try:
                 wm = LLManifest.for_platform(args['platform'], args.get('arch'))(args)
                 wm.do(*args['actions'])
@@ -289,7 +295,8 @@ def main(extra=[]):
                 print '================ Created additional package ', wm.package_file, ' for ', package_id
                 with open(base_touch_template.format(package_id), 'w') as fp:
                     fp.write('set package_file=%s\n' % wm.package_file)
-    
+            else:
+                print '================ Finished additional copy "', package_id, '" in ', args['dest']
     # Write out the package file in this format, so that it can easily be called
     # and used in a .bat file - yeah, it sucks, but this is the simplest...
     if touch:
-- 
cgit v1.2.3


From fac16e53f6b806245b16229b53eb325a5875fc59 Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Fri, 7 Sep 2018 08:30:21 -0400
Subject: refine TeamCity blocks to avoid double nesting, and disable

for Windows
---
 indra/cmake/00-Common.cmake | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
index 24f6329d10..503f4208fe 100644
--- a/indra/cmake/00-Common.cmake
+++ b/indra/cmake/00-Common.cmake
@@ -219,22 +219,24 @@ endif (USESYSTEMLIBS)
 
 macro (buildscripts_block target_name)
     # add custom commands to bracket a target build to make logs easier to read
-
-    if (DEFINED ENV{TEAMCITY_BUILDCONF_NAME})
+    # this is disabled for windows because VS interleaves output in a way that defeats it
+    if (NOT WINDOWS AND DEFINED ENV{TEAMCITY_BUILDCONF_NAME})
         add_custom_command(TARGET ${target_name} PRE_BUILD
-            COMMAND echo ARGS "##teamcity[blockOpened name='${target_name}']" VERBATIM
+            COMMAND echo ARGS "-n" "##"
+            COMMAND echo ARGS "teamcity[blockOpened name='${target_name}']" 
             )
         add_custom_command(TARGET ${target_name} POST_BUILD
-            COMMAND echo ARGS "##teamcity[blockClosed name='${target_name}']" VERBATIM
+            COMMAND echo ARGS "-n" "##"
+            COMMAND echo ARGS "teamcity[blockClosed name='${target_name}']"
             )
-    else (DEFINED ENV{TEAMCITY_BUILDCONF_NAME})
+    else (NOT WINDOWS AND DEFINED ENV{TEAMCITY_BUILDCONF_NAME})
         add_custom_command(TARGET ${target_name} PRE_BUILD
-            COMMAND echo ARGS "################## START ${target_name}" VERBATIM
+            COMMAND echo ARGS "################## START ${target_name}"
             )
         add_custom_command(TARGET ${target_name} POST_BUILD
-            COMMAND echo ARGS "################## FINISH ${target_name}" VERBATIM
+            COMMAND echo ARGS "################## FINISH ${target_name}"
             )
-    endif (DEFINED ENV{TEAMCITY_BUILDCONF_NAME})
+    endif (NOT WINDOWS AND DEFINED ENV{TEAMCITY_BUILDCONF_NAME})
 
 endmacro (buildscripts_block target_name)
 
-- 
cgit v1.2.3


From 9f27bff9fb82aa56fd61f95dc57fca1e119ef767 Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Fri, 7 Sep 2018 11:58:11 -0400
Subject: make the path output strip the 'dest' prefix

---
 indra/lib/python/indra/util/llmanifest.py | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/indra/lib/python/indra/util/llmanifest.py b/indra/lib/python/indra/util/llmanifest.py
index 8904e72440..9569014a47 100755
--- a/indra/lib/python/indra/util/llmanifest.py
+++ b/indra/lib/python/indra/util/llmanifest.py
@@ -500,6 +500,19 @@ class LLManifest(object):
         relative to the destination directory."""
         return os.path.join(self.get_dst_prefix(), relpath)
 
+    def _relative_dst_path(self, dstpath):
+        """
+        Returns the path to a file or directory relative to the destination directory.
+        This should only be used for generating diagnostic output in the path method.
+        """
+        dest_root=self.dst_prefix[0]
+        if dstpath.startswith(dest_root+os.path.sep):
+            return dstpath[len(dest_root)+1:]
+        elif dstpath.startswith(dest_root):
+            return dstpath[len(dest_root):]
+        else:
+            return dstpath
+
     def ensure_src_dir(self, reldir):
         """Construct the path for a directory relative to the
         source path, and ensures that it exists.  Returns the
@@ -790,7 +803,7 @@ class LLManifest(object):
         if dst == None:
             dst = src
         dst = os.path.join(self.get_dst_prefix(), dst)
-        sys.stdout.write("Processing %s => %s ... " % (src, dst))
+        sys.stdout.write("Processing %s => %s ... " % (src, self._relative_dst_path(dst)))
 
         def try_path(src):
             # expand globs
-- 
cgit v1.2.3


From 9fd463bd9496ba5d97abec6ee75b9c0c089aa69d Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Fri, 7 Sep 2018 09:13:57 -0400
Subject: remove only-partially-successful attempt to put teamcity blocks
 around targets

---
 indra/CMakeLists.txt                               |  1 -
 indra/cmake/00-Common.cmake                        | 23 ----------------------
 indra/cmake/LLAddBuildTest.cmake                   |  3 ---
 .../llimage_libtest/CMakeLists.txt                 |  1 -
 .../integration_tests/llui_libtest/CMakeLists.txt  |  1 -
 indra/linux_crash_logger/CMakeLists.txt            |  2 --
 indra/llappearance/CMakeLists.txt                  |  2 --
 indra/llaudio/CMakeLists.txt                       |  1 -
 indra/llcharacter/CMakeLists.txt                   |  1 -
 indra/llcommon/CMakeLists.txt                      |  2 --
 indra/llcorehttp/CMakeLists.txt                    |  2 --
 indra/llcrashlogger/CMakeLists.txt                 |  1 -
 indra/llimage/CMakeLists.txt                       |  1 -
 indra/llimagej2coj/CMakeLists.txt                  |  1 -
 indra/llinventory/CMakeLists.txt                   |  1 -
 indra/llkdu/CMakeLists.txt                         |  1 -
 indra/llmath/CMakeLists.txt                        |  1 -
 indra/llmessage/CMakeLists.txt                     |  1 -
 indra/llplugin/CMakeLists.txt                      |  1 -
 indra/llplugin/slplugin/CMakeLists.txt             |  1 -
 indra/llprimitive/CMakeLists.txt                   |  1 -
 indra/llrender/CMakeLists.txt                      |  2 --
 indra/llui/CMakeLists.txt                          |  1 -
 indra/llvfs/CMakeLists.txt                         |  1 -
 indra/llwindow/CMakeLists.txt                      |  2 --
 indra/llxml/CMakeLists.txt                         |  1 -
 indra/mac_crash_logger/CMakeLists.txt              |  1 -
 indra/media_plugins/base/CMakeLists.txt            |  1 -
 indra/media_plugins/cef/CMakeLists.txt             |  1 -
 indra/media_plugins/example/CMakeLists.txt         |  1 -
 indra/media_plugins/gstreamer010/CMakeLists.txt    |  1 -
 indra/media_plugins/libvlc/CMakeLists.txt          |  1 -
 indra/newview/CMakeLists.txt                       |  7 -------
 indra/test/CMakeLists.txt                          |  1 -
 indra/viewer_components/login/CMakeLists.txt       |  1 -
 indra/win_crash_logger/CMakeLists.txt              |  1 -
 36 files changed, 72 deletions(-)

diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt
index 08d0c7b510..6c20a813ba 100644
--- a/indra/CMakeLists.txt
+++ b/indra/CMakeLists.txt
@@ -44,7 +44,6 @@ if (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts)
 endif (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts)
 
 add_custom_target(viewer)
-buildscripts_block(viewer)
 
 add_subdirectory(${LIBS_OPEN_PREFIX}llcrashlogger)
 add_subdirectory(${LIBS_OPEN_PREFIX}llplugin)
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
index 503f4208fe..40fc706a99 100644
--- a/indra/cmake/00-Common.cmake
+++ b/indra/cmake/00-Common.cmake
@@ -217,27 +217,4 @@ else (USESYSTEMLIBS)
       )
 endif (USESYSTEMLIBS)
 
-macro (buildscripts_block target_name)
-    # add custom commands to bracket a target build to make logs easier to read
-    # this is disabled for windows because VS interleaves output in a way that defeats it
-    if (NOT WINDOWS AND DEFINED ENV{TEAMCITY_BUILDCONF_NAME})
-        add_custom_command(TARGET ${target_name} PRE_BUILD
-            COMMAND echo ARGS "-n" "##"
-            COMMAND echo ARGS "teamcity[blockOpened name='${target_name}']" 
-            )
-        add_custom_command(TARGET ${target_name} POST_BUILD
-            COMMAND echo ARGS "-n" "##"
-            COMMAND echo ARGS "teamcity[blockClosed name='${target_name}']"
-            )
-    else (NOT WINDOWS AND DEFINED ENV{TEAMCITY_BUILDCONF_NAME})
-        add_custom_command(TARGET ${target_name} PRE_BUILD
-            COMMAND echo ARGS "################## START ${target_name}"
-            )
-        add_custom_command(TARGET ${target_name} POST_BUILD
-            COMMAND echo ARGS "################## FINISH ${target_name}"
-            )
-    endif (NOT WINDOWS AND DEFINED ENV{TEAMCITY_BUILDCONF_NAME})
-
-endmacro (buildscripts_block target_name)
-
 endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake
index 3b5bc0af7c..b3f42c1a5e 100644
--- a/indra/cmake/LLAddBuildTest.cmake
+++ b/indra/cmake/LLAddBuildTest.cmake
@@ -105,7 +105,6 @@ INCLUDE(GoogleMock)
 
     # Setup target
     ADD_EXECUTABLE(PROJECT_${project}_TEST_${name} ${${name}_test_SOURCE_FILES})
-    buildscripts_block(PROJECT_${project}_TEST_${name})
     SET_TARGET_PROPERTIES(PROJECT_${project}_TEST_${name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}")
 
     #
@@ -167,7 +166,6 @@ INCLUDE(GoogleMock)
   # Add the test runner target per-project
   # (replaces old _test_ok targets all over the place)
   ADD_CUSTOM_TARGET(${project}_tests ALL DEPENDS ${${project}_TEST_OUTPUT})
-  buildscripts_block(${project}_tests)
   ADD_DEPENDENCIES(${project} ${project}_tests)
 ENDMACRO(LL_ADD_PROJECT_UNIT_TESTS)
 
@@ -215,7 +213,6 @@ FUNCTION(LL_ADD_INTEGRATION_TEST
     message(STATUS "ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files})")
   endif(TEST_DEBUG)
   ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files})
-  buildscripts_block(INTEGRATION_TEST_${testname})
   SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname}
     PROPERTIES
     RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}"
diff --git a/indra/integration_tests/llimage_libtest/CMakeLists.txt b/indra/integration_tests/llimage_libtest/CMakeLists.txt
index 4e23a1fc87..d9353f904c 100644
--- a/indra/integration_tests/llimage_libtest/CMakeLists.txt
+++ b/indra/integration_tests/llimage_libtest/CMakeLists.txt
@@ -41,7 +41,6 @@ add_executable(llimage_libtest
     MACOSX_BUNDLE
     ${llimage_libtest_SOURCE_FILES}
     )
-buildscripts_block(llimage_libtest)
 
 set_target_properties(llimage_libtest
     PROPERTIES
diff --git a/indra/integration_tests/llui_libtest/CMakeLists.txt b/indra/integration_tests/llui_libtest/CMakeLists.txt
index 2d21f9af0f..34e34c7e47 100644
--- a/indra/integration_tests/llui_libtest/CMakeLists.txt
+++ b/indra/integration_tests/llui_libtest/CMakeLists.txt
@@ -56,7 +56,6 @@ set_source_files_properties(${llui_libtest_HEADER_FILES}
 list(APPEND llui_libtest_SOURCE_FILES ${llui_libtest_HEADER_FILES})
 
 add_executable(llui_libtest ${llui_libtest_SOURCE_FILES})
-buildscripts_block(llui_libtest)
 
 # Link with OS-specific libraries for LLWindow dependency
 if (DARWIN)
diff --git a/indra/linux_crash_logger/CMakeLists.txt b/indra/linux_crash_logger/CMakeLists.txt
index 165b33fede..315aed8d11 100644
--- a/indra/linux_crash_logger/CMakeLists.txt
+++ b/indra/linux_crash_logger/CMakeLists.txt
@@ -55,7 +55,6 @@ list(APPEND linux_crash_logger_SOURCE_FILES
 set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed")
 
 add_executable(linux-crash-logger ${linux_crash_logger_SOURCE_FILES})
-buildscripts_block(linux-crash-logger)
 
 # llcommon uses `clock_gettime' which is provided by librt on linux.
 set(LIBRT_LIBRARY rt)
@@ -80,4 +79,3 @@ target_link_libraries(linux-crash-logger
 
 add_custom_target(linux-crash-logger-target ALL
     DEPENDS linux-crash-logger)
-buildscripts_block(linux-crash-logger-target)
diff --git a/indra/llappearance/CMakeLists.txt b/indra/llappearance/CMakeLists.txt
index ad33fed010..20eb4678dd 100644
--- a/indra/llappearance/CMakeLists.txt
+++ b/indra/llappearance/CMakeLists.txt
@@ -77,7 +77,6 @@ set_source_files_properties(${llappearance_HEADER_FILES}
 list(APPEND llappearance_SOURCE_FILES ${llappearance_HEADER_FILES})
 
 add_library (llappearance ${llappearance_SOURCE_FILES})
-buildscripts_block(llappearance)
 
 target_link_libraries(llappearance
     ${LLCHARACTER_LIBRARIES}
@@ -95,7 +94,6 @@ target_link_libraries(llappearance
 
 if (BUILD_HEADLESS)
   add_library (llappearanceheadless ${llappearance_SOURCE_FILES})
-  buildscripts_block(llappearanceheadless)
   
   target_link_libraries(llappearanceheadless
       ${LLCHARACTER_LIBRARIES}
diff --git a/indra/llaudio/CMakeLists.txt b/indra/llaudio/CMakeLists.txt
index fc81d8c6f2..e943dd5d5c 100644
--- a/indra/llaudio/CMakeLists.txt
+++ b/indra/llaudio/CMakeLists.txt
@@ -77,7 +77,6 @@ set_source_files_properties(${llaudio_HEADER_FILES}
 list(APPEND llaudio_SOURCE_FILES ${llaudio_HEADER_FILES})
 
 add_library (llaudio ${llaudio_SOURCE_FILES})
-buildscripts_block(llaudio)
 target_link_libraries(
     llaudio
     ${LLCOMMON_LIBRARIES}
diff --git a/indra/llcharacter/CMakeLists.txt b/indra/llcharacter/CMakeLists.txt
index 3d0eb09ada..a17a5b0aa6 100644
--- a/indra/llcharacter/CMakeLists.txt
+++ b/indra/llcharacter/CMakeLists.txt
@@ -79,7 +79,6 @@ set_source_files_properties(${llcharacter_HEADER_FILES}
 list(APPEND llcharacter_SOURCE_FILES ${llcharacter_HEADER_FILES})
 
 add_library (llcharacter ${llcharacter_SOURCE_FILES})
-buildscripts_block(llcharacter)
 
 target_link_libraries(
     llcharacter
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 0d58a59e3f..42ad56f1b0 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -24,7 +24,6 @@ include_directories(
     )
 
 # add_executable(lltreeiterators lltreeiterators.cpp)
-# buildscripts_block(lltreeiterators)
 # 
 # target_link_libraries(lltreeiterators
 #     ${LLCOMMON_LIBRARIES})
@@ -280,7 +279,6 @@ if(LLCOMMON_LINK_SHARED)
 else(LLCOMMON_LINK_SHARED)
     add_library (llcommon ${llcommon_SOURCE_FILES})
 endif(LLCOMMON_LINK_SHARED)
-buildscripts_block(llcommon)
 
 target_link_libraries(
     llcommon
diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt
index c42bd7b6b2..9dbc6f447e 100644
--- a/indra/llcorehttp/CMakeLists.txt
+++ b/indra/llcorehttp/CMakeLists.txt
@@ -90,7 +90,6 @@ endif (DARWIN OR LINUX)
 list(APPEND llcorehttp_SOURCE_FILES ${llcorehttp_HEADER_FILES})
 
 add_library (llcorehttp ${llcorehttp_SOURCE_FILES})
-buildscripts_block(llcorehttp)
 target_link_libraries(
   llcorehttp
   ${CURL_LIBRARIES}
@@ -215,7 +214,6 @@ endif (DARWIN)
   add_executable(http_texture_load
                  ${llcorehttp_EXAMPLE_SOURCE_FILES}
                  )
-  buildscripts_block(http_texture_load)
   set_target_properties(http_texture_load
                         PROPERTIES
                         RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}"
diff --git a/indra/llcrashlogger/CMakeLists.txt b/indra/llcrashlogger/CMakeLists.txt
index 7d7f3f0167..da23b46b7b 100644
--- a/indra/llcrashlogger/CMakeLists.txt
+++ b/indra/llcrashlogger/CMakeLists.txt
@@ -41,4 +41,3 @@ set_source_files_properties(${llcrashlogger_HEADER_FILES}
 list(APPEND llcrashlogger_SOURCE_FILES ${llcrashlogger_HEADER_FILES})
 
 add_library(llcrashlogger ${llcrashlogger_SOURCE_FILES})
-buildscripts_block(llcrashlogger)
diff --git a/indra/llimage/CMakeLists.txt b/indra/llimage/CMakeLists.txt
index 4b57a77999..293ada7548 100644
--- a/indra/llimage/CMakeLists.txt
+++ b/indra/llimage/CMakeLists.txt
@@ -59,7 +59,6 @@ set_source_files_properties(${llimage_HEADER_FILES}
 list(APPEND llimage_SOURCE_FILES ${llimage_HEADER_FILES})
 
 add_library (llimage ${llimage_SOURCE_FILES})
-buildscripts_block(llimage)
 # Libraries on which this library depends, needed for Linux builds
 # Sort by high-level to low-level
 if (USE_KDU)
diff --git a/indra/llimagej2coj/CMakeLists.txt b/indra/llimagej2coj/CMakeLists.txt
index f05842b721..c9423d50dd 100644
--- a/indra/llimagej2coj/CMakeLists.txt
+++ b/indra/llimagej2coj/CMakeLists.txt
@@ -29,7 +29,6 @@ set_source_files_properties(${llimagej2coj_HEADER_FILES}
 list(APPEND llimagej2coj_SOURCE_FILES ${llimagej2coj_HEADER_FILES})
 
 add_library (llimagej2coj ${llimagej2coj_SOURCE_FILES})
-buildscripts_block(llimagej2coj)
 
 target_link_libraries(
     llimagej2coj
diff --git a/indra/llinventory/CMakeLists.txt b/indra/llinventory/CMakeLists.txt
index 6a5892127d..68dd00d880 100644
--- a/indra/llinventory/CMakeLists.txt
+++ b/indra/llinventory/CMakeLists.txt
@@ -60,7 +60,6 @@ set_source_files_properties(${llinventory_HEADER_FILES}
 list(APPEND llinventory_SOURCE_FILES ${llinventory_HEADER_FILES})
 
 add_library (llinventory ${llinventory_SOURCE_FILES})
-buildscripts_block(llinventory)
 
 
 
diff --git a/indra/llkdu/CMakeLists.txt b/indra/llkdu/CMakeLists.txt
index 59f6d08517..cb0e204e91 100644
--- a/indra/llkdu/CMakeLists.txt
+++ b/indra/llkdu/CMakeLists.txt
@@ -50,7 +50,6 @@ set_source_files_properties(${llkdu_SOURCE_FILES}
 
 if (USE_KDU)
   add_library (llkdu ${llkdu_SOURCE_FILES})
-  buildscripts_block(llkdu)
 
   target_link_libraries(llkdu
     ${KDU_LIBRARY})
diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt
index 110173add3..4c8bcdac91 100644
--- a/indra/llmath/CMakeLists.txt
+++ b/indra/llmath/CMakeLists.txt
@@ -101,7 +101,6 @@ set_source_files_properties(${llmath_HEADER_FILES}
 list(APPEND llmath_SOURCE_FILES ${llmath_HEADER_FILES})
 
 add_library (llmath ${llmath_SOURCE_FILES})
-buildscripts_block(llmath)
 
 target_link_libraries(llmath
     ${LLCOMMON_LIBRARIES}
diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt
index ab59c8bb40..e0922c0667 100644
--- a/indra/llmessage/CMakeLists.txt
+++ b/indra/llmessage/CMakeLists.txt
@@ -203,7 +203,6 @@ set_source_files_properties(${llmessage_HEADER_FILES}
 list(APPEND llmessage_SOURCE_FILES ${llmessage_HEADER_FILES})
 
 add_library (llmessage ${llmessage_SOURCE_FILES})
-buildscripts_block(llmessage)
 
 if (LINUX)
 target_link_libraries(
diff --git a/indra/llplugin/CMakeLists.txt b/indra/llplugin/CMakeLists.txt
index 9d79eabbb3..5cc129a267 100644
--- a/indra/llplugin/CMakeLists.txt
+++ b/indra/llplugin/CMakeLists.txt
@@ -65,7 +65,6 @@ endif(NOT ADDRESS_SIZE EQUAL 32)
 list(APPEND llplugin_SOURCE_FILES ${llplugin_HEADER_FILES})
 
 add_library (llplugin ${llplugin_SOURCE_FILES})
-buildscripts_block(llplugin)
 
 add_subdirectory(slplugin)
 
diff --git a/indra/llplugin/slplugin/CMakeLists.txt b/indra/llplugin/slplugin/CMakeLists.txt
index 3a9d661ff6..33520ad64c 100644
--- a/indra/llplugin/slplugin/CMakeLists.txt
+++ b/indra/llplugin/slplugin/CMakeLists.txt
@@ -49,7 +49,6 @@ add_executable(SLPlugin
     MACOSX_BUNDLE
     ${SLPlugin_SOURCE_FILES}
     )
-buildscripts_block(SLPlugin)
 
 if (WINDOWS)
 set_target_properties(SLPlugin
diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt
index 12c6882844..dd2e806dda 100644
--- a/indra/llprimitive/CMakeLists.txt
+++ b/indra/llprimitive/CMakeLists.txt
@@ -71,7 +71,6 @@ set_source_files_properties(${llprimitive_HEADER_FILES}
 list(APPEND llprimitive_SOURCE_FILES ${llprimitive_HEADER_FILES})
 
 add_library (llprimitive ${llprimitive_SOURCE_FILES})
-buildscripts_block(llprimitive)
 
 target_link_libraries(llprimitive
     ${LLCOMMON_LIBRARIES}
diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt
index de5f24758c..07a0d8c402 100644
--- a/indra/llrender/CMakeLists.txt
+++ b/indra/llrender/CMakeLists.txt
@@ -91,7 +91,6 @@ if (BUILD_HEADLESS)
   add_library (llrenderheadless
     ${llrender_SOURCE_FILES}
     )
-  buildscripts_block(llrenderheadless)
 
   set_property(TARGET llrenderheadless
     PROPERTY COMPILE_DEFINITIONS LL_MESA=1 LL_MESA_HEADLESS=1
@@ -111,7 +110,6 @@ if (BUILD_HEADLESS)
 endif (BUILD_HEADLESS)
 
 add_library (llrender ${llrender_SOURCE_FILES})
-buildscripts_block(llrender)
 
 if (SDL_FOUND)
   set_property(TARGET llrender
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index 41a79d5752..8054eb3619 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -269,7 +269,6 @@ set_source_files_properties(llurlentry.cpp
 list(APPEND llui_SOURCE_FILES ${llui_HEADER_FILES})
 
 add_library (llui ${llui_SOURCE_FILES})
-buildscripts_block(llui)
 # Libraries on which this library depends, needed for Linux builds
 # Sort by high-level to low-level
 target_link_libraries(llui
diff --git a/indra/llvfs/CMakeLists.txt b/indra/llvfs/CMakeLists.txt
index a9d602d333..67dce8c073 100644
--- a/indra/llvfs/CMakeLists.txt
+++ b/indra/llvfs/CMakeLists.txt
@@ -64,7 +64,6 @@ set_source_files_properties(${llvfs_HEADER_FILES}
 list(APPEND llvfs_SOURCE_FILES ${llvfs_HEADER_FILES})
 
 add_library (llvfs ${llvfs_SOURCE_FILES})
-buildscripts_block(llvfs)
 
 set(vfs_BOOST_LIBRARIES
     ${BOOST_FILESYSTEM_LIBRARY}
diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt
index d7ab3bfebb..0743fd899f 100644
--- a/indra/llwindow/CMakeLists.txt
+++ b/indra/llwindow/CMakeLists.txt
@@ -175,7 +175,6 @@ if (BUILD_HEADLESS)
     ${llwindow_SOURCE_FILES}
     ${llwindowheadless_SOURCE_FILES}
     )
-  buildscripts_block(llwindowheadless)
   set_property(TARGET llwindowheadless
     PROPERTY COMPILE_DEFINITIONS LL_MESA=1 LL_MESA_HEADLESS=1
     )
@@ -192,7 +191,6 @@ endif (llwindow_HEADER_FILES)
     ${llwindow_SOURCE_FILES}
     ${viewer_SOURCE_FILES}
     )
-  buildscripts_block(llwindow)
 
 if (SDL_FOUND)
   set_property(TARGET llwindow
diff --git a/indra/llxml/CMakeLists.txt b/indra/llxml/CMakeLists.txt
index cb2d0f5c76..17400a203e 100644
--- a/indra/llxml/CMakeLists.txt
+++ b/indra/llxml/CMakeLists.txt
@@ -40,7 +40,6 @@ set_source_files_properties(${llxml_HEADER_FILES}
 list(APPEND llxml_SOURCE_FILES ${llxml_HEADER_FILES})
 
 add_library (llxml ${llxml_SOURCE_FILES})
-buildscripts_block(llxml)
 # Libraries on which this library depends, needed for Linux builds
 # Sort by high-level to low-level
 target_link_libraries( llxml
diff --git a/indra/mac_crash_logger/CMakeLists.txt b/indra/mac_crash_logger/CMakeLists.txt
index f62bab5673..f6c4dfb59d 100644
--- a/indra/mac_crash_logger/CMakeLists.txt
+++ b/indra/mac_crash_logger/CMakeLists.txt
@@ -58,7 +58,6 @@ list(APPEND mac_crash_logger_SOURCE_FILES ${mac_crash_logger_RESOURCE_FILES})
 add_executable(mac-crash-logger
   MACOSX_BUNDLE
   ${mac_crash_logger_SOURCE_FILES})
-buildscripts_block(mac-crash-logger)
 
 set_target_properties(mac-crash-logger
   PROPERTIES
diff --git a/indra/media_plugins/base/CMakeLists.txt b/indra/media_plugins/base/CMakeLists.txt
index 8ab535e14c..7f2b82ffdd 100644
--- a/indra/media_plugins/base/CMakeLists.txt
+++ b/indra/media_plugins/base/CMakeLists.txt
@@ -49,5 +49,4 @@ set(media_plugin_base_HEADER_FILES
 add_library(media_plugin_base
     ${media_plugin_base_SOURCE_FILES}
     )
-buildscripts_block(media_plugin_base)
 
diff --git a/indra/media_plugins/cef/CMakeLists.txt b/indra/media_plugins/cef/CMakeLists.txt
index dedc47e341..ce6278963d 100644
--- a/indra/media_plugins/cef/CMakeLists.txt
+++ b/indra/media_plugins/cef/CMakeLists.txt
@@ -82,7 +82,6 @@ add_library(media_plugin_cef
     SHARED
     ${media_plugin_cef_SOURCE_FILES}
     )
-buildscripts_block(media_plugin_cef)
 
 #add_dependencies(media_plugin_cef
 #  ${MEDIA_PLUGIN_BASE_LIBRARIES}
diff --git a/indra/media_plugins/example/CMakeLists.txt b/indra/media_plugins/example/CMakeLists.txt
index 95d3d5b5a2..eb067a7f6e 100644
--- a/indra/media_plugins/example/CMakeLists.txt
+++ b/indra/media_plugins/example/CMakeLists.txt
@@ -48,7 +48,6 @@ add_library(media_plugin_example
     SHARED
     ${media_plugin_example_SOURCE_FILES}
     )
-buildscripts_block(media_plugin_example)
 
 target_link_libraries(media_plugin_example
   ${LLPLUGIN_LIBRARIES}
diff --git a/indra/media_plugins/gstreamer010/CMakeLists.txt b/indra/media_plugins/gstreamer010/CMakeLists.txt
index 18b4b761cf..571eb57b24 100644
--- a/indra/media_plugins/gstreamer010/CMakeLists.txt
+++ b/indra/media_plugins/gstreamer010/CMakeLists.txt
@@ -57,7 +57,6 @@ add_library(media_plugin_gstreamer010
     SHARED
     ${media_plugin_gstreamer010_SOURCE_FILES}
     )
-buildscripts_block(media_plugin_gstreamer010)
 
 target_link_libraries(media_plugin_gstreamer010
   ${LLPLUGIN_LIBRARIES}
diff --git a/indra/media_plugins/libvlc/CMakeLists.txt b/indra/media_plugins/libvlc/CMakeLists.txt
index 7946e7ccfc..97392bbe08 100644
--- a/indra/media_plugins/libvlc/CMakeLists.txt
+++ b/indra/media_plugins/libvlc/CMakeLists.txt
@@ -49,7 +49,6 @@ add_library(media_plugin_libvlc
     SHARED
     ${media_plugin_libvlc_SOURCE_FILES}
     )
-buildscripts_block(media_plugin_libvlc)
 
 target_link_libraries(media_plugin_libvlc
   ${LLPLUGIN_LIBRARIES}
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 560c9d0737..e573b927d7 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1722,7 +1722,6 @@ add_executable(${VIEWER_BINARY_NAME}
     MACOSX_BUNDLE
     ${viewer_SOURCE_FILES}
     )
-buildscripts_block(${VIEWER_BINARY_NAME})
 
 if (SDL_FOUND)
   set_property(TARGET ${VIEWER_BINARY_NAME}
@@ -1915,7 +1914,6 @@ if (WINDOWS)
         ${CMAKE_CFG_INTDIR}/touched.bat
         windows-setup-build-all
         )
-      buildscripts_block(llpackage)
         # temporarily disable packaging of event_host until hg subrepos get
         # sorted out on the parabuild cluster...
         #${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/event_host.tar.bz2)
@@ -2255,7 +2253,6 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
           VERBATIM)
 
     add_custom_target(generate_symbols DEPENDS "${VIEWER_SYMBOL_FILE}" ${VIEWER_BINARY_NAME} "${VIEWER_COPY_MANIFEST}")
-    buildscripts_block(generate_symbols)
     add_dependencies(generate_symbols ${VIEWER_BINARY_NAME})
     if (WINDOWS OR LINUX)
       add_dependencies(generate_symbols "${VIEWER_COPY_MANIFEST}")
@@ -2288,7 +2285,6 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
         COMMENT "Packing viewer PDB into ${VIEWER_SYMBOL_FILE_CYGWIN}"
         )
       add_custom_target(generate_symbols DEPENDS "${VIEWER_SYMBOL_FILE}" ${VIEWER_BINARY_NAME})
-      buildscripts_block(generate_symbols)
       add_dependencies(generate_symbols ${VIEWER_BINARY_NAME})
     endif (WINDOWS)
     if (DARWIN)
@@ -2300,7 +2296,6 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
         COMMENT "Generating ${VIEWER_APP_DSYM}"
         )
       add_custom_target(dsym_generate DEPENDS "${VIEWER_APP_DSYM}")
-      buildscripts_block(dsym_generate)
       add_dependencies(dsym_generate ${VIEWER_BINARY_NAME})
       add_custom_command(OUTPUT "${VIEWER_SYMBOL_FILE}"
         # See above comments about "tar ...j"
@@ -2315,7 +2310,6 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
         COMMENT "Packing dSYM into ${VIEWER_SYMBOL_FILE}"
         )
       add_custom_target(dsym_tarball DEPENDS "${VIEWER_SYMBOL_FILE}")
-      buildscripts_block(dsym_tarball)
       add_dependencies(dsym_tarball dsym_generate)
       add_custom_command(OUTPUT "${VIEWER_APP_XCARCHIVE}"
         COMMAND "zip"
@@ -2343,7 +2337,6 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
         "${VIEWER_APP_XCARCHIVE}"
         "${CMAKE_CURRENT_BINARY_DIR}/dsym.stamp"
         )
-      buildscripts_block(generate_symbols)
       add_dependencies(generate_symbols dsym_tarball dsym_xcarchive)
     endif (DARWIN)
     if (LINUX)
diff --git a/indra/test/CMakeLists.txt b/indra/test/CMakeLists.txt
index 11ec2226ea..8344cead57 100644
--- a/indra/test/CMakeLists.txt
+++ b/indra/test/CMakeLists.txt
@@ -81,7 +81,6 @@ set_source_files_properties(${test_HEADER_FILES}
 list(APPEND test_SOURCE_FILES ${test_HEADER_FILES})
 
 add_executable(lltest ${test_SOURCE_FILES})
-buildscripts_block(lltest)
 
 target_link_libraries(lltest
     ${LLDATABASE_LIBRARIES}
diff --git a/indra/viewer_components/login/CMakeLists.txt b/indra/viewer_components/login/CMakeLists.txt
index 79706e0df4..3bedeb7292 100644
--- a/indra/viewer_components/login/CMakeLists.txt
+++ b/indra/viewer_components/login/CMakeLists.txt
@@ -42,7 +42,6 @@ list(APPEND
 add_library(lllogin 
             ${login_SOURCE_FILES}
             )
-buildscripts_block(lllogin)
 
 target_link_libraries(lllogin
     ${LLMESSAGE_LIBRARIES}
diff --git a/indra/win_crash_logger/CMakeLists.txt b/indra/win_crash_logger/CMakeLists.txt
index 9d651fcbc9..144d037a31 100644
--- a/indra/win_crash_logger/CMakeLists.txt
+++ b/indra/win_crash_logger/CMakeLists.txt
@@ -71,7 +71,6 @@ list(APPEND
 find_library(DXGUID_LIBRARY dxguid ${DIRECTX_LIBRARY_DIR})
 
 add_executable(windows-crash-logger WIN32 ${win_crash_logger_SOURCE_FILES})
-buildscripts_block(windows-crash-logger)
 
 target_link_libraries(windows-crash-logger
     ${BREAKPAD_EXCEPTION_HANDLER_LIBRARIES}
-- 
cgit v1.2.3


From 65dd31631f385d6ad85ed78b2fa07525dbd9d360 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Sat, 8 Sep 2018 10:05:26 -0400
Subject: DRTVWR-474, MAINT-9047: Restore viewer to top-level Mac app.

The relationship to MAINT-9047 is that we hope this will improve the behavior
of Mac code signing.
---
 indra/newview/viewer_manifest.py | 633 ++++++++++++++++-----------------------
 1 file changed, 254 insertions(+), 379 deletions(-)

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 541112a765..14ff2c194e 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -880,394 +880,269 @@ class DarwinManifest(ViewerManifest):
         return True
 
     def construct(self):
-        # These are the names of the top-level application and the embedded
-        # applications for the VMP and for the actual viewer, respectively.
-        # These names, without the .app suffix, determine the flyover text for
-        # their corresponding Dock icons.
-        toplevel_app, toplevel_icon = "Second Life.app",          "secondlife.icns"
-        launcher_app, launcher_icon = "Second Life Launcher.app", "secondlife.icns"
-        viewer_app,   viewer_icon   = "Second Life Viewer.app",   "secondlife.icns"
-
         # copy over the build result (this is a no-op if run within the xcode script)
-        self.path(os.path.join(self.args['configuration'], toplevel_app), dst="")
+        self.path(os.path.join(self.args['configuration'], "Second Life.app"), dst="")
 
         pkgdir = os.path.join(self.args['build'], os.pardir, 'packages')
         relpkgdir = os.path.join(pkgdir, "lib", "release")
         debpkgdir = os.path.join(pkgdir, "lib", "debug")
 
-        # -------------------- top-level Second Life.app ---------------------
-        # top-level Second Life application is only a container
         with self.prefix(src="", dst="Contents"):  # everything goes in Contents
-            # top-level Info.plist is as generated by CMake
-            Info_plist = "Info.plist"
-            ## This self.path() call reports 0 files... skip?
-            self.path(Info_plist)
-            Info_plist = self.dst_path_of(Info_plist)
-
-            # the one file in top-level MacOS directory is the trampoline to
-            # our nested launcher_app
+            # CEF framework goes inside Contents/Frameworks.
+            # Remember where we parked this car.
+            with self.prefix(src="", dst="Frameworks"):
+                CEF_framework = "Chromium Embedded Framework.framework"
+                self.path2basename(relpkgdir, CEF_framework)
+                CEF_framework = self.dst_path_of(CEF_framework)
+
             with self.prefix(dst="MacOS"):
-                toplevel_MacOS = self.get_dst_prefix()
-                trampoline = self.put_in_file("""\
-#!/bin/bash
-open "%s" --args "$@"
-""" %
-                    # up one directory from MacOS to its sibling Resources directory
-                    os.path.join('$(dirname "$0")', os.pardir, 'Resources', launcher_app),
-                    "SL_Launcher",      # write this file
-                    "trampoline")       # flag to add to list of copied files
-                # Script must be executable
-                self.run_command(["chmod", "+x", trampoline])
-
-            # Make a symlink to a nested app Frameworks directory that doesn't
-            # yet exist. We shouldn't need this; the only things that need
-            # Frameworks are nested apps under viewer_app, and they should
-            # simply find its Contents/Frameworks by relative pathnames. But
-            # empirically, we do: if we omit this symlink, CEF doesn't work --
-            # the login splash screen doesn't even display. SIIIIGH.
-            # We're passing a path that's already relative, hence symlinkf()
-            # rather than relsymlinkf().
-            self.symlinkf(os.path.join("Resources", viewer_app, "Contents", "Frameworks"))
-
-            with self.prefix(src="", dst="Resources"):
-                # top-level Resources directory should be pretty sparse
-                # need .icns file referenced by top-level Info.plist
+                # NOTE: the -S argument to strip causes it to keep
+                # enough info for annotated backtraces (i.e. function
+                # names in the crash log). 'strip' with no arguments
+                # yields a slightly smaller binary but makes crash
+                # logs mostly useless. This may be desirable for the
+                # final release. Or not.
+                if ("package" in self.args['actions'] or 
+                    "unpacked" in self.args['actions']):
+                    self.run_command(
+                        ['strip', '-S', self.dst_path_of('Second Life')])
+
+            with self.prefix(dst="Resources"):
+                # defer cross-platform file copies until we're in the
+                # nested Resources directory
+                super(DarwinManifest, self).construct()
+
+                # need .icns file referenced by Info.plist
                 with self.prefix(src=self.icon_path(), dst="") :
-                    self.path(toplevel_icon)
-
-                # ------------------- nested launcher_app --------------------
-                with self.prefix(dst=os.path.join(launcher_app, "Contents")):
-                    # Info.plist is just like top-level one...
-                    Info = plistlib.readPlist(Info_plist)
-                    # except for these replacements:
-                    Info["CFBundleExecutable"] = "SL_Launcher"
-                    Info["CFBundleIconFile"] = launcher_icon
-                    self.put_in_file(
-                        plistlib.writePlistToString(Info),
-                        os.path.basename(Info_plist),
-                        "Info.plist")
-
-                    # copy VMP libs to MacOS
-                    with self.prefix(dst="MacOS"):              
-                        #this copies over the python wrapper script,
-                        #associated utilities and required libraries, see
-                        #SL-321, SL-322, SL-323
-                        with self.prefix(src=os.path.join(pkgdir, "VMP"), dst=""):
-                            self.path("SL_Launcher")
-                            self.path("*.py")
-                            # certifi will be imported by requests; this is
-                            # our custom version to get our ca-bundle.crt
-                            self.path("certifi")
-                        with self.prefix(src=os.path.join(pkgdir, "lib", "python"), dst=""):
-                            # llbase provides our llrest service layer and llsd decoding
-                            with self.prefix("llbase"):
-                                # (Why is llbase treated specially here? What
-                                # DON'T we want to copy out of lib/python/llbase?)
-                                self.path("*.py")
-                                self.path("_cllsd.so")
-                            #requests module needed by llbase/llrest.py
-                            #this is only needed on POSIX, because in Windows
-                            #we compile it into the EXE
-                            for pypkg in "chardet", "idna", "requests", "urllib3":
-                                self.path(pypkg)
-
-                    # launcher_app/Contents/Resources
-                    with self.prefix(dst="Resources"):
-                        with self.prefix(src=self.icon_path(), dst="") :
-                            self.path(launcher_icon)
-                            with self.prefix(dst="vmp_icons"):
-                                self.path("secondlife.ico")
-                        #VMP Tkinter icons
-                        with self.prefix("vmp_icons"):
-                            self.path("*.png")
-                            self.path("*.gif")
-
-                # -------------------- nested viewer_app ---------------------
-                with self.prefix(dst=os.path.join(viewer_app, "Contents")):
-                    # Info.plist is just like top-level one...
-                    Info = plistlib.readPlist(Info_plist)
-                    # except for these replacements:
-                    # (CFBundleExecutable may be moot: SL_Launcher directly
-                    # runs the executable, instead of launching the app)
-                    Info["CFBundleExecutable"] = "Second Life"
-                    Info["CFBundleIconFile"] = viewer_icon
-                    self.put_in_file(
-                        plistlib.writePlistToString(Info),
-                        os.path.basename(Info_plist),
-                        "Info.plist")
-
-                    # CEF framework goes inside viewer_app/Contents/Frameworks.
-                    # Remember where we parked this car.
-                    with self.prefix(src="", dst="Frameworks"):
-                        CEF_framework = "Chromium Embedded Framework.framework"
-                        self.path2basename(relpkgdir, CEF_framework)
-                        CEF_framework = self.dst_path_of(CEF_framework)
-
-                    with self.prefix(dst="MacOS"):
-                        # CMake constructs the Second Life executable in the
-                        # MacOS directory belonging to the top-level Second
-                        # Life.app. Move it here.
-                        here = self.get_dst_prefix()
-                        relbase = os.path.realpath(os.path.dirname(Info_plist))
-                        self.cmakedirs(here)
-                        for f in os.listdir(toplevel_MacOS):
-                            if f == os.path.basename(trampoline):
-                                # don't move the trampoline script we just made!
-                                continue
-                            fromwhere = os.path.join(toplevel_MacOS, f)
-                            towhere   = os.path.join(here, f)
-                            print "Moving %s => %s" % \
-                                  (self.relpath(fromwhere, relbase),
-                                   self.relpath(towhere, relbase))
-                            # now do it, only without relativizing paths
-                            os.rename(fromwhere, towhere)
-
-                        # NOTE: the -S argument to strip causes it to keep
-                        # enough info for annotated backtraces (i.e. function
-                        # names in the crash log). 'strip' with no arguments
-                        # yields a slightly smaller binary but makes crash
-                        # logs mostly useless. This may be desirable for the
-                        # final release. Or not.
-                        if ("package" in self.args['actions'] or 
-                            "unpacked" in self.args['actions']):
-                            self.run_command(
-                                ['strip', '-S', self.dst_path_of('Second Life')])
-
-                    with self.prefix(dst="Resources"):
-                        # defer cross-platform file copies until we're in the right
-                        # nested Resources directory
-                        super(DarwinManifest, self).construct()
-
-                        with self.prefix(src=self.icon_path(), dst="") :
-                            self.path(viewer_icon)
-
-                        with self.prefix(src=relpkgdir, dst=""):
-                            self.path("libndofdev.dylib")
-                            self.path("libhunspell-1.3.0.dylib")   
-
-                        with self.prefix("cursors_mac"):
-                            self.path("*.tif")
-
-                        self.path("licenses-mac.txt", dst="licenses.txt")
-                        self.path("featuretable_mac.txt")
-                        self.path("SecondLife.nib")
-
-                        with self.prefix(src=pkgdir,dst=""):
-                            self.path("ca-bundle.crt")
-
-                        self.path("SecondLife.nib")
-
-                        # Translations
-                        self.path("English.lproj/language.txt")
-                        self.replace_in(src="English.lproj/InfoPlist.strings",
-                                        dst="English.lproj/InfoPlist.strings",
-                                        searchdict={'%%VERSION%%':'.'.join(self.args['version'])}
-                                        )
-                        self.path("German.lproj")
-                        self.path("Japanese.lproj")
-                        self.path("Korean.lproj")
-                        self.path("da.lproj")
-                        self.path("es.lproj")
-                        self.path("fr.lproj")
-                        self.path("hu.lproj")
-                        self.path("it.lproj")
-                        self.path("nl.lproj")
-                        self.path("pl.lproj")
-                        self.path("pt.lproj")
-                        self.path("ru.lproj")
-                        self.path("tr.lproj")
-                        self.path("uk.lproj")
-                        self.path("zh-Hans.lproj")
-
-                        def path_optional(src, dst):
-                            """
-                            For a number of our self.path() calls, not only do we want
-                            to deal with the absence of src, we also want to remember
-                            which were present. Return either an empty list (absent)
-                            or a list containing dst (present). Concatenate these
-                            return values to get a list of all libs that are present.
-                            """
-                            # This was simple before we started needing to pass
-                            # wildcards. Fortunately, self.path() ends up appending a
-                            # (source, dest) pair to self.file_list for every expanded
-                            # file processed. Remember its size before the call.
-                            oldlen = len(self.file_list)
-                            self.path(src, dst)
-                            # The dest appended to self.file_list has been prepended
-                            # with self.get_dst_prefix(). Strip it off again.
-                            added = [os.path.relpath(d, self.get_dst_prefix())
-                                     for s, d in self.file_list[oldlen:]]
-                            if not added:
-                                print "Skipping %s" % dst
-                            return added
-
-                        # dylibs is a list of all the .dylib files we expect to need
-                        # in our bundled sub-apps. For each of these we'll create a
-                        # symlink from sub-app/Contents/Resources to the real .dylib.
-                        # Need to get the llcommon dll from any of the build directories as well.
-                        libfile_parent = self.get_dst_prefix()
-                        libfile = "libllcommon.dylib"
-                        dylibs = path_optional(self.find_existing_file(os.path.join(os.pardir,
-                                                                       "llcommon",
-                                                                       self.args['configuration'],
-                                                                       libfile),
-                                                                       os.path.join(relpkgdir, libfile)),
-                                               dst=libfile)
-
-                        for libfile in (
-                                        "libapr-1.0.dylib",
-                                        "libaprutil-1.0.dylib",
-                                        "libcollada14dom.dylib",
-                                        "libexpat.1.dylib",
-                                        "libexception_handler.dylib",
-                                        "libGLOD.dylib",
-                                        # libnghttp2.dylib is a symlink to
-                                        # libnghttp2.major.dylib, which is a symlink to
-                                        # libnghttp2.version.dylib. Get all of them.
-                                        "libnghttp2.*dylib",
-                                        ):
-                            dylibs += path_optional(os.path.join(relpkgdir, libfile), libfile)
-
-                        # SLVoice and vivox lols, no symlinks needed
-                        for libfile in (
-                                        'libortp.dylib',
-                                        'libsndfile.dylib',
-                                        'libvivoxoal.dylib',
-                                        'libvivoxsdk.dylib',
-                                        'libvivoxplatform.dylib',
-                                        'SLVoice',
-                                        ):
-                            self.path2basename(relpkgdir, libfile)
-
-                        # dylibs that vary based on configuration
-                        if self.args['configuration'].lower() == 'debug':
-                            for libfile in (
-                                        "libfmodexL.dylib",
-                                        ):
-                                dylibs += path_optional(os.path.join(debpkgdir, libfile), libfile)
-                        else:
-                            for libfile in (
-                                        "libfmodex.dylib",
-                                        ):
-                                dylibs += path_optional(os.path.join(relpkgdir, libfile), libfile)
-
-                        # our apps
-                        executable_path = {}
-                        for app_bld_dir, app in (("mac_crash_logger", "mac-crash-logger.app"),
-                                                 # plugin launcher
-                                                 (os.path.join("llplugin", "slplugin"), "SLPlugin.app"),
-                                                 ):
-                            self.path2basename(os.path.join(os.pardir,
-                                                            app_bld_dir, self.args['configuration']),
-                                               app)
-                            executable_path[app] = \
-                                self.dst_path_of(os.path.join(app, "Contents", "MacOS"))
-
-                            # our apps dependencies on shared libs
-                            # for each app, for each dylib we collected in dylibs,
-                            # create a symlink to the real copy of the dylib.
-                            with self.prefix(dst=os.path.join(app, "Contents", "Resources")):
-                                for libfile in dylibs:
-                                    self.relsymlinkf(os.path.join(libfile_parent, libfile))
-
-                        # Dullahan helper apps go inside SLPlugin.app
-                        with self.prefix(dst=os.path.join(
-                            "SLPlugin.app", "Contents", "Frameworks")):
-
-                            frameworkname = 'Chromium Embedded Framework'
-
-                            # This code constructs a relative symlink from the
-                            # target framework folder back to the real CEF framework.
-                            # It needs to be relative so that the symlink still works when
-                            # (as is normal) the user moves the app bundle out of the DMG
-                            # and into the /Applications folder. Note we pass catch=False,
-                            # letting the uncaught exception terminate the process, since
-                            # without this symlink, Second Life web media can't possibly work.
-
-                            # It might seem simpler just to symlink Frameworks back to
-                            # the parent of Chromimum Embedded Framework.framework. But
-                            # that would create a symlink cycle, which breaks our
-                            # packaging step. So make a symlink from Chromium Embedded
-                            # Framework.framework to the directory of the same name, which
-                            # is NOT an ancestor of the symlink.
-
-                            # from SLPlugin.app/Contents/Frameworks/Chromium Embedded
-                            # Framework.framework back to
-                            # $viewer_app/Contents/Frameworks/Chromium Embedded Framework.framework
-                            SLPlugin_framework = self.relsymlinkf(CEF_framework, catch=False)
-
-                            # copy DullahanHelper.app
-                            self.path2basename(relpkgdir, 'DullahanHelper.app')
-
-                            # and fix that up with a Frameworks/CEF symlink too
-                            with self.prefix(dst=os.path.join(
-                                'DullahanHelper.app', 'Contents', 'Frameworks')):
-                                # from Dullahan Helper.app/Contents/Frameworks/Chromium Embedded
-                                # Framework.framework back to
-                                # SLPlugin.app/Contents/Frameworks/Chromium Embedded Framework.framework
-                                # Since SLPlugin_framework is itself a
-                                # symlink, don't let relsymlinkf() resolve --
-                                # explicitly call relpath(symlink=True) and
-                                # create that symlink here.
-                                DullahanHelper_framework = \
-                                    self.symlinkf(self.relpath(SLPlugin_framework, symlink=True),
-                                                  catch=False)
-
-                            # change_command includes install_name_tool, the
-                            # -change subcommand and the old framework rpath
-                            # stamped into the executable. To use it with
-                            # run_command(), we must still append the new
-                            # framework path and the pathname of the
-                            # executable to change.
-                            change_command = [
-                                'install_name_tool', '-change',
-                                '@rpath/Frameworks/Chromium Embedded Framework.framework/Chromium Embedded Framework']
-
-                            with self.prefix(dst=os.path.join(
-                                'DullahanHelper.app', 'Contents', 'MacOS')):
-                                # Now self.get_dst_prefix() is, at runtime,
-                                # @executable_path. Locate the helper app
-                                # framework (which is a symlink) from here.
-                                newpath = os.path.join(
-                                    '@executable_path',
-                                    self.relpath(DullahanHelper_framework, symlink=True),
-                                    frameworkname)
-                                # and restamp the DullahanHelper executable
-                                self.run_command(
-                                    change_command +
-                                    [newpath, self.dst_path_of('DullahanHelper')])
-
-                        # SLPlugin plugins
-                        with self.prefix(dst="llplugin"):
-                            dylibexecutable = 'media_plugin_cef.dylib'
-                            self.path2basename("../media_plugins/cef/" + self.args['configuration'],
-                                               dylibexecutable)
-
-                            # Do this install_name_tool *after* media plugin is copied over.
-                            # Locate the framework lib executable -- relative to
-                            # SLPlugin.app/Contents/MacOS, which will be our
-                            # @executable_path at runtime!
-                            newpath = os.path.join(
-                                '@executable_path',
-                                self.relpath(SLPlugin_framework, executable_path["SLPlugin.app"],
-                                             symlink=True),
-                                frameworkname)
-                            # restamp media_plugin_cef.dylib
-                            self.run_command(
-                                change_command +
-                                [newpath, self.dst_path_of(dylibexecutable)])
-
-                            # copy LibVLC plugin itself
-                            self.path2basename("../media_plugins/libvlc/" + self.args['configuration'],
-                                               "media_plugin_libvlc.dylib")
-
-                            # copy LibVLC dynamic libraries
-                            with self.prefix(src=relpkgdir, dst="lib"):
-                                self.path( "libvlc*.dylib*" )
-                                # copy LibVLC plugins folder
-                                with self.prefix(src='plugins', dst=""):
-                                    self.path( "*.dylib" )
-                                    self.path( "plugins.dat" )
+                    self.path("secondlife.icns")
+
+                with self.prefix(src=relpkgdir, dst=""):
+                    self.path("libndofdev.dylib")
+                    self.path("libhunspell-1.3.0.dylib")   
+
+                with self.prefix("cursors_mac"):
+                    self.path("*.tif")
+
+                self.path("licenses-mac.txt", dst="licenses.txt")
+                self.path("featuretable_mac.txt")
+                self.path("SecondLife.nib")
+
+                with self.prefix(src=pkgdir,dst=""):
+                    self.path("ca-bundle.crt")
+
+                self.path("SecondLife.nib")
+
+                # Translations
+                self.path("English.lproj/language.txt")
+                self.replace_in(src="English.lproj/InfoPlist.strings",
+                                dst="English.lproj/InfoPlist.strings",
+                                searchdict={'%%VERSION%%':'.'.join(self.args['version'])}
+                                )
+                self.path("German.lproj")
+                self.path("Japanese.lproj")
+                self.path("Korean.lproj")
+                self.path("da.lproj")
+                self.path("es.lproj")
+                self.path("fr.lproj")
+                self.path("hu.lproj")
+                self.path("it.lproj")
+                self.path("nl.lproj")
+                self.path("pl.lproj")
+                self.path("pt.lproj")
+                self.path("ru.lproj")
+                self.path("tr.lproj")
+                self.path("uk.lproj")
+                self.path("zh-Hans.lproj")
+
+                def path_optional(src, dst):
+                    """
+                    For a number of our self.path() calls, not only do we want
+                    to deal with the absence of src, we also want to remember
+                    which were present. Return either an empty list (absent)
+                    or a list containing dst (present). Concatenate these
+                    return values to get a list of all libs that are present.
+                    """
+                    # This was simple before we started needing to pass
+                    # wildcards. Fortunately, self.path() ends up appending a
+                    # (source, dest) pair to self.file_list for every expanded
+                    # file processed. Remember its size before the call.
+                    oldlen = len(self.file_list)
+                    self.path(src, dst)
+                    # The dest appended to self.file_list has been prepended
+                    # with self.get_dst_prefix(). Strip it off again.
+                    added = [os.path.relpath(d, self.get_dst_prefix())
+                             for s, d in self.file_list[oldlen:]]
+                    if not added:
+                        print "Skipping %s" % dst
+                    return added
+
+                # dylibs is a list of all the .dylib files we expect to need
+                # in our bundled sub-apps. For each of these we'll create a
+                # symlink from sub-app/Contents/Resources to the real .dylib.
+                # Need to get the llcommon dll from any of the build directories as well.
+                libfile_parent = self.get_dst_prefix()
+                libfile = "libllcommon.dylib"
+                dylibs = path_optional(self.find_existing_file(os.path.join(os.pardir,
+                                                               "llcommon",
+                                                               self.args['configuration'],
+                                                               libfile),
+                                                               os.path.join(relpkgdir, libfile)),
+                                       dst=libfile)
+
+                for libfile in (
+                                "libapr-1.0.dylib",
+                                "libaprutil-1.0.dylib",
+                                "libcollada14dom.dylib",
+                                "libexpat.1.dylib",
+                                "libexception_handler.dylib",
+                                "libGLOD.dylib",
+                                # libnghttp2.dylib is a symlink to
+                                # libnghttp2.major.dylib, which is a symlink to
+                                # libnghttp2.version.dylib. Get all of them.
+                                "libnghttp2.*dylib",
+                                ):
+                    dylibs += path_optional(os.path.join(relpkgdir, libfile), libfile)
+
+                # SLVoice and vivox lols, no symlinks needed
+                for libfile in (
+                                'libortp.dylib',
+                                'libsndfile.dylib',
+                                'libvivoxoal.dylib',
+                                'libvivoxsdk.dylib',
+                                'libvivoxplatform.dylib',
+                                'SLVoice',
+                                ):
+                    self.path2basename(relpkgdir, libfile)
+
+                # dylibs that vary based on configuration
+                if self.args['configuration'].lower() == 'debug':
+                    for libfile in (
+                                "libfmodexL.dylib",
+                                ):
+                        dylibs += path_optional(os.path.join(debpkgdir, libfile), libfile)
+                else:
+                    for libfile in (
+                                "libfmodex.dylib",
+                                ):
+                        dylibs += path_optional(os.path.join(relpkgdir, libfile), libfile)
+
+                # our apps
+                executable_path = {}
+                for app_bld_dir, app in (("mac_crash_logger", "mac-crash-logger.app"),
+                                         # plugin launcher
+                                         (os.path.join("llplugin", "slplugin"), "SLPlugin.app"),
+                                         ):
+                    self.path2basename(os.path.join(os.pardir,
+                                                    app_bld_dir, self.args['configuration']),
+                                       app)
+                    executable_path[app] = \
+                        self.dst_path_of(os.path.join(app, "Contents", "MacOS"))
+
+                    # our apps dependencies on shared libs
+                    # for each app, for each dylib we collected in dylibs,
+                    # create a symlink to the real copy of the dylib.
+                    with self.prefix(dst=os.path.join(app, "Contents", "Resources")):
+                        for libfile in dylibs:
+                            self.relsymlinkf(os.path.join(libfile_parent, libfile))
+
+                # Dullahan helper apps go inside SLPlugin.app
+                with self.prefix(dst=os.path.join(
+                    "SLPlugin.app", "Contents", "Frameworks")):
+
+                    frameworkname = 'Chromium Embedded Framework'
+
+                    # This code constructs a relative symlink from the
+                    # target framework folder back to the real CEF framework.
+                    # It needs to be relative so that the symlink still works when
+                    # (as is normal) the user moves the app bundle out of the DMG
+                    # and into the /Applications folder. Note we pass catch=False,
+                    # letting the uncaught exception terminate the process, since
+                    # without this symlink, Second Life web media can't possibly work.
+
+                    # It might seem simpler just to symlink Frameworks back to
+                    # the parent of Chromimum Embedded Framework.framework. But
+                    # that would create a symlink cycle, which breaks our
+                    # packaging step. So make a symlink from Chromium Embedded
+                    # Framework.framework to the directory of the same name, which
+                    # is NOT an ancestor of the symlink.
+
+                    # from SLPlugin.app/Contents/Frameworks/Chromium Embedded
+                    # Framework.framework back to
+                    # $viewer_app/Contents/Frameworks/Chromium Embedded Framework.framework
+                    SLPlugin_framework = self.relsymlinkf(CEF_framework, catch=False)
+
+                    # copy DullahanHelper.app
+                    self.path2basename(relpkgdir, 'DullahanHelper.app')
+
+                    # and fix that up with a Frameworks/CEF symlink too
+                    with self.prefix(dst=os.path.join(
+                        'DullahanHelper.app', 'Contents', 'Frameworks')):
+                        # from Dullahan Helper.app/Contents/Frameworks/Chromium Embedded
+                        # Framework.framework back to
+                        # SLPlugin.app/Contents/Frameworks/Chromium Embedded Framework.framework
+                        # Since SLPlugin_framework is itself a
+                        # symlink, don't let relsymlinkf() resolve --
+                        # explicitly call relpath(symlink=True) and
+                        # create that symlink here.
+                        DullahanHelper_framework = \
+                            self.symlinkf(self.relpath(SLPlugin_framework, symlink=True),
+                                          catch=False)
+
+                    # change_command includes install_name_tool, the
+                    # -change subcommand and the old framework rpath
+                    # stamped into the executable. To use it with
+                    # run_command(), we must still append the new
+                    # framework path and the pathname of the
+                    # executable to change.
+                    change_command = [
+                        'install_name_tool', '-change',
+                        '@rpath/Frameworks/Chromium Embedded Framework.framework/Chromium Embedded Framework']
+
+                    with self.prefix(dst=os.path.join(
+                        'DullahanHelper.app', 'Contents', 'MacOS')):
+                        # Now self.get_dst_prefix() is, at runtime,
+                        # @executable_path. Locate the helper app
+                        # framework (which is a symlink) from here.
+                        newpath = os.path.join(
+                            '@executable_path',
+                            self.relpath(DullahanHelper_framework, symlink=True),
+                            frameworkname)
+                        # and restamp the DullahanHelper executable
+                        self.run_command(
+                            change_command +
+                            [newpath, self.dst_path_of('DullahanHelper')])
+
+                # SLPlugin plugins
+                with self.prefix(dst="llplugin"):
+                    dylibexecutable = 'media_plugin_cef.dylib'
+                    self.path2basename("../media_plugins/cef/" + self.args['configuration'],
+                                       dylibexecutable)
+
+                    # Do this install_name_tool *after* media plugin is copied over.
+                    # Locate the framework lib executable -- relative to
+                    # SLPlugin.app/Contents/MacOS, which will be our
+                    # @executable_path at runtime!
+                    newpath = os.path.join(
+                        '@executable_path',
+                        self.relpath(SLPlugin_framework, executable_path["SLPlugin.app"],
+                                     symlink=True),
+                        frameworkname)
+                    # restamp media_plugin_cef.dylib
+                    self.run_command(
+                        change_command +
+                        [newpath, self.dst_path_of(dylibexecutable)])
+
+                    # copy LibVLC plugin itself
+                    self.path2basename("../media_plugins/libvlc/" + self.args['configuration'],
+                                       "media_plugin_libvlc.dylib")
+
+                    # copy LibVLC dynamic libraries
+                    with self.prefix(src=relpkgdir, dst="lib"):
+                        self.path( "libvlc*.dylib*" )
+                        # copy LibVLC plugins folder
+                        with self.prefix(src='plugins', dst=""):
+                            self.path( "*.dylib" )
+                            self.path( "plugins.dat" )
 
     def package_finish(self):
         global CHANNEL_VENDOR_BASE
-- 
cgit v1.2.3


From a74b3691aff94dfbd0fbfdce05f8a03168328ca7 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Sun, 9 Sep 2018 09:22:06 -0400
Subject: DRTVWR-474, MAINT-9047: Make viewer_manifest use same bundle name.

---
 indra/newview/viewer_manifest.py | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 14ff2c194e..bddacf357d 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -871,6 +871,9 @@ class Windows_x86_64_Manifest(WindowsManifest):
 class DarwinManifest(ViewerManifest):
     build_data_json_platform = 'mac'
 
+    def app_bundle(self):
+        return self.app_name() + ".app"
+
     def finish_build_data_dict(self, build_data_dict):
         build_data_dict.update({'Bundle Id':self.args['bundleid']})
         return build_data_dict
@@ -881,7 +884,10 @@ class DarwinManifest(ViewerManifest):
 
     def construct(self):
         # copy over the build result (this is a no-op if run within the xcode script)
-        self.path(os.path.join(self.args['configuration'], "Second Life.app"), dst="")
+        # Second Life.app is what CMake / Xcode builds
+        # self.app_bundle() is what we ultimately expect to sign and package
+        self.path(os.path.join(self.args['configuration'], "Second Life.app"),
+                  dst=self.app_bundle())
 
         pkgdir = os.path.join(self.args['build'], os.pardir, 'packages')
         relpkgdir = os.path.join(pkgdir, "lib", "release")
@@ -930,8 +936,6 @@ class DarwinManifest(ViewerManifest):
                 with self.prefix(src=pkgdir,dst=""):
                     self.path("ca-bundle.crt")
 
-                self.path("SecondLife.nib")
-
                 # Translations
                 self.path("English.lproj/language.txt")
                 self.replace_in(src="English.lproj/InfoPlist.strings",
@@ -1180,8 +1184,6 @@ class DarwinManifest(ViewerManifest):
 
             # Copy everything in to the mounted .dmg
 
-            app_name = self.app_name()
-
             # Hack:
             # Because there is no easy way to coerce the Finder into positioning
             # the app bundle in the same place with different app names, we are
@@ -1195,7 +1197,7 @@ class DarwinManifest(ViewerManifest):
             if not os.path.exists (self.src_path_of(dmg_template)):
                 dmg_template = os.path.join ('installers', 'darwin', 'release-dmg')
 
-            for s,d in {self.get_dst_prefix():app_name + ".app",
+            for s,d in {self.get_dst_prefix(): self.app_bundle(),
                         os.path.join(dmg_template, "_VolumeIcon.icns"): ".VolumeIcon.icns",
                         os.path.join(dmg_template, "background.jpg"): "background.jpg",
                         os.path.join(dmg_template, "_DS_Store"): ".DS_Store"}.items():
@@ -1238,7 +1240,7 @@ class DarwinManifest(ViewerManifest):
             # the signature are preserved; moving the files using python will leave them behind
             # and invalidate the signatures.
             if 'signature' in self.args:
-                app_in_dmg=os.path.join(volpath,self.app_name()+".app")
+                app_in_dmg=os.path.join(volpath,self.app_bundle())
                 print "Attempting to sign '%s'" % app_in_dmg
                 identity = self.args['signature']
                 if identity == '':
@@ -1293,9 +1295,6 @@ class DarwinManifest(ViewerManifest):
                                 raise
                     self.run_command(['spctl', '-a', '-texec', '-vv', app_in_dmg])
 
-            imagename="SecondLife_" + '_'.join(self.args['version'])
-
-
         finally:
             # Unmount the image even if exceptions from any of the above 
             self.run_command(['hdiutil', 'detach', '-force', devfile])
-- 
cgit v1.2.3


From 886da87c43447040afbafa6628e158e66965141d Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Mon, 10 Sep 2018 09:31:08 -0400
Subject: by default print location in log files

---
 indra/newview/app_settings/logcontrol.xml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/indra/newview/app_settings/logcontrol.xml b/indra/newview/app_settings/logcontrol.xml
index 8ced81fdb3..71445ea541 100644
--- a/indra/newview/app_settings/logcontrol.xml
+++ b/indra/newview/app_settings/logcontrol.xml
@@ -2,6 +2,7 @@
 	<map>
 		<!-- default-level can be ALL, DEBUG, INFO, WARN, ERROR, or NONE -->
 		<key>default-level</key>    <string>INFO</string>
+		<key>print-location</key>   <boolean>true</boolean>
 		<key>settings</key>
 			<array>
 				<!-- Suppress anything but ERROR for some very verbose components -->
-- 
cgit v1.2.3


From 299d4807ab6bc35c3643134a142fb59d5931bed9 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 10 Sep 2018 12:23:42 -0400
Subject: DRTVWR-474, MAINT-9047: Back out changeset 2ed01671b974.

We'll try to address the Mac app bundle name discrepancy a different way.
---
 indra/newview/viewer_manifest.py | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index bddacf357d..14ff2c194e 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -871,9 +871,6 @@ class Windows_x86_64_Manifest(WindowsManifest):
 class DarwinManifest(ViewerManifest):
     build_data_json_platform = 'mac'
 
-    def app_bundle(self):
-        return self.app_name() + ".app"
-
     def finish_build_data_dict(self, build_data_dict):
         build_data_dict.update({'Bundle Id':self.args['bundleid']})
         return build_data_dict
@@ -884,10 +881,7 @@ class DarwinManifest(ViewerManifest):
 
     def construct(self):
         # copy over the build result (this is a no-op if run within the xcode script)
-        # Second Life.app is what CMake / Xcode builds
-        # self.app_bundle() is what we ultimately expect to sign and package
-        self.path(os.path.join(self.args['configuration'], "Second Life.app"),
-                  dst=self.app_bundle())
+        self.path(os.path.join(self.args['configuration'], "Second Life.app"), dst="")
 
         pkgdir = os.path.join(self.args['build'], os.pardir, 'packages')
         relpkgdir = os.path.join(pkgdir, "lib", "release")
@@ -936,6 +930,8 @@ class DarwinManifest(ViewerManifest):
                 with self.prefix(src=pkgdir,dst=""):
                     self.path("ca-bundle.crt")
 
+                self.path("SecondLife.nib")
+
                 # Translations
                 self.path("English.lproj/language.txt")
                 self.replace_in(src="English.lproj/InfoPlist.strings",
@@ -1184,6 +1180,8 @@ class DarwinManifest(ViewerManifest):
 
             # Copy everything in to the mounted .dmg
 
+            app_name = self.app_name()
+
             # Hack:
             # Because there is no easy way to coerce the Finder into positioning
             # the app bundle in the same place with different app names, we are
@@ -1197,7 +1195,7 @@ class DarwinManifest(ViewerManifest):
             if not os.path.exists (self.src_path_of(dmg_template)):
                 dmg_template = os.path.join ('installers', 'darwin', 'release-dmg')
 
-            for s,d in {self.get_dst_prefix(): self.app_bundle(),
+            for s,d in {self.get_dst_prefix():app_name + ".app",
                         os.path.join(dmg_template, "_VolumeIcon.icns"): ".VolumeIcon.icns",
                         os.path.join(dmg_template, "background.jpg"): "background.jpg",
                         os.path.join(dmg_template, "_DS_Store"): ".DS_Store"}.items():
@@ -1240,7 +1238,7 @@ class DarwinManifest(ViewerManifest):
             # the signature are preserved; moving the files using python will leave them behind
             # and invalidate the signatures.
             if 'signature' in self.args:
-                app_in_dmg=os.path.join(volpath,self.app_bundle())
+                app_in_dmg=os.path.join(volpath,self.app_name()+".app")
                 print "Attempting to sign '%s'" % app_in_dmg
                 identity = self.args['signature']
                 if identity == '':
@@ -1295,6 +1293,9 @@ class DarwinManifest(ViewerManifest):
                                 raise
                     self.run_command(['spctl', '-a', '-texec', '-vv', app_in_dmg])
 
+            imagename="SecondLife_" + '_'.join(self.args['version'])
+
+
         finally:
             # Unmount the image even if exceptions from any of the above 
             self.run_command(['hdiutil', 'detach', '-force', devfile])
-- 
cgit v1.2.3


From 298a52f96a92f4368b3c5d955eab6b37a58f4931 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 10 Sep 2018 17:01:53 -0400
Subject: DRTVWR-474, MAINT-9047: Try *not* copying the viewer built by CMake.

The start of viewer_manifest.DarwinManifest.construct() is a path() call to
copy the whole viewer tree from where CMake constructs it. The comment is:
"(this is a no-op if run within the xcode script)." Unfortunately, for unclear
reasons, this has recently started nesting Second Life.app within the Second
Life.app directory, and even to multiple levels. When that happens, copying
the outermost .app directory to the sparseimage in order to convert to dmg
runs out of room because we're trying to pack multiple copies of the whole
viewer tree into the fixed-size sparseimage.

But if it works to simply skip that entire initial copy operation, so much the
better.
---
 indra/newview/viewer_manifest.py | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 14ff2c194e..d16b5d9a7c 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -880,8 +880,8 @@ class DarwinManifest(ViewerManifest):
         return True
 
     def construct(self):
-        # copy over the build result (this is a no-op if run within the xcode script)
-        self.path(os.path.join(self.args['configuration'], "Second Life.app"), dst="")
+##      # copy over the build result (this is a no-op if run within the xcode script)
+##      self.path(os.path.join(self.args['configuration'], "Second Life.app"), dst="")
 
         pkgdir = os.path.join(self.args['build'], os.pardir, 'packages')
         relpkgdir = os.path.join(pkgdir, "lib", "release")
@@ -1238,6 +1238,11 @@ class DarwinManifest(ViewerManifest):
             # the signature are preserved; moving the files using python will leave them behind
             # and invalidate the signatures.
             if 'signature' in self.args:
+                print 72*'='
+                print 'In {}:'.format(volpath)
+                for f in os.listdir(volpath):
+                    print '  {}'.format(f)
+                print 72*'='
                 app_in_dmg=os.path.join(volpath,self.app_name()+".app")
                 print "Attempting to sign '%s'" % app_in_dmg
                 identity = self.args['signature']
-- 
cgit v1.2.3


From e0467f506136dd1fa044da130c7ffd3e817acc07 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 11 Sep 2018 09:18:56 -0400
Subject: DRTVWR-474, MAINT-9047: Must copy CMake-built viewer for EDU.

---
 indra/newview/viewer_manifest.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index d16b5d9a7c..4e6c112cda 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -880,8 +880,8 @@ class DarwinManifest(ViewerManifest):
         return True
 
     def construct(self):
-##      # copy over the build result (this is a no-op if run within the xcode script)
-##      self.path(os.path.join(self.args['configuration'], "Second Life.app"), dst="")
+        # copy over the build result (this is a no-op if run within the xcode script)
+        self.path(os.path.join(self.args['configuration'], "Second Life.app"), dst="")
 
         pkgdir = os.path.join(self.args['build'], os.pardir, 'packages')
         relpkgdir = os.path.join(pkgdir, "lib", "release")
-- 
cgit v1.2.3


From c6865bcd366379028029a24281812cf320de8aff Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 11 Sep 2018 13:56:21 -0400
Subject: DRTVWR-474, MAINT-9047: Make failing spctl command more verbose.

---
 indra/newview/viewer_manifest.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 4e6c112cda..de296bec75 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -1296,7 +1296,7 @@ class DarwinManifest(ViewerManifest):
                             else:
                                 print >> sys.stderr, "Maximum codesign attempts exceeded; giving up"
                                 raise
-                    self.run_command(['spctl', '-a', '-texec', '-vv', app_in_dmg])
+                    self.run_command(['spctl', '-a', '-texec', '-vvvv', app_in_dmg])
 
             imagename="SecondLife_" + '_'.join(self.args['version'])
 
-- 
cgit v1.2.3


From 517e1605e9feb203c9ccd9a115a21cae9bbc704b Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 11 Sep 2018 16:04:33 -0400
Subject: DRTVWR-474, MAINT-9047: Display top-level app bundle in sparseimage.

codesign claims to succeed, but spctl says:
/Volumes/Second Life Installer/Second Life Test.app: rejected
(the code is valid but does not seem to be an app)

Why not? Display what's in Second Life.app/Contents on the mounted
sparseimage: show Info.plist, list Frameworks, MacOS, Resources.
---
 indra/newview/viewer_manifest.py | 36 ++++++++++++++++++++++++++++--------
 1 file changed, 28 insertions(+), 8 deletions(-)

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index de296bec75..5078f323ae 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -1238,11 +1238,6 @@ class DarwinManifest(ViewerManifest):
             # the signature are preserved; moving the files using python will leave them behind
             # and invalidate the signatures.
             if 'signature' in self.args:
-                print 72*'='
-                print 'In {}:'.format(volpath)
-                for f in os.listdir(volpath):
-                    print '  {}'.format(f)
-                print 72*'='
                 app_in_dmg=os.path.join(volpath,self.app_name()+".app")
                 print "Attempting to sign '%s'" % app_in_dmg
                 identity = self.args['signature']
@@ -1296,11 +1291,36 @@ class DarwinManifest(ViewerManifest):
                             else:
                                 print >> sys.stderr, "Maximum codesign attempts exceeded; giving up"
                                 raise
+                    print 72*'='
+                    import stat
+                    print app_in_dmg
+                    # Second Life.app
+                    for sub0 in os.listdir(app_in_dmg):
+                        print '--{}'.format(sub0)
+                        path0 = os.path.join(app_in_dmg, sub0)
+                        if os.path.isfile(path0):
+                            # shouldn't be any file here
+                            with open(path0) as inf:
+                                for line in inf:
+                                    print '  {}'.format(line.rstrip())
+                        elif os.path.isdir(path0):
+                            # Contents
+                            for sub1 in os.listdir(path0):
+                                print '----{}'.format(sub1)
+                                path1 = os.path.join(path0, sub1)
+                                if os.path.isfile(path1):
+                                    # Info.plist, PkgInfo
+                                    with open(path1) as inf:
+                                        for line in inf:
+                                            print '    {}'.format(line.rstrip())
+                                elif os.path.isdir(path1):
+                                    # Frameworks, MacOS, Resources
+                                    for sub2 in os.listdir(path1):
+                                        path2 = os.path.join(path1, sub2)
+                                        print '    {:04o} {}'.format(stat.S_IMODE(os.stat(path2).st_mode), sub2)
+                    print 72*'='
                     self.run_command(['spctl', '-a', '-texec', '-vvvv', app_in_dmg])
 
-            imagename="SecondLife_" + '_'.join(self.args['version'])
-
-
         finally:
             # Unmount the image even if exceptions from any of the above 
             self.run_command(['hdiutil', 'detach', '-force', devfile])
-- 
cgit v1.2.3


From e3d16dcb70da26c7952b45252b74716b1a632b97 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 11 Sep 2018 19:57:42 -0400
Subject: DRTVWR-474: Remove nag about SL_Launcher.

---
 indra/newview/llappviewer.cpp | 20 --------------------
 1 file changed, 20 deletions(-)

diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 687b76c224..dd1d4cea39 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1083,26 +1083,6 @@ bool LLAppViewer::init()
 		}
 	}
 
-// don't nag developers who need to run the executable directly
-#if LL_RELEASE_FOR_DOWNLOAD
-	// MAINT-8305: If we're processing a SLURL, skip the launcher check.
-	if (gSavedSettings.getString("CmdLineLoginLocation").empty())
-	{
-		const char* PARENT = getenv("PARENT");
-		if (! (PARENT && std::string(PARENT) == "SL_Launcher"))
-		{
-			// Don't directly run this executable. Please run the launcher, which
-			// will run the viewer itself.
-			// Naturally we do not consider this bulletproof. The point is to
-			// gently remind a user who *inadvertently* finds him/herself in this
-			// situation to do things the Right Way. Anyone who intentionally
-			// bypasses this mechanism needs no reminder that s/he's shooting
-			// him/herself in the foot.
-			LLNotificationsUtil::add("RunLauncher");
-		}
-	}
-#endif
-
 #if LL_WINDOWS
 	if (gGLManager.mGLVersion < LLFeatureManager::getInstance()->getExpectedGLVersion())
 	{
-- 
cgit v1.2.3


From aaf45f0f63a1c79393e6316e04f78476d2a2af6e Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 11 Sep 2018 19:59:03 -0400
Subject: DRTVWR-474, MAINT-9047: Set viewer name in Info.plist, not launcher.

---
 indra/newview/CMakeLists.txt        | 8 +-------
 indra/newview/Info-SecondLife.plist | 2 +-
 2 files changed, 2 insertions(+), 8 deletions(-)

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 2fc722d4c3..212677717e 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -2056,13 +2056,7 @@ endif (LINUX)
 if (DARWIN)
   # These all get set with PROPERTIES
   set(product "Second Life")
-  # this is the setting for the Python wrapper, see SL-322 and WRAPPER line in Info-SecondLife.plist
-  if (PACKAGE)
-      set(MACOSX_WRAPPER_EXECUTABLE_NAME "SL_Launcher")
-  else (PACKAGE)
-      # force the name of the actual executable to allow running it within Xcode for debugging
-      set(MACOSX_WRAPPER_EXECUTABLE_NAME "../Resources/Second Life Viewer.app/Contents/MacOS/Second Life")
-  endif (PACKAGE)
+  set(MACOSX_EXECUTABLE_NAME "Second Life")
   set(MACOSX_BUNDLE_INFO_STRING "Second Life Viewer")
   set(MACOSX_BUNDLE_ICON_FILE "secondlife.icns")
   set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.secondlife.indra.viewer")
diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist
index af4cf26ac6..31b4201f47 100644
--- a/indra/newview/Info-SecondLife.plist
+++ b/indra/newview/Info-SecondLife.plist
@@ -5,7 +5,7 @@
 	<key>CFBundleDevelopmentRegion</key>
 	<string>English</string>
 	<key>CFBundleExecutable</key>
-	<string>${MACOSX_WRAPPER_EXECUTABLE_NAME}</string>
+	<string>${MACOSX_EXECUTABLE_NAME}</string>
 	<key>CFBundleGetInfoString</key>
 	<string>${MACOSX_BUNDLE_INFO_STRING}</string>
 	<key>CFBundleIconFile</key>
-- 
cgit v1.2.3


From a1a2b672accbcf6f309e01b4717013a7386484bb Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 12 Sep 2018 11:30:43 -0400
Subject: DRTVWR-474: Update to viewer-manager build 519565

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index f07cae8e81..67130a60fd 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3260,9 +3260,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>f45c0a5e7b4601b355e163bf62f5718e</string>
+              <string>cc08a265bd620a5c6756a6c8ddb104ef</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/20587/147509/viewer_manager-1.0.517052-darwin64-517052.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/24391/190021/viewer_manager-1.0.519565-darwin64-519565.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3284,9 +3284,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>d2443caf062697430071d458a965f611</string>
+              <string>40f0b7ecb420e0aa8761e434311e2d20</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/20588/147516/viewer_manager-1.0.517052-windows-517052.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/24393/190032/viewer_manager-1.0.519565-windows-519565.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3297,7 +3297,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>1.0.517052</string>
+        <string>1.0.519565</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From d56ef598f64807100febe5efd835fd287c5f9698 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 12 Sep 2018 12:12:30 -0400
Subject: DRTVWR-474: Update to viewer-manager build 519568

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 67130a60fd..c12cf8108b 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3260,9 +3260,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>cc08a265bd620a5c6756a6c8ddb104ef</string>
+              <string>7ce54dcea1607e7cb6a9cccd9a58e628</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/24391/190021/viewer_manager-1.0.519565-darwin64-519565.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/24396/190047/viewer_manager-2.0.519568-darwin64-519568.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3284,9 +3284,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>40f0b7ecb420e0aa8761e434311e2d20</string>
+              <string>8a06295a3b351b943d2b925eb589ff2b</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/24393/190032/viewer_manager-1.0.519565-windows-519565.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/24395/190053/viewer_manager-2.0.519568-windows-519568.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3297,7 +3297,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>1.0.519565</string>
+        <string>2.0.519568</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From 2081b8a654fa78c4414ec2619522c8ef461a1881 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 12 Sep 2018 12:15:41 -0400
Subject: DRTVWR-474: Make NSIS run new updater.exe after install.

But change shortcuts and registry entries and everything else back to the real
viewer executable, so that every subsequent run directly launches the viewer.

Eliminate SL_Launcher references from viewer_manifest.py.
---
 .../installers/windows/installer_template.nsi      | 41 ++++++++++++++--------
 indra/newview/viewer_manifest.py                   |  9 +++--
 2 files changed, 31 insertions(+), 19 deletions(-)

diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index 14c8dba39f..c53d7989fc 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -299,7 +299,7 @@ StrCpy $SHORTCUT_LANG_PARAM "--set InstallLanguage $(LanguageCode)"
 CreateDirectory	"$SMPROGRAMS\$INSTSHORTCUT"
 SetOutPath "$INSTDIR"
 CreateShortCut	"$SMPROGRAMS\$INSTSHORTCUT\$INSTSHORTCUT.lnk" \
-				"$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$VIEWER_EXE"
+				"$INSTDIR\$VIEWER_EXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$VIEWER_EXE"
 
 
 WriteINIStr		"$SMPROGRAMS\$INSTSHORTCUT\SL Create Account.url" \
@@ -317,9 +317,9 @@ CreateShortCut	"$SMPROGRAMS\$INSTSHORTCUT\Uninstall $INSTSHORTCUT.lnk" \
 # Other shortcuts
 SetOutPath "$INSTDIR"
 CreateShortCut "$DESKTOP\$INSTSHORTCUT.lnk" \
-        "$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$VIEWER_EXE"
+        "$INSTDIR\$VIEWER_EXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$VIEWER_EXE"
 CreateShortCut "$INSTDIR\$INSTSHORTCUT.lnk" \
-        "$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$VIEWER_EXE"
+        "$INSTDIR\$VIEWER_EXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$VIEWER_EXE"
 CreateShortCut "$INSTDIR\Uninstall $INSTSHORTCUT.lnk" \
 				'"$INSTDIR\uninst.exe"' ''
 
@@ -327,7 +327,7 @@ CreateShortCut "$INSTDIR\Uninstall $INSTSHORTCUT.lnk" \
 WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "" "$INSTDIR"
 WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Version" "${VERSION_LONG}"
 WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Shortcut" "$INSTSHORTCUT"
-WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Exe" "$INSTEXE"
+WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Exe" "$VIEWER_EXE"
 WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "Publisher" "Linden Research, Inc."
 WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "URLInfoAbout" "http://secondlife.com/whatis/"
 WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "URLUpdateInfo" "http://secondlife.com/support/downloads/"
@@ -338,10 +338,10 @@ WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninst
 WriteRegDWORD HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "EstimatedSize" "0x0001D500"		# ~117 MB
 
 # from FS:Ansariel
-WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "DisplayIcon" '"$INSTDIR\$INSTEXE"'
+WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "DisplayIcon" '"$INSTDIR\$VIEWER_EXE"'
 
 # BUG-2707 Disable SEHOP for installed viewer.
-WriteRegDWORD HKEY_LOCAL_MACHINE "Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\$INSTEXE" "DisableExceptionChainValidation" 1
+WriteRegDWORD HKEY_LOCAL_MACHINE "Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\$VIEWER_EXE" "DisableExceptionChainValidation" 1
 
 # Write URL registry info
 WriteRegStr HKEY_CLASSES_ROOT "${URLNAME}" "(default)" "URL:Second Life"
@@ -358,9 +358,8 @@ WriteRegStr HKEY_CLASSES_ROOT "x-grid-location-info\DefaultIcon" "" '"$INSTDIR\$
 # URL param must be last item passed to viewer, it ignores subsequent params to avoid parameter injection attacks.
 WriteRegExpandStr HKEY_CLASSES_ROOT "x-grid-location-info\shell\open\command" "" '"$INSTDIR\$VIEWER_EXE" -url "%1"'
 
-# Only allow Launcher to be the icon
-WriteRegStr HKEY_CLASSES_ROOT "Applications\$INSTEXE" "IsHostApp" ""
-WriteRegStr HKEY_CLASSES_ROOT "Applications\${VIEWER_EXE}" "NoStartPage" ""
+WriteRegStr HKEY_CLASSES_ROOT "Applications\$VIEWER_EXE" "IsHostApp" ""
+##WriteRegStr HKEY_CLASSES_ROOT "Applications\${VIEWER_EXE}" "NoStartPage" ""
 
 # Write out uninstaller
 WriteUninstaller "$INSTDIR\uninst.exe"
@@ -398,8 +397,8 @@ Call un.CloseSecondLife
 DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG"
 DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG"
 # BUG-2707 Remove entry that disabled SEHOP
-DeleteRegKey HKEY_LOCAL_MACHINE "Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\$INSTEXE"
-DeleteRegKey HKEY_CLASSES_ROOT "Applications\$INSTEXE"
+DeleteRegKey HKEY_LOCAL_MACHINE "Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\$VIEWER_EXE"
+##DeleteRegKey HKEY_CLASSES_ROOT "Applications\$INSTEXE"
 DeleteRegKey HKEY_CLASSES_ROOT "Applications\${VIEWER_EXE}"
 
 # Clean up shortcuts
@@ -537,6 +536,7 @@ Function RemoveProgFilesOnInst
 
 # Remove old SecondLife.exe to invalidate any old shortcuts to it that may be in non-standard locations. See MAINT-3575
 Delete "$INSTDIR\$INSTEXE"
+Delete "$INSTDIR\$VIEWER_EXE"
 
 # Remove old shader files first so fallbacks will work. See DEV-5663
 RMDir /r "$INSTDIR\app_settings\shaders"
@@ -673,7 +673,7 @@ FunctionEnd
 ;; After install completes, launch app
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 Function .onInstSuccess
-Call CheckWindowsServPack		# Warn if not on the latest SP before asking to launch.
+        Call CheckWindowsServPack		# Warn if not on the latest SP before asking to launch.
         Push $R0
         Push $0
         ;; MAINT-7812: Only write nsis.winstall file with /marker switch
@@ -694,8 +694,21 @@ Call CheckWindowsServPack		# Warn if not on the latest SP before asking to launc
         Pop $R0
         Push $R0					# Option value, unused# 
         StrCmp $SKIP_AUTORUN "true" +2;
-# Assumes SetOutPath $INSTDIR
-	Exec '"$WINDIR\explorer.exe" "$INSTDIR\$INSTSHORTCUT.lnk"'
+        # Assumes SetOutPath $INSTDIR
+        # Run INSTEXE (our updater), passing VIEWER_EXE plus the command-line
+        # arguments built into our shortcuts. This gives the updater a chance
+        # to verify that the viewer we just installed is appropriate for the
+        # running system -- or, if not, to download and install a different
+        # viewer. For instance, if a user running 32-bit Windows installs a
+        # 64-bit viewer, it cannot run on this system. But since the updater
+        # is a 32-bit executable even in the 64-bit viewer package, the
+        # updater can detect the problem and adapt accordingly.
+        # Once everything is in order, the updater will run the specified
+        # viewer with the specified params.
+        # Quote the updater executable and the viewer executable because each
+        # must be a distinct command-line token, but DO NOT quote the language
+        # string because it must decompose into separate command-line tokens.
+        Exec '"$INSTDIR\$INSTEXE" "$INSTDIR\VIEWER_EXE" $SHORTCUT_LANG_PARAM'
         Pop $R0
 # 
 FunctionEnd
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 5078f323ae..6540aa9f6b 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -490,7 +490,7 @@ class WindowsManifest(ViewerManifest):
 
             with self.prefix(src=os.path.join(pkgdir, "VMP"), dst=""):
                 # include the compiled launcher scripts so that it gets included in the file_list
-                self.path('SL_Launcher.exe')
+                self.path('updater.exe')
                 #IUM is not normally executed directly, just imported.  No exe needed.
                 self.path("InstallerUserMessage.py")
 
@@ -768,7 +768,7 @@ class WindowsManifest(ViewerManifest):
         substitution_strings['installer_file'] = installer_file
         
         version_vars = """
-        !define INSTEXE "SL_Launcher.exe"
+        !define INSTEXE "updater.exe"
         !define VERSION "%(version_short)s"
         !define VERSION_LONG "%(version)s"
         !define VERSION_DASHES "%(version_dashes)s"
@@ -812,7 +812,7 @@ class WindowsManifest(ViewerManifest):
         # note that the enclosing setup exe is signed later, after the makensis makes it.
         # Unlike the viewer binary, the VMP filenames are invariant with respect to version, os, etc.
         for exe in (
-            "SL_Launcher.exe",
+            "updater.exe",
             ):
             self.sign(exe)
             
@@ -1376,7 +1376,6 @@ class LinuxManifest(ViewerManifest):
             self.path2basename("../llplugin/slplugin", "SLPlugin") 
             #this copies over the python wrapper script, associated utilities and required libraries, see SL-321, SL-322 and SL-323
             with self.prefix(src="../viewer_components/manager", dst=""):
-                self.path("SL_Launcher")
                 self.path("*.py")
             with self.prefix(src=os.path.join("lib", "python", "llbase"), dst="llbase"):
                 self.path("*.py")
@@ -1455,7 +1454,7 @@ class LinuxManifest(ViewerManifest):
             self.run_command(
                 ["find"] +
                 [os.path.join(self.get_dst_prefix(), dir) for dir in ('bin', 'lib')] +
-                ['-type', 'f', '!', '-name', '*.py', '!', '-name', 'SL_Launcher',
+                ['-type', 'f', '!', '-name', '*.py',
                  '!', '-name', 'update_install', '-exec', 'strip', '-S', '{}', ';'])
 
 class Linux_i686_Manifest(LinuxManifest):
-- 
cgit v1.2.3


From 0c995db8dc90f64263d09a11274088a9b3df9305 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 12 Sep 2018 14:04:36 -0400
Subject: DRTVWR-474: Update to viewer-manager build 519577

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index c12cf8108b..6b87d5575a 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3260,9 +3260,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>7ce54dcea1607e7cb6a9cccd9a58e628</string>
+              <string>876dbbf0f479948488f04eae74dff04b</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/24396/190047/viewer_manager-2.0.519568-darwin64-519568.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/24410/190107/viewer_manager-2.0.519577-darwin64-519577.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3284,9 +3284,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>8a06295a3b351b943d2b925eb589ff2b</string>
+              <string>6616fec70baf8375ed3afca9767b6be5</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/24395/190053/viewer_manager-2.0.519568-windows-519568.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/24411/190113/viewer_manager-2.0.519577-windows-519577.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3297,7 +3297,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.519568</string>
+        <string>2.0.519577</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From d41245f252442d91432f06b039abea81831cc083 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 12 Sep 2018 20:13:53 -0400
Subject: DRTVWR-474: $VIEWER_EXE, rather than plain VIEWER_EXE

---
 indra/newview/installers/windows/installer_template.nsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index c53d7989fc..3117cf6b85 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -708,7 +708,7 @@ Function .onInstSuccess
         # Quote the updater executable and the viewer executable because each
         # must be a distinct command-line token, but DO NOT quote the language
         # string because it must decompose into separate command-line tokens.
-        Exec '"$INSTDIR\$INSTEXE" "$INSTDIR\VIEWER_EXE" $SHORTCUT_LANG_PARAM'
+        Exec '"$INSTDIR\$INSTEXE" "$INSTDIR\$VIEWER_EXE" $SHORTCUT_LANG_PARAM'
         Pop $R0
 # 
 FunctionEnd
-- 
cgit v1.2.3


From 289813994eb492d16e3af0fa30835e2b26a84ced Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 13 Sep 2018 16:20:05 -0400
Subject: DRTVWR-474: Clean up use of LLDir::getAppRODataDir(), esp. on Mac.

Clearly it's not obvious to maintainers that on the Mac, getAppRODataDir()
returns the app's Resources directory: in a number of places the code starts
with the executable directory and appends "../Resources" to find that.
---
 indra/llvfs/lldir_mac.cpp         |  4 ++--
 indra/llwindow/llwindowmacosx.cpp | 10 ++++------
 indra/newview/llstartup.cpp       |  3 +--
 indra/newview/llvoicevivox.cpp    |  9 ++++-----
 4 files changed, 11 insertions(+), 15 deletions(-)

diff --git a/indra/llvfs/lldir_mac.cpp b/indra/llvfs/lldir_mac.cpp
index 79c4362747..87dc1b9795 100644
--- a/indra/llvfs/lldir_mac.cpp
+++ b/indra/llvfs/lldir_mac.cpp
@@ -171,9 +171,9 @@ void LLDir_Mac::initAppDirs(const std::string &app_name,
 	if (!app_read_only_data_dir.empty())
 	{
 		mAppRODataDir = app_read_only_data_dir;
-		mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins";
+		mSkinBaseDir = add(mAppRODataDir, "skins");
 	}
-	mCAFile = getExpandedFilename(LL_PATH_EXECUTABLE, "../Resources", "ca-bundle.crt");
+	mCAFile = add(mAppRODataDir, "ca-bundle.crt");
 }
 
 std::string LLDir_Mac::getCurPath()
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 843294c239..d4afbb15df 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -1429,12 +1429,10 @@ static CursorRef gCursors[UI_CURSOR_COUNT];
 static void initPixmapCursor(int cursorid, int hotspotX, int hotspotY)
 {
 	// cursors are in <Application Bundle>/Contents/Resources/cursors_mac/UI_CURSOR_FOO.tif
-	std::string fullpath = gDirUtilp->getAppRODataDir();
-	fullpath += gDirUtilp->getDirDelimiter();
-	fullpath += "cursors_mac";
-	fullpath += gDirUtilp->getDirDelimiter();
-	fullpath += cursorIDToName(cursorid);
-	fullpath += ".tif";
+	std::string fullpath = gDirUtilp->add(
+		gDirUtilp->getAppRODataDir(),
+		"cursors_mac",
+		cursorIDToName(cursorid) + std::string(".tif"));
 
 	gCursors[cursorid] = createImageCursor(fullpath.c_str(), hotspotX, hotspotY);
 }
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 7a4c41779a..4c51873715 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -479,8 +479,7 @@ bool idle_startup()
 			if (!found_template)
 			{
 				message_template_path =
-					gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE,
-												   "../Resources/app_settings",
+					gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,
 												   "message_template.msg");
 				found_template = LLFile::fopen(message_template_path.c_str(), "r");		/* Flawfinder: ignore */
 			}		
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index b90e09b739..88d17a31a4 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -770,14 +770,13 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()
     {
 #ifndef VIVOXDAEMON_REMOTEHOST
         // Launch the voice daemon
-        std::string exe_path = gDirUtilp->getExecutableDir();
-        exe_path += gDirUtilp->getDirDelimiter();
+        std::string exe_path = gDirUtilp->getAppRODataDir();
 #if LL_WINDOWS
-        exe_path += "SLVoice.exe";
+        gDirUtilp->append(exe_path, "SLVoice.exe");
 #elif LL_DARWIN
-        exe_path += "../Resources/SLVoice";
+        gDirUtilp->append(exe_path, "SLVoice");
 #else
-        exe_path += "SLVoice";
+        gDirUtilp->append(exe_path, "SLVoice");
 #endif
         // See if the vivox executable exists
         llstat s;
-- 
cgit v1.2.3


From 08fefb454bfbf98e90e95af329b21d7e6e146330 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 13 Sep 2018 16:21:50 -0400
Subject: DRTVWR-474: Update to viewer-manager build 519640

---
 autobuild.xml | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 6b87d5575a..1277f70b0b 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3248,7 +3248,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>description</key>
         <string>Linden Lab Viewer Management Process suite.</string>
         <key>license</key>
-        <string>Proprietary</string>
+        <string>viewerlgpl</string>
         <key>license_file</key>
         <string>LICENSE</string>
         <key>name</key>
@@ -3260,9 +3260,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>876dbbf0f479948488f04eae74dff04b</string>
+              <string>952c2e32e37ef67115ba3074892961c3</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/24410/190107/viewer_manager-2.0.519577-darwin64-519577.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/24508/190821/viewer_manager-2.0.519640-darwin64-519640.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3284,9 +3284,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>6616fec70baf8375ed3afca9767b6be5</string>
+              <string>7c8b210c1687a100f0b295d60ffac2c5</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/24411/190113/viewer_manager-2.0.519577-windows-519577.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/24507/190827/viewer_manager-2.0.519640-windows-519640.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3297,7 +3297,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.519577</string>
+        <string>2.0.519640</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From 83b40329fd822277ff5b47e6f36a7897c85e6260 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 13 Sep 2018 16:22:38 -0400
Subject: DRTVWR-474: Make NSIS installer invoke updater precheck subcommand.

---
 indra/newview/installers/windows/installer_template.nsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index 3117cf6b85..76187b49a5 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -708,7 +708,7 @@ Function .onInstSuccess
         # Quote the updater executable and the viewer executable because each
         # must be a distinct command-line token, but DO NOT quote the language
         # string because it must decompose into separate command-line tokens.
-        Exec '"$INSTDIR\$INSTEXE" "$INSTDIR\$VIEWER_EXE" $SHORTCUT_LANG_PARAM'
+        Exec '"$INSTDIR\$INSTEXE" precheck "$INSTDIR\$VIEWER_EXE" $SHORTCUT_LANG_PARAM'
         Pop $R0
 # 
 FunctionEnd
-- 
cgit v1.2.3


From cc99cd65cf0355f201157d8f71743899af6f2ade Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 13 Sep 2018 16:23:45 -0400
Subject: DRTVWR-474: Copy updater and its icons into Mac app's Resources.

---
 indra/newview/viewer_manifest.py | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 6540aa9f6b..32ff7f6ea8 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -470,7 +470,7 @@ class WindowsManifest(ViewerManifest):
                     pass
                 except NoMatchingAssemblyException as err:
                     pass
-                    
+
                 self.ccopy(src,dst)
             else:
                 raise Exception("Directories are not supported by test_CRT_and_copy_action()")
@@ -916,6 +916,15 @@ class DarwinManifest(ViewerManifest):
                 with self.prefix(src=self.icon_path(), dst="") :
                     self.path("secondlife.icns")
 
+                # Copy in the updater script and helper modules
+                self.path(src=os.path.join(pkgdir, 'VMP'), dst="updater")
+
+                with self.prefix(src="", dst=os.path.join("updater", "icons")):
+                    self.path2basename(os.path.join(self.icon_path(), "secondlife.ico"))
+                    with self.prefix(src="vmp_icons", dst=""):
+                        self.path("*.png")
+                        self.path("*.gif")
+
                 with self.prefix(src=relpkgdir, dst=""):
                     self.path("libndofdev.dylib")
                     self.path("libhunspell-1.3.0.dylib")   
-- 
cgit v1.2.3


From a6e2201d2cff8fe03c83a75a2766d1ab71d35a21 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 13 Sep 2018 16:24:53 -0400
Subject: DRTVWR-474: Run the new updater in LEAP mode.

---
 indra/newview/llappviewer.cpp | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index dd1d4cea39..68bb20386a 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1130,6 +1130,21 @@ bool LLAppViewer::init()
 
 	gGLActive = FALSE;
 
+#if LL_WINDOWS
+	std::string updater(
+		"\"" + gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "updater.exe") + "\"");
+#elif LL_DARWIN
+	std::string updater(
+		"python \"" + gDirUtilp->add(gDirUtilp->getAppRODataDir(), "updater", "updater.py") + "\"");
+#else
+	std::string updater(
+		"\"" + gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "updater") + "\"");
+#endif
+
+	// Run the updater, specifying LEAP mode. An exception from the updater
+	// should bother us.
+	LLLeap::create("updater process", (updater + " leap"), true);
+
 	// Iterate over --leap command-line options. But this is a bit tricky: if
 	// there's only one, it won't be an array at all.
 	LLSD LeapCommand(gSavedSettings.getLLSD("LeapCommand"));
-- 
cgit v1.2.3


From e00a8dee3f9675296df5c614b4483509c2ff55bb Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 13 Sep 2018 20:26:21 -0400
Subject: DRTVWR-474: Fix path2basename("secondlife.ico") call.

---
 indra/newview/viewer_manifest.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 32ff7f6ea8..4f0f4b17d9 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -920,7 +920,7 @@ class DarwinManifest(ViewerManifest):
                 self.path(src=os.path.join(pkgdir, 'VMP'), dst="updater")
 
                 with self.prefix(src="", dst=os.path.join("updater", "icons")):
-                    self.path2basename(os.path.join(self.icon_path(), "secondlife.ico"))
+                    self.path2basename(self.icon_path(), "secondlife.ico")
                     with self.prefix(src="vmp_icons", dst=""):
                         self.path("*.png")
                         self.path("*.gif")
-- 
cgit v1.2.3


From 807992adca4708bd2050b1fee8074d3e4521dd30 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 13 Sep 2018 20:55:05 -0400
Subject: DRTVWR-474: Pass updater cmd to LLLeap::create() as vector<string>.

This avoids having to tokenize a single string, avoiding swallowing
backslashes in Windows pathnames in the mistaken belief they're escape
characters. Alternatively, it avoids us having to double-escape them or
convert them to forward slashes or whatever.
---
 indra/newview/llappviewer.cpp | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 68bb20386a..c0fcdd7c79 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1131,19 +1131,21 @@ bool LLAppViewer::init()
 	gGLActive = FALSE;
 
 #if LL_WINDOWS
-	std::string updater(
-		"\"" + gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "updater.exe") + "\"");
+	std::vector<std::string> updater
+		{ gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "updater.exe") };
 #elif LL_DARWIN
-	std::string updater(
-		"python \"" + gDirUtilp->add(gDirUtilp->getAppRODataDir(), "updater", "updater.py") + "\"");
+	// explicitly run the system Python interpreter on updater.py
+	std::vector<std::string> updater
+		{ "python", gDirUtilp->add(gDirUtilp->getAppRODataDir(), "updater", "updater.py") };
 #else
-	std::string updater(
-		"\"" + gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "updater") + "\"");
+	std::vector<std::string> updater
+		{ gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "updater") };
 #endif
+	// add LEAP mode command-line argument to whichever of these we selected
+	updater.push_back("leap");
 
-	// Run the updater, specifying LEAP mode. An exception from the updater
-	// should bother us.
-	LLLeap::create("updater process", (updater + " leap"), true);
+	// Run the updater. An exception from the updater should bother us.
+	LLLeap::create("updater process", updater, true);
 
 	// Iterate over --leap command-line options. But this is a bit tricky: if
 	// there's only one, it won't be an array at all.
-- 
cgit v1.2.3


From 8761e87ac526034f7a601eee5fdb667eba6eefda Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 24 Sep 2018 14:02:23 -0400
Subject: DRTVWR-474: Remove Python autobuild packages and references to them.

We expect the viewer-manager package to be self-contained: we expect it to
bring with it any Python packages it requires. We no longer force developers
to wrap third-party Python packages as autobuild packages.
---
 autobuild.xml                    | 176 ---------------------------------------
 indra/cmake/LLBase.cmake         |   4 -
 indra/cmake/Requests.cmake       |   7 --
 indra/newview/CMakeLists.txt     |   2 -
 indra/newview/viewer_manifest.py |   8 --
 5 files changed, 197 deletions(-)
 delete mode 100644 indra/cmake/LLBase.cmake
 delete mode 100644 indra/cmake/Requests.cmake

diff --git a/autobuild.xml b/autobuild.xml
index 1277f70b0b..29066d7c49 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -225,36 +225,6 @@
         <key>version</key>
         <string>1.57</string>
       </map>
-      <key>chardet</key>
-      <map>
-        <key>copyright</key>
-        <string>Contributors to charset (see https://github.com/chardet/chardet)</string>
-        <key>description</key>
-        <string>Python Character Encoding Library</string>
-        <key>license</key>
-        <string>LGPL</string>
-        <key>license_file</key>
-        <string>LICENSES/chardet.txt</string>
-        <key>name</key>
-        <string>chardet</string>
-        <key>platforms</key>
-        <map>
-          <key>darwin64</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>0124862b6a1b88455c78a68f8b823d21</string>
-              <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6662/23578/chardet-3.0.4-darwin64-506651.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>darwin64</string>
-          </map>
-        </map>
-        <key>version</key>
-        <string>3.0.4</string>
-      </map>
       <key>colladadom</key>
       <map>
         <key>copyright</key>
@@ -1465,36 +1435,6 @@
         <key>version</key>
         <string>2012.1-2</string>
       </map>
-      <key>idna</key>
-      <map>
-        <key>copyright</key>
-        <string>Copyright (c) 2013-2017, Kim Davies. All rights reserved.</string>
-        <key>description</key>
-        <string>Python Internationalized Domain Names in Applications (IDNA) Library</string>
-        <key>license</key>
-        <string>see idna.rst</string>
-        <key>license_file</key>
-        <string>LICENSES/idna.rst</string>
-        <key>name</key>
-        <string>idna</string>
-        <key>platforms</key>
-        <map>
-          <key>darwin64</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>7dfe9fc4023d7d4f511dd9fac7258266</string>
-              <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6663/23584/idna-2.5-darwin64-506652.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>darwin64</string>
-          </map>
-        </map>
-        <key>version</key>
-        <string>2.5</string>
-      </map>
       <key>jpeglib</key>
       <map>
         <key>copyright</key>
@@ -2173,46 +2113,6 @@
         <key>version</key>
         <string>0.0.1</string>
       </map>
-      <key>llbase</key>
-      <map>
-        <key>copyright</key>
-        <string>Copyright (c) 2010, Linden Research, Inc.</string>
-        <key>license</key>
-        <string>mit</string>
-        <key>license_file</key>
-        <string>LICENSES/llbase-license.txt</string>
-        <key>name</key>
-        <string>llbase</string>
-        <key>platforms</key>
-        <map>
-          <key>darwin64</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>e18eeb0691af053b83bd46b76c6ee86a</string>
-              <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6299/21982/llbase-0.9.3.506286-darwin64-506286.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>darwin64</string>
-          </map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>e6865670f9bca1c82fb8b91db3ea515c</string>
-              <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6301/21994/llbase-0.9.3.506286-windows-506286.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>windows</string>
-          </map>
-        </map>
-        <key>version</key>
-        <string>0.9.3.506286</string>
-      </map>
       <key>llca</key>
       <map>
         <key>copyright</key>
@@ -2955,52 +2855,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>version</key>
         <string>8.35.500898</string>
       </map>
-      <key>requests</key>
-      <map>
-        <key>copyright</key>
-        <string>Copyright 2016 Kenneth Reitz</string>
-        <key>description</key>
-        <string>Python HTTP Library</string>
-        <key>license</key>
-        <string>Apache</string>
-        <key>license_file</key>
-        <string>LICENSES/requests.txt</string>
-        <key>name</key>
-        <string>requests</string>
-        <key>platforms</key>
-        <map>
-          <key>darwin64</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>b8d134a970261b445a3f376ba4e05ff7</string>
-              <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6693/23788/requests-2.18.1-darwin64-506681.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>darwin64</string>
-          </map>
-          <key>linux64</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>a92f2235991871c3d601a73cfef9b2af</string>
-              <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/4105/11530/requests-1.0-linux64-504094.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>linux64</string>
-          </map>
-        </map>
-        <key>source</key>
-        <string>https://bitbucket.org/lindenlab/p64_python-requests</string>
-        <key>source_type</key>
-        <string>hg</string>
-        <key>version</key>
-        <string>2.18.1</string>
-      </map>
       <key>slvoice</key>
       <map>
         <key>copyright</key>
@@ -3211,36 +3065,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>version</key>
         <string>0.8.0.1</string>
       </map>
-      <key>urllib3</key>
-      <map>
-        <key>copyright</key>
-        <string>Copyright 2008-2016 Andrey Petrov and contributors (see CONTRIBUTORS.txt)</string>
-        <key>description</key>
-        <string>Python HTTP Library</string>
-        <key>license</key>
-        <string>MIT</string>
-        <key>license_file</key>
-        <string>LICENSES/urllib3.txt</string>
-        <key>name</key>
-        <string>urllib3</string>
-        <key>platforms</key>
-        <map>
-          <key>darwin64</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>22f64c7fbb6704d2e9519fd1cca8e49b</string>
-              <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6659/23560/urllib3-1.21.1-darwin64-506648.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>darwin64</string>
-          </map>
-        </map>
-        <key>version</key>
-        <string>1.21.1</string>
-      </map>
       <key>viewer-manager</key>
       <map>
         <key>copyright</key>
diff --git a/indra/cmake/LLBase.cmake b/indra/cmake/LLBase.cmake
deleted file mode 100644
index 76e3c688a3..0000000000
--- a/indra/cmake/LLBase.cmake
+++ /dev/null
@@ -1,4 +0,0 @@
-# -*- cmake -*-
-include(Prebuilt)
-
-use_prebuilt_binary(llbase)
diff --git a/indra/cmake/Requests.cmake b/indra/cmake/Requests.cmake
deleted file mode 100644
index b9c729d697..0000000000
--- a/indra/cmake/Requests.cmake
+++ /dev/null
@@ -1,7 +0,0 @@
-if (DARWIN)
-   include (Prebuilt)
-   use_prebuilt_binary(requests)
-   use_prebuilt_binary(urllib3)
-   use_prebuilt_binary(chardet)
-   use_prebuilt_binary(idna)
-endif (DARWIN)
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 212677717e..e7111ebe54 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -16,7 +16,6 @@ include(GLOD)
 include(Hunspell)
 include(JsonCpp)
 include(LLAppearance)
-include(LLBase)
 include(LLAudio)
 include(LLCA)
 include(LLCharacter)
@@ -44,7 +43,6 @@ include(OPENAL)
 include(OpenGL)
 include(OpenSSL)
 include(PNG)
-include(Requests)
 include(TemplateCheck)
 include(UI)
 include(UnixInstall)
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 4f0f4b17d9..57da87a3ee 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -502,11 +502,6 @@ class WindowsManifest(ViewerManifest):
                 self.path("*.png")
                 self.path("*.gif")
 
-            #before, we only needed llbase at build time.  With VMP, we need it at run time.
-            with self.prefix(src=os.path.join(pkgdir, "lib", "python", "llbase"), dst="llbase"):
-                self.path("*.py")
-                self.path("_cllsd.so")
-
         # Plugin host application
         self.path2basename(os.path.join(os.pardir,
                                         'llplugin', 'slplugin', self.args['configuration']),
@@ -1386,9 +1381,6 @@ class LinuxManifest(ViewerManifest):
             #this copies over the python wrapper script, associated utilities and required libraries, see SL-321, SL-322 and SL-323
             with self.prefix(src="../viewer_components/manager", dst=""):
                 self.path("*.py")
-            with self.prefix(src=os.path.join("lib", "python", "llbase"), dst="llbase"):
-                self.path("*.py")
-                self.path("_cllsd.so")         
 
         # recurses, packaged again
         self.path("res-sdl")
-- 
cgit v1.2.3


From cc376f86e8496e9e924fd596064c13ee6aa0133e Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 25 Sep 2018 11:21:34 -0400
Subject: DRTVWR-474: Update to viewer-manager build 519951

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 29066d7c49..7f18ab9abf 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3084,9 +3084,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>952c2e32e37ef67115ba3074892961c3</string>
+              <string>904caf508ec1718e1fc9cd321ad95715</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/24508/190821/viewer_manager-2.0.519640-darwin64-519640.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/24994/196128/viewer_manager-2.0.519951-darwin64-519951.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3108,9 +3108,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>7c8b210c1687a100f0b295d60ffac2c5</string>
+              <string>e7f7ed2d40c1e554d038276fef690639</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/24507/190827/viewer_manager-2.0.519640-windows-519640.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/24996/196136/viewer_manager-2.0.519951-windows-519951.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3121,7 +3121,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.519640</string>
+        <string>2.0.519951</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From 267e7d7554a4c11e8d745be3657eed923fa65876 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 26 Sep 2018 16:37:14 -0400
Subject: DRTVWR-474: Finish pulling in new viewer-release.

---
 autobuild.xml | 188 ++--------------------------------------------------------
 1 file changed, 6 insertions(+), 182 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 3107d77548..7f18ab9abf 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -225,36 +225,6 @@
         <key>version</key>
         <string>1.57</string>
       </map>
-      <key>chardet</key>
-      <map>
-        <key>copyright</key>
-        <string>Contributors to charset (see https://github.com/chardet/chardet)</string>
-        <key>description</key>
-        <string>Python Character Encoding Library</string>
-        <key>license</key>
-        <string>LGPL</string>
-        <key>license_file</key>
-        <string>LICENSES/chardet.txt</string>
-        <key>name</key>
-        <string>chardet</string>
-        <key>platforms</key>
-        <map>
-          <key>darwin64</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>0124862b6a1b88455c78a68f8b823d21</string>
-              <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6662/23578/chardet-3.0.4-darwin64-506651.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>darwin64</string>
-          </map>
-        </map>
-        <key>version</key>
-        <string>3.0.4</string>
-      </map>
       <key>colladadom</key>
       <map>
         <key>copyright</key>
@@ -1465,36 +1435,6 @@
         <key>version</key>
         <string>2012.1-2</string>
       </map>
-      <key>idna</key>
-      <map>
-        <key>copyright</key>
-        <string>Copyright (c) 2013-2017, Kim Davies. All rights reserved.</string>
-        <key>description</key>
-        <string>Python Internationalized Domain Names in Applications (IDNA) Library</string>
-        <key>license</key>
-        <string>see idna.rst</string>
-        <key>license_file</key>
-        <string>LICENSES/idna.rst</string>
-        <key>name</key>
-        <string>idna</string>
-        <key>platforms</key>
-        <map>
-          <key>darwin64</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>7dfe9fc4023d7d4f511dd9fac7258266</string>
-              <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6663/23584/idna-2.5-darwin64-506652.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>darwin64</string>
-          </map>
-        </map>
-        <key>version</key>
-        <string>2.5</string>
-      </map>
       <key>jpeglib</key>
       <map>
         <key>copyright</key>
@@ -2173,46 +2113,6 @@
         <key>version</key>
         <string>0.0.1</string>
       </map>
-      <key>llbase</key>
-      <map>
-        <key>copyright</key>
-        <string>Copyright (c) 2010, Linden Research, Inc.</string>
-        <key>license</key>
-        <string>mit</string>
-        <key>license_file</key>
-        <string>LICENSES/llbase-license.txt</string>
-        <key>name</key>
-        <string>llbase</string>
-        <key>platforms</key>
-        <map>
-          <key>darwin64</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>e18eeb0691af053b83bd46b76c6ee86a</string>
-              <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6299/21982/llbase-0.9.3.506286-darwin64-506286.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>darwin64</string>
-          </map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>e6865670f9bca1c82fb8b91db3ea515c</string>
-              <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6301/21994/llbase-0.9.3.506286-windows-506286.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>windows</string>
-          </map>
-        </map>
-        <key>version</key>
-        <string>0.9.3.506286</string>
-      </map>
       <key>llca</key>
       <map>
         <key>copyright</key>
@@ -2955,52 +2855,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>version</key>
         <string>8.35.500898</string>
       </map>
-      <key>requests</key>
-      <map>
-        <key>copyright</key>
-        <string>Copyright 2016 Kenneth Reitz</string>
-        <key>description</key>
-        <string>Python HTTP Library</string>
-        <key>license</key>
-        <string>Apache</string>
-        <key>license_file</key>
-        <string>LICENSES/requests.txt</string>
-        <key>name</key>
-        <string>requests</string>
-        <key>platforms</key>
-        <map>
-          <key>darwin64</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>b8d134a970261b445a3f376ba4e05ff7</string>
-              <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6693/23788/requests-2.18.1-darwin64-506681.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>darwin64</string>
-          </map>
-          <key>linux64</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>a92f2235991871c3d601a73cfef9b2af</string>
-              <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/4105/11530/requests-1.0-linux64-504094.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>linux64</string>
-          </map>
-        </map>
-        <key>source</key>
-        <string>https://bitbucket.org/lindenlab/p64_python-requests</string>
-        <key>source_type</key>
-        <string>hg</string>
-        <key>version</key>
-        <string>2.18.1</string>
-      </map>
       <key>slvoice</key>
       <map>
         <key>copyright</key>
@@ -3211,36 +3065,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>version</key>
         <string>0.8.0.1</string>
       </map>
-      <key>urllib3</key>
-      <map>
-        <key>copyright</key>
-        <string>Copyright 2008-2016 Andrey Petrov and contributors (see CONTRIBUTORS.txt)</string>
-        <key>description</key>
-        <string>Python HTTP Library</string>
-        <key>license</key>
-        <string>MIT</string>
-        <key>license_file</key>
-        <string>LICENSES/urllib3.txt</string>
-        <key>name</key>
-        <string>urllib3</string>
-        <key>platforms</key>
-        <map>
-          <key>darwin64</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>22f64c7fbb6704d2e9519fd1cca8e49b</string>
-              <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6659/23560/urllib3-1.21.1-darwin64-506648.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>darwin64</string>
-          </map>
-        </map>
-        <key>version</key>
-        <string>1.21.1</string>
-      </map>
       <key>viewer-manager</key>
       <map>
         <key>copyright</key>
@@ -3248,7 +3072,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>description</key>
         <string>Linden Lab Viewer Management Process suite.</string>
         <key>license</key>
-        <string>Proprietary</string>
+        <string>viewerlgpl</string>
         <key>license_file</key>
         <string>LICENSE</string>
         <key>name</key>
@@ -3260,9 +3084,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>ce95944fb842849108102263a25fc794</string>
+              <string>904caf508ec1718e1fc9cd321ad95715</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/23237/178332/viewer_manager-1.0.518840-darwin64-518840.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/24994/196128/viewer_manager-2.0.519951-darwin64-519951.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3284,9 +3108,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>642f847a9ac45551af65a55826974334</string>
+              <string>e7f7ed2d40c1e554d038276fef690639</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/23236/178338/viewer_manager-1.0.518840-windows-518840.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/24996/196136/viewer_manager-2.0.519951-windows-519951.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3297,7 +3121,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>1.0.518840</string>
+        <string>2.0.519951</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From fc8b4ec587d8a05579244940e30b81519a1ebf91 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 26 Sep 2018 16:50:58 -0400
Subject: DRTVWR-447: Finish pulling in new viewer-release.

---
 autobuild.xml              | 54 ++++++++++++++++++++++++++++++++++++++++++++++
 indra/llcommon/llerror.cpp | 27 ++++++++++++++++-------
 2 files changed, 73 insertions(+), 8 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 3107d77548..f615a52ba8 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -225,6 +225,60 @@
         <key>version</key>
         <string>1.57</string>
       </map>
+      <key>bugsplat</key>
+      <map>
+        <key>copyright</key>
+        <string>Copyright 2003-2017, BugSplat</string>
+        <key>description</key>
+        <string>Bugsplat crash reporting package</string>
+        <key>license</key>
+        <string>Proprietary</string>
+        <key>license_file</key>
+        <string>LICENSES/BUGSPLAT_LICENSE.txt</string>
+        <key>name</key>
+        <string>bugsplat</string>
+        <key>platforms</key>
+        <map>
+          <key>darwin64</key>
+          <map>
+            <key>archive</key>
+            <map>
+              <key>hash</key>
+              <string>7a7bd828233e8a2b0e9c022f6219e6e7</string>
+              <key>url</key>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23730/182106/bugsplat-1.0.6.519145-darwin64-519145.tar.bz2</string>
+            </map>
+            <key>name</key>
+            <string>darwin64</string>
+          </map>
+          <key>windows</key>
+          <map>
+            <key>archive</key>
+            <map>
+              <key>hash</key>
+              <string>a3938332a11215e6909d67d1b9be5259</string>
+              <key>url</key>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23732/182120/bugsplat-3.6.0.4.519145-windows-519145.tar.bz2</string>
+            </map>
+            <key>name</key>
+            <string>windows</string>
+          </map>
+          <key>windows64</key>
+          <map>
+            <key>archive</key>
+            <map>
+              <key>hash</key>
+              <string>453d624d87a80779f59cfb1880613d90</string>
+              <key>url</key>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23731/182115/bugsplat-3.6.0.4.519145-windows64-519145.tar.bz2</string>
+            </map>
+            <key>name</key>
+            <string>windows64</string>
+          </map>
+        </map>
+        <key>version</key>
+        <string>1.0.6.519145</string>
+      </map>
       <key>chardet</key>
       <map>
         <key>copyright</key>
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index 06c7aef8ab..6dfb4bf028 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -368,6 +368,7 @@ namespace
 	public:
 		std::ostringstream messageStream;
 		bool messageStreamInUse;
+		std::string mFatalMessage;
 
 		void addCallSite(LLError::CallSite&);
 		void invalidateCallSites();
@@ -666,11 +667,16 @@ namespace LLError
 		s->mCrashFunction = f;
 	}
 
-    FatalFunction getFatalFunction()
-    {
+	FatalFunction getFatalFunction()
+	{
 		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
-        return s->mCrashFunction;
-    }
+		return s->mCrashFunction;
+	}
+
+	std::string getFatalMessage()
+	{
+		return Globals::getInstance()->mFatalMessage;
+	}
 
 	void setTimeFunction(TimeFunction f)
 	{
@@ -1256,12 +1262,17 @@ namespace LLError
 		}
 		
 		addEscapedMessage(message_stream, message);
+		std::string message_line(message_stream.str());
 
-		writeToRecorders(site, message_stream.str());
-		
-		if (site.mLevel == LEVEL_ERROR  &&  s->mCrashFunction)
+		writeToRecorders(site, message_line);
+
+		if (site.mLevel == LEVEL_ERROR)
 		{
-			s->mCrashFunction(message_stream.str());
+			g->mFatalMessage = message_line;
+			if (s->mCrashFunction)
+			{
+				s->mCrashFunction(message_line);
+			}
 		}
 	}
 }
-- 
cgit v1.2.3


From 0497b8a537f6549e287c789d661728b850763c79 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 26 Sep 2018 20:43:37 -0400
Subject: DRTVWR-447: Update to viewer-manager build 520046

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index f615a52ba8..4c97752da1 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3314,9 +3314,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>ce95944fb842849108102263a25fc794</string>
+              <string>4785e25bde1503e99cb4c2fe344b3d4e</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/23237/178332/viewer_manager-1.0.518840-darwin64-518840.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/25165/197744/viewer_manager-1.0.520046-darwin64-520046.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3338,9 +3338,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>642f847a9ac45551af65a55826974334</string>
+              <string>b03866283b2cf3d8a79a93a07cbec9d6</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/23236/178338/viewer_manager-1.0.518840-windows-518840.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/25166/197758/viewer_manager-1.0.520046-windows-520046.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3351,7 +3351,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>1.0.518840</string>
+        <string>1.0.520046</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From e1826d508c7bb5edc3917e090ad087b0b3a754cb Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 26 Sep 2018 20:45:03 -0400
Subject: DRTVWR-474: Update to viewer-manager build 520047

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 7f18ab9abf..7f7cf02073 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3084,9 +3084,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>904caf508ec1718e1fc9cd321ad95715</string>
+              <string>0a1471744de42317b9462f0d9ddcc691</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/24994/196128/viewer_manager-2.0.519951-darwin64-519951.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/25167/197752/viewer_manager-2.0.520047-darwin64-520047.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3108,9 +3108,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>e7f7ed2d40c1e554d038276fef690639</string>
+              <string>278eb5ff960846ae69626880a2afa05a</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/24996/196136/viewer_manager-2.0.519951-windows-519951.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/25168/197765/viewer_manager-2.0.520047-windows-520047.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3121,7 +3121,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.519951</string>
+        <string>2.0.520047</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From ec6487f3a70a5067f6d8fc601437160bb4fa753f Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 27 Sep 2018 14:57:03 -0400
Subject: DRTVWR-474: Make LLEventMailDrop pass all saved events to listener.

Previously, LLEventMailDrop would send only the first queued event to a
newly-connected listener. If you wanted to flush all queued events, you'd have
to "pump" the queue by repeatedly disconnecting and reconnecting -- with no
good way to know when you'd caught up.

The new behavior makes LLEventMailDrop resemble a multi-valued future: a
rendezvous between producer and consumer that, once connected, pushes values
rather than requiring them to be pulled (as with a simple queue) -- regardless
of the relative order in which post() and listen() are called.
---
 indra/llcommon/llevents.cpp | 23 +++++++++++++++--------
 indra/llcommon/llevents.h   | 20 +++++++++++++-------
 2 files changed, 28 insertions(+), 15 deletions(-)

diff --git a/indra/llcommon/llevents.cpp b/indra/llcommon/llevents.cpp
index dce97b5411..eedd8c92b5 100644
--- a/indra/llcommon/llevents.cpp
+++ b/indra/llcommon/llevents.cpp
@@ -545,10 +545,8 @@ bool LLEventStream::post(const LLSD& event)
  *****************************************************************************/
 bool LLEventMailDrop::post(const LLSD& event)
 {
-    bool posted = false;
-    
-    if (!mSignal->empty())
-        posted = LLEventStream::post(event);
+    // forward the call to our base class
+    bool posted = LLEventStream::post(event);
     
     if (!posted)
     {   // if the event was not handled we will save it for later so that it can 
@@ -564,16 +562,25 @@ LLBoundListener LLEventMailDrop::listen_impl(const std::string& name,
                                     const NameList& after,
                                     const NameList& before)
 {
-    if (!mEventHistory.empty())
+    // Before actually connecting this listener for subsequent post() calls,
+    // first feed each of the saved events, in order, to the new listener.
+    // Remove any that this listener consumes -- Effective STL, Item 9.
+    for (auto hi(mEventHistory.begin()), hend(mEventHistory.end()); hi != hend; )
     {
-        if (listener(mEventHistory.front()))
+        if (listener(*hi))
         {
-            mEventHistory.pop_front();
+            // new listener consumed this event, erase it
+            hi = mEventHistory.erase(hi);
+        }
+        else
+        {
+            // listener did not consume this event, just move along
+            ++hi;
         }
     }
 
+    // let base class perform the actual connection
     return LLEventStream::listen_impl(name, listener, after, before);
-
 }
 
 
diff --git a/indra/llcommon/llevents.h b/indra/llcommon/llevents.h
index 1d51c660ed..5d60c63810 100644
--- a/indra/llcommon/llevents.h
+++ b/indra/llcommon/llevents.h
@@ -650,15 +650,21 @@ public:
  *   LLEventMailDrop
  *****************************************************************************/
 /**
- * LLEventMailDrop is a specialization of LLEventStream. Events are posted normally, 
- * however if no listeners return that they have handled the event it is placed in 
- * a queue. Subsequent attaching listeners will receive stored events from the queue 
- * until a listener indicates that the event has been handled.  In order to receive 
- * multiple events from a mail drop the listener must disconnect and reconnect.
+ * LLEventMailDrop is a specialization of LLEventStream. Events are posted
+ * normally, however if no listener returns that it has handled the event
+ * (returns true), it is placed in a queue. Subsequent attaching listeners
+ * will receive stored events from the queue until some listener indicates
+ * that the event has been handled.
+ *
+ * LLEventMailDrop completely decouples the timing of post() calls from
+ * listen() calls: every event posted to an LLEventMailDrop is eventually seen
+ * by all listeners, until some listener consumes it. The caveat is that each
+ * event *must* eventually reach a listener that will consume it, else the
+ * queue will grow to arbitrary length.
  * 
  * @NOTE: When using an LLEventMailDrop (or LLEventQueue) with a LLEventTimeout or
- * LLEventFilter attaching the filter downstream using Timeout's constructor will
- * cause the MailDrop to discharge any of it's stored events. The timeout should 
+ * LLEventFilter attaching the filter downstream, using Timeout's constructor will
+ * cause the MailDrop to discharge any of its stored events. The timeout should 
  * instead be connected upstream using its listen() method.  
  * See llcoro::suspendUntilEventOnWithTimeout() for an example.
  */
-- 
cgit v1.2.3


From 371a412a28377527b9aede016e9b482df95ea901 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 27 Sep 2018 17:40:10 -0400
Subject: DRTVWR-474: Update to viewer-manager build 520085

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 7f7cf02073..243954a9ba 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3084,9 +3084,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>0a1471744de42317b9462f0d9ddcc691</string>
+              <string>0a254644186f5523b0261d9427bf3e31</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/25167/197752/viewer_manager-2.0.520047-darwin64-520047.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/25233/198295/viewer_manager-2.0.520085-darwin64-520085.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3108,9 +3108,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>278eb5ff960846ae69626880a2afa05a</string>
+              <string>fee2780a7172732633cd115fdc7925ff</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/25168/197765/viewer_manager-2.0.520047-windows-520047.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/25234/198302/viewer_manager-2.0.520085-windows-520085.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3121,7 +3121,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.520047</string>
+        <string>2.0.520085</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From 182a091ad961fb296aafc974509746a4dff54421 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 27 Sep 2018 17:41:26 -0400
Subject: DRTVWR-474: Pass the leap updater the parameters it requires.

---
 indra/newview/app_settings/settings.xml | 11 +++++++++++
 indra/newview/llappviewer.cpp           | 18 +++++++++++++-----
 2 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 8e8cce5787..26572a7917 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -4316,6 +4316,17 @@
       <key>Value</key>
       <real>96.0</real>
     </map>
+    <key>ForceAddressSize</key>
+    <map>
+      <key>Comment</key>
+      <string>Force Windows update to 32-bit or 64-bit viewer.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>U32</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>ForceAssetFail</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 5a374755f7..776fc85a2d 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1130,21 +1130,29 @@ bool LLAppViewer::init()
 
 	gGLActive = FALSE;
 
-#if LL_WINDOWS
 	std::vector<std::string> updater
+#if LL_WINDOWS
 		{ gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "updater.exe") };
 #elif LL_DARWIN
 	// explicitly run the system Python interpreter on updater.py
-	std::vector<std::string> updater
 		{ "python", gDirUtilp->add(gDirUtilp->getAppRODataDir(), "updater", "updater.py") };
 #else
-	std::vector<std::string> updater
 		{ gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "updater") };
 #endif
 	// add LEAP mode command-line argument to whichever of these we selected
 	updater.push_back("leap");
-
-	// Run the updater. An exception from the updater should bother us.
+	// UpdaterServiceSettings
+	updater.push_back(stringize(gSavedSettings.getU32("UpdaterServiceSetting")));
+	// channel
+	updater.push_back(LLVersionInfo::getChannel());
+	// testok
+	updater.push_back(stringize(gSavedSettings.getBOOL("UpdaterWillingToTest")));
+	// UpdaterServiceURL
+	updater.push_back(gSavedSettings.getString("UpdaterServiceURL"));
+	// ForceAddressSize
+	updater.push_back(stringize(gSavedSettings.getU32("ForceAddressSize")));
+
+	// Run the updater. An exception from launching the updater should bother us.
 	LLLeap::create("updater process", updater, true);
 
 	// Iterate over --leap command-line options. But this is a bit tricky: if
-- 
cgit v1.2.3


From b6e58b3b3af60c90a283949060f5532856d3198e Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 28 Sep 2018 17:16:14 -0400
Subject: DRTVWR-474: Update to viewer-manager build 520110

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 243954a9ba..f92492ec1e 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3084,9 +3084,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>0a254644186f5523b0261d9427bf3e31</string>
+              <string>1cb4af868486605d788ca75ffc786d2d</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/25233/198295/viewer_manager-2.0.520085-darwin64-520085.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/25263/198729/viewer_manager-2.0.520110-darwin64-520110.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3108,9 +3108,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>fee2780a7172732633cd115fdc7925ff</string>
+              <string>f4e68dcae8439c4e08cdb2843812e224</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/25234/198302/viewer_manager-2.0.520085-windows-520085.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/25264/198736/viewer_manager-2.0.520110-windows-520110.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3121,7 +3121,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.520085</string>
+        <string>2.0.520110</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From 6e1b2e137e2b6c6d92d14f478b6908c0c2f1e231 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 28 Sep 2018 17:16:49 -0400
Subject: DRTVWR-474: Make SkipBenchmark a Persistent setting

---
 indra/newview/app_settings/settings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 26572a7917..ca13c60768 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -16183,7 +16183,7 @@
       <string>if true, disables running the GPU benchmark at startup
       (default to class 1)</string>
       <key>Persist</key>
-      <integer>0</integer>
+      <integer>1</integer>
       <key>Type</key>
       <string>Boolean</string>
       <key>Value</key>
-- 
cgit v1.2.3


From b1955d4247a4d28a3a4c259036390ff632e80008 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 3 Oct 2018 14:00:05 -0400
Subject: DRTVWR-474: Do NOT autokill updater process on viewer termination.

The updater is required to survive beyond termination of the viewer that
launched it so it can launch the next installer, or a replacement viewer.
Having the old viewer forcibly terminate it on shutdown would be counter-
productive.

Introduce a third LLLeap::create() overload taking LLProcess::Params, which
gives access to autokill, cwd and other options previously unsupported by
LLLeap. Reimplement the existing create() overloads in terms of this new one,
since LLLeapImpl::LLLeapImpl() is already based on LLProcess::Params anyway.

Use LLProcess::Params in LLAppViewer::init() to specify the updater process,
setting autokill=false.

Refactoring LLLeapImpl() apparently involved engaging an LLInitParam::Block
feature never before used: had to drag operator() into Multiple from its base
class TypedParam (as has been done in other TypedParam subclasses).
---
 indra/llcommon/llinitparam.h  |  3 +++
 indra/llcommon/llleap.cpp     | 51 +++++++++++++++++++++++++++----------------
 indra/llcommon/llleap.h       | 14 ++++++++++++
 indra/newview/llappviewer.cpp | 33 ++++++++++++++--------------
 4 files changed, 65 insertions(+), 36 deletions(-)

diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h
index f1f4226c40..7f5b9b4ac2 100644
--- a/indra/llcommon/llinitparam.h
+++ b/indra/llcommon/llinitparam.h
@@ -2115,6 +2115,9 @@ namespace LLInitParam
 			typedef typename super_t::iterator										iterator;
 			typedef typename super_t::const_iterator								const_iterator;
 
+			using super_t::operator();
+			using super_t::operator const container_t&;
+
 			explicit Multiple(const char* name = "")
 			:	super_t(DERIVED_BLOCK::getBlockDescriptor(), name, container_t(), &validate, RANGE::minCount, RANGE::maxCount)
 			{}
diff --git a/indra/llcommon/llleap.cpp b/indra/llcommon/llleap.cpp
index c87d2a3e58..cf8f8cc6a5 100644
--- a/indra/llcommon/llleap.cpp
+++ b/indra/llcommon/llleap.cpp
@@ -47,9 +47,9 @@ class LLLeapImpl: public LLLeap
     LOG_CLASS(LLLeap);
 public:
     // Called only by LLLeap::create()
-    LLLeapImpl(const std::string& desc, const std::vector<std::string>& plugin):
+    LLLeapImpl(const LLProcess::Params& cparams):
         // We might reassign mDesc in the constructor body if it's empty here.
-        mDesc(desc),
+        mDesc(cparams.desc),
         // We expect multiple LLLeapImpl instances. Definitely tweak
         // mDonePump's name for uniqueness.
         mDonePump("LLLeap", true),
@@ -67,17 +67,17 @@ public:
         // this class or method name.
         mListener(new LLLeapListener(boost::bind(&LLLeapImpl::connect, this, _1, _2)))
     {
-        // Rule out empty vector
-        if (plugin.empty())
+        // Rule out unpopulated Params block
+        if (! cparams.executable.isProvided())
         {
             LLTHROW(Error("no plugin command"));
         }
 
         // Don't leave desc empty either, but in this case, if we weren't
         // given one, we'll fake one.
-        if (desc.empty())
+        if (mDesc.empty())
         {
-            mDesc = LLProcess::basename(plugin[0]);
+            mDesc = LLProcess::basename(cparams.executable);
             // how about a toLower() variant that returns the transformed string?!
             std::string desclower(mDesc);
             LLStringUtil::toLower(desclower);
@@ -87,9 +87,9 @@ public:
             // notice Python specially: we provide Python LLSD serialization
             // support, so there's a pretty good reason to implement plugins
             // in that language.
-            if (plugin.size() >= 2 && (desclower == "python" || desclower == "python.exe"))
+            if (cparams.args.size() && (desclower == "python" || desclower == "python.exe"))
             {
-                mDesc = LLProcess::basename(plugin[1]);
+                mDesc = LLProcess::basename(cparams.args()[0]);
             }
         }
 
@@ -97,14 +97,10 @@ public:
         mDonePump.listen("LLLeap", boost::bind(&LLLeapImpl::bad_launch, this, _1));
 
         // Okay, launch child.
-        LLProcess::Params params;
+        // Get a modifiable copy of params block to set files and postend.
+        LLProcess::Params params(cparams);
+        // copy our deduced mDesc back into the params block
         params.desc = mDesc;
-        std::vector<std::string>::const_iterator pi(plugin.begin()), pend(plugin.end());
-        params.executable = *pi++;
-        for ( ; pi != pend; ++pi)
-        {
-            params.args.add(*pi);
-        }
         params.files.add(LLProcess::FileParam("pipe")); // stdin
         params.files.add(LLProcess::FileParam("pipe")); // stdout
         params.files.add(LLProcess::FileParam("pipe")); // stderr
@@ -429,17 +425,17 @@ private:
     boost::scoped_ptr<LLLeapListener> mListener;
 };
 
-// This must follow the declaration of LLLeapImpl, so it may as well be last.
-LLLeap* LLLeap::create(const std::string& desc, const std::vector<std::string>& plugin, bool exc)
+// These must follow the declaration of LLLeapImpl, so they may as well be last.
+LLLeap* LLLeap::create(const LLProcess::Params& params, bool exc)
 {
     // If caller is willing to permit exceptions, just instantiate.
     if (exc)
-        return new LLLeapImpl(desc, plugin);
+        return new LLLeapImpl(params);
 
     // Caller insists on suppressing LLLeap::Error. Very well, catch it.
     try
     {
-        return new LLLeapImpl(desc, plugin);
+        return new LLLeapImpl(params);
     }
     catch (const LLLeap::Error&)
     {
@@ -447,6 +443,23 @@ LLLeap* LLLeap::create(const std::string& desc, const std::vector<std::string>&
     }
 }
 
+LLLeap* LLLeap::create(const std::string& desc, const std::vector<std::string>& plugin, bool exc)
+{
+    LLProcess::Params params;
+    params.desc = desc;
+    std::vector<std::string>::const_iterator pi(plugin.begin()), pend(plugin.end());
+    // could validate here, but let's rely on LLLeapImpl's constructor
+    if (pi != pend)
+    {
+        params.executable = *pi++;
+    }
+    for ( ; pi != pend; ++pi)
+    {
+        params.args.add(*pi);
+    }
+    return create(params, exc);
+}
+
 LLLeap* LLLeap::create(const std::string& desc, const std::string& plugin, bool exc)
 {
     // Use LLStringUtil::getTokens() to parse the command line
diff --git a/indra/llcommon/llleap.h b/indra/llcommon/llleap.h
index 8aac8a64c5..7cecdf2f8f 100644
--- a/indra/llcommon/llleap.h
+++ b/indra/llcommon/llleap.h
@@ -14,6 +14,7 @@
 
 #include "llinstancetracker.h"
 #include "llexception.h"
+#include "llprocess.h"
 #include <string>
 #include <vector>
 
@@ -61,6 +62,19 @@ public:
     static LLLeap* create(const std::string& desc, const std::string& plugin,
                           bool exc=true);
 
+    /**
+     * Pass an LLProcess::Params instance to specify desc, executable, args et al.
+     *
+     * Note that files and postend are set implicitly; any values you set in
+     * those fields will be disregarded.
+     *
+     * Pass exc=false to suppress LLLeap::Error exception. Obviously in that
+     * case the caller cannot discover the nature of the error, merely that an
+     * error of some kind occurred (because create() returned NULL). Either
+     * way, the error is logged.
+     */
+    static LLLeap* create(const LLProcess::Params& params, bool exc=true);
+
     /**
      * Exception thrown for invalid create() arguments, e.g. no plugin
      * program. This is more resiliant than an LL_ERRS failure, because the
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 776fc85a2d..bc4ce19f77 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1130,30 +1130,35 @@ bool LLAppViewer::init()
 
 	gGLActive = FALSE;
 
-	std::vector<std::string> updater
+	LLProcess::Params updater;
+	updater.desc = "updater process";
+	// Because it's the updater, it MUST persist beyond the lifespan of the
+	// viewer itself.
+	updater.autokill = false;
 #if LL_WINDOWS
-		{ gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "updater.exe") };
+	updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "updater.exe");
 #elif LL_DARWIN
 	// explicitly run the system Python interpreter on updater.py
-		{ "python", gDirUtilp->add(gDirUtilp->getAppRODataDir(), "updater", "updater.py") };
+	updater.executable = "python";
+	updater.args.add(gDirUtilp->add(gDirUtilp->getAppRODataDir(), "updater", "updater.py"));
 #else
-		{ gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "updater") };
+	updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "updater");
 #endif
 	// add LEAP mode command-line argument to whichever of these we selected
-	updater.push_back("leap");
+	updater.args.add("leap");
 	// UpdaterServiceSettings
-	updater.push_back(stringize(gSavedSettings.getU32("UpdaterServiceSetting")));
+	updater.args.add(stringize(gSavedSettings.getU32("UpdaterServiceSetting")));
 	// channel
-	updater.push_back(LLVersionInfo::getChannel());
+	updater.args.add(LLVersionInfo::getChannel());
 	// testok
-	updater.push_back(stringize(gSavedSettings.getBOOL("UpdaterWillingToTest")));
+	updater.args.add(stringize(gSavedSettings.getBOOL("UpdaterWillingToTest")));
 	// UpdaterServiceURL
-	updater.push_back(gSavedSettings.getString("UpdaterServiceURL"));
+	updater.args.add(gSavedSettings.getString("UpdaterServiceURL"));
 	// ForceAddressSize
-	updater.push_back(stringize(gSavedSettings.getU32("ForceAddressSize")));
+	updater.args.add(stringize(gSavedSettings.getU32("ForceAddressSize")));
 
 	// Run the updater. An exception from launching the updater should bother us.
-	LLLeap::create("updater process", updater, true);
+	LLLeap::create(updater, true);
 
 	// Iterate over --leap command-line options. But this is a bit tricky: if
 	// there's only one, it won't be an array at all.
@@ -3923,12 +3928,6 @@ void LLAppViewer::requestQuit()
 		gAgentAvatarp->updateAvatarRezMetrics(true); // force a last packet to be sent.
 	}
 
-	// Try to send last batch of avatar rez metrics.
-	if (!gDisconnected && isAgentAvatarValid())
-	{
-		gAgentAvatarp->updateAvatarRezMetrics(true); // force a last packet to be sent.
-	}
-
 	LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral*)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE);
 	effectp->setPositionGlobal(gAgent.getPositionGlobal());
 	effectp->setColor(LLColor4U(gAgent.getEffectColor()));
-- 
cgit v1.2.3


From 05068186c349294caf4fef3c970f9d75a9f30460 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 4 Oct 2018 16:35:38 -0400
Subject: DRTVWR-474: Make login coroutine sync with updater process on
 failure.

Specifically, introduce an LLEventMailDrop("LoginSync"). When the updater
detects that an update is required, it will post to that rendezvous point.

When login.cgi responds with login failure, make the login coroutine wait (a
few seconds) for that ping from the updater.

If we receive that ping and if it contains a "reply" key, make the fail.login
listener respond to the updater with an indication of whether to proceed with
update.

If both login.cgi and the updater concur that an update is required, produce a
new confirmation message for the user and then (once user responds) tell the
updater to proceed. Otherwise, produce the usual login-failure message and
tell the updater never mind.

Introduce LLCoro::OverrideConsuming to provide temporary save/restore of the
set_consuming() / get_consuming() flag. It's a good idea to set the consuming
flag when retrieving data from an LLEventMailDrop.
---
 indra/llcommon/llcoros.h                           | 20 +++++++
 indra/newview/lllogininstance.cpp                  | 63 ++++++++++++++++++----
 indra/newview/lllogininstance.h                    |  6 ++-
 .../newview/skins/default/xui/en/notifications.xml | 13 ++++-
 indra/viewer_components/login/lllogin.cpp          | 56 +++++++++++++++++--
 5 files changed, 142 insertions(+), 16 deletions(-)

diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h
index 8fb27af6a4..c551413811 100644
--- a/indra/llcommon/llcoros.h
+++ b/indra/llcommon/llcoros.h
@@ -169,6 +169,26 @@ public:
     static void set_consuming(bool consuming);
     static bool get_consuming();
 
+    /**
+     * RAII control of the consuming flag
+     */
+    class OverrideConsuming
+    {
+    public:
+        OverrideConsuming(bool consuming):
+            mPrevConsuming(get_consuming())
+        {
+            set_consuming(consuming);
+        }
+        ~OverrideConsuming()
+        {
+            set_consuming(mPrevConsuming);
+        }
+
+    private:
+        bool mPrevConsuming;
+    };
+
     /**
      * Please do NOT directly use boost::dcoroutines::future! It is essential
      * to maintain the "current" coroutine at every context switch. This
diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp
index bc93fa2c20..126c6be388 100644
--- a/indra/newview/lllogininstance.cpp
+++ b/indra/newview/lllogininstance.cpp
@@ -253,14 +253,12 @@ bool LLLoginInstance::handleLoginEvent(const LLSD& event)
 
 	mLoginState = event["state"].asString();
 	mResponseData = event["data"];
-	
+
 	if(event.has("transfer_rate"))
 	{
 		mTransferRate = event["transfer_rate"].asReal();
 	}
 
-	
-
 	// Call the method registered in constructor, if any, for more specific
 	// handling
 	mDispatcher.try_call(event);
@@ -276,6 +274,14 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)
     // Login has failed. 
     // Figure out why and respond...
     LLSD response = event["data"];
+    LLSD updater  = response["updater"];
+
+    // Always provide a response to the updater, if in fact the updater
+    // contacted us, if in fact the ping contains a 'reply' key. Most code
+    // paths tell it not to proceed with updating.
+    ResponsePtr resp(std::make_shared<LLEventAPI::Response>
+                         (LLSDMap("update", false), updater));
+
     std::string reason_response = response["reason"].asString();
     std::string message_response = response["message"].asString();
     LL_DEBUGS("LLLogin") << "reason " << reason_response
@@ -328,17 +334,44 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)
     }
     else if(reason_response == "update")
     {
-        // This shouldn't happen - the viewer manager should have forced an update; 
-        // possibly the user ran the viewer directly and bypassed the update check
+        // This can happen if the user clicked Login quickly, before we heard
+        // back from the Viewer Version Manager, but login failed because
+        // login.cgi is insisting on a required update. We were called with an
+        // event that bundles both the login.cgi 'response' and the
+        // synchronization event from the 'updater'.
         std::string required_version = response["message_args"]["VERSION"];
         LL_WARNS("LLLogin") << "Login failed because an update to version " << required_version << " is required." << LL_ENDL;
 
         if (gViewerWindow)
             gViewerWindow->setShowProgress(FALSE);
 
-        LLSD data(LLSD::emptyMap());
-        data["VERSION"] = required_version;
-        LLNotificationsUtil::add("RequiredUpdate", data, LLSD::emptyMap(), boost::bind(&LLLoginInstance::handleLoginDisallowed, this, _1, _2));
+        LLSD args(LLSDMap("VERSION", required_version));
+        if (updater.isUndefined())
+        {
+            // If the updater failed to shake hands, better advise the user to
+            // download the update him/herself.
+            LLNotificationsUtil::add(
+                "RequiredUpdate",
+                args,
+                updater,
+                boost::bind(&LLLoginInstance::handleLoginDisallowed, this, _1, _2));
+        }
+        else
+        {
+            // If we've heard from the updater that an update is required,
+            // then display the prompt that assures the user we'll take care
+            // of it. This is the one case in which we bind 'resp':
+            // instead of destroying our Response object (and thus sending a
+            // negative reply to the updater) as soon as we exit this
+            // function, bind our shared_ptr so it gets passed into
+            // syncWithUpdater. That ensures that the response is delayed
+            // until the user has responded to the notification.
+            LLNotificationsUtil::add(
+                "PauseForUpdate",
+                args,
+                updater,
+                boost::bind(&LLLoginInstance::syncWithUpdater, this, resp, _1, _2));
+        }
     }
     else if(   reason_response == "key"
             || reason_response == "presence"
@@ -361,6 +394,19 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)
     }   
 }
 
+void LLLoginInstance::syncWithUpdater(ResponsePtr resp, const LLSD& notification, const LLSD& response)
+{
+    LL_INFOS("LLLogin") << "LLLoginInstance::syncWithUpdater" << LL_ENDL;
+    // 'resp' points to an instance of LLEventAPI::Response that will be
+    // destroyed as soon as we return and the notification response functor is
+    // unregistered. Modify it so that it tells the updater to go ahead and
+    // perform the update. Naturally, if we allowed the user a choice as to
+    // whether to proceed or not, this assignment would reflect the user's
+    // selection.
+    (*resp)["update"] = true;
+    attemptComplete();
+}
+
 void LLLoginInstance::handleLoginDisallowed(const LLSD& notification, const LLSD& response)
 {
     attemptComplete();
@@ -420,7 +466,6 @@ bool LLLoginInstance::handleTOSResponse(bool accepted, const std::string& key)
 	return true;
 }
 
-
 std::string construct_start_string()
 {
 	std::string start;
diff --git a/indra/newview/lllogininstance.h b/indra/newview/lllogininstance.h
index 651ad10afb..b759b43474 100644
--- a/indra/newview/lllogininstance.h
+++ b/indra/newview/lllogininstance.h
@@ -28,8 +28,10 @@
 #define LL_LLLOGININSTANCE_H
 
 #include "lleventdispatcher.h"
+#include "lleventapi.h"
 #include <boost/scoped_ptr.hpp>
 #include <boost/function.hpp>
+#include <memory>                   // std::shared_ptr
 #include "llsecapi.h"
 class LLLogin;
 class LLEventStream;
@@ -68,6 +70,7 @@ public:
 	LLNotificationsInterface& getNotificationsInterface() const { return *mNotifications; }
 
 private:
+	typedef std::shared_ptr<LLEventAPI::Response> ResponsePtr;
 	void constructAuthParams(LLPointer<LLCredential> user_credentials);
 	void updateApp(bool mandatory, const std::string& message);
 	bool updateDialogCallback(const LLSD& notification, const LLSD& response);
@@ -77,7 +80,8 @@ private:
 	void handleLoginSuccess(const LLSD& event);
 	void handleDisconnect(const LLSD& event);
 	void handleIndeterminate(const LLSD& event);
-    void handleLoginDisallowed(const LLSD& notification, const LLSD& response);
+	void handleLoginDisallowed(const LLSD& notification, const LLSD& response);
+	void syncWithUpdater(ResponsePtr resp, const LLSD& notification, const LLSD& response);
 
 	bool handleTOSResponse(bool v, const std::string& key);
 
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 9eaa5330c3..5f9b8adc89 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -3841,7 +3841,6 @@ Finished download of raw terrain file to:
    name="RequiredUpdate"
    type="alertmodal">
 Version [VERSION] is required for login.
-This should have been updated for you but apparently was not.
 Please download from https://secondlife.com/support/downloads/
     <tag>confirm</tag>
     <usetemplate
@@ -3849,6 +3848,18 @@ Please download from https://secondlife.com/support/downloads/
      yestext="OK"/>
   </notification>
 
+  <notification
+   icon="alertmodal.tga"
+   name="PauseForUpdate"
+   type="alertmodal">
+Version [VERSION] is required for login.
+Click OK to download and install.
+    <tag>confirm</tag>
+    <usetemplate
+     name="okbutton"
+     yestext="OK"/>
+  </notification>
+
   <notification
    icon="alertmodal.tga"
    name="LoginFailedUnknown"
diff --git a/indra/viewer_components/login/lllogin.cpp b/indra/viewer_components/login/lllogin.cpp
index c767d52c7b..9193d32b49 100644
--- a/indra/viewer_components/login/lllogin.cpp
+++ b/indra/viewer_components/login/lllogin.cpp
@@ -128,6 +128,15 @@ void LLLogin::Impl::connect(const std::string& uri, const LLSD& login_params)
     LL_DEBUGS("LLLogin") << " connected with  uri '" << uri << "', login_params " << login_params << LL_ENDL;	
 }
 
+namespace {
+// Instantiate this rendezvous point at namespace scope so it's already
+// present no matter how early the updater might post to it.
+// Use an LLEventMailDrop, which has future-like semantics: regardless of the
+// relative order in which post() or listen() are called, it delivers each
+// post() event to its listener(s) until one of them consumes that event.
+static LLEventMailDrop sSyncPoint("LoginSync");
+}
+
 void LLLogin::Impl::loginCoro(std::string uri, LLSD login_params)
 {
     LLSD printable_params = login_params;
@@ -219,7 +228,44 @@ void LLLogin::Impl::loginCoro(std::string uri, LLSD login_params)
         }
         else
         {
-            sendProgressEvent("offline", "fail.login", mAuthResponse["responses"]);
+            // Synchronize here with the updater. We synchronize here rather
+            // than in the fail.login handler, which actually examines the
+            // response from login.cgi, because here we are definitely in a
+            // coroutine and can definitely use suspendUntilBlah(). Whoever's
+            // listening for fail.login might not be.
+
+            // If the reason for login failure is that we must install a
+            // required update, we definitely want to pass control to the
+            // updater to manage that for us. We'll handle any other login
+            // failure ourselves, as usual. We figure that no matter where you
+            // are in the world, or what kind of network you're on, we can
+            // reasonably expect the Viewer Version Manager to respond more or
+            // less as quickly as login.cgi. This synchronization is only
+            // intended to smooth out minor races between the two services.
+            // But what if the updater crashes? Use a timeout so that
+            // eventually we'll tire of waiting for it and carry on as usual.
+            // Given the above, it can be a fairly short timeout, at least
+            // from a human point of view.
+
+            // Since sSyncPoint is an LLEventMailDrop, we DEFINITELY want to
+            // consume the posted event.
+            LLCoros::OverrideConsuming oc(true);
+            // Timeout should produce the isUndefined() object passed here.
+            LL_DEBUGS("LLLogin") << "Login failure, waiting for sync from updater" << LL_ENDL;
+            LLSD updater = llcoro::suspendUntilEventOnWithTimeout(sSyncPoint, 10, LLSD());
+            if (updater.isUndefined())
+            {
+                LL_WARNS("LLLogin") << "Failed to hear from updater, proceeding with fail.login"
+                                    << LL_ENDL;
+            }
+            else
+            {
+                LL_DEBUGS("LLLogin") << "Got responses from updater and login.cgi" << LL_ENDL;
+            }
+            // Let the fail.login handler deal with empty updater response.
+            LLSD responses(mAuthResponse["responses"]);
+            responses["updater"] = updater;
+            sendProgressEvent("offline", "fail.login", responses);
         }
         return;             // Done!
     }
@@ -249,10 +295,10 @@ void LLLogin::Impl::loginCoro(std::string uri, LLSD login_params)
     // *NOTE: The response from LLXMLRPCListener's Poller::poll method returns an
     // llsd with no "responses" node. To make the output from an incomplete login symmetrical 
     // to success, add a data/message and data/reason fields.
-    LLSD error_response;
-    error_response["reason"] = mAuthResponse["status"];
-    error_response["errorcode"] = mAuthResponse["errorcode"];
-    error_response["message"] = mAuthResponse["error"];
+    LLSD error_response(LLSDMap
+                        ("reason",    mAuthResponse["status"])
+                        ("errorcode", mAuthResponse["errorcode"])
+                        ("message",   mAuthResponse["error"]));
     if(mAuthResponse.has("certificate"))
     {
         error_response["certificate"] = mAuthResponse["certificate"];
-- 
cgit v1.2.3


From 73e70ff0bb484e52b786adb0fe523ea959985b20 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 4 Oct 2018 17:18:08 -0400
Subject: DRTVWR-474: Make "LLNotifications" "requestAdd" propagate "reqid"
 from request to response to help with request/response matching protocol.

---
 indra/llui/llnotificationslistener.cpp | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/indra/llui/llnotificationslistener.cpp b/indra/llui/llnotificationslistener.cpp
index b6a32a0e78..be26416cbb 100644
--- a/indra/llui/llnotificationslistener.cpp
+++ b/indra/llui/llnotificationslistener.cpp
@@ -90,9 +90,12 @@ void LLNotificationsListener::requestAdd(const LLSD& event_data) const
 {
 	if(event_data.has("reply"))
 	{
+		LLSD payload(event_data["payload"]);
+		// copy reqid, if provided, to link response with request
+		payload["reqid"] = event_data["reqid"];
 		mNotifications.add(event_data["name"], 
 						   event_data["substitutions"], 
-						   event_data["payload"],
+						   payload,
 						   boost::bind(&LLNotificationsListener::NotificationResponder, 
 									   this, 
 									   event_data["reply"].asString(), 
@@ -112,10 +115,12 @@ void LLNotificationsListener::NotificationResponder(const std::string& reply_pum
 										const LLSD& notification, 
 										const LLSD& response) const
 {
-	LLSD reponse_event;
-	reponse_event["notification"] = notification;
-	reponse_event["response"] = response;
-	LLEventPumps::getInstance()->obtain(reply_pump).post(reponse_event);
+	LLSD response_event;
+	response_event["notification"] = notification;
+	response_event["response"] = response;
+	// surface reqid at top level of response for request/response protocol
+	response_event["reqid"] = notification["payload"]["reqid"];
+	LLEventPumps::getInstance()->obtain(reply_pump).post(response_event);
 }
 
 void LLNotificationsListener::listChannels(const LLSD& params) const
-- 
cgit v1.2.3


From a3e569c90d7cc45d0e2bef77d36d4fea8924af6d Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 5 Oct 2018 14:38:25 -0400
Subject: DRTVWR-474: Add OptionaUpdateReady, PromptOptionalUpdate
 notifications.

---
 .../newview/skins/default/xui/en/notifications.xml | 26 ++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 5f9b8adc89..e2859603e0 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -3860,6 +3860,32 @@ Click OK to download and install.
      yestext="OK"/>
   </notification>
 
+  <notification
+   icon="alertmodal.tga"
+   name="OptionalUpdateReady"
+   type="alertmodal">
+Version [VERSION] has been downloaded and is ready to install.
+Click OK to install.
+    <tag>confirm</tag>
+    <usetemplate
+     name="okbutton"
+     yestext="OK"/>
+  </notification>
+
+  <notification
+   icon="alertmodal.tga"
+   name="PromptOptionalUpdate"
+   type="alertmodal">
+Version [VERSION] has been downloaded and is ready to install.
+Proceed?
+    <tag>confirm</tag>
+    <usetemplate
+     canceltext="Not Now"
+     name="yesnocancelbuttons"
+     notext="Skip"
+     yestext="Install"/>
+  </notification>
+
   <notification
    icon="alertmodal.tga"
    name="LoginFailedUnknown"
-- 
cgit v1.2.3


From a11230f87ad57440585d12ed600d56ee9f654623 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 5 Oct 2018 15:29:08 -0400
Subject: DRTVWR-474: Update to viewer-manager build 520325

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index f92492ec1e..10dcc5c2a0 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3084,9 +3084,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>1cb4af868486605d788ca75ffc786d2d</string>
+              <string>be69b65c9372562ce1aeb884802fdf1e</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/25263/198729/viewer_manager-2.0.520110-darwin64-520110.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/25619/201842/viewer_manager-2.0.520325-darwin64-520325.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3108,9 +3108,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>f4e68dcae8439c4e08cdb2843812e224</string>
+              <string>5934273cf5272982926f553baf5505b8</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/25264/198736/viewer_manager-2.0.520110-windows-520110.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/25623/201856/viewer_manager-2.0.520325-windows-520325.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3121,7 +3121,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.520110</string>
+        <string>2.0.520325</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From d87cc1859f3f96b98a627fdc674e297e78438681 Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Thu, 11 Oct 2018 14:17:52 -0400
Subject: Modify logging so that the in-viewer console and stderr do not escape
 line breaks Improve the implementation so that escaping is computed only once

---
 indra/llcommon/llerror.cpp                | 149 ++++++++++++++++++++----------
 indra/llcommon/llerrorcontrol.h           |  19 +++-
 indra/llcommon/tests/llerror_test.cpp     |  68 +++++++-------
 indra/newview/app_settings/logcontrol.xml |   1 -
 indra/newview/app_settings/settings.xml   |  11 ---
 indra/newview/llappviewer.cpp             |   7 +-
 indra/newview/llviewerwindow.cpp          |   3 +
 indra/test/test.cpp                       |   1 -
 8 files changed, 152 insertions(+), 107 deletions(-)

diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index 6dfb4bf028..668ea1f7d2 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -119,8 +119,6 @@ namespace {
 			{
 				LL_INFOS() << "Error setting log file to " << filename << LL_ENDL;
 			}
-			mWantsTime = true;
-            mWantsTags = true;
 		}
 		
 		~RecordToFile()
@@ -146,7 +144,7 @@ namespace {
 	public:
 		RecordToStderr(bool timestamp) : mUseANSI(ANSI_PROBE) 
 		{
-			mWantsTime = timestamp;
+            this->showMultiline(true);
 		}
 		
 		virtual void recordMessage(LLError::ELevel level,
@@ -207,7 +205,13 @@ namespace {
 	class RecordToFixedBuffer : public LLError::Recorder
 	{
 	public:
-		RecordToFixedBuffer(LLLineBuffer* buffer) : mBuffer(buffer) { }
+		RecordToFixedBuffer(LLLineBuffer* buffer)
+            : mBuffer(buffer)
+            {
+                this->showMultiline(true);
+                this->showTags(false);
+                this->showLocation(false);
+            }
 		
 		virtual void recordMessage(LLError::ELevel level,
 								   const std::string& message)
@@ -224,7 +228,11 @@ namespace {
 	{
 	public:
 		RecordToWinDebug()
-		{}
+		{
+            this->showMultiline(true);
+            this->showTags(false);
+            this->showLocation(false);
+        }
 
 		virtual void recordMessage(LLError::ELevel level,
 								   const std::string& message)
@@ -411,8 +419,6 @@ namespace LLError
 	public:
 		virtual ~SettingsConfig();
 
-		bool                                mPrintLocation;
-
 		LLError::ELevel                     mDefaultLevel;
 		
 		LevelMap                            mFunctionLevelMap;
@@ -453,7 +459,6 @@ namespace LLError
 
 	SettingsConfig::SettingsConfig()
 		: LLRefCount(),
-		mPrintLocation(false),
 		mDefaultLevel(LLError::LEVEL_DEBUG),
 		mFunctionLevelMap(),
 		mClassLevelMap(),
@@ -655,12 +660,6 @@ namespace LLError
 		commonInit(user_dir, app_dir, log_to_stderr);
 	}
 
-	void setPrintLocation(bool print)
-	{
-		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
-		s->mPrintLocation = print;
-	}
-
 	void setFatalFunction(const FatalFunction& f)
 	{
 		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
@@ -775,7 +774,6 @@ namespace LLError
 		s->mTagLevelMap.clear();
 		s->mUniqueLogMessages.clear();
 		
-		setPrintLocation(config["print-location"]);
 		setDefaultLevel(decodeLevel(config["default-level"]));
 		
 		LLSD sets = config["settings"];
@@ -798,11 +796,12 @@ namespace LLError
 namespace LLError
 {
 	Recorder::Recorder()
-	:	mWantsTime(false),
-		mWantsTags(false),
-		mWantsLevel(true),
-		mWantsLocation(false),
-		mWantsFunctionName(true)
+    	: mWantsTime(true)
+        , mWantsTags(true)
+        , mWantsLevel(true)
+        , mWantsLocation(true)
+        , mWantsFunctionName(true)
+        , mWantsMultiline(false)
 	{
 	}
 
@@ -839,6 +838,42 @@ namespace LLError
 		return mWantsFunctionName;
 	}
 
+	// virtual 
+	bool Recorder::wantsMultiline() 
+	{ 
+		return mWantsMultiline;
+	}
+
+    void Recorder::showTime(bool show)
+    {
+        mWantsTime = show;
+    }
+    
+    void Recorder::showTags(bool show)
+    {
+        mWantsTags = show;
+    }
+
+    void Recorder::showLevel(bool show)
+    {
+        mWantsLevel = show;
+    }
+
+    void Recorder::showLocation(bool show)
+    {
+        mWantsLocation = show;
+    }
+
+    void Recorder::showFunctionName(bool show)
+    {
+        mWantsFunctionName = show;
+    }
+
+    void Recorder::showMultiline(bool show)
+    {
+        mWantsMultiline = show;
+    }
+
 	void addRecorder(RecorderPtr recorder)
 	{
 		if (!recorder)
@@ -871,17 +906,15 @@ namespace LLError
 		s->mFileRecorder.reset();
 		s->mFileRecorderFileName.clear();
 		
-		if (file_name.empty())
-		{
-			return;
-		}
-		
-		RecorderPtr recordToFile(new RecordToFile(file_name));
-		if (boost::dynamic_pointer_cast<RecordToFile>(recordToFile)->okay())
+		if (!file_name.empty())
 		{
-			s->mFileRecorderFileName = file_name;
-			s->mFileRecorder = recordToFile;
-			addRecorder(recordToFile);
+            RecorderPtr recordToFile(new RecordToFile(file_name));
+            if (boost::dynamic_pointer_cast<RecordToFile>(recordToFile)->okay())
+            {
+                s->mFileRecorderFileName = file_name;
+                s->mFileRecorder = recordToFile;
+                addRecorder(recordToFile);
+            }
 		}
 	}
 	
@@ -892,14 +925,12 @@ namespace LLError
 		removeRecorder(s->mFixedBufferRecorder);
 		s->mFixedBufferRecorder.reset();
 		
-		if (!fixedBuffer)
+		if (fixedBuffer)
 		{
-			return;
-		}
-		
-		RecorderPtr recordToFixedBuffer(new RecordToFixedBuffer(fixedBuffer));
-		s->mFixedBufferRecorder = recordToFixedBuffer;
-		addRecorder(recordToFixedBuffer);
+            RecorderPtr recordToFixedBuffer(new RecordToFixedBuffer(fixedBuffer));
+            s->mFixedBufferRecorder = recordToFixedBuffer;
+            addRecorder(recordToFixedBuffer);
+        }
 	}
 
 	std::string logFileName()
@@ -911,8 +942,9 @@ namespace LLError
 
 namespace
 {
-    void addEscapedMessage(std::ostream& out, const std::string& message)
+    std::string escapedMessageLines(const std::string& message)
     {
+        std::ostringstream out;
         size_t written_out = 0;
         size_t all_content = message.length();
         size_t escape_char_index; // always relative to start of message
@@ -948,13 +980,16 @@ namespace
             // write whatever was left
             out << message.substr(written_out, std::string::npos);
         }
+        return out.str();
     }
 
-	void writeToRecorders(const LLError::CallSite& site, const std::string& escaped_message, bool show_location = true, bool show_time = true, bool show_tags = true, bool show_level = true, bool show_function = true)
+	void writeToRecorders(const LLError::CallSite& site, const std::string& message)
 	{
 		LLError::ELevel level = site.mLevel;
 		LLError::SettingsConfigPtr s = LLError::Settings::getInstance()->getSettingsConfig();
-	
+
+        std::string escaped_message;
+        
 		for (Recorders::const_iterator i = s->mRecorders.begin();
 			i != s->mRecorders.end();
 			++i)
@@ -969,7 +1004,7 @@ namespace
 			}
             message_stream << " ";
             
-			if (show_level && r->wantsLevel())
+			if (r->wantsLevel())
             {
 				message_stream << site.mLevelString;
             }
@@ -981,19 +1016,30 @@ namespace
 			}
             message_stream << " ";
 
-            if (r->wantsLocation() || level == LLError::LEVEL_ERROR || s->mPrintLocation)
+            if (r->wantsLocation() || level == LLError::LEVEL_ERROR)
             {
                 message_stream << site.mLocationString;
             }
             message_stream << " ";
 
-			if (show_function && r->wantsFunctionName())
+			if (r->wantsFunctionName())
 			{
 				message_stream << site.mFunctionString;
 			}
             message_stream << " : ";
 
-			message_stream << escaped_message;
+            if (r->wantsMultiline())
+            {
+                message_stream << message;
+            }
+            else
+            {
+                if (escaped_message.empty())
+                {
+                    escaped_message = escapedMessageLines(message);
+                }
+                message_stream << escaped_message;
+            }
 
 			r->recordMessage(level, message_stream.str());
 		}
@@ -1236,10 +1282,11 @@ namespace LLError
 			delete out;
 		}
 
-		std::ostringstream message_stream;
 
 		if (site.mPrintOnce)
 		{
+            std::ostringstream message_stream;
+
 			std::map<std::string, unsigned int>::iterator messageIter = s->mUniqueLogMessages.find(message);
 			if (messageIter != s->mUniqueLogMessages.end())
 			{
@@ -1259,19 +1306,18 @@ namespace LLError
 				message_stream << "ONCE: ";
 				s->mUniqueLogMessages[message] = 1;
 			}
+            message_stream << message;
+            message = message_stream.str();
 		}
 		
-		addEscapedMessage(message_stream, message);
-		std::string message_line(message_stream.str());
-
-		writeToRecorders(site, message_line);
+		writeToRecorders(site, message);
 
 		if (site.mLevel == LEVEL_ERROR)
 		{
-			g->mFatalMessage = message_line;
+			g->mFatalMessage = message;
 			if (s->mCrashFunction)
 			{
-				s->mCrashFunction(message_line);
+				s->mCrashFunction(message);
 			}
 		}
 	}
@@ -1579,3 +1625,4 @@ bool debugLoggingEnabled(const std::string& tag)
 }
 
 
+
diff --git a/indra/llcommon/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h
index ddbcdc94a0..a6278b3e50 100644
--- a/indra/llcommon/llerrorcontrol.h
+++ b/indra/llcommon/llerrorcontrol.h
@@ -148,13 +148,22 @@ namespace LLError
 		bool wantsLevel();
 		bool wantsLocation(); 
 		bool wantsFunctionName();
+        bool wantsMultiline();
+
+		void showTime(bool show);
+		void showTags(bool show);
+		void showLevel(bool show);
+		void showLocation(bool show); 
+		void showFunctionName(bool show);
+		void showMultiline(bool show);
 
 	protected:
-		bool	mWantsTime,
-				mWantsTags,
-				mWantsLevel,
-				mWantsLocation,
-				mWantsFunctionName;
+		bool mWantsTime;
+        bool mWantsTags;
+        bool mWantsLevel;
+        bool mWantsLocation;
+        bool mWantsFunctionName;
+        bool mWantsMultiline;
 	};
 
 	typedef boost::shared_ptr<Recorder> RecorderPtr;
diff --git a/indra/llcommon/tests/llerror_test.cpp b/indra/llcommon/tests/llerror_test.cpp
index ce0dbce075..bd0357e4bf 100644
--- a/indra/llcommon/tests/llerror_test.cpp
+++ b/indra/llcommon/tests/llerror_test.cpp
@@ -78,8 +78,12 @@ namespace tut
 	class TestRecorder : public LLError::Recorder
 	{
 	public:
-		TestRecorder() { mWantsTime = false; mWantsTags = true; }
-		virtual ~TestRecorder() {  }
+		TestRecorder()
+            {
+                showTime(false);
+            }
+		virtual ~TestRecorder()
+            {}
 
 		virtual void recordMessage(LLError::ELevel level,
 						   const std::string& message)
@@ -90,8 +94,6 @@ namespace tut
 		int countMessages()			{ return (int) mMessages.size(); }
 		void clearMessages()		{ mMessages.clear(); }
 
-		void setWantsTime(bool t)	{ mWantsTime = t; }
-
 		std::string message(int n)
 		{
 			std::ostringstream test_name;
@@ -139,9 +141,14 @@ namespace tut
 		}
 
 		void setWantsTime(bool t)
-		{
-			boost::dynamic_pointer_cast<TestRecorder>(mRecorder)->setWantsTime(t);
-		}
+            {
+                boost::dynamic_pointer_cast<TestRecorder>(mRecorder)->showTime(t);
+            }
+
+		void setWantsMultiline(bool t)
+            {
+                boost::dynamic_pointer_cast<TestRecorder>(mRecorder)->showMultiline(t);
+            }
 
 		std::string message(int n)
 		{
@@ -378,27 +385,6 @@ namespace
 	}
 }
 
-namespace tut
-{
-	template<> template<>
-	void ErrorTestObject::test<5>()
-		// file and line information in log messages
-	{
-		std::string location = writeReturningLocation();
-			// expecting default to not print location information
-
-		LLError::setPrintLocation(true);
-		writeReturningLocation();
-
-		LLError::setPrintLocation(false);
-		writeReturningLocation();
-
-		ensure_message_does_not_contain(0, location);
-		ensure_message_field_equals(1, LOCATION_FIELD, location);
-		ensure_message_does_not_contain(2, location);
-	}
-}
-
 /* The following helper functions and class members all log a simple message
 	from some particular function scope.  Each function takes a bool argument
 	that indicates if it should log its own name or not (in the manner that
@@ -583,7 +569,6 @@ namespace tut
 		// special handling of LL_ERRS() calls
 	void ErrorTestObject::test<8>()
 	{
-		LLError::setPrintLocation(false);
 		std::string location = errorReturningLocation();
 
 		ensure_message_field_equals(0, LOCATION_FIELD, location);
@@ -630,15 +615,15 @@ namespace tut
 		// output order
 	void ErrorTestObject::test<10>()
 	{
-		LLError::setPrintLocation(true);
 		LLError::setTimeFunction(roswell);
 		setWantsTime(true);
+
 		std::string location,
 					function;
 		writeReturningLocationAndFunction(location, function);
 
 		ensure_equals("order is time level tags location function message",
-			message(0),
+                      message(0),
                       roswell() + " INFO " + "# " /* no tag */ + location + " " + function + " : " + "apple");
 	}
 
@@ -658,7 +643,7 @@ namespace tut
 		LLError::setTimeFunction(roswell);
 
 		LLError::RecorderPtr anotherRecorder(new TestRecorder());
-		boost::dynamic_pointer_cast<TestRecorder>(anotherRecorder)->setWantsTime(true);
+		boost::dynamic_pointer_cast<TestRecorder>(anotherRecorder)->showTime(true);
 		LLError::addRecorder(anotherRecorder);
 
 		LL_INFOS() << "baz" << LL_ENDL;
@@ -896,6 +881,25 @@ namespace tut
     }
 }
 
+namespace tut
+{
+    template<> template<>
+    void ErrorTestObject::test<19>()
+        // backslash, return, and newline are not escaped with backslashes
+    {
+        LLError::setDefaultLevel(LLError::LEVEL_DEBUG);
+        setWantsMultiline(true); 
+        writeMsgNeedsEscaping(); // but should not be now
+        ensure_message_field_equals(0, MSG_FIELD, "backslash\\");
+        ensure_message_field_equals(1, MSG_FIELD, "newline\nafternewline");
+        ensure_message_field_equals(2, MSG_FIELD, "return\rafterreturn");
+        ensure_message_field_equals(3, MSG_FIELD, "backslash\\backslash\\");
+        ensure_message_field_equals(4, MSG_FIELD, "backslash\\newline\nanothernewline\nafternewline");
+        ensure_message_field_equals(5, MSG_FIELD, "backslash\\returnnewline\r\n\\afterbackslash");
+        ensure_message_count(6);
+    }
+}
+
 /* Tests left:
 	handling of classes without LOG_CLASS
 
diff --git a/indra/newview/app_settings/logcontrol.xml b/indra/newview/app_settings/logcontrol.xml
index 71445ea541..8ced81fdb3 100644
--- a/indra/newview/app_settings/logcontrol.xml
+++ b/indra/newview/app_settings/logcontrol.xml
@@ -2,7 +2,6 @@
 	<map>
 		<!-- default-level can be ALL, DEBUG, INFO, WARN, ERROR, or NONE -->
 		<key>default-level</key>    <string>INFO</string>
-		<key>print-location</key>   <boolean>true</boolean>
 		<key>settings</key>
 			<array>
 				<!-- Suppress anything but ERROR for some very verbose components -->
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 8e8cce5787..44aa22b387 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -13980,17 +13980,6 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
-    <key>VerboseLogs</key>
-    <map>
-      <key>Comment</key>
-      <string>Display source file and line number for each log item for debugging purposes</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>Boolean</string>
-      <key>Value</key>
-      <integer>0</integer>
-    </map>
     <key>VertexShaderEnable</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index dd82aa735f..b3f09a73a2 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -885,11 +885,6 @@ bool LLAppViewer::init()
 	mNumSessions++;
 	gSavedSettings.setS32("NumSessions", mNumSessions);
 
-	if (gSavedSettings.getBOOL("VerboseLogs"))
-	{
-		LLError::setPrintLocation(true);
-	}
-
 	// LLKeyboard relies on LLUI to know what some accelerator keys are called.
 	LLKeyboard::setStringTranslatorFunc( LLTrans::getKeyboardString );
 
@@ -1702,7 +1697,7 @@ bool LLAppViewer::cleanup()
 
 	release_start_screen(); // just in case
 
-	LLError::logToFixedBuffer(NULL);
+	LLError::logToFixedBuffer(NULL); // stop the fixed buffer recorder
 
 	LL_INFOS() << "Cleaning Up" << LL_ENDL;
 
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 01ec703fe6..873d011acc 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -306,6 +306,9 @@ private:
 RecordToChatConsole::RecordToChatConsole():
 	mRecorder(new RecordToChatConsoleRecorder())
 {
+    mRecorder->showTags(false);
+    mRecorder->showLocation(false);
+    mRecorder->showMultiline(true);
 }
 
 ////////////////////////////////////////////////////////////////////////////
diff --git a/indra/test/test.cpp b/indra/test/test.cpp
index 80c84d9bea..9d6e9539cb 100644
--- a/indra/test/test.cpp
+++ b/indra/test/test.cpp
@@ -535,7 +535,6 @@ int main(int argc, char **argv)
 		LLError::setDefaultLevel(LLError::LEVEL_DEBUG);
 	}	
 	LLError::setFatalFunction(wouldHaveCrashed);
-	LLError::setPrintLocation(true);
 	std::string test_app_name(argv[0]);
 	std::string test_log = test_app_name + ".log";
 	LLFile::remove(test_log);
-- 
cgit v1.2.3


From f960db28b72b9a1390e9e5e60f135806bfb9ced5 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 11 Oct 2018 20:52:01 -0400
Subject: DRTVWR-474: Update to viewer-manager build 520566

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 10dcc5c2a0..e9bd57b4e0 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3084,9 +3084,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>be69b65c9372562ce1aeb884802fdf1e</string>
+              <string>55535daa041b922c22902b9d9e5d2b60</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/25619/201842/viewer_manager-2.0.520325-darwin64-520325.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/25997/204690/viewer_manager-2.0.520566-darwin64-520566.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3108,9 +3108,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>5934273cf5272982926f553baf5505b8</string>
+              <string>23e95f315f0adf957585af3f4eb42e88</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/25623/201856/viewer_manager-2.0.520325-windows-520325.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/25999/204773/viewer_manager-2.0.520566-windows-520566.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3121,7 +3121,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.520325</string>
+        <string>2.0.520566</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From 3abc0095c9e39faf8976ef815b0da656423c4905 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 12 Oct 2018 14:08:59 -0400
Subject: DRTVWR-474: Update to viewer-manager build 520576

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index e9bd57b4e0..f0358eb8ba 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3084,9 +3084,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>55535daa041b922c22902b9d9e5d2b60</string>
+              <string>eeeb18f7396de3147c6d958dfbc1a2e5</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/25997/204690/viewer_manager-2.0.520566-darwin64-520566.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/26016/204885/viewer_manager-2.0.520576-darwin64-520576.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3108,9 +3108,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>23e95f315f0adf957585af3f4eb42e88</string>
+              <string>2832c40449a8a8230e9072ceac5120af</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/25999/204773/viewer_manager-2.0.520566-windows-520566.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/26017/204891/viewer_manager-2.0.520576-windows-520576.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3121,7 +3121,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.520566</string>
+        <string>2.0.520576</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From 72c0845a243ebdf0293bf7665474cfc652492bc7 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 16 Oct 2018 11:29:32 -0400
Subject: DRTVWR-447: Update to bugsplat build 520674

---
 autobuild.xml | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 4c97752da1..160f1d7d59 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -244,9 +244,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>7a7bd828233e8a2b0e9c022f6219e6e7</string>
+              <string>436b124bce8cf57b18dbf10f5e6ebcd4</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23730/182106/bugsplat-1.0.6.519145-darwin64-519145.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/26151/206132/bugsplat-1.0.7.520674-darwin64-520674.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -256,9 +256,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>a3938332a11215e6909d67d1b9be5259</string>
+              <string>5d19acddc51ee7c802297dd176194362</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23732/182120/bugsplat-3.6.0.4.519145-windows-519145.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/26153/206145/bugsplat-3.6.0.4.520674-windows-520674.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -268,16 +268,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>453d624d87a80779f59cfb1880613d90</string>
+              <string>78f5688b694e04c052fb0a1165c98bb5</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23731/182115/bugsplat-3.6.0.4.519145-windows64-519145.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/26152/206142/bugsplat-3.6.0.4.520674-windows64-520674.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.0.6.519145</string>
+        <string>1.0.7.520674</string>
       </map>
       <key>chardet</key>
       <map>
-- 
cgit v1.2.3


From 00a839d66590de1204af5fa295f66abcff87e477 Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Tue, 16 Oct 2018 16:18:31 -0400
Subject: renumber the new test to replace the one that was removed

---
 indra/llcommon/tests/llerror_test.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/llcommon/tests/llerror_test.cpp b/indra/llcommon/tests/llerror_test.cpp
index bd0357e4bf..e7084fffc6 100644
--- a/indra/llcommon/tests/llerror_test.cpp
+++ b/indra/llcommon/tests/llerror_test.cpp
@@ -884,7 +884,7 @@ namespace tut
 namespace tut
 {
     template<> template<>
-    void ErrorTestObject::test<19>()
+    void ErrorTestObject::test<5>()
         // backslash, return, and newline are not escaped with backslashes
     {
         LLError::setDefaultLevel(LLError::LEVEL_DEBUG);
-- 
cgit v1.2.3


From 9cdcef4d501f4a7fec3b1c7051037df9db082278 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 16 Oct 2018 16:53:06 -0400
Subject: DRTVWR-447: Use new attachmentsForBugsplatStartupManager SDK method
 to attach user settings file and static debug info file to Mac crash reports,
 as well as SecondLife.log, just like Windows crash reports.

---
 indra/newview/llappdelegate-objc.mm | 74 +++++++++++++++++++++++++++----------
 1 file changed, 55 insertions(+), 19 deletions(-)

diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm
index f55304f30b..1d55537427 100644
--- a/indra/newview/llappdelegate-objc.mm
+++ b/indra/newview/llappdelegate-objc.mm
@@ -26,6 +26,8 @@
 
 #import "llappdelegate-objc.h"
 #if defined(LL_BUGSPLAT)
+#include <boost/filesystem.hpp>
+#include <vector>
 @import BugsplatMac;
 // derived from BugsplatMac's BugsplatTester/AppDelegate.m
 @interface LLAppDelegate () <BugsplatStartupManagerDelegate>
@@ -271,25 +273,59 @@
     infos("bugsplatStartupManagerWillSendCrashReport");
 }
 
-- (BugsplatAttachment *)attachmentForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager {
-    std::string logfile = CrashMetadata_instance().logFilePathname;
-    // Still to do:
-    // userSettingsPathname
-    // staticDebugPathname
-    // but the BugsplatMac version 1.0.5 BugsplatStartupManagerDelegate API
-    // doesn't yet provide a way to attach more than one file.
-    NSString *ns_logfile = [NSString stringWithCString:logfile.c_str()
-                                              encoding:NSUTF8StringEncoding];
-    NSData *data = [NSData dataWithContentsOfFile:ns_logfile];
-
-    // Apologies for the hard-coded log-file basename, but I do not know the
-    // incantation for "$(basename "$logfile")" in this language.
-    BugsplatAttachment *attachment = 
-        [[BugsplatAttachment alloc] initWithFilename:@"SecondLife.log"
-                                      attachmentData:data
-                                         contentType:@"text/plain"];
-    infos("attachmentForBugsplatStartupManager attaching " + logfile);
-    return attachment;
+struct AttachmentInfo
+{
+    AttachmentInfo(const std::string& path, const std::string& type):
+        pathname(path),
+        basename(boost::filesystem::path(path).filename().string()),
+        mimetype(type)
+    {}
+
+    std::string pathname, basename, mimetype;
+};
+
+- (NSArray<BugsplatAttachment *> *)attachmentsForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager
+{
+    const CrashMetadata& metadata(CrashMetadata_instance());
+
+    // Since we must do very similar processing for each of several file
+    // pathnames, start by collecting them into a vector so we can iterate
+    // instead of spelling out the logic for each.
+    std::vector<AttachmentInfo> info{
+        AttachmentInfo(metadata.logFilePathname,      "text/plain"),
+        AttachmentInfo(metadata.userSettingsPathname, "text/xml"),
+        AttachmentInfo(metadata.staticDebugPathname,  "text/xml")
+    };
+
+    // We "happen to know" that info[0].basename is "SecondLife.old" -- due to
+    // the fact that BugsplatMac only notices a crash during the viewer run
+    // following the crash. Replace .old with .log to reduce confusion.
+    info[0].basename = 
+        boost::filesystem::path(info[0].pathname).stem().string() + ".log";
+
+    NSMutableArray *attachments = [[NSMutableArray alloc] init];
+
+    // Iterate over each AttachmentInfo in info vector
+    for (const AttachmentInfo& attach : info)
+    {
+        NSString *nspathname = [NSString stringWithCString:attach.pathname.c_str()
+                                                  encoding:NSUTF8StringEncoding];
+        NSString *nsbasename = [NSString stringWithCString:attach.basename.c_str()
+                                                  encoding:NSUTF8StringEncoding];
+        NSString *nsmimetype = [NSString stringWithCString:attach.mimetype.c_str()
+                                                  encoding:NSUTF8StringEncoding];
+        NSData *nsdata = [NSData dataWithContentsOfFile:nspathname];
+
+        BugsplatAttachment *attachment =
+            [[BugsplatAttachment alloc] initWithFilename:nsbasename
+                                          attachmentData:nsdata
+                                             contentType:nsmimetype];
+
+        [attachments addObject:attachment];
+        infos("attachmentsForBugsplatStartupManager attaching " + attach.pathname);
+    }
+
+    return attachments;
 }
 
 - (void)bugsplatStartupManagerDidFinishSendingCrashReport:(BugsplatStartupManager *)bugsplatStartupManager
-- 
cgit v1.2.3


From bffe112cf5a1b9dd8acf5146c733a0fe186f6e89 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 17 Oct 2018 10:30:24 -0400
Subject: Last rev before Poseidon merge

---
 .hgtags | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.hgtags b/.hgtags
index 06d289325d..ea43dd32fc 100755
--- a/.hgtags
+++ b/.hgtags
@@ -541,3 +541,4 @@ ad0e15543836d64d6399d28b32852510435e344a 5.1.0-release
 ac3b1332ad4f55b7182a8cbcc1254535a0069f75 5.1.7-release
 23ea0fe36fadf009a60c080392ce80e4bf8af8d9 5.1.8-release
 52422540bfe54b71155aa455360bee6e3ef1fd96 5.1.9-release
+1cfa567caf5088ae299271be08cc2d9f0801ff6a pre-Poseidon
-- 
cgit v1.2.3


From d81863d23d49f3a71fb477d7e5c9d149b14da9f2 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 17 Oct 2018 10:56:43 -0400
Subject: DRTVWR-447: Finish merging Poseidon into BugSplat

---
 autobuild.xml                    |  54 +++++++
 indra/newview/CMakeLists.txt     | 339 +++++++++++++++++++++++++++------------
 indra/newview/viewer_manifest.py | 318 +++++++++++++++++++-----------------
 3 files changed, 466 insertions(+), 245 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index f0358eb8ba..b1f4597a70 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -225,6 +225,60 @@
         <key>version</key>
         <string>1.57</string>
       </map>
+      <key>bugsplat</key>
+      <map>
+        <key>copyright</key>
+        <string>Copyright 2003-2017, BugSplat</string>
+        <key>description</key>
+        <string>Bugsplat crash reporting package</string>
+        <key>license</key>
+        <string>Proprietary</string>
+        <key>license_file</key>
+        <string>LICENSES/BUGSPLAT_LICENSE.txt</string>
+        <key>name</key>
+        <string>bugsplat</string>
+        <key>platforms</key>
+        <map>
+          <key>darwin64</key>
+          <map>
+            <key>archive</key>
+            <map>
+              <key>hash</key>
+              <string>436b124bce8cf57b18dbf10f5e6ebcd4</string>
+              <key>url</key>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/26151/206132/bugsplat-1.0.7.520674-darwin64-520674.tar.bz2</string>
+            </map>
+            <key>name</key>
+            <string>darwin64</string>
+          </map>
+          <key>windows</key>
+          <map>
+            <key>archive</key>
+            <map>
+              <key>hash</key>
+              <string>5d19acddc51ee7c802297dd176194362</string>
+              <key>url</key>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/26153/206145/bugsplat-3.6.0.4.520674-windows-520674.tar.bz2</string>
+            </map>
+            <key>name</key>
+            <string>windows</string>
+          </map>
+          <key>windows64</key>
+          <map>
+            <key>archive</key>
+            <map>
+              <key>hash</key>
+              <string>78f5688b694e04c052fb0a1165c98bb5</string>
+              <key>url</key>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/26152/206142/bugsplat-3.6.0.4.520674-windows64-520674.tar.bz2</string>
+            </map>
+            <key>name</key>
+            <string>windows64</string>
+          </map>
+        </map>
+        <key>version</key>
+        <string>1.0.7.520674</string>
+      </map>
       <key>colladadom</key>
       <map>
         <key>copyright</key>
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index e7111ebe54..5c918fc3b2 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -3,7 +3,14 @@
 project(viewer)
 
 include(00-Common)
+# DON'T move Linking.cmake to its place in the alphabetized list below: it
+# sets variables on which the 3p .cmake files depend.
+include(Linking)
+
 include(Boost)
+if (BUGSPLAT_DB)
+  include(bugsplat)
+endif (BUGSPLAT_DB)
 include(BuildPackagesInfo)
 include(BuildVersion)
 include(CMakeCopyIfDifferent)
@@ -36,7 +43,6 @@ include(LLUI)
 include(LLVFS)
 include(LLWindow)
 include(LLXML)
-include(Linking)
 include(NDOF)
 include(NVAPI)
 include(OPENAL)
@@ -91,6 +97,12 @@ include_directories(
     ${CMAKE_CURRENT_SOURCE_DIR}
     )
 
+if (BUGSPLAT_DB)
+  include_directories(
+    ${BUGSPLAT_INCLUDE_DIR}
+    )
+endif (BUGSPLAT_DB)
+
 include_directories(SYSTEM
     ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
     ${LLXML_SYSTEM_INCLUDE_DIRS}
@@ -1354,6 +1366,14 @@ if (DARWIN)
 
   # This should be compiled with the viewer.
   LIST(APPEND viewer_SOURCE_FILES llappdelegate-objc.mm)
+  set_source_files_properties(
+    llappdelegate-objc.mm
+    PROPERTIES
+    COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}"
+    # BugsplatMac is a module, imported with @import. That language feature
+    # demands these switches.
+    COMPILE_FLAGS "-fmodules -fcxx-modules"
+    )
 
   find_library(AGL_LIBRARY AGL)
   find_library(APPKIT_LIBRARY AppKit)
@@ -1368,6 +1388,12 @@ if (DARWIN)
     ${COREAUDIO_LIBRARY}
     )
 
+  if (BUGSPLAT_DB)
+    list(APPEND viewer_LIBRARIES
+      ${BUGSPLAT_LIBRARIES}
+      )
+  endif (BUGSPLAT_DB)
+
   # Add resource files to the project.
   set(viewer_RESOURCE_FILES
     secondlife.icns
@@ -1393,6 +1419,11 @@ endif (DARWIN)
 
 if (LINUX)
     LIST(APPEND viewer_SOURCE_FILES llappviewerlinux.cpp)
+    set_source_files_properties(
+      llappviewerlinux.cpp
+      PROPERTIES
+      COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}"
+      )
     LIST(APPEND viewer_SOURCE_FILES llappviewerlinux_api_dbus.cpp)
     SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed")
 
@@ -1409,6 +1440,11 @@ if (WINDOWS)
          llappviewerwin32.cpp
          llwindebug.cpp
          )
+    set_source_files_properties(
+      llappviewerwin32.cpp
+      PROPERTIES
+      COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}"
+      )
 
     list(APPEND viewer_HEADER_FILES
          llappviewerwin32.h
@@ -1691,6 +1727,11 @@ if (SDL_FOUND)
     )
 endif (SDL_FOUND)
 
+if (BUGSPLAT_DB)
+  set_property(TARGET ${VIEWER_BINARY_NAME}
+    PROPERTY COMPILE_DEFINITIONS "LL_BUGSPLAT")
+endif (BUGSPLAT_DB)
+
 # add package files
 file(GLOB EVENT_HOST_SCRIPT_GLOB_LIST
      ${CMAKE_CURRENT_SOURCE_DIR}/../viewer_components/*.py)
@@ -1789,7 +1830,7 @@ if (WINDOWS)
            ${SHARED_LIB_STAGING_DIR}/Debug/fmodexL.dll
           )
     endif (FMODEX)
-    
+
     add_custom_command(
       OUTPUT  ${CMAKE_CFG_INTDIR}/copy_touched.bat
       COMMAND ${PYTHON_EXECUTABLE}
@@ -1798,15 +1839,16 @@ if (WINDOWS)
         --actions=copy
         --arch=${ARCH}
         --artwork=${ARTWORK_DIR}
+        "--bugsplat=${BUGSPLAT_DB}"
         --build=${CMAKE_CURRENT_BINARY_DIR}
         --buildtype=${CMAKE_BUILD_TYPE}
+        "--channel=${VIEWER_CHANNEL}"
         --configuration=${CMAKE_CFG_INTDIR}
         --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
         --grid=${GRID}
-        "--channel=${VIEWER_CHANNEL}"
-        --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
         --source=${CMAKE_CURRENT_SOURCE_DIR}
         --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/copy_touched.bat
+        --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
       DEPENDS
         ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
         stage_third_party_libs
@@ -1824,24 +1866,9 @@ if (WINDOWS)
 
     add_dependencies(${VIEWER_BINARY_NAME}
       SLPlugin
-   windows-crash-logger
+      windows-crash-logger
     )
 
-    # sets the 'working directory' for debugging from visual studio.
-    if (NOT UNATTENDED)
-        add_custom_command(
-            TARGET ${VIEWER_BINARY_NAME} POST_BUILD
-            COMMAND ${CMAKE_SOURCE_DIR}/tools/vstool/vstool.exe
-            ARGS
-              --solution
-              ${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}.sln
-              --workingdir
-              ${VIEWER_BINARY_NAME}
-              "${CMAKE_CURRENT_SOURCE_DIR}"
-            COMMENT "Setting the ${VIEWER_BINARY_NAME} working directory for debugging."
-            )
-    endif (NOT UNATTENDED)
-
     if (PACKAGE)
       add_custom_command(
         OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/event_host.tar.bz2
@@ -1864,15 +1891,16 @@ if (WINDOWS)
           ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
           --arch=${ARCH}
           --artwork=${ARTWORK_DIR}
+          "--bugsplat=${BUGSPLAT_DB}"
           --build=${CMAKE_CURRENT_BINARY_DIR}
           --buildtype=${CMAKE_BUILD_TYPE}
           "--channel=${VIEWER_CHANNEL}"
-          --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
           --configuration=${CMAKE_CFG_INTDIR}
           --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
           --grid=${GRID}
           --source=${CMAKE_CURRENT_SOURCE_DIR}
           --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/touched.bat
+          --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
         DEPENDS
             ${VIEWER_BINARY_NAME}
             ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
@@ -1903,8 +1931,8 @@ else (WINDOWS)
 endif (WINDOWS)
 
 # *NOTE: - this list is very sensitive to ordering, test carefully on all
-# platforms if you change the releative order of the entries here.
-# In particular, cmake 2.6.4 (when buidling with linux/makefile generators)
+# platforms if you change the relative order of the entries here.
+# In particular, cmake 2.6.4 (when building with linux/makefile generators)
 # appears to sometimes de-duplicate redundantly listed dependencies improperly.
 # To work around this, higher level modules should be listed before the modules
 # that they depend upon. -brad
@@ -1979,6 +2007,12 @@ target_link_libraries(${VIEWER_BINARY_NAME}
     ${LLAPPEARANCE_LIBRARIES}
     )
 
+if (BUGSPLAT_DB)
+  target_link_libraries(${VIEWER_BINARY_NAME}
+    ${BUGSPLAT_LIBRARIES}
+    )
+endif (BUGSPLAT_DB)
+
 set(ARTWORK_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE PATH
     "Path to artwork files.")
 
@@ -2002,15 +2036,16 @@ if (LINUX)
         ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
         --arch=${ARCH}
         --artwork=${ARTWORK_DIR}
+        "--bugsplat=${BUGSPLAT_DB}"
         --build=${CMAKE_CURRENT_BINARY_DIR}
         --buildtype=${CMAKE_BUILD_TYPE}
         "--channel=${VIEWER_CHANNEL}"
-        --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
         --configuration=${CMAKE_CFG_INTDIR}
         --dest=${CMAKE_CURRENT_BINARY_DIR}/packaged
         --grid=${GRID}
         --source=${CMAKE_CURRENT_SOURCE_DIR}
         --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.touched
+        --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
       DEPENDS
         ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
         ${COPY_INPUT_DEPENDENCIES}
@@ -2024,17 +2059,18 @@ if (LINUX)
     COMMAND ${PYTHON_EXECUTABLE}
     ARGS
       ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
-      --arch=${ARCH}
       --actions=copy
+      --arch=${ARCH}
       --artwork=${ARTWORK_DIR}
+      "--bugsplat=${BUGSPLAT_DB}"
       --build=${CMAKE_CURRENT_BINARY_DIR}
       --buildtype=${CMAKE_BUILD_TYPE}
+      "--channel=${VIEWER_CHANNEL}"
       --configuration=${CMAKE_CFG_INTDIR}
       --dest=${CMAKE_CURRENT_BINARY_DIR}/packaged
       --grid=${GRID}
-      "--channel=${VIEWER_CHANNEL}"
-      --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
       --source=${CMAKE_CURRENT_SOURCE_DIR}
+      --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
     DEPENDS
       ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
       ${COPY_INPUT_DEPENDENCIES}
@@ -2052,31 +2088,45 @@ if (LINUX)
 endif (LINUX)
 
 if (DARWIN)
-  # These all get set with PROPERTIES
-  set(product "Second Life")
-  set(MACOSX_EXECUTABLE_NAME "Second Life")
-  set(MACOSX_BUNDLE_INFO_STRING "Second Life Viewer")
+  # These all get set with PROPERTIES. It's not that the property names are
+  # magically known to CMake -- it's that these names are referenced in the
+  # Info-SecondLife.plist file in the configure_file() directive below.
+  set(product "${VIEWER_CHANNEL}")
+  set(MACOSX_BUNDLE_INFO_STRING "${VIEWER_CHANNEL}")
   set(MACOSX_BUNDLE_ICON_FILE "secondlife.icns")
   set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.secondlife.indra.viewer")
   set(MACOSX_BUNDLE_LONG_VERSION_STRING "${VIEWER_CHANNEL} ${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}")
   set(MACOSX_BUNDLE_BUNDLE_NAME "SecondLife")
-  set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${VIEWER_SHORT_VERSION}")
+  set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}")
   set(MACOSX_BUNDLE_BUNDLE_VERSION "${VIEWER_SHORT_VERSION}${VIEWER_MACOSX_PHASE}${VIEWER_REVISION}")
   set(MACOSX_BUNDLE_COPYRIGHT "Copyright © Linden Research, Inc. 2007")
   set(MACOSX_BUNDLE_NSMAIN_NIB_FILE "SecondLife.nib")
   set(MACOSX_BUNDLE_NSPRINCIPAL_CLASS "NSApplication")
+
+  # https://blog.kitware.com/upcoming-in-cmake-2-8-12-osx-rpath-support/
+  set(CMAKE_MACOSX_RPATH 1)
   
   set_target_properties(
     ${VIEWER_BINARY_NAME}
     PROPERTIES
     OUTPUT_NAME "${product}"
+    # From Contents/MacOS/SecondLife, look in Contents/Frameworks
+    INSTALL_RPATH "@loader_path/../Frameworks"
+    # SIGH, as of 2018-05-24 (cmake 3.11.1) the INSTALL_RPATH property simply
+    # does not work. Try this:
+    LINK_FLAGS "-rpath @loader_path/../Frameworks"
     MACOSX_BUNDLE_INFO_PLIST
     "${CMAKE_CURRENT_SOURCE_DIR}/Info-SecondLife.plist"
     )
 
+  set(VIEWER_APP_BUNDLE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app")
+  set(VIEWER_APP_EXE "${VIEWER_APP_BUNDLE}/Contents/MacOS/${product}")
+  set(VIEWER_APP_DSYM "${VIEWER_APP_EXE}.dSYM")
+  set(VIEWER_APP_XCARCHIVE "${VIEWER_APP_BUNDLE}/../${product}.xcarchive.zip")
+
   configure_file(
      "${CMAKE_CURRENT_SOURCE_DIR}/Info-SecondLife.plist"
-     "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app/Contents/Info.plist"
+     "${VIEWER_APP_BUNDLE}/Contents/Info.plist"
     )
 
   add_custom_command(
@@ -2087,15 +2137,16 @@ if (DARWIN)
       --actions=copy
       --arch=${ARCH}
       --artwork=${ARTWORK_DIR}
+      "--bugsplat=${BUGSPLAT_DB}"
       --build=${CMAKE_CURRENT_BINARY_DIR}
       --buildtype=${CMAKE_BUILD_TYPE}
+      --bundleid=${MACOSX_BUNDLE_GUI_IDENTIFIER}
+      "--channel=${VIEWER_CHANNEL}"
       --configuration=${CMAKE_CFG_INTDIR}
-      --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app
+      --dest=${VIEWER_APP_BUNDLE}
       --grid=${GRID}
-      "--channel=${VIEWER_CHANNEL}"
-      --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
-      --bundleid=${MACOSX_BUNDLE_GUI_IDENTIFIER}
       --source=${CMAKE_CURRENT_SOURCE_DIR}
+      --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
     DEPENDS
       ${VIEWER_BINARY_NAME}
       ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
@@ -2120,15 +2171,16 @@ if (DARWIN)
           ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
           --arch=${ARCH}
           --artwork=${ARTWORK_DIR}
+          "--bugsplat=${BUGSPLAT_DB}"
           --build=${CMAKE_CURRENT_BINARY_DIR}
           --buildtype=${CMAKE_BUILD_TYPE}
+          "--channel=${VIEWER_CHANNEL}"
           --configuration=${CMAKE_CFG_INTDIR}
-          --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app
+          --dest=${VIEWER_APP_BUNDLE}
           --grid=${GRID}
-          "--channel=${VIEWER_CHANNEL}"
-          --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
           --source=${CMAKE_CURRENT_SOURCE_DIR}
           --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.touched
+          --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
           ${SIGNING_SETTING}
         DEPENDS
           ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
@@ -2140,67 +2192,152 @@ if (INSTALL)
   include(${CMAKE_CURRENT_SOURCE_DIR}/ViewerInstall.cmake)
 endif (INSTALL)
 
-if (PACKAGE)
-  set(SYMBOL_SEARCH_DIRS "")
-  # Note that the path to VIEWER_SYMBOL_FILE must match that in ../../build.sh
-  if (WINDOWS)
-    list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
-    set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-windows-$ENV{AUTOBUILD_ADDRSIZE}.tar.bz2")
-    # slplugin.exe failing symbols dump - need to debug, might have to do with updated version of google breakpad
-    # set(VIEWER_EXE_GLOBS "${VIEWER_BINARY_NAME}${CMAKE_EXECUTABLE_SUFFIX} slplugin.exe")
-    set(VIEWER_EXE_GLOBS "${VIEWER_BINARY_NAME}${CMAKE_EXECUTABLE_SUFFIX}")
-    set(VIEWER_LIB_GLOB "*${CMAKE_SHARED_MODULE_SUFFIX}")
-    set(VIEWER_COPY_MANIFEST copy_w_viewer_manifest)
-  endif (WINDOWS)
-  if (DARWIN)
-    list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
-    # *TODO: Generate these search dirs in the cmake files related to each binary.
-    list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/llplugin/slplugin/${CMAKE_CFG_INTDIR}")
-    list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/mac_crash_logger/${CMAKE_CFG_INTDIR}")
-    list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/gstreamer010/${CMAKE_CFG_INTDIR}")
-    set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-darwin-$ENV{AUTOBUILD_ADDRSIZE}.tar.bz2")
-    set(VIEWER_EXE_GLOBS "'Second Life' SLPlugin mac-crash-logger")
-    set(VIEWER_EXE_GLOBS "'Second Life' mac-crash-logger")
-    set(VIEWER_LIB_GLOB "*.dylib")
-  endif (DARWIN)
-  if (LINUX)
-    list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/packaged")
-    set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-linux-$ENV{AUTOBUILD_ADDRSIZE}.tar.bz2")
-    set(VIEWER_EXE_GLOBS "do-not-directly-run-secondlife-bin SLPlugin")
-    set(VIEWER_EXE_GLOBS "do-not-directly-run-secondlife-bin")
-    set(VIEWER_LIB_GLOB "*${CMAKE_SHARED_MODULE_SUFFIX}*")
-    set(VIEWER_COPY_MANIFEST copy_l_viewer_manifest)
-  endif (LINUX)
-
-  if(RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING)
-  if(CMAKE_CFG_INTDIR STREQUAL ".")
-      set(LLBUILD_CONFIG ${CMAKE_BUILD_TYPE})
-  else(CMAKE_CFG_INTDIR STREQUAL ".")
-      # set LLBUILD_CONFIG to be a shell variable evaluated at build time
-      # reflecting the configuration we are currently building.
-      set(LLBUILD_CONFIG ${CMAKE_CFG_INTDIR})
-  endif(CMAKE_CFG_INTDIR STREQUAL ".")
-  add_custom_command(OUTPUT "${VIEWER_SYMBOL_FILE}"
-    COMMAND "${PYTHON_EXECUTABLE}"
-    ARGS
-      "${CMAKE_CURRENT_SOURCE_DIR}/generate_breakpad_symbols.py"
-      "${LLBUILD_CONFIG}"
-      "${SYMBOL_SEARCH_DIRS}"
-      "${VIEWER_EXE_GLOBS}"
-      "${VIEWER_LIB_GLOB}"
-      "${AUTOBUILD_INSTALL_DIR}/bin/dump_syms"
-      "${VIEWER_SYMBOL_FILE}"
-    DEPENDS generate_breakpad_symbols.py
-        VERBATIM)
-
-  add_custom_target(generate_breakpad_symbols DEPENDS "${VIEWER_SYMBOL_FILE}" "${VIEWER_BINARY_NAME}" "${VIEWER_COPY_MANIFEST}")
-  add_dependencies(generate_breakpad_symbols "${VIEWER_BINARY_NAME}")
-  if (WINDOWS OR LINUX)
-    add_dependencies(generate_breakpad_symbols "${VIEWER_COPY_MANIFEST}")
-  endif (WINDOWS OR LINUX)
-  add_dependencies(llpackage generate_breakpad_symbols)
-  endif(RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING)
-endif (PACKAGE)
+# Note that the conventional VIEWER_SYMBOL_FILE is set by ../../build.sh
+if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIEWER_SYMBOL_FILE)
+  if (NOT BUGSPLAT_DB)
+    # Breakpad symbol-file generation
+    set(SYMBOL_SEARCH_DIRS "")
+    if (WINDOWS)
+      list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
+      # slplugin.exe failing symbols dump - need to debug, might have to do with updated version of google breakpad
+      # set(VIEWER_EXE_GLOBS "${VIEWER_BINARY_NAME}${CMAKE_EXECUTABLE_SUFFIX} slplugin.exe")
+      set(VIEWER_EXE_GLOBS "${VIEWER_BINARY_NAME}${CMAKE_EXECUTABLE_SUFFIX}")
+      set(VIEWER_LIB_GLOB "*${CMAKE_SHARED_MODULE_SUFFIX}")
+      set(VIEWER_COPY_MANIFEST copy_w_viewer_manifest)
+    endif (WINDOWS)
+    if (DARWIN)
+      list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
+      # *TODO: Generate these search dirs in the cmake files related to each binary.
+      list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/llplugin/slplugin/${CMAKE_CFG_INTDIR}")
+      list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/mac_crash_logger/${CMAKE_CFG_INTDIR}")
+      list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/gstreamer010/${CMAKE_CFG_INTDIR}")
+      set(VIEWER_EXE_GLOBS "'${product}' SLPlugin mac-crash-logger")
+      set(VIEWER_EXE_GLOBS "'${product}' mac-crash-logger")
+      set(VIEWER_LIB_GLOB "*.dylib")
+    endif (DARWIN)
+    if (LINUX)
+      list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/packaged")
+      set(VIEWER_EXE_GLOBS "do-not-directly-run-secondlife-bin SLPlugin")
+      set(VIEWER_EXE_GLOBS "do-not-directly-run-secondlife-bin")
+      set(VIEWER_LIB_GLOB "*${CMAKE_SHARED_MODULE_SUFFIX}*")
+      set(VIEWER_COPY_MANIFEST copy_l_viewer_manifest)
+    endif (LINUX)
+
+    if(CMAKE_CFG_INTDIR STREQUAL ".")
+        set(LLBUILD_CONFIG ${CMAKE_BUILD_TYPE})
+    else(CMAKE_CFG_INTDIR STREQUAL ".")
+        # set LLBUILD_CONFIG to be a shell variable evaluated at build time
+        # reflecting the configuration we are currently building.
+        set(LLBUILD_CONFIG ${CMAKE_CFG_INTDIR})
+    endif(CMAKE_CFG_INTDIR STREQUAL ".")
+    add_custom_command(OUTPUT "${VIEWER_SYMBOL_FILE}"
+      COMMAND "${PYTHON_EXECUTABLE}"
+      ARGS
+        "${CMAKE_CURRENT_SOURCE_DIR}/generate_breakpad_symbols.py"
+        "${LLBUILD_CONFIG}"
+        "${SYMBOL_SEARCH_DIRS}"
+        "${VIEWER_EXE_GLOBS}"
+        "${VIEWER_LIB_GLOB}"
+        "${AUTOBUILD_INSTALL_DIR}/bin/dump_syms"
+        "${VIEWER_SYMBOL_FILE}"
+      DEPENDS generate_breakpad_symbols.py
+          VERBATIM)
+
+    add_custom_target(generate_symbols DEPENDS "${VIEWER_SYMBOL_FILE}" ${VIEWER_BINARY_NAME} "${VIEWER_COPY_MANIFEST}")
+    add_dependencies(generate_symbols ${VIEWER_BINARY_NAME})
+    if (WINDOWS OR LINUX)
+      add_dependencies(generate_symbols "${VIEWER_COPY_MANIFEST}")
+    endif (WINDOWS OR LINUX)
+
+  else (NOT BUGSPLAT_DB)
+    # BugSplat symbol-file generation
+    if (WINDOWS)
+      # Just pack up a tarball containing only the .pdb file for the
+      # executable. Because we intend to use cygwin tar, we must render
+      # VIEWER_SYMBOL_FILE in cygwin path syntax.
+      execute_process(COMMAND "cygpath" "-u" "${VIEWER_SYMBOL_FILE}"
+        OUTPUT_VARIABLE VIEWER_SYMBOL_FILE_CYGWIN
+        OUTPUT_STRIP_TRAILING_WHITESPACE)
+      execute_process(COMMAND "cygpath" "-u" "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}"
+        OUTPUT_VARIABLE PARENT_DIRECTORY_CYGWIN
+        OUTPUT_STRIP_TRAILING_WHITESPACE)
+      add_custom_command(OUTPUT "${VIEWER_SYMBOL_FILE}"
+        # Use of 'tar ...j' here assumes VIEWER_SYMBOL_FILE endswith .tar.bz2;
+        # testing a string suffix is painful enough in CMake language that
+        # we'll continue assuming it until forced to generalize.
+        COMMAND "tar"
+        ARGS
+          "cjf"
+          "${VIEWER_SYMBOL_FILE_CYGWIN}"
+          "-C"
+          "${PARENT_DIRECTORY_CYGWIN}"
+          "secondlife-bin.pdb"
+        DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-bin.pdb"
+        COMMENT "Packing viewer PDB into ${VIEWER_SYMBOL_FILE_CYGWIN}"
+        )
+      add_custom_target(generate_symbols DEPENDS "${VIEWER_SYMBOL_FILE}" ${VIEWER_BINARY_NAME})
+      add_dependencies(generate_symbols ${VIEWER_BINARY_NAME})
+    endif (WINDOWS)
+    if (DARWIN)
+      # Have to run dsymutil first, then pack up the resulting .dSYM directory
+      add_custom_command(OUTPUT "${VIEWER_APP_DSYM}"
+        COMMAND "dsymutil"
+        ARGS
+          ${VIEWER_APP_EXE}
+        COMMENT "Generating ${VIEWER_APP_DSYM}"
+        )
+      add_custom_target(dsym_generate DEPENDS "${VIEWER_APP_DSYM}")
+      add_dependencies(dsym_generate ${VIEWER_BINARY_NAME})
+      add_custom_command(OUTPUT "${VIEWER_SYMBOL_FILE}"
+        # See above comments about "tar ...j"
+        COMMAND "tar"
+        ARGS
+          "cjf"
+          "${VIEWER_SYMBOL_FILE}"
+          "-C"
+          "${VIEWER_APP_DSYM}/.."
+          "${product}.dSYM"
+        DEPENDS "${VIEWER_APP_DSYM}"
+        COMMENT "Packing dSYM into ${VIEWER_SYMBOL_FILE}"
+        )
+      add_custom_target(dsym_tarball DEPENDS "${VIEWER_SYMBOL_FILE}")
+      add_dependencies(dsym_tarball dsym_generate)
+      add_custom_command(OUTPUT "${VIEWER_APP_XCARCHIVE}"
+        COMMAND "zip"
+        ARGS
+          "-r"
+          "${VIEWER_APP_XCARCHIVE}"
+          "."
+        WORKING_DIRECTORY "${VIEWER_APP_DSYM}/.."
+        DEPENDS "${VIEWER_APP_DSYM}"
+        COMMENT "Generating xcarchive.zip for upload to BugSplat"
+        )
+      add_custom_target(dsym_xcarchive DEPENDS "${VIEWER_APP_XCARCHIVE}")
+      add_dependencies(dsym_xcarchive dsym_generate)
+      # Have to create a stamp file, and depend on it, to force CMake to run
+      # the cleanup step.
+      add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/dsym.stamp"
+        COMMAND rm -rf "${VIEWER_APP_DSYM}"
+        COMMAND touch "${CMAKE_CURRENT_BINARY_DIR}/dsym.stamp"
+        DEPENDS "${VIEWER_SYMBOL_FILE}" "${VIEWER_APP_XCARCHIVE}"
+        COMMENT "Cleaning up dSYM"
+        )
+      add_custom_target(generate_symbols DEPENDS
+        "${VIEWER_APP_DSYM}"
+        "${VIEWER_SYMBOL_FILE}"
+        "${VIEWER_APP_XCARCHIVE}"
+        "${CMAKE_CURRENT_BINARY_DIR}/dsym.stamp"
+        )
+      add_dependencies(generate_symbols dsym_tarball dsym_xcarchive)
+    endif (DARWIN)
+    if (LINUX)
+      # TBD
+    endif (LINUX)
+  endif (NOT BUGSPLAT_DB)
+
+  # for both BUGSPLAT_DB and Breakpad
+  add_dependencies(llpackage generate_symbols)
+endif ()
 
 if (LL_TESTS)
   # To add a viewer unit test, just add the test .cpp file below
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 57da87a3ee..5dd4d13a3a 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -26,19 +26,20 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 $/LicenseInfo$
 """
-import sys
-import os
-import os.path
-import shutil
 import errno
 import json
+import os
+import os.path
 import plistlib
 import random
 import re
+import shutil
 import stat
 import subprocess
+import sys
 import tarfile
 import time
+import zipfile
 
 viewer_dir = os.path.dirname(__file__)
 # Add indra/lib/python to our path so we don't have to muck with PYTHONPATH.
@@ -63,7 +64,7 @@ class ViewerManifest(LLManifest):
         self.path(src="../../etc/message.xml", dst="app_settings/message.xml")
 
         if self.is_packaging_viewer():
-            with self.prefix(src="app_settings"):
+            with self.prefix(src_dst="app_settings"):
                 self.exclude("logcontrol.xml")
                 self.exclude("logcontrol-dev.xml")
                 self.path("*.ini")
@@ -85,7 +86,7 @@ class ViewerManifest(LLManifest):
             
                 # ... and the included spell checking dictionaries
                 pkgdir = os.path.join(self.args['build'], os.pardir, 'packages')
-                with self.prefix(src=pkgdir,dst=""):
+                with self.prefix(src=pkgdir):
                     self.path("dictionaries")
 
                 # include the extracted packages information (see BuildPackagesInfo.cmake)
@@ -107,17 +108,18 @@ class ViewerManifest(LLManifest):
                                         Type='String',
                                         Value=''))
                 settings_install = {}
-                if 'sourceid' in self.args and self.args['sourceid']:
+                sourceid = self.args.get('sourceid')
+                if sourceid:
                     settings_install['sourceid'] = settings_template['sourceid'].copy()
-                    settings_install['sourceid']['Value'] = self.args['sourceid']
-                    print "Set sourceid in settings_install.xml to '%s'" % self.args['sourceid']
+                    settings_install['sourceid']['Value'] = sourceid
+                    print "Set sourceid in settings_install.xml to '%s'" % sourceid
 
-                if 'channel_suffix' in self.args and self.args['channel_suffix']:
+                if self.args.get('channel_suffix'):
                     settings_install['CmdLineChannel'] = settings_template['CmdLineChannel'].copy()
                     settings_install['CmdLineChannel']['Value'] = self.channel_with_pkg_suffix()
                     print "Set CmdLineChannel in settings_install.xml to '%s'" % self.channel_with_pkg_suffix()
 
-                if 'grid' in self.args and self.args['grid']:
+                if self.args.get('grid'):
                     settings_install['CmdLineGridChoice'] = settings_template['CmdLineGridChoice'].copy()
                     settings_install['CmdLineGridChoice']['Value'] = self.grid()
                     print "Set CmdLineGridChoice in settings_install.xml to '%s'" % self.grid()
@@ -129,20 +131,20 @@ class ViewerManifest(LLManifest):
                                  src="environment")
 
 
-            with self.prefix(src="character"):
+            with self.prefix(src_dst="character"):
                 self.path("*.llm")
                 self.path("*.xml")
                 self.path("*.tga")
 
             # Include our fonts
-            with self.prefix(src="fonts"):
+            with self.prefix(src_dst="fonts"):
                 self.path("*.ttf")
                 self.path("*.txt")
 
             # skins
-            with self.prefix(src="skins"):
+            with self.prefix(src_dst="skins"):
                     # include the entire textures directory recursively
-                    with self.prefix(src="*/textures"):
+                    with self.prefix(src_dst="*/textures"):
                             self.path("*/*.tga")
                             self.path("*/*.j2c")
                             self.path("*/*.jpg")
@@ -170,7 +172,7 @@ class ViewerManifest(LLManifest):
 
 
             # local_assets dir (for pre-cached textures)
-            with self.prefix(src="local_assets"):
+            with self.prefix(src_dst="local_assets"):
                 self.path("*.j2c")
                 self.path("*.tga")
 
@@ -186,6 +188,10 @@ class ViewerManifest(LLManifest):
                             "Address Size":self.address_size,
                             "Update Service":"https://update.secondlife.com/update",
                             }
+            # Only store this if it's both present and non-empty
+            bugsplat_db = self.args.get('bugsplat')
+            if bugsplat_db:
+                build_data_dict["BugSplat DB"] = bugsplat_db
             build_data_dict = self.finish_build_data_dict(build_data_dict)
             with open(os.path.join(os.pardir,'build_data.json'), 'w') as build_data_handle:
                 json.dump(build_data_dict,build_data_handle)
@@ -206,8 +212,9 @@ class ViewerManifest(LLManifest):
 
     def channel_with_pkg_suffix(self):
         fullchannel=self.channel()
-        if 'channel_suffix' in self.args and self.args['channel_suffix']:
-            fullchannel+=' '+self.args['channel_suffix']
+        channel_suffix = self.args.get('channel_suffix')
+        if channel_suffix:
+            fullchannel+=' '+channel_suffix
         return fullchannel
 
     def channel_variant(self):
@@ -215,8 +222,7 @@ class ViewerManifest(LLManifest):
         return self.channel().replace(CHANNEL_VENDOR_BASE, "").strip()
 
     def channel_type(self): # returns 'release', 'beta', 'project', or 'test'
-        global CHANNEL_VENDOR_BASE
-        channel_qualifier=self.channel().replace(CHANNEL_VENDOR_BASE, "").lower().strip()
+        channel_qualifier=self.channel_variant().lower()
         if channel_qualifier.startswith('release'):
             channel_type='release'
         elif channel_qualifier.startswith('beta'):
@@ -234,11 +240,12 @@ class ViewerManifest(LLManifest):
         if self.channel_type() == 'release':
             suffix=suffix.replace('Release', '').strip()
         # for the base release viewer, suffix will now be null - for any other, append what remains
-        if len(suffix) > 0:
-            suffix = "_"+ ("_".join(suffix.split()))
+        if suffix:
+            suffix = "_".join([''] + suffix.split())
         # the additional_packages mechanism adds more to the installer name (but not to the app name itself)
-        if 'channel_suffix' in self.args and self.args['channel_suffix']:
-            suffix+='_'+("_".join(self.args['channel_suffix'].split()))
+        # ''.split() produces empty list, so suffix only changes if
+        # channel_suffix is non-empty
+        suffix = "_".join([suffix] + self.args.get('channel_suffix', '').split())
         return suffix
 
     def installer_base_name(self):
@@ -488,19 +495,19 @@ class WindowsManifest(ViewerManifest):
             # Find secondlife-bin.exe in the 'configuration' dir, then rename it to the result of final_exe.
             self.path(src='%s/secondlife-bin.exe' % self.args['configuration'], dst=self.final_exe())
 
-            with self.prefix(src=os.path.join(pkgdir, "VMP"), dst=""):
+            with self.prefix(src=os.path.join(pkgdir, "VMP")):
                 # include the compiled launcher scripts so that it gets included in the file_list
                 self.path('updater.exe')
                 #IUM is not normally executed directly, just imported.  No exe needed.
                 self.path("InstallerUserMessage.py")
 
-            with self.prefix(src=self.icon_path(), dst="vmp_icons"):
-                self.path("secondlife.ico")
-
-            #VMP  Tkinter icons
-            with self.prefix("vmp_icons"):
-                self.path("*.png")
-                self.path("*.gif")
+            with self.prefix(dst="vmp_icons"):
+                with self.prefix(src=self.icon_path()):
+                    self.path("secondlife.ico")
+                #VMP  Tkinter icons
+                with self.prefix(src="vmp_icons"):
+                    self.path("*.png")
+                    self.path("*.gif")
 
         # Plugin host application
         self.path2basename(os.path.join(os.pardir,
@@ -508,8 +515,8 @@ class WindowsManifest(ViewerManifest):
                            "slplugin.exe")
         
         # Get shared libs from the shared libs staging directory
-        with self.prefix(src=os.path.join(os.pardir, 'sharedlibs', self.args['configuration']),
-                       dst=""):
+        with self.prefix(src=os.path.join(self.args['build'], os.pardir,
+                                          'sharedlibs', self.args['configuration'])):
 
             # Get llcommon and deps. If missing assume static linkage and continue.
             try:
@@ -575,6 +582,17 @@ class WindowsManifest(ViewerManifest):
             # Hunspell
             self.path("libhunspell.dll")
 
+            # BugSplat
+            if self.args.get('bugsplat'):
+                if(self.address_size == 64):
+                    self.path("BsSndRpt64.exe")
+                    self.path("BugSplat64.dll")
+                    self.path("BugSplatRc64.dll")
+                else:
+                    self.path("BsSndRpt.exe")
+                    self.path("BugSplat.dll")
+                    self.path("BugSplatRc.dll")
+
             # For google-perftools tcmalloc allocator.
             try:
                 if self.args['configuration'].lower() == 'debug':
@@ -584,114 +602,116 @@ class WindowsManifest(ViewerManifest):
             except:
                 print "Skipping libtcmalloc_minimal.dll"
 
-
         self.path(src="licenses-win32.txt", dst="licenses.txt")
         self.path("featuretable.txt")
 
-        with self.prefix(src=pkgdir,dst=""):
+        with self.prefix(src=pkgdir):
             self.path("ca-bundle.crt")
 
         # Media plugins - CEF
-        with self.prefix(src='../media_plugins/cef/%s' % self.args['configuration'], dst="llplugin"):
-            self.path("media_plugin_cef.dll")
-
-        # Media plugins - LibVLC
-        with self.prefix(src='../media_plugins/libvlc/%s' % self.args['configuration'], dst="llplugin"):
-            self.path("media_plugin_libvlc.dll")
-
-        # Media plugins - Example (useful for debugging - not shipped with release viewer)
-        if self.channel_type() != 'release':
-            with self.prefix(src='../media_plugins/example/%s' % self.args['configuration'], dst="llplugin"):
-                self.path("media_plugin_example.dll")
-
-        # CEF runtime files - debug
-        # CEF runtime files - not debug (release, relwithdebinfo etc.)
-        config = 'debug' if self.args['configuration'].lower() == 'debug' else 'release'
-        with self.prefix(src=os.path.join(pkgdir, 'bin', config), dst="llplugin"):
-            self.path("chrome_elf.dll")
-            self.path("d3dcompiler_43.dll")
-            self.path("d3dcompiler_47.dll")
-            self.path("libcef.dll")
-            self.path("libEGL.dll")
-            self.path("libGLESv2.dll")
-            self.path("dullahan_host.exe")
-            self.path("natives_blob.bin")
-            self.path("snapshot_blob.bin")
-            self.path("widevinecdmadapter.dll")
-
-        # MSVC DLLs needed for CEF and have to be in same directory as plugin
-        with self.prefix(src=os.path.join(os.pardir, 'sharedlibs', 'Release'), dst="llplugin"):
-            self.path("msvcp120.dll")
-            self.path("msvcr120.dll")
-
-        # CEF files common to all configurations
-        with self.prefix(src=os.path.join(pkgdir, 'resources'), dst="llplugin"):
-            self.path("cef.pak")
-            self.path("cef_100_percent.pak")
-            self.path("cef_200_percent.pak")
-            self.path("cef_extensions.pak")
-            self.path("devtools_resources.pak")
-            self.path("icudtl.dat")
-
-        with self.prefix(src=os.path.join(pkgdir, 'resources', 'locales'), dst=os.path.join('llplugin', 'locales')):
-            self.path("am.pak")
-            self.path("ar.pak")
-            self.path("bg.pak")
-            self.path("bn.pak")
-            self.path("ca.pak")
-            self.path("cs.pak")
-            self.path("da.pak")
-            self.path("de.pak")
-            self.path("el.pak")
-            self.path("en-GB.pak")
-            self.path("en-US.pak")
-            self.path("es-419.pak")
-            self.path("es.pak")
-            self.path("et.pak")
-            self.path("fa.pak")
-            self.path("fi.pak")
-            self.path("fil.pak")
-            self.path("fr.pak")
-            self.path("gu.pak")
-            self.path("he.pak")
-            self.path("hi.pak")
-            self.path("hr.pak")
-            self.path("hu.pak")
-            self.path("id.pak")
-            self.path("it.pak")
-            self.path("ja.pak")
-            self.path("kn.pak")
-            self.path("ko.pak")
-            self.path("lt.pak")
-            self.path("lv.pak")
-            self.path("ml.pak")
-            self.path("mr.pak")
-            self.path("ms.pak")
-            self.path("nb.pak")
-            self.path("nl.pak")
-            self.path("pl.pak")
-            self.path("pt-BR.pak")
-            self.path("pt-PT.pak")
-            self.path("ro.pak")
-            self.path("ru.pak")
-            self.path("sk.pak")
-            self.path("sl.pak")
-            self.path("sr.pak")
-            self.path("sv.pak")
-            self.path("sw.pak")
-            self.path("ta.pak")
-            self.path("te.pak")
-            self.path("th.pak")
-            self.path("tr.pak")
-            self.path("uk.pak")
-            self.path("vi.pak")
-            self.path("zh-CN.pak")
-            self.path("zh-TW.pak")
-
-        with self.prefix(src=os.path.join(pkgdir, 'bin', 'release'), dst="llplugin"):
-            self.path("libvlc.dll")
-            self.path("libvlccore.dll")
-            self.path("plugins/")
+        with self.prefix(dst="llplugin"):
+            with self.prefix(src=os.path.join(self.args['build'], os.pardir, 'media_plugins')):
+                with self.prefix(src=os.path.join('cef', self.args['configuration'])):
+                    self.path("media_plugin_cef.dll")
+
+                # Media plugins - LibVLC
+                with self.prefix(src=os.path.join('libvlc', self.args['configuration'])):
+                    self.path("media_plugin_libvlc.dll")
+
+                # Media plugins - Example (useful for debugging - not shipped with release viewer)
+                if self.channel_type() != 'release':
+                    with self.prefix(src=os.path.join('example', self.args['configuration'])):
+                        self.path("media_plugin_example.dll")
+
+            # CEF runtime files - debug
+            # CEF runtime files - not debug (release, relwithdebinfo etc.)
+            config = 'debug' if self.args['configuration'].lower() == 'debug' else 'release'
+            with self.prefix(src=os.path.join(pkgdir, 'bin', config)):
+                self.path("chrome_elf.dll")
+                self.path("d3dcompiler_43.dll")
+                self.path("d3dcompiler_47.dll")
+                self.path("libcef.dll")
+                self.path("libEGL.dll")
+                self.path("libGLESv2.dll")
+                self.path("dullahan_host.exe")
+                self.path("natives_blob.bin")
+                self.path("snapshot_blob.bin")
+                self.path("widevinecdmadapter.dll")
+
+            # MSVC DLLs needed for CEF and have to be in same directory as plugin
+            with self.prefix(src=os.path.join(self.args['build'], os.pardir,
+                                              'sharedlibs', 'Release')):
+                self.path("msvcp120.dll")
+                self.path("msvcr120.dll")
+
+            # CEF files common to all configurations
+            with self.prefix(src=os.path.join(pkgdir, 'resources')):
+                self.path("cef.pak")
+                self.path("cef_100_percent.pak")
+                self.path("cef_200_percent.pak")
+                self.path("cef_extensions.pak")
+                self.path("devtools_resources.pak")
+                self.path("icudtl.dat")
+
+            with self.prefix(src=os.path.join(pkgdir, 'resources', 'locales'), dst='locales'):
+                self.path("am.pak")
+                self.path("ar.pak")
+                self.path("bg.pak")
+                self.path("bn.pak")
+                self.path("ca.pak")
+                self.path("cs.pak")
+                self.path("da.pak")
+                self.path("de.pak")
+                self.path("el.pak")
+                self.path("en-GB.pak")
+                self.path("en-US.pak")
+                self.path("es-419.pak")
+                self.path("es.pak")
+                self.path("et.pak")
+                self.path("fa.pak")
+                self.path("fi.pak")
+                self.path("fil.pak")
+                self.path("fr.pak")
+                self.path("gu.pak")
+                self.path("he.pak")
+                self.path("hi.pak")
+                self.path("hr.pak")
+                self.path("hu.pak")
+                self.path("id.pak")
+                self.path("it.pak")
+                self.path("ja.pak")
+                self.path("kn.pak")
+                self.path("ko.pak")
+                self.path("lt.pak")
+                self.path("lv.pak")
+                self.path("ml.pak")
+                self.path("mr.pak")
+                self.path("ms.pak")
+                self.path("nb.pak")
+                self.path("nl.pak")
+                self.path("pl.pak")
+                self.path("pt-BR.pak")
+                self.path("pt-PT.pak")
+                self.path("ro.pak")
+                self.path("ru.pak")
+                self.path("sk.pak")
+                self.path("sl.pak")
+                self.path("sr.pak")
+                self.path("sv.pak")
+                self.path("sw.pak")
+                self.path("ta.pak")
+                self.path("te.pak")
+                self.path("th.pak")
+                self.path("tr.pak")
+                self.path("uk.pak")
+                self.path("vi.pak")
+                self.path("zh-CN.pak")
+                self.path("zh-TW.pak")
+
+            with self.prefix(src=os.path.join(pkgdir, 'bin', 'release')):
+                self.path("libvlc.dll")
+                self.path("libvlccore.dll")
+                self.path("plugins/")
 
         # pull in the crash logger and updater from other projects
         # tag:"crash-logger" here as a cue to the exporter
@@ -874,6 +894,12 @@ class DarwinManifest(ViewerManifest):
         # darwin requires full app bundle packaging even for debugging.
         return True
 
+    def is_rearranging(self):
+        # That said, some stuff should still only be performed once.
+        # Are either of these actions in 'actions'? Is the set intersection
+        # non-empty?
+        return bool(set(["package", "unpacked"]).intersection(self.args['actions']))
+
     def construct(self):
         # copy over the build result (this is a no-op if run within the xcode script)
         self.path(os.path.join(self.args['configuration'], "Second Life.app"), dst="")
@@ -1362,19 +1388,19 @@ class LinuxManifest(ViewerManifest):
         debpkgdir = os.path.join(pkgdir, "lib", "debug")
 
         self.path("licenses-linux.txt","licenses.txt")
-        with self.prefix("linux_tools", dst=""):
+        with self.prefix("linux_tools"):
             self.path("client-readme.txt","README-linux.txt")
             self.path("client-readme-voice.txt","README-linux-voice.txt")
             self.path("client-readme-joystick.txt","README-linux-joystick.txt")
             self.path("wrapper.sh","secondlife")
-            with self.prefix(src="", dst="etc"):
+            with self.prefix(dst="etc"):
                 self.path("handle_secondlifeprotocol.sh")
                 self.path("register_secondlifeprotocol.sh")
                 self.path("refresh_desktop_app_entry.sh")
                 self.path("launch_url.sh")
             self.path("install.sh")
 
-        with self.prefix(src="", dst="bin"):
+        with self.prefix(dst="bin"):
             self.path("secondlife-bin","do-not-directly-run-secondlife-bin")
             self.path("../linux_crash_logger/linux-crash-logger","linux-crash-logger.bin")
             self.path2basename("../llplugin/slplugin", "SLPlugin") 
@@ -1388,9 +1414,9 @@ class LinuxManifest(ViewerManifest):
         # Get the icons based on the channel type
         icon_path = self.icon_path()
         print "DEBUG: icon_path '%s'" % icon_path
-        with self.prefix(src=icon_path, dst="") :
+        with self.prefix(src=icon_path) :
             self.path("secondlife_256.png","secondlife_icon.png")
-            with self.prefix(src="",dst="res-sdl") :
+            with self.prefix(dst="res-sdl") :
                 self.path("secondlife_256.BMP","ll_icon.BMP")
 
         # plugins
@@ -1412,7 +1438,7 @@ class LinuxManifest(ViewerManifest):
 
         self.path("featuretable_linux.txt")
 
-        with self.prefix(src=pkgdir,dst=""):
+        with self.prefix(src=pkgdir):
             self.path("ca-bundle.crt")
 
     def package_finish(self):
@@ -1468,7 +1494,7 @@ class Linux_i686_Manifest(LinuxManifest):
         relpkgdir = os.path.join(pkgdir, "lib", "release")
         debpkgdir = os.path.join(pkgdir, "lib", "debug")
 
-        with self.prefix(relpkgdir, dst="lib"):
+        with self.prefix(src=relpkgdir, dst="lib"):
             self.path("libapr-1.so")
             self.path("libapr-1.so.0")
             self.path("libapr-1.so.0.4.5")
@@ -1554,4 +1580,8 @@ class Linux_x86_64_Manifest(LinuxManifest):
 ################################################################
 
 if __name__ == "__main__":
-    main()
+    extra_arguments = [
+        dict(name='bugsplat', description="""BugSplat database to which to post crashes,
+             if BugSplat crash reporting is desired""", default=''),
+        ]
+    main(extra=extra_arguments)
-- 
cgit v1.2.3


From 01c6fe141e64b742bb33782238faa4a0a5ca6816 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 17 Oct 2018 11:35:01 -0400
Subject: DRTVWR-447: Update to viewer-manager build 520737

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index b1f4597a70..5b0817cbf8 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3138,9 +3138,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>eeeb18f7396de3147c6d958dfbc1a2e5</string>
+              <string>021b56ca0b1e34f40fa5fca713072c40</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/26016/204885/viewer_manager-2.0.520576-darwin64-520576.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/26246/206828/viewer_manager-2.0.520737-darwin64-520737.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3162,9 +3162,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>2832c40449a8a8230e9072ceac5120af</string>
+              <string>be91869780e39f58eaf1cd8c85b3b951</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/26017/204891/viewer_manager-2.0.520576-windows-520576.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/26247/206835/viewer_manager-2.0.520737-windows-520737.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3175,7 +3175,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.520576</string>
+        <string>2.0.520737</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From 3c4d63c6a1b0f5567c24d457b820022cf4de45cf Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 17 Oct 2018 13:04:32 -0400
Subject: DRTVWR-447: Update to viewer-manager build 520750

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 5b0817cbf8..6ce20e45ab 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3138,9 +3138,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>021b56ca0b1e34f40fa5fca713072c40</string>
+              <string>1d801a03cb87a248b6573f8550603286</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/26246/206828/viewer_manager-2.0.520737-darwin64-520737.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/26264/206909/viewer_manager-2.0.520750-darwin64-520750.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3162,9 +3162,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>be91869780e39f58eaf1cd8c85b3b951</string>
+              <string>65e20bc630033178f3f7e4890c0b85f7</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/26247/206835/viewer_manager-2.0.520737-windows-520737.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/26265/206915/viewer_manager-2.0.520750-windows-520750.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3175,7 +3175,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.520737</string>
+        <string>2.0.520750</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From 2c5d7199f69984ddba602ac50f8f55c6fd73fc9d Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 17 Oct 2018 13:53:37 -0400
Subject: DRTVWR-447: Restore channel-name sensitivity of Mac BugSplat viewer.

---
 indra/newview/viewer_manifest.py | 34 ++--------------------------------
 1 file changed, 2 insertions(+), 32 deletions(-)

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 5dd4d13a3a..0aea31d563 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -902,7 +902,7 @@ class DarwinManifest(ViewerManifest):
 
     def construct(self):
         # copy over the build result (this is a no-op if run within the xcode script)
-        self.path(os.path.join(self.args['configuration'], "Second Life.app"), dst="")
+        self.path(os.path.join(self.args['configuration'], self.channel()+".app"), dst="")
 
         pkgdir = os.path.join(self.args['build'], os.pardir, 'packages')
         relpkgdir = os.path.join(pkgdir, "lib", "release")
@@ -926,7 +926,7 @@ class DarwinManifest(ViewerManifest):
                 if ("package" in self.args['actions'] or 
                     "unpacked" in self.args['actions']):
                     self.run_command(
-                        ['strip', '-S', self.dst_path_of('Second Life')])
+                        ['strip', '-S', self.dst_path_of(self.channel())])
 
             with self.prefix(dst="Resources"):
                 # defer cross-platform file copies until we're in the
@@ -960,8 +960,6 @@ class DarwinManifest(ViewerManifest):
                 with self.prefix(src=pkgdir,dst=""):
                     self.path("ca-bundle.crt")
 
-                self.path("SecondLife.nib")
-
                 # Translations
                 self.path("English.lproj/language.txt")
                 self.replace_in(src="English.lproj/InfoPlist.strings",
@@ -1321,34 +1319,6 @@ class DarwinManifest(ViewerManifest):
                             else:
                                 print >> sys.stderr, "Maximum codesign attempts exceeded; giving up"
                                 raise
-                    print 72*'='
-                    import stat
-                    print app_in_dmg
-                    # Second Life.app
-                    for sub0 in os.listdir(app_in_dmg):
-                        print '--{}'.format(sub0)
-                        path0 = os.path.join(app_in_dmg, sub0)
-                        if os.path.isfile(path0):
-                            # shouldn't be any file here
-                            with open(path0) as inf:
-                                for line in inf:
-                                    print '  {}'.format(line.rstrip())
-                        elif os.path.isdir(path0):
-                            # Contents
-                            for sub1 in os.listdir(path0):
-                                print '----{}'.format(sub1)
-                                path1 = os.path.join(path0, sub1)
-                                if os.path.isfile(path1):
-                                    # Info.plist, PkgInfo
-                                    with open(path1) as inf:
-                                        for line in inf:
-                                            print '    {}'.format(line.rstrip())
-                                elif os.path.isdir(path1):
-                                    # Frameworks, MacOS, Resources
-                                    for sub2 in os.listdir(path1):
-                                        path2 = os.path.join(path1, sub2)
-                                        print '    {:04o} {}'.format(stat.S_IMODE(os.stat(path2).st_mode), sub2)
-                    print 72*'='
                     self.run_command(['spctl', '-a', '-texec', '-vvvv', app_in_dmg])
 
         finally:
-- 
cgit v1.2.3


From cd9d051b9024e4e0fc16a4aca28601d2a88a4045 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 17 Oct 2018 16:42:59 -0400
Subject: DRTVWR-447: Move test<5> and writeMsgNeedsEscaping() into sequence.

---
 indra/llcommon/tests/llerror_test.cpp | 66 +++++++++++++++++------------------
 1 file changed, 33 insertions(+), 33 deletions(-)

diff --git a/indra/llcommon/tests/llerror_test.cpp b/indra/llcommon/tests/llerror_test.cpp
index e7084fffc6..8e1f4c14ac 100644
--- a/indra/llcommon/tests/llerror_test.cpp
+++ b/indra/llcommon/tests/llerror_test.cpp
@@ -498,6 +498,39 @@ namespace
 	}
 }
 
+namespace
+{
+    void writeMsgNeedsEscaping()
+    {
+        LL_DEBUGS("WriteTag") << "backslash\\" << LL_ENDL;
+        LL_INFOS("WriteTag") << "newline\nafternewline" << LL_ENDL;
+        LL_WARNS("WriteTag") << "return\rafterreturn" << LL_ENDL;
+
+        LL_DEBUGS("WriteTag") << "backslash\\backslash\\" << LL_ENDL;
+        LL_INFOS("WriteTag") << "backslash\\newline\nanothernewline\nafternewline" << LL_ENDL;
+        LL_WARNS("WriteTag") << "backslash\\returnnewline\r\n\\afterbackslash" << LL_ENDL;
+    }
+};
+
+namespace tut
+{
+    template<> template<>
+    void ErrorTestObject::test<5>()
+        // backslash, return, and newline are not escaped with backslashes
+    {
+        LLError::setDefaultLevel(LLError::LEVEL_DEBUG);
+        setWantsMultiline(true); 
+        writeMsgNeedsEscaping(); // but should not be now
+        ensure_message_field_equals(0, MSG_FIELD, "backslash\\");
+        ensure_message_field_equals(1, MSG_FIELD, "newline\nafternewline");
+        ensure_message_field_equals(2, MSG_FIELD, "return\rafterreturn");
+        ensure_message_field_equals(3, MSG_FIELD, "backslash\\backslash\\");
+        ensure_message_field_equals(4, MSG_FIELD, "backslash\\newline\nanothernewline\nafternewline");
+        ensure_message_field_equals(5, MSG_FIELD, "backslash\\returnnewline\r\n\\afterbackslash");
+        ensure_message_count(6);
+    }
+}
+
 namespace tut
 {
 	template<> template<>
@@ -820,20 +853,6 @@ namespace tut
 	}
 }
 
-namespace
-{
-    void writeMsgNeedsEscaping()
-    {
-        LL_DEBUGS("WriteTag") << "backslash\\" << LL_ENDL;
-        LL_INFOS("WriteTag") << "newline\nafternewline" << LL_ENDL;
-        LL_WARNS("WriteTag") << "return\rafterreturn" << LL_ENDL;
-
-        LL_DEBUGS("WriteTag") << "backslash\\backslash\\" << LL_ENDL;
-        LL_INFOS("WriteTag") << "backslash\\newline\nanothernewline\nafternewline" << LL_ENDL;
-        LL_WARNS("WriteTag") << "backslash\\returnnewline\r\n\\afterbackslash" << LL_ENDL;
-    }
-};
-
 namespace tut
 {
     template<> template<>
@@ -881,25 +900,6 @@ namespace tut
     }
 }
 
-namespace tut
-{
-    template<> template<>
-    void ErrorTestObject::test<5>()
-        // backslash, return, and newline are not escaped with backslashes
-    {
-        LLError::setDefaultLevel(LLError::LEVEL_DEBUG);
-        setWantsMultiline(true); 
-        writeMsgNeedsEscaping(); // but should not be now
-        ensure_message_field_equals(0, MSG_FIELD, "backslash\\");
-        ensure_message_field_equals(1, MSG_FIELD, "newline\nafternewline");
-        ensure_message_field_equals(2, MSG_FIELD, "return\rafterreturn");
-        ensure_message_field_equals(3, MSG_FIELD, "backslash\\backslash\\");
-        ensure_message_field_equals(4, MSG_FIELD, "backslash\\newline\nanothernewline\nafternewline");
-        ensure_message_field_equals(5, MSG_FIELD, "backslash\\returnnewline\r\n\\afterbackslash");
-        ensure_message_count(6);
-    }
-}
-
 /* Tests left:
 	handling of classes without LOG_CLASS
 
-- 
cgit v1.2.3


From a3ca2c9ac830f58dbd6fa49090a936134f5cbf19 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 17 Oct 2018 16:47:05 -0400
Subject: DRTVWR-447: Restore diagnostic output to Mac app bundle packaging.

---
 indra/newview/viewer_manifest.py | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 0aea31d563..40fa6cacf3 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -1319,6 +1319,34 @@ class DarwinManifest(ViewerManifest):
                             else:
                                 print >> sys.stderr, "Maximum codesign attempts exceeded; giving up"
                                 raise
+                    print 72*'='
+                    import stat
+                    print app_in_dmg
+                    # Second Life.app
+                    for sub0 in os.listdir(app_in_dmg):
+                        print '--{}'.format(sub0)
+                        path0 = os.path.join(app_in_dmg, sub0)
+                        if os.path.isfile(path0):
+                            # shouldn't be any file here
+                            with open(path0) as inf:
+                                for line in inf:
+                                    print '  {}'.format(line.rstrip())
+                        elif os.path.isdir(path0):
+                            # Contents
+                            for sub1 in os.listdir(path0):
+                                print '----{}'.format(sub1)
+                                path1 = os.path.join(path0, sub1)
+                                if os.path.isfile(path1):
+                                    # Info.plist, PkgInfo
+                                    with open(path1) as inf:
+                                        for line in inf:
+                                            print '    {}'.format(line.rstrip())
+                                elif os.path.isdir(path1):
+                                    # Frameworks, MacOS, Resources
+                                    for sub2 in os.listdir(path1):
+                                        path2 = os.path.join(path1, sub2)
+                                        print '    {:04o} {}'.format(stat.S_IMODE(os.stat(path2).st_mode), sub2)
+                    print 72*'='
                     self.run_command(['spctl', '-a', '-texec', '-vvvv', app_in_dmg])
 
         finally:
-- 
cgit v1.2.3


From d86b311b2cdc2f58ef53aa2f7a8d180fe4a61353 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 17 Oct 2018 22:34:58 -0400
Subject: DRTVWR-447: Restore MACOSX_EXECUTABLE_NAME, used for Info.plist.

---
 indra/newview/CMakeLists.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 5c918fc3b2..1b19497354 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -2092,6 +2092,7 @@ if (DARWIN)
   # magically known to CMake -- it's that these names are referenced in the
   # Info-SecondLife.plist file in the configure_file() directive below.
   set(product "${VIEWER_CHANNEL}")
+  set(MACOSX_EXECUTABLE_NAME "${VIEWER_CHANNEL}")
   set(MACOSX_BUNDLE_INFO_STRING "${VIEWER_CHANNEL}")
   set(MACOSX_BUNDLE_ICON_FILE "secondlife.icns")
   set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.secondlife.indra.viewer")
-- 
cgit v1.2.3


From fa5350db7be671b9b935383e5925dcc64d440952 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 18 Oct 2018 11:44:56 -0400
Subject: DRTVWR-447: Update to bugsplat build 520784

---
 autobuild.xml | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 6ce20e45ab..08d4694942 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -244,9 +244,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>436b124bce8cf57b18dbf10f5e6ebcd4</string>
+              <string>492f182607d6096ebc5620779fa6121d</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/26151/206132/bugsplat-1.0.7.520674-darwin64-520674.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/26319/207508/bugsplat-1.0.7.520784-darwin64-520784.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -256,9 +256,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>5d19acddc51ee7c802297dd176194362</string>
+              <string>dfbc7f3c1fd88adc8015e9c2c21b2435</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/26153/206145/bugsplat-3.6.0.4.520674-windows-520674.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/26321/207522/bugsplat-3.6.0.4.520784-windows-520784.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -268,16 +268,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>78f5688b694e04c052fb0a1165c98bb5</string>
+              <string>131db9b0775375386023f454cce9b803</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/26152/206142/bugsplat-3.6.0.4.520674-windows64-520674.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/26320/207516/bugsplat-3.6.0.4.520784-windows64-520784.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.0.7.520674</string>
+        <string>1.0.7.520784</string>
       </map>
       <key>colladadom</key>
       <map>
-- 
cgit v1.2.3


From b4bc7f7c0c1c8804ad9688e1759cc86629193a37 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 18 Oct 2018 13:55:55 -0400
Subject: DRTVWR-447: Update bugsplat to codeticket version 520791.

---
 autobuild.xml | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 08d4694942..76c33d0005 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -244,9 +244,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>492f182607d6096ebc5620779fa6121d</string>
+              <string>c3b5e8c57bd1c92bc9e0956586908b99</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/26319/207508/bugsplat-1.0.7.520784-darwin64-520784.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/26330/207568/bugsplat-1.0.7.520791-darwin64-520791.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -256,9 +256,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>dfbc7f3c1fd88adc8015e9c2c21b2435</string>
+              <string>766dfde65a5b42ea5691d41df79c43e0</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/26321/207522/bugsplat-3.6.0.4.520784-windows-520784.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/26332/207582/bugsplat-3.6.0.4.520791-windows-520791.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -268,16 +268,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>131db9b0775375386023f454cce9b803</string>
+              <string>afd01285e22f27d473fac6f88fac9a3b</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/26320/207516/bugsplat-3.6.0.4.520784-windows64-520784.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/26331/207576/bugsplat-3.6.0.4.520791-windows64-520791.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.0.7.520784</string>
+        <string>1.0.7.520791</string>
       </map>
       <key>colladadom</key>
       <map>
-- 
cgit v1.2.3


From c532e3075c7857f3f3f0097890d93bd90ff82db0 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 18 Oct 2018 15:31:44 -0400
Subject: DRTVWR-447: Re-inject BugsplatServerURL into Mac's Info.plist.

---
 indra/newview/viewer_manifest.py | 41 +++++++++++++---------------------------
 1 file changed, 13 insertions(+), 28 deletions(-)

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 40fa6cacf3..fb132732a5 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -909,6 +909,19 @@ class DarwinManifest(ViewerManifest):
         debpkgdir = os.path.join(pkgdir, "lib", "debug")
 
         with self.prefix(src="", dst="Contents"):  # everything goes in Contents
+            bugsplat_db = self.args.get('bugsplat')
+            if bugsplat_db:
+                # Inject BugsplatServerURL into Info.plist if provided.
+                Info_plist = self.dst_path_of("Info.plist")
+                Info = plistlib.readPlist(Info_plist)
+                # https://www.bugsplat.com/docs/platforms/os-x#configuration
+                Info["BugsplatServerURL"] = \
+                    "https://{}.bugsplat.com/".format(bugsplat_db)
+                self.put_in_file(
+                    plistlib.writePlistToString(Info),
+                    os.path.basename(Info_plist),
+                    "Info.plist")
+
             # CEF framework goes inside Contents/Frameworks.
             # Remember where we parked this car.
             with self.prefix(src="", dst="Frameworks"):
@@ -1319,34 +1332,6 @@ class DarwinManifest(ViewerManifest):
                             else:
                                 print >> sys.stderr, "Maximum codesign attempts exceeded; giving up"
                                 raise
-                    print 72*'='
-                    import stat
-                    print app_in_dmg
-                    # Second Life.app
-                    for sub0 in os.listdir(app_in_dmg):
-                        print '--{}'.format(sub0)
-                        path0 = os.path.join(app_in_dmg, sub0)
-                        if os.path.isfile(path0):
-                            # shouldn't be any file here
-                            with open(path0) as inf:
-                                for line in inf:
-                                    print '  {}'.format(line.rstrip())
-                        elif os.path.isdir(path0):
-                            # Contents
-                            for sub1 in os.listdir(path0):
-                                print '----{}'.format(sub1)
-                                path1 = os.path.join(path0, sub1)
-                                if os.path.isfile(path1):
-                                    # Info.plist, PkgInfo
-                                    with open(path1) as inf:
-                                        for line in inf:
-                                            print '    {}'.format(line.rstrip())
-                                elif os.path.isdir(path1):
-                                    # Frameworks, MacOS, Resources
-                                    for sub2 in os.listdir(path1):
-                                        path2 = os.path.join(path1, sub2)
-                                        print '    {:04o} {}'.format(stat.S_IMODE(os.stat(path2).st_mode), sub2)
-                    print 72*'='
                     self.run_command(['spctl', '-a', '-texec', '-vvvv', app_in_dmg])
 
         finally:
-- 
cgit v1.2.3


From f55d3071e16f06c7afc0940928fa2e9a620556d9 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 22 Oct 2018 14:21:35 -0400
Subject: DRTVWR-447: Restore copying BugsplatMac.framework into Mac package.

---
 indra/newview/viewer_manifest.py | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index fb132732a5..ed9b5a35fd 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -929,6 +929,9 @@ class DarwinManifest(ViewerManifest):
                 self.path2basename(relpkgdir, CEF_framework)
                 CEF_framework = self.dst_path_of(CEF_framework)
 
+                if self.args.get('bugsplat'):
+                    self.path2basename(relpkgdir, "BugsplatMac.framework")
+
             with self.prefix(dst="MacOS"):
                 # NOTE: the -S argument to strip causes it to keep
                 # enough info for annotated backtraces (i.e. function
-- 
cgit v1.2.3


From 279073dbb3eb03fbe1f897bd142a53d7c4c5bc7d Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 22 Oct 2018 19:59:07 -0400
Subject: DRTVWR-447: Introduce LLManifest.process_either().

process_directory() and process_file() are reached both from the top-level
caller (try_path(), a local function within LLManifest.path()) and recursively
from process_directory(). Both places tested os.path.isdir(source), and if so
called process_directory(), else process_file(). Both places were wrong, as it
turns out.

os.path.isdir(symlink_to_directory) returns True. That meant that despite
explicit logic in ccopymumble() to recreate symlinks in the destination area,
we were consistently recopying the contents of symlinked directories.

The downside to this -- in addition to inflating the size of the installer! --
is that macOS is very particular about the structure of a Framework bundle. It
*must* include a Versions/Current symlink identifying which of the other
Versions subdirectories is, in fact, current. If Current is itself a
subdirectory, codesign can't figure out how to sign the framework, and fails.

The logic for deciding between process_directory() and process_file() must
explicitly check for os.path.islink(source). Rather than replicating that
change in both places, introduce process_either() which decides how to forward
the call, and call it both from try_path() and from process_directory().
---
 indra/lib/python/indra/util/llmanifest.py | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/indra/lib/python/indra/util/llmanifest.py b/indra/lib/python/indra/util/llmanifest.py
index 9569014a47..2e6cf53912 100755
--- a/indra/lib/python/indra/util/llmanifest.py
+++ b/indra/lib/python/indra/util/llmanifest.py
@@ -615,6 +615,14 @@ class LLManifest(object):
             # *TODO is this gonna be useful?
             print "Cleaning up " + c
 
+    def process_either(self, src, dst):
+        # If it's a real directory, recurse through it --
+        # but not a symlink! Handle those like files.
+        if os.path.isdir(src) and not os.path.islink(src):
+            return self.process_directory(src, dst)
+        else:
+            return self.process_file(src, dst)
+
     def process_file(self, src, dst):
         if self.includes(src, dst):
             for action in self.actions:
@@ -641,10 +649,7 @@ class LLManifest(object):
         for name in names:
             srcname = os.path.join(src, name)
             dstname = os.path.join(dst, name)
-            if os.path.isdir(srcname):
-                count += self.process_directory(srcname, dstname)
-            else:
-                count += self.process_file(srcname, dstname)
+            count += self.process_either(srcname, dstname)
         return count
 
     def includes(self, src, dst):
@@ -816,11 +821,7 @@ class LLManifest(object):
                 # if we're specifying a single path (not a glob),
                 # we should error out if it doesn't exist
                 self.check_file_exists(src)
-                # if it's a directory, recurse through it
-                if os.path.isdir(src):
-                    count += self.process_directory(src, dst)
-                else:
-                    count += self.process_file(src, dst)
+                count += self.process_either(src, dst)
             return count
 
         try_prefixes = [self.get_src_prefix(), self.get_artwork_prefix(), self.get_build_prefix()]
-- 
cgit v1.2.3


From 32e30386d8cef58533610d31eaba3d3ac976ab76 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 23 Oct 2018 10:52:06 -0400
Subject: DRTVWR-447: Try to defeat scary Mac Gatekeeper popups by replacing
 the viewer's baked-in BugsplatMac.framework @rpath path with one based on
 @executable_path.

---
 indra/newview/viewer_manifest.py | 30 +++++++++++++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index ed9b5a35fd..508c5cb043 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -933,6 +933,34 @@ class DarwinManifest(ViewerManifest):
                     self.path2basename(relpkgdir, "BugsplatMac.framework")
 
             with self.prefix(dst="MacOS"):
+                executable = self.dst_path_of(self.channel())
+                if self.args.get('bugsplat'):
+                    # According to Apple Technical Note TN2206:
+                    # https://developer.apple.com/library/archive/technotes/tn2206/_index.html#//apple_ref/doc/uid/DTS40007919-CH1-TNTAG207
+                    # "If an app uses @rpath or an absolute path to link to a
+                    # dynamic library outside of the app, the app will be
+                    # rejected by Gatekeeper. ... Neither the codesign nor the
+                    # spctl tool will show the error."
+                    # (Thanks, Apple. Maybe fix spctl to warn?)
+                    # The BugsplatMac framework embeds @rpath, which is
+                    # causing scary Gatekeeper popups at viewer start. Work
+                    # around this by changing the reference baked into our
+                    # viewer. The install_name_tool -change option needs the
+                    # previous value. Instead of guessing -- which might
+                    # silently be defeated by a BugSplat SDK update that
+                    # changes their baked-in @rpath -- ask for the path
+                    # stamped into the framework.
+                    # Let exception, if any, propagate -- if this doesn't
+                    # work, we need the build to noisily fail!
+                    oldpath = subprocess.check_output(
+                        ['objdump', '-macho', '-dylib-id', '-non-verbose',
+                         os.path.join(relpkgdir, "BugsplatMac.framework", "BugsplatMac")]
+                        ).splitlines()[-1]  # take the last line of output
+                    self.run_command(
+                        ['install_name_tool', '-change', oldpath,
+                         '@executable_path/../Frameworks/BugsplatMac.framework/BugsplatMac',
+                         executable])
+
                 # NOTE: the -S argument to strip causes it to keep
                 # enough info for annotated backtraces (i.e. function
                 # names in the crash log). 'strip' with no arguments
@@ -942,7 +970,7 @@ class DarwinManifest(ViewerManifest):
                 if ("package" in self.args['actions'] or 
                     "unpacked" in self.args['actions']):
                     self.run_command(
-                        ['strip', '-S', self.dst_path_of(self.channel())])
+                        ['strip', '-S', executable])
 
             with self.prefix(dst="Resources"):
                 # defer cross-platform file copies until we're in the
-- 
cgit v1.2.3


From 9b5b44314acdef260ab515855a72c707e8f3f5fc Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 26 Oct 2018 14:55:13 -0400
Subject: DRTVWR-447: For some reason the Windows viewer exe wasn't signed.

viewer_manifest.py was signing updater.exe within the package, and then
signing the installer executable itself, but not the actual viewer executable.
Add that.
---
 indra/newview/viewer_manifest.py | 1 +
 1 file changed, 1 insertion(+)

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 508c5cb043..f2b0fe6a32 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -827,6 +827,7 @@ class WindowsManifest(ViewerManifest):
         # note that the enclosing setup exe is signed later, after the makensis makes it.
         # Unlike the viewer binary, the VMP filenames are invariant with respect to version, os, etc.
         for exe in (
+            self.final_exe(),
             "updater.exe",
             ):
             self.sign(exe)
-- 
cgit v1.2.3


From 6240677945381bf2a03d9342be9ca8beeb487edf Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Sat, 27 Oct 2018 11:37:57 -0400
Subject: DRTVWR-447: Update to viewer-manager build 521169

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 76c33d0005..22e095973e 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3138,9 +3138,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>1d801a03cb87a248b6573f8550603286</string>
+              <string>1b20fe924598080e9c469931f88f0a68</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/26264/206909/viewer_manager-2.0.520750-darwin64-520750.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/26804/214046/viewer_manager-2.0.521169-darwin64-521169.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3162,9 +3162,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>65e20bc630033178f3f7e4890c0b85f7</string>
+              <string>87484123c7282c32f51935891e639f83</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/26265/206915/viewer_manager-2.0.520750-windows-520750.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/26805/214053/viewer_manager-2.0.521169-windows-521169.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3175,7 +3175,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.520750</string>
+        <string>2.0.521169</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From 7aec2a7bf15c55c61ce6d4eb0bfb5f2d9d513a08 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Sat, 27 Oct 2018 12:04:57 -0400
Subject: DRTVWR-447: Update to viewer-manager build 521170

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 22e095973e..4317de3408 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3138,9 +3138,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>1b20fe924598080e9c469931f88f0a68</string>
+              <string>51f77e40a4d3a259033b3017de8f3569</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/26804/214046/viewer_manager-2.0.521169-darwin64-521169.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/26806/214061/viewer_manager-2.0.521170-darwin64-521170.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3162,9 +3162,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>87484123c7282c32f51935891e639f83</string>
+              <string>86a396beb2355f9bd51c912dfd679d48</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/26805/214053/viewer_manager-2.0.521169-windows-521169.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/26807/214067/viewer_manager-2.0.521170-windows-521170.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3175,7 +3175,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.521169</string>
+        <string>2.0.521170</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From 0ca69bb2ebf206705045a72b004e302af1f6d5dd Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Sat, 27 Oct 2018 15:24:24 -0400
Subject: DRTVWR-447: Stop passing UpdaterServiceURL to leap updater.

In fact, mark UpdaterServiceURL as obsolete. (Consumers should consult
build_data.json.)
---
 indra/newview/app_settings/settings.xml | 2 +-
 indra/newview/llappviewer.cpp           | 2 --
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 8722050569..1242d63e8a 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -13510,7 +13510,7 @@
     <key>UpdaterServiceURL</key>
     <map>
       <key>Comment</key>
-      <string>Default location for the updater service.</string>
+      <string>Obsolete; no longer used.</string>
       <key>Persist</key>
       <integer>0</integer>
       <key>Type</key>
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index e527b70b0e..bda76c14d1 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1156,8 +1156,6 @@ bool LLAppViewer::init()
 	updater.args.add(LLVersionInfo::getChannel());
 	// testok
 	updater.args.add(stringize(gSavedSettings.getBOOL("UpdaterWillingToTest")));
-	// UpdaterServiceURL
-	updater.args.add(gSavedSettings.getString("UpdaterServiceURL"));
 	// ForceAddressSize
 	updater.args.add(stringize(gSavedSettings.getU32("ForceAddressSize")));
 
-- 
cgit v1.2.3


From 810cebe967b75c6ba6428e0bdf8fc2fabf8379e5 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 29 Oct 2018 15:36:43 -0400
Subject: SL-9964: Put Mac cursors back into Resources/cursors_mac
 subdirectory.

---
 indra/newview/viewer_manifest.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index f2b0fe6a32..3556b82320 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -995,7 +995,7 @@ class DarwinManifest(ViewerManifest):
                     self.path("libndofdev.dylib")
                     self.path("libhunspell-1.3.0.dylib")   
 
-                with self.prefix("cursors_mac"):
+                with self.prefix(src_dst="cursors_mac"):
                     self.path("*.tif")
 
                 self.path("licenses-mac.txt", dst="licenses.txt")
-- 
cgit v1.2.3


From a5f492acf19664593b040a8cdff1e5e251f65dba Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 29 Oct 2018 17:17:26 -0400
Subject: SL-9980: Launch the first-run updater via explorer.exe as we used to
 run the viewer from the installer.

Turns out that the peculiar indirection through explorer.exe was a known trick
for an elevated-privileges program to launch a program as the logged-in
Windows user. (They could have commented that...)

But explorer.exe doesn't pass command-line parameters, so if you want to pass
any such to the actual target program, you have to launch a shortcut with
those parameters.

But this target program (the updater) and its parameters (precheck mumble) are
specific to the very first viewer run after installation, so delete it after.
Having an additional permanent icon that always runs the updater before the
viewer would only confuse matters.
---
 indra/newview/installers/windows/installer_template.nsi | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index 76187b49a5..adcf8fd0e4 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -705,10 +705,21 @@ Function .onInstSuccess
         # updater can detect the problem and adapt accordingly.
         # Once everything is in order, the updater will run the specified
         # viewer with the specified params.
+        # 'Exec updater' causes the viewer to inherit elevated Admin privileges. See
+        # http://mdb-blog.blogspot.com/2013/01/nsis-lunch-program-as-user-from-uac.html
+        # for workaround: running the updater via explorer.exe.
+        # Thing is, you can't pass parameters with the explorer.exe trick, so
+        # you have to create a shortcut or a .bat file. Since we don't want a
+        # permanent shortcut for the user to relaunch the updater like this
+        # first time, create it in a temp location and delete it once we've
+        # used it.
         # Quote the updater executable and the viewer executable because each
         # must be a distinct command-line token, but DO NOT quote the language
         # string because it must decompose into separate command-line tokens.
-        Exec '"$INSTDIR\$INSTEXE" precheck "$INSTDIR\$VIEWER_EXE" $SHORTCUT_LANG_PARAM'
+        CreateShortCut "$TEMP\SLFirst.lnk" "$INSTDIR\$INSTEXE" \
+                       'precheck "$INSTDIR\$VIEWER_EXE" $SHORTCUT_LANG_PARAM'
+        Exec '"$WINDIR\explorer.exe" "$TEMP\SLFirst.lnk"'
+        Delete "$TEMP\SLFirst.lnk"
         Pop $R0
 # 
 FunctionEnd
-- 
cgit v1.2.3


From e2ca890898ecb79ff314b1f748bb6a3a9dbf602b Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 30 Oct 2018 10:36:28 -0400
Subject: DRTVWR-447: Copy VIEWER_EXE to local variable (thanks Ansariel)

---
 indra/newview/installers/windows/installer_template.nsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index adcf8fd0e4..f8e9bc4781 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -382,6 +382,7 @@ Section Uninstall
 # Start with some default values.
 StrCpy $INSTPROG "${INSTNAME}"
 StrCpy $INSTEXE "${INSTEXE}"
+StrCpy $VIEWER_EXE "${VIEWER_EXE}"
 StrCpy $INSTSHORTCUT "${SHORTCUT}"
 
 # Make sure the user can install/uninstall
-- 
cgit v1.2.3


From a186f9a729e9ae9c834121708177b177f2c26283 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 1 Nov 2018 22:08:44 -0400
Subject: DRTVWR-447: Allow Standard Windows user to install for current user.

This should eliminate any confusion due to a Standard user needing to elevate
to Admin privileges, since from that point on Windows tells the running
program the current user is that Admin. Bypass all that.
---
 .../installers/windows/installer_template.nsi      | 165 ++++++++++-----------
 indra/newview/installers/windows/lang_da.nsi       | Bin 7816 -> 7816 bytes
 indra/newview/installers/windows/lang_de.nsi       | Bin 9850 -> 9854 bytes
 indra/newview/installers/windows/lang_en-us.nsi    | Bin 8734 -> 11342 bytes
 indra/newview/installers/windows/lang_es.nsi       | Bin 9872 -> 9876 bytes
 indra/newview/installers/windows/lang_fr.nsi       | Bin 10258 -> 10262 bytes
 indra/newview/installers/windows/lang_it.nsi       | Bin 9520 -> 9524 bytes
 indra/newview/installers/windows/lang_ja.nsi       | Bin 7204 -> 7208 bytes
 indra/newview/installers/windows/lang_pl.nsi       | Bin 8136 -> 8136 bytes
 indra/newview/installers/windows/lang_pt-br.nsi    | Bin 9864 -> 9864 bytes
 indra/newview/installers/windows/lang_ru.nsi       | Bin 9188 -> 9188 bytes
 indra/newview/installers/windows/lang_tr.nsi       | Bin 9286 -> 9290 bytes
 indra/newview/installers/windows/lang_zh.nsi       | Bin 6846 -> 6850 bytes
 indra/newview/viewer_manifest.py                   |   4 +-
 14 files changed, 81 insertions(+), 88 deletions(-)

diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index f8e9bc4781..500b35255e 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -32,7 +32,7 @@ SetCompress auto			# Compress if saves space
 SetCompressor /solid lzma	# Compress whole installer as one block
 SetDatablockOptimize off	# Only saves us 0.1%, not worth it
 XPStyle on                  # Add an XP manifest to the installer
-RequestExecutionLevel admin	# For when we write to Program Files
+RequestExecutionLevel highest           # match MULTIUSER_EXECUTIONLEVEL
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Project flags
@@ -90,20 +90,43 @@ InstProgressFlags smooth colored		# New colored smooth look
 SetOverwrite on							# Overwrite files by default
 AutoCloseWindow true					# After all files install, close window
 
-# initial location of install (default when not already installed)
-#   note: Now we defer looking for existing install until onInit when we
-#   are able to engage the 32/64 registry function
-InstallDir "%%PROGRAMFILES%%\${INSTNAME}"
+# Registry key paths, ours and Microsoft's
+!define LINDEN_KEY      "SOFTWARE\Linden Research, Inc."
+!define INSTNAME_KEY    "${LINDEN_KEY}\${INSTNAME}"
+!define MSCURRVER_KEY   "SOFTWARE\Microsoft\Windows\CurrentVersion"
+!define MSNTCURRVER_KEY "SOFTWARE\Microsoft\Windows NT\CurrentVersion"
+!define MSUNINSTALL_KEY "${MSCURRVER_KEY}\Uninstall\${INSTNAME}"
+
+# from http://nsis.sourceforge.net/Docs/MultiUser/Readme.html
+# Highest level permitted for user: Admin for Admin, Standard for Standard
+!define MULTIUSER_EXECUTIONLEVEL Highest
+!define MULTIUSER_MUI
+# Look for /AllUsers or /CurrentUser switches
+!define MULTIUSER_INSTALLMODE_COMMANDLINE
+# appended to $PROGRAMFILES, as affected by MULTIUSER_USE_PROGRAMFILES64
+!define MULTIUSER_INSTALLMODE_INSTDIR "${INSTNAME}"
+# expands to !define MULTIUSER_USE_PROGRAMFILES64 or nothing
+%%PROGRAMFILES%%
+# should make MultiUser.nsh initialization read existing INSTDIR from registry
+!define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY "${INSTNAME_KEY}"
+!define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME ""
+# should make MultiUser.nsh initialization write $MultiUser.InstallMode to registry
+!define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY "${INSTNAME_KEY}"
+!define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME "InstallMode"
+!include MultiUser.nsh
+!include MUI2.nsh
 
 UninstallText $(UninstallTextMsg)
 DirText $(DirectoryChooseTitle) $(DirectoryChooseSetup)
-Page directory dirPre
-Page instfiles
+!insertmacro MULTIUSER_PAGE_INSTALLMODE
+!define MUI_PAGE_CUSTOMFUNCTION_PRE dirPre
+!insertmacro MUI_PAGE_DIRECTORY
+!insertmacro MUI_PAGE_INSTFILES
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Variables
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-Var INSTPROG
+Var INSTNAME
 Var INSTEXE
 Var VIEWER_EXE
 Var INSTSHORTCUT
@@ -142,20 +165,13 @@ FunctionEnd
 ;; entry to the language ID selector below
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 Function .onInit
+!insertmacro MULTIUSER_INIT
 
 %%ENGAGEREGISTRY%%
 
-# read the current location of the install for this version
-# if $0 is empty, this is the first time for this viewer name
-ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\\Linden Research, Inc.\\${INSTNAME}" ""
-
-# viewer with this name not installed before
-${If} $0 == ""
-    # nothing to do here
-${Else}
-	# use the value we got from registry as install location
-    StrCpy $INSTDIR $0
-${EndIf}
+# Setting MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY and
+# MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME should
+# read the current location of the install for this version into INSTDIR.
 
 Call CheckCPUFlags							# Make sure we have SSE2 support
 Call CheckWindowsVersion					# Don't install On unsupported systems
@@ -181,7 +197,7 @@ Call CheckWindowsVersion					# Don't install On unsupported systems
 lbl_configure_default_lang:
 # If we currently have a version of SL installed, default to the language of that install
 # Otherwise don't change $LANGUAGE and it will default to the OS UI language.
-    ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\${INSTNAME}" "InstallerLanguage"
+    ReadRegStr $0 SHELL_CONTEXT "${INSTNAME_KEY}" "InstallerLanguage"
     IfErrors +2 0	# If error skip the copy instruction 
 	StrCpy $LANGUAGE $0
 
@@ -204,7 +220,7 @@ lbl_build_menu:
     StrCpy $LANGUAGE $0
 
 # Save language in registry		
-	WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\${INSTNAME}" "InstallerLanguage" $LANGUAGE
+	WriteRegStr SHELL_CONTEXT "${INSTNAME_KEY}" "InstallerLanguage" $LANGUAGE
 lbl_return:
     Pop $0
     Return
@@ -215,16 +231,20 @@ FunctionEnd
 ;; Prep Uninstaller Section
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 Function un.onInit
+!insertmacro MULTIUSER_UNINIT
 
 %%ENGAGEREGISTRY%%
 
 # Read language from registry and set for uninstaller. Key will be removed on successful uninstall
-	ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\${INSTNAME}" "InstallerLanguage"
+	ReadRegStr $0 SHELL_CONTEXT "${INSTNAME_KEY}" "InstallerLanguage"
     IfErrors lbl_end
 	StrCpy $LANGUAGE $0
 lbl_end:
     Return
 
+    # Does MultiUser.nsh init read back
+    # MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY into $MultiUser.InstallMode?
+
 FunctionEnd
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -272,15 +292,14 @@ FunctionEnd
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 Section ""
 
-SetShellVarContext all			# Install for all users (if you change this, change it in the uninstall as well)
+# SetShellVarContext is set by MultiUser.nsh initialization.
 
 # Start with some default values.
-StrCpy $INSTPROG "${INSTNAME}"
+StrCpy $INSTNAME "${INSTNAME}"
 StrCpy $INSTEXE "${INSTEXE}"
 StrCpy $VIEWER_EXE "${VIEWER_EXE}"
 StrCpy $INSTSHORTCUT "${SHORTCUT}"
 
-Call CheckIfAdministrator		# Make sure the user can install/uninstall
 Call CloseSecondLife			# Make sure Second Life not currently running
 Call CheckWillUninstallV2		# Check if Second Life is already installed
 
@@ -324,24 +343,24 @@ CreateShortCut "$INSTDIR\Uninstall $INSTSHORTCUT.lnk" \
 				'"$INSTDIR\uninst.exe"' ''
 
 # Write registry
-WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "" "$INSTDIR"
-WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Version" "${VERSION_LONG}"
-WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Shortcut" "$INSTSHORTCUT"
-WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Exe" "$VIEWER_EXE"
-WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "Publisher" "Linden Research, Inc."
-WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "URLInfoAbout" "http://secondlife.com/whatis/"
-WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "URLUpdateInfo" "http://secondlife.com/support/downloads/"
-WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "HelpLink" "https://support.secondlife.com/contact-support/"
-WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "DisplayName" "$INSTPROG"
-WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "UninstallString" '"$INSTDIR\uninst.exe"'
-WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "DisplayVersion" "${VERSION_LONG}"
-WriteRegDWORD HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "EstimatedSize" "0x0001D500"		# ~117 MB
+WriteRegStr SHELL_CONTEXT "${INSTNAME_KEY}" "" "$INSTDIR"
+WriteRegStr SHELL_CONTEXT "${INSTNAME_KEY}" "Version" "${VERSION_LONG}"
+WriteRegStr SHELL_CONTEXT "${INSTNAME_KEY}" "Shortcut" "$INSTSHORTCUT"
+WriteRegStr SHELL_CONTEXT "${INSTNAME_KEY}" "Exe" "$VIEWER_EXE"
+WriteRegStr SHELL_CONTEXT "${MSUNINSTALL_KEY}" "Publisher" "Linden Research, Inc."
+WriteRegStr SHELL_CONTEXT "${MSUNINSTALL_KEY}" "URLInfoAbout" "http://secondlife.com/whatis/"
+WriteRegStr SHELL_CONTEXT "${MSUNINSTALL_KEY}" "URLUpdateInfo" "http://secondlife.com/support/downloads/"
+WriteRegStr SHELL_CONTEXT "${MSUNINSTALL_KEY}" "HelpLink" "https://support.secondlife.com/contact-support/"
+WriteRegStr SHELL_CONTEXT "${MSUNINSTALL_KEY}" "DisplayName" "$INSTNAME"
+WriteRegStr SHELL_CONTEXT "${MSUNINSTALL_KEY}" "UninstallString" '"$INSTDIR\uninst.exe"'
+WriteRegStr SHELL_CONTEXT "${MSUNINSTALL_KEY}" "DisplayVersion" "${VERSION_LONG}"
+WriteRegDWORD SHELL_CONTEXT "${MSUNINSTALL_KEY}" "EstimatedSize" "0x0001D500"		# ~117 MB
 
 # from FS:Ansariel
-WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "DisplayIcon" '"$INSTDIR\$VIEWER_EXE"'
+WriteRegStr SHELL_CONTEXT "${MSUNINSTALL_KEY}" "DisplayIcon" '"$INSTDIR\$VIEWER_EXE"'
 
 # BUG-2707 Disable SEHOP for installed viewer.
-WriteRegDWORD HKEY_LOCAL_MACHINE "Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\$VIEWER_EXE" "DisableExceptionChainValidation" 1
+WriteRegDWORD SHELL_CONTEXT "${MSNTCURRVER_KEY}\Image File Execution Options\$VIEWER_EXE" "DisableExceptionChainValidation" 1
 
 # Write URL registry info
 WriteRegStr HKEY_CLASSES_ROOT "${URLNAME}" "(default)" "URL:Second Life"
@@ -380,25 +399,29 @@ SectionEnd
 Section Uninstall
 
 # Start with some default values.
-StrCpy $INSTPROG "${INSTNAME}"
+StrCpy $INSTNAME "${INSTNAME}"
 StrCpy $INSTEXE "${INSTEXE}"
 StrCpy $VIEWER_EXE "${VIEWER_EXE}"
 StrCpy $INSTSHORTCUT "${SHORTCUT}"
 
-# Make sure the user can install/uninstall
-Call un.CheckIfAdministrator
-
-# Uninstall for all users (if you change this, change it in the install as well)
-SetShellVarContext all			
+# SetShellVarContext per the mode saved at install time in registry at
+# MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY
+# MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME
+# Couln't get NSIS to expand $MultiUser.InstallMode into the function name at Call time
+${If} $MultiUser.InstallMode == 'AllUsers'
+  Call un.MultiUser.InstallMode.AllUsers
+${Else}
+  Call un.MultiUser.InstallMode.CurrentUser
+${EndIf}
 
 # Make sure we're not running
 Call un.CloseSecondLife
 
 # Clean up registry keys and subkeys (these should all be !defines somewhere)
-DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG"
-DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG"
+DeleteRegKey SHELL_CONTEXT "${INSTNAME_KEY}"
+DeleteRegKey SHELL_CONTEXT "${MSCURRVER_KEY}\Uninstall\$INSTNAME"
 # BUG-2707 Remove entry that disabled SEHOP
-DeleteRegKey HKEY_LOCAL_MACHINE "Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\$VIEWER_EXE"
+DeleteRegKey SHELL_CONTEXT "${MSNTCURRVER_KEY}\Image File Execution Options\$VIEWER_EXE"
 ##DeleteRegKey HKEY_CLASSES_ROOT "Applications\$INSTEXE"
 DeleteRegKey HKEY_CLASSES_ROOT "Applications\${VIEWER_EXE}"
 
@@ -418,36 +441,6 @@ Call un.UserSettingsFiles
 
 SectionEnd
 
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Make sure the user can install
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-Function CheckIfAdministrator
-    DetailPrint $(CheckAdministratorInstDP)
-    UserInfo::GetAccountType
-    Pop $R0
-    StrCmp $R0 "Admin" lbl_is_admin
-        MessageBox MB_OK $(CheckAdministratorInstMB)
-        Quit
-lbl_is_admin:
-    Return
-
-FunctionEnd
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Make sure the user can uninstall
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-Function un.CheckIfAdministrator
-    DetailPrint $(CheckAdministratorUnInstDP)
-    UserInfo::GetAccountType
-    Pop $R0
-    StrCmp $R0 "Admin" lbl_is_admin
-        MessageBox MB_OK $(CheckAdministratorUnInstMB)
-        Quit
-lbl_is_admin:
-    Return
-
-FunctionEnd
-
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Function CheckWillUninstallV2               
 ;;
@@ -571,10 +564,10 @@ Push $2
   StrCpy $0 0	# Index number used to iterate via EnumRegKey
 
   LOOP:
-    EnumRegKey $1 HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" $0
+    EnumRegKey $1 SHELL_CONTEXT "${MSNTCURRVER_KEY}\ProfileList" $0
     StrCmp $1 "" DONE               # No more users
 
-    ReadRegStr $2 HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$1" "ProfileImagePath" 
+    ReadRegStr $2 SHELL_CONTEXT "${MSNTCURRVER_KEY}\ProfileList\$1" "ProfileImagePath" 
     StrCmp $2 "" CONTINUE 0         # "ProfileImagePath" value is missing
 
 # Required since ProfileImagePath is of type REG_EXPAND_SZ
@@ -604,7 +597,7 @@ Pop $0
 
 # Delete files in ProgramData\Secondlife
 Push $0
-  ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" "Common AppData"
+  ReadRegStr $0 SHELL_CONTEXT "${MSCURRVER_KEY}\Explorer\Shell Folders" "Common AppData"
   StrCmp $0 "" +2
   RMDir /r "$0\SecondLife"
 Pop $0
@@ -661,8 +654,8 @@ NOFOLDER:
 MessageBox MB_YESNO $(DeleteRegistryKeysMB) IDYES DeleteKeys IDNO NoDelete
 
 DeleteKeys:
-  DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Classes\x-grid-location-info"
-  DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Classes\secondlife"
+  DeleteRegKey SHELL_CONTEXT "SOFTWARE\Classes\x-grid-location-info"
+  DeleteRegKey SHELL_CONTEXT "SOFTWARE\Classes\secondlife"
   DeleteRegKey HKEY_CLASSES_ROOT "x-grid-location-info"
   DeleteRegKey HKEY_CLASSES_ROOT "secondlife"
 
@@ -758,10 +751,10 @@ FunctionEnd
 ;    StrCpy $0 0	# Index number used to iterate via EnumRegKey
 ;
 ;  LOOP:
-;    EnumRegKey $1 HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" $0
+;    EnumRegKey $1 SHELL_CONTEXT "${MSNTCURRVER_KEY}\ProfileList" $0
 ;    StrCmp $1 "" DONE               # no more users
 ;
-;    ReadRegStr $2 HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$1" "ProfileImagePath"
+;    ReadRegStr $2 SHELL_CONTEXT "${MSNTCURRVER_KEY}\ProfileList\$1" "ProfileImagePath"
 ;    StrCmp $2 "" CONTINUE 0         # "ProfileImagePath" value is missing
 ;
 ;# Required since ProfileImagePath is of type REG_EXPAND_SZ
@@ -780,7 +773,7 @@ FunctionEnd
 ;
 ;# Copy files in Documents and Settings\All Users\SecondLife
 ;Push $0
-;    ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" "Common AppData"
+;    ReadRegStr $0 SHELL_CONTEXT "${MSCURRVER_KEY}\Explorer\Shell Folders" "Common AppData"
 ;    StrCmp $0 "" +2
 ;    RMDir /r "$2\Application Data\SecondLife\"
 ;Pop $0
diff --git a/indra/newview/installers/windows/lang_da.nsi b/indra/newview/installers/windows/lang_da.nsi
index 83e1a3ea94..b3b8cf34d5 100644
Binary files a/indra/newview/installers/windows/lang_da.nsi and b/indra/newview/installers/windows/lang_da.nsi differ
diff --git a/indra/newview/installers/windows/lang_de.nsi b/indra/newview/installers/windows/lang_de.nsi
index 2a868acc89..7758a3bda6 100644
Binary files a/indra/newview/installers/windows/lang_de.nsi and b/indra/newview/installers/windows/lang_de.nsi differ
diff --git a/indra/newview/installers/windows/lang_en-us.nsi b/indra/newview/installers/windows/lang_en-us.nsi
index 00aa47de69..1e81c5294a 100644
Binary files a/indra/newview/installers/windows/lang_en-us.nsi and b/indra/newview/installers/windows/lang_en-us.nsi differ
diff --git a/indra/newview/installers/windows/lang_es.nsi b/indra/newview/installers/windows/lang_es.nsi
index 1ecf254ffb..6d4a7495a6 100644
Binary files a/indra/newview/installers/windows/lang_es.nsi and b/indra/newview/installers/windows/lang_es.nsi differ
diff --git a/indra/newview/installers/windows/lang_fr.nsi b/indra/newview/installers/windows/lang_fr.nsi
index bec5835bed..421015fc6b 100644
Binary files a/indra/newview/installers/windows/lang_fr.nsi and b/indra/newview/installers/windows/lang_fr.nsi differ
diff --git a/indra/newview/installers/windows/lang_it.nsi b/indra/newview/installers/windows/lang_it.nsi
index 1d2e150525..df735ba742 100644
Binary files a/indra/newview/installers/windows/lang_it.nsi and b/indra/newview/installers/windows/lang_it.nsi differ
diff --git a/indra/newview/installers/windows/lang_ja.nsi b/indra/newview/installers/windows/lang_ja.nsi
index 1bd6526670..f2cc1f9fde 100644
Binary files a/indra/newview/installers/windows/lang_ja.nsi and b/indra/newview/installers/windows/lang_ja.nsi differ
diff --git a/indra/newview/installers/windows/lang_pl.nsi b/indra/newview/installers/windows/lang_pl.nsi
index a172f0cdeb..61dc769126 100644
Binary files a/indra/newview/installers/windows/lang_pl.nsi and b/indra/newview/installers/windows/lang_pl.nsi differ
diff --git a/indra/newview/installers/windows/lang_pt-br.nsi b/indra/newview/installers/windows/lang_pt-br.nsi
index 87032fec18..d481434ab2 100644
Binary files a/indra/newview/installers/windows/lang_pt-br.nsi and b/indra/newview/installers/windows/lang_pt-br.nsi differ
diff --git a/indra/newview/installers/windows/lang_ru.nsi b/indra/newview/installers/windows/lang_ru.nsi
index 019c66123c..a42c719169 100644
Binary files a/indra/newview/installers/windows/lang_ru.nsi and b/indra/newview/installers/windows/lang_ru.nsi differ
diff --git a/indra/newview/installers/windows/lang_tr.nsi b/indra/newview/installers/windows/lang_tr.nsi
index 1c4e2c2f48..c320764fac 100644
Binary files a/indra/newview/installers/windows/lang_tr.nsi and b/indra/newview/installers/windows/lang_tr.nsi differ
diff --git a/indra/newview/installers/windows/lang_zh.nsi b/indra/newview/installers/windows/lang_zh.nsi
index 355e01a333..8da802df68 100644
Binary files a/indra/newview/installers/windows/lang_zh.nsi and b/indra/newview/installers/windows/lang_zh.nsi differ
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 3556b82320..1e58cec808 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -806,10 +806,10 @@ class WindowsManifest(ViewerManifest):
 
         if(self.address_size == 64):
             engage_registry="SetRegView 64"
-            program_files="$PROGRAMFILES64"
+            program_files="!define MULTIUSER_USE_PROGRAMFILES64"
         else:
             engage_registry="SetRegView 32"
-            program_files="$PROGRAMFILES32"
+            program_files=""
 
         tempfile = "secondlife_setup_tmp.nsi"
         # the following replaces strings in the nsi template
-- 
cgit v1.2.3


From 75cbe187a6572e904e2f931c6a1902b186eec844 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 2 Nov 2018 07:59:51 -0400
Subject: DRTVWR-447: Back out changeset 69118ad33b45: directly run updater
 from NSIS installer, instead of via explorer.exe.

A recent test run performed the install, then opened an Explorer window on My
Documents. <eyeroll/>
---
 indra/newview/installers/windows/installer_template.nsi | 13 +------------
 1 file changed, 1 insertion(+), 12 deletions(-)

diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index adcf8fd0e4..76187b49a5 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -705,21 +705,10 @@ Function .onInstSuccess
         # updater can detect the problem and adapt accordingly.
         # Once everything is in order, the updater will run the specified
         # viewer with the specified params.
-        # 'Exec updater' causes the viewer to inherit elevated Admin privileges. See
-        # http://mdb-blog.blogspot.com/2013/01/nsis-lunch-program-as-user-from-uac.html
-        # for workaround: running the updater via explorer.exe.
-        # Thing is, you can't pass parameters with the explorer.exe trick, so
-        # you have to create a shortcut or a .bat file. Since we don't want a
-        # permanent shortcut for the user to relaunch the updater like this
-        # first time, create it in a temp location and delete it once we've
-        # used it.
         # Quote the updater executable and the viewer executable because each
         # must be a distinct command-line token, but DO NOT quote the language
         # string because it must decompose into separate command-line tokens.
-        CreateShortCut "$TEMP\SLFirst.lnk" "$INSTDIR\$INSTEXE" \
-                       'precheck "$INSTDIR\$VIEWER_EXE" $SHORTCUT_LANG_PARAM'
-        Exec '"$WINDIR\explorer.exe" "$TEMP\SLFirst.lnk"'
-        Delete "$TEMP\SLFirst.lnk"
+        Exec '"$INSTDIR\$INSTEXE" precheck "$INSTDIR\$VIEWER_EXE" $SHORTCUT_LANG_PARAM'
         Pop $R0
 # 
 FunctionEnd
-- 
cgit v1.2.3


From e7ce166469dafe815ab002be76c6f80acaaff35c Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 2 Nov 2018 08:24:28 -0400
Subject: DRTVWR-447: Fix NSIS installer icons with "Modern UI" mechanism.

---
 indra/newview/installers/windows/installer_template.nsi | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index 219ee2695b..bd290b710b 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -80,9 +80,12 @@ Name ${INSTNAME}
 
 SubCaption 0 $(LicenseSubTitleSetup)	# Override "license agreement" text
 
+!define MUI_ICON   "%%SOURCE%%\installers\windows\install_icon.ico"
+!define MUI_UNICON "%%SOURCE%%\installers\windows\uninstall_icon.ico"
+
 BrandingText " "						# Bottom of window text
-Icon          %%SOURCE%%\installers\windows\install_icon.ico
-UninstallIcon %%SOURCE%%\installers\windows\uninstall_icon.ico
+Icon          "${MUI_ICON}"
+UninstallIcon "${MUI_UNICON}"
 WindowIcon on							# Show our icon in left corner
 BGGradient off							# No big background window
 CRCCheck on								# Make sure CRC is OK
-- 
cgit v1.2.3


From 6c51d3ba7481fbe68ed138ebb530c2875637d506 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 7 Nov 2018 15:45:18 -0800
Subject: SL-9952: Update to viewer-manager build 521490

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 4317de3408..33c9dd9e5a 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3138,9 +3138,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>51f77e40a4d3a259033b3017de8f3569</string>
+              <string>9d5f69b45558d1653ebd2a3c70c869b5</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/26806/214061/viewer_manager-2.0.521170-darwin64-521170.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/27297/218880/viewer_manager-2.0.521490-darwin64-521490.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3162,9 +3162,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>86a396beb2355f9bd51c912dfd679d48</string>
+              <string>9d26790001ccc0756e4a992dcd55cc91</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/26807/214067/viewer_manager-2.0.521170-windows-521170.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/27300/218889/viewer_manager-2.0.521490-windows-521490.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3175,7 +3175,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.521170</string>
+        <string>2.0.521490</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From cb5c5bb6ee2705791717ea319a415728d9c06eee Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 7 Nov 2018 15:57:20 -0800
Subject: SL-9952: updater.exe now renamed to SLVersionChecker.exe thereby
 avoiding strange Windows requirement for elevated privilege.

---
 indra/newview/llappviewer.cpp    |  8 ++++----
 indra/newview/viewer_manifest.py | 10 ++++------
 2 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index bda76c14d1..d3577d50a1 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1140,13 +1140,13 @@ bool LLAppViewer::init()
 	// viewer itself.
 	updater.autokill = false;
 #if LL_WINDOWS
-	updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "updater.exe");
+	updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "SLVersionChecker.exe");
 #elif LL_DARWIN
-	// explicitly run the system Python interpreter on updater.py
+	// explicitly run the system Python interpreter on SLVersionChecker.py
 	updater.executable = "python";
-	updater.args.add(gDirUtilp->add(gDirUtilp->getAppRODataDir(), "updater", "updater.py"));
+	updater.args.add(gDirUtilp->add(gDirUtilp->getAppRODataDir(), "updater", "SLVersionChecker.py"));
 #else
-	updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "updater");
+	updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "SLVersionChecker");
 #endif
 	// add LEAP mode command-line argument to whichever of these we selected
 	updater.args.add("leap");
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 1e58cec808..3e8bb388d2 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -497,9 +497,7 @@ class WindowsManifest(ViewerManifest):
 
             with self.prefix(src=os.path.join(pkgdir, "VMP")):
                 # include the compiled launcher scripts so that it gets included in the file_list
-                self.path('updater.exe')
-                #IUM is not normally executed directly, just imported.  No exe needed.
-                self.path("InstallerUserMessage.py")
+                self.path('SLVersionChecker.exe')
 
             with self.prefix(dst="vmp_icons"):
                 with self.prefix(src=self.icon_path()):
@@ -713,7 +711,7 @@ class WindowsManifest(ViewerManifest):
                 self.path("libvlccore.dll")
                 self.path("plugins/")
 
-        # pull in the crash logger and updater from other projects
+        # pull in the crash logger from other projects
         # tag:"crash-logger" here as a cue to the exporter
         self.path(src='../win_crash_logger/%s/windows-crash-logger.exe' % self.args['configuration'],
                   dst="win_crash_logger.exe")
@@ -783,7 +781,7 @@ class WindowsManifest(ViewerManifest):
         substitution_strings['installer_file'] = installer_file
         
         version_vars = """
-        !define INSTEXE "updater.exe"
+        !define INSTEXE "SLVersionChecker.exe"
         !define VERSION "%(version_short)s"
         !define VERSION_LONG "%(version)s"
         !define VERSION_DASHES "%(version_dashes)s"
@@ -828,7 +826,7 @@ class WindowsManifest(ViewerManifest):
         # Unlike the viewer binary, the VMP filenames are invariant with respect to version, os, etc.
         for exe in (
             self.final_exe(),
-            "updater.exe",
+            "SLVersionChecker.exe",
             ):
             self.sign(exe)
             
-- 
cgit v1.2.3


From 4e776c522cb4ba49a5b833d4b9164ab8c48f4b9b Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 8 Nov 2018 14:21:31 -0800
Subject: SL-10030: Update to viewer-manager build 521526

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 33c9dd9e5a..a51f14b274 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3138,9 +3138,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>9d5f69b45558d1653ebd2a3c70c869b5</string>
+              <string>c543e73c35c605eaf509bc7651c11227</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/27297/218880/viewer_manager-2.0.521490-darwin64-521490.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/27348/219718/viewer_manager-2.0.521526-darwin64-521526.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3162,9 +3162,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>9d26790001ccc0756e4a992dcd55cc91</string>
+              <string>fec612973e0d70f82da8c8f22a10c6f3</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/27300/218889/viewer_manager-2.0.521490-windows-521490.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/27349/219725/viewer_manager-2.0.521526-windows-521526.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3175,7 +3175,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.521490</string>
+        <string>2.0.521526</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From f49ee0a0538ae03e9299c95a15f0485dee971dbd Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 14 Nov 2018 16:19:47 -0500
Subject: DRTVWR-447: Animesh + BugSplat = 6.1

---
 indra/newview/VIEWER_VERSION.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 5fe6072304..dfda3e0b4f 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-6.0.1
+6.1.0
-- 
cgit v1.2.3


From dd9f6784ccc5d285ef50f0b8693ee92bb872d992 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 15 Nov 2018 12:06:30 -0500
Subject: SL-10010: Use c:\Program Files rather than c:\Program Files (x86) for
 64-bit viewers.

It seems there's a longstanding bug in NSIS: it fails to use $PROGRAMFILES64
rather than $PROGRAMFILES when performing an all-users install of a 64-bit
program. Try to remedy that.

Also pick up a few NSIS suggestions from Ansariel Hiller.
---
 .../installers/windows/installer_template.nsi      |  22 ++++++++++++++++++++-
 indra/newview/installers/windows/lang_en-us.nsi    | Bin 11342 -> 11488 bytes
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index bd290b710b..840203c178 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -46,9 +46,13 @@ RequestExecutionLevel highest           # match MULTIUSER_EXECUTIONLEVEL
 ;; (these files are in the same place as the nsi template but the python script generates a new nsi file in the 
 ;; application directory so we have to add a path to these include files)
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Ansariel notes: "Under certain circumstances the installer will fall back
+;; to the first defined (aka default) language version. So you want to include
+;; en-us as first language file."
+!include "%%SOURCE%%\installers\windows\lang_en-us.nsi"
+
 !include "%%SOURCE%%\installers\windows\lang_da.nsi"
 !include "%%SOURCE%%\installers\windows\lang_de.nsi"
-!include "%%SOURCE%%\installers\windows\lang_en-us.nsi"
 !include "%%SOURCE%%\installers\windows\lang_es.nsi"
 !include "%%SOURCE%%\installers\windows\lang_fr.nsi"
 !include "%%SOURCE%%\installers\windows\lang_ja.nsi"
@@ -108,8 +112,22 @@ AutoCloseWindow true					# After all files install, close window
 !define MULTIUSER_INSTALLMODE_COMMANDLINE
 # appended to $PROGRAMFILES, as affected by MULTIUSER_USE_PROGRAMFILES64
 !define MULTIUSER_INSTALLMODE_INSTDIR "${INSTNAME}"
+
 # expands to !define MULTIUSER_USE_PROGRAMFILES64 or nothing
 %%PROGRAMFILES%%
+# Bug in MultiUser.nsh?! This reference:
+# http://nsis.sourceforge.net/Docs/MultiUser/Readme.html
+# says:
+# MULTIUSER_USE_PROGRAMFILES64 	Use $PROGRAMFILES64 instead of $PROGRAMFILES as the default all users directory.
+# Yet as far as I can tell from:
+# https://sourceforge.net/p/nsis/mailman/message/22246769/
+# (which contains a patch), that functionality has never been released with
+# NSIS. Instead of applying a patch to each developer machine and each
+# TeamCity build host, try overwriting $PROGRAMFILES with $PROGRAMFILES64?!
+!ifdef MULTIUSER_USE_PROGRAMFILES64
+  StrCpy $PROGRAMFILES $PROGRAMFILES64
+!endif
+
 # should make MultiUser.nsh initialization read existing INSTDIR from registry
 !define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY "${INSTNAME_KEY}"
 !define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME ""
@@ -118,6 +136,8 @@ AutoCloseWindow true					# After all files install, close window
 !define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME "InstallMode"
 !include MultiUser.nsh
 !include MUI2.nsh
+!define MUI_BGCOLOR FFFFFF
+!insertmacro MUI_FUNCTION_GUIINIT
 
 UninstallText $(UninstallTextMsg)
 DirText $(DirectoryChooseTitle) $(DirectoryChooseSetup)
diff --git a/indra/newview/installers/windows/lang_en-us.nsi b/indra/newview/installers/windows/lang_en-us.nsi
index 1e81c5294a..fd4d340816 100644
Binary files a/indra/newview/installers/windows/lang_en-us.nsi and b/indra/newview/installers/windows/lang_en-us.nsi differ
-- 
cgit v1.2.3


From db2cddf93fd3f39ca0330a8a8b93641377404dd1 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 15 Nov 2018 16:02:47 -0500
Subject: SL-10010: Use trunk NSIS + Unicode attrib, instead of Unicode fork.

Back out misguided attempt to overwrite $PROGRAMFILES with $PROGRAMFILES64.
---
 .../newview/installers/windows/installer_template.nsi  | 18 ++----------------
 indra/newview/viewer_manifest.py                       |  4 +---
 2 files changed, 3 insertions(+), 19 deletions(-)

diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index 840203c178..f62a14d65f 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -18,8 +18,7 @@
 ;;
 ;; Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 ;;
-;; NSIS Unicode 2.46.5 or higher required
-;; http://www.scratchpaper.com/
+;; NSIS 3 or higher required for Unicode support
 ;;
 ;; Author: James Cook, TankMaster Finesmith, Don Kjer, Callum Prentice
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -27,6 +26,7 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Compiler flags
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+Unicode true
 SetOverwrite on				# Overwrite files
 SetCompress auto			# Compress if saves space
 SetCompressor /solid lzma	# Compress whole installer as one block
@@ -112,22 +112,8 @@ AutoCloseWindow true					# After all files install, close window
 !define MULTIUSER_INSTALLMODE_COMMANDLINE
 # appended to $PROGRAMFILES, as affected by MULTIUSER_USE_PROGRAMFILES64
 !define MULTIUSER_INSTALLMODE_INSTDIR "${INSTNAME}"
-
 # expands to !define MULTIUSER_USE_PROGRAMFILES64 or nothing
 %%PROGRAMFILES%%
-# Bug in MultiUser.nsh?! This reference:
-# http://nsis.sourceforge.net/Docs/MultiUser/Readme.html
-# says:
-# MULTIUSER_USE_PROGRAMFILES64 	Use $PROGRAMFILES64 instead of $PROGRAMFILES as the default all users directory.
-# Yet as far as I can tell from:
-# https://sourceforge.net/p/nsis/mailman/message/22246769/
-# (which contains a patch), that functionality has never been released with
-# NSIS. Instead of applying a patch to each developer machine and each
-# TeamCity build host, try overwriting $PROGRAMFILES with $PROGRAMFILES64?!
-!ifdef MULTIUSER_USE_PROGRAMFILES64
-  StrCpy $PROGRAMFILES $PROGRAMFILES64
-!endif
-
 # should make MultiUser.nsh initialization read existing INSTDIR from registry
 !define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY "${INSTNAME_KEY}"
 !define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME ""
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 3e8bb388d2..32773b2c36 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -830,12 +830,10 @@ class WindowsManifest(ViewerManifest):
             ):
             self.sign(exe)
             
-        # We use the Unicode version of NSIS, available from
-        # http://www.scratchpaper.com/
         # Check two paths, one for Program Files, and one for Program Files (x86).
         # Yay 64bit windows.
         for ProgramFiles in 'ProgramFiles', 'ProgramFiles(x86)':
-            NSIS_path = os.path.expandvars(r'${%s}\NSIS\Unicode\makensis.exe' % ProgramFiles)
+            NSIS_path = os.path.expandvars(r'${%s}\NSIS\makensis.exe' % ProgramFiles)
             if os.path.exists(NSIS_path):
                 break
         installer_created=False
-- 
cgit v1.2.3


From 4f6037a823b3d53a9051aec172cf432c63775b39 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Mon, 19 Nov 2018 19:20:57 +0200
Subject: SL-3404 Named log output for easier debugging and testing

---
 indra/newview/llviewerparcelmgr.cpp | 28 +++++++++++++++-------------
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index f4d14a39fe..5477d2d444 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -957,7 +957,7 @@ void LLViewerParcelMgr::sendParcelGodForceOwner(const LLUUID& owner_id)
 		return;
 	}
 
-	LL_INFOS() << "Claiming " << mWestSouth << " to " << mEastNorth << LL_ENDL;
+	LL_INFOS("ParcelMgr") << "Claiming " << mWestSouth << " to " << mEastNorth << LL_ENDL;
 
 	// BUG: Only works for the region containing mWestSouthBottom
 	LLVector3d east_north_region_check( mEastNorth );
@@ -980,7 +980,7 @@ void LLViewerParcelMgr::sendParcelGodForceOwner(const LLUUID& owner_id)
 		return;
 	}
 
-	LL_INFOS() << "Region " << region->getOriginGlobal() << LL_ENDL;
+	LL_INFOS("ParcelMgr") << "Region " << region->getOriginGlobal() << LL_ENDL;
 
 	LLSD payload;
 	payload["owner_id"] = owner_id;
@@ -1120,8 +1120,8 @@ LLViewerParcelMgr::ParcelBuyInfo* LLViewerParcelMgr::setupParcelBuy(
 	
 	if (is_claim)
 	{
-		LL_INFOS() << "Claiming " << mWestSouth << " to " << mEastNorth << LL_ENDL;
-		LL_INFOS() << "Region " << region->getOriginGlobal() << LL_ENDL;
+		LL_INFOS("ParcelMgr") << "Claiming " << mWestSouth << " to " << mEastNorth << LL_ENDL;
+		LL_INFOS("ParcelMgr") << "Region " << region->getOriginGlobal() << LL_ENDL;
 
 		// BUG: Only works for the region containing mWestSouthBottom
 		LLVector3d east_north_region_check( mEastNorth );
@@ -1294,8 +1294,6 @@ void LLViewerParcelMgr::sendParcelPropertiesUpdate(LLParcel* parcel, bool use_ag
 	if (!region) 
         return;
 
-	//LL_INFOS() << "found region: " << region->getName() << LL_ENDL;
-
 	LLSD body;
 	std::string url = region->getCapability("ParcelPropertiesUpdate");
 	if (!url.empty())
@@ -1304,7 +1302,7 @@ void LLViewerParcelMgr::sendParcelPropertiesUpdate(LLParcel* parcel, bool use_ag
 		U32 message_flags = 0x01;
 		body["flags"] = ll_sd_from_U32(message_flags);
 		parcel->packMessage(body);
-		LL_INFOS() << "Sending parcel properties update via capability to: "
+		LL_INFOS("ParcelMgr") << "Sending parcel properties update via capability to: "
 			<< url << LL_ENDL;
 
         LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, body,
@@ -1356,6 +1354,8 @@ void LLViewerParcelMgr::setHoverParcel(const LLVector3d& pos)
 		return;
 	}
 
+	LL_DEBUGS("ParcelMgr") << "Requesting parcel properties on hover, for " << pos << LL_ENDL;
+
 
 	// Send a rectangle around the point.
 	// This means the parcel sent back is at least a rectangle around the point,
@@ -1472,7 +1472,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
     if (request_result == PARCEL_RESULT_NO_DATA)
     {
         // no valid parcel data
-        LL_INFOS() << "no valid parcel data" << LL_ENDL;
+        LL_INFOS("ParcelMgr") << "no valid parcel data" << LL_ENDL;
         return;
     }
 
@@ -1504,7 +1504,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
     }
     else
     {
-        LL_INFOS() << "out of order agent parcel sequence id " << sequence_id
+        LL_INFOS("ParcelMgr") << "out of order agent parcel sequence id " << sequence_id
             << " last good " << parcel_mgr.mAgentParcelSequenceID
             << LL_ENDL;
         return;
@@ -1552,6 +1552,8 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
 
 	msg->getS32("ParcelData", "OtherCleanTime", other_clean_time );
 
+	LL_DEBUGS("ParcelMgr") << "Processing parcel " << local_id << " update, target(sequence): " << sequence_id << LL_ENDL;
+
 	// Actually extract the data.
 	if (parcel)
 	{
@@ -1790,7 +1792,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
                         }
                         else
                         {
-                            LL_INFOS() << "Stopping parcel music (invalid audio stream URL)" << LL_ENDL;
+                            LL_INFOS("ParcelMgr") << "Stopping parcel music (invalid audio stream URL)" << LL_ENDL;
                             // clears the URL
                             // null value causes fade out
                             LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null);
@@ -1798,7 +1800,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
                     }
                     else if (!gAudiop->getInternetStreamURL().empty())
                     {
-                        LL_INFOS() << "Stopping parcel music (parcel stream URL is empty)" << LL_ENDL;
+                        LL_INFOS("ParcelMgr") << "Stopping parcel music (parcel stream URL is empty)" << LL_ENDL;
                         // null value causes fade out
                         LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null);
                     }
@@ -1827,7 +1829,7 @@ void LLViewerParcelMgr::optionally_start_music(const std::string& music_url)
 		     gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) &&
 			 gSavedSettings.getBOOL("MediaTentativeAutoPlay")))
 		{
-			LL_INFOS() << "Starting parcel music " << music_url << LL_ENDL;
+			LL_INFOS("ParcelMgr") << "Starting parcel music " << music_url << LL_ENDL;
 			LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(music_url);
 		}
 		else
@@ -1855,7 +1857,7 @@ void LLViewerParcelMgr::processParcelAccessListReply(LLMessageSystem *msg, void
 
 	if (parcel_id != parcel->getLocalID())
 	{
-		LL_WARNS_ONCE("") << "processParcelAccessListReply for parcel " << parcel_id
+		LL_WARNS_ONCE("ParcelMgr") << "processParcelAccessListReply for parcel " << parcel_id
 			<< " which isn't the selected parcel " << parcel->getLocalID()<< LL_ENDL;
 		return;
 	}
-- 
cgit v1.2.3


From baeca41027d586871fd38fb2c9d8684f747231c7 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Mon, 19 Nov 2018 20:20:34 +0200
Subject: SL-10089 Logs to see which gSavedSettings.get calls should be cached

---
 doc/contributions.txt     |  1 +
 indra/llxml/llcontrol.cpp | 94 ++++++++++++++++++++++++++++++++++++++++++++++-
 indra/llxml/llcontrol.h   |  3 ++
 3 files changed, 97 insertions(+), 1 deletion(-)

diff --git a/doc/contributions.txt b/doc/contributions.txt
index 88b2a77393..97c7ff1098 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -777,6 +777,7 @@ Jonathan Yap
 	STORM-2100
 	STORM-2104
 	STORM-2142
+	SL-10089
 Kadah Coba
 	STORM-1060
     STORM-1843
diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp
index 20ab1a7ad3..ccf4f3ddf5 100644
--- a/indra/llxml/llcontrol.cpp
+++ b/indra/llxml/llcontrol.cpp
@@ -43,6 +43,9 @@
 #include "llrect.h"
 #include "llxmltree.h"
 #include "llsdserialize.h"
+#include "llfile.h"
+#include "lltimer.h"
+#include "lldir.h"
 
 #if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG
 #define CONTROL_ERRS LL_ERRS("ControlErrors")
@@ -92,6 +95,17 @@ template <> LLSD convert_from_llsd<LLSD>(const LLSD& sd, eControlType type, cons
 //this defines the current version of the settings file
 const S32 CURRENT_VERSION = 101;
 
+// If you define the environment variable LL_SETTINGS_PROFILE to any value this will activate
+// the gSavedSettings profiling code.  This code tracks the calls to get a saved (debug) setting.
+// When the viewer exits the results are written to the log directory to the file specified
+// by SETTINGS_PROFILE below.  Only settings with an average access rate >= 2/second are output.
+typedef std::pair<std::string, U32> settings_pair_t;
+typedef std::vector<settings_pair_t> settings_vec_t;
+LLSD getCount;
+settings_vec_t getCount_v;
+F64 start_time = 0;
+std::string SETTINGS_PROFILE = "settings_profile.log";
+
 bool LLControlVariable::llsd_compare(const LLSD& a, const LLSD & b)
 {
 	bool result = false;
@@ -327,6 +341,11 @@ LLSD LLControlVariable::getSaveValue() const
 
 LLPointer<LLControlVariable> LLControlGroup::getControl(const std::string& name)
 {
+	if (mSettingsProfile)
+	{
+		incrCount(name);
+	}
+
 	ctrl_name_table_t::iterator iter = mNameTable.find(name);
 	return iter == mNameTable.end() ? LLPointer<LLControlVariable>() : iter->second;
 }
@@ -349,8 +368,14 @@ const std::string LLControlGroup::mTypeString[TYPE_COUNT] = { "U32"
                                                              };
 
 LLControlGroup::LLControlGroup(const std::string& name)
-:	LLInstanceTracker<LLControlGroup, std::string>(name)
+:	LLInstanceTracker<LLControlGroup, std::string>(name),
+	mSettingsProfile(false)
 {
+
+	if (NULL != getenv("LL_SETTINGS_PROFILE"))
+	{
+		mSettingsProfile = true;
+	}
 }
 
 LLControlGroup::~LLControlGroup()
@@ -358,8 +383,66 @@ LLControlGroup::~LLControlGroup()
 	cleanup();
 }
 
+static bool compareRoutine(settings_pair_t lhs, settings_pair_t rhs)
+{
+	return lhs.second > rhs.second;
+};
+
 void LLControlGroup::cleanup()
 {
+	if(mSettingsProfile && getCount.size() != 0)
+	{
+		std::string file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, SETTINGS_PROFILE);
+		LLFILE* out = LLFile::fopen(file, "w"); /* Flawfinder: ignore */
+		if(!out)
+		{
+			LL_WARNS("SettingsProfile") << "Error opening " << SETTINGS_PROFILE << LL_ENDL;
+		}
+		else
+		{
+			F64 end_time = LLTimer::getTotalSeconds();
+			U32 total_seconds = (U32)(end_time - start_time);
+
+			std::string msg = llformat("Runtime (seconds): %d\n\n No. accesses   Avg. accesses/sec  Name\n", total_seconds);
+			std::ostringstream data_msg;
+
+			data_msg << msg;
+			size_t data_size = data_msg.str().size();
+			if (fwrite(data_msg.str().c_str(), 1, data_size, out) != data_size)
+			{
+				LL_WARNS("SettingsProfile") << "Failed to write settings profile header" << LL_ENDL;
+			}
+
+			for (LLSD::map_const_iterator iter = getCount.beginMap(); iter != getCount.endMap(); ++iter)
+			{
+				getCount_v.push_back(settings_pair_t(iter->first, iter->second.asInteger()));
+			}
+			sort(getCount_v.begin(), getCount_v.end(), compareRoutine);
+
+			for (settings_vec_t::iterator iter = getCount_v.begin(); iter != getCount_v.end(); ++iter)
+			{
+				U32 access_rate = 0;
+				if (total_seconds != 0)
+				{
+					access_rate = iter->second / total_seconds;
+				}
+				if (access_rate >= 2)
+				{
+					std::ostringstream data_msg;
+					msg = llformat("%13d        %7d       %s", iter->second, access_rate, iter->first.c_str());
+					data_msg << msg << "\n";
+					size_t data_size = data_msg.str().size();
+					if (fwrite(data_msg.str().c_str(), 1, data_size, out) != data_size)
+					{
+						LL_WARNS("SettingsProfile") << "Failed to write settings profile" << LL_ENDL;
+					}
+				}
+			}
+			getCount = LLSD::emptyMap();
+			fclose(out);
+		}
+	}
+
 	mNameTable.clear();
 }
 
@@ -460,6 +543,15 @@ LLControlVariable* LLControlGroup::declareLLSD(const std::string& name, const LL
 	return declareControl(name, TYPE_LLSD, initial_val, comment, persist);
 }
 
+void LLControlGroup::incrCount(const std::string& name)
+{
+	if (0.0 == start_time)
+	{
+		start_time = LLTimer::getTotalSeconds();
+	}
+	getCount[name] = getCount[name].asInteger() + 1;
+}
+
 BOOL LLControlGroup::getBOOL(const std::string& name)
 {
 	return (BOOL)get<bool>(name);
diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h
index 8136a3e88a..de0d366492 100644
--- a/indra/llxml/llcontrol.h
+++ b/indra/llxml/llcontrol.h
@@ -301,6 +301,9 @@ public:
  	U32 saveToFile(const std::string& filename, BOOL nondefault_only);
  	U32	loadFromFile(const std::string& filename, bool default_values = false, bool save_values = true);
 	void	resetToDefaults();
+	void	incrCount(const std::string& name);
+
+	bool	mSettingsProfile;
 };
 
 
-- 
cgit v1.2.3


From faf79976c0ad3ea9406f3c13348c6ee27837ef2c Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Tue, 20 Nov 2018 15:53:43 +0200
Subject: SL-10094 FIXED Mute sound should ONLY mute the viewer's sounds, not
 the whole computer's (Mac) sound.

---
 indra/newview/llappviewermacosx.cpp | 62 -------------------------------------
 indra/newview/llappviewermacosx.h   |  4 ---
 2 files changed, 66 deletions(-)

diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp
index d472f8926b..1db48119aa 100644
--- a/indra/newview/llappviewermacosx.cpp
+++ b/indra/newview/llappviewermacosx.cpp
@@ -337,68 +337,6 @@ std::string LLAppViewerMacOSX::generateSerialNumber()
 	return serial_md5;
 }
 
-static AudioDeviceID get_default_audio_output_device(void)
-{
-	AudioDeviceID device = 0;
-	UInt32 size = sizeof(device);
-	AudioObjectPropertyAddress device_address = { kAudioHardwarePropertyDefaultOutputDevice,
-												  kAudioObjectPropertyScopeGlobal,
-												  kAudioObjectPropertyElementMaster };
-
-	OSStatus err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &device_address, 0, NULL, &size, &device);
-	if(err != noErr)
-	{
-		LL_DEBUGS("SystemMute") << "Couldn't get default audio output device (0x" << std::hex << err << ")" << LL_ENDL;
-	}
-
-	return device;
-}
-
-//virtual
-void LLAppViewerMacOSX::setMasterSystemAudioMute(bool new_mute)
-{
-	AudioDeviceID device = get_default_audio_output_device();
-
-	if(device != 0)
-	{
-		UInt32 mute = new_mute;
-		AudioObjectPropertyAddress device_address = { kAudioDevicePropertyMute,
-													  kAudioDevicePropertyScopeOutput,
-													  kAudioObjectPropertyElementMaster };
-
-		OSStatus err = AudioObjectSetPropertyData(device, &device_address, 0, NULL, sizeof(mute), &mute);
-		if(err != noErr)
-		{
-			LL_INFOS("SystemMute") << "Couldn't set audio mute property (0x" << std::hex << err << ")" << LL_ENDL;
-		}
-	}
-}
-
-//virtual
-bool LLAppViewerMacOSX::getMasterSystemAudioMute()
-{
-	// Assume the system isn't muted 
-	UInt32 mute = 0;
-
-	AudioDeviceID device = get_default_audio_output_device();
-
-	if(device != 0)
-	{
-		UInt32 size = sizeof(mute);
-		AudioObjectPropertyAddress device_address = { kAudioDevicePropertyMute,
-													  kAudioDevicePropertyScopeOutput,
-													  kAudioObjectPropertyElementMaster };
-
-		OSStatus err = AudioObjectGetPropertyData(device, &device_address, 0, NULL, &size, &mute);
-		if(err != noErr)
-		{
-			LL_DEBUGS("SystemMute") << "Couldn't get audio mute property (0x" << std::hex << err << ")" << LL_ENDL;
-		}
-	}
-	
-	return (mute != 0);
-}
-
 void handleUrl(const char* url_utf8)
 {
     if (url_utf8 && gViewerAppPtr)
diff --git a/indra/newview/llappviewermacosx.h b/indra/newview/llappviewermacosx.h
index ebb41a495c..d5a80864be 100644
--- a/indra/newview/llappviewermacosx.h
+++ b/indra/newview/llappviewermacosx.h
@@ -42,10 +42,6 @@ public:
 	//
 	virtual bool init();			// Override to do application initialization
 
-	// mute/unmute the system's master audio
-	virtual void setMasterSystemAudioMute(bool mute);
-	virtual bool getMasterSystemAudioMute();
-
 protected:
 	virtual bool restoreErrorTrap();
 	virtual void initCrashReporting(bool reportFreeze);
-- 
cgit v1.2.3


From c99a66a482d8893055be6e130bae22d3d67d123e Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Wed, 21 Nov 2018 17:41:15 +0200
Subject: SL-10113 FIXED [Win] File pickers are not threaded in XUI preview
 floater

---
 indra/newview/llfloateruipreview.cpp | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp
index 76ad2146f1..4e0b27a4f8 100644
--- a/indra/newview/llfloateruipreview.cpp
+++ b/indra/newview/llfloateruipreview.cpp
@@ -60,6 +60,7 @@
 #include "llfloaterreg.h"
 #include "llscrollcontainer.h"	// scroll container for overlapping elements
 #include "lllivefile.h"					// live file poll/stat/reload
+#include "llviewermenufile.h" // LLFilePickerReplyThread
 
 // Boost (for linux/unix command-line execv)
 #include <boost/tokenizer.hpp>
@@ -206,7 +207,9 @@ private:
 	void onClickSaveAll(S32 id);
 	void onClickEditFloater();
 	void onClickBrowseForEditor();
+	void getExecutablePath(const std::vector<std::string>& filenames);
 	void onClickBrowseForDiffs();
+	void getDiffsFilePath(const std::vector<std::string>& filenames);
 	void onClickToggleDiffHighlighting();
 	void onClickToggleOverlapping();
 	void onClickCloseDisplayedFloater(S32 id);
@@ -1019,15 +1022,14 @@ void LLFloaterUIPreview::onClickEditFloater()
 // Respond to button click to browse for an executable with which to edit XML files
 void LLFloaterUIPreview::onClickBrowseForEditor()
 {
-	// Let the user choose an executable through the file picker dialog box
-	LLFilePicker& picker = LLFilePicker::instance();
-    if (!picker.getOpenFile(LLFilePicker::FFLOAD_EXE))
-	{
-		return; // user cancelled -- do nothing
-	}
+    // Let the user choose an executable through the file picker dialog box
+    (new LLFilePickerReplyThread(boost::bind(&LLFloaterUIPreview::getExecutablePath, this, _1), LLFilePicker::FFLOAD_EXE, false))->getFile();
+}
 
+void LLFloaterUIPreview::getExecutablePath(const std::vector<std::string>& filenames)
+{
 	// put the selected path into text field
-	const std::string chosen_path = picker.getFirstFile();
+	const std::string chosen_path = filenames[0];
 	std::string executable_path = chosen_path;
 #if LL_DARWIN
 	// on Mac, if it's an application bundle, figure out the actual path from the Info.plist file
@@ -1075,15 +1077,13 @@ void LLFloaterUIPreview::onClickBrowseForEditor()
 void LLFloaterUIPreview::onClickBrowseForDiffs()
 {
 	// create load dialog box
-	LLFilePicker::ELoadFilter type = (LLFilePicker::ELoadFilter)((intptr_t)((void*)LLFilePicker::FFLOAD_XML));	// nothing for *.exe so just use all
-	LLFilePicker& picker = LLFilePicker::instance();
-	if (!picker.getOpenFile(type))	// user cancelled -- do nothing
-	{
-		return;
-	}
+    (new LLFilePickerReplyThread(boost::bind(&LLFloaterUIPreview::getDiffsFilePath, this, _1), LLFilePicker::FFLOAD_XML, false))->getFile();
+}
 
+void LLFloaterUIPreview::getDiffsFilePath(const std::vector<std::string>& filenames)
+{
 	// put the selected path into text field
-	const std::string chosen_path = picker.getFirstFile();
+	const std::string chosen_path = filenames[0];
 	mDiffPathTextBox->setText(std::string(chosen_path));	// copy the path to the executable to the textfield for display and later fetching
 	if(LLView::sHighlightingDiffs)								// if we're already highlighting, toggle off and then on so we get the data from the new file
 	{
-- 
cgit v1.2.3


From dea5450d789cb876856db8fc0159e1df34009c19 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Tue, 20 Nov 2018 19:47:00 +0200
Subject: SL-4730 Prevent viewer from getting more texture details when low on
 memory

---
 indra/newview/llviewertexture.cpp | 129 +++++++++++++++++++++-----------------
 indra/newview/llviewertexture.h   |   7 ++-
 2 files changed, 78 insertions(+), 58 deletions(-)

diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index d2157f33cf..db3adcec2b 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -100,7 +100,7 @@ const S32 MAX_CACHED_RAW_TERRAIN_IMAGE_AREA = 128 * 128;
 const S32 DEFAULT_ICON_DIMENTIONS = 32;
 S32 LLViewerTexture::sMinLargeImageSize = 65536; //256 * 256.
 S32 LLViewerTexture::sMaxSmallImageSize = MAX_CACHED_RAW_IMAGE_AREA;
-BOOL LLViewerTexture::sFreezeImageScalingDown = FALSE;
+bool LLViewerTexture::sFreezeImageUpdates = false;
 F32 LLViewerTexture::sCurrentTime = 0.0f;
 F32  LLViewerTexture::sTexelPixelRatio = 1.0f;
 
@@ -484,53 +484,68 @@ static LLTrace::BlockTimerStatHandle FTM_TEXTURE_MEMORY_CHECK("Memory Check");
 //static 
 bool LLViewerTexture::isMemoryForTextureLow()
 {
-	static LLFrameTimer timer;
-	static bool low_mem = false;
+    // Note: we need to figure out a better source for 'min' values,
+    // what is free for low end at minimal settings is 'nothing left'
+    // for higher end gpus at high settings.
+    const S32Megabytes MIN_FREE_TEXTURE_MEMORY(20);
+    const S32Megabytes MIN_FREE_MAIN_MEMORY(100);
 
-	if(timer.getElapsedTimeF32() < GPU_MEMORY_CHECK_WAIT_TIME) //call this once per second.
-	{
-		return low_mem;
-	}
-	timer.reset();
+    S32Megabytes gpu;
+    S32Megabytes physical;
+    getGPUMemoryForTextures(gpu, physical);
 
-	LL_RECORD_BLOCK_TIME(FTM_TEXTURE_MEMORY_CHECK);
+    return (gpu < MIN_FREE_TEXTURE_MEMORY) || (physical < MIN_FREE_MAIN_MEMORY);
+}
 
-	const S32Megabytes MIN_FREE_TEXTURE_MEMORY(20); //MB Changed to 20 MB per MAINT-6882
-	const S32Megabytes MIN_FREE_MAIN_MEMORY(100); //MB	
+//static
+bool LLViewerTexture::isMemoryForTextureSuficientlyFree()
+{
+    const S32Megabytes DESIRED_FREE_TEXTURE_MEMORY(50);
+    const S32Megabytes DESIRED_FREE_MAIN_MEMORY(200);
 
-	low_mem = false;
-	if (gGLManager.mHasATIMemInfo)
-	{
-		S32 meminfo[4];
-		glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo);
+    S32Megabytes gpu;
+    S32Megabytes physical;
+    getGPUMemoryForTextures(gpu, physical);
 
-		if((S32Megabytes)meminfo[0] < MIN_FREE_TEXTURE_MEMORY)
-		{
-			low_mem = true;
-		}
+    return (gpu > DESIRED_FREE_TEXTURE_MEMORY) && (physical > DESIRED_FREE_MAIN_MEMORY);
+}
 
-		if(!low_mem) //check main memory, only works for windows.
-		{
-			LLMemory::updateMemoryInfo();
-			if(LLMemory::getAvailableMemKB() < MIN_FREE_TEXTURE_MEMORY)
-			{
-				low_mem = true;
-			}
-		}
-	}
-	//Enabled this branch per MAINT-6882
-	else if (gGLManager.mHasNVXMemInfo)
-	{
-		S32 free_memory;
-		glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &free_memory);
-		
-		if ((S32Megabytes)(free_memory / 1024) < MIN_FREE_TEXTURE_MEMORY)
-		{
-			low_mem = true;
-		}
-	}
+//static
+void LLViewerTexture::getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &physical)
+{
+    static LLFrameTimer timer;
+    static S32Megabytes gpu_res = S32Megabytes(S32_MAX);
+    static S32Megabytes physical_res = S32Megabytes(S32_MAX);
+
+    if (timer.getElapsedTimeF32() < GPU_MEMORY_CHECK_WAIT_TIME) //call this once per second.
+    {
+        gpu = gpu_res;
+        physical = physical_res;
+        return;
+    }
+    timer.reset();
+
+    LL_RECORD_BLOCK_TIME(FTM_TEXTURE_MEMORY_CHECK);
+
+    if (gGLManager.mHasATIMemInfo)
+    {
+        S32 meminfo[4];
+        glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo);
+        gpu_res = (S32Megabytes)meminfo[0];
+
+        //check main memory, only works for windows.
+        LLMemory::updateMemoryInfo();
+        physical_res = LLMemory::getAvailableMemKB();
+    }
+    else if (gGLManager.mHasNVXMemInfo)
+    {
+        S32 free_memory;
+        glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &free_memory);
+        gpu_res = (S32Megabytes)(free_memory / 1024);
+    }
 
-	return low_mem;
+    gpu = gpu_res;
+    physical = physical_res;
 }
 
 static LLTrace::BlockTimerStatHandle FTM_TEXTURE_UPDATE_MEDIA("Media");
@@ -575,17 +590,18 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity
 	}
 	else if(isMemoryForTextureLow())
 	{
-		// Note: isMemoryForTextureLow() uses 1s delay, make sure we waited enough for it to restore
+		// Note: isMemoryForTextureLow() uses 1s delay, make sure we waited enough for it to recheck
 		if (sEvaluationTimer.getElapsedTimeF32() > GPU_MEMORY_CHECK_WAIT_TIME)
 		{
 			sDesiredDiscardBias += discard_bias_delta;
 			sEvaluationTimer.reset();
 		}
 	}
-	else if (sDesiredDiscardBias > 0.0f &&
-			 sBoundTextureMemory < sMaxBoundTextureMemory * texmem_lower_bound_scale &&
-			 sTotalTextureMemory < sMaxTotalTextureMem * texmem_lower_bound_scale)
-	{			 
+	else if (sDesiredDiscardBias > 0.0f
+			 && sBoundTextureMemory < sMaxBoundTextureMemory * texmem_lower_bound_scale
+			 && sTotalTextureMemory < sMaxTotalTextureMem * texmem_lower_bound_scale
+			 && isMemoryForTextureSuficientlyFree())
+	{
 		// If we are using less texture memory than we should,
 		// scale down the desired discard level
 		if (sEvaluationTimer.getElapsedTimeF32() > discard_delta_time)
@@ -595,14 +611,8 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity
 		}
 	}
 	sDesiredDiscardBias = llclamp(sDesiredDiscardBias, desired_discard_bias_min, desired_discard_bias_max);
-	
-	F32 camera_moving_speed = LLViewerCamera::getInstance()->getAverageSpeed();
-	F32 camera_angular_speed = LLViewerCamera::getInstance()->getAverageAngularSpeed();
-	sCameraMovingBias = llmax(0.2f * camera_moving_speed, 2.0f * camera_angular_speed - 1);
-	sCameraMovingDiscardBias = (S8)(sCameraMovingBias);
 
-	LLViewerTexture::sFreezeImageScalingDown = (sBoundTextureMemory < 0.75f * sMaxBoundTextureMemory * texmem_middle_bound_scale) &&
-				(sTotalTextureMemory < 0.75f * sMaxTotalTextureMem * texmem_middle_bound_scale);
+	LLViewerTexture::sFreezeImageUpdates = sDesiredDiscardBias > (desired_discard_bias_max - 1.0f);
 }
 
 //end of static functions
@@ -3126,9 +3136,9 @@ S8 LLViewerLODTexture::getType() const
 	return LLViewerTexture::LOD_TEXTURE;
 }
 
-BOOL LLViewerLODTexture::isUpdateFrozen()
+bool LLViewerLODTexture::isUpdateFrozen()
 {
-	return LLViewerTexture::sFreezeImageScalingDown && !getDiscardLevel();
+	return LLViewerTexture::sFreezeImageUpdates;
 }
 
 // This is gauranteed to get called periodically for every texture
@@ -3254,9 +3264,16 @@ void LLViewerLODTexture::processTextureStats()
 				(!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel))
 			{
 				scaleDown();
-				
 			}
 		}
+
+		if (isUpdateFrozen() // we are out of memory and nearing max allowed bias
+			&& mBoostLevel < LLGLTexture::BOOST_SCULPTED
+			&& mDesiredDiscardLevel < current_discard)
+		{
+			// stop requesting more
+			mDesiredDiscardLevel = current_discard;
+		}
 	}
 
 	if(mForceToSaveRawImage && mDesiredSavedRawDiscardLevel >= 0)
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index 5d89f9f029..7cbcc931b1 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -186,6 +186,9 @@ private:
 	virtual void switchToCachedImage();
 	
 	static bool isMemoryForTextureLow() ;
+	static bool isMemoryForTextureSuficientlyFree();
+	static void getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &physical);
+
 protected:
 	LLUUID mID;
 	S32 mTextureListType; // along with mID identifies where to search for this texture in TextureList
@@ -227,7 +230,7 @@ public:
 	static S32 sMaxSculptRez ;
 	static S32 sMinLargeImageSize ;
 	static S32 sMaxSmallImageSize ;
-	static BOOL sFreezeImageScalingDown ;//do not scale down image res if set.
+	static bool sFreezeImageUpdates;
 	static F32  sCurrentTime ;
 
 	enum EDebugTexels
@@ -543,7 +546,7 @@ public:
 	/*virtual*/ S8 getType() const;
 	// Process image stats to determine priority/quality requirements.
 	/*virtual*/ void processTextureStats();
-	BOOL isUpdateFrozen() ;
+	bool isUpdateFrozen() ;
 
 private:
 	void init(bool firstinit) ;
-- 
cgit v1.2.3


From 8420e20102006b780d6959ec3d0fa6d905a32f16 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 21 Nov 2018 09:53:45 -0500
Subject: DRTVWR-447: Fix syntax error in embedded variable reference.

---
 indra/newview/installers/windows/lang_ru.nsi | Bin 9188 -> 9186 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)

diff --git a/indra/newview/installers/windows/lang_ru.nsi b/indra/newview/installers/windows/lang_ru.nsi
index a42c719169..d8990fd955 100644
Binary files a/indra/newview/installers/windows/lang_ru.nsi and b/indra/newview/installers/windows/lang_ru.nsi differ
-- 
cgit v1.2.3


From 24872bea74a9275b388a4306091f940ccbf80270 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 21 Nov 2018 09:55:54 -0500
Subject: DRTVWR-447: Fix longstanding NSIS warning about unused label.

---
 indra/newview/installers/windows/installer_template.nsi | 1 -
 1 file changed, 1 deletion(-)

diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index f62a14d65f..355272cd08 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -216,7 +216,6 @@ lbl_configure_default_lang:
     Goto lbl_return
     StrCmp $SKIP_DIALOGS "true" lbl_return
   
-lbl_build_menu:
 	Push ""
 # Use separate file so labels can be UTF-16 but we can still merge changes into this ASCII file. JC
     !include "%%SOURCE%%\installers\windows\language_menu.nsi"
-- 
cgit v1.2.3


From 7ca89229f86aa8c056b45be1b59d221799e56a84 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 21 Nov 2018 12:07:18 -0500
Subject: SL-10077: Save correct uninstall directory and (un)install mode.

Curiously, the value of $INSTDIR is correct before MULTIUSER_UNINIT, but is
made incorrect by MULTIUSER_UNINIT. Save and restore the correct value.

Saving $MultiUser.InstallMode in the registry (by setting relevant macros
examined by MultiUser.nsh) is susceptible to overwriting if the user installs
multiple viewers with the same channel name. Instead, write an InstallMode.txt
in the install directory, and read it back on uninstall. Of course, add it to
the files to be deleted on uninstall.
---
 .../installers/windows/installer_template.nsi      | 48 +++++++++++++++++-----
 1 file changed, 38 insertions(+), 10 deletions(-)

diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index 355272cd08..b2d376d0c0 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -117,9 +117,12 @@ AutoCloseWindow true					# After all files install, close window
 # should make MultiUser.nsh initialization read existing INSTDIR from registry
 !define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY "${INSTNAME_KEY}"
 !define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME ""
-# should make MultiUser.nsh initialization write $MultiUser.InstallMode to registry
-!define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY "${INSTNAME_KEY}"
-!define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME "InstallMode"
+# Don't set MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY and
+# MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME to cause the installer to
+# write $MultiUser.InstallMode to the registry, because when the user installs
+# multiple viewers with the same channel (same ${INSTNAME}, hence same
+# ${INSTNAME_KEY}), the registry entry is overwritten. Instead we'll write a
+# little file into the install directory -- see .onInstSuccess and un.onInit.
 !include MultiUser.nsh
 !include MUI2.nsh
 !define MUI_BGCOLOR FFFFFF
@@ -239,7 +242,21 @@ FunctionEnd
 ;; Prep Uninstaller Section
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 Function un.onInit
-!insertmacro MULTIUSER_UNINIT
+    # Save $INSTDIR -- it appears to have the correct value before
+    # MULTIUSER_UNINIT, but then gets munged by MULTIUSER_UNINIT?!
+    Push $INSTDIR
+    !insertmacro MULTIUSER_UNINIT
+    Pop $INSTDIR
+
+    # Now read InstallMode.txt from $INSTDIR
+    Push $0
+    ClearErrors
+    FileOpen $0 "$INSTDIR\InstallMode.txt" r
+    IfErrors skipread
+    FileRead $0 $MultiUser.InstallMode
+    FileClose $0
+skipread:
+    Pop $0
 
 %%ENGAGEREGISTRY%%
 
@@ -248,10 +265,10 @@ Function un.onInit
     IfErrors lbl_end
 	StrCpy $LANGUAGE $0
 lbl_end:
-    Return
 
-    # Does MultiUser.nsh init read back
-    # MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY into $MultiUser.InstallMode?
+##  MessageBox MB_OK "After restoring:$\n$$INSTDIR = '$INSTDIR'$\n$$MultiUser.InstallMode = '$MultiUser.InstallMode'$\n$$LANGUAGE = '$LANGUAGE'"
+
+    Return
 
 FunctionEnd
 
@@ -417,8 +434,10 @@ StrCpy $INSTSHORTCUT "${SHORTCUT}"
 # MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME
 # Couln't get NSIS to expand $MultiUser.InstallMode into the function name at Call time
 ${If} $MultiUser.InstallMode == 'AllUsers'
+##MessageBox MB_OK "Uninstalling for all users"
   Call un.MultiUser.InstallMode.AllUsers
 ${Else}
+##MessageBox MB_OK "Uninstalling for current user"
   Call un.MultiUser.InstallMode.CurrentUser
 ${EndIf}
 
@@ -626,6 +645,9 @@ Function un.ProgramFiles
 # This placeholder is replaced by the complete list of files to uninstall by viewer_manifest.py
 %%DELETE_FILES%%
 
+# our InstallMode.txt
+Delete "$INSTDIR\InstallMode.txt"
+
 # Optional/obsolete files.  Delete won't fail if they don't exist.
 Delete "$INSTDIR\autorun.bat"
 Delete "$INSTDIR\dronesettings.ini"
@@ -675,7 +697,13 @@ FunctionEnd
 ;; After install completes, launch app
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 Function .onInstSuccess
-        Call CheckWindowsServPack		# Warn if not on the latest SP before asking to launch.
+        Push $0
+        FileOpen $0 "$INSTDIR\InstallMode.txt" w
+        # No newline -- this is for our use, not for users to read.
+        FileWrite $0 "$MultiUser.InstallMode"
+        FileClose $0
+        Pop $0
+
         Push $R0
         Push $0
         ;; MAINT-7812: Only write nsis.winstall file with /marker switch
@@ -694,7 +722,8 @@ Function .onInstSuccess
         ClearErrors
         Pop $0
         Pop $R0
-        Push $R0					# Option value, unused# 
+
+        Call CheckWindowsServPack		# Warn if not on the latest SP before asking to launch.
         StrCmp $SKIP_AUTORUN "true" +2;
         # Assumes SetOutPath $INSTDIR
         # Run INSTEXE (our updater), passing VIEWER_EXE plus the command-line
@@ -711,7 +740,6 @@ Function .onInstSuccess
         # must be a distinct command-line token, but DO NOT quote the language
         # string because it must decompose into separate command-line tokens.
         Exec '"$INSTDIR\$INSTEXE" precheck "$INSTDIR\$VIEWER_EXE" $SHORTCUT_LANG_PARAM'
-        Pop $R0
 # 
 FunctionEnd
 
-- 
cgit v1.2.3


From feb886e08a3cc3ce9a64a16e72cb17b3d5910ab3 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 21 Nov 2018 14:40:12 -0500
Subject: DRTVWR-447: Update to viewer-manager build 521943

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index a51f14b274..5a0194cf86 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3138,9 +3138,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>c543e73c35c605eaf509bc7651c11227</string>
+              <string>15e764eb3a0efefe0eda103c72407ab4</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/27348/219718/viewer_manager-2.0.521526-darwin64-521526.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/27985/227818/viewer_manager-2.0.521943-darwin64-521943.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3162,9 +3162,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>fec612973e0d70f82da8c8f22a10c6f3</string>
+              <string>ea65e1c59d34f19c64fa2a1b32d312ad</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/27349/219725/viewer_manager-2.0.521526-windows-521526.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/27986/227825/viewer_manager-2.0.521943-windows-521943.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3175,7 +3175,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.521526</string>
+        <string>2.0.521943</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From 7d745679cef8fd91394ca97f0d9f1cf252d57782 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Thu, 22 Nov 2018 15:46:59 +0200
Subject: line endings fix

---
 indra/newview/llfloateruipreview.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp
index 4e0b27a4f8..db5a192287 100644
--- a/indra/newview/llfloateruipreview.cpp
+++ b/indra/newview/llfloateruipreview.cpp
@@ -1023,7 +1023,7 @@ void LLFloaterUIPreview::onClickEditFloater()
 void LLFloaterUIPreview::onClickBrowseForEditor()
 {
     // Let the user choose an executable through the file picker dialog box
-    (new LLFilePickerReplyThread(boost::bind(&LLFloaterUIPreview::getExecutablePath, this, _1), LLFilePicker::FFLOAD_EXE, false))->getFile();
+    (new LLFilePickerReplyThread(boost::bind(&LLFloaterUIPreview::getExecutablePath, this, _1), LLFilePicker::FFLOAD_EXE, false))->getFile();
 }
 
 void LLFloaterUIPreview::getExecutablePath(const std::vector<std::string>& filenames)
@@ -1077,7 +1077,7 @@ void LLFloaterUIPreview::getExecutablePath(const std::vector<std::string>& filen
 void LLFloaterUIPreview::onClickBrowseForDiffs()
 {
 	// create load dialog box
-    (new LLFilePickerReplyThread(boost::bind(&LLFloaterUIPreview::getDiffsFilePath, this, _1), LLFilePicker::FFLOAD_XML, false))->getFile();
+    (new LLFilePickerReplyThread(boost::bind(&LLFloaterUIPreview::getDiffsFilePath, this, _1), LLFilePicker::FFLOAD_XML, false))->getFile();
 }
 
 void LLFloaterUIPreview::getDiffsFilePath(const std::vector<std::string>& filenames)
-- 
cgit v1.2.3


From e1c7688b2c69c3a79b673011abe6d59ce97acdff Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Mon, 26 Nov 2018 18:50:40 +0200
Subject: SL-10101 Remade most frequent setting calls to cached variants

---
 indra/newview/llappviewer.cpp       |  6 ++++--
 indra/newview/llmeshrepository.cpp  | 25 ++++++++++++++-----------
 indra/newview/lltool.cpp            |  4 +++-
 indra/newview/llviewermedia.cpp     | 10 ++++++----
 indra/newview/llviewershadermgr.cpp |  3 ++-
 indra/newview/llvovolume.cpp        | 29 ++++++++++++++++++++---------
 indra/newview/llvowlsky.cpp         |  3 ++-
 7 files changed, 51 insertions(+), 29 deletions(-)

diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 4374caacdf..f1af872fb4 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -5439,7 +5439,8 @@ void LLAppViewer::resumeMainloopTimeout(const std::string& state, F32 secs)
 	{
 		if(secs < 0.0f)
 		{
-			secs = gSavedSettings.getF32("MainloopTimeoutDefault");
+			static LLCachedControl<F32> mainloop_timeout(gSavedSettings, "MainloopTimeoutDefault", 60);
+			secs = mainloop_timeout;
 		}
 
 		mMainloopTimeout->setTimeout(secs);
@@ -5466,7 +5467,8 @@ void LLAppViewer::pingMainloopTimeout(const std::string& state, F32 secs)
 	{
 		if(secs < 0.0f)
 		{
-			secs = gSavedSettings.getF32("MainloopTimeoutDefault");
+			static LLCachedControl<F32> mainloop_timeout(gSavedSettings, "MainloopTimeoutDefault", 60);
+			secs = mainloop_timeout;
 		}
 
 		mMainloopTimeout->setTimeout(secs);
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index e38bd8846d..a689a0da0b 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -4302,10 +4302,13 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLSD& header, F32 radius, S32* byte
 	F32 dlow = llmin(radius/0.06f, max_distance);
 	F32 dmid = llmin(radius/0.24f, max_distance);
 	
-	F32 METADATA_DISCOUNT = (F32) gSavedSettings.getU32("MeshMetaDataDiscount");  //discount 128 bytes to cover the cost of LLSD tags and compression domain overhead
-	F32 MINIMUM_SIZE = (F32) gSavedSettings.getU32("MeshMinimumByteSize"); //make sure nothing is "free"
+	static LLCachedControl<U32> metadata_discount_ch(gSavedSettings, "MeshMetaDataDiscount", 384);  //discount 128 bytes to cover the cost of LLSD tags and compression domain overhead
+	static LLCachedControl<U32> minimum_size_ch(gSavedSettings, "MeshMinimumByteSize", 16); //make sure nothing is "free"
+	static LLCachedControl<U32> bytes_per_triangle_ch(gSavedSettings, "MeshBytesPerTriangle", 16);
 
-	F32 bytes_per_triangle = (F32) gSavedSettings.getU32("MeshBytesPerTriangle");
+	F32 metadata_discount = (F32)metadata_discount_ch;
+	F32 minimum_size = (F32)minimum_size_ch;
+	F32 bytes_per_triangle = (F32)bytes_per_triangle_ch;
 
 	S32 bytes_lowest = header["lowest_lod"]["size"].asInteger();
 	S32 bytes_low = header["low_lod"]["size"].asInteger();
@@ -4332,10 +4335,10 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLSD& header, F32 radius, S32* byte
 		bytes_lowest = bytes_low;
 	}
 
-	F32 triangles_lowest = llmax((F32) bytes_lowest-METADATA_DISCOUNT, MINIMUM_SIZE)/bytes_per_triangle;
-	F32 triangles_low = llmax((F32) bytes_low-METADATA_DISCOUNT, MINIMUM_SIZE)/bytes_per_triangle;
-	F32 triangles_mid = llmax((F32) bytes_mid-METADATA_DISCOUNT, MINIMUM_SIZE)/bytes_per_triangle;
-	F32 triangles_high = llmax((F32) bytes_high-METADATA_DISCOUNT, MINIMUM_SIZE)/bytes_per_triangle;
+	F32 triangles_lowest = llmax((F32) bytes_lowest-metadata_discount, minimum_size)/bytes_per_triangle;
+	F32 triangles_low = llmax((F32) bytes_low-metadata_discount, minimum_size)/bytes_per_triangle;
+	F32 triangles_mid = llmax((F32) bytes_mid-metadata_discount, minimum_size)/bytes_per_triangle;
+	F32 triangles_high = llmax((F32) bytes_high-metadata_discount, minimum_size)/bytes_per_triangle;
 
 	if (bytes)
 	{
@@ -4429,13 +4432,13 @@ bool LLMeshCostData::init(const LLSD& header)
     mSizeByLOD[2] = bytes_med;
     mSizeByLOD[3] = bytes_high;
 
-    F32 METADATA_DISCOUNT = (F32) gSavedSettings.getU32("MeshMetaDataDiscount");  //discount 128 bytes to cover the cost of LLSD tags and compression domain overhead
-    F32 MINIMUM_SIZE = (F32) gSavedSettings.getU32("MeshMinimumByteSize"); //make sure nothing is "free"
-    F32 bytes_per_triangle = (F32) gSavedSettings.getU32("MeshBytesPerTriangle");
+    static LLCachedControl<U32> metadata_discount(gSavedSettings, "MeshMetaDataDiscount", 384);  //discount 128 bytes to cover the cost of LLSD tags and compression domain overhead
+    static LLCachedControl<U32> minimum_size(gSavedSettings, "MeshMinimumByteSize", 16); //make sure nothing is "free"
+    static LLCachedControl<U32> bytes_per_triangle(gSavedSettings, "MeshBytesPerTriangle", 16);
 
     for (S32 i=0; i<4; i++)
     {
-        mEstTrisByLOD[i] = llmax((F32) mSizeByLOD[i]-METADATA_DISCOUNT, MINIMUM_SIZE)/bytes_per_triangle; 
+        mEstTrisByLOD[i] = llmax((F32)mSizeByLOD[i] - (F32)metadata_discount, (F32)minimum_size) / (F32)bytes_per_triangle;
     }
 
     return true;
diff --git a/indra/newview/lltool.cpp b/indra/newview/lltool.cpp
index 4aad650b68..b5d78f3654 100644
--- a/indra/newview/lltool.cpp
+++ b/indra/newview/lltool.cpp
@@ -191,7 +191,9 @@ LLTool* LLTool::getOverrideTool(MASK mask)
 	{
 		return NULL;
 	}
-	if (gSavedSettings.getBOOL("EnableAltZoom"))
+
+	static LLCachedControl<bool> alt_zoom(gSavedSettings, "EnableAltZoom", true);
+	if (alt_zoom)
 	{
 		if (mask & MASK_ALT)
 		{
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 22a21c9ca3..f4e1524371 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -682,8 +682,8 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
 
 	std::vector<LLViewerMediaImpl*> proximity_order;
 
-	bool inworld_media_enabled = gSavedSettings.getBOOL("AudioStreamingMedia");
-	bool inworld_audio_enabled = gSavedSettings.getBOOL("AudioStreamingMusic");
+	static LLCachedControl<bool> inworld_media_enabled(gSavedSettings, "AudioStreamingMedia", true);
+	static LLCachedControl<bool> inworld_audio_enabled(gSavedSettings, "AudioStreamingMusic", true);
 	U32 max_instances = gSavedSettings.getU32("PluginInstancesTotal");
 	U32 max_normal = gSavedSettings.getU32("PluginInstancesNormal");
 	U32 max_low = gSavedSettings.getU32("PluginInstancesLow");
@@ -941,7 +941,8 @@ void LLViewerMedia::setAllMediaEnabled(bool val)
 			LLViewerParcelMedia::play(LLViewerParcelMgr::getInstance()->getAgentParcel());
 		}
 
-		if (gSavedSettings.getBOOL("AudioStreamingMusic") &&
+		static LLCachedControl<bool> audio_streaming_music(gSavedSettings, "AudioStreamingMusic", true);
+		if (audio_streaming_music &&
 			!LLViewerMedia::isParcelAudioPlaying() &&
 			gAudiop &&
 			LLViewerMedia::hasParcelAudio())
@@ -1012,7 +1013,8 @@ void LLViewerMedia::setAllMediaPaused(bool val)
             LLViewerParcelMedia::play(LLViewerParcelMgr::getInstance()->getAgentParcel());
         }
 
-        if (gSavedSettings.getBOOL("AudioStreamingMusic") &&
+        static LLCachedControl<bool> audio_streaming_music(gSavedSettings, "AudioStreamingMusic", true);
+        if (audio_streaming_music &&
             !LLViewerMedia::isParcelAudioPlaying() &&
             gAudiop &&
             LLViewerMedia::hasParcelAudio())
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index ff7647a7e4..f610335b07 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -399,7 +399,8 @@ void LLViewerShaderMgr::setShaders()
 		return;
 	}
 
-	LLGLSLShader::sIndexedTextureChannels = llmax(llmin(gGLManager.mNumTextureImageUnits, (S32) gSavedSettings.getU32("RenderMaxTextureIndex")), 1);
+	static LLCachedControl<U32> max_texture_index(gSavedSettings, "RenderMaxTextureIndex", 16);
+	LLGLSLShader::sIndexedTextureChannels = llmax(llmin(gGLManager.mNumTextureImageUnits, (S32) max_texture_index), 1);
 
 	//NEVER use more than 16 texture channels (work around for prevalent driver bug)
 	LLGLSLShader::sIndexedTextureChannels = llmin(LLGLSLShader::sIndexedTextureChannels, 16);
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 24726e61e8..3c487a112e 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -1380,7 +1380,8 @@ BOOL LLVOVolume::calcLOD()
     mLODDistance = distance;
     mLODRadius = radius;
 
-    if (gSavedSettings.getBOOL("DebugObjectLODs"))
+    static LLCachedControl<bool> debug_lods(gSavedSettings, "DebugObjectLODs", false);
+    if (debug_lods)
     {
         if (getAvatar() && isRootEdit())
         {
@@ -4276,10 +4277,16 @@ F32 LLVOVolume::getBinRadius()
 	
 	F32 scale = 1.f;
 
-	S32 size_factor = llmax(gSavedSettings.getS32("OctreeStaticObjectSizeFactor"), 1);
-	S32 attachment_size_factor = llmax(gSavedSettings.getS32("OctreeAttachmentSizeFactor"), 1);
-	LLVector3 distance_factor = gSavedSettings.getVector3("OctreeDistanceFactor");
-	LLVector3 alpha_distance_factor = gSavedSettings.getVector3("OctreeAlphaDistanceFactor");
+	static LLCachedControl<S32> octree_size_factor(gSavedSettings, "OctreeStaticObjectSizeFactor", 3);
+	static LLCachedControl<S32> octree_attachment_size_factor(gSavedSettings, "OctreeAttachmentSizeFactor", 4);
+	static LLCachedControl<LLVector3> octree_distance_factor(gSavedSettings, "OctreeDistanceFactor", LLVector3(0.01f, 0.f, 0.f));
+	static LLCachedControl<LLVector3> octree_alpha_distance_factor(gSavedSettings, "OctreeAlphaDistanceFactor", LLVector3(0.1f, 0.f, 0.f));
+
+	S32 size_factor = llmax((S32)octree_size_factor, 1);
+	S32 attachment_size_factor = llmax((S32)octree_attachment_size_factor, 1);
+	LLVector3 distance_factor = octree_distance_factor;
+	LLVector3 alpha_distance_factor = octree_alpha_distance_factor;
+
 	const LLVector4a* ext = mDrawable->getSpatialExtents();
 	
 	BOOL shrink_wrap = mDrawable->isAnimating();
@@ -5352,8 +5359,10 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
 
 	U32 useage = group->getSpatialPartition()->mBufferUsage;
 
-	U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask);
-	U32 max_total = (gSavedSettings.getS32("RenderMaxNodeSize")*1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask);
+	LLCachedControl<S32> max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512);
+	LLCachedControl<S32> max_node_size(gSavedSettings, "RenderMaxNodeSize", 65536);
+	U32 max_vertices = (max_vbo_size * 1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask);
+	U32 max_total = (max_node_size * 1024) / LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask);
 	max_vertices = llmin(max_vertices, (U32) 65535);
 
 	U32 cur_total = 0;
@@ -6106,7 +6115,8 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
 #endif
 	
 	//calculate maximum number of vertices to store in a single buffer
-	U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask);
+	LLCachedControl<S32> max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512);
+	U32 max_vertices = (max_vbo_size * 1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask);
 	max_vertices = llmin(max_vertices, (U32) 65535);
 
 	{
@@ -6149,7 +6159,8 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
 		texture_index_channels = gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels;
 	}
 
-	texture_index_channels = llmin(texture_index_channels, (S32) gSavedSettings.getU32("RenderMaxTextureIndex"));
+	static LLCachedControl<U32> max_texture_index(gSavedSettings, "RenderMaxTextureIndex", 16);
+	texture_index_channels = llmin(texture_index_channels, (S32) max_texture_index);
 	
 	//NEVER use more than 16 texture index channels (workaround for prevalent driver bug)
 	texture_index_channels = llmin(texture_index_channels, 16);
diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp
index 3b9b96e9f1..2cb5fc81b0 100644
--- a/indra/newview/llvowlsky.cpp
+++ b/indra/newview/llvowlsky.cpp
@@ -335,7 +335,8 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable)
 	}
 
 	{
-		const U32 max_buffer_bytes = gSavedSettings.getS32("RenderMaxVBOSize")*1024;
+		LLCachedControl<S32> max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512);
+		const U32 max_buffer_bytes = max_vbo_size * 1024;
 		const U32 data_mask = LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK;
 		const U32 max_verts = max_buffer_bytes / LLVertexBuffer::calcVertexSize(data_mask);
 
-- 
cgit v1.2.3


From c7a7503b2ccebda39a48a1164bf07e4541fd8d2b Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Tue, 27 Nov 2018 18:51:53 +0200
Subject: SL-10096 ParcelPropertiesRequest is sent too often when terraforming
 or hover tooltips are On

---
 indra/newview/llviewerparcelmgr.cpp     | 121 +++++++++++++++++++++++---------
 indra/newview/llviewerparceloverlay.cpp |  17 +++++
 indra/newview/llviewerparceloverlay.h   |   2 +
 3 files changed, 107 insertions(+), 33 deletions(-)

diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index 5477d2d444..416d5d8e2e 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -1331,22 +1331,18 @@ void LLViewerParcelMgr::sendParcelPropertiesUpdate(LLParcel* parcel, bool use_ag
 void LLViewerParcelMgr::setHoverParcel(const LLVector3d& pos)
 {
 	static U32 last_west, last_south;
-
+	static LLUUID last_region;
 
 	// only request parcel info if position has changed outside of the
 	// last parcel grid step
-	U32 west_parcel_step = (U32) floor( pos.mdV[VX] / PARCEL_GRID_STEP_METERS );
-	U32 south_parcel_step = (U32) floor( pos.mdV[VY] / PARCEL_GRID_STEP_METERS );
-	
+	const U32 west_parcel_step = (U32) floor( pos.mdV[VX] / PARCEL_GRID_STEP_METERS );
+	const U32 south_parcel_step = (U32) floor( pos.mdV[VY] / PARCEL_GRID_STEP_METERS );
+
 	if ((west_parcel_step == last_west) && (south_parcel_step == last_south))
 	{
+		// We are staying in same segment
 		return;
 	}
-	else 
-	{
-		last_west = west_parcel_step;
-		last_south = south_parcel_step;
-	}
 
 	LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( pos );
 	if (!region)
@@ -1354,36 +1350,95 @@ void LLViewerParcelMgr::setHoverParcel(const LLVector3d& pos)
 		return;
 	}
 
-	LL_DEBUGS("ParcelMgr") << "Requesting parcel properties on hover, for " << pos << LL_ENDL;
+	LLUUID region_id = region->getRegionID();
+	LLVector3 pos_in_region = region->getPosRegionFromGlobal(pos);
+
+	bool request_properties = false;
+	if (region_id != last_region)
+	{
+		request_properties = true;
+	}
+	else
+	{
+		// Check if new position is in same parcel.
+		// This check is not ideal, since it checks by way of straight lines.
+		// So sometimes (small parcel in the middle of large one) it can
+		// decide that parcel actually changed, but it still allows to 
+		// reduce amount of requests significantly
+
+		S32 west_parcel_local = (S32)(pos_in_region.mV[VX] / PARCEL_GRID_STEP_METERS);
+		S32 south_parcel_local = (S32)(pos_in_region.mV[VY] / PARCEL_GRID_STEP_METERS);
+
+		LLViewerParcelOverlay* overlay = region->getParcelOverlay();
+		if (!overlay)
+		{
+			 request_properties = true;
+		}
+		while (!request_properties && west_parcel_step < last_west)
+		{
+			S32 segment_shift = last_west - west_parcel_step;
+			request_properties = overlay->parcelLineFlags(south_parcel_local, west_parcel_local + segment_shift) & PARCEL_WEST_LINE;
+			last_west--;
+		}
+		while (!request_properties && south_parcel_step < last_south)
+		{
+			S32 segment_shift = last_south - south_parcel_step;
+			request_properties = overlay->parcelLineFlags(south_parcel_local + segment_shift, west_parcel_local) & PARCEL_SOUTH_LINE;
+			last_south--;
+		}
+		// Note: could have just swapped values, reused first two 'while' and set last_south, last_west separately,
+		// but this looks to be easier to understand/straightforward/less bulky
+		while (!request_properties && west_parcel_step > last_west)
+		{
+			S32 segment_shift = west_parcel_step - last_west;
+			request_properties = overlay->parcelLineFlags(south_parcel_local, west_parcel_local - segment_shift + 1) & PARCEL_WEST_LINE;
+			last_west++;
+		}
+		while (!request_properties && south_parcel_step > last_south)
+		{
+			S32 segment_shift = south_parcel_step - last_south;
+			request_properties = overlay->parcelLineFlags(south_parcel_local - segment_shift + 1, west_parcel_local) & PARCEL_SOUTH_LINE;
+			last_south++;
+		}
+
+		// if (!request_properties) last_south and last_west will be equal to new values
+	}
+
+	if (request_properties)
+	{
+		last_west = west_parcel_step;
+		last_south = south_parcel_step;
+		last_region = region_id;
 
+		LL_DEBUGS("ParcelMgr") << "Requesting parcel properties on hover, for " << pos << LL_ENDL;
 
-	// Send a rectangle around the point.
-	// This means the parcel sent back is at least a rectangle around the point,
-	// which is more efficient for public land.  Fewer requests are sent.  JC
-	LLVector3 wsb_region = region->getPosRegionFromGlobal( pos );
 
-	F32 west  = PARCEL_GRID_STEP_METERS * floor( wsb_region.mV[VX] / PARCEL_GRID_STEP_METERS );
-	F32 south = PARCEL_GRID_STEP_METERS * floor( wsb_region.mV[VY] / PARCEL_GRID_STEP_METERS );
+		// Send a rectangle around the point.
+		// This means the parcel sent back is at least a rectangle around the point,
+		// which is more efficient for public land.  Fewer requests are sent.  JC
+		F32 west = PARCEL_GRID_STEP_METERS * floor(pos_in_region.mV[VX] / PARCEL_GRID_STEP_METERS);
+		F32 south = PARCEL_GRID_STEP_METERS * floor(pos_in_region.mV[VY] / PARCEL_GRID_STEP_METERS);
 
-	F32 east  = west  + PARCEL_GRID_STEP_METERS;
-	F32 north = south + PARCEL_GRID_STEP_METERS;
+		F32 east = west + PARCEL_GRID_STEP_METERS;
+		F32 north = south + PARCEL_GRID_STEP_METERS;
 
-	// Send request message
-	LLMessageSystem *msg = gMessageSystem;
-	msg->newMessageFast(_PREHASH_ParcelPropertiesRequest);
-	msg->nextBlockFast(_PREHASH_AgentData);
-	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
-	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
-	msg->nextBlockFast(_PREHASH_ParcelData);
-	msg->addS32Fast(_PREHASH_SequenceID,	HOVERED_PARCEL_SEQ_ID );
-	msg->addF32Fast(_PREHASH_West,			west );
-	msg->addF32Fast(_PREHASH_South,			south );
-	msg->addF32Fast(_PREHASH_East,			east );
-	msg->addF32Fast(_PREHASH_North,			north );
-	msg->addBOOL("SnapSelection",			FALSE );
-	msg->sendReliable( region->getHost() );
+		// Send request message
+		LLMessageSystem *msg = gMessageSystem;
+		msg->newMessageFast(_PREHASH_ParcelPropertiesRequest);
+		msg->nextBlockFast(_PREHASH_AgentData);
+		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+		msg->nextBlockFast(_PREHASH_ParcelData);
+		msg->addS32Fast(_PREHASH_SequenceID, HOVERED_PARCEL_SEQ_ID);
+		msg->addF32Fast(_PREHASH_West, west);
+		msg->addF32Fast(_PREHASH_South, south);
+		msg->addF32Fast(_PREHASH_East, east);
+		msg->addF32Fast(_PREHASH_North, north);
+		msg->addBOOL("SnapSelection", FALSE);
+		msg->sendReliable(region->getHost());
 
-	mHoverRequestResult = PARCEL_RESULT_NO_DATA;
+		mHoverRequestResult = PARCEL_RESULT_NO_DATA;
+	}
 }
 
 
diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp
index 4fd423b6f4..7c3dd00e1a 100644
--- a/indra/newview/llviewerparceloverlay.cpp
+++ b/indra/newview/llviewerparceloverlay.cpp
@@ -274,6 +274,23 @@ U8 LLViewerParcelOverlay::ownership( const LLVector3& pos) const
 	return ownership(row, column);
 }
 
+U8 LLViewerParcelOverlay::parcelLineFlags(const LLVector3& pos) const
+{
+    S32 row = S32(pos.mV[VY] / PARCEL_GRID_STEP_METERS);
+    S32 column = S32(pos.mV[VX] / PARCEL_GRID_STEP_METERS);
+    return parcelLineFlags(row, column);
+}
+U8 LLViewerParcelOverlay::parcelLineFlags(S32 row, S32 col) const
+{
+    U8 flags = PARCEL_WEST_LINE | PARCEL_SOUTH_LINE;
+    if (row > mParcelGridsPerEdge || col > mParcelGridsPerEdge)
+    {
+        LL_WARNS() << "Attempted to get ownership out of region's overlay, row: " << row << " col: " << col << LL_ENDL;
+        return flags;
+    }
+    return mOwnership[row * mParcelGridsPerEdge + col] & flags;
+}
+
 F32 LLViewerParcelOverlay::getOwnedRatio() const
 {
 	S32	size = mParcelGridsPerEdge * mParcelGridsPerEdge;
diff --git a/indra/newview/llviewerparceloverlay.h b/indra/newview/llviewerparceloverlay.h
index 14a2af5354..e30dbf17b3 100644
--- a/indra/newview/llviewerparceloverlay.h
+++ b/indra/newview/llviewerparceloverlay.h
@@ -71,6 +71,8 @@ public:
 	S32				renderPropertyLines();
 
 	U8				ownership( const LLVector3& pos) const;
+	U8				parcelLineFlags( const LLVector3& pos) const;
+	U8				parcelLineFlags(S32 row, S32 col) const;
 
 	// MANIPULATE
 	void	uncompressLandOverlay(S32 chunk, U8 *compressed_overlay);
-- 
cgit v1.2.3


From e2442851c61ad645020d78be8ae0c7c851024758 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Tue, 27 Nov 2018 20:07:41 +0200
Subject: SL-10080 Limit LOD factor to 4

---
 indra/newview/llappviewer.cpp     | 6 +++---
 indra/newview/llviewercontrol.cpp | 6 +++---
 indra/newview/llvovolume.h        | 2 ++
 3 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index f1af872fb4..bd45f68a5c 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -568,12 +568,12 @@ static void settings_to_globals()
 	LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO");
 	LLImageGL::sGlobalUseAnisotropic	= gSavedSettings.getBOOL("RenderAnisotropic");
 	LLImageGL::sCompressTextures		= gSavedSettings.getBOOL("RenderCompressTextures");
-	LLVOVolume::sLODFactor				= gSavedSettings.getF32("RenderVolumeLODFactor");
+	LLVOVolume::sLODFactor				= llmin(gSavedSettings.getF32("RenderVolumeLODFactor"), MAX_LOD_FACTOR);
 	LLVOVolume::sDistanceFactor			= 1.f-LLVOVolume::sLODFactor * 0.1f;
 	LLVolumeImplFlexible::sUpdateFactor = gSavedSettings.getF32("RenderFlexTimeFactor");
 	LLVOTree::sTreeFactor				= gSavedSettings.getF32("RenderTreeLODFactor");
-	LLVOAvatar::sLODFactor				= gSavedSettings.getF32("RenderAvatarLODFactor");
-	LLVOAvatar::sPhysicsLODFactor		= gSavedSettings.getF32("RenderAvatarPhysicsLODFactor");
+	LLVOAvatar::sLODFactor				= llmin(gSavedSettings.getF32("RenderAvatarLODFactor"), MAX_LOD_FACTOR);
+	LLVOAvatar::sPhysicsLODFactor		= llmin(gSavedSettings.getF32("RenderAvatarPhysicsLODFactor"), MAX_LOD_FACTOR);
 	LLVOAvatar::updateImpostorRendering(gSavedSettings.getU32("RenderAvatarMaxNonImpostors"));
 	LLVOAvatar::sVisibleInFirstPerson	= gSavedSettings.getBOOL("FirstPersonAvatarVisible");
 	// clamp auto-open time to some minimum usable value
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 88984d518a..e62d6eb951 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -219,20 +219,20 @@ static bool handleAnisotropicChanged(const LLSD& newvalue)
 
 static bool handleVolumeLODChanged(const LLSD& newvalue)
 {
-	LLVOVolume::sLODFactor = (F32) newvalue.asReal();
+	LLVOVolume::sLODFactor = llmin((F32) newvalue.asReal(), MAX_LOD_FACTOR);
 	LLVOVolume::sDistanceFactor = 1.f-LLVOVolume::sLODFactor * 0.1f;
 	return true;
 }
 
 static bool handleAvatarLODChanged(const LLSD& newvalue)
 {
-	LLVOAvatar::sLODFactor = (F32) newvalue.asReal();
+	LLVOAvatar::sLODFactor = llmin((F32) newvalue.asReal(), MAX_LOD_FACTOR);
 	return true;
 }
 
 static bool handleAvatarPhysicsLODChanged(const LLSD& newvalue)
 {
-	LLVOAvatar::sPhysicsLODFactor = (F32) newvalue.asReal();
+	LLVOAvatar::sPhysicsLODFactor = llmin((F32) newvalue.asReal(), MAX_LOD_FACTOR);
 	return true;
 }
 
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 0882fc095d..13db9c39b7 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -54,6 +54,8 @@ enum LLVolumeInterfaceType
 	INTERFACE_FLEXIBLE = 1,
 };
 
+const F32 MAX_LOD_FACTOR = 4.0f;
+
 
 class LLRiggedVolume : public LLVolume
 {
-- 
cgit v1.2.3


From a5b624fe3aac98655a0fec23044e7fbf6326c4db Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 27 Nov 2018 17:28:21 -0500
Subject: SL-10030: Update to viewer-manager build 522023

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 5a0194cf86..553b8ade24 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3138,9 +3138,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>15e764eb3a0efefe0eda103c72407ab4</string>
+              <string>7f4af59da23c015cd9cfcdd567a5966d</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/27985/227818/viewer_manager-2.0.521943-darwin64-521943.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28113/229287/viewer_manager-2.0.522023-darwin64-522023.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3162,9 +3162,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>ea65e1c59d34f19c64fa2a1b32d312ad</string>
+              <string>105a3eb51d99cbf6fcf4f65a7f1c3f31</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/27986/227825/viewer_manager-2.0.521943-windows-521943.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28114/229293/viewer_manager-2.0.522023-windows-522023.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3175,7 +3175,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.521943</string>
+        <string>2.0.522023</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From c54d3eaa7d63ca7f864886544abe68f9be1441e5 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 28 Nov 2018 07:11:21 -0500
Subject: SL-10030: Update to viewer-manager build 522036

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 553b8ade24..b474265f40 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3138,9 +3138,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>7f4af59da23c015cd9cfcdd567a5966d</string>
+              <string>aa6b3ad6366967f546c9144456b8f58a</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28113/229287/viewer_manager-2.0.522023-darwin64-522023.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28129/229691/viewer_manager-2.0.522036-darwin64-522036.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3162,9 +3162,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>105a3eb51d99cbf6fcf4f65a7f1c3f31</string>
+              <string>958221ef0fd6d542f7c12d18383ec34a</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28114/229293/viewer_manager-2.0.522023-windows-522023.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28130/229697/viewer_manager-2.0.522036-windows-522036.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3175,7 +3175,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.522023</string>
+        <string>2.0.522036</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From 58634033918b2be86534120e08d3b49a4ebcef5a Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 28 Nov 2018 15:59:06 -0500
Subject: SL-10030: Update to viewer-manager build 522055

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index b474265f40..2d63f2e3ab 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3138,9 +3138,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>aa6b3ad6366967f546c9144456b8f58a</string>
+              <string>499b1cfb532786a4dee27d68e84c928b</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28129/229691/viewer_manager-2.0.522036-darwin64-522036.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28164/229888/viewer_manager-2.0.522055-darwin64-522055.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3162,9 +3162,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>958221ef0fd6d542f7c12d18383ec34a</string>
+              <string>220eba0d32d7ad14c783aa1e09e5e7e9</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28130/229697/viewer_manager-2.0.522036-windows-522036.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28165/229894/viewer_manager-2.0.522055-windows-522055.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3175,7 +3175,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.522036</string>
+        <string>2.0.522055</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From 31b6d83606daff4dfcb18ead9db4a0d5a6b82c74 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 28 Nov 2018 16:00:27 -0500
Subject: SL-10030: Include nextviewer.bat in the Windows install directory.

---
 indra/newview/viewer_manifest.py | 1 +
 1 file changed, 1 insertion(+)

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 32773b2c36..4e8df5ce29 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -498,6 +498,7 @@ class WindowsManifest(ViewerManifest):
             with self.prefix(src=os.path.join(pkgdir, "VMP")):
                 # include the compiled launcher scripts so that it gets included in the file_list
                 self.path('SLVersionChecker.exe')
+                self.path('nextviewer.bat')
 
             with self.prefix(dst="vmp_icons"):
                 with self.prefix(src=self.icon_path()):
-- 
cgit v1.2.3


From ed5dfb0b2f8dfc4f5163fed324909c0c012df391 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 28 Nov 2018 18:32:48 -0500
Subject: SL-10030: Update to viewer-manager build 522068

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 2d63f2e3ab..9e1a54dca3 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3138,9 +3138,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>499b1cfb532786a4dee27d68e84c928b</string>
+              <string>3fb7877981cf1ca6a79addf2e279a751</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28164/229888/viewer_manager-2.0.522055-darwin64-522055.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28187/230154/viewer_manager-2.0.522068-darwin64-522068.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3162,9 +3162,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>220eba0d32d7ad14c783aa1e09e5e7e9</string>
+              <string>59e9894657f0175a5c84b459098584b9</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28165/229894/viewer_manager-2.0.522055-windows-522055.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28188/230160/viewer_manager-2.0.522068-windows-522068.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3175,7 +3175,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.522055</string>
+        <string>2.0.522068</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From ff802c5cd20d299c773cf58cb75ff8d62aec1c11 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 28 Nov 2018 22:02:50 -0500
Subject: SL-10030: Update to viewer-manager build 522079

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 9e1a54dca3..5dfab783d6 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3138,9 +3138,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>3fb7877981cf1ca6a79addf2e279a751</string>
+              <string>1859ebf1b12485211ef4243b48c19410</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28187/230154/viewer_manager-2.0.522068-darwin64-522068.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28203/230495/viewer_manager-2.0.522079-darwin64-522079.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3162,9 +3162,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>59e9894657f0175a5c84b459098584b9</string>
+              <string>e6251d211ac0b5b4258c3a04fd5f3ffe</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28188/230160/viewer_manager-2.0.522068-windows-522068.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28204/230501/viewer_manager-2.0.522079-windows-522079.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3175,7 +3175,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.522068</string>
+        <string>2.0.522079</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From f3b2ac0858e1dff226892e25cd1cebbe98a225a3 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Thu, 29 Nov 2018 18:38:47 +0200
Subject: SL-10135 Change group notices to show as SLT

---
 indra/newview/llnotificationlistitem.cpp                 | 11 ++++++-----
 indra/newview/lltoastgroupnotifypanel.cpp                | 16 ++++++++--------
 indra/newview/skins/default/xui/en/language_settings.xml |  1 +
 3 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/indra/newview/llnotificationlistitem.cpp b/indra/newview/llnotificationlistitem.cpp
index a5bc75e6bd..b405d3dca2 100644
--- a/indra/newview/llnotificationlistitem.cpp
+++ b/indra/newview/llnotificationlistitem.cpp
@@ -135,7 +135,8 @@ std::string LLNotificationListItem::buildNotificationDate(const LLDate& time_sta
 			   	+LLTrans::getString("TimeDay")+"]/["
 				+LLTrans::getString("TimeYear")+"] ["
 				+LLTrans::getString("TimeHour")+"]:["
-				+LLTrans::getString("TimeMin")+"]";
+				+LLTrans::getString("TimeMin")+"] ["
+				+LLTrans::getString("TimeTimezone")+"]";
 			break;
 	}
     LLSD substitution;
@@ -376,13 +377,13 @@ BOOL LLGroupNoticeNotificationListItem::postBuild()
     mTitleBoxExp->setValue(mParams.subject);
     mNoticeTextExp->setValue(mParams.message);
 
-    mTimeBox->setValue(buildNotificationDate(mParams.time_stamp, UTC));
-    mTimeBoxExp->setValue(buildNotificationDate(mParams.time_stamp, UTC));
+    mTimeBox->setValue(buildNotificationDate(mParams.time_stamp));
+    mTimeBoxExp->setValue(buildNotificationDate(mParams.time_stamp));
     //Workaround: in case server timestamp is 0 - we use the time when notification was actually received
     if (mParams.time_stamp.isNull())
     {
-        mTimeBox->setValue(buildNotificationDate(mParams.received_time, UTC));
-        mTimeBoxExp->setValue(buildNotificationDate(mParams.received_time, UTC));
+        mTimeBox->setValue(buildNotificationDate(mParams.received_time));
+        mTimeBoxExp->setValue(buildNotificationDate(mParams.received_time));
     }
     setSender(mParams.sender);
 
diff --git a/indra/newview/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp
index f7dc32d0d7..817d1dd7b4 100644
--- a/indra/newview/lltoastgroupnotifypanel.cpp
+++ b/indra/newview/lltoastgroupnotifypanel.cpp
@@ -84,14 +84,14 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(const LLNotificationPtr& notifi
 	//message body
 	const std::string& message = payload["message"].asString();
 
-	std::string timeStr = "["+LLTrans::getString("UTCTimeWeek")+"],["
-							+LLTrans::getString("UTCTimeDay")+"] ["
-							+LLTrans::getString("UTCTimeMth")+"] ["
-							+LLTrans::getString("UTCTimeYr")+"] ["
-							+LLTrans::getString("UTCTimeHr")+"]:["
-							+LLTrans::getString("UTCTimeMin")+"]:["
-							+LLTrans::getString("UTCTimeSec")+"] ["
-							+LLTrans::getString("UTCTimeTimezone")+"]";
+	std::string timeStr = "[" + LLTrans::getString("TimeWeek") + "], ["
+							  + LLTrans::getString("TimeMonth") + "]/["
+							  + LLTrans::getString("TimeDay") + "]/["
+							  + LLTrans::getString("TimeYear") + "] ["
+							  + LLTrans::getString("TimeHour") + "]:["
+							  + LLTrans::getString("TimeMin") + "] ["
+							  + LLTrans::getString("TimeTimezone") + "]";
+
 	const LLDate timeStamp = notification->getDate();
 	LLDate notice_date = timeStamp.notNull() ? timeStamp : payload["received_time"].asDate();
 	LLSD substitution;
diff --git a/indra/newview/skins/default/xui/en/language_settings.xml b/indra/newview/skins/default/xui/en/language_settings.xml
index 51779e4bfd..d418fc38e3 100644
--- a/indra/newview/skins/default/xui/en/language_settings.xml
+++ b/indra/newview/skins/default/xui/en/language_settings.xml
@@ -42,6 +42,7 @@
 	<string name="TimeWeek">wkday,datetime,slt</string>
 	<string name="TimeAMPM">ampm,datetime,slt</string>
 	<string name="TimeHour12">hour12,datetime,slt</string>	
+	<string name="TimeTimezone">timezone,datetime,slt</string>
 
 	<string name="LTimeMthNum">mthnum,datetime,local</string>
 	<string name="LTimeWeek">wkday,datetime,local</string>
-- 
cgit v1.2.3


From 13f8cfd1c27a5ca0d9b66a38cbe11fc96a123a8c Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Thu, 29 Nov 2018 19:25:00 +0200
Subject: SL-9954 Mac Viewer crashes if logcontrol-dev.xml is modified

---
 indra/llcommon/llerror.cpp | 48 +++++++++++++++++++++++++++++-----------------
 1 file changed, 30 insertions(+), 18 deletions(-)

diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index 40eb7d9bac..17d8164289 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -382,15 +382,22 @@ namespace
 
 		{
 			llifstream file(filename().c_str());
-			if (file.is_open())
+			if (!file.is_open())
 			{
-				LLSDSerialize::fromXML(configuration, file);
+				LL_WARNS() << filename() << " failed to open file; not changing configuration" << LL_ENDL;
+				return false;
+			}
+
+			if (LLSDSerialize::fromXML(configuration, file) == LLSDParser::PARSE_FAILURE)
+			{
+				LL_WARNS() << filename() << " parcing error; not changing configuration" << LL_ENDL;
+				return false;
 			}
 
-			if (configuration.isUndefined())
+			if (configuration.isUndefined() || !configuration.isMap() || configuration.emptyMap())
 			{
-				LL_WARNS() << filename() << " missing, ill-formed,"
-							" or simply undefined; not changing configuration"
+				LL_WARNS() << filename() << " missing, ill-formed, or simply undefined"
+							" content; not changing configuration"
 						<< LL_ENDL;
 				return false;
 			}
@@ -856,19 +863,24 @@ namespace LLError
             setEnabledLogTypesMask(config["enabled-log-types-mask"].asInteger());
         }
         
-		LLSD sets = config["settings"];
-		LLSD::array_const_iterator a, end;
-		for (a = sets.beginArray(), end = sets.endArray(); a != end; ++a)
-		{
-			const LLSD& entry = *a;
-			
-			ELevel level = decodeLevel(entry["level"]);
-			
-			setLevels(s->mFunctionLevelMap,	entry["functions"],	level);
-			setLevels(s->mClassLevelMap,	entry["classes"],	level);
-			setLevels(s->mFileLevelMap,		entry["files"],		level);
-			setLevels(s->mTagLevelMap,		entry["tags"],		level);
-		}
+        if (config.has("settings") && config["settings"].isArray())
+        {
+            LLSD sets = config["settings"];
+            LLSD::array_const_iterator a, end;
+            for (a = sets.beginArray(), end = sets.endArray(); a != end; ++a)
+            {
+                const LLSD& entry = *a;
+                if (entry.isMap() && !entry.emptyMap())
+                {
+                    ELevel level = decodeLevel(entry["level"]);
+
+                    setLevels(s->mFunctionLevelMap, entry["functions"], level);
+                    setLevels(s->mClassLevelMap, entry["classes"], level);
+                    setLevels(s->mFileLevelMap, entry["files"], level);
+                    setLevels(s->mTagLevelMap, entry["tags"], level);
+                }
+            }
+        }
 	}
 }
 
-- 
cgit v1.2.3


From d9fdb948d9b7d7b873ec83c43332f97018573194 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Thu, 29 Nov 2018 21:04:35 +0200
Subject: SL-9747 [Mesh Uploader] Remove confusing model_metric from upload

---
 indra/llprimitive/llmodel.h                        |  3 ---
 indra/newview/llfloatermodelpreview.cpp            |  3 ---
 indra/newview/llmeshrepository.cpp                 | 14 +----------
 .../skins/default/xui/en/floater_model_preview.xml | 29 ----------------------
 4 files changed, 1 insertion(+), 48 deletions(-)

diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h
index cf3288489a..51fa2f8079 100644
--- a/indra/llprimitive/llmodel.h
+++ b/indra/llprimitive/llmodel.h
@@ -154,7 +154,6 @@ public:
 	void ClearFacesAndMaterials() { mVolumeFaces.clear(); mMaterialList.clear(); }
 
 	std::string getName() const;
-	std::string getMetric() const {return mMetric;}
 	EModelStatus getStatus() const {return mStatus;}
 	static std::string getStatusString(U32 status) ;
 
@@ -260,8 +259,6 @@ public:
 	std::string mRequestedLabel; // name requested in UI, if any.
 	std::string mLabel; // name computed from dae.
 
-	std::string mMetric; // user-supplied metric data for upload
-
 	LLVector3 mNormalizedScale;
 	LLVector3 mNormalizedTranslation;
 
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 268c646719..818d364c3e 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -1418,8 +1418,6 @@ void LLModelPreview::rebuildUploadData()
 
 	std::string requested_name = mFMP->getChild<LLUICtrl>("description_form")->getValue().asString();
 
-	std::string metric = mFMP->getChild<LLUICtrl>("model_category_combo")->getValue().asString();
-
 	LLSpinCtrl* scale_spinner = mFMP->getChild<LLSpinCtrl>("import_scale");
 
 	F32 scale = scale_spinner->getValue().asReal();
@@ -1460,7 +1458,6 @@ void LLModelPreview::rebuildUploadData()
 			if (base_model && !requested_name.empty())
 			{
 				base_model->mRequestedLabel = requested_name;
-				base_model->mMetric = metric;
 			}
 
 			for (int i = LLModel::NUM_LODS - 1; i >= LLModel::LOD_IMPOSTOR; i--)
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index a689a0da0b..f32dad7f55 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -2174,7 +2174,6 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
 
 	std::map<LLModel*,S32> mesh_index;
 	std::string model_name;
-	std::string model_metric;
 
 	S32 instance_num = 0;
 	
@@ -2204,11 +2203,6 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
 				model_name = data.mBaseModel->getName();
 			}
 
-			if (model_metric.empty())
-			{
-				model_metric = data.mBaseModel->getMetric();
-			}
-
 			std::stringstream ostr;
 			
 			LLModel::Decomposition& decomp =
@@ -2363,11 +2357,6 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
 				model_name = data.mBaseModel->getName();
 			}
 
-			if (model_metric.empty())
-			{
-				model_metric = data.mBaseModel->getMetric();
-			}
-
 			std::stringstream ostr;
 			
 			LLModel::Decomposition& decomp =
@@ -2498,8 +2487,7 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
 
 	if (model_name.empty()) model_name = "mesh model";
 	result["name"] = model_name;
-	if (model_metric.empty()) model_metric = "MUT_Unspecified";
-	res["metric"] = model_metric;
+	res["metric"] = "MUT_Unspecified";
 	result["asset_resources"] = res;
 	dump_llsd_to_file(result,make_dump_name("whole_model_",dump_num));
 
diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml
index 3db431de1b..5a86eb06fb 100644
--- a/indra/newview/skins/default/xui/en/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml
@@ -73,35 +73,6 @@
           prevalidate_callback="ascii"
           top_pad="5"
           width="290" />
-        <text
-          follows="left|top"
-          height="15"
-          layout="topleft"
-          left_pad="15"
-          name="model_category_label"
-          text_color="White"
-          top="0"
-          width="200">
-          This model represents...
-        </text>
-        <combo_box
-          follows="left|top"
-          height="23"
-          left_pad="10"
-          name="model_category_combo"
-          top_pad="10"
-          width="200">
-        <combo_box.drop_down_button
-          label_color="White"/>
-          <combo_item name="Choose one" label="Choose One..." value="MUT_Unspecified"/>
-          <combo_item name="Avatar shape" label="Avatar shape" value="MUT_AvatarShape"/>
-          <combo_item name="Avatar attachment" label="Avatar attachment" value="MUT_AvatarAttachment"/>
-          <combo_item name="Moving object (vehicle, animal)" label="Moving object (vehicle, animal)" value="MUT_MovingObject"/>
-          <combo_item name="Building Component" label="Building Component" value="MUT_BuildingComponent"/>
-          <combo_item name="Large, non moving etc" label="Large, non moving etc" value="MUT_LargeStationary"/>
-          <combo_item name="Smaller, non-moving etc" label="Smaller, non-moving etc" value="MUT_SmallStationary"/>
-          <combo_item name="Not really any of these" label="Not really any of these" value="MUT_Other"/>
-         </combo_box>
     </panel>
     <tab_container
       follows="top|left"
-- 
cgit v1.2.3


From 4d9ad4612a9db32cda11a4ca62baf9ae90ae26ee Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 29 Nov 2018 14:49:19 -0500
Subject: SL-10030: Update to viewer-manager build 522096

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 5dfab783d6..a063e4be0e 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3138,9 +3138,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>1859ebf1b12485211ef4243b48c19410</string>
+              <string>2040ddeb5dd2040f9d57bdc1865af520</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28203/230495/viewer_manager-2.0.522079-darwin64-522079.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28232/230664/viewer_manager-2.0.522096-darwin64-522096.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3162,9 +3162,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>e6251d211ac0b5b4258c3a04fd5f3ffe</string>
+              <string>a3c4980f31e3437910b72bd45efb0e6d</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28204/230501/viewer_manager-2.0.522079-windows-522079.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28233/230672/viewer_manager-2.0.522096-windows-522096.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3175,7 +3175,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.522079</string>
+        <string>2.0.522096</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From d9983255569eb5c49e8a414b4b8e8f56f9d33533 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Fri, 30 Nov 2018 17:29:54 +0200
Subject: SL-10145 Right clicking on unselected link in editor near selected
 text shows wrong menu

---
 indra/llui/lltexteditor.cpp | 22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 134b76c720..137167db2a 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -732,14 +732,30 @@ BOOL LLTextEditor::handleRightMouseDown(S32 x, S32 y, MASK mask)
 	{
 		setFocus(TRUE);
 	}
+
+	bool show_menu = false;
+
 	// Prefer editor menu if it has selection. See EXT-6806.
-	if (hasSelection() || !LLTextBase::handleRightMouseDown(x, y, mask))
+	if (hasSelection())
 	{
-		if(getShowContextMenu())
+		S32 click_pos = getDocIndexFromLocalCoord(x, y, FALSE);
+		if (click_pos > mSelectionStart && click_pos < mSelectionEnd)
 		{
-			showContextMenu(x, y);
+			show_menu = true;
 		}
 	}
+
+	// Let segments handle the click, if nothing does, show editor menu
+	if (!show_menu && !LLTextBase::handleRightMouseDown(x, y, mask))
+	{
+		show_menu = true;
+	}
+
+	if (show_menu && getShowContextMenu())
+	{
+		showContextMenu(x, y);
+	}
+
 	return TRUE;
 }
 
-- 
cgit v1.2.3


From 63117d291936310b2059f07c79c3ccc87baaa064 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 30 Nov 2018 15:06:27 -0500
Subject: SL-10147: Copy placeholder English text to supported NSIS languages.

---
 indra/newview/installers/windows/lang_da.nsi    | Bin 7816 -> 11760 bytes
 indra/newview/installers/windows/lang_de.nsi    | Bin 9854 -> 12582 bytes
 indra/newview/installers/windows/lang_es.nsi    | Bin 9876 -> 12630 bytes
 indra/newview/installers/windows/lang_fr.nsi    | Bin 10262 -> 12990 bytes
 indra/newview/installers/windows/lang_it.nsi    | Bin 9524 -> 12278 bytes
 indra/newview/installers/windows/lang_ja.nsi    | Bin 7208 -> 9988 bytes
 indra/newview/installers/windows/lang_pl.nsi    | Bin 8136 -> 12080 bytes
 indra/newview/installers/windows/lang_pt-br.nsi | Bin 9864 -> 12748 bytes
 indra/newview/installers/windows/lang_ru.nsi    | Bin 9186 -> 11940 bytes
 indra/newview/installers/windows/lang_tr.nsi    | Bin 9290 -> 12044 bytes
 indra/newview/installers/windows/lang_zh.nsi    | Bin 6850 -> 9708 bytes
 11 files changed, 0 insertions(+), 0 deletions(-)

diff --git a/indra/newview/installers/windows/lang_da.nsi b/indra/newview/installers/windows/lang_da.nsi
index b3b8cf34d5..f462c82078 100644
Binary files a/indra/newview/installers/windows/lang_da.nsi and b/indra/newview/installers/windows/lang_da.nsi differ
diff --git a/indra/newview/installers/windows/lang_de.nsi b/indra/newview/installers/windows/lang_de.nsi
index 7758a3bda6..6abd496849 100644
Binary files a/indra/newview/installers/windows/lang_de.nsi and b/indra/newview/installers/windows/lang_de.nsi differ
diff --git a/indra/newview/installers/windows/lang_es.nsi b/indra/newview/installers/windows/lang_es.nsi
index 6d4a7495a6..5daac908c9 100644
Binary files a/indra/newview/installers/windows/lang_es.nsi and b/indra/newview/installers/windows/lang_es.nsi differ
diff --git a/indra/newview/installers/windows/lang_fr.nsi b/indra/newview/installers/windows/lang_fr.nsi
index 421015fc6b..c437a0bdb4 100644
Binary files a/indra/newview/installers/windows/lang_fr.nsi and b/indra/newview/installers/windows/lang_fr.nsi differ
diff --git a/indra/newview/installers/windows/lang_it.nsi b/indra/newview/installers/windows/lang_it.nsi
index df735ba742..78be4a3464 100644
Binary files a/indra/newview/installers/windows/lang_it.nsi and b/indra/newview/installers/windows/lang_it.nsi differ
diff --git a/indra/newview/installers/windows/lang_ja.nsi b/indra/newview/installers/windows/lang_ja.nsi
index f2cc1f9fde..2eb40e280b 100644
Binary files a/indra/newview/installers/windows/lang_ja.nsi and b/indra/newview/installers/windows/lang_ja.nsi differ
diff --git a/indra/newview/installers/windows/lang_pl.nsi b/indra/newview/installers/windows/lang_pl.nsi
index 61dc769126..05977847b9 100644
Binary files a/indra/newview/installers/windows/lang_pl.nsi and b/indra/newview/installers/windows/lang_pl.nsi differ
diff --git a/indra/newview/installers/windows/lang_pt-br.nsi b/indra/newview/installers/windows/lang_pt-br.nsi
index d481434ab2..79c2b7b114 100644
Binary files a/indra/newview/installers/windows/lang_pt-br.nsi and b/indra/newview/installers/windows/lang_pt-br.nsi differ
diff --git a/indra/newview/installers/windows/lang_ru.nsi b/indra/newview/installers/windows/lang_ru.nsi
index d8990fd955..0ef1023d88 100644
Binary files a/indra/newview/installers/windows/lang_ru.nsi and b/indra/newview/installers/windows/lang_ru.nsi differ
diff --git a/indra/newview/installers/windows/lang_tr.nsi b/indra/newview/installers/windows/lang_tr.nsi
index c320764fac..4bb4e14bfa 100644
Binary files a/indra/newview/installers/windows/lang_tr.nsi and b/indra/newview/installers/windows/lang_tr.nsi differ
diff --git a/indra/newview/installers/windows/lang_zh.nsi b/indra/newview/installers/windows/lang_zh.nsi
index 8da802df68..fccf119625 100644
Binary files a/indra/newview/installers/windows/lang_zh.nsi and b/indra/newview/installers/windows/lang_zh.nsi differ
-- 
cgit v1.2.3


From 095c7eb0af14b600b5d41a3f72414da399a003a3 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Mon, 3 Dec 2018 16:14:22 +0200
Subject: SL-10150 'Preset in use' shows last used preset name after deleting
 it

---
 indra/newview/llfloaterpreference.cpp | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index d63ee1b367..92c9d1ae59 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -2600,6 +2600,10 @@ void LLPanelPreferenceGraphics::onPresetsListChange()
 	{
 		instance->saveSettings(); //make cancel work correctly after changing the preset
 	}
+	else
+	{
+		instance->saveGraphicsPreset(std::string());
+	}
 }
 
 void LLPanelPreferenceGraphics::setPresetText()
-- 
cgit v1.2.3


From c94e981f40652920a7fb5234a65369bf58d41865 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Mon, 3 Dec 2018 17:30:35 +0200
Subject: SL-10080 clamp instead of llmax

---
 indra/newview/llappviewer.cpp     | 6 +++---
 indra/newview/llviewercontrol.cpp | 6 +++---
 indra/newview/llvoavatar.h        | 2 ++
 3 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index bd45f68a5c..7c79cc7ddf 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -568,12 +568,12 @@ static void settings_to_globals()
 	LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO");
 	LLImageGL::sGlobalUseAnisotropic	= gSavedSettings.getBOOL("RenderAnisotropic");
 	LLImageGL::sCompressTextures		= gSavedSettings.getBOOL("RenderCompressTextures");
-	LLVOVolume::sLODFactor				= llmin(gSavedSettings.getF32("RenderVolumeLODFactor"), MAX_LOD_FACTOR);
+	LLVOVolume::sLODFactor				= llclamp(gSavedSettings.getF32("RenderVolumeLODFactor"), 0.01f, MAX_LOD_FACTOR);
 	LLVOVolume::sDistanceFactor			= 1.f-LLVOVolume::sLODFactor * 0.1f;
 	LLVolumeImplFlexible::sUpdateFactor = gSavedSettings.getF32("RenderFlexTimeFactor");
 	LLVOTree::sTreeFactor				= gSavedSettings.getF32("RenderTreeLODFactor");
-	LLVOAvatar::sLODFactor				= llmin(gSavedSettings.getF32("RenderAvatarLODFactor"), MAX_LOD_FACTOR);
-	LLVOAvatar::sPhysicsLODFactor		= llmin(gSavedSettings.getF32("RenderAvatarPhysicsLODFactor"), MAX_LOD_FACTOR);
+	LLVOAvatar::sLODFactor				= llclamp(gSavedSettings.getF32("RenderAvatarLODFactor"), 0.f, MAX_AVATAR_LOD_FACTOR);
+	LLVOAvatar::sPhysicsLODFactor		= llclamp(gSavedSettings.getF32("RenderAvatarPhysicsLODFactor"), 0.f, MAX_AVATAR_LOD_FACTOR);
 	LLVOAvatar::updateImpostorRendering(gSavedSettings.getU32("RenderAvatarMaxNonImpostors"));
 	LLVOAvatar::sVisibleInFirstPerson	= gSavedSettings.getBOOL("FirstPersonAvatarVisible");
 	// clamp auto-open time to some minimum usable value
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index e62d6eb951..a699491e1b 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -219,20 +219,20 @@ static bool handleAnisotropicChanged(const LLSD& newvalue)
 
 static bool handleVolumeLODChanged(const LLSD& newvalue)
 {
-	LLVOVolume::sLODFactor = llmin((F32) newvalue.asReal(), MAX_LOD_FACTOR);
+	LLVOVolume::sLODFactor = llclamp((F32) newvalue.asReal(), 0.01f, MAX_LOD_FACTOR);
 	LLVOVolume::sDistanceFactor = 1.f-LLVOVolume::sLODFactor * 0.1f;
 	return true;
 }
 
 static bool handleAvatarLODChanged(const LLSD& newvalue)
 {
-	LLVOAvatar::sLODFactor = llmin((F32) newvalue.asReal(), MAX_LOD_FACTOR);
+	LLVOAvatar::sLODFactor = llclamp((F32) newvalue.asReal(), 0.f, MAX_AVATAR_LOD_FACTOR);
 	return true;
 }
 
 static bool handleAvatarPhysicsLODChanged(const LLSD& newvalue)
 {
-	LLVOAvatar::sPhysicsLODFactor = llmin((F32) newvalue.asReal(), MAX_LOD_FACTOR);
+	LLVOAvatar::sPhysicsLODFactor = llclamp((F32) newvalue.asReal(), 0.f, MAX_AVATAR_LOD_FACTOR);
 	return true;
 }
 
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index deb22617a4..a4f8e95c65 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -75,6 +75,8 @@ class LLTexGlobalColor;
 struct LLAppearanceMessageContents;
 class LLViewerJointMesh;
 
+const F32 MAX_AVATAR_LOD_FACTOR = 1.0f;
+
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // LLVOAvatar
-- 
cgit v1.2.3


From a39d330cc22c603d5c06fabe86104e8948573e20 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Mon, 3 Dec 2018 20:27:44 +0200
Subject: SL-10152 Uninstaller's offers to delete remaining files is
 problematic

---
 .../newview/installers/windows/installer_template.nsi |   4 +---
 indra/newview/installers/windows/lang_en-us.nsi       | Bin 8734 -> 8814 bytes
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index 14c8dba39f..d6e4b005df 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -651,9 +651,7 @@ RMDir "$INSTDIR"
 IfFileExists "$INSTDIR" FOLDERFOUND NOFOLDER
 
 FOLDERFOUND:
-# Silent uninstall always removes all files (/SD IDYES)
-  MessageBox MB_YESNO $(DeleteProgramFilesMB) /SD IDYES IDNO NOFOLDER
-  RMDir /r "$INSTDIR"
+  MessageBox MB_OK $(DeleteProgramFilesMB) /SD IDOK IDOK NOFOLDER
 
 NOFOLDER:
 
diff --git a/indra/newview/installers/windows/lang_en-us.nsi b/indra/newview/installers/windows/lang_en-us.nsi
index 00aa47de69..f854f5db06 100644
Binary files a/indra/newview/installers/windows/lang_en-us.nsi and b/indra/newview/installers/windows/lang_en-us.nsi differ
-- 
cgit v1.2.3


From abf1b6474e0c75131439b6cc7888027d07fe4c7e Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 3 Dec 2018 16:07:27 -0500
Subject: SL-10153: Update to viewer-manager build 522199

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index a063e4be0e..6aae9561ab 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3138,9 +3138,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>2040ddeb5dd2040f9d57bdc1865af520</string>
+              <string>3504fe5c13ff8ca3bae9de2bfda5d1a5</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28232/230664/viewer_manager-2.0.522096-darwin64-522096.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28374/232934/viewer_manager-2.0.522199-darwin64-522199.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3162,9 +3162,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>a3c4980f31e3437910b72bd45efb0e6d</string>
+              <string>d035a93c4d8554241fd43ac91033a838</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28233/230672/viewer_manager-2.0.522096-windows-522096.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28375/232940/viewer_manager-2.0.522199-windows-522199.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3175,7 +3175,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.522096</string>
+        <string>2.0.522199</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From 8205bd22f16c517acbfab1661738176dc158d89b Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 3 Dec 2018 18:59:10 -0500
Subject: SL-10153: Update to viewer-manager build 522217

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 6aae9561ab..2ebb1cce23 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3138,9 +3138,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>3504fe5c13ff8ca3bae9de2bfda5d1a5</string>
+              <string>7e4fc2b997ff9ef0122e0a56fc765112</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28374/232934/viewer_manager-2.0.522199-darwin64-522199.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28398/233376/viewer_manager-2.0.522217-darwin64-522217.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3162,9 +3162,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>d035a93c4d8554241fd43ac91033a838</string>
+              <string>998737a96678a7c0881982e884a22d7e</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28375/232940/viewer_manager-2.0.522199-windows-522199.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28399/233382/viewer_manager-2.0.522217-windows-522217.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3175,7 +3175,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.522199</string>
+        <string>2.0.522217</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From 320b7bacc2ef34b1434178cce8eb2818493fec21 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Tue, 4 Dec 2018 18:51:44 +0200
Subject: SL-10149 FIXED 'Mute when minimized' checkbox is displayed without
 focus on it after pressing on label in the "Preferences" floater

---
 indra/llui/llcheckboxctrl.h           | 2 ++
 indra/newview/llfloaterpreference.cpp | 6 ++++++
 2 files changed, 8 insertions(+)

diff --git a/indra/llui/llcheckboxctrl.h b/indra/llui/llcheckboxctrl.h
index 5ce45b2135..71bdc32e66 100644
--- a/indra/llui/llcheckboxctrl.h
+++ b/indra/llui/llcheckboxctrl.h
@@ -92,6 +92,8 @@ public:
 	// LLCheckBoxCtrl interface
 	virtual BOOL		toggle()				{ return mButton->toggleState(); }		// returns new state
 
+	void				setBtnFocus() { mButton->setFocus(TRUE); }
+
 	void				setEnabledColor( const LLColor4 &color ) { mTextEnabledColor = color; }
 	void				setDisabledColor( const LLColor4 &color ) { mTextDisabledColor = color; }
 
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 92c9d1ae59..c66247b4b7 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -2329,6 +2329,7 @@ BOOL LLPanelPreference::postBuild()
 	if (hasChild("mute_chb_label", TRUE))
 	{
 		getChild<LLTextBox>("mute_chb_label")->setShowCursorHand(false);
+		getChild<LLTextBox>("mute_chb_label")->setSoundFlags(LLView::MOUSE_UP);
 		getChild<LLTextBox>("mute_chb_label")->setClickedCallback(boost::bind(&toggleMuteWhenMinimized));
 	}
 
@@ -2452,6 +2453,11 @@ void LLPanelPreference::toggleMuteWhenMinimized()
 {
 	std::string mute("MuteWhenMinimized");
 	gSavedSettings.setBOOL(mute, !gSavedSettings.getBOOL(mute));
+	LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+	if (instance)
+	{
+		instance->getChild<LLCheckBoxCtrl>("mute_when_minimized")->setBtnFocus();
+	}
 }
 
 void LLPanelPreference::cancel()
-- 
cgit v1.2.3


From 6e87cc5a7570884e81c671bd6e94e3a2b68099ad Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Tue, 4 Dec 2018 20:45:49 +0200
Subject: mac build fix

---
 indra/newview/llfloaterpreference.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index c66247b4b7..ac751a785d 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -2608,7 +2608,8 @@ void LLPanelPreferenceGraphics::onPresetsListChange()
 	}
 	else
 	{
-		instance->saveGraphicsPreset(std::string());
+		std::string dummy;
+		instance->saveGraphicsPreset(dummy);
 	}
 }
 
-- 
cgit v1.2.3


From 4c92c7b2d025b7cd85bf176287b86a3990959841 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Tue, 4 Dec 2018 17:52:46 +0200
Subject: SL-1481 Don't predict region crossings over a second

---
 indra/newview/app_settings/settings.xml | 11 +++++++
 indra/newview/llviewerobject.cpp        | 58 ++++++++++++++++++++++++---------
 indra/newview/llviewerobject.h          |  4 ++-
 indra/newview/llviewerobjectlist.cpp    |  2 ++
 4 files changed, 59 insertions(+), 16 deletions(-)

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 3ad8b6cded..0eef5120eb 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -14068,6 +14068,17 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
+    <key>RegionCrossingInterpolationTime</key>
+    <map>
+      <key>Comment</key>
+      <string>How long to extrapolate object motion after crossing regions</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>F32</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
     <key>VerboseLogs</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 1e46a1cf9e..079a9f0372 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -127,6 +127,7 @@ BOOL		LLViewerObject::sUseSharedDrawables(FALSE); // TRUE
 // sMaxUpdateInterpolationTime must be greater than sPhaseOutUpdateInterpolationTime
 F64Seconds	LLViewerObject::sMaxUpdateInterpolationTime(3.0);		// For motion interpolation: after X seconds with no updates, don't predict object motion
 F64Seconds	LLViewerObject::sPhaseOutUpdateInterpolationTime(2.0);	// For motion interpolation: after Y seconds with no updates, taper off motion prediction
+F64Seconds	LLViewerObject::sMaxRegionCrossingInterpolationTime(1.0);// For motion interpolation: don't interpolate over this time on region crossing
 
 std::map<std::string, U32> LLViewerObject::sObjectDataMap;
 
@@ -2487,7 +2488,7 @@ void LLViewerObject::loadFlags(U32 flags)
 	return;
 }
 
-void LLViewerObject::idleUpdate(LLAgent &agent, const F64 &time)
+void LLViewerObject::idleUpdate(LLAgent &agent, const F64 &frame_time)
 {
 	//static LLTrace::BlockTimerStatHandle ftm("Viewer Object");
 	//LL_RECORD_BLOCK_TIME(ftm);
@@ -2498,19 +2499,19 @@ void LLViewerObject::idleUpdate(LLAgent &agent, const F64 &time)
 		{
 			// calculate dt from last update
 			F32 time_dilation = mRegionp ? mRegionp->getTimeDilation() : 1.0f;
-			F32 dt_raw = ((F64Seconds)time - mLastInterpUpdateSecs).value();
+			F32 dt_raw = ((F64Seconds)frame_time - mLastInterpUpdateSecs).value();
 			F32 dt = time_dilation * dt_raw;
 
 			applyAngularVelocity(dt);
 
 			if (isAttachment())
 			{
-				mLastInterpUpdateSecs = (F64Seconds)time;
+				mLastInterpUpdateSecs = (F64Seconds)frame_time;
 				return;
 			}
 			else
 			{	// Move object based on it's velocity and rotation
-				interpolateLinearMotion(time, dt);
+				interpolateLinearMotion(frame_time, dt);
 			}
 		}
 
@@ -2520,7 +2521,7 @@ void LLViewerObject::idleUpdate(LLAgent &agent, const F64 &time)
 
 
 // Move an object due to idle-time viewer side updates by interpolating motion
-void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& time, const F32SecondsImplicit& dt_seconds)
+void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& frame_time, const F32SecondsImplicit& dt_seconds)
 {
 	// linear motion
 	// PHYSICS_TIMESTEP is used below to correct for the fact that the velocity in object
@@ -2532,7 +2533,7 @@ void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& time, con
 	// zeroing it out	
 
 	F32 dt = dt_seconds;
-	F64Seconds time_since_last_update = time - mLastMessageUpdateSecs;
+	F64Seconds time_since_last_update = frame_time - mLastMessageUpdateSecs;
 	if (time_since_last_update <= (F64Seconds)0.0 || dt <= 0.f)
 	{
 		return;
@@ -2580,7 +2581,7 @@ void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& time, con
 						 (time_since_last_packet > sPhaseOutUpdateInterpolationTime))
 					{
 						// Start to reduce motion interpolation since we haven't seen a server update in a while
-						F64Seconds time_since_last_interpolation = time - mLastInterpUpdateSecs;
+						F64Seconds time_since_last_interpolation = frame_time - mLastInterpUpdateSecs;
 						F64 phase_out = 1.0;
 						if (time_since_last_update > sMaxUpdateInterpolationTime)
 						{	// Past the time limit, so stop the object
@@ -2636,6 +2637,7 @@ void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& time, con
 
 		// Check to see if it's going off the region
 		LLVector3 temp(new_pos);
+		static F64SecondsImplicit region_cross_expire = 0; // frame time we detected region crossing in + wait time
 		if (temp.clamp(0.f, mRegionp->getWidth()))
 		{	// Going off this region, so see if we might end up on another region
 			LLVector3d old_pos_global = mRegionp->getPosGlobalFromRegion(getPositionRegion());
@@ -2644,21 +2646,47 @@ void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& time, con
 			// Clip the positions to known regions
 			LLVector3d clip_pos_global = LLWorld::getInstance()->clipToVisibleRegions(old_pos_global, new_pos_global);
 			if (clip_pos_global != new_pos_global)
-			{	// Was clipped, so this means we hit a edge where there is no region to enter
-				
-				//LL_INFOS() << "Hit empty region edge, clipped predicted position to " << mRegionp->getPosRegionFromGlobal(clip_pos_global)
-				//	<< " from " << new_pos << LL_ENDL;
-				new_pos = mRegionp->getPosRegionFromGlobal(clip_pos_global);
+			{
+				// Was clipped, so this means we hit a edge where there is no region to enter
+				LLVector3 clip_pos = mRegionp->getPosRegionFromGlobal(clip_pos_global);
+				LL_DEBUGS("Interpolate") << "Hit empty region edge, clipped predicted position to "
+										 << clip_pos
+										 << " from " << new_pos << LL_ENDL;
+				new_pos = clip_pos;
 				
 				// Stop motion and get server update for bouncing on the edge
 				new_v.clear();
 				setAcceleration(LLVector3::zero);
 			}
 			else
-			{	// Let predicted movement cross into another region
-				//LL_INFOS() << "Predicting region crossing to " << new_pos << LL_ENDL;
+			{
+				// Check for how long we are crossing.
+				// Note: theoretically we can find time from velocity, acceleration and
+				// distance from border to new position, but it is not going to work
+				// if 'phase_out' activates
+				if (region_cross_expire == 0)
+				{
+					// Workaround: we can't accurately figure out time when we cross border
+					// so just write down time 'after the fact', it is far from optimal in
+					// case of lags, but for lags sMaxUpdateInterpolationTime will kick in first
+					LL_DEBUGS("Interpolate") << "Predicted region crossing, new position " << new_pos << LL_ENDL;
+					region_cross_expire = frame_time + sMaxRegionCrossingInterpolationTime;
+				}
+				else if (frame_time > region_cross_expire)
+				{
+					// Predicting crossing over 1s, stop motion
+					// Stop motion
+					LL_DEBUGS("Interpolate") << "Predicting region crossing for too long, stopping at " << new_pos << LL_ENDL;
+					new_v.clear();
+					setAcceleration(LLVector3::zero);
+					region_cross_expire = 0;
+				}
 			}
 		}
+		else
+		{
+			region_cross_expire = 0;
+		}
 
 		// Set new position and velocity
 		setPositionRegion(new_pos);
@@ -2669,7 +2697,7 @@ void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& time, con
 	}		
 
 	// Update the last time we did anything
-	mLastInterpUpdateSecs = time;
+	mLastInterpUpdateSecs = frame_time;
 }
 
 
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index d6c8b76147..990c392531 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -615,7 +615,7 @@ private:
     U32 checkMediaURL(const std::string &media_url);
 	
 	// Motion prediction between updates
-	void interpolateLinearMotion(const F64SecondsImplicit & time, const F32SecondsImplicit & dt);
+	void interpolateLinearMotion(const F64SecondsImplicit & frame_time, const F32SecondsImplicit & dt);
 
 	static void initObjectDataMap();
 
@@ -851,6 +851,7 @@ protected:
 
 	static void setPhaseOutUpdateInterpolationTime(F32 value)	{ sPhaseOutUpdateInterpolationTime = (F64Seconds) value;	}
 	static void setMaxUpdateInterpolationTime(F32 value)		{ sMaxUpdateInterpolationTime = (F64Seconds) value;	}
+	static void setMaxRegionCrossingInterpolationTime(F32 value)		{ sMaxRegionCrossingInterpolationTime = (F64Seconds) value; }
 
 	static void	setVelocityInterpolate(BOOL value)		{ sVelocityInterpolate = value;	}
 	static void	setPingInterpolate(BOOL value)			{ sPingInterpolate = value;	}
@@ -860,6 +861,7 @@ private:
 
 	static F64Seconds sPhaseOutUpdateInterpolationTime;	// For motion interpolation
 	static F64Seconds sMaxUpdateInterpolationTime;			// For motion interpolation
+	static F64Seconds sMaxRegionCrossingInterpolationTime;			// For motion interpolation
 
 	static BOOL sVelocityInterpolate;
 	static BOOL sPingInterpolate;
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 2aff71367e..932759c86d 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -854,6 +854,7 @@ void LLViewerObjectList::update(LLAgent &agent)
 	
 	F32 interp_time = gSavedSettings.getF32("InterpolationTime");
 	F32 phase_out_time = gSavedSettings.getF32("InterpolationPhaseOut");
+	F32 region_interp_time = llclamp(gSavedSettings.getF32("RegionCrossingInterpolationTime"), 0.5f, 5.f);
 	if (interp_time < 0.0 || 
 		phase_out_time < 0.0 ||
 		phase_out_time > interp_time)
@@ -864,6 +865,7 @@ void LLViewerObjectList::update(LLAgent &agent)
 	}
 	LLViewerObject::setPhaseOutUpdateInterpolationTime( interp_time );
 	LLViewerObject::setMaxUpdateInterpolationTime( phase_out_time );
+	LLViewerObject::setMaxRegionCrossingInterpolationTime(region_interp_time);
 
 	gAnimateTextures = gSavedSettings.getBOOL("AnimateTextures");
 
-- 
cgit v1.2.3


From 8892ec5a3bb45eeaf3e66cb9ce884f312bfdfe71 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 4 Dec 2018 16:14:32 -0500
Subject: SL-10153: Update to viewer-manager build 522260

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 2ebb1cce23..953c703886 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3138,9 +3138,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>7e4fc2b997ff9ef0122e0a56fc765112</string>
+              <string>49d8224983843e61b2a770d0e6880c85</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28398/233376/viewer_manager-2.0.522217-darwin64-522217.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28466/235199/viewer_manager-2.0.522260-darwin64-522260.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3162,9 +3162,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>998737a96678a7c0881982e884a22d7e</string>
+              <string>9fc5bf5c63b655f3ed63efd862435926</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28399/233382/viewer_manager-2.0.522217-windows-522217.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28467/235205/viewer_manager-2.0.522260-windows-522260.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3175,7 +3175,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.522217</string>
+        <string>2.0.522260</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From d509e315cfedb1785723184d5f2105af0436eb57 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 5 Dec 2018 10:30:53 -0500
Subject: DRTVWR-447: Fix BugSplat init with non-ASCII chars in install path.

The whole remaining difference between llifstream and std::ifstream is that
the former handles UTF-8 coded pathnames. Microsoft's implementation of the
latter does not.
---
 indra/newview/llappviewerwin32.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 75fa3baa42..fff2653c98 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -600,7 +600,9 @@ bool LLAppViewerWin32::init()
 
 	std::string build_data_fname(
 		gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "build_data.json"));
-	std::ifstream inf(build_data_fname.c_str());
+	// Use llifstream instead of std::ifstream because LL_PATH_EXECUTABLE
+	// could contain non-ASCII characters, which std::ifstream doesn't handle.
+	llifstream inf(build_data_fname.c_str());
 	if (! inf.is_open())
 	{
 		LL_WARNS() << "Can't initialize BugSplat, can't read '" << build_data_fname
-- 
cgit v1.2.3


From 7a336f63cc77a93362f5d4fcc274d1d908ef2f63 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 5 Dec 2018 16:57:00 -0500
Subject: SL-10153: If $APPDATA isn't already good, try SHGetFolderPath().

In that case, also update $APPDATA for child processes.
---
 indra/llvfs/lldir_win32.cpp | 29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/indra/llvfs/lldir_win32.cpp b/indra/llvfs/lldir_win32.cpp
index 9836fa28f2..3e48e086d7 100644
--- a/indra/llvfs/lldir_win32.cpp
+++ b/indra/llvfs/lldir_win32.cpp
@@ -48,10 +48,38 @@ LLDir_Win32::LLDir_Win32()
 	// set this first: used by append() and add() methods
 	mDirDelimiter = "\\";
 
+	WCHAR w_str[MAX_PATH];
 	// Application Data is where user settings go. We rely on $APPDATA being
 	// correct; in fact the VMP makes a point of setting it properly, since
 	// Windows itself botches the job for non-ASCII usernames (MAINT-8087).
 	mOSUserDir = ll_safe_string(getenv("APPDATA"));
+	// On Windows, it's a Bad Thing if a pathname contains ASCII question
+	// marks. In our experience, it means that the original pathname contained
+	// non-ASCII characters that were munged to '?' somewhere along the way.
+	// Convert to LLWString first, though, in case one of the bytes in a
+	// non-ASCII UTF-8 string accidentally resembles '?'.
+	if (utf8string_to_wstring(mOSUserDir).find(llwchar('?')) != LLWString::npos)
+	{
+		// It is really unclear what we should do if the following call fails.
+		// We use it, among other things, to find where to put our log file!
+		if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, w_str)))
+		{
+			// But of course, only update mOSUserDir if SHGetFolderPathW() works.
+			mOSUserDir = utf16str_to_utf8str(llutf16string(w_str));
+			// Not only that: update our environment so that child processes
+			// will see a reasonable value as well. Use _putenv_s() rather
+			// than _wputenv_s() because WE want to control the encoding with
+			// which APPDATA is passed to child processes, instead of letting
+			// somebody else pick it.
+			_putenv_s("APPDATA", mOSUserDir.c_str());
+			// SL-10153: It is really tempting to make the above _putenv_s()
+			// call unconditional, since we've observed cases in which the
+			// parent viewer receives a valid non-ASCII APPDATA value while
+			// the child SLVersionChecker process receives one containing
+			// question marks. But if what we see is already valid, what do we
+			// gain by storing it again?
+		}
+	}
 
 	// We want cache files to go on the local disk, even if the
 	// user is on a network with a "roaming profile".
@@ -63,7 +91,6 @@ LLDir_Win32::LLDir_Win32()
 	// cleans up that version on upgrade.  JC
 	mOSCacheDir = ll_safe_string(getenv("LOCALAPPDATA"));
 
-	WCHAR w_str[MAX_PATH];
 	if (GetTempPath(MAX_PATH, w_str))
 	{
 		if (wcslen(w_str))	/* Flawfinder: ignore */ 
-- 
cgit v1.2.3


From 1029f6b776fbef66959ef621f233cf1012b3f72b Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 5 Dec 2018 17:16:06 -0500
Subject: SL-10153: Update to viewer-manager build 522314

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 953c703886..5f7e22347b 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3138,9 +3138,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>49d8224983843e61b2a770d0e6880c85</string>
+              <string>acab355caaab1a5841a200e2d0dd9891</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28466/235199/viewer_manager-2.0.522260-darwin64-522260.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28547/236386/viewer_manager-2.0.522314-darwin64-522314.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3162,9 +3162,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>9fc5bf5c63b655f3ed63efd862435926</string>
+              <string>e649491175876e6bf016a36f97c69497</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28467/235205/viewer_manager-2.0.522260-windows-522260.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28548/236392/viewer_manager-2.0.522314-windows-522314.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3175,7 +3175,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.522260</string>
+        <string>2.0.522314</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From b39cfe229ba127b9ac3e47edd1255b95fe32c5ea Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Fri, 7 Dec 2018 13:31:54 +0200
Subject: SL-10175 Update copyright year in application info

---
 indra/newview/CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index ce8b662231..33886acb71 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -2074,7 +2074,7 @@ if (DARWIN)
   set(MACOSX_BUNDLE_BUNDLE_NAME "SecondLife")
   set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${VIEWER_SHORT_VERSION}")
   set(MACOSX_BUNDLE_BUNDLE_VERSION "${VIEWER_SHORT_VERSION}${VIEWER_MACOSX_PHASE}${VIEWER_REVISION}")
-  set(MACOSX_BUNDLE_COPYRIGHT "Copyright © Linden Research, Inc. 2007")
+  set(MACOSX_BUNDLE_COPYRIGHT "Copyright © Linden Research, Inc. 2018")
   set(MACOSX_BUNDLE_NSMAIN_NIB_FILE "SecondLife.nib")
   set(MACOSX_BUNDLE_NSPRINCIPAL_CLASS "NSApplication")
   
-- 
cgit v1.2.3


From a48ff6c2fadb5697ab204a34ac696f1ce920e02d Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Thu, 6 Dec 2018 19:50:33 +0200
Subject: SL-10172 Add a KB link to the TLS failure dialog

---
 indra/newview/llxmlrpctransaction.cpp | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp
index 143c97fca4..f5c169996f 100644
--- a/indra/newview/llxmlrpctransaction.cpp
+++ b/indra/newview/llxmlrpctransaction.cpp
@@ -507,6 +507,8 @@ void LLXMLRPCTransaction::Impl::setHttpStatus(const LLCore::HttpStatus &status)
 
 	case CURLE_SSL_CACERT:
 	case CURLE_SSL_CONNECT_ERROR:
+		{
+		std::string uri_base = "https://community.secondlife.com/knowledgebase/english/error-messages-r520/#Section__3";
 		message =
 			"Often this means that your computer\'s clock is set incorrectly.\n"
 			"Please go to Control Panels and make sure the time and date\n"
@@ -514,8 +516,9 @@ void LLXMLRPCTransaction::Impl::setHttpStatus(const LLCore::HttpStatus &status)
 			"Also check that your network and firewall are set up correctly.\n"
 			"If you continue to receive this error, please go\n"
 			"to the Support section of the SecondLife.com web site\n"
-			"and report the problem.";
+			"and report the problem.\n\n[" + uri_base + " Knowledge Base]";
 		break;
+		}
 
 	default:
 		break;
-- 
cgit v1.2.3


From 758e7e8df753a9b63782ff2964c26c0b0a4015fe Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 6 Dec 2018 14:33:51 -0500
Subject: SL-10174: LOCALAPPDATA bad? Try SHGetFolderPath(CSIDL_LOCAL_APPDATA).

This logic is essentially copy-and-edited from the same suspenders-and-belt
concerning APPDATA and CSIDL_APPDATA for SL-10153.
---
 indra/llvfs/lldir_win32.cpp | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/indra/llvfs/lldir_win32.cpp b/indra/llvfs/lldir_win32.cpp
index 3e48e086d7..f972f27fd0 100644
--- a/indra/llvfs/lldir_win32.cpp
+++ b/indra/llvfs/lldir_win32.cpp
@@ -90,6 +90,19 @@ LLDir_Win32::LLDir_Win32()
 	// We used to store the cache in AppData\Roaming, and the installer
 	// cleans up that version on upgrade.  JC
 	mOSCacheDir = ll_safe_string(getenv("LOCALAPPDATA"));
+	// Windows really does not deal well with pathnames containing non-ASCII
+	// characters. See above remarks about APPDATA.
+	if (utf8string_to_wstring(mOSCacheDir).find(llwchar('?')) != LLWString::npos)
+	{
+		if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, w_str)))
+		{
+			// But of course, only update mOSCacheDir if SHGetFolderPathW() works.
+			mOSCacheDir = utf16str_to_utf8str(llutf16string(w_str));
+			// Update our environment so that child processes will see a
+			// reasonable value as well.
+			_putenv_s("LOCALAPPDATA", mOSCacheDir.c_str());
+		}
+	}
 
 	if (GetTempPath(MAX_PATH, w_str))
 	{
-- 
cgit v1.2.3


From 6e58201736fd3f5a0cdf5a49f2fb8a391ba58222 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Sat, 8 Dec 2018 10:25:15 -0500
Subject: SL-10153: Update to viewer-manager build 522407

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 5f7e22347b..ebda8c791d 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3138,9 +3138,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>acab355caaab1a5841a200e2d0dd9891</string>
+              <string>f76807ee2425b1532595bc716456fa6a</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28547/236386/viewer_manager-2.0.522314-darwin64-522314.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28665/237854/viewer_manager-2.0.522407-darwin64-522407.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3162,9 +3162,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>e649491175876e6bf016a36f97c69497</string>
+              <string>5cb25b4d66f9a8d4f485b7eab7d02ed0</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28548/236392/viewer_manager-2.0.522314-windows-522314.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28666/237860/viewer_manager-2.0.522407-windows-522407.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3175,7 +3175,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.522314</string>
+        <string>2.0.522407</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From a36cd3a2925bf77aa804a5617e0a227cabacde46 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Sat, 8 Dec 2018 10:30:18 -0500
Subject: SL-10153: Try to handle non-English non-ASCII Windows APPDATA.

---
 indra/llvfs/lldir_win32.cpp | 113 ++++++++++++++++++++++++++++++++++----------
 1 file changed, 89 insertions(+), 24 deletions(-)

diff --git a/indra/llvfs/lldir_win32.cpp b/indra/llvfs/lldir_win32.cpp
index f972f27fd0..96bd779b5f 100644
--- a/indra/llvfs/lldir_win32.cpp
+++ b/indra/llvfs/lldir_win32.cpp
@@ -31,6 +31,8 @@
 #include "lldir_win32.h"
 #include "llerror.h"
 #include "llrand.h"		// for gLindenLabRandomNumber
+#include "stringize.h"
+#include "llfile.h"
 #include <shlobj.h>
 #include <fstream>
 
@@ -43,6 +45,48 @@
 #define PACKVERSION(major,minor) MAKELONG(minor,major)
 DWORD GetDllVersion(LPCTSTR lpszDllName);
 
+namespace
+{ // anonymous
+    enum class prst { INIT, OPEN, SKIP } state;
+    llofstream prelogf;
+
+    void prelog(const std::string& message)
+    {
+        switch (state)
+        {
+        case prst::INIT:
+            // assume we failed, until we succeed
+            state = prst::SKIP;
+
+            // can't initialize within one case of a switch statement
+            const char* prelog_name;
+            prelog_name = getenv("PRELOG");
+            if (! prelog_name)
+                // no PRELOG variable set, carry on
+                return;
+            prelogf.open(prelog_name, std::ios_base::app);
+            if (! prelogf.is_open())
+                // can't complain to anybody; how?
+                return;
+            // got the log file open, cool!
+            state = prst::OPEN;
+            prelogf << "========================================================================"
+                    << std::endl;
+            // fall through, don't break
+
+        case prst::OPEN:
+            prelogf << message << std::endl;
+            break;
+
+        case prst::SKIP:
+            // either PRELOG isn't set, or we failed to open that pathname
+            break;
+        }
+    }
+} // anonymous namespace
+
+#define PRELOG(expression) prelog(STRINGIZE(expression))
+
 LLDir_Win32::LLDir_Win32()
 {
 	// set this first: used by append() and add() methods
@@ -52,32 +96,38 @@ LLDir_Win32::LLDir_Win32()
 	// Application Data is where user settings go. We rely on $APPDATA being
 	// correct; in fact the VMP makes a point of setting it properly, since
 	// Windows itself botches the job for non-ASCII usernames (MAINT-8087).
-	mOSUserDir = ll_safe_string(getenv("APPDATA"));
+	// Try using wide-character getenv()??
+	wchar_t *APPDATA = _wgetenv(L"APPDATA");
+	if (APPDATA)
+	{
+		mOSUserDir = ll_convert_wide_to_string(APPDATA, CP_UTF8);
+	}
+	PRELOG("APPDATA='" << mOSUserDir << "'");
 	// On Windows, it's a Bad Thing if a pathname contains ASCII question
 	// marks. In our experience, it means that the original pathname contained
 	// non-ASCII characters that were munged to '?' somewhere along the way.
 	// Convert to LLWString first, though, in case one of the bytes in a
 	// non-ASCII UTF-8 string accidentally resembles '?'.
-	if (utf8string_to_wstring(mOSUserDir).find(llwchar('?')) != LLWString::npos)
+	// Bear in mind that llwchar is not necessarily wchar_t, therefore L'?' is
+	// not necessarily the right type.
+	if (mOSUserDir.empty() ||
+		utf8string_to_wstring(mOSUserDir).find(llwchar('?')) != LLWString::npos)
 	{
-		// It is really unclear what we should do if the following call fails.
-		// We use it, among other things, to find where to put our log file!
-		if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, w_str)))
+		PRELOG("APPDATA empty or contains ASCII '?'");
+		//HRESULT okay = SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, w_str);
+		wchar_t *pwstr = NULL;
+		HRESULT okay = SHGetKnownFolderPath(FOLDERID_RoamingAppData, 0, NULL, &pwstr);
+		PRELOG("SHGetKnownFolderPath(FOLDERID_RoamingAppData) returned " << okay);
+		if (SUCCEEDED(okay) && pwstr)
 		{
-			// But of course, only update mOSUserDir if SHGetFolderPathW() works.
-			mOSUserDir = utf16str_to_utf8str(llutf16string(w_str));
+			// But of course, only update mOSUserDir if SHGetKnownFolderPath() works.
+			mOSUserDir = ll_convert_wide_to_string(pwstr, CP_UTF8);
 			// Not only that: update our environment so that child processes
-			// will see a reasonable value as well. Use _putenv_s() rather
-			// than _wputenv_s() because WE want to control the encoding with
-			// which APPDATA is passed to child processes, instead of letting
-			// somebody else pick it.
-			_putenv_s("APPDATA", mOSUserDir.c_str());
-			// SL-10153: It is really tempting to make the above _putenv_s()
-			// call unconditional, since we've observed cases in which the
-			// parent viewer receives a valid non-ASCII APPDATA value while
-			// the child SLVersionChecker process receives one containing
-			// question marks. But if what we see is already valid, what do we
-			// gain by storing it again?
+			// will see a reasonable value as well.
+			_wputenv_s(L"APPDATA", pwstr);
+			// SHGetKnownFolderPath() contract requires us to free pwstr
+			CoTaskMemFree(pwstr);
+			PRELOG("mOSUserDir='" << mOSUserDir << "'");
 		}
 	}
 
@@ -89,18 +139,33 @@ LLDir_Win32::LLDir_Win32()
 	//
 	// We used to store the cache in AppData\Roaming, and the installer
 	// cleans up that version on upgrade.  JC
-	mOSCacheDir = ll_safe_string(getenv("LOCALAPPDATA"));
+	// Again, try using wide-character getenv().
+	wchar_t *LOCALAPPDATA = _wgetenv(L"LOCALAPPDATA");
+	if (LOCALAPPDATA)
+	{
+		mOSCacheDir = ll_convert_wide_to_string(LOCALAPPDATA, CP_UTF8);
+	}
+	PRELOG("LOCALAPPDATA='" << mOSCacheDir << "'");
 	// Windows really does not deal well with pathnames containing non-ASCII
 	// characters. See above remarks about APPDATA.
-	if (utf8string_to_wstring(mOSCacheDir).find(llwchar('?')) != LLWString::npos)
+	if (mOSCacheDir.empty() ||
+		utf8string_to_wstring(mOSCacheDir).find(llwchar('?')) != LLWString::npos)
 	{
-		if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, w_str)))
+		PRELOG("LOCALAPPDATA empty or contains ASCII '?'");
+		//HRESULT okay = SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, w_str);
+		wchar_t *pwstr = NULL;
+		HRESULT okay = SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &pwstr);
+		PRELOG("SHGetKnownFolderPath(FOLDERID_LocalAppData) returned " << okay);
+		if (SUCCEEDED(okay) && pwstr)
 		{
-			// But of course, only update mOSCacheDir if SHGetFolderPathW() works.
-			mOSCacheDir = utf16str_to_utf8str(llutf16string(w_str));
+			// But of course, only update mOSCacheDir if SHGetKnownFolderPath() works.
+			mOSCacheDir = ll_convert_wide_to_string(pwstr, CP_UTF8);
 			// Update our environment so that child processes will see a
 			// reasonable value as well.
-			_putenv_s("LOCALAPPDATA", mOSCacheDir.c_str());
+			_wputenv_s(L"LOCALAPPDATA", pwstr);
+			// SHGetKnownFolderPath() contract requires us to free pwstr
+			CoTaskMemFree(pwstr);
+			PRELOG("mOSCacheDir='" << mOSCacheDir << "'");
 		}
 	}
 
-- 
cgit v1.2.3


From a4eb5056a717feaf940f125756c7521b9103d41a Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Sat, 8 Dec 2018 11:26:37 -0500
Subject: SL-10153: Need ole32 for new Windows call to CoTaskMemFree().

---
 indra/llvfs/CMakeLists.txt | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/indra/llvfs/CMakeLists.txt b/indra/llvfs/CMakeLists.txt
index 67dce8c073..8578f7a6bd 100644
--- a/indra/llvfs/CMakeLists.txt
+++ b/indra/llvfs/CMakeLists.txt
@@ -98,6 +98,9 @@ if (LL_TESTS)
 
     # INTEGRATION TESTS
     set(test_libs llmath llcommon llvfs ${LLCOMMON_LIBRARIES} ${WINDOWS_LIBRARIES})
+    if (WINDOWS)
+      list(APPEND test_libs ole32)
+    endif (WINDOWS)
 
     # TODO: Some of these need refactoring to be proper Unit tests rather than Integration tests.
     LL_ADD_INTEGRATION_TEST(lldir "" "${test_libs}")
-- 
cgit v1.2.3


From 601cbe1f60b94ae8105329b4e4f745b36721e5aa Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Sat, 8 Dec 2018 12:18:46 -0500
Subject: SL-10153: Add ole32 to WINDOWS_LIBRARIES so it's everywhere we need.

---
 indra/cmake/Linking.cmake             | 1 +
 indra/llvfs/CMakeLists.txt            | 3 ---
 indra/newview/CMakeLists.txt          | 1 -
 indra/win_crash_logger/CMakeLists.txt | 1 -
 4 files changed, 1 insertion(+), 5 deletions(-)

diff --git a/indra/cmake/Linking.cmake b/indra/cmake/Linking.cmake
index 74fe3f1137..3cb235a9d5 100644
--- a/indra/cmake/Linking.cmake
+++ b/indra/cmake/Linking.cmake
@@ -66,6 +66,7 @@ if (WINDOWS)
       wldap32
       gdi32
       user32
+      ole32
       dbghelp
       )
 else (WINDOWS)
diff --git a/indra/llvfs/CMakeLists.txt b/indra/llvfs/CMakeLists.txt
index 8578f7a6bd..67dce8c073 100644
--- a/indra/llvfs/CMakeLists.txt
+++ b/indra/llvfs/CMakeLists.txt
@@ -98,9 +98,6 @@ if (LL_TESTS)
 
     # INTEGRATION TESTS
     set(test_libs llmath llcommon llvfs ${LLCOMMON_LIBRARIES} ${WINDOWS_LIBRARIES})
-    if (WINDOWS)
-      list(APPEND test_libs ole32)
-    endif (WINDOWS)
 
     # TODO: Some of these need refactoring to be proper Unit tests rather than Integration tests.
     LL_ADD_INTEGRATION_TEST(lldir "" "${test_libs}")
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index f10b54d73c..99f99834f3 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1585,7 +1585,6 @@ if (WINDOWS)
         kernel32
         odbc32
         odbccp32
-        ole32
         oleaut32
         shell32
         Vfw32
diff --git a/indra/win_crash_logger/CMakeLists.txt b/indra/win_crash_logger/CMakeLists.txt
index 144d037a31..4fba26ab2f 100644
--- a/indra/win_crash_logger/CMakeLists.txt
+++ b/indra/win_crash_logger/CMakeLists.txt
@@ -89,7 +89,6 @@ target_link_libraries(windows-crash-logger
     ${GOOGLE_PERFTOOLS_LIBRARIES}
     user32
     gdi32
-    ole32
     oleaut32
     wininet
     Wldap32
-- 
cgit v1.2.3


From 221201de4eaba585ae713b279a0e9ba1c8fd61cf Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Sun, 9 Dec 2018 20:57:36 +0200
Subject: SL-10001 Fixed scale

---
 indra/newview/llmanip.cpp | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/indra/newview/llmanip.cpp b/indra/newview/llmanip.cpp
index 1dc03123eb..6589aa477f 100644
--- a/indra/newview/llmanip.cpp
+++ b/indra/newview/llmanip.cpp
@@ -441,14 +441,13 @@ void LLManip::renderXYZ(const LLVector3 &vec)
 		LLUIImagePtr imagep = LLUI::getUIImage("Rounded_Square");
 		gViewerWindow->setup2DRender();
 		const LLVector2& display_scale = gViewerWindow->getDisplayScale();
-		gGL.scalef(display_scale.mV[VX], display_scale.mV[VY], 1.f);
 		gGL.color4f(0.f, 0.f, 0.f, 0.7f);
 
 		imagep->draw(
-			window_center_x - 115, 
-			window_center_y + vertical_offset - PAD, 
-			235,
-			PAD * 2 + 10, 
+			(window_center_x - 115) * display_scale.mV[VX],
+			(window_center_y + vertical_offset - PAD) * display_scale.mV[VY],
+			235 * display_scale.mV[VX],
+			(PAD * 2 + 10) * display_scale.mV[VY],
 			LLColor4(0.f, 0.f, 0.f, 0.7f) );
 
         LLFontGL* font = LLFontGL::getFontSansSerif();
-- 
cgit v1.2.3


From 1e5ad657abcff4f3bd8d4b6f870e15b75215799d Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Mon, 10 Dec 2018 18:28:45 +0200
Subject: SL-10092 Autoreplace Keyword was not working with non-English
 characters

---
 indra/newview/llautoreplace.cpp | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/indra/newview/llautoreplace.cpp b/indra/newview/llautoreplace.cpp
index dd9354fe3a..0516520c56 100644
--- a/indra/newview/llautoreplace.cpp
+++ b/indra/newview/llautoreplace.cpp
@@ -68,8 +68,8 @@ void LLAutoReplace::autoreplaceCallback(S32& replacement_start, S32& replacement
 					word_start--; // walk word_start back to the beginning of the word
 				}
 				LL_DEBUGS("AutoReplace") << "word_start: " << word_start << " word_end: " << word_end << LL_ENDL;
-				std::string str_text  = std::string(input_text.begin(), input_text.end());
-				std::string last_word = str_text.substr(word_start, word_end - word_start + 1);
+				LLWString old_string = input_text.substr(word_start, word_end - word_start + 1);
+				std::string last_word = wstring_to_utf8str(old_string);
 				std::string replacement_word(mSettings.replaceWord(last_word));
 
 				if (replacement_word != last_word)
@@ -79,9 +79,8 @@ void LLAutoReplace::autoreplaceCallback(S32& replacement_start, S32& replacement
 					{
 						// return the replacement string
 						replacement_start = word_start;
-						replacement_length = last_word.length();
+						replacement_length = word_end - word_start + 1;
 						replacement_string = utf8str_to_wstring(replacement_word);
-						LLWString old_string = utf8str_to_wstring(last_word);
 						S32 size_change = replacement_string.size() - old_string.size();
 						cursor_pos += size_change;
 					}
-- 
cgit v1.2.3


From 73eadfa12a23ed5e2e47c208f18795061caff6f3 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 10 Dec 2018 17:11:40 -0500
Subject: INTL-318: Stop processing Danish and Polish language files.

---
 indra/newview/installers/windows/installer_template.nsi | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index b2d376d0c0..9a304559e1 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -51,27 +51,28 @@ RequestExecutionLevel highest           # match MULTIUSER_EXECUTIONLEVEL
 ;; en-us as first language file."
 !include "%%SOURCE%%\installers\windows\lang_en-us.nsi"
 
-!include "%%SOURCE%%\installers\windows\lang_da.nsi"
+# Danish and Polish no longer supported by the viewer itself
+##!include "%%SOURCE%%\installers\windows\lang_da.nsi"
 !include "%%SOURCE%%\installers\windows\lang_de.nsi"
 !include "%%SOURCE%%\installers\windows\lang_es.nsi"
 !include "%%SOURCE%%\installers\windows\lang_fr.nsi"
 !include "%%SOURCE%%\installers\windows\lang_ja.nsi"
 !include "%%SOURCE%%\installers\windows\lang_it.nsi"
-!include "%%SOURCE%%\installers\windows\lang_pl.nsi"
+##!include "%%SOURCE%%\installers\windows\lang_pl.nsi"
 !include "%%SOURCE%%\installers\windows\lang_pt-br.nsi"
 !include "%%SOURCE%%\installers\windows\lang_ru.nsi"
 !include "%%SOURCE%%\installers\windows\lang_tr.nsi"
 !include "%%SOURCE%%\installers\windows\lang_zh.nsi"
 
 # *TODO: Move these into the language files themselves
-LangString LanguageCode ${LANG_DANISH}   "da"
+##LangString LanguageCode ${LANG_DANISH}   "da"
 LangString LanguageCode ${LANG_GERMAN}   "de"
 LangString LanguageCode ${LANG_ENGLISH}  "en"
 LangString LanguageCode ${LANG_SPANISH}  "es"
 LangString LanguageCode ${LANG_FRENCH}   "fr"
 LangString LanguageCode ${LANG_JAPANESE} "ja"
 LangString LanguageCode ${LANG_ITALIAN}  "it"
-LangString LanguageCode ${LANG_POLISH}   "pl"
+##LangString LanguageCode ${LANG_POLISH}   "pl"
 LangString LanguageCode ${LANG_PORTUGUESEBR} "pt"
 LangString LanguageCode ${LANG_RUSSIAN}  "ru"
 LangString LanguageCode ${LANG_TURKISH}  "tr"
-- 
cgit v1.2.3


From 9479d422d4b34e2ffd08017272412ab3bd1ae00e Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 10 Dec 2018 17:14:31 -0500
Subject: SL-10153: Use a degenerate singleton for PRELOG log file.

The previous build declared a static std::ofstream; but the code that
determines the pathname for the log file is called so early that static
objects have not yet been constructed. Declare a pointer instead, and
instantiate it on demand.
---
 indra/llvfs/lldir_win32.cpp | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/indra/llvfs/lldir_win32.cpp b/indra/llvfs/lldir_win32.cpp
index 96bd779b5f..e97424c9a9 100644
--- a/indra/llvfs/lldir_win32.cpp
+++ b/indra/llvfs/lldir_win32.cpp
@@ -30,7 +30,6 @@
 
 #include "lldir_win32.h"
 #include "llerror.h"
-#include "llrand.h"		// for gLindenLabRandomNumber
 #include "stringize.h"
 #include "llfile.h"
 #include <shlobj.h>
@@ -47,8 +46,10 @@ DWORD GetDllVersion(LPCTSTR lpszDllName);
 
 namespace
 { // anonymous
-    enum class prst { INIT, OPEN, SKIP } state;
-    llofstream prelogf;
+    enum class prst { INIT, OPEN, SKIP } state = prst::INIT;
+    // This is called so early that we can't count on static objects being
+    // properly constructed yet, so declare a pointer instead of an instance.
+    std::ofstream* prelogf = nullptr;
 
     void prelog(const std::string& message)
     {
@@ -64,18 +65,18 @@ namespace
             if (! prelog_name)
                 // no PRELOG variable set, carry on
                 return;
-            prelogf.open(prelog_name, std::ios_base::app);
-            if (! prelogf.is_open())
+            prelogf = new std::ofstream(prelog_name, std::ios_base::app);
+            if (! (prelogf && prelogf->is_open()))
                 // can't complain to anybody; how?
                 return;
             // got the log file open, cool!
             state = prst::OPEN;
-            prelogf << "========================================================================"
-                    << std::endl;
+            (*prelogf) << "========================================================================"
+                       << std::endl;
             // fall through, don't break
 
         case prst::OPEN:
-            prelogf << message << std::endl;
+            (*prelogf) << message << std::endl;
             break;
 
         case prst::SKIP:
-- 
cgit v1.2.3


From 63d601679168d0bf8de2600bb74e435f54096b9a Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 11 Dec 2018 09:06:41 -0500
Subject: SL-10153: Update to viewer-manager build 522443

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index ebda8c791d..f646843086 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3138,9 +3138,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>f76807ee2425b1532595bc716456fa6a</string>
+              <string>9ff6f24f703663e82489253c0a1fae8a</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28665/237854/viewer_manager-2.0.522407-darwin64-522407.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28732/238505/viewer_manager-2.0.522443-darwin64-522443.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3162,9 +3162,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>5cb25b4d66f9a8d4f485b7eab7d02ed0</string>
+              <string>6e9d92a0810619377dd8f3dccee9e594</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28666/237860/viewer_manager-2.0.522407-windows-522407.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28731/238511/viewer_manager-2.0.522443-windows-522443.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3175,7 +3175,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.522407</string>
+        <string>2.0.522443</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From d72dd8a35dadefb816ad29bb9e41559fa288679a Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 11 Dec 2018 15:47:17 -0500
Subject: SL-10153: Update to viewer-manager build 522465

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index f646843086..ddf07016ae 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3138,9 +3138,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>9ff6f24f703663e82489253c0a1fae8a</string>
+              <string>cf01ec13d504668201fe820ea2289024</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28732/238505/viewer_manager-2.0.522443-darwin64-522443.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28777/239560/viewer_manager-2.0.522465-darwin64-522465.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3162,9 +3162,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>6e9d92a0810619377dd8f3dccee9e594</string>
+              <string>f6c99e3647a5eb01292d0a2362131869</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28731/238511/viewer_manager-2.0.522443-windows-522443.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28776/239566/viewer_manager-2.0.522465-windows-522465.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3175,7 +3175,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.522443</string>
+        <string>2.0.522465</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From bb4a649b9c324e7989de6e59398c85e80fe2acc7 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 11 Dec 2018 15:47:29 -0500
Subject: SL-10153: Validate APPDATA, LOCALAPPDATA by checking existence.

---
 indra/llvfs/lldir_win32.cpp | 21 ++++++++-------------
 1 file changed, 8 insertions(+), 13 deletions(-)

diff --git a/indra/llvfs/lldir_win32.cpp b/indra/llvfs/lldir_win32.cpp
index e97424c9a9..fc4680bbfb 100644
--- a/indra/llvfs/lldir_win32.cpp
+++ b/indra/llvfs/lldir_win32.cpp
@@ -104,17 +104,13 @@ LLDir_Win32::LLDir_Win32()
 		mOSUserDir = ll_convert_wide_to_string(APPDATA, CP_UTF8);
 	}
 	PRELOG("APPDATA='" << mOSUserDir << "'");
-	// On Windows, it's a Bad Thing if a pathname contains ASCII question
-	// marks. In our experience, it means that the original pathname contained
-	// non-ASCII characters that were munged to '?' somewhere along the way.
-	// Convert to LLWString first, though, in case one of the bytes in a
-	// non-ASCII UTF-8 string accidentally resembles '?'.
-	// Bear in mind that llwchar is not necessarily wchar_t, therefore L'?' is
-	// not necessarily the right type.
-	if (mOSUserDir.empty() ||
-		utf8string_to_wstring(mOSUserDir).find(llwchar('?')) != LLWString::npos)
+	// On Windows, we could have received a plain-ASCII pathname in which
+	// non-ASCII characters have been munged to '?', or the pathname could
+	// have been badly encoded and decoded such that we now have garbage
+	// instead of a valid path. Check that mOSUserDir actually exists.
+	if (mOSUserDir.empty() || ! fileExists(mOSUserDir))
 	{
-		PRELOG("APPDATA empty or contains ASCII '?'");
+		PRELOG("APPDATA does not exist");
 		//HRESULT okay = SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, w_str);
 		wchar_t *pwstr = NULL;
 		HRESULT okay = SHGetKnownFolderPath(FOLDERID_RoamingAppData, 0, NULL, &pwstr);
@@ -149,10 +145,9 @@ LLDir_Win32::LLDir_Win32()
 	PRELOG("LOCALAPPDATA='" << mOSCacheDir << "'");
 	// Windows really does not deal well with pathnames containing non-ASCII
 	// characters. See above remarks about APPDATA.
-	if (mOSCacheDir.empty() ||
-		utf8string_to_wstring(mOSCacheDir).find(llwchar('?')) != LLWString::npos)
+	if (mOSCacheDir.empty() || ! fileExists(mOSCacheDir))
 	{
-		PRELOG("LOCALAPPDATA empty or contains ASCII '?'");
+		PRELOG("LOCALAPPDATA does not exist");
 		//HRESULT okay = SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, w_str);
 		wchar_t *pwstr = NULL;
 		HRESULT okay = SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &pwstr);
-- 
cgit v1.2.3


From c658e891345fd98dcededa5c21efc17993805522 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Wed, 12 Dec 2018 15:24:26 +0200
Subject: SL-9512 Move constant to common place

---
 indra/newview/lltoastnotifypanel.cpp   | 8 +++-----
 indra/newview/lltoastpanel.cpp         | 3 +++
 indra/newview/lltoastpanel.h           | 1 +
 indra/newview/lltoastscripttextbox.cpp | 4 +---
 4 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index e3a856be5c..a2116817a2 100644
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -46,8 +46,6 @@
 const S32 BOTTOM_PAD = VPAD * 3;
 const S32 IGNORE_BTN_TOP_DELTA = 3*VPAD;//additional ignore_btn padding
 S32 BUTTON_WIDTH = 90;
-// *TODO: magic numbers - copied from llnotify.cpp(250)
-const S32 MAX_LENGTH = 512 + 20 + DB_FIRST_NAME_BUF_SIZE + DB_LAST_NAME_BUF_SIZE + DB_INV_ITEM_NAME_BUF_SIZE; 
 
 
 //static
@@ -319,7 +317,7 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )
         mTextBox = getChild<LLTextEditor>("text_editor_box"); 
     }
 
-    mTextBox->setMaxTextLength(MAX_LENGTH);
+    mTextBox->setMaxTextLength(LLToastPanel::MAX_TEXT_LENGTH);
     mTextBox->setVisible(TRUE);
     mTextBox->setPlainText(!show_images);
     mTextBox->setContentTrusted(is_content_trusted);
@@ -411,7 +409,7 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )
 	//.xml file intially makes info panel only follow left/right/top. This is so that when control buttons are added the info panel 
 	//can shift upward making room for the buttons inside mControlPanel. After the buttons are added, the info panel can then be set to follow 'all'.
 	mInfoPanel->setFollowsAll();
-    snapToMessageHeight(mTextBox, MAX_LENGTH);
+	snapToMessageHeight(mTextBox, LLToastPanel::MAX_TEXT_LENGTH);
 
 	// reshape the panel to its previous size
 	if (current_rect.notEmpty())
@@ -472,7 +470,7 @@ void LLIMToastNotifyPanel::snapToMessageHeight()
 	//Add message height if it is visible
 	if (mTextBox->getVisible())
 	{
-		S32 new_panel_height = computeSnappedToMessageHeight(mTextBox, MAX_LENGTH);
+		S32 new_panel_height = computeSnappedToMessageHeight(mTextBox, LLToastPanel::MAX_TEXT_LENGTH);
 
 		//reshape the panel with new height
 		if (new_panel_height != getRect().getHeight())
diff --git a/indra/newview/lltoastpanel.cpp b/indra/newview/lltoastpanel.cpp
index e1b764a943..7c624d5b50 100644
--- a/indra/newview/lltoastpanel.cpp
+++ b/indra/newview/lltoastpanel.cpp
@@ -26,6 +26,7 @@
 
 #include "llviewerprecompiledheaders.h"
 
+#include "lldbstrings.h"
 #include "llpanelgenerictip.h"
 #include "llpanelonlinestatus.h"
 #include "llnotifications.h"
@@ -35,6 +36,8 @@
 
 //static
 const S32 LLToastPanel::MIN_PANEL_HEIGHT = 40; // VPAD(4)*2 + ICON_HEIGHT(32)
+// 'magic numbers', consider initializing (512+20) part from xml/notifications
+const S32 LLToastPanel::MAX_TEXT_LENGTH = 512 + 20 + DB_FIRST_NAME_BUF_SIZE + DB_LAST_NAME_BUF_SIZE + DB_INV_ITEM_NAME_BUF_SIZE;
 
 LLToastPanel::LLToastPanel(const LLNotificationPtr& notification)
 {
diff --git a/indra/newview/lltoastpanel.h b/indra/newview/lltoastpanel.h
index 51630381f2..6a9b72a5ae 100644
--- a/indra/newview/lltoastpanel.h
+++ b/indra/newview/lltoastpanel.h
@@ -49,6 +49,7 @@ public:
 	virtual const LLUUID& getID();
 
 	static const S32 MIN_PANEL_HEIGHT;
+	static const S32 MAX_TEXT_LENGTH;
 
 	/**
 	 * Builder method for constructing notification specific panels.
diff --git a/indra/newview/lltoastscripttextbox.cpp b/indra/newview/lltoastscripttextbox.cpp
index 518c6c0ee4..eb86a44055 100644
--- a/indra/newview/lltoastscripttextbox.cpp
+++ b/indra/newview/lltoastscripttextbox.cpp
@@ -36,8 +36,6 @@
 #include "llviewertexteditor.h"
 
 const S32 LLToastScriptTextbox::DEFAULT_MESSAGE_MAX_LINE_COUNT= 14;
-// *TODO: magic numbers - copied from lltoastnotifypanel.cpp(50) which was copied from llnotify.cpp(250)
-const S32 MAX_LENGTH = 512 + 20 + DB_FIRST_NAME_BUF_SIZE + DB_LAST_NAME_BUF_SIZE + DB_INV_ITEM_NAME_BUF_SIZE;
 
 LLToastScriptTextbox::LLToastScriptTextbox(const LLNotificationPtr& notification)
 :	LLToastPanel(notification)
@@ -45,7 +43,7 @@ LLToastScriptTextbox::LLToastScriptTextbox(const LLNotificationPtr& notification
 	buildFromFile( "panel_notify_textbox.xml");
 
 	mInfoText = getChild<LLTextEditor>("text_editor_box");
-	mInfoText->setMaxTextLength(MAX_LENGTH);
+	mInfoText->setMaxTextLength(LLToastPanel::MAX_TEXT_LENGTH);
 	mInfoText->setValue(notification->getMessage());
 
 	getChild<LLButton>("ignore_btn")->setClickedCallback(boost::bind(&LLToastScriptTextbox::onClickIgnore, this));
-- 
cgit v1.2.3


From 21d4ce26d3b3db5458321271ea5b7c7069289c94 Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Wed, 12 Dec 2018 00:11:16 +0200
Subject: INTL-324 added support for TLS failure dialog localization

---
 indra/newview/llxmlrpctransaction.cpp          | 31 ++++++--------------------
 indra/newview/skins/default/xui/en/strings.xml | 25 +++++++++++++++++++++
 2 files changed, 32 insertions(+), 24 deletions(-)

diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp
index f5c169996f..cc223c1f48 100644
--- a/indra/newview/llxmlrpctransaction.cpp
+++ b/indra/newview/llxmlrpctransaction.cpp
@@ -483,42 +483,25 @@ void LLXMLRPCTransaction::Impl::setHttpStatus(const LLCore::HttpStatus &status)
 {
 	CURLcode code = static_cast<CURLcode>(status.toULong());
 	std::string message;
-	std::string uri = "http://secondlife.com/community/support.php";
+	std::string uri = "http://support.secondlife.com";
 	LLURI failuri(mURI);
-
+	LLStringUtil::format_map_t args;
 
 	switch (code)
 	{
 	case CURLE_COULDNT_RESOLVE_HOST:
-		message =
-			std::string("DNS could not resolve the host name(") + failuri.hostName() + ").\n"
-			"Please verify that you can connect to the www.secondlife.com\n"
-			"web site.  If you can, but continue to receive this error,\n"
-			"please go to the support section and report this problem.";
+		args["[HOSTNAME]"] = failuri.hostName();
+		message = LLTrans::getString("couldnt_resolve_host", args);
 		break;
 
 	case CURLE_SSL_PEER_CERTIFICATE:
-		message =
-			"The login server couldn't verify itself via SSL.\n"
-			"If you continue to receive this error, please go\n"
-			"to the Support section of the SecondLife.com web site\n"
-			"and report the problem.";
+		message = LLTrans::getString("ssl_peer_certificate");
 		break;
 
 	case CURLE_SSL_CACERT:
-	case CURLE_SSL_CONNECT_ERROR:
-		{
-		std::string uri_base = "https://community.secondlife.com/knowledgebase/english/error-messages-r520/#Section__3";
-		message =
-			"Often this means that your computer\'s clock is set incorrectly.\n"
-			"Please go to Control Panels and make sure the time and date\n"
-			"are set correctly.\n"
-			"Also check that your network and firewall are set up correctly.\n"
-			"If you continue to receive this error, please go\n"
-			"to the Support section of the SecondLife.com web site\n"
-			"and report the problem.\n\n[" + uri_base + " Knowledge Base]";
+	case CURLE_SSL_CONNECT_ERROR:		
+		message = LLTrans::getString("ssl_connect_error");
 		break;
-		}
 
 	default:
 		break;
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index f5f4b4acab..e8fdb2d5b1 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -4233,4 +4233,29 @@ Try enclosing path to the editor with double quotes.
       The physics shape does not have correct version. Set the correct version for the physics model.
   </string>
 
+  <!-- CURL error messages -->
+  <string name="couldnt_resolve_host">
+DNS could not resolve the host name([HOSTNAME]).
+Please verify that you can connect to the www.secondlife.com
+web site.  If you can, but continue to receive this error,
+please go to the support section and report this problem.
+  </string>
+  <string name="ssl_peer_certificate">
+The login server couldn't verify itself via SSL.
+If you continue to receive this error, please go
+to the Support section of the SecondLife.com web site
+and report the problem.
+  </string>
+  <string name="ssl_connect_error">
+Often this means that your computer's clock is set incorrectly.
+Please go to Control Panels and make sure the time and date
+are set correctly.
+Also check that your network and firewall are set up correctly.
+If you continue to receive this error, please go
+to the Support section of the SecondLife.com web site
+and report the problem.
+
+[https://community.secondlife.com/knowledgebase/english/error-messages-r520/#Section__3 Knowledge Base]
+  </string>
+
 </strings>
-- 
cgit v1.2.3


From 4e894eb2a7ed6651c54890cd20106bfacd61ef0a Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 11 Dec 2018 20:48:20 -0500
Subject: SL-10153: Improve ll_convert_string_to_wide() and its converse.

Instead of returning a wchar_t* and requiring the caller to delete it later,
return a std::basic_string<wchar_t> that's self-cleaning. If the caller wants
a wchar_t*, s/he can call c_str() on the returned string.

Default the code_page parameter to CP_UTF8, since we try to be really
consistent about using UTF-8 encoding for all our internal std::strings.
---
 indra/llcommon/llstring.cpp | 32 ++++++++++++++++++++++----------
 indra/llcommon/llstring.h   | 10 ++++++----
 2 files changed, 28 insertions(+), 14 deletions(-)

diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp
index 9a02fecd72..42390c8a7b 100644
--- a/indra/llcommon/llstring.cpp
+++ b/indra/llcommon/llstring.cpp
@@ -30,6 +30,7 @@
 #include "llerror.h"
 #include "llfasttimer.h"
 #include "llsd.h"
+#include <vector>
 
 #if LL_WINDOWS
 #include "llwin32headerslean.h"
@@ -672,6 +673,11 @@ namespace snprintf_hack
 	}
 }
 
+std::string ll_convert_wide_to_string(const wchar_t* in)
+{
+	return ll_convert_wide_to_string(in, CP_UTF8);
+}
+
 std::string ll_convert_wide_to_string(const wchar_t* in, unsigned int code_page)
 {
 	std::string out;
@@ -709,7 +715,12 @@ std::string ll_convert_wide_to_string(const wchar_t* in, unsigned int code_page)
 	return out;
 }
 
-wchar_t* ll_convert_string_to_wide(const std::string& in, unsigned int code_page)
+std::basic_string<wchar_t> ll_convert_string_to_wide(const std::string& in)
+{
+	return ll_convert_string_to_wide(in, CP_UTF8);
+}
+
+std::basic_string<wchar_t> ll_convert_string_to_wide(const std::string& in, unsigned int code_page)
 {
 	// From review:
 	// We can preallocate a wide char buffer that is the same length (in wchar_t elements) as the utf8 input,
@@ -719,24 +730,25 @@ wchar_t* ll_convert_string_to_wide(const std::string& in, unsigned int code_page
 	// but we *are* seeing string operations taking a bunch of time, especially when constructing widgets.
 //	int output_str_len = MultiByteToWideChar(code_page, 0, in.c_str(), in.length(), NULL, 0);
 
-	// reserve place to NULL terminator
-	int output_str_len = in.length();
-	wchar_t* w_out = new wchar_t[output_str_len + 1];
+	// reserve an output buffer that will be destroyed on exit, with a place
+	// to put NULL terminator
+	std::vector<wchar_t> w_out(in.length() + 1);
 
-	memset(w_out, 0, output_str_len + 1);
-	int real_output_str_len = MultiByteToWideChar (code_page, 0, in.c_str(), in.length(), w_out, output_str_len);
+	memset(&w_out[0], 0, w_out.size());
+	int real_output_str_len = MultiByteToWideChar(code_page, 0, in.c_str(), in.length(),
+												  &w_out[0], w_out.size() - 1);
 
 	//looks like MultiByteToWideChar didn't add null terminator to converted string, see EXT-4858.
 	w_out[real_output_str_len] = 0;
 
-	return w_out;
+	// construct string<wchar_t> from our temporary output buffer
+	return {&w_out[0]};
 }
 
 std::string ll_convert_string_to_utf8_string(const std::string& in)
 {
-	wchar_t* w_mesg = ll_convert_string_to_wide(in, CP_ACP);
-	std::string out_utf8(ll_convert_wide_to_string(w_mesg, CP_UTF8));
-	delete[] w_mesg;
+	auto w_mesg = ll_convert_string_to_wide(in, CP_ACP);
+	std::string out_utf8(ll_convert_wide_to_string(w_mesg.c_str(), CP_UTF8));
 
 	return out_utf8;
 }
diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h
index 68ee9db46b..7c3e9f952d 100644
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -635,16 +635,18 @@ using snprintf_hack::snprintf;
  * This replaces the unsafe W2A macro from ATL.
  */
 LL_COMMON_API std::string ll_convert_wide_to_string(const wchar_t* in, unsigned int code_page);
+LL_COMMON_API std::string ll_convert_wide_to_string(const wchar_t* in); // default CP_UTF8
 
 /**
  * Converts a string to wide string.
- *
- * It will allocate memory for result string with "new []". Don't forget to release it with "delete []".
  */
-LL_COMMON_API wchar_t* ll_convert_string_to_wide(const std::string& in, unsigned int code_page);
+LL_COMMON_API std::basic_string<wchar_t> ll_convert_string_to_wide(const std::string& in,
+                                                                   unsigned int code_page);
+LL_COMMON_API std::basic_string<wchar_t> ll_convert_string_to_wide(const std::string& in);
+                                                                   // default CP_UTF8
 
 /**
- * Converts incoming string into urf8 string
+ * Converts incoming string into utf8 string
  *
  */
 LL_COMMON_API std::string ll_convert_string_to_utf8_string(const std::string& in);
-- 
cgit v1.2.3


From 02b9ac8d9a349b757a426842b5125057d11c0bbb Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 11 Dec 2018 20:51:51 -0500
Subject: SL-10153: Fix OSMessageBoxWin32() to handle non-ASCII text.

---
 indra/llwindow/llwindowwin32.cpp | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 4ee4a5357c..504c1589b0 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -3275,8 +3275,10 @@ S32 OSMessageBoxWin32(const std::string& text, const std::string& caption, U32 t
 		break;
 	}
 
-	// HACK! Doesn't properly handle wide strings!
-	int retval_win = MessageBoxA(NULL, text.c_str(), caption.c_str(), uType);
+	int retval_win = MessageBoxW(NULL, // HWND
+								 ll_convert_string_to_wide(text).c_str(),
+								 ll_convert_string_to_wide(caption).c_str(),
+								 uType);
 	S32 retval;
 
 	switch(retval_win)
-- 
cgit v1.2.3


From 701ae96ff685847c8ddb46a4460fd70940733255 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Thu, 13 Dec 2018 12:37:18 +0200
Subject: SL-10228 FIXED HTTP/HTTPS URL in the object name is represented as a
 hyperlink in message floater

---
 .../newview/skins/default/xui/en/notifications.xml | 28 +++++++++++-----------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index cc57e1375a..23a8d21f8a 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -1845,7 +1845,7 @@ You are not allowed to terraform parcel [PARCEL].
    name="CannotCopyWarning"
    type="alertmodal">
 You do not have permission to copy the following items:
-[ITEMS]
+&lt;nolink&gt;[ITEMS]&lt;/nolink&gt;
 and will lose it from your inventory if you give it away. Do you really want to offer these items?
     <tag>confirm</tag>
     <usetemplate
@@ -9479,7 +9479,7 @@ You Can't create trees and grass on land you don't own.
    name="NoCopyPermsNoObject"
    type="notify">
    <tag>fail</tag>
-Copy failed because you lack permission to copy the object '[OBJ_NAME]'.
+Copy failed because you lack permission to copy the object &lt;nolink&gt;'[OBJ_NAME]'&lt;/nolink&gt;.
   </notification>
 
   <notification
@@ -9487,7 +9487,7 @@ Copy failed because you lack permission to copy the object '[OBJ_NAME]'.
    name="NoTransPermsNoObject"
    type="notify">
    <tag>fail</tag>
-Copy failed because the object '[OBJ_NAME]' cannot be transferred to you.
+Copy failed because the object &lt;nolink&gt;'[OBJ_NAME]'&lt;/nolink&gt; cannot be transferred to you.
   </notification>
 
   <notification
@@ -9495,7 +9495,7 @@ Copy failed because the object '[OBJ_NAME]' cannot be transferred to you.
    name="AddToNavMeshNoCopy"
    type="notify">
    <tag>fail</tag>
-Copy failed because the object '[OBJ_NAME]' contributes to navmesh.
+Copy failed because the object &lt;nolink&gt;'[OBJ_NAME]'&lt;/nolink&gt; contributes to navmesh.
   </notification>
 
   <notification
@@ -9619,7 +9619,7 @@ Save Back To Inventory has been disabled.
    name="NoExistNoSaveToContents"
    type="notify">
    <tag>fail</tag>
-Cannot save '[OBJ_NAME]' to object contents because the object it was rezzed from no longer exists.
+Cannot save &lt;nolink&gt;'[OBJ_NAME]'&lt;/nolink&gt; to object contents because the object it was rezzed from no longer exists.
   </notification>
 
   <notification
@@ -9627,7 +9627,7 @@ Cannot save '[OBJ_NAME]' to object contents because the object it was rezzed fro
    name="NoModNoSaveToContents"
    type="notify">
    <tag>fail</tag>
-Cannot save '[OBJ_NAME]' to object contents because you do not have permission to modify the object '[DEST_NAME]'.
+Cannot save &lt;nolink&gt;'[OBJ_NAME]'&lt;/nolink&gt; to object contents because you do not have permission to modify the object &lt;nolink&gt;'[DEST_NAME]'&lt;/nolink&gt;.
   </notification>
 
   <notification
@@ -9635,7 +9635,7 @@ Cannot save '[OBJ_NAME]' to object contents because you do not have permission t
    name="NoSaveBackToInvDisabled"
    type="notify">
    <tag>fail</tag>
-Cannot save '[OBJ_NAME]' back to inventory -- this operation has been disabled.
+Cannot save &lt;nolink&gt;'[OBJ_NAME]'&lt;/nolink&gt; back to inventory -- this operation has been disabled.
   </notification>
 
   <notification
@@ -9643,7 +9643,7 @@ Cannot save '[OBJ_NAME]' back to inventory -- this operation has been disabled.
    name="NoCopyNoSelCopy"
    type="notify">
    <tag>fail</tag>
-You cannot copy your selection because you do not have permission to copy the object '[OBJ_NAME]'.
+You cannot copy your selection because you do not have permission to copy the object &lt;nolink&gt;'[OBJ_NAME]'&lt;/nolink&gt;.
   </notification>
 
   <notification
@@ -9651,7 +9651,7 @@ You cannot copy your selection because you do not have permission to copy the ob
    name="NoTransNoSelCopy"
    type="notify">
    <tag>fail</tag>
-You cannot copy your selection because the object '[OBJ_NAME]' is not transferrable.
+You cannot copy your selection because the object &lt;nolink&gt;'[OBJ_NAME]'&lt;/nolink&gt; is not transferrable.
   </notification>
 
   <notification
@@ -9659,7 +9659,7 @@ You cannot copy your selection because the object '[OBJ_NAME]' is not transferra
    name="NoTransNoCopy"
    type="notify">
    <tag>fail</tag>
-You cannot copy your selection because the object '[OBJ_NAME]' is not transferrable.
+You cannot copy your selection because the object &lt;nolink&gt;'[OBJ_NAME]'&lt;/nolink&gt; is not transferrable.
   </notification>
 
   <notification
@@ -9667,7 +9667,7 @@ You cannot copy your selection because the object '[OBJ_NAME]' is not transferra
    name="NoPermsNoRemoval"
    type="notify">
    <tag>fail</tag>
-Removal of the object '[OBJ_NAME]' from the simulator is disallowed by the permissions system.
+Removal of the object &lt;nolink&gt;'[OBJ_NAME]'&lt;/nolink&gt; from the simulator is disallowed by the permissions system.
   </notification>
 
   <notification
@@ -9675,7 +9675,7 @@ Removal of the object '[OBJ_NAME]' from the simulator is disallowed by the permi
    name="NoModNoSaveSelection"
    type="notify">
    <tag>fail</tag>
-Cannot save your selection because you do not have permission to modify the object '[OBJ_NAME]'.
+Cannot save your selection because you do not have permission to modify the object &lt;nolink&gt;'[OBJ_NAME]'&lt;/nolink&gt;.
   </notification>
 
   <notification
@@ -9683,7 +9683,7 @@ Cannot save your selection because you do not have permission to modify the obje
    name="NoCopyNoSaveSelection"
    type="notify">
    <tag>fail</tag>
-Cannot save your selection because the object '[OBJ_NAME]' is not copyable.
+Cannot save your selection because the object &lt;nolink&gt;'[OBJ_NAME]'&lt;/nolink&gt; is not copyable.
   </notification>
 
   <notification
@@ -9691,7 +9691,7 @@ Cannot save your selection because the object '[OBJ_NAME]' is not copyable.
    name="NoModNoTaking"
    type="notify">
    <tag>fail</tag>
-You cannot take your selection because you do not have permission to modify the object '[OBJ_NAME]'.
+You cannot take your selection because you do not have permission to modify the object &lt;nolink&gt;'[OBJ_NAME]'&lt;/nolink&gt;.
   </notification>
 
   <notification
-- 
cgit v1.2.3


From aa90985d677dfea573216b1a3a58acaa3b866656 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Wed, 12 Dec 2018 20:21:21 +0200
Subject: SL-10231 Bug in texture cache size computation

---
 indra/newview/lltexturecache.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index 633e025478..eb4b914e18 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -1038,11 +1038,11 @@ S64 LLTextureCache::initCache(ELLPath location, S64 max_size, BOOL texture_cache
 {
 	llassert_always(getPending() == 0) ; //should not start accessing the texture cache before initialized.
 
-	S64 header_size = (max_size / 100) * 36; //0.36 * max_size
-	S64 max_entries = header_size / (TEXTURE_CACHE_ENTRY_SIZE + TEXTURE_FAST_CACHE_ENTRY_SIZE);
+	S64 entries_size = (max_size * 36) / 100; //0.36 * max_size
+	S64 max_entries = entries_size / (TEXTURE_CACHE_ENTRY_SIZE + TEXTURE_FAST_CACHE_ENTRY_SIZE);
 	sCacheMaxEntries = (S32)(llmin((S64)sCacheMaxEntries, max_entries));
-	header_size = sCacheMaxEntries * TEXTURE_CACHE_ENTRY_SIZE;
-	max_size -= header_size;
+	entries_size = sCacheMaxEntries * (TEXTURE_CACHE_ENTRY_SIZE + TEXTURE_FAST_CACHE_ENTRY_SIZE);
+	max_size -= entries_size;
 	if (sCacheMaxTexturesSize > 0)
 		sCacheMaxTexturesSize = llmin(sCacheMaxTexturesSize, max_size);
 	else
-- 
cgit v1.2.3


From 80054757ed0eee816c253a7707576252b7e89d9e Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Thu, 13 Dec 2018 00:10:52 +0200
Subject: SL-1481 Time limit should be per object

---
 indra/newview/llviewerobject.cpp | 14 +++++++-------
 indra/newview/llviewerobject.h   |  1 +
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 079a9f0372..007adf2a72 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -261,6 +261,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
 	mLastInterpUpdateSecs(0.f),
 	mLastMessageUpdateSecs(0.f),
 	mLatestRecvPacketID(0),
+	mRegionCrossExpire(0),
 	mData(NULL),
 	mAudioSourcep(NULL),
 	mAudioGain(1.f),
@@ -2636,8 +2637,7 @@ void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& frame_tim
 		new_pos.mV[VZ] = llmax(min_height, new_pos.mV[VZ]);
 
 		// Check to see if it's going off the region
-		LLVector3 temp(new_pos);
-		static F64SecondsImplicit region_cross_expire = 0; // frame time we detected region crossing in + wait time
+		LLVector3 temp(new_pos.mV[VX], new_pos.mV[VY], 0.f);
 		if (temp.clamp(0.f, mRegionp->getWidth()))
 		{	// Going off this region, so see if we might end up on another region
 			LLVector3d old_pos_global = mRegionp->getPosGlobalFromRegion(getPositionRegion());
@@ -2664,28 +2664,28 @@ void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& frame_tim
 				// Note: theoretically we can find time from velocity, acceleration and
 				// distance from border to new position, but it is not going to work
 				// if 'phase_out' activates
-				if (region_cross_expire == 0)
+				if (mRegionCrossExpire == 0)
 				{
 					// Workaround: we can't accurately figure out time when we cross border
 					// so just write down time 'after the fact', it is far from optimal in
 					// case of lags, but for lags sMaxUpdateInterpolationTime will kick in first
 					LL_DEBUGS("Interpolate") << "Predicted region crossing, new position " << new_pos << LL_ENDL;
-					region_cross_expire = frame_time + sMaxRegionCrossingInterpolationTime;
+					mRegionCrossExpire = frame_time + sMaxRegionCrossingInterpolationTime;
 				}
-				else if (frame_time > region_cross_expire)
+				else if (frame_time > mRegionCrossExpire)
 				{
 					// Predicting crossing over 1s, stop motion
 					// Stop motion
 					LL_DEBUGS("Interpolate") << "Predicting region crossing for too long, stopping at " << new_pos << LL_ENDL;
 					new_v.clear();
 					setAcceleration(LLVector3::zero);
-					region_cross_expire = 0;
+					mRegionCrossExpire = 0;
 				}
 			}
 		}
 		else
 		{
-			region_cross_expire = 0;
+			mRegionCrossExpire = 0;
 		}
 
 		// Set new position and velocity
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 990c392531..8b1535851e 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -772,6 +772,7 @@ protected:
 	F64Seconds		mLastInterpUpdateSecs;			// Last update for purposes of interpolation
 	F64Seconds		mLastMessageUpdateSecs;			// Last update from a message from the simulator
 	TPACKETID		mLatestRecvPacketID;			// Latest time stamp on message from simulator
+	F64SecondsImplicit mRegionCrossExpire;		// frame time we detected region crossing in + wait time
 
 	// extra data sent from the sim...currently only used for tree species info
 	U8* mData;
-- 
cgit v1.2.3


From 5111e0c921d17b83b41aef02b6334a8361ce1181 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Thu, 13 Dec 2018 18:21:11 +0200
Subject: SL-10229 FIXED Group icon doesn't display by default in the People
 and Profile floaters after creating new group

---
 indra/newview/llpanelgroupgeneral.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index f85a2ffbc1..b53cd222e7 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -461,11 +461,12 @@ bool LLPanelGroupGeneral::createGroupCallback(const LLSD& notification, const LL
 			// Yay!  We are making a new group!
 			U32 enrollment_fee = (mCtrlEnrollmentFee->get() ? 
 									(U32) mSpinEnrollmentFee->get() : 0);
-		
+			LLUUID insignia_id = mInsignia->getImageItemID().isNull() ? LLUUID::null : mInsignia->getImageAssetID();
+
 			LLGroupMgr::getInstance()->sendCreateGroupRequest(mGroupNameEditor->getText(),
 												mEditCharter->getText(),
 												mCtrlShowInGroupList->get(),
-												mInsignia->getImageAssetID(),
+												insignia_id,
 												enrollment_fee,
 												mCtrlOpenEnrollment->get(),
 												false,
-- 
cgit v1.2.3


From cbf4295b63fcc7128f928d1718efe069a9f3a789 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 13 Dec 2018 12:02:38 -0500
Subject: SL-10153: Update to viewer-manager build 522507

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index ddf07016ae..3b4eb2cd87 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3138,9 +3138,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>cf01ec13d504668201fe820ea2289024</string>
+              <string>e2bef561238448fe512146baa6dacabc</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28777/239560/viewer_manager-2.0.522465-darwin64-522465.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28859/240421/viewer_manager-2.0.522507-darwin64-522507.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3162,9 +3162,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>f6c99e3647a5eb01292d0a2362131869</string>
+              <string>75cdf1afc293423553b6d190ce422412</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28776/239566/viewer_manager-2.0.522465-windows-522465.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28858/240427/viewer_manager-2.0.522507-windows-522507.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3175,7 +3175,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.522465</string>
+        <string>2.0.522507</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From bf2efcf43e5efaf91220a0c77f3db792636edeb1 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Fri, 14 Dec 2018 16:48:54 +0200
Subject: SL-10233 FIXED 'Default' button doesn't work in 'Pick:Texture'
 floater for multiple selections with different textures

---
 indra/newview/lltexturectrl.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index a5a2eec246..1a2a10f721 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -131,7 +131,7 @@ LLFloaterTexturePicker::~LLFloaterTexturePicker()
 
 void LLFloaterTexturePicker::setImageID(const LLUUID& image_id, bool set_selection /*=true*/)
 {
-	if( mImageAssetID != image_id && mActive)
+	if( ((mImageAssetID != image_id) || mTentative) && mActive)
 	{
 		mNoCopyTextureSelected = FALSE;
 		mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
-- 
cgit v1.2.3


From 514e4f661bbf4355ead4e60288c0075cc945b597 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Thu, 13 Dec 2018 20:01:01 +0200
Subject: SL-10236 The "Attach To", "Attach To HUD", and "Wear" options aren't
 greyed out

---
 indra/newview/llinventorybridge.cpp |  5 ++++-
 indra/newview/lloutfitslist.cpp     | 21 +++++++++++++++++++--
 indra/newview/llviewermenu.cpp      | 18 ++++++------------
 3 files changed, 29 insertions(+), 15 deletions(-)

diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 1987e15850..e7367d5ced 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -7344,7 +7344,10 @@ void LLFolderViewGroupedItemBridge::groupFilterContextMenu(folder_view_item_dequ
     {
 		if (!LLAppearanceMgr::instance().canAddWearables(ids) && canWearSelected(ids))
         {
-			disabled_items.push_back(std::string("Wearable Add"));
+            disabled_items.push_back(std::string("Wearable And Object Wear"));
+            disabled_items.push_back(std::string("Wearable Add"));
+            disabled_items.push_back(std::string("Attach To"));
+            disabled_items.push_back(std::string("Attach To HUD"));
         }
     }
 	disable_context_entries_if_present(menu, disabled_items);
diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp
index 892fa385d7..f2a284a561 100644
--- a/indra/newview/lloutfitslist.cpp
+++ b/indra/newview/lloutfitslist.cpp
@@ -621,8 +621,14 @@ void LLOutfitsList::applyFilterToTab(
 
 bool LLOutfitsList::canWearSelected()
 {
+	if (!isAgentAvatarValid())
+	{
+		return false;
+	}
+
 	uuid_vec_t selected_items;
 	getSelectedItemsUUIDs(selected_items);
+	S32 nonreplacable_objects = 0;
 
 	for (uuid_vec_t::const_iterator it = selected_items.begin(); it != selected_items.end(); ++it)
 	{
@@ -633,10 +639,21 @@ bool LLOutfitsList::canWearSelected()
 		{
 			return false;
 		}
+
+		const LLViewerInventoryItem* item = gInventory.getItem(id);
+		if (!item)
+		{
+			return false;
+		}
+
+		if (item->getType() == LLAssetType::AT_OBJECT)
+		{
+			nonreplacable_objects++;
+		}
 	}
 
-	// All selected items can be worn.
-	return true;
+	// All selected items can be worn. But do we have enough space for them?
+	return nonreplacable_objects == 0 || gAgentAvatarp->canAttachMoreObjects(nonreplacable_objects);
 }
 
 void LLOutfitsList::wearSelectedItems()
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 6c52f118ad..ba68ce4cf4 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -7068,25 +7068,19 @@ BOOL object_selected_and_point_valid()
 
 BOOL object_is_wearable()
 {
-	if (!object_selected_and_point_valid())
+	if (!isAgentAvatarValid())
 	{
 		return FALSE;
 	}
-	if (sitting_on_selection())
+	if (!object_selected_and_point_valid())
 	{
 		return FALSE;
 	}
-	LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
-	for (LLObjectSelection::valid_root_iterator iter = LLSelectMgr::getInstance()->getSelection()->valid_root_begin();
-		 iter != LLSelectMgr::getInstance()->getSelection()->valid_root_end(); iter++)
+	if (sitting_on_selection())
 	{
-		LLSelectNode* node = *iter;		
-		if (node->mPermissions->getOwner() == gAgent.getID())
-		{
-			return TRUE;
-		}
+		return FALSE;
 	}
-	return FALSE;
+	return gAgentAvatarp->canAttachMoreObjects();
 }
 
 
@@ -9207,7 +9201,7 @@ void initialize_menus()
 	enable.add("Object.EnableOpen", boost::bind(&enable_object_open));
 	enable.add("Object.EnableTouch", boost::bind(&enable_object_touch, _1));
 	enable.add("Object.EnableDelete", boost::bind(&enable_object_delete));
-	enable.add("Object.EnableWear", boost::bind(&object_selected_and_point_valid));
+	enable.add("Object.EnableWear", boost::bind(&object_is_wearable));
 
 	enable.add("Object.EnableStandUp", boost::bind(&enable_object_stand_up));
 	enable.add("Object.EnableSit", boost::bind(&enable_object_sit, _1));
-- 
cgit v1.2.3


From 9ffcafb64b4483c315d00e88ffc1438bce1f7915 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 14 Dec 2018 10:48:43 -0500
Subject: SL-10153: Introduce ll_convert, windows_message() templates.

Add ll_convert<TO, FROM> template, used as (e.g.):
ll_convert<std::string>(value_of_some_other_string_type);
There is no generic template implementation -- the template exists solely to
provide generic aliases for a bewildering family of llstring.h string-
conversion functions with highly-specific names. There's a generic
implementation, though, for the degenerate case where FROM and TO are
identical.

Add ll_convert<> specialization aliases for most of the string-conversion
functions declared in llstring.h, including the Windows-specific ones
involving llutf16string and std::wstring.

Add a mini-lecture in llstring.h about appropriate use of string types on
Windows.

Add LL_WCHAR_T_NATIVE llpreprocessor.h macro so we can detect whether to
provide separate conversions for llutf16string and std::wstring, or whether
those would collide because the types are identical.

Add inline ll_convert_wide_to_string(const std::wstring&) overloads so caller
isn't required to call arg.c_str(), which naturally permits an ll_convert
alias.

Add ll_convert_wide_to_wstring(), ll_convert_wstring_to_wide() as placeholders
for converting between Windows std::wstring and Linden LLWString, with
corresponding ll_convert aliases. We don't yet have library code to perform
such conversions officially; for now, just copy characters.

Add LLStringUtil::getenv(key) and getoptenv(key) functions. The latter returns
boost::optional<string_type> in case the caller needs to detect absence of a
given environment variable rather than simply accepting a default value.
Naturally getenv(), which accepts a default, is implemented using getoptenv().
getoptenv(), in turn, is implemented using an underlying llstring_getoptenv().

On Windows, llstring_getoptenv() returns boost::optional<std::wstring> (based
on GetEnvironmentVariableW()), whereas elsewhere, llstring_getoptenv() returns
boost::optional<std::string> (based on classic Posix getenv()).

The beauty of generic ll_convert is that the portable LLStringUtilBase<T>::
getoptenv() template can call the platform-specific llstring_getoptenv() and
transparently perform whatever conversion is necessary to return the desired
string_type.

Add windows_message<T>(error) template, with an overload that implicitly calls
GetLastError(). We provide a single concrete windows_message<std::wstring>()
implementation because that's what we get from Windows FormatMessageW() --
everything else is a generic conversion to the desired target string type.

This obviates llprocess.cpp's previous WindowsErrorString() implementation --
reimplement using windows_message<std::string>().
---
 indra/llcommon/llpreprocessor.h |  21 +++++
 indra/llcommon/llprocess.cpp    |  27 +-----
 indra/llcommon/llstring.cpp     | 125 +++++++++++++++++++++++++++-
 indra/llcommon/llstring.h       | 176 ++++++++++++++++++++++++++++++++++++++--
 indra/llcommon/stdtypes.h       |   7 +-
 5 files changed, 323 insertions(+), 33 deletions(-)

diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h
index ef015fdce4..e8f9981437 100644
--- a/indra/llcommon/llpreprocessor.h
+++ b/indra/llcommon/llpreprocessor.h
@@ -101,6 +101,9 @@
 
 #endif
 
+// Although thread_local is now a standard storage class, we can't just
+// #define LL_THREAD_LOCAL as thread_local because the *usage* is different.
+// We'll have to take the time to change LL_THREAD_LOCAL declarations by hand.
 #if LL_WINDOWS
 # define LL_THREAD_LOCAL __declspec(thread)
 #else
@@ -177,6 +180,24 @@
 #define LL_DLLIMPORT
 #endif // LL_WINDOWS
 
+#if ! defined(LL_WINDOWS)
+#define LL_WCHAR_T_NATIVE 1
+#else  // LL_WINDOWS
+// https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros
+// _WCHAR_T_DEFINED is defined if wchar_t is provided at all.
+// Specifically, it has value 1 if wchar_t is an intrinsic type, else empty.
+// _NATIVE_WCHAR_T_DEFINED has value 1 if wchar_t is intrinsic, else undefined.
+// For years we have compiled with /Zc:wchar_t-, meaning that wchar_t is a
+// typedef for unsigned short (in stddef.h). Lore has it that one of our
+// proprietary binary-only libraries has traditionally been built that way and
+// therefore EVERYTHING ELSE requires it. Therefore, in a typical Linden
+// Windows build, _WCHAR_T_DEFINED is defined but empty, while
+// _NATIVE_WCHAR_T_DEFINED is undefined.
+# if defined(_NATIVE_WCHAR_T_DEFINED)
+#  define LL_WCHAR_T_NATIVE 1
+# endif // _NATIVE_WCHAR_T_DEFINED
+#endif // LL_WINDOWS
+
 #if LL_COMMON_LINK_SHARED
 // CMake automagically defines llcommon_EXPORTS only when building llcommon
 // sources, and only when llcommon is a shared library (i.e. when
diff --git a/indra/llcommon/llprocess.cpp b/indra/llcommon/llprocess.cpp
index 5753efdc59..1fa53f322b 100644
--- a/indra/llcommon/llprocess.cpp
+++ b/indra/llcommon/llprocess.cpp
@@ -1205,30 +1205,9 @@ static LLProcess::Status interpret_status(int status)
 /// GetLastError()/FormatMessage() boilerplate
 static std::string WindowsErrorString(const std::string& operation)
 {
-	int result = GetLastError();
-
-	LPTSTR error_str = 0;
-	if (FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
-					   NULL,
-					   result,
-					   0,
-					   (LPTSTR)&error_str,
-					   0,
-					   NULL)
-		!= 0) 
-	{
-		// convert from wide-char string to multi-byte string
-		char message[256];
-		wcstombs(message, error_str, sizeof(message));
-		message[sizeof(message)-1] = 0;
-		LocalFree(error_str);
-		// convert to std::string to trim trailing whitespace
-		std::string mbsstr(message);
-		mbsstr.erase(mbsstr.find_last_not_of(" \t\r\n"));
-		return STRINGIZE(operation << " failed (" << result << "): " << mbsstr);
-	}
-	return STRINGIZE(operation << " failed (" << result
-					 << "), but FormatMessage() did not explain");
+	auto result = GetLastError();
+	return STRINGIZE(operation << " failed (" << result << "): "
+					 << windows_message<std::string>(result));
 }
 
 /*****************************************************************************
diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp
index 42390c8a7b..f931103ba6 100644
--- a/indra/llcommon/llstring.cpp
+++ b/indra/llcommon/llstring.cpp
@@ -53,6 +53,40 @@ std::string ll_safe_string(const char* in, S32 maxlen)
 	return std::string();
 }
 
+boost::optional<std::wstring> llstring_getoptenv(const std::string& key)
+{
+    auto wkey = ll_convert_string_to_wide(key);
+    // Take a wild guess as to how big the buffer should be.
+    std::vector<wchar_t> buffer(1024);
+    auto n = GetEnvironmentVariableW(wkey.c_str(), &buffer[0], buffer.size());
+    // If our initial guess was too short, n will indicate the size (in
+    // wchar_t's) that buffer should have been, including the terminating nul.
+    if (n > (buffer.size() - 1))
+    {
+        // make it big enough
+        buffer.resize(n);
+        // and try again
+        n = GetEnvironmentVariableW(wkey.c_str(), &buffer[0], buffer.size());
+    }
+    // did that (ultimately) succeed?
+    if (n)
+    {
+        // great, return populated boost::optional
+        return { &buffer[0] };
+    }
+
+    // not successful
+    auto last_error = GetLastError();
+    // Don't bother warning for NOT_FOUND; that's an expected case
+    if (last_error != ERROR_ENVVAR_NOT_FOUND)
+    {
+        LL_WARNS() << "GetEnvironmentVariableW('" << key << "') failed: "
+                   << windows_message<std::string>(last_error) << LL_ENDL;
+    }
+    // return empty boost::optional
+    return {};
+}
+
 bool is_char_hex(char hex)
 {
 	if((hex >= '0') && (hex <= '9'))
@@ -715,12 +749,12 @@ std::string ll_convert_wide_to_string(const wchar_t* in, unsigned int code_page)
 	return out;
 }
 
-std::basic_string<wchar_t> ll_convert_string_to_wide(const std::string& in)
+std::wstring ll_convert_string_to_wide(const std::string& in)
 {
 	return ll_convert_string_to_wide(in, CP_UTF8);
 }
 
-std::basic_string<wchar_t> ll_convert_string_to_wide(const std::string& in, unsigned int code_page)
+std::wstring ll_convert_string_to_wide(const std::string& in, unsigned int code_page)
 {
 	// From review:
 	// We can preallocate a wide char buffer that is the same length (in wchar_t elements) as the utf8 input,
@@ -745,6 +779,24 @@ std::basic_string<wchar_t> ll_convert_string_to_wide(const std::string& in, unsi
 	return {&w_out[0]};
 }
 
+LLWString ll_convert_wide_to_wstring(const std::wstring& in)
+{
+    // This function, like its converse, is a placeholder, encapsulating a
+    // guilty little hack: the only "official" way nat has found to convert
+    // between std::wstring (16 bits on Windows) and LLWString (UTF-32) is
+    // by using iconv, which we've avoided so far. It kinda sorta works to
+    // just copy individual characters...
+    // The point is that if/when we DO introduce some more official way to
+    // perform such conversions, we should only have to call it here.
+    return { in.begin(), in.end() };
+}
+
+std::wstring ll_convert_wstring_to_wide(const LLWString& in)
+{
+    // See comments in ll_convert_wide_to_wstring()
+    return { in.begin(), in.end() };
+}
+
 std::string ll_convert_string_to_utf8_string(const std::string& in)
 {
 	auto w_mesg = ll_convert_string_to_wide(in, CP_ACP);
@@ -752,7 +804,74 @@ std::string ll_convert_string_to_utf8_string(const std::string& in)
 
 	return out_utf8;
 }
-#endif // LL_WINDOWS
+
+namespace
+{
+
+void HeapFree_deleter(void* ptr)
+{
+    // instead of LocalFree(), per https://stackoverflow.com/a/31541205
+    HeapFree(GetProcessHeap(), NULL, ptr);
+}
+
+} // anonymous namespace
+
+template<>
+std::wstring windows_message<std::wstring>(DWORD error)
+{
+    // derived from https://stackoverflow.com/a/455533
+    wchar_t* rawptr = nullptr;
+    auto okay = FormatMessageW(
+        // use system message tables for GetLastError() codes
+        FORMAT_MESSAGE_FROM_SYSTEM |
+        // internally allocate buffer and return its pointer
+        FORMAT_MESSAGE_ALLOCATE_BUFFER |
+        // you cannot pass insertion parameters (thanks Gandalf)
+        FORMAT_MESSAGE_IGNORE_INSERTS |
+        // ignore line breaks in message definition text
+        FORMAT_MESSAGE_MAX_WIDTH_MASK,
+        NULL,                       // lpSource, unused with FORMAT_MESSAGE_FROM_SYSTEM
+        error,                      // dwMessageId
+        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // dwLanguageId
+        (LPWSTR)&rawptr,         // lpBuffer: force-cast wchar_t** to wchar_t*
+        0,                // nSize, unused with FORMAT_MESSAGE_ALLOCATE_BUFFER
+        NULL);            // Arguments, unused
+
+    // make a unique_ptr from rawptr so it gets cleaned up properly
+    std::unique_ptr<wchar_t, void(*)(void*)> bufferptr(rawptr, HeapFree_deleter);
+
+    if (okay && bufferptr)
+    {
+        // got the message, return it ('okay' is length in characters)
+        return { bufferptr.get(), okay };
+    }
+
+    // did not get the message, synthesize one
+    auto format_message_error = GetLastError();
+    std::wostringstream out;
+    out << L"GetLastError() " << error << L" (FormatMessageW() failed with "
+        << format_message_error << L")";
+    return out.str();
+}
+
+#else  // ! LL_WINDOWS
+
+boost::optional<std::string> llstring_getoptenv(const std::string& key)
+{
+    auto found = getenv(key.c_str());
+    if (found)
+    {
+        // return populated boost::optional
+        return { found };
+    }
+    else
+    {
+        // return empty boost::optional
+        return {};
+    }
+}
+
+#endif // ! LL_WINDOWS
 
 long LLStringOps::sPacificTimeOffset = 0;
 long LLStringOps::sLocalTimeOffset = 0;
diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h
index 7c3e9f952d..2dccc7cbdf 100644
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -27,6 +27,7 @@
 #ifndef LL_LLSTRING_H
 #define LL_LLSTRING_H
 
+#include <boost/optional/optional.hpp>
 #include <string>
 #include <cstdio>
 //#include <locale>
@@ -337,6 +338,19 @@ public:
 		const string_type& string,
 		const string_type& substr);
 
+	/**
+	 * get environment string value with proper Unicode handling
+	 * (key is always UTF-8)
+	 * detect absence by return value == dflt
+	 */
+	static string_type getenv(const std::string& key, const string_type& dflt="");
+	/**
+	 * get optional environment string value with proper Unicode handling
+	 * (key is always UTF-8)
+	 * detect absence by (! return value)
+	 */
+	static boost::optional<string_type> getoptenv(const std::string& key);
+
 	static void	addCRLF(string_type& string);
 	static void	removeCRLF(string_type& string);
 	static void removeWindowsCR(string_type& string);
@@ -496,6 +510,37 @@ LL_COMMON_API bool iswindividual(llwchar elem);
  * Unicode support
  */
 
+/// generic conversion aliases
+template<typename TO, typename FROM, typename Enable=void>
+struct ll_convert_impl
+{
+    // Don't even provide a generic implementation. We specialize for every
+    // combination we do support.
+    TO operator()(const FROM& in) const;
+};
+
+// Use a function template to get the nice ll_convert<TO>(from_value) API.
+template<typename TO, typename FROM>
+TO ll_convert(const FROM& in)
+{
+    return ll_convert_impl<TO, FROM>()(in);
+}
+
+// degenerate case
+template<typename T>
+struct ll_convert_impl<T, T>
+{
+    T operator()(const T& in) const { return in; }
+};
+
+// specialize ll_convert_impl<TO, FROM> to return EXPR
+#define ll_convert_alias(TO, FROM, EXPR)                    \
+template<>                                                  \
+struct ll_convert_impl<TO, FROM>                            \
+{                                                           \
+    TO operator()(const FROM& in) const { return EXPR; }    \
+}
+
 // Make the incoming string a utf8 string. Replaces any unknown glyph
 // with the UNKNOWN_CHARACTER. Once any unknown glyph is found, the rest
 // of the data may not be recovered.
@@ -503,30 +548,83 @@ LL_COMMON_API std::string rawstr_to_utf8(const std::string& raw);
 
 //
 // We should never use UTF16 except when communicating with Win32!
+// https://docs.microsoft.com/en-us/cpp/cpp/char-wchar-t-char16-t-char32-t
+// nat 2018-12-14: I consider the whole llutf16string thing a mistake, because
+// the Windows APIs we want to call are all defined in terms of wchar_t*
+// (or worse, LPCTSTR).
+// https://docs.microsoft.com/en-us/windows/desktop/winprog/windows-data-types
+
+// While there is no point coding for an ASCII-only world (! defined(UNICODE)),
+// use of U16 and llutf16string for Windows APIs locks in /Zc:wchar_t-. Going
+// forward, we should code in terms of wchar_t and std::wstring so as to
+// support either setting of /Zc:wchar_t.
+
+// The first link above states that char can be used to hold ASCII or any
+// multi-byte character set, and distinguishes wchar_t (UTF-16LE), char16_t
+// (UTF-16) and char32_t (UTF-32). Nonetheless, within this code base:
+// * char and std::string always hold UTF-8 (of which ASCII is a subset). It
+//   is a BUG if they are used to pass strings in any other multi-byte
+//   encoding.
+// * wchar_t and std::wstring should be our interface to Windows wide-string
+//   APIs, and therefore hold UTF-16LE.
+// * U16 and llutf16string are the previous but DEPRECATED UTF-16LE type. Do
+//   not introduce new uses of U16 or llutf16string for string data.
+// * llwchar and LLWString hold UTF-32 strings.
+// * Do not introduce char16_t or std::u16string.
+// * Do not introduce char32_t or std::u32string.
 //
+// This typedef may or may not be identical to std::wstring, depending on
+// LL_WCHAR_T_NATIVE.
 typedef std::basic_string<U16> llutf16string;
 
+#if ! defined(LL_WCHAR_T_NATIVE)
+// wchar_t is identical to U16, and std::wstring is identical to llutf16string.
+// Defining an ll_convert alias involving llutf16string would collide with the
+// comparable preferred alias involving std::wstring. (In this scenario, if
+// you pass llutf16string, it will engage the std::wstring specialization.)
+#define ll_convert_u16_alias(TO, FROM, EXPR) // nothing
+#else
+// wchar_t is a distinct native type, so llutf16string is also a distinct
+// type, and there IS a point to converting separately to/from llutf16string.
+// (But why? Windows APIs are still defined in terms of wchar_t, and
+// in this scenario llutf16string won't work for them!)
+#define ll_convert_u16_alias(TO, FROM, EXPR) ll_convert_alias(TO, FROM, EXPR)
+
+// converting between std::wstring and llutf16string involves copying chars
+// enclose the brace-initialization expression in parens to protect the comma
+// from macro-argument parsing
+ll_convert_alias(llutf16string, std::wstring, ({ in.begin(), in.end() }));
+ll_convert_alias(std::wstring, llutf16string, ({ in.begin(), in.end() }));
+#endif
+
 LL_COMMON_API LLWString utf16str_to_wstring(const llutf16string &utf16str, S32 len);
 LL_COMMON_API LLWString utf16str_to_wstring(const llutf16string &utf16str);
+ll_convert_u16_alias(LLWString, llutf16string, utf16str_to_wstring(in));
 
 LL_COMMON_API llutf16string wstring_to_utf16str(const LLWString &utf32str, S32 len);
 LL_COMMON_API llutf16string wstring_to_utf16str(const LLWString &utf32str);
+ll_convert_u16_alias(llutf16string, LLWString, wstring_to_utf16str(in));
 
 LL_COMMON_API llutf16string utf8str_to_utf16str ( const std::string& utf8str, S32 len);
 LL_COMMON_API llutf16string utf8str_to_utf16str ( const std::string& utf8str );
+ll_convert_u16_alias(llutf16string, std::string, utf8str_to_utf16str(in));
 
 LL_COMMON_API LLWString utf8str_to_wstring(const std::string &utf8str, S32 len);
 LL_COMMON_API LLWString utf8str_to_wstring(const std::string &utf8str);
 // Same function, better name. JC
 inline LLWString utf8string_to_wstring(const std::string& utf8_string) { return utf8str_to_wstring(utf8_string); }
+// best name of all
+ll_convert_alias(LLWString, std::string, utf8string_to_wstring(in));
 
 //
 LL_COMMON_API S32 wchar_to_utf8chars(llwchar inchar, char* outchars);
 
 LL_COMMON_API std::string wstring_to_utf8str(const LLWString &utf32str, S32 len);
 LL_COMMON_API std::string wstring_to_utf8str(const LLWString &utf32str);
+ll_convert_alias(std::string, LLWString, wstring_to_utf8str(in));
 LL_COMMON_API std::string utf16str_to_utf8str(const llutf16string &utf16str, S32 len);
 LL_COMMON_API std::string utf16str_to_utf8str(const llutf16string &utf16str);
+ll_convert_u16_alias(std::string, llutf16string, utf16str_to_utf8str(in));
 
 #if LL_WINDOWS
 inline std::string wstring_to_utf8str(const llutf16string &utf16str) { return utf16str_to_utf8str(utf16str);}
@@ -636,14 +734,36 @@ using snprintf_hack::snprintf;
  */
 LL_COMMON_API std::string ll_convert_wide_to_string(const wchar_t* in, unsigned int code_page);
 LL_COMMON_API std::string ll_convert_wide_to_string(const wchar_t* in); // default CP_UTF8
+inline std::string ll_convert_wide_to_string(const std::wstring& in, unsigned int code_page)
+{
+    return ll_convert_wide_to_string(in.c_str(), code_page);
+}
+inline std::string ll_convert_wide_to_string(const std::wstring& in)
+{
+    return ll_convert_wide_to_string(in.c_str());
+}
+ll_convert_alias(std::string, std::wstring, ll_convert_wide_to_string(in));
 
 /**
  * Converts a string to wide string.
  */
-LL_COMMON_API std::basic_string<wchar_t> ll_convert_string_to_wide(const std::string& in,
-                                                                   unsigned int code_page);
-LL_COMMON_API std::basic_string<wchar_t> ll_convert_string_to_wide(const std::string& in);
-                                                                   // default CP_UTF8
+LL_COMMON_API std::wstring ll_convert_string_to_wide(const std::string& in,
+                                                     unsigned int code_page);
+LL_COMMON_API std::wstring ll_convert_string_to_wide(const std::string& in);
+                                                     // default CP_UTF8
+ll_convert_alias(std::wstring, std::string, ll_convert_string_to_wide(in));
+
+/**
+ * Convert a Windows wide string to our LLWString
+ */
+LL_COMMON_API LLWString ll_convert_wide_to_wstring(const std::wstring& in);
+ll_convert_alias(LLWString, std::wstring, ll_convert_wide_to_wstring(in));
+
+/**
+ * Convert LLWString to Windows wide string
+ */
+LL_COMMON_API std::wstring ll_convert_wstring_to_wide(const LLWString& in);
+ll_convert_alias(std::wstring, LLWString, ll_convert_wstring_to_wide(in));
 
 /**
  * Converts incoming string into utf8 string
@@ -651,8 +771,39 @@ LL_COMMON_API std::basic_string<wchar_t> ll_convert_string_to_wide(const std::st
  */
 LL_COMMON_API std::string ll_convert_string_to_utf8_string(const std::string& in);
 
+/// Get Windows message string for passed GetLastError() code
+// VS 2013 doesn't let us forward-declare this template, which is what we
+// started with, so the implementation could reference the specialization we
+// haven't yet declared. Somewhat weirdly, just stating the generic
+// implementation in terms of the specialization works, even in this order...
+
+// the general case is just a conversion from the sole implementation
+// Microsoft says DWORD is a typedef for unsigned long
+// https://docs.microsoft.com/en-us/windows/desktop/winprog/windows-data-types
+// so rather than drag windows.h into everybody's include space...
+template<typename STRING>
+STRING windows_message(unsigned long error)
+{
+    return ll_convert<STRING>(windows_message<std::wstring>(error));
+}
+
+/// There's only one real implementation
+template<>
+LL_COMMON_API std::wstring windows_message<std::wstring>(unsigned long error);
+
+/// Get Windows message string, implicitly calling GetLastError()
+template<typename STRING>
+STRING windows_message() { return windows_message<STRING>(GetLastError()); }
+
 //@}
-#endif // LL_WINDOWS
+
+LL_COMMON_API boost::optional<std::wstring> llstring_getoptenv(const std::string& key);
+
+#else // ! LL_WINDOWS
+
+LL_COMMON_API boost::optional<std::string>  llstring_getoptenv(const std::string& key);
+
+#endif // ! LL_WINDOWS
 
 /**
  * Many of the 'strip' and 'replace' methods of LLStringUtilBase need
@@ -1595,6 +1746,21 @@ bool LLStringUtilBase<T>::endsWith(
 	return (idx == (string.size() - substr.size()));
 }
 
+// static
+template<class T>
+auto LLStringUtilBase<T>::getoptenv(const std::string& key) -> boost::optional<string_type>
+{
+    auto found{llstring_getoptenv(key)};
+    return found? { ll_convert<string_type>(*found) } : {};
+}
+
+// static
+template<class T>
+auto LLStringUtilBase<T>::getenv(const std::string& key, const string_type& dflt) -> string_type
+{
+    auto found{getoptenv(key)};
+    return found? *found : dflt;
+}
 
 template<class T> 
 BOOL LLStringUtilBase<T>::convertToBOOL(const string_type& string, BOOL& value)
diff --git a/indra/llcommon/stdtypes.h b/indra/llcommon/stdtypes.h
index bf3f3f9ee8..6c9871e76c 100644
--- a/indra/llcommon/stdtypes.h
+++ b/indra/llcommon/stdtypes.h
@@ -37,7 +37,12 @@ typedef signed int			S32;
 typedef unsigned int			U32;
 
 #if LL_WINDOWS
-// Windows wchar_t is 16-bit
+// https://docs.microsoft.com/en-us/cpp/build/reference/zc-wchar-t-wchar-t-is-native-type
+// https://docs.microsoft.com/en-us/cpp/cpp/fundamental-types-cpp
+// Windows wchar_t is 16-bit, whichever way /Zc:wchar_t is set. In effect,
+// Windows wchar_t is always a typedef, either for unsigned short or __wchar_t.
+// (__wchar_t, available either way, is Microsoft's native 2-byte wchar_t type.)
+// In any case, llwchar should be a UTF-32 type.
 typedef U32				llwchar;
 #else
 typedef wchar_t				llwchar;
-- 
cgit v1.2.3


From 132e708fec50fd756b822925313456c70a4ff27f Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 14 Dec 2018 12:01:51 -0500
Subject: SL-10153: Fix previous commit for non-Windows systems.

Move Windows-flavored llstring_getoptenv() to Windows-specific section of
llstring.cpp.

boost::optional type must be stated explicitly to initialize with a value.

On platforms where llwchar is the same as wchar_t, LLWString is the same as
std::wstring, so ll_convert specializations for std::wstring would duplicate
those for LLWString. Defend against that.

The compilers we use don't like 'return condition? { expr } : {}', in which we
hope to construct and return an instance of the declared return type without
having to restate the type. It works to use an explicit 'if' statement.
---
 indra/llcommon/llstring.cpp | 70 ++++++++++++++++++++++-----------------------
 indra/llcommon/llstring.h   | 30 +++++++++++++------
 2 files changed, 57 insertions(+), 43 deletions(-)

diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp
index f931103ba6..0174c411b4 100644
--- a/indra/llcommon/llstring.cpp
+++ b/indra/llcommon/llstring.cpp
@@ -53,40 +53,6 @@ std::string ll_safe_string(const char* in, S32 maxlen)
 	return std::string();
 }
 
-boost::optional<std::wstring> llstring_getoptenv(const std::string& key)
-{
-    auto wkey = ll_convert_string_to_wide(key);
-    // Take a wild guess as to how big the buffer should be.
-    std::vector<wchar_t> buffer(1024);
-    auto n = GetEnvironmentVariableW(wkey.c_str(), &buffer[0], buffer.size());
-    // If our initial guess was too short, n will indicate the size (in
-    // wchar_t's) that buffer should have been, including the terminating nul.
-    if (n > (buffer.size() - 1))
-    {
-        // make it big enough
-        buffer.resize(n);
-        // and try again
-        n = GetEnvironmentVariableW(wkey.c_str(), &buffer[0], buffer.size());
-    }
-    // did that (ultimately) succeed?
-    if (n)
-    {
-        // great, return populated boost::optional
-        return { &buffer[0] };
-    }
-
-    // not successful
-    auto last_error = GetLastError();
-    // Don't bother warning for NOT_FOUND; that's an expected case
-    if (last_error != ERROR_ENVVAR_NOT_FOUND)
-    {
-        LL_WARNS() << "GetEnvironmentVariableW('" << key << "') failed: "
-                   << windows_message<std::string>(last_error) << LL_ENDL;
-    }
-    // return empty boost::optional
-    return {};
-}
-
 bool is_char_hex(char hex)
 {
 	if((hex >= '0') && (hex <= '9'))
@@ -854,6 +820,40 @@ std::wstring windows_message<std::wstring>(DWORD error)
     return out.str();
 }
 
+boost::optional<std::wstring> llstring_getoptenv(const std::string& key)
+{
+    auto wkey = ll_convert_string_to_wide(key);
+    // Take a wild guess as to how big the buffer should be.
+    std::vector<wchar_t> buffer(1024);
+    auto n = GetEnvironmentVariableW(wkey.c_str(), &buffer[0], buffer.size());
+    // If our initial guess was too short, n will indicate the size (in
+    // wchar_t's) that buffer should have been, including the terminating nul.
+    if (n > (buffer.size() - 1))
+    {
+        // make it big enough
+        buffer.resize(n);
+        // and try again
+        n = GetEnvironmentVariableW(wkey.c_str(), &buffer[0], buffer.size());
+    }
+    // did that (ultimately) succeed?
+    if (n)
+    {
+        // great, return populated boost::optional
+        return boost::optional<std::wstring>(&buffer[0]);
+    }
+
+    // not successful
+    auto last_error = GetLastError();
+    // Don't bother warning for NOT_FOUND; that's an expected case
+    if (last_error != ERROR_ENVVAR_NOT_FOUND)
+    {
+        LL_WARNS() << "GetEnvironmentVariableW('" << key << "') failed: "
+                   << windows_message<std::string>(last_error) << LL_ENDL;
+    }
+    // return empty boost::optional
+    return {};
+}
+
 #else  // ! LL_WINDOWS
 
 boost::optional<std::string> llstring_getoptenv(const std::string& key)
@@ -862,7 +862,7 @@ boost::optional<std::string> llstring_getoptenv(const std::string& key)
     if (found)
     {
         // return populated boost::optional
-        return { found };
+        return boost::optional<std::string>(found);
     }
     else
     {
diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h
index 2dccc7cbdf..87cb35c59c 100644
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -583,19 +583,24 @@ typedef std::basic_string<U16> llutf16string;
 // comparable preferred alias involving std::wstring. (In this scenario, if
 // you pass llutf16string, it will engage the std::wstring specialization.)
 #define ll_convert_u16_alias(TO, FROM, EXPR) // nothing
-#else
+#else  // defined(LL_WCHAR_T_NATIVE)
 // wchar_t is a distinct native type, so llutf16string is also a distinct
 // type, and there IS a point to converting separately to/from llutf16string.
 // (But why? Windows APIs are still defined in terms of wchar_t, and
 // in this scenario llutf16string won't work for them!)
 #define ll_convert_u16_alias(TO, FROM, EXPR) ll_convert_alias(TO, FROM, EXPR)
 
-// converting between std::wstring and llutf16string involves copying chars
-// enclose the brace-initialization expression in parens to protect the comma
-// from macro-argument parsing
-ll_convert_alias(llutf16string, std::wstring, ({ in.begin(), in.end() }));
-ll_convert_alias(std::wstring, llutf16string, ({ in.begin(), in.end() }));
-#endif
+#if LL_WINDOWS
+// LL_WCHAR_T_NATIVE is defined on non-Windows systems because, in fact,
+// wchar_t is native. Everywhere but Windows, we use it for llwchar (see
+// stdtypes.h). That makes LLWString identical to std::wstring, so these
+// aliases for std::wstring would collide with those for LLWString. Only
+// define on Windows, where converting between std::wstring and llutf16string
+// means copying chars.
+ll_convert_alias(llutf16string, std::wstring, llutf16string(in.begin(), in.end()));
+ll_convert_alias(std::wstring, llutf16string,  std::wstring(in.begin(), in.end()));
+#endif // LL_WINDOWS
+#endif // defined(LL_WCHAR_T_NATIVE)
 
 LL_COMMON_API LLWString utf16str_to_wstring(const llutf16string &utf16str, S32 len);
 LL_COMMON_API LLWString utf16str_to_wstring(const llutf16string &utf16str);
@@ -1751,7 +1756,16 @@ template<class T>
 auto LLStringUtilBase<T>::getoptenv(const std::string& key) -> boost::optional<string_type>
 {
     auto found{llstring_getoptenv(key)};
-    return found? { ll_convert<string_type>(*found) } : {};
+    if (found)
+    {
+        // return populated boost::optional
+        return { ll_convert<string_type>(*found) };
+    }
+    else
+    {
+        // empty boost::optional
+        return {};
+    }
 }
 
 // static
-- 
cgit v1.2.3


From c4096f670c7b3d43f8a5c1f65ef7e02033b0329d Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 14 Dec 2018 15:38:13 -0500
Subject: SL-10153: Review and rationalize fetching paths from environment.

Use LLStringUtil::getenv() or getoptenv() whenever we fetch a string that will
be used as a pathname.

Use LLFile::tmpdir() instead of getenv("TEMP").

As an added extra-special bonus, finally clean up $TMP/llcontrol-test-zzzzzz
directories that have been accumulating every time we run a local build!
---
 indra/llcommon/llfile.cpp                   | 19 +++++----
 indra/llcommon/tests/llleap_test.cpp        |  7 ++--
 indra/llcommon/tests/llprocess_test.cpp     |  5 ++-
 indra/llcommon/tests/llsdserialize_test.cpp |  7 ++--
 indra/llmessage/tests/commtest.h            |  8 +---
 indra/llmessage/tests/llhttpclient_test.cpp |  9 +++--
 indra/llrender/llfontgl.cpp                 | 41 ++++++++------------
 indra/llvfs/lldir_linux.cpp                 | 33 ++++++++--------
 indra/llvfs/lldir_solaris.cpp               | 60 ++++++++++++-----------------
 indra/llvfs/lldir_win32.cpp                 | 26 ++++++-------
 indra/llxml/tests/llcontrol_test.cpp        | 39 ++++++++-----------
 indra/newview/llexternaleditor.cpp          |  7 ++--
 indra/newview/llwebprofile.cpp              |  4 +-
 13 files changed, 116 insertions(+), 149 deletions(-)

diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp
index fc203f78e1..8355b1e797 100644
--- a/indra/llcommon/llfile.cpp
+++ b/indra/llcommon/llfile.cpp
@@ -30,6 +30,7 @@
 #if LL_WINDOWS
 #include "llwin32headerslean.h"
 #include <stdlib.h>                 // Windows errno
+#include <vector>
 #else
 #include <errno.h>
 #endif
@@ -134,8 +135,10 @@ int warnif(const std::string& desc, const std::string& filename, int rc, int acc
 		{
 			// Only do any of this stuff (before LL_ENDL) if it will be logged.
 			LL_DEBUGS("LLFile") << empty;
-			const char* TEMP = getenv("TEMP");
-			if (! TEMP)
+			// would be nice to use LLDir for this, but dependency goes the
+			// wrong way
+			const char* TEMP = LLFile::tmpdir();
+			if (! (TEMP && *TEMP))
 			{
 				LL_CONT << "No $TEMP, not running 'handle'";
 			}
@@ -341,17 +344,13 @@ const char *LLFile::tmpdir()
 #if LL_WINDOWS
 		sep = '\\';
 
-		DWORD len = GetTempPathW(0, L"");
-		llutf16string utf16path;
-		utf16path.resize(len + 1);
-		len = GetTempPathW(static_cast<DWORD>(utf16path.size()), &utf16path[0]);
-		utf8path = utf16str_to_utf8str(utf16path);
+		std::vector<wchar_t> utf16path(MAX_PATH + 1);
+		GetTempPathW(utf16path.size(), &utf16path[0]);
+		utf8path = ll_convert_wide_to_string(&utf16path[0]);
 #else
 		sep = '/';
 
-		char *env = getenv("TMPDIR");
-
-		utf8path = env ? env : "/tmp/";
+		utf8path = LLStringUtil::getenv("TMPDIR", "/tmp/");
 #endif
 		if (utf8path[utf8path.size() - 1] != sep)
 		{
diff --git a/indra/llcommon/tests/llleap_test.cpp b/indra/llcommon/tests/llleap_test.cpp
index c387da6c48..45648536c4 100644
--- a/indra/llcommon/tests/llleap_test.cpp
+++ b/indra/llcommon/tests/llleap_test.cpp
@@ -26,6 +26,7 @@
 #include "wrapllerrs.h"
 #include "llevents.h"
 #include "llprocess.h"
+#include "llstring.h"
 #include "stringize.h"
 #include "StringVec.h"
 #include <functional>
@@ -198,14 +199,12 @@ namespace tut
             // basename.
             reader_module(LLProcess::basename(
                               reader.getName().substr(0, reader.getName().length()-3))),
-            pPYTHON(getenv("PYTHON")),
-            PYTHON(pPYTHON? pPYTHON : "")
+            PYTHON(LLStringUtil::getenv("PYTHON"))
         {
-            ensure("Set PYTHON to interpreter pathname", pPYTHON);
+            ensure("Set PYTHON to interpreter pathname", !PYTHON.empty());
         }
         NamedExtTempFile reader;
         const std::string reader_module;
-        const char* pPYTHON;
         const std::string PYTHON;
     };
     typedef test_group<llleap_data> llleap_group;
diff --git a/indra/llcommon/tests/llprocess_test.cpp b/indra/llcommon/tests/llprocess_test.cpp
index b27e125d2e..5c87cdabd9 100644
--- a/indra/llcommon/tests/llprocess_test.cpp
+++ b/indra/llcommon/tests/llprocess_test.cpp
@@ -34,6 +34,7 @@
 #include "stringize.h"
 #include "llsdutil.h"
 #include "llevents.h"
+#include "llstring.h"
 #include "wrapllerrs.h"
 
 #if defined(LL_WINDOWS)
@@ -142,8 +143,8 @@ struct PythonProcessLauncher
         mDesc(desc),
         mScript("py", script)
     {
-        const char* PYTHON(getenv("PYTHON"));
-        tut::ensure("Set $PYTHON to the Python interpreter", PYTHON);
+        auto PYTHON(LLStringUtil::getenv("PYTHON"));
+        tut::ensure("Set $PYTHON to the Python interpreter", !PYTHON.empty());
 
         mParams.desc = desc + " script";
         mParams.executable = PYTHON;
diff --git a/indra/llcommon/tests/llsdserialize_test.cpp b/indra/llcommon/tests/llsdserialize_test.cpp
index 745e3a168c..6ac974e659 100644
--- a/indra/llcommon/tests/llsdserialize_test.cpp
+++ b/indra/llcommon/tests/llsdserialize_test.cpp
@@ -41,6 +41,7 @@ typedef U32 uint32_t;
 #include <sys/stat.h>
 #include <sys/wait.h>
 #include "llprocess.h"
+#include "llstring.h"
 #endif
 
 #include "boost/range.hpp"
@@ -1705,8 +1706,8 @@ namespace tut
         template <typename CONTENT>
         void python(const std::string& desc, const CONTENT& script, int expect=0)
         {
-            const char* PYTHON(getenv("PYTHON"));
-            ensure("Set $PYTHON to the Python interpreter", PYTHON);
+            auto PYTHON(LLStringUtil::getenv("PYTHON"));
+            ensure("Set $PYTHON to the Python interpreter", !PYTHON.empty());
 
             NamedTempFile scriptfile("py", script);
 
@@ -1714,7 +1715,7 @@ namespace tut
             std::string q("\"");
             std::string qPYTHON(q + PYTHON + q);
             std::string qscript(q + scriptfile.getName() + q);
-            int rc = _spawnl(_P_WAIT, PYTHON, qPYTHON.c_str(), qscript.c_str(), NULL);
+            int rc = _spawnl(_P_WAIT, PYTHON.c_str(), qPYTHON.c_str(), qscript.c_str(), NULL);
             if (rc == -1)
             {
                 char buffer[256];
diff --git a/indra/llmessage/tests/commtest.h b/indra/llmessage/tests/commtest.h
index 7c8f27bbd2..0359eba803 100644
--- a/indra/llmessage/tests/commtest.h
+++ b/indra/llmessage/tests/commtest.h
@@ -34,6 +34,7 @@
 #include "llsd.h"
 #include "llhost.h"
 #include "llexception.h"
+#include "llstring.h"
 #include "stringize.h"
 #include <map>
 #include <string>
@@ -46,12 +47,7 @@ struct CommtestError: public LLException
 
 static bool query_verbose()
 {
-    const char* cbose = getenv("INTEGRATION_TEST_VERBOSE");
-    if (! cbose)
-    {
-        cbose = "1";
-    }
-    std::string strbose(cbose);
+    std::string strbose(LLStringUtil::getenv("INTEGRATION_TEST_VERBOSE", "1"));
     return (! (strbose == "0" || strbose == "off" ||
                strbose == "false" || strbose == "quiet"));
 }
diff --git a/indra/llmessage/tests/llhttpclient_test.cpp b/indra/llmessage/tests/llhttpclient_test.cpp
index 9356a14f1f..78faa66a0d 100644
--- a/indra/llmessage/tests/llhttpclient_test.cpp
+++ b/indra/llmessage/tests/llhttpclient_test.cpp
@@ -41,6 +41,7 @@
 #include "llpumpio.h"
 
 #include "lliosocket.h"
+#include "llstring.h"
 #include "stringize.h"
 #include "llcleanup.h"
 
@@ -50,13 +51,13 @@ namespace tut
 	{
 	public:
 		HTTPClientTestData():
-			PORT(getenv("PORT")),
+			PORT(LLStringUtil::getenv("PORT")),
 			// Turning NULL PORT into empty string doesn't make things work;
 			// that's just to keep this initializer from blowing up. We test
 			// PORT separately in the constructor body.
-			local_server(STRINGIZE("http://127.0.0.1:" << (PORT? PORT : "") << "/"))
+			local_server(STRINGIZE("http://127.0.0.1:" << PORT << "/"))
 		{
-			ensure("Set environment variable PORT to local test server port", PORT);
+			ensure("Set environment variable PORT to local test server port", !PORT.empty());
 			apr_pool_create(&mPool, NULL);
 			LLCurl::initClass(false);
 			mClientPump = new LLPumpIO(mPool);
@@ -87,7 +88,7 @@ namespace tut
 			}
 		}
 
-		const char* const PORT;
+		const std::string PORT;
 		const std::string local_server;
 
 	private:
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index cf0a117567..bb56988422 100644
--- a/indra/llrender/llfontgl.cpp
+++ b/indra/llrender/llfontgl.cpp
@@ -1063,33 +1063,24 @@ LLFontGL* LLFontGL::getFontDefault()
 // static 
 std::string LLFontGL::getFontPathSystem()
 {
-	std::string system_path;
-
-	// Try to figure out where the system's font files are stored.
-	char *system_root = NULL;
-#if LL_WINDOWS
-	system_root = getenv("SystemRoot");	/* Flawfinder: ignore */
-	if (!system_root)
-	{
-		LL_WARNS() << "SystemRoot not found, attempting to load fonts from default path." << LL_ENDL;
-	}
+#if LL_DARWIN
+    // HACK for Mac OS X
+    return "/System/Library/Fonts/";
+
+#elif LL_WINDOWS
+    wchar_t *pwstr = NULL;
+    HRESULT okay = SHGetKnownFolderPath(FOLDERID_Fonts, 0, NULL, &pwstr);
+    if (SUCCEEDED(okay) && pwstr)
+    {
+        std::string fontpath(ll_convert_wide_to_string(pwstr));
+        // SHGetKnownFolderPath() contract requires us to free pwstr
+        CoTaskMemFree(pwstr);
+        return fontpath;
+    }
 #endif
 
-	if (system_root)
-	{
-		system_path = llformat("%s/fonts/", system_root);
-	}
-	else
-	{
-#if LL_WINDOWS
-		// HACK for windows 98/Me
-		system_path = "/WINDOWS/FONTS/";
-#elif LL_DARWIN
-		// HACK for Mac OS X
-		system_path = "/System/Library/Fonts/";
-#endif
-	}
-	return system_path;
+    LL_WARNS() << "Could not determine system fonts path" << LL_ENDL;
+    return {};
 }
 
 
diff --git a/indra/llvfs/lldir_linux.cpp b/indra/llvfs/lldir_linux.cpp
index 2cd06b81f8..80ad05345a 100644
--- a/indra/llvfs/lldir_linux.cpp
+++ b/indra/llvfs/lldir_linux.cpp
@@ -29,6 +29,7 @@
 #include "lldir_linux.h"
 #include "llerror.h"
 #include "llrand.h"
+#include "llstring.h"
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
@@ -40,28 +41,24 @@ static std::string getCurrentUserHome(char* fallback)
 {
 	const uid_t uid = getuid();
 	struct passwd *pw;
-	char *result_cstr = fallback;
-	
+
 	pw = getpwuid(uid);
 	if ((pw != NULL) && (pw->pw_dir != NULL))
 	{
-		result_cstr = (char*) pw->pw_dir;
+		return pw->pw_dir;
+	}
+
+	LL_INFOS() << "Couldn't detect home directory from passwd - trying $HOME" << LL_ENDL;
+	auto home_env = LLStringUtil::getoptenv("HOME");
+	if (home_env)
+	{
+		return *home_env;
 	}
 	else
 	{
-		LL_INFOS() << "Couldn't detect home directory from passwd - trying $HOME" << LL_ENDL;
-		const char *const home_env = getenv("HOME");	/* Flawfinder: ignore */ 
-		if (home_env)
-		{
-			result_cstr = (char*) home_env;
-		}
-		else
-		{
-			LL_WARNS() << "Couldn't detect home directory!  Falling back to " << fallback << LL_ENDL;
-		}
+		LL_WARNS() << "Couldn't detect home directory!  Falling back to " << fallback << LL_ENDL;
+		return fallback;
 	}
-	
-	return std::string(result_cstr);
 }
 
 
@@ -156,18 +153,18 @@ void LLDir_Linux::initAppDirs(const std::string &app_name,
 	if (!app_read_only_data_dir.empty())
 	{
 		mAppRODataDir = app_read_only_data_dir;
-		mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins";
+		mSkinBaseDir = add(mAppRODataDir, "skins");
 	}
 	mAppName = app_name;
 
 	std::string upper_app_name(app_name);
 	LLStringUtil::toUpper(upper_app_name);
 
-	char* app_home_env = getenv((upper_app_name + "_USER_DIR").c_str());	/* Flawfinder: ignore */ 
+	auto app_home_env(LLStringUtil::getoptenv(upper_app_name + "_USER_DIR"));
 	if (app_home_env)
 	{
 		// user has specified own userappdir i.e. $SECONDLIFE_USER_DIR
-		mOSUserAppDir = app_home_env;
+		mOSUserAppDir = *app_home_env;
 	}
 	else
 	{
diff --git a/indra/llvfs/lldir_solaris.cpp b/indra/llvfs/lldir_solaris.cpp
index d3536a12ee..f18560ff20 100644
--- a/indra/llvfs/lldir_solaris.cpp
+++ b/indra/llvfs/lldir_solaris.cpp
@@ -29,6 +29,7 @@
 #include "lldir_solaris.h"
 #include "llerror.h"
 #include "llrand.h"
+#include "llstring.h"
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
@@ -41,30 +42,28 @@
 
 static std::string getCurrentUserHome(char* fallback)
 {
+	// fwiw this exactly duplicates getCurrentUserHome() in lldir_linux.cpp...
+	// we should either derive both from LLDir_Posix or just axe Solaris.
 	const uid_t uid = getuid();
 	struct passwd *pw;
-	char *result_cstr = fallback;
-	
+
 	pw = getpwuid(uid);
 	if ((pw != NULL) && (pw->pw_dir != NULL))
 	{
-		result_cstr = (char*) pw->pw_dir;
+		return pw->pw_dir;
+	}
+
+	LL_INFOS() << "Couldn't detect home directory from passwd - trying $HOME" << LL_ENDL;
+	auto home_env = LLStringUtil::getoptenv("HOME");
+	if (home_env)
+	{
+		return *home_env;
 	}
 	else
 	{
-		LL_INFOS() << "Couldn't detect home directory from passwd - trying $HOME" << LL_ENDL;
-		const char *const home_env = getenv("HOME");	/* Flawfinder: ignore */ 
-		if (home_env)
-		{
-			result_cstr = (char*) home_env;
-		}
-		else
-		{
-			LL_WARNS() << "Couldn't detect home directory!  Falling back to " << fallback << LL_ENDL;
-		}
+		LL_WARNS() << "Couldn't detect home directory!  Falling back to " << fallback << LL_ENDL;
+		return fallback;
 	}
-	
-	return std::string(result_cstr);
 }
 
 
@@ -135,27 +134,15 @@ LLDir_Solaris::LLDir_Solaris()
 	//NOTE: Why force people to cd into the package directory?
 	//      Look for SECONDLIFE env variable and use it, if set.
 
-	char *dcf = getenv("SECONDLIFE");
-	if(dcf != NULL){
-		(void)strcpy(path, dcf);
-		(void)strcat(path, "/bin");	//NOTE:  make sure we point at the bin
-		mExecutableDir = strdup(path);
+	auto SECONDLIFE(LLDirUtil::getoptenv("SECONDLIFE"));
+	if(SECONDLIFE){
+		mExecutableDir = add(*SECONDLIFE, "bin"); //NOTE:  make sure we point at the bin
 	}else{
-			// plunk a null at last '/' to get exec dir
-		char *s = execpath + strlen(execpath) -1;
-		while(*s != '/' && s != execpath){
-			--s;
-		}
-	
-		if(s != execpath){
-			*s = (char)NULL;
-	
-			mExecutableDir = strdup(execpath);
-			LL_INFOS() << "mExecutableDir = [" << mExecutableDir << "]" << LL_ENDL;
-		}
+		mExecutableDir = getDirName(execpath);
+		LL_INFOS() << "mExecutableDir = [" << mExecutableDir << "]" << LL_ENDL;
 	}
-	
-	mLLPluginDir = mExecutableDir + mDirDelimiter + "llplugin";
+
+	mLLPluginDir = add(mExecutableDir, "llplugin");
 
 	// *TODO: don't use /tmp, use $HOME/.secondlife/tmp or something.
 	mTempDir = "/tmp";
@@ -175,17 +162,18 @@ void LLDir_Solaris::initAppDirs(const std::string &app_name,
 	if (!app_read_only_data_dir.empty())
 	{
 		mAppRODataDir = app_read_only_data_dir;
+		mSkinBaseDir = add(mAppRODataDir, "skins");
 	}
 	mAppName = app_name;
 
 	std::string upper_app_name(app_name);
 	LLStringUtil::toUpper(upper_app_name);
 
-	char* app_home_env = getenv((upper_app_name + "_USER_DIR").c_str());	/* Flawfinder: ignore */ 
+	auto app_home_env(LLStringUtil::getoptenv(upper_app_name + "_USER_DIR"));
 	if (app_home_env)
 	{
 		// user has specified own userappdir i.e. $SECONDLIFE_USER_DIR
-		mOSUserAppDir = app_home_env;
+		mOSUserAppDir = *app_home_env;
 	}
 	else
 	{
diff --git a/indra/llvfs/lldir_win32.cpp b/indra/llvfs/lldir_win32.cpp
index fc4680bbfb..acf734f16b 100644
--- a/indra/llvfs/lldir_win32.cpp
+++ b/indra/llvfs/lldir_win32.cpp
@@ -30,6 +30,7 @@
 
 #include "lldir_win32.h"
 #include "llerror.h"
+#include "llstring.h"
 #include "stringize.h"
 #include "llfile.h"
 #include <shlobj.h>
@@ -55,17 +56,17 @@ namespace
     {
         switch (state)
         {
+            boost::optional<std::string> prelog_name;
+
         case prst::INIT:
             // assume we failed, until we succeed
             state = prst::SKIP;
 
-            // can't initialize within one case of a switch statement
-            const char* prelog_name;
-            prelog_name = getenv("PRELOG");
+            prelog_name = LLDirUtil::getoptenv("PRELOG");
             if (! prelog_name)
                 // no PRELOG variable set, carry on
                 return;
-            prelogf = new std::ofstream(prelog_name, std::ios_base::app);
+            prelogf = new llofstream(*prelog_name, std::ios_base::app);
             if (! (prelogf && prelogf->is_open()))
                 // can't complain to anybody; how?
                 return;
@@ -95,13 +96,11 @@ LLDir_Win32::LLDir_Win32()
 
 	WCHAR w_str[MAX_PATH];
 	// Application Data is where user settings go. We rely on $APPDATA being
-	// correct; in fact the VMP makes a point of setting it properly, since
-	// Windows itself botches the job for non-ASCII usernames (MAINT-8087).
-	// Try using wide-character getenv()??
-	wchar_t *APPDATA = _wgetenv(L"APPDATA");
+	// correct.
+	auto APPDATA = LLStringUtil::getoptenv("APPDATA");
 	if (APPDATA)
 	{
-		mOSUserDir = ll_convert_wide_to_string(APPDATA, CP_UTF8);
+		mOSUserDir = *APPDATA;
 	}
 	PRELOG("APPDATA='" << mOSUserDir << "'");
 	// On Windows, we could have received a plain-ASCII pathname in which
@@ -118,7 +117,7 @@ LLDir_Win32::LLDir_Win32()
 		if (SUCCEEDED(okay) && pwstr)
 		{
 			// But of course, only update mOSUserDir if SHGetKnownFolderPath() works.
-			mOSUserDir = ll_convert_wide_to_string(pwstr, CP_UTF8);
+			mOSUserDir = ll_convert_wide_to_string(pwstr);
 			// Not only that: update our environment so that child processes
 			// will see a reasonable value as well.
 			_wputenv_s(L"APPDATA", pwstr);
@@ -136,11 +135,10 @@ LLDir_Win32::LLDir_Win32()
 	//
 	// We used to store the cache in AppData\Roaming, and the installer
 	// cleans up that version on upgrade.  JC
-	// Again, try using wide-character getenv().
-	wchar_t *LOCALAPPDATA = _wgetenv(L"LOCALAPPDATA");
+	auto LOCALAPPDATA = LLStringUtil::getoptenv("LOCALAPPDATA");
 	if (LOCALAPPDATA)
 	{
-		mOSCacheDir = ll_convert_wide_to_string(LOCALAPPDATA, CP_UTF8);
+		mOSCacheDir = *LOCALAPPDATA;
 	}
 	PRELOG("LOCALAPPDATA='" << mOSCacheDir << "'");
 	// Windows really does not deal well with pathnames containing non-ASCII
@@ -155,7 +153,7 @@ LLDir_Win32::LLDir_Win32()
 		if (SUCCEEDED(okay) && pwstr)
 		{
 			// But of course, only update mOSCacheDir if SHGetKnownFolderPath() works.
-			mOSCacheDir = ll_convert_wide_to_string(pwstr, CP_UTF8);
+			mOSCacheDir = ll_convert_wide_to_string(pwstr);
 			// Update our environment so that child processes will see a
 			// reasonable value as well.
 			_wputenv_s(L"LOCALAPPDATA", pwstr);
diff --git a/indra/llxml/tests/llcontrol_test.cpp b/indra/llxml/tests/llcontrol_test.cpp
index 2b691ffbb1..f7e43d6def 100644
--- a/indra/llxml/tests/llcontrol_test.cpp
+++ b/indra/llxml/tests/llcontrol_test.cpp
@@ -27,43 +27,31 @@
 
 #include "linden_common.h"
 #include "llsdserialize.h"
+#include "llfile.h"
+#include "stringize.h"
 
 #include "../llcontrol.h"
 
 #include "../test/lltut.h"
+#include <memory>
+#include <vector>
 
 namespace tut
 {
-
 	struct control_group
 	{
-		LLControlGroup* mCG;
+		std::unique_ptr<LLControlGroup> mCG;
 		std::string mTestConfigDir;
 		std::string mTestConfigFile;
+		std::vector<std::string> mCleanups;
 		static bool mListenerFired;
 		control_group()
 		{
-			mCG = new LLControlGroup("foo");
+			mCG.reset(new LLControlGroup("foo"));
 			LLUUID random;
 			random.generate();
 			// generate temp dir
-			std::ostringstream oStr;
-
-#ifdef LL_WINDOWS
-			char* tmp_dir = getenv("TMP");
-			if(tmp_dir)
-			{
-				oStr << tmp_dir << "/llcontrol-test-" << random << "/";
-			}
-			else
-			{
-				oStr << "c:/tmp/llcontrol-test-" << random << "/";
-			}
-#else
-			oStr << "/tmp/llcontrol-test-" << random << "/";
-#endif
-
-			mTestConfigDir = oStr.str();
+			mTestConfigDir = STRINGIZE(LLFile::tmpdir() << "llcontrol-test-" << random << "/");
 			mTestConfigFile = mTestConfigDir + "settings.xml";
 			LLFile::mkdir(mTestConfigDir);
 			LLSD config;
@@ -76,7 +64,12 @@ namespace tut
 		~control_group()
 		{
 			//Remove test files
-			delete mCG;
+			for (auto filename : mCleanups)
+			{
+				LLFile::remove(filename);
+			}
+			LLFile::remove(mTestConfigFile);
+			LLFile::rmdir(mTestConfigDir);
 		}
 		void writeSettingsFile(const LLSD& config)
 		{
@@ -118,6 +111,7 @@ namespace tut
 		ensure_equals("value of changed setting", mCG->getU32("TestSetting"), 13);
 		LLControlGroup test_cg("foo2");
 		std::string temp_test_file = (mTestConfigDir + "setting_llsd_temp.xml");
+		mCleanups.push_back(temp_test_file);
 		mCG->saveToFile(temp_test_file.c_str(), TRUE);
 		results = test_cg.loadFromFile(temp_test_file.c_str());
 		ensure("number of changed settings loaded", (results == 1));
@@ -139,6 +133,7 @@ namespace tut
 		ensure_equals("value of changed setting", mCG->getU32("TestSetting"), 13);
 		LLControlGroup test_cg("foo3");
 		std::string temp_test_file = (mTestConfigDir + "setting_llsd_persist_temp.xml");
+		mCleanups.push_back(temp_test_file);
 		mCG->saveToFile(temp_test_file.c_str(), TRUE);
 		results = test_cg.loadFromFile(temp_test_file.c_str());
 		//If we haven't changed any settings, then we shouldn't have any settings to load
@@ -153,7 +148,7 @@ namespace tut
 		ensure("number of settings", (results == 1));
 		mCG->getControl("TestSetting")->getSignal()->connect(boost::bind(&this->handleListenerTest));
 		mCG->setU32("TestSetting", 13);
-		ensure("listener fired on changed setting", mListenerFired);	   
+		ensure("listener fired on changed setting", mListenerFired);
 	}
 
 }
diff --git a/indra/newview/llexternaleditor.cpp b/indra/newview/llexternaleditor.cpp
index df9c848cb8..776bbf78c2 100644
--- a/indra/newview/llexternaleditor.cpp
+++ b/indra/newview/llexternaleditor.cpp
@@ -31,6 +31,7 @@
 #include "llui.h"
 #include "llprocess.h"
 #include "llsdutil.h"
+#include "llstring.h"
 #include <boost/foreach.hpp>
 
 // static
@@ -188,12 +189,12 @@ std::string LLExternalEditor::findCommand(
 		cmd = LLUI::sSettingGroups["config"]->getString(sSetting);
 		LL_INFOS() << "Using setting" << LL_ENDL;
 	}
-	else					// otherwise use the path specified by the environment variable
+	else                    // otherwise use the path specified by the environment variable
 	{
-		char* env_var_val = getenv(env_var.c_str());
+		auto env_var_val(LLStringUtil::getoptenv(env_var));
 		if (env_var_val)
 		{
-			cmd = env_var_val;
+			cmd = *env_var_val;
 			LL_INFOS() << "Using env var " << env_var << LL_ENDL;
 		}
 	}
diff --git a/indra/newview/llwebprofile.cpp b/indra/newview/llwebprofile.cpp
index 81d4e30a7a..8dcef2c7cd 100644
--- a/indra/newview/llwebprofile.cpp
+++ b/indra/newview/llwebprofile.cpp
@@ -33,6 +33,7 @@
 #include "llimagepng.h"
 
 #include "llsdserialize.h"
+#include "llstring.h"
 
 // newview
 #include "llpanelprofile.h" // for getProfileURL(). FIXME: move the method to LLAvatarActions
@@ -264,6 +265,5 @@ void LLWebProfile::reportImageUploadStatus(bool ok)
 std::string LLWebProfile::getAuthCookie()
 {
 	// This is needed to test image uploads on Linux viewer built with OpenSSL 1.0.0 (0.9.8 works fine).
-	const char* debug_cookie = getenv("LL_SNAPSHOT_COOKIE");
-	return debug_cookie ? debug_cookie : sAuthCookie;
+	return LLStringUtil::getenv("LL_SNAPSHOT_COOKIE", sAuthCookie);
 }
-- 
cgit v1.2.3


From 3c53f8abded5da7e9743b743170538a1ede5635a Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 14 Dec 2018 16:00:09 -0500
Subject: SL-10153: VS 2013 isn't so fond of ?: involving std::string.

---
 indra/llcommon/llstring.h | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h
index 87cb35c59c..8d2c8d79d7 100644
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -1773,7 +1773,14 @@ template<class T>
 auto LLStringUtilBase<T>::getenv(const std::string& key, const string_type& dflt) -> string_type
 {
     auto found{getoptenv(key)};
-    return found? *found : dflt;
+    if (found)
+    {
+        return *found;
+    }
+    else
+    {
+        return dflt;
+    }
 }
 
 template<class T> 
-- 
cgit v1.2.3


From 4a136572857fcf5d5fd21789a777bbde67c1076d Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Sat, 15 Dec 2018 09:13:24 -0500
Subject: SL-10153: auto name{expression} declares an initializer_list instead
 of a variable of type decltype(expression).

Using SHGetKnownFolderPath(FOLDERID_Fonts) in LLFontGL::getFontPathSystem()
requires new Windows #include files.

A variable with a constructor can't be declared within the braces of a switch
statement, even outside any of its case clauses.
---
 indra/llcommon/llstring.h   | 4 ++--
 indra/llrender/llfontgl.cpp | 6 ++++++
 indra/llvfs/lldir_win32.cpp | 6 +++---
 3 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h
index 8d2c8d79d7..30bec3a6f8 100644
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -1755,7 +1755,7 @@ bool LLStringUtilBase<T>::endsWith(
 template<class T>
 auto LLStringUtilBase<T>::getoptenv(const std::string& key) -> boost::optional<string_type>
 {
-    auto found{llstring_getoptenv(key)};
+    auto found(llstring_getoptenv(key));
     if (found)
     {
         // return populated boost::optional
@@ -1772,7 +1772,7 @@ auto LLStringUtilBase<T>::getoptenv(const std::string& key) -> boost::optional<s
 template<class T>
 auto LLStringUtilBase<T>::getenv(const std::string& key, const string_type& dflt) -> string_type
 {
-    auto found{getoptenv(key)};
+    auto found(getoptenv(key));
     if (found)
     {
         return *found;
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index bb56988422..9b43680949 100644
--- a/indra/llrender/llfontgl.cpp
+++ b/indra/llrender/llfontgl.cpp
@@ -44,6 +44,12 @@
 // Third party library includes
 #include <boost/tokenizer.hpp>
 
+#if LL_WINDOWS
+#include <Shlobj.h>
+#include <Knownfolders.h>
+#include <Objbase.h>
+#endif // LL_WINDOWS
+
 const S32 BOLD_OFFSET = 1;
 
 // static class members
diff --git a/indra/llvfs/lldir_win32.cpp b/indra/llvfs/lldir_win32.cpp
index acf734f16b..b3b3afb37e 100644
--- a/indra/llvfs/lldir_win32.cpp
+++ b/indra/llvfs/lldir_win32.cpp
@@ -54,15 +54,15 @@ namespace
 
     void prelog(const std::string& message)
     {
+        boost::optional<std::string> prelog_name;
+
         switch (state)
         {
-            boost::optional<std::string> prelog_name;
-
         case prst::INIT:
             // assume we failed, until we succeed
             state = prst::SKIP;
 
-            prelog_name = LLDirUtil::getoptenv("PRELOG");
+            prelog_name = LLStringUtil::getoptenv("PRELOG");
             if (! prelog_name)
                 // no PRELOG variable set, carry on
                 return;
-- 
cgit v1.2.3


From 4b99e6a1f11efe66b3fb0aa3b6fa721afe698446 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 17 Dec 2018 15:23:57 -0500
Subject: SL-10252: On Windows, use $SystemRoot again, not FOLDERID_Fonts.

---
 indra/llrender/llfontgl.cpp | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index 9b43680949..8cd18c5fa1 100644
--- a/indra/llrender/llfontgl.cpp
+++ b/indra/llrender/llfontgl.cpp
@@ -40,6 +40,7 @@
 #include "v4color.h"
 #include "lltexture.h"
 #include "lldir.h"
+#include "llstring.h"
 
 // Third party library includes
 #include <boost/tokenizer.hpp>
@@ -1074,6 +1075,14 @@ std::string LLFontGL::getFontPathSystem()
     return "/System/Library/Fonts/";
 
 #elif LL_WINDOWS
+    auto system_root = LLStringUtil::getenv("SystemRoot");
+    if (! system_root.empty())
+    {
+        std::string fontpath(gDirUtilp->add(system_root, "fonts") + gDirUtilp->getDirDelimiter());
+        LL_INFOS() << "from SystemRoot: " << fontpath << LL_ENDL;
+        return fontpath;
+    }
+
     wchar_t *pwstr = NULL;
     HRESULT okay = SHGetKnownFolderPath(FOLDERID_Fonts, 0, NULL, &pwstr);
     if (SUCCEEDED(okay) && pwstr)
@@ -1081,6 +1090,7 @@ std::string LLFontGL::getFontPathSystem()
         std::string fontpath(ll_convert_wide_to_string(pwstr));
         // SHGetKnownFolderPath() contract requires us to free pwstr
         CoTaskMemFree(pwstr);
+        LL_INFOS() << "from SHGetKnownFolderPath(): " << fontpath << LL_ENDL;
         return fontpath;
     }
 #endif
-- 
cgit v1.2.3


From 2b2b6d40847d9d1bcd070a16003834389d954f32 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Tue, 18 Dec 2018 11:41:32 +0200
Subject: SL-10251 show correct fee for 'save to disk' option on Japanese
 localization

---
 indra/newview/skins/default/xui/ja/panel_snapshot_options.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml b/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml
index ebaab7c122..04dfc0176d 100644
--- a/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml
+++ b/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="panel_snapshot_options">
 	<button label="ディスクに保存" name="save_to_computer_btn"/>
-	<button label="持ち物に保存(L$[Amount])" name="save_to_inventory_btn"/>
+	<button label="持ち物に保存(L$[AMOUNT])" name="save_to_inventory_btn"/>
 	<button label="プロフィールフィードで共有する" name="save_to_profile_btn"/>
 	<button label="Facebook で共有する" name="send_to_facebook_btn"/>
 	<button label="Twitter で共有する" name="send_to_twitter_btn"/>
-- 
cgit v1.2.3


From 224c65716377b61c8f7918ca88434ffaa8356bc1 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Tue, 18 Dec 2018 17:23:55 +0200
Subject: SL-10235 FIXED Texture tab is opened with Bumpiness or Shininess
 instead of Texture as default value

---
 indra/newview/llpanelface.cpp | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 8d7865c8ba..2232589ec4 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -1384,6 +1384,11 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
 			mColorSwatch->setFallbackImage(LLUI::getUIImage("locked_image.j2c") );
 			mColorSwatch->setValid(FALSE);
 		}
+		LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
+		if (radio_mat_type)
+		{
+			radio_mat_type->setSelectedIndex(0);
+		}
 		getChildView("color trans")->setEnabled(FALSE);
 		getChildView("rptctrl")->setEnabled(FALSE);
 		getChildView("tex gen")->setEnabled(FALSE);
-- 
cgit v1.2.3


From b08065dafd0d745516bb522a586af2cc09ea42bc Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Wed, 19 Dec 2018 18:39:59 +0200
Subject: SL-10155 FIXED [MAC] Mesh upload tries to upload folder instead of
 opening it

---
 indra/newview/llfilepicker.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
index 0f22b6200f..b6fd70452e 100644
--- a/indra/newview/llfilepicker.cpp
+++ b/indra/newview/llfilepicker.cpp
@@ -101,6 +101,8 @@ LLFilePicker::LLFilePicker()
 	mOFN.lpfnHook = NULL;
 	mOFN.lpTemplateName = NULL;
 	mFilesW[0] = '\0';
+#elif LL_DARWIN
+	mPickOptions = 0;
 #endif
 
 }
-- 
cgit v1.2.3


From 0acab8ba2d22e9b0ce0dec1a41813242419e057f Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Mon, 24 Dec 2018 15:57:04 +0200
Subject: SL-10283 Allow changing "Repeats per meter" on face 6 of hollowed
 cube

---
 indra/llprimitive/llprimitive.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp
index c69c059880..27d1bee9bd 100644
--- a/indra/llprimitive/llprimitive.cpp
+++ b/indra/llprimitive/llprimitive.cpp
@@ -1580,7 +1580,7 @@ bool LLPrimitive::getTESTAxes(const U8 face, U32* s_axis, U32* t_axis)
 		*s_axis = VY; *t_axis = VZ;
 		return true;
 	}
-	else if (face == 5)
+	else if (face >= 5)
 	{
 		*s_axis = VX; *t_axis = VY;
 		return true;
-- 
cgit v1.2.3


From efa5f24d1b00472485a3764d550882484fe5bdd5 Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Thu, 3 Jan 2019 00:35:38 +0200
Subject: SL-10288 Mesh uploader changes from Firestorm

---
 doc/contributions.txt                              |   2 +
 indra/newview/app_settings/settings.xml            | 199 +++++++-
 .../shaders/class1/objects/previewV.glsl           |   8 +-
 indra/newview/lldynamictexture.cpp                 |  30 +-
 indra/newview/llfloatermodelpreview.cpp            | 527 ++++++++++++++-------
 indra/newview/llfloatermodelpreview.h              |   2 +
 indra/newview/pipeline.cpp                         |   6 +-
 .../skins/default/xui/en/floater_model_preview.xml | 369 ++++++++++-----
 8 files changed, 844 insertions(+), 299 deletions(-)

diff --git a/doc/contributions.txt b/doc/contributions.txt
index 97c7ff1098..bb910aa838 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -256,6 +256,8 @@ Benja Kepler
 	VWR-746
 Benjamin Bigdipper
 Beth Walcher
+Beq Janus
+	SL-10288
 Bezilon Kasei
 Biancaluce Robbiani
 	CT-225
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 0eef5120eb..1abddc80cb 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -6628,8 +6628,189 @@
     <key>Value</key>
     <integer>600</integer>
   </map>
-  <key>MigrateCacheDirectory</key>
-    <map>
+  <key>MeshPreviewCanvasColor</key>
+  <map>
+    <key>Comment</key>
+    <string>Canvas colour for the Mesh uploader</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Color4</string>
+    <key>Value</key>
+    <array>
+      <real>0.169</real>
+      <real>0.169</real>
+      <real>0.169</real>
+      <real>1.0</real>
+    </array>
+  </map>
+  <key>MeshPreviewEdgeColor</key>
+  <map>
+    <key>Comment</key>
+    <string>Edge colour for the Mesh uploader preview</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Color4</string>
+    <key>Value</key>
+    <array>
+      <real>0.4</real>
+      <real>0.4</real>
+      <real>0.4</real>
+      <real>1.0</real>
+    </array>
+  </map>
+  <key>MeshPreviewBaseColor</key>
+  <map>
+    <key>Comment</key>
+    <string>base diffuse colour for the Mesh uploader</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Color4</string>
+    <key>Value</key>
+    <array>
+      <real>1.0</real>
+      <real>1.0</real>
+      <real>1.0</real>
+      <real>1.0</real>
+    </array>
+  </map>
+  <key>MeshPreviewBrightnessColor</key>
+  <map>
+    <key>Comment</key>
+    <string>Brightness modifier</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Color3</string>
+    <key>Value</key>
+    <array>
+      <real>0.9</real>
+      <real>0.9</real>
+      <real>0.9</real>
+    </array>
+  </map>
+  <key>MeshPreviewEdgeWidth</key>
+  <map>
+    <key>Comment</key>
+    <string>line thickness used when display edges is selected in mesh preview</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>F32</string>
+    <key>Value</key>
+      <real>1.0</real>
+  </map>
+  <key>MeshPreviewPhysicsEdgeColor</key>
+  <map>
+    <key>Comment</key>
+    <string>Edge colour for the Mesh uploader physics preview</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Color4</string>
+    <key>Value</key>
+    <array>
+      <real>0.0</real>
+      <real>0.25</real>
+      <real>0.5</real>
+      <real>0.25</real>
+    </array>
+  </map>
+  <key>MeshPreviewPhysicsFillColor</key>
+  <map>
+    <key>Comment</key>
+    <string>Fill colour for the Mesh uploader physics preview</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Color4</string>
+    <key>Value</key>
+    <array>
+      <real>0.0</real>
+      <real>0.5</real>
+      <real>1.0</real>
+      <real>0.5</real>
+    </array>
+  </map>
+  <key>MeshPreviewPhysicsEdgeWidth</key>
+  <map>
+    <key>Comment</key>
+    <string>line thickness used when display physics is selected in mesh preview</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>F32</string>
+    <key>Value</key>
+    <real>1.0</real>
+  </map>
+  <key>MeshPreviewDegenerateEdgeColor</key>
+  <map>
+    <key>Comment</key>
+    <string>Edge colour for the Mesh uploader Degenerate preview</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Color4</string>
+    <key>Value</key>
+    <array>
+      <real>1.0</real>
+      <real>0.0</real>
+      <real>0.0</real>
+      <real>1.0</real>
+    </array>
+  </map>
+  <key>MeshPreviewDegenerateFillColor</key>
+  <map>
+    <key>Comment</key>
+    <string>Fill colour for the Mesh uploader Degenerate preview</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Color4</string>
+    <key>Value</key>
+    <array>
+      <real>1.0</real>
+      <real>0.0</real>
+      <real>0.0</real>
+      <real>0.5</real>
+    </array>
+  </map>
+  <key>MeshPreviewDegenerateEdgeWidth</key>
+  <map>
+    <key>Comment</key>
+    <string>line thickness used when display Degenerate is selected in mesh preview</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>F32</string>
+    <key>Value</key>
+    <real>3.0</real>
+  </map>
+  <key>MeshPreviewDegeneratePointSize</key>
+  <map>
+    <key>Comment</key>
+    <string>Large point size used to highlight degenerate triangle vertices in Mesh preview</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>F32</string>
+    <key>Value</key>
+    <real>8.0</real>
+  </map>
+  <key>MeshPreviewZoomLimit</key>
+  <map>
+    <key>Comment</key>
+    <string>Maximum Zoom level in preview</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>F32</string>
+    <key>Value</key>
+    <real>10.0</real>
+  </map>
+  <map>
       <key>Comment</key>
       <string>Check for old version of disk cache to migrate to current location</string>
       <key>Persist</key>
@@ -7868,7 +8049,17 @@
       <key>Value</key>
 	  <integer>13</integer>
     </map>
-
+  <key>PreviewRenderSize</key>  
+  <map>
+    <key>Comment</key>
+    <string>Resolution of the image rendered for the mesh upload preview</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>S32</string>
+    <key>Value</key>
+    <integer>1024</integer>
+  </map>
   <key>PreviewAmbientColor</key>
   <map>
     <key>Comment</key>
@@ -7885,8 +8076,6 @@
       <real>1.0</real>
     </array>
   </map>
-
-
   <key>PreviewDiffuse0</key>
   <map>
     <key>Comment</key>
diff --git a/indra/newview/app_settings/shaders/class1/objects/previewV.glsl b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl
index 7f3f84398b..3424613e94 100644
--- a/indra/newview/app_settings/shaders/class1/objects/previewV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl
@@ -91,8 +91,10 @@ void main()
 
 	// Collect normal lights (need to be divided by two, as we later multiply by 2)
 	col.rgb += light_diffuse[1].rgb * calcDirectionalLight(norm, light_position[1].xyz);
-	col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].z);
-	col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].z);
-		
+//	col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].z);
+	col.rgb += light_diffuse[2].rgb * calcDirectionalLight(norm, light_position[2].xyz);
+//	col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].z);
+	col.rgb += light_diffuse[3].rgb * calcDirectionalLight(norm, light_position[3].xyz);
+	col /= 2.0;
 	vertex_color = col*color;
 }
diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp
index fa9a0712fa..af6977d3cd 100644
--- a/indra/newview/lldynamictexture.cpp
+++ b/indra/newview/lldynamictexture.cpp
@@ -125,11 +125,17 @@ BOOL LLViewerDynamicTexture::render()
 //-----------------------------------------------------------------------------
 void LLViewerDynamicTexture::preRender(BOOL clear_depth)
 {
-	//only images up to 512x512 are supported
-	llassert(mFullHeight <= 512);
-	llassert(mFullWidth <= 512);
+	// <FS:Beq> changes to support higher resolution rendering in the preview
+	////only images up to 512x512 are supported
+	//llassert(mFullHeight <= 512);
+	//llassert(mFullWidth <= 512);
+	gPipeline.allocatePhysicsBuffer();
+	llassert(mFullWidth <= static_cast<S32>(gPipeline.mPhysicsDisplay.getWidth()));
+	llassert(mFullHeight <= static_cast<S32>(gPipeline.mPhysicsDisplay.getHeight()));
 
-	if (gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI)
+//	if (gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI)
+	if (gGLManager.mHasFramebufferObject && gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsATI)
+// </FS:Beq>
 	{ //using offscreen render target, just use the bottom left corner
 		mOrigin.set(0, 0);
 	}
@@ -215,14 +221,15 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
 	{
 		return TRUE;
 	}
-
-	bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI;
-
+	// <FS:Beq> changes to support higher resolution rendering in the preview
+	//	bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI;
+	bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsATI;
 	if (use_fbo)
 	{
-		gPipeline.mWaterDis.bindTarget();
+//		gPipeline.mWaterDis.bindTarget();
+		gPipeline.mPhysicsDisplay.bindTarget();
 	}
-
+	// </FS:Beq>
 	LLGLSLShader::bindNoShader();
 	LLVertexBuffer::unbind();
 	
@@ -258,7 +265,10 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
 
 	if (use_fbo)
 	{
-		gPipeline.mWaterDis.flush();
+		// <FS:Beq> changes to support higher resolution rendering in the preview
+		// gPipeline.mWaterDis.flush();
+		gPipeline.mPhysicsDisplay.flush();
+		// </FS:Beq>
 	}
 
 	return ret;
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 818d364c3e..01f0a5197d 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -427,8 +427,11 @@ void LLFloaterModelPreview::initModelPreview()
 	{
 		delete mModelPreview;
 	}
-
-	mModelPreview = new LLModelPreview(512, 512, this );
+	// <FS:Beq> mesh uploader changes to allow higher resolution render
+	//	mModelPreview = new LLModelPreview(512, 512, this);
+	auto size = gSavedSettings.getS32("PreviewRenderSize");
+	mModelPreview = new LLModelPreview(size, size, this );
+	// </FS:Beq>
 	mModelPreview->setPreviewTarget(16.f);
 	mModelPreview->setDetailsCallback(boost::bind(&LLFloaterModelPreview::setDetails, this, _1, _2, _3, _4, _5));
 	mModelPreview->setModelUpdatedCallback(boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this, _1));
@@ -438,8 +441,16 @@ void LLFloaterModelPreview::onViewOptionChecked(LLUICtrl* ctrl)
 {
 	if (mModelPreview)
 	{
-		mModelPreview->mViewOption[ctrl->getName()] = !mModelPreview->mViewOption[ctrl->getName()];
-		
+		// <FS:Beq> only show explode when phsyics is on
+		//		mModelPreview->mViewOption[ctrl->getName()] = !mModelPreview->mViewOption[ctrl->getName()];
+		auto name = ctrl->getName();
+		mModelPreview->mViewOption[name] = !mModelPreview->mViewOption[name];
+		if (name == "show_physics")
+		{
+			auto enabled = mModelPreview->mViewOption[name];
+			childSetEnabled("physics_explode", enabled);
+			childSetVisible("physics_explode", enabled);
+		}
 		mModelPreview->refresh();
 	}
 }
@@ -653,6 +664,43 @@ void LLFloaterModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit)
 	}
 }
 
+// <FS:Beq> extracted method to simplify changes in layout
+void LLFloaterModelPreview::draw3dPreview()
+{
+	gGL.color3f(1.f, 1.f, 1.f);
+
+	gGL.getTexUnit(0)->bind(mModelPreview);
+
+
+	LLView* preview_panel = getChild<LLView>("preview_panel");
+
+	if (!preview_panel)
+	{
+		LL_WARNS() << "preview_panel not found in floater definition" << LL_ENDL;
+	}
+	LLRect rect = preview_panel->getRect();
+
+	if (rect != mPreviewRect)
+	{
+		mModelPreview->refresh();
+		mPreviewRect = preview_panel->getRect();
+	}
+
+	gGL.begin( LLRender::QUADS );
+	{
+		gGL.texCoord2f(0.f, 1.f);
+		gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mTop-1);
+		gGL.texCoord2f(0.f, 0.f);
+		gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mBottom);
+		gGL.texCoord2f(1.f, 0.f);
+		gGL.vertex2i(mPreviewRect.mRight-1, mPreviewRect.mBottom);
+		gGL.texCoord2f(1.f, 1.f);
+		gGL.vertex2i(mPreviewRect.mRight-1, mPreviewRect.mTop-1);
+	}
+	gGL.end();
+
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+}
 
 //-----------------------------------------------------------------------------
 // draw()
@@ -1218,6 +1266,7 @@ LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp)
 , mResetJoints( false )
 , mModelNoErrors( true )
 , mLastJointUpdate( false )
+, mHasDegenerate( false ) // <FS:Beq>
 {
 	mNeedsUpdate = TRUE;
 	mCameraDistance = 0.f;
@@ -2707,8 +2756,20 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim
 
 void LLModelPreview::updateStatusMessages()
 {
+// <FS:Beq> bit mask values for physics errors. used to prevent overwrite of single line status
+// TODO: use this to provied multiline status
+	enum PhysicsError
+	{
+		NONE=0,
+		NOHAVOK=1,
+		DEGENERATE=2,
+		TOOMANYHULLS=4,
+		TOOMANYVERTSINHULL=8
+	};
+// </FS:Beq>
 	assert_main_thread();
 
+	U32 has_physics_error{ PhysicsError::NONE }; // <FS:Beq> physics error bitmap
 	//triangle/vertex/submesh count for each mesh asset for each lod
 	std::vector<S32> tris[LLModel::NUM_LODS];
 	std::vector<S32> verts[LLModel::NUM_LODS];
@@ -2797,44 +2858,72 @@ void LLModelPreview::updateStatusMessages()
 	{
 		mMaxTriangleLimit = total_tris[LLModel::LOD_HIGH];
 	}
-
-	bool has_degenerate = false;
-
+	// <FS:Beq> make has_degenerate a member so that we can use it in the render method
+	// has_degenerate = false
+	mHasDegenerate = false;
 	{//check for degenerate triangles in physics mesh
 		U32 lod = LLModel::LOD_PHYSICS;
 		const LLVector4a scale(0.5f);
-		for (U32 i = 0; i < mModel[lod].size() && !has_degenerate; ++i)
+		for (U32 i = 0; i < mModel[lod].size() && !mHasDegenerate; ++i)// <FS:Beq> make has_degenerate a member 
 		{ //for each model in the lod
 			if (mModel[lod][i] && mModel[lod][i]->mPhysics.mHull.empty())
 			{ //no decomp exists
 				S32 cur_submeshes = mModel[lod][i]->getNumVolumeFaces();
-				for (S32 j = 0; j < cur_submeshes && !has_degenerate; ++j)
+				for (S32 j = 0; j < cur_submeshes && !mHasDegenerate; ++j)// <FS:Beq> make has_degenerate a member 
 				{ //for each submesh (face), add triangles and vertices to current total
 					LLVolumeFace& face = mModel[lod][i]->getVolumeFace(j);
-					for (S32 k = 0; (k < face.mNumIndices) && !has_degenerate; )
+					for (S32 k = 0; (k < face.mNumIndices) && !mHasDegenerate; )// <FS:Beq> make has_degenerate a member 
 					{
-						U16 index_a = face.mIndices[k+0];
-						U16 index_b = face.mIndices[k+1];
-						U16 index_c = face.mIndices[k+2];
-
-						LLVector4a v1; v1.setMul(face.mPositions[index_a], scale);
-						LLVector4a v2; v2.setMul(face.mPositions[index_b], scale);
-						LLVector4a v3; v3.setMul(face.mPositions[index_c], scale);
-
-						if (ll_is_degenerate(v1,v2,v3))
+						U16 index_a = face.mIndices[k + 0];
+						U16 index_b = face.mIndices[k + 1];
+						U16 index_c = face.mIndices[k + 2];
+						// <FS:Beq> FIRE-23367/23387 - Allow forced empty triangle placeholders created by the LOD processing.
+						//	LLVector4a v1; v1.setMul(face.mPositions[index_a], scale);
+						//	LLVector4a v2; v2.setMul(face.mPositions[index_b], scale);
+						//	LLVector4a v3; v3.setMul(face.mPositions[index_c], scale);
+
+						//	if (ll_is_degenerate(v1, v2, v3))
+						//	{
+						//		mHasDegenerate = true;// <FS:Beq> make has_degenerate a member 
+						//	}
+						//	else
+						//	{
+						//		k += 3;
+						//	}
+						if (index_c == 0 && index_b == 0 && index_a == 0) // test in reverse as 3rd index is less likely to be 0 in a normal case
 						{
-							has_degenerate = true;
+							LL_DEBUGS("MeshValidation") << "Empty placeholder triangle (3 identical index 0 verts) ignored" << LL_ENDL;
 						}
 						else
 						{
-							k += 3;
+							LLVector4a v1; v1.setMul(face.mPositions[index_a], scale);
+							LLVector4a v2; v2.setMul(face.mPositions[index_b], scale);
+							LLVector4a v3; v3.setMul(face.mPositions[index_c], scale);
+							if (ll_is_degenerate(v1, v2, v3))
+							{
+								mHasDegenerate = true;// <FS:Beq> make has_degenerate a member 
+							}
 						}
+						k += 3;
 					}
 				}
 			}
 		}
 	}
 
+	// <FS:Beq> flag degenerates here rather than deferring to a MAV error later
+	mFMP->childSetVisible("physics_status_message_text", mHasDegenerate); //display or clear
+	auto degenerateIcon = mFMP->getChild<LLIconCtrl>("physics_status_message_icon");
+	degenerateIcon->setVisible(mHasDegenerate);
+	if (mHasDegenerate)
+	{
+		has_physics_error |= PhysicsError::DEGENERATE;
+		mFMP->childSetValue("physics_status_message_text", mFMP->getString("phys_status_degenerate_triangles"));
+		LLUIImagePtr img = LLUI::getUIImage("ModelImport_Status_Error");
+		degenerateIcon->setImage(img);
+	}
+	// </FS:Beq>
+
 	mFMP->childSetTextArg("submeshes_info", "[SUBMESHES]", llformat("%d", total_submeshes[LLModel::LOD_HIGH]));
 
 	std::string mesh_status_na = mFMP->getString("mesh_status_na");
@@ -2959,14 +3048,22 @@ void LLModelPreview::updateStatusMessages()
 			}
 		}
 	}
-	mFMP->childSetVisible("physics_status_message_text", physExceededVertexLimit);
-	LLIconCtrl* physStatusIcon = mFMP->getChild<LLIconCtrl>("physics_status_message_icon");
-	physStatusIcon->setVisible(physExceededVertexLimit);
+
 	if (physExceededVertexLimit)
 	{
-		mFMP->childSetValue("physics_status_message_text", mFMP->getString("phys_status_vertex_limit_exceeded"));
-		LLUIImagePtr img = LLUI::getUIImage("ModelImport_Status_Warning");
-		physStatusIcon->setImage(img);
+		has_physics_error |= PhysicsError::TOOMANYVERTSINHULL;
+	}
+
+	if (!(has_physics_error & PhysicsError::DEGENERATE)){ // only update this field (incluides clearing it) if it is not already in use.
+		mFMP->childSetVisible("physics_status_message_text", physExceededVertexLimit);
+		LLIconCtrl* physStatusIcon = mFMP->getChild<LLIconCtrl>("physics_status_message_icon");
+		physStatusIcon->setVisible(physExceededVertexLimit);
+		if (physExceededVertexLimit)
+		{
+			mFMP->childSetValue("physics_status_message_text", mFMP->getString("phys_status_vertex_limit_exceeded"));
+			LLUIImagePtr img = LLUI::getUIImage("ModelImport_Status_Warning");
+			physStatusIcon->setImage(img);
+		}
 	}
 
 	if (getLoadState() >= LLModelLoader::ERROR_PARSING)
@@ -2995,12 +3092,21 @@ void LLModelPreview::updateStatusMessages()
 			mModelNoErrors = false;
 		}
 	}
-
-	// Todo: investigate use of has_degenerate and include into mModelNoErrors upload blocking mechanics
-	// current use of has_degenerate won't block upload permanently - later checks will restore the button
-	if (!mModelNoErrors || has_degenerate)
+	// <FS:Beq> Improve the error checking the TO DO here is no longer applicable but not an FS comment so edited to stop it being picked up
+	//// To do investigate use of has_degenerate and include into mModelNoErrors upload blocking mechanics
+	//// current use of has_degenerate won't block upload permanently - later checks will restore the button
+	//if (!mModelNoErrors || mHasDegenerate)
+	//{
+	//	mFMP->childDisable("ok_btn");
+	if (!mModelNoErrors || mHasDegenerate)
 	{
 		mFMP->childDisable("ok_btn");
+		mFMP->childDisable("calculate_btn");
+	}
+	else
+	{
+		mFMP->childEnable("ok_btn");
+		mFMP->childEnable("calculate_btn");
 	}
 	
 	//add up physics triangles etc
@@ -3616,11 +3722,30 @@ BOOL LLModelPreview::render()
 	bool textures = mViewOption["show_textures"];
 	bool physics = mViewOption["show_physics"];
 
+	// <FS:Beq> Extra configurability, to be exposed later as controls?
+	static LLCachedControl<LLColor4> canvas_col(gSavedSettings, "MeshPreviewCanvasColor");
+	static LLCachedControl<LLColor4> edge_col(gSavedSettings, "MeshPreviewEdgeColor");
+	static LLCachedControl<LLColor4> base_col(gSavedSettings, "MeshPreviewBaseColor");
+	static LLCachedControl<LLColor3> brightness(gSavedSettings, "MeshPreviewBrightnessColor");
+	static LLCachedControl<F32> edge_width(gSavedSettings, "MeshPreviewEdgeWidth");
+	static LLCachedControl<LLColor4> phys_edge_col(gSavedSettings, "MeshPreviewPhysicsEdgeColor");
+	static LLCachedControl<LLColor4> phys_fill_col(gSavedSettings, "MeshPreviewPhysicsFillColor");
+	static LLCachedControl<F32> phys_edge_width(gSavedSettings, "MeshPreviewPhysicsEdgeWidth");
+	static LLCachedControl<LLColor4> deg_edge_col(gSavedSettings, "MeshPreviewDegenerateEdgeColor");
+	static LLCachedControl<LLColor4> deg_fill_col(gSavedSettings, "MeshPreviewDegenerateFillColor");	
+	static LLCachedControl<F32> deg_edge_width(gSavedSettings, "MeshPreviewDegenerateEdgeWidth");
+	static LLCachedControl<F32> deg_point_size(gSavedSettings, "MeshPreviewDegeneratePointSize");
+	// </FS:Beq>
 	S32 width = getWidth();
 	S32 height = getHeight();
 
 	LLGLSUIDefault def;
 	LLGLDisable no_blend(GL_BLEND);
+// <FS:Beq> Clean up render of mesh preview
+//	LLGLEnable blend(GL_BLEND);
+//	gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
+// </FS:Beq> 
+
 	LLGLEnable cull(GL_CULL_FACE);
 	LLGLDepthTest depth(GL_TRUE);
 	LLGLDisable fog(GL_FOG);
@@ -3639,9 +3764,9 @@ BOOL LLModelPreview::render()
 		gGL.matrixMode(LLRender::MM_MODELVIEW);
 		gGL.pushMatrix();
 		gGL.loadIdentity();
-
-		gGL.color4f(0.169f, 0.169f, 0.169f, 1.f);
-
+		// <FS:Beq> uploader improvements
+		//gGL.color4f(0.169f, 0.169f, 0.169f, 1.f);
+		gGL.color4fv(static_cast<LLColor4>(canvas_col).mV);
 		gl_rect_2d_simple( width, height );
 
 		gGL.matrixMode(LLRender::MM_PROJECTION);
@@ -3789,8 +3914,11 @@ BOOL LLModelPreview::render()
 	stop_glerror();
 
 	gGL.pushMatrix();
-	const F32 BRIGHTNESS = 0.9f;
-	gGL.color3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS);
+	// <FS:Beq> mesh uploader improvements configurable brightness
+	//const F32 BRIGHTNESS = 0.9f;
+	//gGL.color3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS);
+	gGL.color4fv(edge_col().mV);
+	// </FS:Beq>
 
 	const U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0;
 
@@ -3875,16 +4003,22 @@ BOOL LLModelPreview::render()
 						}
 						else
 						{
-							gGL.diffuseColor4f(1,1,1,1);
+						// <FS:Beq> improved mesh uploader
+						//	gGL.diffuseColor4f(1,1,1,1);
+							gGL.diffuseColor4fv(static_cast<LLColor4>(base_col).mV);
+						// </FS:Beq>
+
 						}
 
 						buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
 						gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-						gGL.diffuseColor3f(0.4f, 0.4f, 0.4f);
-
+						// <FS:Beq> improved mesh uploader
+						//gGL.diffuseColor3f(0.4f, 0.4f, 0.4f);
+						gGL.diffuseColor4fv(static_cast<LLColor4>(edge_col).mV);
+						// </FS:Beq> 
 						if (edges)
 						{
-							glLineWidth(3.f);
+							glLineWidth(edge_width);
 							glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
 							buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
 							glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
@@ -3896,11 +4030,25 @@ BOOL LLModelPreview::render()
 
 			if (physics)
 			{
+				// <FS:Beq> model upload improvements - use the settings
+				////Vector4a physicsFillColour(0.4, 0.4, 0.4, 0.4);
+				//const LLColor4 physicsFillColour(0.0, 0.5, 1.0, 0.5);
+				////LLVector4a physicsEdgeColour(1.0, 1.0, 0.0, 1.0);
+				//const LLColor4 physicsEdgeColour=physicsFillColour*0.5;
+				//const LLColor4 degenerateFill(1.0, 0.0, 0.0, 0.5);
+				//const LLColor4 degenerateEdge(1.0,0.0,0.0,1.0);
+				// </FS:Beq> 
+
 				glClear(GL_DEPTH_BUFFER_BIT);
-				
-				for (U32 i = 0; i < 2; i++)
+				//<FS:Beq> refactor to remove silly variable names
+				//				for (U32 i = 0; i < 2; i++)
+				for (U32 pass = 0; pass < 2; pass++)
+				//</FS:Beq>
 				{
-					if (i == 0)
+					//<FS:Beq> refactor to remove silly variable names
+					//if (i == 0)
+					if (pass == 0)
+					//</FS:Beq>
 					{ //depth only pass
 						gGL.setColorMask(false, false);
 					}
@@ -3910,8 +4058,11 @@ BOOL LLModelPreview::render()
 					}
 
 					//enable alpha blending on second pass but not first pass
-					LLGLState blend(GL_BLEND, i); 
-					
+					//<FS:Beq> refactor to remove silly variable names
+					//LLGLState blend(GL_BLEND, i);
+					LLGLState blend(GL_BLEND, pass);
+					//</FS:Beq>
+
 					gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
 
 					for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
@@ -3920,175 +4071,196 @@ BOOL LLModelPreview::render()
 
 						LLModel* model = instance.mLOD[LLModel::LOD_PHYSICS];
 
-							if (!model)
-							{
-								continue;
-							}
+						if (!model)
+						{
+							continue;
+						}
 
-							gGL.pushMatrix();
-							LLMatrix4 mat = instance.mTransform;
+						gGL.pushMatrix();
+						LLMatrix4 mat = instance.mTransform;
 
-						gGL.multMatrix((GLfloat*) mat.mMatrix);
+						gGL.multMatrix((GLfloat*)mat.mMatrix);
 
 
-							bool render_mesh = true;
+						bool render_mesh = true;
+						LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread;
+						if (decomp)
+						{
+							LLMutexLock(decomp->mMutex);
+
+							LLModel::Decomposition& physics = model->mPhysics;
 
-							LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread;
-							if (decomp)
+							if (!physics.mHull.empty())
 							{
-								LLMutexLock(decomp->mMutex);
-
-								LLModel::Decomposition& physics = model->mPhysics;
+								render_mesh = false;
 
-								if (!physics.mHull.empty())
-								{
-									render_mesh = false;
+								if (physics.mMesh.empty())
+								{ //build vertex buffer for physics mesh
+									gMeshRepo.buildPhysicsMesh(physics);
+								}
 
-									if (physics.mMesh.empty())
-									{ //build vertex buffer for physics mesh
-										gMeshRepo.buildPhysicsMesh(physics);
-									}
-						
-									if (!physics.mMesh.empty())
-									{ //render hull instead of mesh
-										for (U32 i = 0; i < physics.mMesh.size(); ++i)
+								if (!physics.mMesh.empty())
+								{ //render hull instead of mesh
+									for (U32 i = 0; i < physics.mMesh.size(); ++i)
+									{
+										if (explode > 0.f)
 										{
-											if (explode > 0.f)
-											{
-												gGL.pushMatrix();
+											gGL.pushMatrix();
 
-												LLVector3 offset = model->mHullCenter[i]-model->mCenterOfHullCenters;
-												offset *= explode;
+											LLVector3 offset = model->mHullCenter[i] - model->mCenterOfHullCenters;
+											offset *= explode;
 
-												gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]);
-											}
+											gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]);
+										}
 
-											static std::vector<LLColor4U> hull_colors;
+										static std::vector<LLColor4U> hull_colors;
 
-											if (i+1 >= hull_colors.size())
-											{
-												hull_colors.push_back(LLColor4U(rand()%128+127, rand()%128+127, rand()%128+127, 128));
-											}
+										if (i + 1 >= hull_colors.size())
+										{
+											hull_colors.push_back(LLColor4U(rand() % 128 + 127, rand() % 128 + 127, rand() % 128 + 127, 128));
+										}
 
-											gGL.diffuseColor4ubv(hull_colors[i].mV);
-											LLVertexBuffer::drawArrays(LLRender::TRIANGLES, physics.mMesh[i].mPositions, physics.mMesh[i].mNormals);
+										gGL.diffuseColor4ubv(hull_colors[i].mV);
+										LLVertexBuffer::drawArrays(LLRender::TRIANGLES, physics.mMesh[i].mPositions, physics.mMesh[i].mNormals);
 
-											if (explode > 0.f)
-											{
-												gGL.popMatrix();
-											}
+										if (explode > 0.f)
+										{
+											gGL.popMatrix();
 										}
 									}
 								}
 							}
-						
-							if (render_mesh)
+						}
+
+						if (render_mesh)
+						{
+							if (mVertexBuffer[LLModel::LOD_PHYSICS].empty())
 							{
-								if (mVertexBuffer[LLModel::LOD_PHYSICS].empty())
-								{
-									genBuffers(LLModel::LOD_PHYSICS, false);
-								}
+								genBuffers(LLModel::LOD_PHYSICS, false);
+							}
 
-								U32 num_models = mVertexBuffer[LLModel::LOD_PHYSICS][model].size();
+							U32 num_models = mVertexBuffer[LLModel::LOD_PHYSICS][model].size();
+							if (pass > 0){
 								for (U32 i = 0; i < num_models; ++i)
 								{
 									LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i];
 
 									gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-									gGL.diffuseColor4f(0.4f, 0.4f, 0.0f, 0.4f);
+									gGL.diffuseColor4fv(phys_fill_col().mV);
 
 									buffer->setBuffer(type_mask & buffer->getTypeMask());
-									buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
-
-									gGL.diffuseColor3f(1.f, 1.f, 0.f);
+									buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts() - 1, buffer->getNumIndices(), 0);
 
-									glLineWidth(2.f);
+									gGL.diffuseColor4fv(phys_edge_col().mV);
+									glLineWidth(phys_edge_width);
 									glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-									buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
+									buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts() - 1, buffer->getNumIndices(), 0);
 
 									glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
 									glLineWidth(1.f);
 								}
 							}
-
-							gGL.popMatrix();
 						}
 
-					glLineWidth(3.f);
-					glPointSize(8.f);
-					gPipeline.enableLightsFullbright(LLColor4::white);
-					//show degenerate triangles
-					LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
-					LLGLDisable cull(GL_CULL_FACE);
-					gGL.diffuseColor4f(1.f,0.f,0.f,1.f);
-					const LLVector4a scale(0.5f);
+						gGL.popMatrix();
+					}
 
-					for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
+					//<FS:Beq> refactor to remove silly variable names
+					// also only do this if mDegenerate was set in the preceding mesh checks [Check this if the ordering ever breaks]
+					//if (i > 0)
+					if (pass > 0 && mHasDegenerate)
+					//</FS:Beq>
 					{
-						LLModelInstance& instance = *iter;
-
-						LLModel* model = instance.mLOD[LLModel::LOD_PHYSICS];
-
-						if (!model)
+						glLineWidth(deg_edge_width);
+						glPointSize(deg_point_size);
+// <FS:Beq> This single line is why the degenerate triangles display has been crap forever. 
+// 						gPipeline.enableLightsFullbright(LLColor4::white);
+						//show degenerate triangles
+						LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
+						LLGLDisable cull(GL_CULL_FACE);
+						const LLVector4a scale(0.5f);
+
+						for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
 						{
-							continue;
-						}
+							LLModelInstance& instance = *iter;
 
-						gGL.pushMatrix();
-						LLMatrix4 mat = instance.mTransform;
+							LLModel* model = instance.mLOD[LLModel::LOD_PHYSICS];
 
-						gGL.multMatrix((GLfloat*) mat.mMatrix);
+							if (!model)
+							{
+								continue;
+							}
 
+							gGL.pushMatrix();
+							LLMatrix4 mat = instance.mTransform;
 
-						LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread;
-						if (decomp)
-						{
-							LLMutexLock(decomp->mMutex);
+							gGL.multMatrix((GLfloat*)mat.mMatrix);
 
-							LLModel::Decomposition& physics = model->mPhysics;
 
-							if (physics.mHull.empty())
+							LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread;
+							if (decomp)
 							{
-								if (mVertexBuffer[LLModel::LOD_PHYSICS].empty())
-								{
-									genBuffers(LLModel::LOD_PHYSICS, false);
-								}
-							
-								for (U32 i = 0; i < mVertexBuffer[LLModel::LOD_PHYSICS][model].size(); ++i)
-								{
-									LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i];
+								LLMutexLock(decomp->mMutex);
 
-									buffer->setBuffer(type_mask & buffer->getTypeMask());
+								LLModel::Decomposition& physics = model->mPhysics;
 
-									LLStrider<LLVector3> pos_strider; 
-									buffer->getVertexStrider(pos_strider, 0);
-									LLVector4a* pos = (LLVector4a*) pos_strider.get();
-							
-									LLStrider<U16> idx;
-									buffer->getIndexStrider(idx, 0);
+								if (physics.mHull.empty())
+								{
+									if (mVertexBuffer[LLModel::LOD_PHYSICS].empty())
+									{
+										genBuffers(LLModel::LOD_PHYSICS, false);
+									}
 
-									for (U32 i = 0; i < buffer->getNumIndices(); i += 3)
+									auto num_degenerate = 0;
+									//<FS:Beq> More nested i variable silliness
+									//									for (U32 i = 0; i < mVertexBuffer[LLModel::LOD_PHYSICS][model].size(); ++i)
+									auto num_models = mVertexBuffer[LLModel::LOD_PHYSICS][model].size();
+									for (U32 v = 0; v < num_models; ++v)
 									{
-										LLVector4a v1; v1.setMul(pos[*idx++], scale);
-										LLVector4a v2; v2.setMul(pos[*idx++], scale);
-										LLVector4a v3; v3.setMul(pos[*idx++], scale);
+										LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][v];
+									//</FS:Beq>
+										if(buffer->getNumVerts() < 3)continue;
+
+										buffer->setBuffer(type_mask & buffer->getTypeMask());
+
+										LLStrider<LLVector3> pos_strider;
+										buffer->getVertexStrider(pos_strider, 0);
+										LLVector4a* pos = (LLVector4a*)pos_strider.get();
+
+										LLStrider<U16> idx;
+										buffer->getIndexStrider(idx, 0);
 
-										if (ll_is_degenerate(v1,v2,v3))
+										LLVector4a v1, v2, v3;
+										//<FS:Beq> rename inner most i to avoid merge confusion
+										for (U32 indices_offset = 0; indices_offset < buffer->getNumIndices(); indices_offset += 3)
 										{
-											buffer->draw(LLRender::LINE_LOOP, 3, i);
-											buffer->draw(LLRender::POINTS, 3, i);
+											v1.setMul(pos[*idx++], scale);
+											v2.setMul(pos[*idx++], scale);
+											v3.setMul(pos[*idx++], scale);
+
+											if (ll_is_degenerate(v1, v2, v3))
+											{
+												num_degenerate++;
+												glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+												gGL.diffuseColor3fv(deg_edge_col().mV);
+												buffer->drawRange(LLRender::TRIANGLES, 0, 2, 3, indices_offset);
+												buffer->drawRange(LLRender::POINTS, 0, 2, 3, indices_offset);
+												glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+												gGL.diffuseColor3fv(deg_fill_col().mV);
+												buffer->drawRange(LLRender::TRIANGLES, 0, 2, 3, indices_offset);
+											}
 										}
 									}
 								}
 							}
-						}
 
-						gGL.popMatrix();
+							gGL.popMatrix();
+						}
+						glLineWidth(1.f);
+						glPointSize(1.f);
+						gPipeline.enableLightsPreview();
+						gGL.setSceneBlendType(LLRender::BT_ALPHA);
 					}
-					glLineWidth(1.f);
-					glPointSize(1.f);
-					gPipeline.enableLightsPreview();
-					gGL.setSceneBlendType(LLRender::BT_ALPHA);
 				}
 			}
 		}
@@ -4170,16 +4342,19 @@ BOOL LLModelPreview::render()
 							}
 						
 							buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0);
-							gGL.diffuseColor3f(0.4f, 0.4f, 0.4f);
+							// <FS:Beq> configurable colour and width
+							//gGL.diffuseColor3f(0.4f, 0.4f, 0.4f);
 
 							if (edges)
 							{
-								glLineWidth(3.f);
+								gGL.diffuseColor4fv(edge_col().mV);
+								glLineWidth(edge_width);
 								glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
 								buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0);
 								glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
 								glLineWidth(1.f);
 							}
+							// </FS:Beq>
 						}
 					}
 				}
@@ -4237,8 +4412,11 @@ void LLModelPreview::rotate(F32 yaw_radians, F32 pitch_radians)
 void LLModelPreview::zoom(F32 zoom_amt)
 {
 	F32 new_zoom = mCameraZoom+zoom_amt;
-
-	mCameraZoom	= llclamp(new_zoom, 1.f, 10.f);
+	// <FS:Beq> add configurable zoom TODO: stop clamping in render
+	// mCameraZoom = llclamp(new_zoom, 1.f, 10.f);
+	static LLCachedControl<F32> zoom_limit(gSavedSettings, "MeshPreviewZoomLimit");
+	mCameraZoom	= llclamp(new_zoom, 1.f, zoom_limit());
+	// </FS:Beq>
 }
 
 void LLModelPreview::pan(F32 right, F32 up)
@@ -4444,11 +4622,22 @@ void LLFloaterModelPreview::toggleCalculateButton(bool visible)
 		childSetTextArg("server_weight", "[SIM]", tbd);
 		childSetTextArg("physics_weight", "[PH]", tbd);
 		childSetTextArg("upload_fee", "[FEE]", tbd);
-		childSetTextArg("price_breakdown", "[STREAMING]", tbd);
-		childSetTextArg("price_breakdown", "[PHYSICS]", tbd);
-		childSetTextArg("price_breakdown", "[INSTANCES]", tbd);
-		childSetTextArg("price_breakdown", "[TEXTURES]", tbd);
-		childSetTextArg("price_breakdown", "[MODEL]", tbd);
+		// <FS:Beq> add extended info fields
+		//childSetTextArg("price_breakdown", "[STREAMING]", dashes);
+		//childSetTextArg("price_breakdown", "[PHYSICS]", dashes);
+		//childSetTextArg("price_breakdown", "[INSTANCES]", dashes);
+		//childSetTextArg("price_breakdown", "[TEXTURES]", dashes);
+		//childSetTextArg("price_breakdown", "[MODEL]", dashes);
+		std::string dashes = hasString("--") ? getString("--") : "--";
+		childSetTextArg("price_breakdown", "[STREAMING]", dashes);
+		childSetTextArg("price_breakdown", "[PHYSICS]", dashes);
+		childSetTextArg("price_breakdown", "[INSTANCES]", dashes);
+		childSetTextArg("price_breakdown", "[TEXTURES]", dashes);
+		childSetTextArg("price_breakdown", "[MODEL]", dashes);
+		childSetTextArg("physics_breakdown", "[PCH]", dashes);
+		childSetTextArg("physics_breakdown", "[PM]", dashes);
+		childSetTextArg("physics_breakdown", "[PHU]", dashes);
+		// </FS:Beq>
 	}
 }
 
@@ -4498,6 +4687,16 @@ void LLFloaterModelPreview::handleModelPhysicsFeeReceived()
 	childSetTextArg("price_breakdown", "[INSTANCES]", llformat("%d", result["upload_price_breakdown"]["mesh_instance"].asInteger()));
 	childSetTextArg("price_breakdown", "[TEXTURES]", llformat("%d", result["upload_price_breakdown"]["texture"].asInteger()));
 	childSetTextArg("price_breakdown", "[MODEL]", llformat("%d", result["upload_price_breakdown"]["model"].asInteger()));
+//<FS:Beq> Updates for enhanced Mesh feedback at upload
+	childSetTextArg("physics_breakdown", "[PCH]", llformat("%0.3f", result["model_physics_cost"]["hull"].asReal()));
+	childSetTextArg("physics_breakdown", "[PM]", llformat("%0.3f", result["model_physics_cost"]["mesh"].asReal()));
+	childSetTextArg("physics_breakdown", "[PHU]", llformat("%0.3f", result["model_physics_cost"]["decomposition"].asReal()));
+	childSetTextArg("streaming_breakdown", "[STR_TOTAL]", llformat("%d", result["streaming_cost"].asInteger()));
+	childSetTextArg("streaming_breakdown", "[STR_HIGH]", llformat("%d", result["streaming_params"]["high_lod"].asInteger()));
+	childSetTextArg("streaming_breakdown", "[STR_MED]", llformat("%d", result["streaming_params"]["medium_lod"].asInteger()));
+	childSetTextArg("streaming_breakdown", "[STR_LOW]", llformat("%d", result["streaming_params"]["low_lod"].asInteger()));
+	childSetTextArg("streaming_breakdown", "[STR_LOWEST]", llformat("%d", result["streaming_params"]["lowest_lod"].asInteger()));
+//</FS:Beq>
 	childSetVisible("upload_fee", true);
 	childSetVisible("price_breakdown", true);
 	mUploadBtn->setEnabled(isModelUploadAllowed());
diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h
index 7ec6a58ac7..564f4c39de 100644
--- a/indra/newview/llfloatermodelpreview.h
+++ b/indra/newview/llfloatermodelpreview.h
@@ -152,6 +152,7 @@ protected:
 	static void		onAutoFillCommit(LLUICtrl*,void*);
 	
 	void onLODParamCommit(S32 lod, bool enforce_tri_limit);
+	void draw3dPreview();
 
 	static void		onExplodeCommit(LLUICtrl*, void*);
 	
@@ -310,6 +311,7 @@ public:
 	static bool 		sIgnoreLoadedCallback;
     std::vector<S32> mLodsQuery;
     std::vector<S32> mLodsWithParsingError;
+	bool mHasDegenerate;
 
 protected:
 
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 40d6d325ba..c7626304ed 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -6582,7 +6582,7 @@ void LLPipeline::enableLightsPreview()
 	light->enable();
 	light->setPosition(light_pos);
 	light->setDiffuse(diffuse0);
-	light->setAmbient(LLColor4::black);
+	light->setAmbient(ambient);
 	light->setSpecular(specular0);
 	light->setSpotExponent(0.f);
 	light->setSpotCutoff(180.f);
@@ -6593,7 +6593,7 @@ void LLPipeline::enableLightsPreview()
 	light->enable();
 	light->setPosition(light_pos);
 	light->setDiffuse(diffuse1);
-	light->setAmbient(LLColor4::black);
+	light->setAmbient(ambient);
 	light->setSpecular(specular1);
 	light->setSpotExponent(0.f);
 	light->setSpotCutoff(180.f);
@@ -6603,7 +6603,7 @@ void LLPipeline::enableLightsPreview()
 	light->enable();
 	light->setPosition(light_pos);
 	light->setDiffuse(diffuse2);
-	light->setAmbient(LLColor4::black);
+	light->setAmbient(ambient);
 	light->setSpecular(specular2);
 	light->setSpotExponent(0.f);
 	light->setSpotCutoff(180.f);
diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml
index 5a86eb06fb..e073268b0a 100644
--- a/indra/newview/skins/default/xui/en/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml
@@ -2,12 +2,12 @@
 <floater
  can_close="true"
  can_drag_on_left="false"
- can_minimize="false"
- can_resize="false"
- height="480"
- min_height="480"
- width="980"
- min_width="980"
+ can_minimize="true"
+ can_resize="true"
+ height="600"
+ min_height="600"
+ width="1024"
+ min_width="1024"
  name="Model Preview"
  title="UPLOAD MODEL"
  help_topic="upload_model" >
@@ -33,19 +33,21 @@
   <string name="mesh_status_missing_lod">Missing required level of detail.</string>
   <string name="mesh_status_invalid_material_list">LOD materials are not a subset of reference model.</string>
   <string name="phys_status_vertex_limit_exceeded">Some physical hulls exceed vertex limitations.</string>
+  <string name="phys_status_degenerate_triangles">The physics mesh too dense remove the small thin triangles (see preview)</string>
+  <string name="phys_status_no_havok">The Firestorm OpenSim build is not supported for physics upload in SL.</string>
   <string name="layer_all">All</string> <!-- Text to display in physics layer combo box for "all layers" -->
   <string name="decomposing">Analyzing...</string>
   <string name="simplifying">Simplifying...</string>
   <string name="tbd">TBD</string>
 
-<panel
-  follows="top|left"
-  height="455"
-  layout="topleft"
-  left="3"
-  name="left_panel"
-  top_pad="10"
-  width="630">
+  <panel
+    follows="top|left"
+    height="580"
+    layout="topleft"
+    left="3"
+    name="left_panel"
+    top_pad="0"
+    width="630">
     <panel
       follows="all"
       height="50"
@@ -755,8 +757,9 @@
                       name="first_step_name"
                       text_color="White"
                       top_pad="0"
-                      width="210">
-                      Step 1: Level of Detail
+                      width="210"
+                      valign="center">
+                      Step 1: Pick a physics model :
                     </text>
                     <combo_box
                       follows="left|top"
@@ -798,7 +801,7 @@
               layout="topleft"
               left="18"
               name="physics_tab_border"
-              top_pad="15"
+              top_pad="10"
               width="589"/>
                 <panel
                   bg_alpha_color="0 0 0 0"
@@ -807,7 +810,7 @@
                   follows="top|left"
                   left="18"
                   name="physics analysis"
-                  top_pad="15"
+                  top_pad="10"
                   visible="true"
                   width="589">
                     <text
@@ -819,7 +822,7 @@
                       name="method_label"
                       text_color="White"
                       top_pad="0">
-                      Step 2: Analyze
+                      Step 2: Convert to hulls (optional)
                     </text>
                     <text
                       follows="top|left"
@@ -905,7 +908,7 @@
               layout="topleft"
               left="18"
               name="physics_tab_border"
-              top_pad="15"
+              top_pad="10"
               width="589"/>
                 <panel
                   bg_alpha_color="0 0 0 0"
@@ -914,7 +917,7 @@
                   height="66"
                   left="18"
                   name="physics simplification"
-                  top_pad="15"
+                  top_pad="10"
                   width="589">
                     <text
                       text_color="White"
@@ -1013,7 +1016,7 @@
               layout="topleft"
               left="18"
               name="physics_tab_border"
-              top_pad="15"
+              top_pad="10"
               width="589"/>
                 <panel
                   bg_alpha_color="0 0 0 0"
@@ -1075,10 +1078,9 @@
                  follows="left|top"
                  height="19"
                  layout="topleft"
-                 left_pad="5"
-                 top_delta="0"
+                 top_pad="5"
                  name="physics message"
-                 width="270">
+                 width="589">
                      <icon
                       follows="left|top"
                       height="16"
@@ -1093,7 +1095,7 @@
                       layout="topleft"
                       left_pad="2"
                       name="physics_status_message_text"
-                      width="252"
+                      width="573"
                       top_delta="3"/>
                 </panel>
         </panel>
@@ -1219,13 +1221,14 @@
      </panel>
     </tab_container>
     <panel
-     follows="top|left"
-     height="80"
-     layout="top|left"
-     left="0"
+     follows="top|left|bottom"
+     layout="topleft"
+     height="184"
+     left="4"
+     border="true"
      name="weights_and_warning_panel"
      top_pad="3"
-     width="625">
+     width="629">
        <button
          follows="top|left"
          label="Calculate weights &amp; fee"
@@ -1265,10 +1268,10 @@
          label_color="White"
          layout="topleft"
          name="reset_btn"
-         right="-2"
+         right="-5"
          top="3"
          height="20"
-         width="275"/>
+         width="265"/>
        <!-- ========== WEIGHTS ==========-->
        <text
          follows="top|left"
@@ -1287,7 +1290,7 @@
          left_pad="0"
          name="prim_weight"
          top_delta="0"
-         width="120"
+         width="130"
          word_wrap="true">
          Land impact: [EQ]
        </text>
@@ -1297,7 +1300,7 @@
          left_pad="0"
          name="download_weight"
          top_delta="0"
-         width="100"
+         width="130"
          word_wrap="true">
          Download: [ST]
        </text>
@@ -1307,7 +1310,7 @@
          layout="topleft"
          left_pad="0"
          name="physics_weight"
-         width="90"
+         width="130"
          word_wrap="true">
          Physics: [PH]
        </text>
@@ -1317,17 +1320,148 @@
          layout="topleft"
          left_pad="0"
          name="server_weight"
-         width="83"
+         width="130"
          word_wrap="true">
          Server: [SIM]
        </text>
-       <!-- ========== NOTE MESSAGE ========== -->
+       <!-- =========== Cost breakdown ======== -->
+      <panel
+        border="true"
+        top_pad="5"
+        layout="topleft"
+        left="6"
+        name="price_breakdown_panel"
+        width="120"
+        height="100">
+        <text
+          layout="topleft"
+          left="3">
+          Price Breakdown
+        </text>
+        <view_border
+          bevel_style="none"
+          follows="top|left"
+          height="0"
+          layout="topleft"
+          left="3"
+          name="price_breakdown_border"
+          top_pad="5"
+          width="110"/>
+        <text
+          height="80"
+          top_pad="5"
+          layout="topleft"
+          left="3"
+          name="price_breakdown_labels"
+          width="70"
+          word_wrap="false">
+Download:
+Physics:
+Instances:
+Textures:
+Model:
+        </text>
+        <text
+          height="80"
+          top_delta="0"
+          layout="topleft"
+          halign="right"
+          left_pad="0"
+          name="price_breakdown"
+          width="40"
+          word_wrap="false">
+[STREAMING]
+[PHYSICS]
+[INSTANCES]
+[TEXTURES]
+[MODEL]
+        </text>
+      </panel>
+       <!-- 
+       Streaming breakdown numbers are available but not fully understood
+       uncommenting the following sections will display the numbers for debugging purposes
+       <text
+        height="80"
+        top_delta="0"
+        layout="topleft"
+        left="130"
+        name="streaming_breakdown_labels"
+        width="65"
+        word_wrap="true">
+Streaming/Download:
+High:
+Medium:
+Low:
+Lowest:
+      </text>
        <text
+        height="80"
+        top_delta="0"
+        layout="topleft"
+        left_pad="0"
+        name="streaming_breakdown"
+        width="95"
+        word_wrap="true">
+[STR_TOTAL]
+[STR_HIGH]
+[STR_MED]
+[STR_LOW]
+[STR_LOWEST]
+      </text>-->
+      <panel
+        border="true"
+        layout="topleft"
+        left_pad="265"
+        name="price_breakdown_panel"
+        width="120"
+        height="100">
+        <text
+          layout="topleft"
+          left="3">
+          Physics Costs
+        </text>
+        <view_border
+          bevel_style="none"
+          follows="top|left"
+          height="0"
+          layout="topleft"
+          left="3"
+          name="price_breakdown_border"
+          top_pad="5"
+          width="110"/>
+        <text
+         height="80"
+         top_pad="5"
+         layout="topleft"
+         left="5"
+         name="physics_breakdown_labels"
+         width="65">
+Base Hull:
+Mesh:
+Analysed:
+        </text>
+        <text
+         height="80"
+         top_delta="0"
+         layout="topleft"
+         left_pad="0"
+         name="physics_breakdown"
+         width="40"
+         halign="right"
+         word_wrap="false"
+         visible="true">
+[PCH]
+[PM]
+[PHU]
+        </text>-->
+      </panel>
+      <!-- ========== NOTE MESSAGE ========== -->
+      <text
          font="SansSerif"
          layout="topleft"
          left="6"
          name="warning_title"
-         top_pad="10"
+         top_pad="5"
          text_color="DrYellow"
          visible="false"
          width="40">
@@ -1346,104 +1480,110 @@
          visible="false">
          You dont have rights to upload mesh models. [[VURL] Find out how] to get certified.
        </text>
-       <text text_color="Yellow" layout="topleft" top_delta="20" left="6" name="status">[STATUS]</text>
-  
+       <text text_color="Yellow" layout="topleft" top_delta="5" left="6" name="status">
+[STATUS]
+       </text>
     </panel>
-</panel>
-
-<text 
- follows="left|top"
- layout="topleft"
- left="640"
- name="lod_label"
- text_color="White"
- top="13"
- height="15"
- width="290">
- Preview:
- </text>
-<panel
- border="true"
- bevel_style="none"
- follows="top|left"
- name="preview_panel"
- top_pad="4"
- width="290"
- height="290"/>
-
-<panel
-  follows="all"
-  height="130"
-  layout="topleft"
-  name="right_panel"
-  top_pad="5"
-  width="340">
-    <combo_box
-      top_pad="3"
+  </panel>
+  <panel
+    follows="top|left|bottom|right"
+    can_resize="true"
+    name="right_panel"
+    top="0"
+    left="640"
+    background_visible="true"
+    width="375">
+    <text
       follows="left|top"
-      height="18"
       layout="topleft"
-      name="preview_lod_combo"
-      width="150"
-      tool_tip="LOD to view in preview render">
+      left="0"
+      name="lod_label"
+      text_color="White"
+      top="13"
+      height="15"
+      width="290">
+      Preview:
+    </text>
+    <panel
+      can_resize="false"
+      follows="top|left"
+      height="20"
+      name="right_upper_panel"
+      top="8"
+      left="60"
+      background_visible="true"
+      width="315">
+      <combo_box
+        top_pad="3"
+        can_resize="false"
+        follows="top|left"
+        height="18"
+        layout="topleft"
+        name="preview_lod_combo"
+        width="75"
+        tool_tip="LOD to view in preview render">
         <combo_item name="high">   High   </combo_item>
         <combo_item name="medium"> Medium </combo_item>
         <combo_item name="low">    Low    </combo_item>
         <combo_item name="lowest"> Lowest </combo_item>
-    </combo_box>
-    <text
-      follows="top|left"
-      layout="topleft"
-      text_color="White"
-      top="5"
-      left_pad="20"
-      name="label_display"
-      width="50">
-      Display...
-    </text>
-    <check_box
-      follows="top|left"
-      label="Edges"
+      </combo_box>
+    </panel>
+  </panel>
+  <panel
+     border="true"
+     bevel_style="none"
+     follows="top|left|right|bottom"
+     layout="topleft"
+     name="preview_panel"
+     top="30"
+     width="375"
+     height="525"/>
+
+   <panel
+     follows="left|right|bottom"
+     layout="topleft"
+     height="40"
+     name="lower_right_panel"
+     top_pad="5"
+     width="375">
+     <check_box
+       follows="right|bottom"
+       label="Edges"
       label_text.text_color="White"
       layout="topleft"
-      left_delta="0"
       name="show_edges"
-      top_pad="8">
-    </check_box>
+      width="70"
+      left="0"
+      top_pad="8"/>
     <check_box
-      follows="top|left"
+      follows="right|bottom"
+      left_pad="8"
       label="Physics"
       label_text.text_color="White"
-      layout="topleft"
-      name="show_physics"
-      top_pad="8">
-    </check_box>
+      name="show_physics"/>
     <check_box
-      follows="top|left"
+      follows="right|bottom"
       label="Textures"
       label_text.text_color="White"
       layout="topleft"
       name="show_textures"
-      top_pad="8">
-    </check_box>
+      left_pad="0"/>
     <check_box
-      follows="top|left"
-      label="Skin weights"
+      follows="right|bottom"
+      label="Weights"
       label_text.text_color="White"
       layout="topleft"
       name="show_skin_weight"
-      top_pad="8">
-    </check_box>
+      left_pad="0"/>
     <check_box
-      follows="top|left"
+      follows="right|bottom"
       label="Joints"
       label_text.text_color="White"
       layout="topleft"
       name="show_joint_positions"
-      top_pad="8">
-    </check_box>
+      left_pad="0"/>
     <text
-      follows="top|left"
+      follows="right|bottom"
       layout="topleft"
       left="2"
       name="physics_explode_label"
@@ -1453,12 +1593,13 @@
     </text>
     <slider
       name="physics_explode"
-      follows="top|left"
-      top="100"
-      left="0"
+      follows="right|bottom"
+      valign="center"
+      top="15"
+      left="80"
       min_val="0.0"
       max_val="3.0"
       height="20"
-      width="150"/>
-</panel>
+      width="120"/>
+  </panel>
 </floater>
-- 
cgit v1.2.3


From 9a24c728d8b6a5e42e4babcebe75116db36e9f0f Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Thu, 3 Jan 2019 01:19:41 +0200
Subject: SL-10288 settings.xml fix

---
 indra/newview/app_settings/settings.xml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 1abddc80cb..72301e7d14 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -6810,6 +6810,7 @@
     <key>Value</key>
     <real>10.0</real>
   </map>
+  <key>MigrateCacheDirectory</key>
   <map>
       <key>Comment</key>
       <string>Check for old version of disk cache to migrate to current location</string>
@@ -16480,3 +16481,4 @@
 </map>
 </llsd>
 
+
-- 
cgit v1.2.3


From 76369c2463246227e297c6fee88a4de4e6d4ed67 Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Thu, 3 Jan 2019 14:30:01 +0200
Subject: SL-10288 comments cleanup

---
 .../shaders/class1/objects/previewV.glsl           |   2 -
 indra/newview/lldynamictexture.cpp                 |  15 +--
 indra/newview/llfloatermodelpreview.cpp            | 118 ++++-----------------
 3 files changed, 21 insertions(+), 114 deletions(-)

diff --git a/indra/newview/app_settings/shaders/class1/objects/previewV.glsl b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl
index 3424613e94..de2ea2a065 100644
--- a/indra/newview/app_settings/shaders/class1/objects/previewV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl
@@ -91,9 +91,7 @@ void main()
 
 	// Collect normal lights (need to be divided by two, as we later multiply by 2)
 	col.rgb += light_diffuse[1].rgb * calcDirectionalLight(norm, light_position[1].xyz);
-//	col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].z);
 	col.rgb += light_diffuse[2].rgb * calcDirectionalLight(norm, light_position[2].xyz);
-//	col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].z);
 	col.rgb += light_diffuse[3].rgb * calcDirectionalLight(norm, light_position[3].xyz);
 	col /= 2.0;
 	vertex_color = col*color;
diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp
index af6977d3cd..e180d91461 100644
--- a/indra/newview/lldynamictexture.cpp
+++ b/indra/newview/lldynamictexture.cpp
@@ -125,17 +125,11 @@ BOOL LLViewerDynamicTexture::render()
 //-----------------------------------------------------------------------------
 void LLViewerDynamicTexture::preRender(BOOL clear_depth)
 {
-	// <FS:Beq> changes to support higher resolution rendering in the preview
-	////only images up to 512x512 are supported
-	//llassert(mFullHeight <= 512);
-	//llassert(mFullWidth <= 512);
 	gPipeline.allocatePhysicsBuffer();
 	llassert(mFullWidth <= static_cast<S32>(gPipeline.mPhysicsDisplay.getWidth()));
 	llassert(mFullHeight <= static_cast<S32>(gPipeline.mPhysicsDisplay.getHeight()));
 
-//	if (gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI)
 	if (gGLManager.mHasFramebufferObject && gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsATI)
-// </FS:Beq>
 	{ //using offscreen render target, just use the bottom left corner
 		mOrigin.set(0, 0);
 	}
@@ -221,15 +215,13 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
 	{
 		return TRUE;
 	}
-	// <FS:Beq> changes to support higher resolution rendering in the preview
-	//	bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI;
+
 	bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsATI;
 	if (use_fbo)
 	{
-//		gPipeline.mWaterDis.bindTarget();
 		gPipeline.mPhysicsDisplay.bindTarget();
 	}
-	// </FS:Beq>
+
 	LLGLSLShader::bindNoShader();
 	LLVertexBuffer::unbind();
 	
@@ -265,10 +257,7 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
 
 	if (use_fbo)
 	{
-		// <FS:Beq> changes to support higher resolution rendering in the preview
-		// gPipeline.mWaterDis.flush();
 		gPipeline.mPhysicsDisplay.flush();
-		// </FS:Beq>
 	}
 
 	return ret;
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 01f0a5197d..c86eed2192 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -427,11 +427,8 @@ void LLFloaterModelPreview::initModelPreview()
 	{
 		delete mModelPreview;
 	}
-	// <FS:Beq> mesh uploader changes to allow higher resolution render
-	//	mModelPreview = new LLModelPreview(512, 512, this);
 	auto size = gSavedSettings.getS32("PreviewRenderSize");
 	mModelPreview = new LLModelPreview(size, size, this );
-	// </FS:Beq>
 	mModelPreview->setPreviewTarget(16.f);
 	mModelPreview->setDetailsCallback(boost::bind(&LLFloaterModelPreview::setDetails, this, _1, _2, _3, _4, _5));
 	mModelPreview->setModelUpdatedCallback(boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this, _1));
@@ -441,8 +438,6 @@ void LLFloaterModelPreview::onViewOptionChecked(LLUICtrl* ctrl)
 {
 	if (mModelPreview)
 	{
-		// <FS:Beq> only show explode when phsyics is on
-		//		mModelPreview->mViewOption[ctrl->getName()] = !mModelPreview->mViewOption[ctrl->getName()];
 		auto name = ctrl->getName();
 		mModelPreview->mViewOption[name] = !mModelPreview->mViewOption[name];
 		if (name == "show_physics")
@@ -664,7 +659,6 @@ void LLFloaterModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit)
 	}
 }
 
-// <FS:Beq> extracted method to simplify changes in layout
 void LLFloaterModelPreview::draw3dPreview()
 {
 	gGL.color3f(1.f, 1.f, 1.f);
@@ -1266,7 +1260,7 @@ LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp)
 , mResetJoints( false )
 , mModelNoErrors( true )
 , mLastJointUpdate( false )
-, mHasDegenerate( false ) // <FS:Beq>
+, mHasDegenerate( false )
 {
 	mNeedsUpdate = TRUE;
 	mCameraDistance = 0.f;
@@ -2756,7 +2750,7 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim
 
 void LLModelPreview::updateStatusMessages()
 {
-// <FS:Beq> bit mask values for physics errors. used to prevent overwrite of single line status
+// bit mask values for physics errors. used to prevent overwrite of single line status
 // TODO: use this to provied multiline status
 	enum PhysicsError
 	{
@@ -2766,10 +2760,10 @@ void LLModelPreview::updateStatusMessages()
 		TOOMANYHULLS=4,
 		TOOMANYVERTSINHULL=8
 	};
-// </FS:Beq>
+
 	assert_main_thread();
 
-	U32 has_physics_error{ PhysicsError::NONE }; // <FS:Beq> physics error bitmap
+	U32 has_physics_error{ PhysicsError::NONE }; // physics error bitmap
 	//triangle/vertex/submesh count for each mesh asset for each lod
 	std::vector<S32> tris[LLModel::NUM_LODS];
 	std::vector<S32> verts[LLModel::NUM_LODS];
@@ -2858,38 +2852,25 @@ void LLModelPreview::updateStatusMessages()
 	{
 		mMaxTriangleLimit = total_tris[LLModel::LOD_HIGH];
 	}
-	// <FS:Beq> make has_degenerate a member so that we can use it in the render method
-	// has_degenerate = false
+
 	mHasDegenerate = false;
 	{//check for degenerate triangles in physics mesh
 		U32 lod = LLModel::LOD_PHYSICS;
 		const LLVector4a scale(0.5f);
-		for (U32 i = 0; i < mModel[lod].size() && !mHasDegenerate; ++i)// <FS:Beq> make has_degenerate a member 
+		for (U32 i = 0; i < mModel[lod].size() && !mHasDegenerate; ++i)
 		{ //for each model in the lod
 			if (mModel[lod][i] && mModel[lod][i]->mPhysics.mHull.empty())
 			{ //no decomp exists
 				S32 cur_submeshes = mModel[lod][i]->getNumVolumeFaces();
-				for (S32 j = 0; j < cur_submeshes && !mHasDegenerate; ++j)// <FS:Beq> make has_degenerate a member 
+				for (S32 j = 0; j < cur_submeshes && !mHasDegenerate; ++j)
 				{ //for each submesh (face), add triangles and vertices to current total
 					LLVolumeFace& face = mModel[lod][i]->getVolumeFace(j);
-					for (S32 k = 0; (k < face.mNumIndices) && !mHasDegenerate; )// <FS:Beq> make has_degenerate a member 
+					for (S32 k = 0; (k < face.mNumIndices) && !mHasDegenerate; )
 					{
 						U16 index_a = face.mIndices[k + 0];
 						U16 index_b = face.mIndices[k + 1];
 						U16 index_c = face.mIndices[k + 2];
-						// <FS:Beq> FIRE-23367/23387 - Allow forced empty triangle placeholders created by the LOD processing.
-						//	LLVector4a v1; v1.setMul(face.mPositions[index_a], scale);
-						//	LLVector4a v2; v2.setMul(face.mPositions[index_b], scale);
-						//	LLVector4a v3; v3.setMul(face.mPositions[index_c], scale);
-
-						//	if (ll_is_degenerate(v1, v2, v3))
-						//	{
-						//		mHasDegenerate = true;// <FS:Beq> make has_degenerate a member 
-						//	}
-						//	else
-						//	{
-						//		k += 3;
-						//	}
+
 						if (index_c == 0 && index_b == 0 && index_a == 0) // test in reverse as 3rd index is less likely to be 0 in a normal case
 						{
 							LL_DEBUGS("MeshValidation") << "Empty placeholder triangle (3 identical index 0 verts) ignored" << LL_ENDL;
@@ -2901,7 +2882,7 @@ void LLModelPreview::updateStatusMessages()
 							LLVector4a v3; v3.setMul(face.mPositions[index_c], scale);
 							if (ll_is_degenerate(v1, v2, v3))
 							{
-								mHasDegenerate = true;// <FS:Beq> make has_degenerate a member 
+								mHasDegenerate = true;
 							}
 						}
 						k += 3;
@@ -2911,7 +2892,7 @@ void LLModelPreview::updateStatusMessages()
 		}
 	}
 
-	// <FS:Beq> flag degenerates here rather than deferring to a MAV error later
+	// flag degenerates here rather than deferring to a MAV error later
 	mFMP->childSetVisible("physics_status_message_text", mHasDegenerate); //display or clear
 	auto degenerateIcon = mFMP->getChild<LLIconCtrl>("physics_status_message_icon");
 	degenerateIcon->setVisible(mHasDegenerate);
@@ -2922,7 +2903,6 @@ void LLModelPreview::updateStatusMessages()
 		LLUIImagePtr img = LLUI::getUIImage("ModelImport_Status_Error");
 		degenerateIcon->setImage(img);
 	}
-	// </FS:Beq>
 
 	mFMP->childSetTextArg("submeshes_info", "[SUBMESHES]", llformat("%d", total_submeshes[LLModel::LOD_HIGH]));
 
@@ -3092,12 +3072,7 @@ void LLModelPreview::updateStatusMessages()
 			mModelNoErrors = false;
 		}
 	}
-	// <FS:Beq> Improve the error checking the TO DO here is no longer applicable but not an FS comment so edited to stop it being picked up
-	//// To do investigate use of has_degenerate and include into mModelNoErrors upload blocking mechanics
-	//// current use of has_degenerate won't block upload permanently - later checks will restore the button
-	//if (!mModelNoErrors || mHasDegenerate)
-	//{
-	//	mFMP->childDisable("ok_btn");
+
 	if (!mModelNoErrors || mHasDegenerate)
 	{
 		mFMP->childDisable("ok_btn");
@@ -3722,7 +3697,7 @@ BOOL LLModelPreview::render()
 	bool textures = mViewOption["show_textures"];
 	bool physics = mViewOption["show_physics"];
 
-	// <FS:Beq> Extra configurability, to be exposed later as controls?
+	// Extra configurability, to be exposed later as controls?
 	static LLCachedControl<LLColor4> canvas_col(gSavedSettings, "MeshPreviewCanvasColor");
 	static LLCachedControl<LLColor4> edge_col(gSavedSettings, "MeshPreviewEdgeColor");
 	static LLCachedControl<LLColor4> base_col(gSavedSettings, "MeshPreviewBaseColor");
@@ -3735,16 +3710,12 @@ BOOL LLModelPreview::render()
 	static LLCachedControl<LLColor4> deg_fill_col(gSavedSettings, "MeshPreviewDegenerateFillColor");	
 	static LLCachedControl<F32> deg_edge_width(gSavedSettings, "MeshPreviewDegenerateEdgeWidth");
 	static LLCachedControl<F32> deg_point_size(gSavedSettings, "MeshPreviewDegeneratePointSize");
-	// </FS:Beq>
+
 	S32 width = getWidth();
 	S32 height = getHeight();
 
 	LLGLSUIDefault def;
 	LLGLDisable no_blend(GL_BLEND);
-// <FS:Beq> Clean up render of mesh preview
-//	LLGLEnable blend(GL_BLEND);
-//	gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
-// </FS:Beq> 
 
 	LLGLEnable cull(GL_CULL_FACE);
 	LLGLDepthTest depth(GL_TRUE);
@@ -3764,8 +3735,7 @@ BOOL LLModelPreview::render()
 		gGL.matrixMode(LLRender::MM_MODELVIEW);
 		gGL.pushMatrix();
 		gGL.loadIdentity();
-		// <FS:Beq> uploader improvements
-		//gGL.color4f(0.169f, 0.169f, 0.169f, 1.f);
+
 		gGL.color4fv(static_cast<LLColor4>(canvas_col).mV);
 		gl_rect_2d_simple( width, height );
 
@@ -3914,11 +3884,7 @@ BOOL LLModelPreview::render()
 	stop_glerror();
 
 	gGL.pushMatrix();
-	// <FS:Beq> mesh uploader improvements configurable brightness
-	//const F32 BRIGHTNESS = 0.9f;
-	//gGL.color3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS);
 	gGL.color4fv(edge_col().mV);
-	// </FS:Beq>
 
 	const U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0;
 
@@ -4003,19 +3969,12 @@ BOOL LLModelPreview::render()
 						}
 						else
 						{
-						// <FS:Beq> improved mesh uploader
-						//	gGL.diffuseColor4f(1,1,1,1);
 							gGL.diffuseColor4fv(static_cast<LLColor4>(base_col).mV);
-						// </FS:Beq>
-
 						}
 
 						buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
 						gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-						// <FS:Beq> improved mesh uploader
-						//gGL.diffuseColor3f(0.4f, 0.4f, 0.4f);
 						gGL.diffuseColor4fv(static_cast<LLColor4>(edge_col).mV);
-						// </FS:Beq> 
 						if (edges)
 						{
 							glLineWidth(edge_width);
@@ -4030,25 +3989,10 @@ BOOL LLModelPreview::render()
 
 			if (physics)
 			{
-				// <FS:Beq> model upload improvements - use the settings
-				////Vector4a physicsFillColour(0.4, 0.4, 0.4, 0.4);
-				//const LLColor4 physicsFillColour(0.0, 0.5, 1.0, 0.5);
-				////LLVector4a physicsEdgeColour(1.0, 1.0, 0.0, 1.0);
-				//const LLColor4 physicsEdgeColour=physicsFillColour*0.5;
-				//const LLColor4 degenerateFill(1.0, 0.0, 0.0, 0.5);
-				//const LLColor4 degenerateEdge(1.0,0.0,0.0,1.0);
-				// </FS:Beq> 
-
 				glClear(GL_DEPTH_BUFFER_BIT);
-				//<FS:Beq> refactor to remove silly variable names
-				//				for (U32 i = 0; i < 2; i++)
 				for (U32 pass = 0; pass < 2; pass++)
-				//</FS:Beq>
 				{
-					//<FS:Beq> refactor to remove silly variable names
-					//if (i == 0)
 					if (pass == 0)
-					//</FS:Beq>
 					{ //depth only pass
 						gGL.setColorMask(false, false);
 					}
@@ -4058,10 +4002,7 @@ BOOL LLModelPreview::render()
 					}
 
 					//enable alpha blending on second pass but not first pass
-					//<FS:Beq> refactor to remove silly variable names
-					//LLGLState blend(GL_BLEND, i);
 					LLGLState blend(GL_BLEND, pass);
-					//</FS:Beq>
 
 					gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
 
@@ -4165,16 +4106,11 @@ BOOL LLModelPreview::render()
 						gGL.popMatrix();
 					}
 
-					//<FS:Beq> refactor to remove silly variable names
-					// also only do this if mDegenerate was set in the preceding mesh checks [Check this if the ordering ever breaks]
-					//if (i > 0)
+					// only do this if mDegenerate was set in the preceding mesh checks [Check this if the ordering ever breaks]
 					if (pass > 0 && mHasDegenerate)
-					//</FS:Beq>
 					{
 						glLineWidth(deg_edge_width);
 						glPointSize(deg_point_size);
-// <FS:Beq> This single line is why the degenerate triangles display has been crap forever. 
-// 						gPipeline.enableLightsFullbright(LLColor4::white);
 						//show degenerate triangles
 						LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
 						LLGLDisable cull(GL_CULL_FACE);
@@ -4212,13 +4148,10 @@ BOOL LLModelPreview::render()
 									}
 
 									auto num_degenerate = 0;
-									//<FS:Beq> More nested i variable silliness
-									//									for (U32 i = 0; i < mVertexBuffer[LLModel::LOD_PHYSICS][model].size(); ++i)
 									auto num_models = mVertexBuffer[LLModel::LOD_PHYSICS][model].size();
 									for (U32 v = 0; v < num_models; ++v)
 									{
 										LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][v];
-									//</FS:Beq>
 										if(buffer->getNumVerts() < 3)continue;
 
 										buffer->setBuffer(type_mask & buffer->getTypeMask());
@@ -4231,7 +4164,6 @@ BOOL LLModelPreview::render()
 										buffer->getIndexStrider(idx, 0);
 
 										LLVector4a v1, v2, v3;
-										//<FS:Beq> rename inner most i to avoid merge confusion
 										for (U32 indices_offset = 0; indices_offset < buffer->getNumIndices(); indices_offset += 3)
 										{
 											v1.setMul(pos[*idx++], scale);
@@ -4342,8 +4274,6 @@ BOOL LLModelPreview::render()
 							}
 						
 							buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0);
-							// <FS:Beq> configurable colour and width
-							//gGL.diffuseColor3f(0.4f, 0.4f, 0.4f);
 
 							if (edges)
 							{
@@ -4354,7 +4284,6 @@ BOOL LLModelPreview::render()
 								glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
 								glLineWidth(1.f);
 							}
-							// </FS:Beq>
 						}
 					}
 				}
@@ -4412,11 +4341,9 @@ void LLModelPreview::rotate(F32 yaw_radians, F32 pitch_radians)
 void LLModelPreview::zoom(F32 zoom_amt)
 {
 	F32 new_zoom = mCameraZoom+zoom_amt;
-	// <FS:Beq> add configurable zoom TODO: stop clamping in render
-	// mCameraZoom = llclamp(new_zoom, 1.f, 10.f);
+	// TODO: stop clamping in render
 	static LLCachedControl<F32> zoom_limit(gSavedSettings, "MeshPreviewZoomLimit");
 	mCameraZoom	= llclamp(new_zoom, 1.f, zoom_limit());
-	// </FS:Beq>
 }
 
 void LLModelPreview::pan(F32 right, F32 up)
@@ -4622,12 +4549,6 @@ void LLFloaterModelPreview::toggleCalculateButton(bool visible)
 		childSetTextArg("server_weight", "[SIM]", tbd);
 		childSetTextArg("physics_weight", "[PH]", tbd);
 		childSetTextArg("upload_fee", "[FEE]", tbd);
-		// <FS:Beq> add extended info fields
-		//childSetTextArg("price_breakdown", "[STREAMING]", dashes);
-		//childSetTextArg("price_breakdown", "[PHYSICS]", dashes);
-		//childSetTextArg("price_breakdown", "[INSTANCES]", dashes);
-		//childSetTextArg("price_breakdown", "[TEXTURES]", dashes);
-		//childSetTextArg("price_breakdown", "[MODEL]", dashes);
 		std::string dashes = hasString("--") ? getString("--") : "--";
 		childSetTextArg("price_breakdown", "[STREAMING]", dashes);
 		childSetTextArg("price_breakdown", "[PHYSICS]", dashes);
@@ -4637,7 +4558,6 @@ void LLFloaterModelPreview::toggleCalculateButton(bool visible)
 		childSetTextArg("physics_breakdown", "[PCH]", dashes);
 		childSetTextArg("physics_breakdown", "[PM]", dashes);
 		childSetTextArg("physics_breakdown", "[PHU]", dashes);
-		// </FS:Beq>
 	}
 }
 
@@ -4687,7 +4607,7 @@ void LLFloaterModelPreview::handleModelPhysicsFeeReceived()
 	childSetTextArg("price_breakdown", "[INSTANCES]", llformat("%d", result["upload_price_breakdown"]["mesh_instance"].asInteger()));
 	childSetTextArg("price_breakdown", "[TEXTURES]", llformat("%d", result["upload_price_breakdown"]["texture"].asInteger()));
 	childSetTextArg("price_breakdown", "[MODEL]", llformat("%d", result["upload_price_breakdown"]["model"].asInteger()));
-//<FS:Beq> Updates for enhanced Mesh feedback at upload
+
 	childSetTextArg("physics_breakdown", "[PCH]", llformat("%0.3f", result["model_physics_cost"]["hull"].asReal()));
 	childSetTextArg("physics_breakdown", "[PM]", llformat("%0.3f", result["model_physics_cost"]["mesh"].asReal()));
 	childSetTextArg("physics_breakdown", "[PHU]", llformat("%0.3f", result["model_physics_cost"]["decomposition"].asReal()));
@@ -4696,7 +4616,7 @@ void LLFloaterModelPreview::handleModelPhysicsFeeReceived()
 	childSetTextArg("streaming_breakdown", "[STR_MED]", llformat("%d", result["streaming_params"]["medium_lod"].asInteger()));
 	childSetTextArg("streaming_breakdown", "[STR_LOW]", llformat("%d", result["streaming_params"]["low_lod"].asInteger()));
 	childSetTextArg("streaming_breakdown", "[STR_LOWEST]", llformat("%d", result["streaming_params"]["lowest_lod"].asInteger()));
-//</FS:Beq>
+
 	childSetVisible("upload_fee", true);
 	childSetVisible("price_breakdown", true);
 	mUploadBtn->setEnabled(isModelUploadAllowed());
-- 
cgit v1.2.3


From 9a0f37670874a3289b31f0ba02342e85a1784447 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Thu, 3 Jan 2019 16:45:17 +0200
Subject: SL-8963 Fixed Long name of region overlaps with next one on the World
 map

---
 indra/newview/llworldmapview.cpp | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp
index b88631a71b..f1c23bdb2d 100644
--- a/indra/newview/llworldmapview.cpp
+++ b/indra/newview/llworldmapview.cpp
@@ -465,7 +465,11 @@ void LLWorldMapView::draw()
 					mesg, 0,
 					llfloor(left + 3), llfloor(bottom + 2),
 					LLColor4::white,
-					LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW);
+					LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW,
+					S32_MAX, //max_chars
+					sMapScale, //max_pixels
+					NULL,
+					TRUE); //use ellipses
 			}
 		}
 	}
-- 
cgit v1.2.3


From ab428e194eaa144e8dcecc353c3c7ed83d6cee3e Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Fri, 4 Jan 2019 10:57:49 +0200
Subject: SL-1866 FIXED [OSX] Viewer crashes when the user changes avatar after
 editing texture

---
 indra/newview/lltexturectrl.cpp | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 1a2a10f721..1396a8546d 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -1096,6 +1096,10 @@ void LLTextureCtrl::setVisible( BOOL visible )
 void LLTextureCtrl::setEnabled( BOOL enabled )
 {
 	LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
+	if( floaterp )
+	{
+		floaterp->setActive(enabled);
+	}
 	if( enabled )
 	{
 		std::string tooltip;
@@ -1110,11 +1114,6 @@ void LLTextureCtrl::setEnabled( BOOL enabled )
 		closeDependentFloater();
 	}
 
-	if( floaterp )
-	{
-		floaterp->setActive(enabled);
-	}
-
 	mCaption->setEnabled( enabled );
 
 	LLView::setEnabled( enabled );
@@ -1215,9 +1214,10 @@ void LLTextureCtrl::showPicker(BOOL take_focus)
 void LLTextureCtrl::closeDependentFloater()
 {
 	LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
-	if( floaterp )
+	if( floaterp && floaterp->isInVisibleChain())
 	{
 		floaterp->setOwner(NULL);
+		floaterp->setVisible(FALSE);
 		floaterp->closeFloater();
 	}
 }
-- 
cgit v1.2.3


From 09b750483a2cde7ea3c80a0238f3224a2cf1cb70 Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Thu, 3 Jan 2019 22:59:49 +0200
Subject: SL-10293 Firestorm PR: preferences and menu search

---
 doc/contributions.txt                              |   1 +
 indra/llui/CMakeLists.txt                          |   1 +
 indra/llui/llbutton.cpp                            |   4 +
 indra/llui/llbutton.h                              |   7 +
 indra/llui/llcheckboxctrl.h                        |  13 ++
 indra/llui/llmenugl.cpp                            |   4 +
 indra/llui/llmenugl.h                              |   9 +-
 indra/llui/llsearchablecontrol.h                   |  71 ++++++++++
 indra/llui/llsliderctrl.h                          |  15 +-
 indra/llui/lltabcontainer.cpp                      |  50 ++++++-
 indra/llui/lltabcontainer.h                        |   2 +
 indra/llui/lltextbase.cpp                          |  11 ++
 indra/llui/lltextbase.h                            |   8 +-
 indra/llui/lluictrl.h                              |   1 +
 indra/newview/CMakeLists.txt                       |   2 +
 indra/newview/llfloaterpreference.cpp              | 121 +++++++++++++++-
 indra/newview/llfloaterpreference.h                |  15 ++
 indra/newview/llsearchableui.cpp                   | 154 +++++++++++++++++++++
 indra/newview/llsearchableui.h                     | 121 ++++++++++++++++
 indra/newview/llstatusbar.cpp                      |  92 +++++++++++-
 indra/newview/llstatusbar.h                        |  17 +++
 .../skins/default/xui/en/floater_preferences.xml   |  42 +++++-
 .../skins/default/xui/en/panel_status_bar.xml      |  40 ++++++
 23 files changed, 789 insertions(+), 12 deletions(-)
 create mode 100644 indra/llui/llsearchablecontrol.h
 create mode 100644 indra/newview/llsearchableui.cpp
 create mode 100644 indra/newview/llsearchableui.h

diff --git a/doc/contributions.txt b/doc/contributions.txt
index bb910aa838..66323a38c6 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -1070,6 +1070,7 @@ Nicky Dasmijn
     STORM-2010
 	STORM-2082
 	MAINT-6665
+	SL-10293
 Nicky Perian
 	OPEN-1
 	STORM-1087
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index 8054eb3619..e44f57fa9f 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -200,6 +200,7 @@ set(llui_HEADER_FILES
     llresizehandle.h
     llresmgr.h
     llrngwriter.h
+    llsearchablecontrol.h
     llsearcheditor.h 
     llscrollbar.h
     llscrollcontainer.h
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 510a2537b9..6b7a8a8b86 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -769,6 +769,10 @@ void LLButton::draw()
 		}
 	}
 
+	// Highlight if needed
+	if( ll::ui::SearchableControl::getHighlighted() )
+		label_color = ll::ui::SearchableControl::getHighlightColor();
+
 	// Unselected label assignments
 	LLWString label = getCurrentLabel();
 
diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h
index 7b4719866d..7629ed1fea 100644
--- a/indra/llui/llbutton.h
+++ b/indra/llui/llbutton.h
@@ -62,6 +62,7 @@ class LLUICtrlFactory;
 
 class LLButton
 : public LLUICtrl, public LLBadgeOwner
+, public ll::ui::SearchableControl
 {
 public:
 	struct Params 
@@ -380,6 +381,12 @@ protected:
 	LLFlashTimer *				mFlashingTimer;
 	bool                        mForceFlashing; // Stick flashing color even if button is pressed
 	bool						mHandleRightMouse;
+
+protected:
+	virtual std::string _getSearchText() const
+	{
+		return getLabelUnselected() + getToolTip();
+	}
 };
 
 // Build time optimization, generate once in .cpp file
diff --git a/indra/llui/llcheckboxctrl.h b/indra/llui/llcheckboxctrl.h
index 71bdc32e66..07ae9c3b18 100644
--- a/indra/llui/llcheckboxctrl.h
+++ b/indra/llui/llcheckboxctrl.h
@@ -47,6 +47,7 @@ class LLViewBorder;
 
 class LLCheckBoxCtrl
 : public LLUICtrl
+, public ll::ui::SearchableControl
 {
 public:
 	struct Params 
@@ -108,6 +109,18 @@ public:
 	virtual BOOL		isDirty()	const;		// Returns TRUE if the user has modified this control.
 	virtual void		resetDirty();			// Clear dirty state
 
+protected:
+	virtual std::string _getSearchText() const
+	{
+		return getLabel() + getToolTip();
+	}
+
+	virtual void onSetHighlight() const // When highlight, really do highlight the label
+	{
+		if( mLabel )
+			mLabel->ll::ui::SearchableControl::setHighlighted( ll::ui::SearchableControl::getHighlighted() );
+	}
+
 protected:
 	// note: value is stored in toggle state of button
 	LLButton*		mButton;
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index 0d42f726fa..92543b952e 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -504,6 +504,10 @@ void LLMenuItemGL::draw( void )
 		color = mDisabledColor.get();
 	}
 
+	// Highlight if needed
+	if( ll::ui::SearchableControl::getHighlighted() )
+		color = ll::ui::SearchableControl::getHighlightColor();
+
 	// Draw the text on top.
 	if (mBriefItem)
 	{
diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h
index 69f7d21513..78f688642e 100644
--- a/indra/llui/llmenugl.h
+++ b/indra/llui/llmenugl.h
@@ -48,7 +48,7 @@ extern S32 MENU_BAR_WIDTH;
 // The LLMenuItemGL represents a single menu item in a menu. 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-class LLMenuItemGL : public LLUICtrl
+class LLMenuItemGL: public LLUICtrl, public ll::ui::SearchableControl
 {
 public:
 	struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
@@ -175,7 +175,12 @@ protected:
 	// This function appends the character string representation of
 	// the current accelerator key and mask to the provided string.
 	void appendAcceleratorString( std::string& st ) const;
-		
+
+	virtual std::string _getSearchText() const
+	{
+		return mLabel.getString();
+	}
+
 protected:
 	KEY mAcceleratorKey;
 	MASK mAcceleratorMask;
diff --git a/indra/llui/llsearchablecontrol.h b/indra/llui/llsearchablecontrol.h
new file mode 100644
index 0000000000..f7f1ffa0a5
--- /dev/null
+++ b/indra/llui/llsearchablecontrol.h
@@ -0,0 +1,71 @@
+/**
+* @file llsearchablecontrol.h
+*
+* $LicenseInfo:firstyear=2019&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2019, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+
+#ifndef LL_SEARCHABLE_CONTROL_H
+#define LL_SEARCHABLE_CONTROL_H
+
+#include "lluicolortable.h"
+#include "lluicolor.h"
+
+namespace ll
+{
+	namespace ui
+	{
+		class SearchableControl
+		{
+			mutable bool mIsHighlighed;
+		public:
+			SearchableControl()
+				: mIsHighlighed( false )
+			{ }
+			virtual ~SearchableControl()
+			{ }
+
+			LLColor4 getHighlightColor( ) const
+			{
+				static LLUIColor highlight_color = LLUIColorTable::instance().getColor("SearchableControlHighlightColor", LLColor4::red);
+				return highlight_color.get();
+			}
+
+			void setHighlighted( bool aVal ) const
+			{
+				mIsHighlighed = aVal;
+				onSetHighlight( );
+			}
+			bool getHighlighted( ) const
+			{ return mIsHighlighed; }
+
+			std::string getSearchText() const
+			{ return _getSearchText(); } 
+		protected:
+			virtual std::string _getSearchText() const = 0;
+			virtual void onSetHighlight( ) const
+			{ }
+		};
+	}
+}
+
+
+#endif
diff --git a/indra/llui/llsliderctrl.h b/indra/llui/llsliderctrl.h
index 67cca9ef04..2bb8668b90 100644
--- a/indra/llui/llsliderctrl.h
+++ b/indra/llui/llsliderctrl.h
@@ -35,7 +35,7 @@
 #include "lllineeditor.h"
 
 
-class LLSliderCtrl : public LLF32UICtrl
+class LLSliderCtrl: public LLF32UICtrl, public ll::ui::SearchableControl
 {
 public:
 	struct Params : public LLInitParam::Block<Params, LLF32UICtrl::Params>
@@ -131,6 +131,19 @@ public:
 	static void		onEditorGainFocus(LLFocusableElement* caller, void *userdata);
 	static void		onEditorChangeFocus(LLUICtrl* caller, S32 direction, void *userdata);
 
+protected:
+	virtual std::string _getSearchText() const
+	{
+		std::string strLabel;
+		if( mLabelBox )
+			strLabel = mLabelBox->getLabel();
+		return strLabel + getToolTip();
+	}
+	virtual void onSetHighlight() const  // When highlight, really do highlight the label
+	{
+		if( mLabelBox )
+			mLabelBox->ll::ui::SearchableControl::setHighlighted( ll::ui::SearchableControl::getHighlighted() );
+	}
 private:
 	void			updateText();
 	void			reportInvalidData();
diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index 1b2f09cff5..9c8636f936 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -76,7 +76,8 @@ public:
 		mButton(b),
 		mOldState(FALSE),
 		mPlaceholderText(placeholder),
-		mPadding(0)
+		mPadding(0),
+		mVisible(true)
 	{}
 
 	LLTabContainer*  mTabContainer;
@@ -85,6 +86,8 @@ public:
 	BOOL			 mOldState;
 	LLTextBox*		 mPlaceholderText;
 	S32				 mPadding;
+
+	mutable bool mVisible;
 };
 
 //----------------------------------------------------------------------------
@@ -398,7 +401,10 @@ void LLTabContainer::draw()
 				{
 					break;
 				}
-				target_pixel_scroll += (*iter)->mButton->getRect().getWidth();
+
+				if( (*iter)->mVisible )
+					target_pixel_scroll += (*iter)->mButton->getRect().getWidth();
+
 				cur_scroll_pos--;
 			}
 
@@ -467,6 +473,12 @@ void LLTabContainer::draw()
 		{
 			LLTabTuple* tuple = *iter;
 
+			if( !tuple->mVisible )
+			{
+				tuple->mButton->setVisible( false );
+				continue;
+			}
+
 			tuple->mButton->translate( left ? left - tuple->mButton->getRect().mLeft : 0,
 									   top ? top - tuple->mButton->getRect().mTop : 0 );
 			if (top) top -= BTN_HEIGHT + tabcntrv_pad;
@@ -1505,7 +1517,7 @@ BOOL LLTabContainer::setTab(S32 which)
 	}
 
 	BOOL is_visible = FALSE;
-	if (selected_tuple->mButton->getEnabled())
+	if( selected_tuple->mButton->getEnabled() && selected_tuple->mVisible )
 	{
 		setCurrentPanelIndex(which);
 
@@ -2121,3 +2133,35 @@ S32 LLTabContainer::getTotalTabWidth() const
 {
     return mTotalTabWidth;
 }
+
+void LLTabContainer::setTabVisibility( LLPanel const *aPanel, bool aVisible )
+{
+	for( tuple_list_t::const_iterator itr = mTabList.begin(); itr != mTabList.end(); ++itr )
+	{
+		LLTabTuple const *pTT = *itr;
+		if( pTT->mTabPanel == aPanel )
+		{
+			pTT->mVisible = aVisible;
+			break;
+		}
+	}
+
+	bool foundTab( false );
+	for( tuple_list_t::const_iterator itr = mTabList.begin(); itr != mTabList.end(); ++itr )
+	{
+		LLTabTuple const *pTT = *itr;
+		if( pTT->mVisible )
+		{
+			this->selectTab( itr - mTabList.begin() );
+			foundTab = true;
+			break;
+		}
+	}
+
+	if( foundTab )
+		this->setVisible( TRUE );
+	else
+		this->setVisible( FALSE );
+
+	updateMaxScrollPos();
+}
diff --git a/indra/llui/lltabcontainer.h b/indra/llui/lltabcontainer.h
index 4a5f08f5d3..6bf963313c 100644
--- a/indra/llui/lltabcontainer.h
+++ b/indra/llui/lltabcontainer.h
@@ -216,6 +216,8 @@ public:
 	S32			getMinTabWidth() const { return mMinTabWidth; }
 	S32			getMaxTabWidth() const { return mMaxTabWidth; }
 
+	void setTabVisibility( LLPanel const *aPanel, bool );
+
 	void		startDragAndDropDelayTimer() { mDragAndDropDelayTimer.start(); }
 	
 	void onTabBtn( const LLSD& data, LLPanel* panel );
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index c570285856..a23741b6dd 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -1222,6 +1222,17 @@ void LLTextBase::draw()
 		gl_rect_2d(text_rect, bg_color % alpha, TRUE);
 	}
 
+	// Draw highlighted if needed
+	if( ll::ui::SearchableControl::getHighlighted() )
+	{
+		LLColor4 bg_color = ll::ui::SearchableControl::getHighlightColor();
+		LLRect bg_rect = mVisibleTextRect;
+		if( mScroller )
+			bg_rect.intersectWith( text_rect );
+
+		gl_rect_2d( text_rect, bg_color, TRUE );
+	}
+	
 	bool should_clip = mClip || mScroller != NULL;
 	{ LLLocalClipRect clip(text_rect, should_clip);
  
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 5fdde445ef..9831c35858 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -275,7 +275,8 @@ typedef LLPointer<LLTextSegment> LLTextSegmentPtr;
 class LLTextBase 
 :	public LLUICtrl,
 	protected LLEditMenuHandler,
-	public LLSpellCheckMenuHandler
+	public LLSpellCheckMenuHandler,
+	public ll::ui::SearchableControl
 {
 public:
 	friend class LLTextSegment;
@@ -617,6 +618,11 @@ protected:
 	void							appendAndHighlightTextImpl(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params, bool underline_on_hover_only = false);
 	S32 normalizeUri(std::string& uri);
 	
+protected:
+	virtual std::string _getSearchText() const
+	{
+		return mLabel.getString() + getToolTip();
+	}
 
 protected:
 	// text segmentation and flow
diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h
index 550bee5c70..63baed6793 100644
--- a/indra/llui/lluictrl.h
+++ b/indra/llui/lluictrl.h
@@ -37,6 +37,7 @@
 #include "llinitparam.h"
 #include "llview.h"
 #include "llviewmodel.h"		// *TODO move dependency to .cpp file
+#include "llsearchablecontrol.h"
 
 const BOOL TAKE_FOCUS_YES = TRUE;
 const BOOL TAKE_FOCUS_NO  = FALSE;
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 33886acb71..a8019ee168 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -532,6 +532,7 @@ set(viewer_SOURCE_FILES
     llscrollingpanelparam.cpp
     llscrollingpanelparambase.cpp
     llsculptidsize.cpp
+    llsearchableui.cpp
     llsearchcombobox.cpp
     llsearchhistory.cpp
     llsecapi.cpp
@@ -1148,6 +1149,7 @@ set(viewer_HEADER_FILES
     llscrollingpanelparam.h
     llscrollingpanelparambase.h
     llsculptidsize.h
+    llsearchableui.h
     llsearchcombobox.h
     llsearchhistory.h
     llsecapi.h
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index ac751a785d..c3dea73c05 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -117,6 +117,8 @@
 #include "llfeaturemanager.h"
 #include "llviewertexturelist.h"
 
+#include "llsearchableui.h"
+
 const F32 BANDWIDTH_UPDATER_TIMEOUT = 0.5f;
 char const* const VISIBILITY_DEFAULT = "default";
 char const* const VISIBILITY_HIDDEN = "hidden";
@@ -393,6 +395,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
 
 	mCommitCallbackRegistrar.add("Pref.ClearLog",				boost::bind(&LLConversationLog::onClearLog, &LLConversationLog::instance()));
 	mCommitCallbackRegistrar.add("Pref.DeleteTranscripts",      boost::bind(&LLFloaterPreference::onDeleteTranscripts, this));
+	mCommitCallbackRegistrar.add("UpdateFilter", boost::bind(&LLFloaterPreference::onUpdateFilterTerm, this, false)); // <FS:ND/> Hook up for filtering
 }
 
 void LLFloaterPreference::processProperties( void* pData, EAvatarProcessorType type )
@@ -506,7 +509,10 @@ BOOL LLFloaterPreference::postBuild()
 	LLSliderCtrl* fov_slider = getChild<LLSliderCtrl>("camera_fov");
 	fov_slider->setMinValue(LLViewerCamera::getInstance()->getMinView());
 	fov_slider->setMaxValue(LLViewerCamera::getInstance()->getMaxView());
-
+	
+	// Hook up and init for filtering
+	mFilterEdit = getChild<LLSearchEditor>("search_prefs_edit");
+	mFilterEdit->setKeystrokeCallback(boost::bind(&LLFloaterPreference::onUpdateFilterTerm, this, false));
 
 	return TRUE;
 }
@@ -786,6 +792,13 @@ void LLFloaterPreference::onOpen(const LLSD& key)
 	save_btn->setEnabled(started);
 	delete_btn->setEnabled(started);
 	exceptions_btn->setEnabled(started);
+
+	collectSearchableItems();
+	if (!mFilterEdit->getText().empty())
+	{
+		mFilterEdit->setText(LLStringExplicit(""));
+		onUpdateFilterTerm(true);
+	}
 }
 
 void LLFloaterPreference::onVertexShaderEnable()
@@ -2985,3 +2998,109 @@ void LLFloaterPreferenceProxy::onChangeSocksSettings()
 
 }
 
+void LLFloaterPreference::onUpdateFilterTerm(bool force)
+{
+	LLWString seachValue = utf8str_to_wstring( mFilterEdit->getValue() );
+	LLWStringUtil::toLower( seachValue );
+
+	if( !mSearchData || (mSearchData->mLastFilter == seachValue && !force))
+		return;
+
+	mSearchData->mLastFilter = seachValue;
+
+	if( !mSearchData->mRootTab )
+		return;
+
+	mSearchData->mRootTab->hightlightAndHide( seachValue );
+	LLTabContainer *pRoot = getChild< LLTabContainer >( "pref core" );
+	if( pRoot )
+		pRoot->selectFirstTab();
+}
+
+void collectChildren( LLView const *aView, ll::prefs::PanelDataPtr aParentPanel, ll::prefs::TabContainerDataPtr aParentTabContainer )
+{
+	if( !aView )
+		return;
+
+	llassert_always( aParentPanel || aParentTabContainer );
+
+	LLView::child_list_const_iter_t itr = aView->beginChild();
+	LLView::child_list_const_iter_t itrEnd = aView->endChild();
+
+	while( itr != itrEnd )
+	{
+		LLView *pView = *itr;
+		ll::prefs::PanelDataPtr pCurPanelData = aParentPanel;
+		ll::prefs::TabContainerDataPtr pCurTabContainer = aParentTabContainer;
+		if( !pView )
+			continue;
+		LLPanel const *pPanel = dynamic_cast< LLPanel const *>( pView );
+		LLTabContainer const *pTabContainer = dynamic_cast< LLTabContainer const *>( pView );
+		ll::ui::SearchableControl const *pSCtrl = dynamic_cast< ll::ui::SearchableControl const *>( pView );
+
+		if( pTabContainer )
+		{
+			pCurPanelData.reset();
+
+			pCurTabContainer = ll::prefs::TabContainerDataPtr( new ll::prefs::TabContainerData );
+			pCurTabContainer->mTabContainer = const_cast< LLTabContainer *>( pTabContainer );
+			pCurTabContainer->mLabel = pTabContainer->getLabel();
+			pCurTabContainer->mPanel = 0;
+
+			if( aParentPanel )
+				aParentPanel->mChildPanel.push_back( pCurTabContainer );
+			if( aParentTabContainer )
+				aParentTabContainer->mChildPanel.push_back( pCurTabContainer );
+		}
+		else if( pPanel )
+		{
+			pCurTabContainer.reset();
+
+			pCurPanelData = ll::prefs::PanelDataPtr( new ll::prefs::PanelData );
+			pCurPanelData->mPanel = pPanel;
+			pCurPanelData->mLabel = pPanel->getLabel();
+
+			llassert_always( aParentPanel || aParentTabContainer );
+
+			if( aParentTabContainer )
+				aParentTabContainer->mChildPanel.push_back( pCurPanelData );
+			else if( aParentPanel )
+				aParentPanel->mChildPanel.push_back( pCurPanelData );
+		}
+		else if( pSCtrl && pSCtrl->getSearchText().size() )
+		{
+			ll::prefs::SearchableItemPtr item = ll::prefs::SearchableItemPtr( new ll::prefs::SearchableItem() );
+			item->mView = pView;
+			item->mCtrl = pSCtrl;
+
+			item->mLabel = utf8str_to_wstring( pSCtrl->getSearchText() );
+			LLWStringUtil::toLower( item->mLabel );
+
+			llassert_always( aParentPanel || aParentTabContainer );
+
+			if( aParentPanel )
+				aParentPanel->mChildren.push_back( item );
+			if( aParentTabContainer )
+				aParentTabContainer->mChildren.push_back( item );
+		}
+		collectChildren( pView, pCurPanelData, pCurTabContainer );
+		++itr;
+	}
+}
+
+void LLFloaterPreference::collectSearchableItems()
+{
+	mSearchData.reset( nullptr );
+	LLTabContainer *pRoot = getChild< LLTabContainer >( "pref core" );
+	if( mFilterEdit && pRoot )
+	{
+		mSearchData.reset(new ll::prefs::SearchData() );
+
+		ll::prefs::TabContainerDataPtr pRootTabcontainer = ll::prefs::TabContainerDataPtr( new ll::prefs::TabContainerData );
+		pRootTabcontainer->mTabContainer = pRoot;
+		pRootTabcontainer->mLabel = pRoot->getLabel();
+		mSearchData->mRootTab = pRootTabcontainer;
+
+		collectChildren( this, ll::prefs::PanelDataPtr(), pRootTabcontainer );
+	}
+}
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 4e51137df5..d609c42ebe 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -36,6 +36,7 @@
 #include "llfloater.h"
 #include "llavatarpropertiesprocessor.h"
 #include "llconversationlog.h"
+#include "llsearcheditor.h"
 
 class LLConversationLogObserver;
 class LLPanelPreference;
@@ -47,6 +48,14 @@ class LLSliderCtrl;
 class LLSD;
 class LLTextBox;
 
+namespace ll
+{
+	namespace prefs
+	{
+		struct SearchData;
+	}
+}
+
 typedef std::map<std::string, std::string> notifications_map;
 
 typedef enum
@@ -205,6 +214,12 @@ private:
 	LLAvatarData mAvatarProperties;
 	std::string mSavedGraphicsPreset;
 	LOG_CLASS(LLFloaterPreference);
+
+	LLSearchEditor *mFilterEdit;
+	std::unique_ptr< ll::prefs::SearchData > mSearchData;
+
+	void onUpdateFilterTerm( bool force = false );
+	void collectSearchableItems();
 };
 
 class LLPanelPreference : public LLPanel
diff --git a/indra/newview/llsearchableui.cpp b/indra/newview/llsearchableui.cpp
new file mode 100644
index 0000000000..6058079ae4
--- /dev/null
+++ b/indra/newview/llsearchableui.cpp
@@ -0,0 +1,154 @@
+/**
+* @file llsearchableui.cpp
+*
+* $LicenseInfo:firstyear=2019&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2019, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+
+#include "llviewerprecompiledheaders.h"
+#include "llsearchableui.h"
+
+#include "llview.h"
+#include "lltabcontainer.h"
+#include "llmenugl.h"
+
+ll::prefs::SearchableItem::~SearchableItem()
+{}
+
+void ll::prefs::SearchableItem::setNotHighlighted()
+{
+	mCtrl->setHighlighted( false );
+}
+
+bool ll::prefs::SearchableItem::hightlightAndHide( LLWString const &aFilter )
+{
+	if( mCtrl->getHighlighted() )
+		return true;
+
+	LLView const *pView = dynamic_cast< LLView const* >( mCtrl );
+	if( pView && !pView->getVisible() )
+		return false;
+
+	if( aFilter.empty() )
+	{
+		mCtrl->setHighlighted( false );
+		return true;
+	}
+
+	if( mLabel.find( aFilter ) != LLWString::npos )
+	{
+		mCtrl->setHighlighted( true );
+		return true;
+	}
+
+	return false;
+}
+
+ll::prefs::PanelData::~PanelData()
+{}
+
+bool ll::prefs::PanelData::hightlightAndHide( LLWString const &aFilter )
+{
+	for( tSearchableItemList::iterator itr = mChildren.begin(); itr  != mChildren.end(); ++itr )
+		(*itr)->setNotHighlighted( );
+
+	bool bVisible(false);
+	for( tSearchableItemList::iterator itr = mChildren.begin(); itr  != mChildren.end(); ++itr )
+		bVisible |= (*itr)->hightlightAndHide( aFilter );
+
+	for( tPanelDataList::iterator itr = mChildPanel.begin(); itr  != mChildPanel.end(); ++itr )
+		bVisible |= (*itr)->hightlightAndHide( aFilter );
+
+	return bVisible;
+}
+
+bool ll::prefs::TabContainerData::hightlightAndHide( LLWString const &aFilter )
+{
+	for( tSearchableItemList::iterator itr = mChildren.begin(); itr  != mChildren.end(); ++itr )
+		(*itr)->setNotHighlighted( );
+
+	bool bVisible(false);
+	for( tSearchableItemList::iterator itr = mChildren.begin(); itr  != mChildren.end(); ++itr )
+		bVisible |= (*itr)->hightlightAndHide( aFilter );
+
+	for( tPanelDataList::iterator itr = mChildPanel.begin(); itr  != mChildPanel.end(); ++itr )
+	{
+		bool bPanelVisible = (*itr)->hightlightAndHide( aFilter );
+		if( (*itr)->mPanel )
+			mTabContainer->setTabVisibility( (*itr)->mPanel, bPanelVisible );
+		bVisible |= bPanelVisible;
+	}
+
+	return bVisible;
+}
+
+ll::statusbar::SearchableItem::SearchableItem()
+	: mMenu(0)
+	, mCtrl(0)
+	, mWasHiddenBySearch( false )
+{ }
+
+void ll::statusbar::SearchableItem::setNotHighlighted( )
+{
+	for( tSearchableItemList::iterator itr = mChildren.begin(); itr  != mChildren.end(); ++itr )
+		(*itr)->setNotHighlighted( );
+
+	if( mCtrl )
+	{
+		mCtrl->setHighlighted( false );
+
+		if( mWasHiddenBySearch )
+			mMenu->setVisible( TRUE );
+	}
+}
+
+bool ll::statusbar::SearchableItem::hightlightAndHide( LLWString const &aFilter )
+{
+	if( mMenu && !mMenu->getVisible() && !mWasHiddenBySearch )
+		return false;
+
+	setNotHighlighted( );
+
+	bool bVisible(false);
+	for( tSearchableItemList::iterator itr = mChildren.begin(); itr  != mChildren.end(); ++itr )
+		bVisible |= (*itr)->hightlightAndHide( aFilter );
+
+	if( aFilter.empty() )
+	{
+		if( mCtrl )
+			mCtrl->setHighlighted( false );
+		return true;
+	}
+
+	if( mLabel.find( aFilter ) != LLWString::npos )
+	{
+		if( mCtrl )
+			mCtrl->setHighlighted( true );
+		return true;
+	}
+
+	if( mCtrl && !bVisible )
+	{
+		mWasHiddenBySearch = true;
+		mMenu->setVisible(FALSE);
+	}
+	return bVisible;
+}
diff --git a/indra/newview/llsearchableui.h b/indra/newview/llsearchableui.h
new file mode 100644
index 0000000000..42b2866fb6
--- /dev/null
+++ b/indra/newview/llsearchableui.h
@@ -0,0 +1,121 @@
+/**
+* @file llsearchableui.h
+*
+* $LicenseInfo:firstyear=2019&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2019, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+
+#ifndef LL_SEARCHABLE_UI_H
+#define LL_SEARCHABLE_UI_H
+
+class LLMenuItemGL;
+class LLView;
+class LLPanel;
+class LLTabContainer;
+
+#include "llsearchablecontrol.h"
+
+namespace ll
+{
+	namespace prefs
+	{
+		struct SearchableItem;
+		struct PanelData;
+		struct TabContainerData;
+
+		typedef boost::shared_ptr< SearchableItem > SearchableItemPtr;
+		typedef boost::shared_ptr< PanelData > PanelDataPtr;
+		typedef boost::shared_ptr< TabContainerData > TabContainerDataPtr;
+
+		typedef std::vector< TabContainerData > tTabContainerDataList;
+		typedef std::vector< SearchableItemPtr > tSearchableItemList;
+		typedef std::vector< PanelDataPtr > tPanelDataList;
+
+		struct SearchableItem
+		{
+			LLWString mLabel;
+			LLView const *mView;
+			ll::ui::SearchableControl const *mCtrl;
+
+			std::vector< boost::shared_ptr< SearchableItem >  > mChildren;
+
+			virtual ~SearchableItem();
+
+			void setNotHighlighted();
+			virtual bool hightlightAndHide( LLWString const &aFilter );
+		};
+
+		struct PanelData
+		{
+			LLPanel const *mPanel;
+			std::string mLabel;
+
+			std::vector< boost::shared_ptr< SearchableItem > > mChildren;
+			std::vector< boost::shared_ptr< PanelData > > mChildPanel;
+
+			virtual ~PanelData();
+
+			virtual bool hightlightAndHide( LLWString const &aFilter );
+		};
+
+		struct TabContainerData: public PanelData
+		{
+			LLTabContainer *mTabContainer;
+			virtual bool hightlightAndHide( LLWString const &aFilter );
+		};
+
+		struct SearchData
+		{
+			TabContainerDataPtr mRootTab;
+			LLWString mLastFilter;
+		};
+	}
+	namespace statusbar
+	{
+		struct SearchableItem;
+
+		typedef boost::shared_ptr< SearchableItem > SearchableItemPtr;
+
+		typedef std::vector< SearchableItemPtr > tSearchableItemList;
+
+		struct SearchableItem
+		{
+			LLWString mLabel;
+			LLMenuItemGL *mMenu;
+			tSearchableItemList mChildren;
+			ll::ui::SearchableControl const *mCtrl;
+			bool mWasHiddenBySearch;
+
+			SearchableItem();
+
+			void setNotHighlighted( );
+			bool hightlightAndHide( LLWString const &aFilter );
+		};
+
+		struct SearchData
+		{
+			SearchableItemPtr mRootMenu;
+			LLWString mLastFilter;
+		};
+	}
+}
+
+#endif
diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp
index 43c0fbd53a..b893e4a058 100644
--- a/indra/newview/llstatusbar.cpp
+++ b/indra/newview/llstatusbar.cpp
@@ -81,6 +81,8 @@
 #include "llparcel.h"
 #include "llstring.h"
 #include "message.h"
+#include "llsearchableui.h"
+#include "llsearcheditor.h"
 
 // system includes
 #include <iomanip>
@@ -113,7 +115,9 @@ LLStatusBar::LLStatusBar(const LLRect& rect)
 	mBalance(0),
 	mHealth(100),
 	mSquareMetersCredit(0),
-	mSquareMetersCommitted(0)
+	mSquareMetersCommitted(0),
+	mFilterEdit(NULL),			// Edit for filtering
+	mSearchPanel(NULL)			// Panel for filtering
 {
 	setRect(rect);
 	
@@ -239,6 +243,16 @@ BOOL LLStatusBar::postBuild()
 	mPanelNearByMedia->setFollows(FOLLOWS_TOP|FOLLOWS_RIGHT);
 	mPanelNearByMedia->setVisible(FALSE);
 
+	// Hook up and init for filtering
+	mFilterEdit = getChild<LLSearchEditor>( "search_menu_edit" );
+	mSearchPanel = getChild<LLPanel>( "menu_search_panel" );
+
+	//mSearchPanel->setVisible(gSavedSettings.getBOOL("MenuSearch"));
+	mFilterEdit->setKeystrokeCallback(boost::bind(&LLStatusBar::onUpdateFilterTerm, this));
+	mFilterEdit->setCommitCallback(boost::bind(&LLStatusBar::onUpdateFilterTerm, this));
+	collectSearchableItems();
+	//gSavedSettings.getControl("MenuSearch")->getCommitSignal()->connect(boost::bind(&LLStatusBar::updateMenuSearchVisibility, this, _2));
+
 	return TRUE;
 }
 
@@ -318,6 +332,7 @@ void LLStatusBar::setVisibleForMouselook(bool visible)
 	mMediaToggle->setVisible(visible);
 	mSGBandwidth->setVisible(visible);
 	mSGPacketLoss->setVisible(visible);
+	mSearchPanel->setVisible(visible && gSavedSettings.getBOOL("MenuSearch"));
 	setBackgroundVisible(visible);
 	mIconPresets->setVisible(visible);
 }
@@ -358,6 +373,12 @@ void LLStatusBar::setBalance(S32 balance)
 		balance_bg_view->setShape(balance_bg_rect);
 	}
 
+	// If the search panel is shown, move this according to the new balance width. Parcel text will reshape itself in setParcelInfoText
+	if (mSearchPanel && mSearchPanel->getVisible())
+	{
+		updateMenuSearchPosition();
+	}
+
 	if (mBalance && (fabs((F32)(mBalance - balance)) > gSavedSettings.getF32("UISndMoneyChangeThreshold")))
 	{
 		if (mBalance > balance)
@@ -570,6 +591,75 @@ void LLStatusBar::onVolumeChanged(const LLSD& newvalue)
 	refresh();
 }
 
+void LLStatusBar::onUpdateFilterTerm()
+{
+	LLWString searchValue = utf8str_to_wstring( mFilterEdit->getValue() );
+	LLWStringUtil::toLower( searchValue );
+
+	if( !mSearchData || mSearchData->mLastFilter == searchValue )
+		return;
+
+	mSearchData->mLastFilter = searchValue;
+
+	mSearchData->mRootMenu->hightlightAndHide( searchValue );
+	gMenuBarView->needsArrange();
+}
+
+void collectChildren( LLMenuGL *aMenu, ll::statusbar::SearchableItemPtr aParentMenu )
+{
+	for( U32 i = 0; i < aMenu->getItemCount(); ++i )
+	{
+		LLMenuItemGL *pMenu = aMenu->getItem( i );
+
+		ll::statusbar::SearchableItemPtr pItem( new ll::statusbar::SearchableItem );
+		pItem->mCtrl = pMenu;
+		pItem->mMenu = pMenu;
+		pItem->mLabel = utf8str_to_wstring( pMenu->ll::ui::SearchableControl::getSearchText() );
+		LLWStringUtil::toLower( pItem->mLabel );
+		aParentMenu->mChildren.push_back( pItem );
+
+		LLMenuItemBranchGL *pBranch = dynamic_cast< LLMenuItemBranchGL* >( pMenu );
+		if( pBranch )
+			collectChildren( pBranch->getBranch(), pItem );
+	}
+
+}
+
+void LLStatusBar::collectSearchableItems()
+{
+	mSearchData.reset( new ll::statusbar::SearchData );
+	ll::statusbar::SearchableItemPtr pItem( new ll::statusbar::SearchableItem );
+	mSearchData->mRootMenu = pItem;
+	collectChildren( gMenuBarView, pItem );
+}
+
+void LLStatusBar::updateMenuSearchVisibility(const LLSD& data)
+{
+	bool visible = data.asBoolean();
+	mSearchPanel->setVisible(visible);
+	if (!visible)
+	{
+		mFilterEdit->setText(LLStringUtil::null);
+		onUpdateFilterTerm();
+	}
+	else
+	{
+		updateMenuSearchPosition();
+	}
+}
+
+void LLStatusBar::updateMenuSearchPosition()
+{
+	const S32 HPAD = 12;
+	LLRect balanceRect = getChildView("balance_bg")->getRect();
+	LLRect searchRect = mSearchPanel->getRect();
+	S32 w = searchRect.getWidth();
+	searchRect.mLeft = balanceRect.mLeft - w - HPAD;
+	searchRect.mRight = searchRect.mLeft + w;
+	mSearchPanel->setShape( searchRect );
+}
+
+
 // Implements secondlife:///app/balance/request to request a L$ balance
 // update via UDP message system. JC
 class LLBalanceHandler : public LLCommandHandler
diff --git a/indra/newview/llstatusbar.h b/indra/newview/llstatusbar.h
index a3326e752a..403d590aca 100644
--- a/indra/newview/llstatusbar.h
+++ b/indra/newview/llstatusbar.h
@@ -45,7 +45,15 @@ class LLPanelPresetsPulldown;
 class LLPanelVolumePulldown;
 class LLPanelNearByMedia;
 class LLIconCtrl;
+class LLSearchEditor;
 
+namespace ll
+{
+	namespace statusbar
+	{
+		struct SearchData;
+	}
+}
 class LLStatusBar
 :	public LLPanel
 {
@@ -99,6 +107,15 @@ private:
 	static void onClickMediaToggle(void* data);
 	static void onClickBalance(void* data);
 
+	LLSearchEditor *mFilterEdit;
+	LLPanel *mSearchPanel;
+	void onUpdateFilterTerm();
+
+	std::unique_ptr< ll::statusbar::SearchData > mSearchData;
+	void collectSearchableItems();
+	void updateMenuSearchVisibility( const LLSD& data );
+	void updateMenuSearchPosition();
+
 private:
 	LLTextBox	*mTextTime;
 
diff --git a/indra/newview/skins/default/xui/en/floater_preferences.xml b/indra/newview/skins/default/xui/en/floater_preferences.xml
index 845c1efe4d..0e62d50072 100644
--- a/indra/newview/skins/default/xui/en/floater_preferences.xml
+++ b/indra/newview/skins/default/xui/en/floater_preferences.xml
@@ -3,7 +3,7 @@
  legacy_header_height="18"
  positioning="centered"
  default_tab_group="1"
- height="512"
+ height="530"
  layout="topleft"
  name="Preferences"
  help_topic="preferences"
@@ -25,7 +25,7 @@ https://accounts.secondlife.com/change_email/
      layout="topleft"
      right="-105"
      name="OK"
-     top="473"
+     top="492"
      width="90">
         <button.commit_callback
          function="Pref.OK" />
@@ -43,6 +43,42 @@ https://accounts.secondlife.com/change_email/
         <button.commit_callback
          function="Pref.Cancel" />
     </button>
+
+    <panel
+     name="search_panel"
+     layout="topleft"
+     follows="left|top|right"
+     left="4"
+     right="-4"
+     top="21"
+     height="18"
+     tab_group="2">
+        <search_editor
+         clear_button_visible="true"
+         follows="left|top|right"
+         height="18"
+         label="Search Settings"
+         layout="topleft"
+         left="0"
+         max_length_bytes="255"
+         name="search_prefs_edit"
+         right="-1"
+         text_pad_left="6"
+         tool_tip="Type the search term you are interested in here. Results will be displayed for partial fulltext matches within the setting's name or comment."
+         top="0">
+         <search_editor.commit_callback
+          function="UpdateFilter" />
+         <search_editor.clear_button
+          rect.height="18"
+          rect.width="18"
+          rect.bottom="-1" />
+         <search_editor.search_button
+          rect.height="12"
+          rect.width="12"
+          rect.bottom="-1" />
+        </search_editor>
+    </panel>
+
     <tab_container
      follows="all"
      halign="left"
@@ -54,7 +90,7 @@ https://accounts.secondlife.com/change_email/
      tab_position="left"
      tab_width="140"
      tab_padding_right="0"
-     top="21"
+     top="40"
      width="658">
         <panel
 	 class="panel_preference"
diff --git a/indra/newview/skins/default/xui/en/panel_status_bar.xml b/indra/newview/skins/default/xui/en/panel_status_bar.xml
index 998f1ce599..52bcce01f7 100644
--- a/indra/newview/skins/default/xui/en/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml
@@ -33,6 +33,46 @@
      name="buycurrencylabel">
         L$ [AMT]
     </panel.string>
+  <panel
+	 height="18"
+	 left="-458"
+	 top="0"
+	 width="120"
+	 follows="right|top"
+	 name="menu_search_panel"
+	 background_opaque="true"
+	 background_visible="true"
+	 bg_opaque_color="MouseGray">
+		<search_editor
+		 clear_button_visible="true"
+		 follows="left|top"
+		 height="18"
+		 label="Search Menus"
+		 layout="topleft"
+		 left="0"
+		 max_length_bytes="255"
+		 name="search_menu_edit"
+		 right="-1"
+		 text_pad_left="6"
+		 tool_tip="Type the search term you are interested in here. Results will be displayed for partial fulltext matches within the menu."
+		 top="0">
+			<search_button 
+			 top_pad="4"
+			 left_pad="4" 
+			 width="12"
+			 height="12" 
+			 image_unselected="Search"
+			 image_selected="Search"/>
+			<clear_button
+			 bottom="2"
+			 height="12"
+			 image_unselected="Icon_Close_Foreground"
+			 image_selected="Icon_Close_Press"
+			 pad_right="4"
+			 pad_left="4"
+			 width="12"/>
+		</search_editor>
+  </panel>
   <panel
     height="18"
     left="-416"
-- 
cgit v1.2.3


From 2461a7fe396fe95a043ed1cfc3b0c251d242a2c3 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Tue, 8 Jan 2019 14:15:44 +0200
Subject: SL-10320 FIXED Crash in LLVOAvatar::updateAttachmentOverrides()

---
 indra/newview/llvoavatar.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 321f774210..2682c5b698 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -5992,7 +5992,7 @@ void LLVOAvatar::rebuildAttachmentOverrides()
                 LLViewerObject *vo = *at_it;
                 // Attached animated objects affect joints in their control
                 // avs, not the avs to which they are attached.
-                if (!vo->isAnimatedObject())
+                if (vo && !vo->isAnimatedObject())
                 {
                     addAttachmentOverridesForObject(vo);
                 }
@@ -6043,7 +6043,7 @@ void LLVOAvatar::updateAttachmentOverrides()
                 LLViewerObject *vo = *at_it;
                 // Attached animated objects affect joints in their control
                 // avs, not the avs to which they are attached.
-                if (!vo->isAnimatedObject())
+                if (vo && !vo->isAnimatedObject())
                 {
                     addAttachmentOverridesForObject(vo, &meshes_seen);
                 }
-- 
cgit v1.2.3


From 4316f1d322bc8e0439780d68442d76b17927247c Mon Sep 17 00:00:00 2001
From: "Brad Payne (Vir Linden)" <vir@lindenlab.com>
Date: Tue, 8 Jan 2019 21:28:47 +0000
Subject: SL-10285 - removed one possible route for the isImpostor() crash.
 Intermittent issue.

---
 indra/newview/llcontrolavatar.cpp | 2 ++
 indra/newview/llviewerobject.cpp  | 1 +
 2 files changed, 3 insertions(+)

diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp
index d3fd5813a0..0f02c23cb0 100644
--- a/indra/newview/llcontrolavatar.cpp
+++ b/indra/newview/llcontrolavatar.cpp
@@ -60,6 +60,8 @@ LLControlAvatar::LLControlAvatar(const LLUUID& id, const LLPCode pcode, LLViewer
 // virtual
 LLControlAvatar::~LLControlAvatar()
 {
+	// Should already have been unlinked before destruction
+	llassert(!mRootVolp);
 }
 
 // virtual
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 007adf2a72..ec1095813b 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -3100,6 +3100,7 @@ void LLViewerObject::unlinkControlAvatar()
         if (mControlAvatar)
         {
             mControlAvatar->markForDeath();
+			mControlAvatar->mRootVolp = NULL;
             mControlAvatar = NULL;
         }
     }
-- 
cgit v1.2.3


From cd859cd9e8a032d2d708788893654e5ceaadac09 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Wed, 9 Jan 2019 10:57:15 +0200
Subject: SL-10321 FIXED 'Uploads' tab is not displayed after any search in
 Preferences

---
 indra/newview/llsearchableui.cpp | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/indra/newview/llsearchableui.cpp b/indra/newview/llsearchableui.cpp
index 6058079ae4..de90896548 100644
--- a/indra/newview/llsearchableui.cpp
+++ b/indra/newview/llsearchableui.cpp
@@ -70,6 +70,11 @@ bool ll::prefs::PanelData::hightlightAndHide( LLWString const &aFilter )
 	for( tSearchableItemList::iterator itr = mChildren.begin(); itr  != mChildren.end(); ++itr )
 		(*itr)->setNotHighlighted( );
 
+	if (aFilter.empty())
+	{
+		return true;
+	}
+
 	bool bVisible(false);
 	for( tSearchableItemList::iterator itr = mChildren.begin(); itr  != mChildren.end(); ++itr )
 		bVisible |= (*itr)->hightlightAndHide( aFilter );
-- 
cgit v1.2.3


From 1349eacc5cddb8d8522b4250cd3e7e54de55de2d Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Wed, 9 Jan 2019 17:21:13 +0200
Subject: SL-10325 FIXED Preferences tabs are displayed incorrectly if hovering
 it while searching any keyword

---
 indra/llui/lltabcontainer.cpp | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index 9c8636f936..6521b883f8 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -736,11 +736,11 @@ BOOL LLTabContainer::handleToolTip( S32 x, S32 y, MASK mask)
 		{
 			for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
 			{
-				LLTabTuple* tuple = *iter;
-				tuple->mButton->setVisible( TRUE );
-				S32 local_x = x - tuple->mButton->getRect().mLeft;
-				S32 local_y = y - tuple->mButton->getRect().mBottom;
-				handled = tuple->mButton->handleToolTip( local_x, local_y, mask);
+				LLButton* tab_button = (*iter)->mButton;
+				if (!tab_button->getVisible()) continue;
+				S32 local_x = x - tab_button->getRect().mLeft;
+				S32 local_y = y - tab_button->getRect().mBottom;
+				handled = tab_button->handleToolTip(local_x, local_y, mask);
 				if( handled )
 				{
 					break;
-- 
cgit v1.2.3


From fdf39d3cf4ece8e587dcc865b1c6d5ab12e66948 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Thu, 10 Jan 2019 15:41:48 +0200
Subject: SL-10329 Increase panel height to avoid message overlapping

---
 indra/newview/skins/default/xui/en/floater_model_preview.xml | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml
index e073268b0a..a07fe99aef 100644
--- a/indra/newview/skins/default/xui/en/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml
@@ -34,7 +34,6 @@
   <string name="mesh_status_invalid_material_list">LOD materials are not a subset of reference model.</string>
   <string name="phys_status_vertex_limit_exceeded">Some physical hulls exceed vertex limitations.</string>
   <string name="phys_status_degenerate_triangles">The physics mesh too dense remove the small thin triangles (see preview)</string>
-  <string name="phys_status_no_havok">The Firestorm OpenSim build is not supported for physics upload in SL.</string>
   <string name="layer_all">All</string> <!-- Text to display in physics layer combo box for "all layers" -->
   <string name="decomposing">Analyzing...</string>
   <string name="simplifying">Simplifying...</string>
@@ -1223,7 +1222,7 @@
     <panel
      follows="top|left|bottom"
      layout="topleft"
-     height="184"
+     height="197"
      left="4"
      border="true"
      name="weights_and_warning_panel"
@@ -1412,7 +1411,7 @@ Lowest:
         border="true"
         layout="topleft"
         left_pad="265"
-        name="price_breakdown_panel"
+        name="physics_costs_panel"
         width="120"
         height="100">
         <text
@@ -1480,7 +1479,7 @@ Analysed:
          visible="false">
          You dont have rights to upload mesh models. [[VURL] Find out how] to get certified.
        </text>
-       <text text_color="Yellow" layout="topleft" top_delta="5" left="6" name="status">
+       <text text_color="Yellow" layout="topleft" top_pad="-1" left="6" name="status">
 [STATUS]
        </text>
     </panel>
-- 
cgit v1.2.3


From 02aa64e195c25087e9cf7c7f32a851d8b84d2798 Mon Sep 17 00:00:00 2001
From: eli <eli@lindenlab.com>
Date: Thu, 10 Jan 2019 16:46:49 -0800
Subject: FIX INTL-324 Viewer Set55 translation (viewer-neko)

---
 .../newview/skins/default/xui/de/notifications.xml | 36 ++++++++++++----------
 indra/newview/skins/default/xui/de/strings.xml     | 21 +++++++++++++
 .../newview/skins/default/xui/es/notifications.xml | 35 ++++++++++++---------
 indra/newview/skins/default/xui/es/strings.xml     | 21 +++++++++++++
 .../newview/skins/default/xui/fr/notifications.xml | 36 ++++++++++++----------
 indra/newview/skins/default/xui/fr/strings.xml     | 21 +++++++++++++
 .../newview/skins/default/xui/it/notifications.xml | 34 +++++++++++---------
 indra/newview/skins/default/xui/it/strings.xml     | 21 +++++++++++++
 .../newview/skins/default/xui/ja/notifications.xml | 34 +++++++++++---------
 indra/newview/skins/default/xui/ja/strings.xml     | 21 +++++++++++++
 .../newview/skins/default/xui/pt/notifications.xml | 36 ++++++++++++----------
 indra/newview/skins/default/xui/pt/strings.xml     | 21 +++++++++++++
 .../newview/skins/default/xui/ru/notifications.xml | 36 ++++++++++++----------
 indra/newview/skins/default/xui/ru/strings.xml     | 21 +++++++++++++
 .../newview/skins/default/xui/tr/notifications.xml | 36 ++++++++++++----------
 indra/newview/skins/default/xui/tr/strings.xml     | 21 +++++++++++++
 .../newview/skins/default/xui/zh/notifications.xml | 32 ++++++++++---------
 indra/newview/skins/default/xui/zh/strings.xml     | 21 +++++++++++++
 18 files changed, 366 insertions(+), 138 deletions(-)

diff --git a/indra/newview/skins/default/xui/de/notifications.xml b/indra/newview/skins/default/xui/de/notifications.xml
index 43af1d8655..57dbaa0ea6 100644
--- a/indra/newview/skins/default/xui/de/notifications.xml
+++ b/indra/newview/skins/default/xui/de/notifications.xml
@@ -244,6 +244,10 @@ Wählen Sie ein einzelnes Objekt aus und versuchen Sie es erneut.
 		Hinweis: Bei Aktivierung dieser Option sehen alle Personen, die diesen Computer benutzen, Ihre Lieblingsorte.
 		<usetemplate name="okbutton" yestext="OK"/>
 	</notification>
+	<notification name="AllowMultipleViewers">
+		Das Starten mehrerer Second Life Viewer wird nicht unterstützt. Dies kann zu Kollisionen des Textur-Caches, Fehlern sowie verschlechterter Grafik und Leistung führen.
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
 	<notification name="GrantModifyRights">
 		Wenn Sie einem anderen Einwohner Änderungsrechte gewähren, dann kann dieser JEDES Objekt, das Sie inworld besitzen, ändern, löschen oder an sich nehmen. Seien Sie daher beim Gewähren dieser Rechte sehr vorsichtig!
 Möchten Sie [NAME] Änderungsrechte gewähren?
@@ -725,9 +729,9 @@ Sie können die Grafikqualität unter Einstellungen &gt; Grafik wieder erhöhen.
 		Sie sind nicht zum Terraformen der Parzelle „[PARCEL]“ berechtigt.
 	</notification>
 	<notification name="CannotCopyWarning">
-		Sie sind nicht berechtigt, die folgenden Objekte zu kopieren:
-[ITEMS]
-Wenn Sie diese weitergeben, werden sie aus Ihrem Inventar entfernt. Möchten Sie diese Objekte wirklich weggeben?
+		Sie sind nicht berechtigt, die folgenden Objekte zu kopieren: 
+&lt;nolink&gt;[ITEMS]&lt;/nolink&gt;
+und die Objekte werden aus Ihrem Inventar gelöscht, wenn Sie diese weggeben. Möchten Sie diese Objekte wirklich weggeben?
 		<usetemplate name="okcancelbuttons" notext="Nein" yestext="Ja"/>
 	</notification>
 	<notification name="CannotGiveItem">
@@ -3730,13 +3734,13 @@ es sich nicht in der gleichen Region befindet wie Sie.
 		Auf Land, das Sie nicht besitzen, können Sie keine Bäume und Gräser erstellen.
 	</notification>
 	<notification name="NoCopyPermsNoObject">
-		Kopieren fehlgeschlagen, da Sie keine Berechtigung zum Kopieren des Objekts „OBJ_NAME]“ besitzen.
+		Kopieren fehlgeschlagen, da Sie nicht über die Berechtigung zum Kopieren des Objekts &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; verfügen.
 	</notification>
 	<notification name="NoTransPermsNoObject">
-		Kopieren fehlgeschlagen, weil Objekt „[OBJ_NAME]“ nicht an Sie übertragen werden kann.
+		Kopieren fehlgeschlagen, da das Objekt &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; nicht an Sie übertragen werden kann.
 	</notification>
 	<notification name="AddToNavMeshNoCopy">
-		Kopieren fehlgeschlagen, weil Objekt „[OBJ_NAME]“ zum Navmesh beiträgt.
+		Kopieren fehlgeschlagen, da das Objekt &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; zum Navmesh beiträgt.
 	</notification>
 	<notification name="DupeWithNoRootsSelected">
 		Ohne ausgewählte Hauptobjekte duplizieren.
@@ -3781,34 +3785,34 @@ Warten Sie kurz und versuchen Sie es noch einmal.
 		Erneutes Speichern im Inventar ist deaktiviert.
 	</notification>
 	<notification name="NoExistNoSaveToContents">
-		„[OBJ_NAME]“ kann nicht im Objektinhalt gespeichert werden, da das Objekt, aus dem es gerezzt wurde, nicht mehr existiert.
+		&lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; kann nicht im Objektinhalt gespeichert werden, da das Objekt, aus dem es gerezzt wurde, nicht mehr existiert.
 	</notification>
 	<notification name="NoModNoSaveToContents">
-		„[OBJ_NAME]“ kann nicht in Objektinhalt gespeichert werden, da Sie nicht die Berechtigung zum Modifizieren des Objekts „[DEST_NAME]“ besitzen.
+		&lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; kann nicht in Objektinhalt gespeichert werden, da Sie nicht über die Berechtigung zum Modifizieren des Objekts &lt;nolink&gt;&apos;[DEST_NAME]&apos;&lt;/nolink&gt; verfügen.
 	</notification>
 	<notification name="NoSaveBackToInvDisabled">
-		„[OBJ_NAME]“ kann nicht erneut im Inventar gespeichert werden – dieser Vorgang wurde deaktiviert.
+		&lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; kann nicht erneut im Inventar gespeichert werden – dieser Vorgang wurde deaktiviert.
 	</notification>
 	<notification name="NoCopyNoSelCopy">
-		Sie können Ihre Auswahl nicht kopieren, da Sie nicht die Berechtigung zum Kopieren des Objekts „[OBJ_NAME]“ haben.
+		Sie können Ihre Auswahl nicht kopieren, da Sie nicht über die Berechtigung zum Kopieren des Objekts &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; verfügen.
 	</notification>
 	<notification name="NoTransNoSelCopy">
-		Sie können Ihre Auswahl nicht kopieren, da das Objekt „[OBJ_NAME]“ nicht übertragbar ist.
+		Sie können Ihre Auswahl nicht kopieren, da das Objekt &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; nicht übertragbar ist.
 	</notification>
 	<notification name="NoTransNoCopy">
-		Sie können Ihre Auswahl nicht kopieren, da das Objekt „[OBJ_NAME]“ nicht übertragbar ist.
+		Sie können Ihre Auswahl nicht kopieren, da das Objekt &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; nicht übertragbar ist.
 	</notification>
 	<notification name="NoPermsNoRemoval">
-		Entfernen des Objekts „[OBJ_NAME]“ aus dem Simulator wird vom Berechtigungssystem nicht gestattet.
+		Entfernen des Objekts &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; aus dem Simulator wird vom Berechtigungssystem nicht gestattet.
 	</notification>
 	<notification name="NoModNoSaveSelection">
-		Sie können Ihre Auswahl nicht speichern, da Sie keine Berechtigung zum Modifizieren des Objekts „[OBJ_NAME]“ besitzen.
+		Sie können Ihre Auswahl nicht speichern, da Sie nicht über die Berechtigung zum Modifizieren des Objekts &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; verfügen.
 	</notification>
 	<notification name="NoCopyNoSaveSelection">
-		Ihre Auswahl kann nicht gespeichert werden, da das Objekt „[OBJ_NAME]“ nicht kopiert werden kann.
+		Ihre Auswahl kann nicht gespeichert werden, da das Objekt &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; nicht kopiert werden kann.
 	</notification>
 	<notification name="NoModNoTaking">
-		Sie können Ihre Auswahl nicht in Empfang nehmen, da Sie nicht die Berechtigung zum Modifizieren des Objekts „[OBJ_NAME]“ haben.
+		Sie können Ihre Auswahl nicht in Empfang nehmen, da Sie nicht über die Berechtigung zum Modifizieren des Objekts &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; verfügen.
 	</notification>
 	<notification name="RezDestInternalError">
 		Interner Fehler: Unbekannter Zielttyp.
diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml
index cde04d8d69..78d445f362 100644
--- a/indra/newview/skins/default/xui/de/strings.xml
+++ b/indra/newview/skins/default/xui/de/strings.xml
@@ -5740,4 +5740,25 @@ Setzen Sie den Editorpfad in Anführungszeichen
 	<string name="Mav_Details_MAV_UNKNOWN_VERSION">
 		Die Physikform hat keine korrekte Version. Legen Sie die korrekte Version für das Physikmodell fest.
 	</string>
+	<string name="couldnt_resolve_host">
+		Der DNS konnte den Hostnamen ([HOSTNAME]) nicht auflösen Prüfen 
+Sie bitte, ob Sie die Website www.secondlife.com aufrufen können. Wenn Sie die 
+Website aufrufen können, jedoch weiterhin diese Fehlermeldung erhalten, 
+besuchen Sie bitte den Support-Bereich und melden Sie das Problem.
+	</string>
+	<string name="ssl_peer_certificate">
+		Der Anmeldeserver konnte sich nicht per SSL verifizieren. 
+Wenn Sie diese Fehlermeldung weiterhin erhalten, besuchen 
+Sie bitte den Support-Bereich der Website Secondlife.com 
+und melden Sie das Problem.
+	</string>
+	<string name="ssl_connect_error">
+		Die Ursache hierfür ist häufig eine falsch eingestellte Uhrzeit auf Ihrem Computer. 
+Bitte vergewissern Sie sich, dass Datum und Uhrzeit in der Systemsteuerung korrekt 
+eingestellt sind. Überprüfen Sie außerdem, ob Ihre Netzwerk- und Firewall-Einstellungen 
+korrekt sind. Wenn Sie diese Fehlermeldung weiterhin erhalten, besuchen Sie bitte den 
+Support-Bereich der Website Secondlife.com und melden Sie das Problem. 
+
+[https://community.secondlife.com/knowledgebase/english/error-messages-r520/#Section__3 Knowledge-Base]
+	</string>
 </strings>
diff --git a/indra/newview/skins/default/xui/es/notifications.xml b/indra/newview/skins/default/xui/es/notifications.xml
index 70825eadbe..7b1185c4c3 100644
--- a/indra/newview/skins/default/xui/es/notifications.xml
+++ b/indra/newview/skins/default/xui/es/notifications.xml
@@ -243,6 +243,10 @@ La inicialización del mercado ha fallado por un error del sistema o de la red.
 		Nota: Al activar esta opción, cualquiera que utilice este ordenador podrá ver tu lista de lugares favoritos.
 		<usetemplate name="okbutton" yestext="OK"/>
 	</notification>
+	<notification name="AllowMultipleViewers">
+		No es posible ejecutar varios visores Second Life ya que esta funcionalidad no es compatible. Puede provocar problemas de caché en la textura, imágenes degradadas o alteradas y un bajo rendimiento.
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
 	<notification name="GrantModifyRights">
 		Al conceder permisos de modificación a otro Residente, le estás permitiendo cambiar, borrar o tomar CUALQUIER objeto que tengas en el mundo. Sé MUY cuidadoso al conceder este permiso.
 ¿Quieres conceder permisos de modificación a [NAME]?
@@ -713,8 +717,9 @@ La calidad gráfica puede ajustarse en Preferencias &gt; Gráficos.
 		No tienes permiso para modificar el terreno de la parcela [PARCEL].
 	</notification>
 	<notification name="CannotCopyWarning">
-		No tienes permiso para copiar los elementos siguientes:
-[ITEMS] y, si los das, los perderás del inventario. ¿Seguro que quieres ofrecerlos?
+		No tienes permiso para copiar los elementos siguientes: 
+&lt;nolink&gt;[ITEMS]&lt;/nolink&gt;
+y, si los das, los perderás del inventario. ¿Seguro que quieres ofrecerlos?
 		<usetemplate name="okcancelbuttons" notext="No" yestext="Sí"/>
 	</notification>
 	<notification name="CannotGiveItem">
@@ -3712,13 +3717,13 @@ no está en la misma región que tú.
 		No puedes crear árboles y hierba en un terreno que no es tuyo.
 	</notification>
 	<notification name="NoCopyPermsNoObject">
-		Error al copiar: careces de permiso para copiar el objeto &apos;[OBJ_NAME]&apos;.
+		Error al copiar porque no tienes permiso para copiar el objeto &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;.
 	</notification>
 	<notification name="NoTransPermsNoObject">
-		Error al copiar: no se te puede transferir el objeto &apos;[OBJ_NAME]&apos;.
+		Error al copiar porque no puedes recibir una transferencia del objeto &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;.
 	</notification>
 	<notification name="AddToNavMeshNoCopy">
-		Error al copiar porque el objeto &apos;[OBJ_NAME]&apos; contribuye al navmesh.
+		Error al copiar porque el objeto &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; contribuye a navmesh.
 	</notification>
 	<notification name="DupeWithNoRootsSelected">
 		Duplicación sin objetos raíz seleccionados.
@@ -3763,34 +3768,34 @@ Prueba otra vez dentro de un minuto.
 		Se ha deshabilitado Devolver el objeto a mi inventario.
 	</notification>
 	<notification name="NoExistNoSaveToContents">
-		No se puede guardar &apos;[OBJ_NAME]&apos; en el contenido del objeto porque el objeto desde el cual ha sido colocado ya no existe.
+		No se puede guardar &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; en los contenidos del objeto porque el objeto a partir del cual fue creado ya no existe.
 	</notification>
 	<notification name="NoModNoSaveToContents">
-		No se puede guardar &apos;[OBJ_NAME]&apos; en el contenido del objeto porque no tienes permiso para modificar el objeto &apos;[DEST_NAME]&apos;.
+		No se puede guardar &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; en los contenidos del objeto porque no tienes permiso para modificar el objeto &lt;nolink&gt;&apos;[DEST_NAME]&apos;&lt;/nolink&gt;.
 	</notification>
 	<notification name="NoSaveBackToInvDisabled">
-		No se puede guardar &apos;[OBJ_NAME]&apos; de nuevo en el inventario; esta operación está desactivada.
+		No se puede volver a guardar &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; en el inventario. Esta operación fue desactivada.
 	</notification>
 	<notification name="NoCopyNoSelCopy">
-		No se puede copiar tu selección porque no tienes permiso para copiar el objeto &apos;[OBJ_NAME]&apos;.
+		No puedes copiar el elemento seleccionado porque no tienes permiso para copiar el objeto &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;.
 	</notification>
 	<notification name="NoTransNoSelCopy">
-		No se puede copiar tu selección porque el objeto &apos;[OBJ_NAME]&apos; es intransferible.
+		No puedes copiar el elemento seleccionado porque el objeto &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; no es transferible.
 	</notification>
 	<notification name="NoTransNoCopy">
-		No se puede copiar tu selección porque el objeto &apos;[OBJ_NAME]&apos; es intransferible.
+		No puedes copiar el elemento seleccionado porque el objeto &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; no es transferible.
 	</notification>
 	<notification name="NoPermsNoRemoval">
-		El sistema de permisos no admite la eliminación del objeto &apos;[OBJ_NAME]&apos; del simulador.
+		El sistema de permisos no autoriza quitar el objeto &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; del simulador.
 	</notification>
 	<notification name="NoModNoSaveSelection">
-		No se puede guardar tu selección porque no tienes permiso para modificar el objeto &apos;[OBJ_NAME]&apos;.
+		No puedes guardar el elemento seleccionado porque no tienes permiso para modificar el objeto &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;.
 	</notification>
 	<notification name="NoCopyNoSaveSelection">
-		No se puede guardar tu selección porque el objeto &apos;[OBJ_NAME]&apos; no se puede copiar.
+		No puedes guardar el elemento seleccionado porque el objeto &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; no puede ser copiado.
 	</notification>
 	<notification name="NoModNoTaking">
-		No se puede aceptar tu selección porque no tienes permiso para modificar el objeto &apos;[OBJ_NAME]&apos;.
+		No puedes tomar el elemento seleccionado porque no tienes permiso para modificar el objeto &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;.
 	</notification>
 	<notification name="RezDestInternalError">
 		Error interno: tipo de destino desconocido.
diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml
index 36a2711a5c..15e3c0622d 100644
--- a/indra/newview/skins/default/xui/es/strings.xml
+++ b/indra/newview/skins/default/xui/es/strings.xml
@@ -5651,4 +5651,25 @@ Inténtalo incluyendo la ruta de acceso al editor entre comillas
 	<string name="Mav_Details_MAV_UNKNOWN_VERSION">
 		La versión de la forma física no es correcta. Configura la versión correcta del modelo físico.
 	</string>
+	<string name="couldnt_resolve_host">
+		Error de DNS al resolver el nombre del host([HOSTNAME]). 
+Por favor verifica si puedes conectarte al sitio web www.secondlife.com. 
+Si puedes conectarte, pero aún recibes este error, por favor accede a 
+la sección Soporte y genera un informe del problema.
+	</string>
+	<string name="ssl_peer_certificate">
+		El servidor de inicio de sesión no pudo verificarse vía SSL. 
+Si aún recibes este error, por favor accede a 
+la sección Soporte del sitio web Secondlife.com 
+y genera un informe del problema.
+	</string>
+	<string name="ssl_connect_error">
+		En general esto significa que el horario de tu computadora no está bien configurado. 
+Por favor accede al Panel de control y asegúrate de que la hora y la fecha estén 
+bien configurados. Verifica también que tu red y tu cortafuegos estén bien 
+configurados. Si aún recibes este error, por favor accede a la sección Soporte 
+del sitio web Secondlife.com y genera un informe del problema. 
+
+[https://community.secondlife.com/knowledgebase/english/error-messages-r520/#Section__3 Base de conocimientos]
+	</string>
 </strings>
diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml
index 74abecf760..9066f1e70c 100644
--- a/indra/newview/skins/default/xui/fr/notifications.xml
+++ b/indra/newview/skins/default/xui/fr/notifications.xml
@@ -244,6 +244,10 @@ Veuillez ne sélectionner qu&apos;un seul objet.
 		Remarque : si vous activez cette option, toutes les personnes utilisant cet ordinateur pourront voir votre liste d&apos;endroits favoris.
 		<usetemplate name="okbutton" yestext="OK"/>
 	</notification>
+	<notification name="AllowMultipleViewers">
+		L&apos;exécution de plusieurs visualiseurs Second Life n&apos;est pas prise en charge. Cela peut entraîner des collisions de cache de texture, une corruption et une dégradation des visuels et des performances.
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
 	<notification name="GrantModifyRights">
 		Lorsque vous accordez des droits de modification à un autre résident, vous lui permettez de changer, supprimer ou prendre n&apos;importe lequel de vos objets dans Second Life. Réfléchissez bien avant d&apos;accorder ces droits.
 Voulez-vous vraiment accorder des droits de modification à [NAME] ?
@@ -717,9 +721,9 @@ La qualité des graphiques peut être augmentée à la section Préférences &gt
 		Vous n&apos;êtes pas autorisé(e) à terraformer la parcelle [PARCEL].
 	</notification>
 	<notification name="CannotCopyWarning">
-		Vous n&apos;êtes pas autorisé à copier les articles suivants :
-[ITEMS].
-Ceux-ci disparaîtront donc de votre inventaire si vous les donnez. Voulez-vous vraiment offrir ces articles ?
+		Vous n&apos;êtes pas autorisé à copier les objets suivants : 
+&lt;nolink&gt;[ITEMS]&lt;/nolink&gt;
+et il disparaîtra de votre inventaire si vous le donnez. Voulez-vous vraiment offrir ces articles ?
 		<usetemplate name="okcancelbuttons" notext="Non" yestext="Oui"/>
 	</notification>
 	<notification name="CannotGiveItem">
@@ -3715,13 +3719,13 @@ il ne se trouve pas dans la même région que vous.
 		Vous ne pouvez pas créer d&apos;arbres ni d&apos;herbe sur un terrain qui ne vous appartient pas.
 	</notification>
 	<notification name="NoCopyPermsNoObject">
-		Échec de la copie car vous ne disposez pas des droits requis pour copier l&apos;objet [OBJ_NAME].
+		La copie a échoué car vous ne disposez pas de l&apos;autorisation nécessaire pour copier l&apos;objet &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;.
 	</notification>
 	<notification name="NoTransPermsNoObject">
-		Échec de la copie car l&apos;objet [OBJ_NAME] ne peut pas vous être transféré.
+		La copie a échoué car l&apos;objet &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; ne peut pas vous être transféré.
 	</notification>
 	<notification name="AddToNavMeshNoCopy">
-		Échec de la copie car l&apos;objet [OBJ_NAME] contribue au maillage de navigation.
+		La copie a échoué car l&apos;objet &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; contribue à navmesh.
 	</notification>
 	<notification name="DupeWithNoRootsSelected">
 		Dupliquer sans objet racine sélectionné
@@ -3766,34 +3770,34 @@ Veuillez réessayer dans une minute.
 		Le réenregistrement dans l&apos;inventaire a été désactivé.
 	</notification>
 	<notification name="NoExistNoSaveToContents">
-		Impossible d&apos;enregistrer [OBJ_NAME] dans le contenu des objets car l&apos;objet à partir duquel il a été rezzé n&apos;existe plus.
+		Impossible de sauvegarder &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;  dans le contenu de l&apos;objet car l&apos;objet à partir duquel il a été rezzé n&apos;existe plus.
 	</notification>
 	<notification name="NoModNoSaveToContents">
-		Impossible d&apos;enregistrer [OBJ_NAME] dans le contenu des objets car vous ne disposez pas des droits requis pour modifier l&apos;objet [DEST_NAME].
+		Impossible de sauvegarder&lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; dans le contenu de l&apos;objet car vous n&apos;êtes pas autorisé à modifier l&apos;objet &lt;nolink&gt;&apos;[DEST_NAME]&apos;&lt;/nolink&gt;.
 	</notification>
 	<notification name="NoSaveBackToInvDisabled">
-		Impossible de réenregistrer [OBJ_NAME] dans l&apos;inventaire -- cette opération a été désactivée.
+		Impossible de sauvegarder &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; dans l&apos;inventaire - cette opération a été désactivée.
 	</notification>
 	<notification name="NoCopyNoSelCopy">
-		Vous ne pouvez pas copier votre sélection car vous n&apos;avez pas le droit de copier l&apos;objet [OBJ_NAME].
+		Vous ne pouvez pas copier votre sélection parce que vous n&apos;êtes pas autorisé à copier l&apos;objet &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;.
 	</notification>
 	<notification name="NoTransNoSelCopy">
-		Vous ne pouvez pas copier votre sélection car l&apos;objet [OBJ_NAME] n&apos;est pas transférable.
+		Vous ne pouvez pas copier votre sélection parce que l&apos;objet  &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; n&apos;est pas transférable.
 	</notification>
 	<notification name="NoTransNoCopy">
-		Vous ne pouvez pas copier votre sélection car l&apos;objet [OBJ_NAME] n&apos;est pas transférable.
+		Vous ne pouvez pas copier votre sélection parce que l&apos;objet  &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; n&apos;est pas transférable.
 	</notification>
 	<notification name="NoPermsNoRemoval">
-		La suppression de l&apos;objet [OBJ_NAME] du simulateur n&apos;est pas autorisée par le système de droits.
+		La suppression de l&apos;objet &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; du simulateur n&apos;est pas autorisée par le système d&apos;autorisations.
 	</notification>
 	<notification name="NoModNoSaveSelection">
-		Vous ne pouvez pas enregistrer votre sélection car vous n&apos;avez pas le droit de modifier l&apos;objet [OBJ_NAME].
+		Impossible de sauvegarder votre sélection parce que vous n&apos;êtes pas autorisé à modifier l&apos;objet &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;.
 	</notification>
 	<notification name="NoCopyNoSaveSelection">
-		Vous ne pouvez pas enregistrer votre sélection car l&apos;objet [OBJ_NAME] ne peut pas être copié.
+		Impossible d&apos;enregistrer votre sélection car l&apos;objet &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; n&apos;est pas copiable.
 	</notification>
 	<notification name="NoModNoTaking">
-		Vous ne pouvez pas prendre votre sélection car vous n&apos;avez pas le droit de modifier l&apos;objet [OBJ_NAME].
+		Vous ne pouvez pas sauvegarder votre sélection parce que vous n&apos;êtes pas autorisé à modifier l&apos;objet &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;.
 	</notification>
 	<notification name="RezDestInternalError">
 		Erreur interne : type de destination inconnue.
diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml
index 7f5851b51d..13dd2b3640 100644
--- a/indra/newview/skins/default/xui/fr/strings.xml
+++ b/indra/newview/skins/default/xui/fr/strings.xml
@@ -5741,4 +5741,25 @@ Essayez avec le chemin d&apos;accès à l&apos;éditeur entre guillemets doubles
 	<string name="Mav_Details_MAV_UNKNOWN_VERSION">
 		La forme physique n’a pas la version correcte. Configurez la version correcte pour le modèle physique.
 	</string>
+	<string name="couldnt_resolve_host">
+		DNS n&apos;a pas pu résoudre le nom d&apos;hôte([HOSTNAME]). 
+Veuillez vérifier que vous parvenez à vous connecter au site www.secondlife.com. 
+Si c&apos;est le cas, et que vous continuez à recevoir ce message d&apos;erreur, veuillez vous 
+rendre à la section Support et signaler ce problème
+	</string>
+	<string name="ssl_peer_certificate">
+		Le serveur d&apos;identification a rencontré une erreur de connexion SSL. 
+Si vous continuez à recevoir ce message d&apos;erreur, 
+veuillez vous rendre à la section Support du site web 
+SecondLife.com et signaler ce problème
+	</string>
+	<string name="ssl_connect_error">
+		Ceci est souvent dû à un mauvais réglage de l&apos;horloge de votre ordinateur. 
+Veuillez aller à Tableaux de bord et assurez-vous que l&apos;heure et la date sont réglés 
+correctement. Vérifiez également que votre réseau et votre pare-feu sont configurés 
+correctement. Si vous continuez à recevoir ce message d&apos;erreur, veuillez vous rendre 
+à la section Support du site web SecondLife.com et signaler ce problème. 
+
+[https://community.secondlife.com/knowledgebase/english/error-messages-r520/#Section__3 Base de connaissances]
+	</string>
 </strings>
diff --git a/indra/newview/skins/default/xui/it/notifications.xml b/indra/newview/skins/default/xui/it/notifications.xml
index d1a47535d8..8a057914ac 100644
--- a/indra/newview/skins/default/xui/it/notifications.xml
+++ b/indra/newview/skins/default/xui/it/notifications.xml
@@ -244,6 +244,10 @@ Scegli solo un oggetto e riprova.
 		Nota: Se attivi questa opzione, chiunque usa questo computer può vedere l&apos;elenco di luoghi preferiti.
 		<usetemplate name="okbutton" yestext="OK"/>
 	</notification>
+	<notification name="AllowMultipleViewers">
+		Non è possibile utilizzare più di un viewer Second Life contemporaneamente. L’utilizzo simultaneo potrebbe portare a collisioni o corruzione della cache texture, e ad un peggioramento nelle immagini e nella performance.
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
 	<notification name="GrantModifyRights">
 		Quando concedi i diritti di modifica ad un altro residente, gli permetti di modificare, eliminare o prendere QUALSIASI oggetto che possiedi in Second Life. Pertanto ti consigliamo di essere ben sicuro quando concedi questo diritto.
 Vuoi concedere i diritti di modifica a [NAME]?
@@ -716,8 +720,8 @@ La qualità grafica può essere aumentata in Preferenze &gt; Grafica.
 	</notification>
 	<notification name="CannotCopyWarning">
 		Non hai l&apos;autorizzazione a copiare i seguenti oggetti:
-[ITEMS]
-e se li dai via, verranno eliminati dal tuo inventario. Sicuro di volere offrire questi oggetti?
+&lt;nolink&gt;[ITEMS]&lt;/nolink&gt;
+e se li dai via, verranno eliminati dal tuo inventario. Sicuro di voler offrire questi oggetti?
 		<usetemplate name="okcancelbuttons" notext="No" yestext="Si"/>
 	</notification>
 	<notification name="CannotGiveItem">
@@ -3719,13 +3723,13 @@ non è nella stessa regione in cui ti trovi.
 		Non puoi creare alberi ed erba su terreni che non sono di tua proprietà.
 	</notification>
 	<notification name="NoCopyPermsNoObject">
-		Copia non riuscita perché non hai l&apos;autorizzazione necessaria per copiare l&apos;oggetto &apos;[OBJ_NAME]&apos;.
+		Copia non riuscita perché non hai il permesso per copiare l’oggetto &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;.
 	</notification>
 	<notification name="NoTransPermsNoObject">
-		La copia non è riuscita perché &apos;[OBJ_NAME]&apos; non può essere trasferito a te.
+		Copia non riuscita perché l’oggetto &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; non può esserti trasferito.
 	</notification>
 	<notification name="AddToNavMeshNoCopy">
-		La copia non è riuscita perché &apos;[OBJ_NAME]&apos; contribuisce al navmesh.
+		Copia non riuscita perché l’oggetto &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; contribuisce al navmesh.
 	</notification>
 	<notification name="DupeWithNoRootsSelected">
 		Duplicato senza oggetto principale selezionato.
@@ -3770,34 +3774,34 @@ Riprova tra un minuto.
 		Opzione Salva nell&apos;inventario disattivata
 	</notification>
 	<notification name="NoExistNoSaveToContents">
-		Impossibile salvare &apos;[OBJ_NAME]&apos; nei contenuti dell&apos;oggetto perché l&apos;oggetto da cui è stato razzato non esiste più.
+		Impossibile salvare &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; in contenuti oggetto perché l’oggetto da cui è stato rezzato non esiste più.
 	</notification>
 	<notification name="NoModNoSaveToContents">
-		Impossibile salvare &apos;[OBJ_NAME]&apos; nei contenuti dell&apos;oggetto perché non hai l&apos;autorizzazione necessaria per modificare l&apos;oggetto &apos;[DEST_NAME]&apos;.
+		Impossibile salvare &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; in contenuti oggetto perché non hai i permessi per modificare l’oggetto &lt;nolink&gt;&apos;[DEST_NAME]’&lt;/nolink&gt;.
 	</notification>
 	<notification name="NoSaveBackToInvDisabled">
-		Impossibile riportare &apos;[OBJ_NAME]&apos; nell&apos;inventario -- questa operazione è stata disattivata.
+		Impossibile salvare &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; nell’inventario: questa operazione è stata disabilitata.
 	</notification>
 	<notification name="NoCopyNoSelCopy">
-		Non puoi copiare l&apos;elemento selezionato perché non hai l&apos;autorizzazione necessaria per copiare l&apos;oggetto &apos;[OBJ_NAME]&apos;.
+		Non puoi copiare la selezione perché non hai il permesso di copiare l’oggetto &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;.
 	</notification>
 	<notification name="NoTransNoSelCopy">
-		Non puoi copiare la selezione perché l&apos;oggetto &apos;[OBJ_NAME]&apos; non può essere trasferito.
+		Non puoi copiare la selezione perché l’oggetto &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; non è trasferibile.
 	</notification>
 	<notification name="NoTransNoCopy">
-		Non puoi copiare la selezione perché l&apos;oggetto &apos;[OBJ_NAME]&apos; non può essere trasferito.
+		Non puoi copiare la selezione perché l’oggetto &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; non è trasferibile.
 	</notification>
 	<notification name="NoPermsNoRemoval">
-		La rimozione dell&apos;oggetto &apos;[OBJ_NAME]&apos; dal simulatore non è consentita dal sistema delle autorizzazioni.
+		La rimozione dell’oggetto &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; dal simulatore è disattivata dal sistema dei permessi.
 	</notification>
 	<notification name="NoModNoSaveSelection">
-		Non puoi salvare l&apos;elemento selezionato perché non hai l&apos;autorizzazione necessaria per modificare l&apos;oggetto &apos;[OBJ_NAME]&apos;.
+		Non puoi copiare la selezione perché non hai il permesso di modificare l’oggetto &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;.
 	</notification>
 	<notification name="NoCopyNoSaveSelection">
-		Non puoi salvare la selezione perché l&apos;oggetto &apos;[OBJ_NAME]&apos; non può essere copiato.
+		Non puoi copiare la selezione perché l’oggetto &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; non è copiabile.
 	</notification>
 	<notification name="NoModNoTaking">
-		Non puoi prendere l&apos;elemento selezionato perché non hai l&apos;autorizzazione necessaria per modificare l&apos;oggetto &apos;[OBJ_NAME]&apos;.
+		Non puoi prendere ciò che hai selezionato perché non hai il permesso di modificare l’oggetto &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;.
 	</notification>
 	<notification name="RezDestInternalError">
 		Errore interno: Tipo di destinazione sconosciuto.
diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml
index 918e655ab6..be3acc14b3 100644
--- a/indra/newview/skins/default/xui/it/strings.xml
+++ b/indra/newview/skins/default/xui/it/strings.xml
@@ -5656,4 +5656,25 @@ Prova a racchiudere il percorso dell&apos;editor in doppie virgolette.
 	<string name="Mav_Details_MAV_UNKNOWN_VERSION">
 		La versione della forma fisica non è corretta. Imposta la versione corretta per il modello della fisica.
 	</string>
+	<string name="couldnt_resolve_host">
+		Il DNS non ha potuto risolvere il nome dell’host([HOSTNAME]). 
+Verifica di riuscire a connetterti al sito web www.secondlife.com. 
+Se riesci ma continui a ricevere questo errore, visita la sezione 
+Assistenza e segnala il problema.
+	</string>
+	<string name="ssl_peer_certificate">
+		Il server per il login non ha potuto effettuare la verifica tramite SSL. 
+Se continui a ricevere questo errore, visita 
+la sezione Assistenza nel sito SecondLife.com 
+e segnala il problema.
+	</string>
+	<string name="ssl_connect_error">
+		Spesso l’errore è dovuto all’orologio del computer, impostato incorrettamente. 
+Vai al Pannello di Controllo e assicurati che data e ora siano 
+esatte. Controlla anche che il network e il firewall siano impostati 
+correttamente. Se continui a ricevere questo errore, visita la sezione 
+Assistenza nel sito SecondLife.com e segnala il problema. 
+
+[https://community.secondlife.com/knowledgebase/english/error-messages-r520/#Section__3 Base conoscenze]
+	</string>
 </strings>
diff --git a/indra/newview/skins/default/xui/ja/notifications.xml b/indra/newview/skins/default/xui/ja/notifications.xml
index 99ba5b2655..fc6c951a55 100644
--- a/indra/newview/skins/default/xui/ja/notifications.xml
+++ b/indra/newview/skins/default/xui/ja/notifications.xml
@@ -244,6 +244,10 @@
 		注意:このオプションを有効にすると、このパソコンを使うユーザーは誰でも、あなたのお気に入りの場所を見ることができるようになります。
 		<usetemplate name="okbutton" yestext="OK"/>
 	</notification>
+	<notification name="AllowMultipleViewers">
+		複数の Second Life ビューワを実行することはサポートされていません。テクスチャキャッシュのコリジョンや破損、およびビジュアルとパフォーマンスの低下につながる恐れがあります。
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
 	<notification name="GrantModifyRights">
 		他人に修正権限を与えると、権限を与えられた人はあなたが所有するインワールドのオブジェクトを変更、削除、持ち帰ることができます。この権限を与える際には十分に注意してください。
 [NAME] に修正権限を与えますか?
@@ -735,7 +739,9 @@ L$ が不足しているのでこのグループに参加することができ
 		あなたには [PARCEL] 区画を地形編集する許可がありません。
 	</notification>
 	<notification name="CannotCopyWarning">
-		あなたには[ITEMS]というアイテムをコピーする許可がありません。他の住人に提供すると、そのアイテムはあなたのインベントリから削除されます。本当にこれらのアイテムを譲りますか?
+		あなたには次アイテムをコピーする権限がありません: 
+&lt;nolink&gt;[ITEMS]&lt;/nolink&gt; 
+他の住人に譲ると、そのアイテムはあなたの持ち物から削除されます。本当にこれらのアイテムを譲りますか?
 		<usetemplate name="okcancelbuttons" notext="いいえ" yestext="はい"/>
 	</notification>
 	<notification name="CannotGiveItem">
@@ -3756,13 +3762,13 @@ M キーを押して変更します。
 		所有していない土地に木や草を植えることはできません。
 	</notification>
 	<notification name="NoCopyPermsNoObject">
-		オブジェクト &apos;[OBJ_NAME]&apos; をコピーする権限がないため、コピーに失敗しました。
+		あなたにはオブジェクト &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; をコピーする権限がないため、コピーに失敗しました。
 	</notification>
 	<notification name="NoTransPermsNoObject">
-		オブジェクト &apos;[OBJ_NAME]&apos; をあなたに転送できないため、コピーに失敗しました。
+		オブジェクト &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; はあなたに譲渡できないため、コピーに失敗しました。
 	</notification>
 	<notification name="AddToNavMeshNoCopy">
-		オブジェクト &apos;[OBJ_NAME]&apos; がナビメッシュに貢献しているため、コピーに失敗しました。
+		オブジェクト &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; は navmesh に関連があるため、コピーに失敗しました。
 	</notification>
 	<notification name="DupeWithNoRootsSelected">
 		ルートオブジェクトを選択せずに複製します。
@@ -3807,34 +3813,34 @@ M キーを押して変更します。
 		「「持ち物」に保存」が無効になっています。
 	</notification>
 	<notification name="NoExistNoSaveToContents">
-		&apos;[OBJ_NAME]&apos; の Rez 元であるオブジェクトが存在しないため、このオブジェクトをオブジェクトコンテンツに保存できません。
+		「存在しません」から rez されたため、&lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; をオブジェクトの中身に保存できませんでした。
 	</notification>
 	<notification name="NoModNoSaveToContents">
-		オブジェクト &apos;[DEST_NAME]&apos; を修正する権限がないため、オブジェクトのコンテンツに &apos;[OBJ_NAME]&apos; を保存できません。
+		あなたにはオブジェクト &lt;nolink&gt;&apos;[DEST_NAME]&apos;&lt;/nolink&gt; を修正する権限がないため、&lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;をオブジェクトの中身に保存できませんでした。
 	</notification>
 	<notification name="NoSaveBackToInvDisabled">
-		インベントリに &apos;[OBJ_NAME]&apos; を保存することはできません - この操作が無効になっています。
+		&lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; をインベントリに保存できません。この操作は無効になりました。
 	</notification>
 	<notification name="NoCopyNoSelCopy">
-		オブジェクト &apos;[OBJ_NAME]&apos; を変更する権限を持っていないため、選択したものをコピーできません。
+		あなたにはオブジェクト &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; をコピーする権限がないため、選択内容をコピーできません。
 	</notification>
 	<notification name="NoTransNoSelCopy">
-		オブジェクト &apos;[OBJ_NAME]&apos; を転送できないため、選択したものをコピーできません。
+		オブジェクト &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; を譲渡できないため、選択内容をコピーできません。
 	</notification>
 	<notification name="NoTransNoCopy">
-		オブジェクト &apos;[OBJ_NAME]&apos; を転送できないため、選択したものをコピーできません。
+		オブジェクト &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; を譲渡できないため、選択内容をコピーできません。
 	</notification>
 	<notification name="NoPermsNoRemoval">
-		シミュレータからのオブジェクト &apos;[OBJ_NAME]&apos; の削除は、権限システムによって無効にされています。
+		オブジェクト &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; をシミュレーターから削除することは、権限のシステムにより許可されていません。
 	</notification>
 	<notification name="NoModNoSaveSelection">
-		オブジェクト &apos;[OBJ_NAME]&apos; を変更する権限を持っていないため、選択したものを保存できません。
+		あなたにはオブジェクト &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; を修正する権限がないため、選択内容を保存できません。
 	</notification>
 	<notification name="NoCopyNoSaveSelection">
-		オブジェクト &apos;[OBJ_NAME]&apos; をコピーできないため、選択したものを保存できません。
+		オブジェクト &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; はコピー不可なため、選択内容を保存できません。
 	</notification>
 	<notification name="NoModNoTaking">
-		オブジェクト &apos;[OBJ_NAME]&apos; を変更する権限を持っていないため、選択したものを取得できません。
+		あなたにはオブジェクト &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; を修正する権限がないため、選択内容を選ぶことはできません。
 	</notification>
 	<notification name="RezDestInternalError">
 		内部エラー: 不明な宛先タイプ。
diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml
index bcf4698bb0..9116bba8bb 100644
--- a/indra/newview/skins/default/xui/ja/strings.xml
+++ b/indra/newview/skins/default/xui/ja/strings.xml
@@ -5739,4 +5739,25 @@ www.secondlife.com から最新バージョンをダウンロードしてくだ
 	<string name="Mav_Details_MAV_UNKNOWN_VERSION">
 		物理形状のバージョンが正しくありません。物理モデルに正しいバージョンを設定してください。
 	</string>
+	<string name="couldnt_resolve_host">
+		DNS がホスト名 ([HOSTNAME]) を解決できませんでした。
+www.secondlife.com のウェブサイトに接続できるかご確認ください。
+接続できても、このエラーが継続的に起こる場合は、
+サポートセクションから問題を報告してください。
+	</string>
+	<string name="ssl_peer_certificate">
+		ログインサーバーが SSL 経由で確認できませんでした。
+このエラーが継続的に起こる場合は、
+Secondlife.com のサポートセクションから
+問題を報告してください。
+	</string>
+	<string name="ssl_connect_error">
+		この問題の多くは、お使いのコンピュータの時計が正しく設定されていないために起こります。
+コントロールパネルから時刻と日付が正しく設定されているかご確認ください。
+お使いのネットワークとファイアウォールも正しく設定されているかお確かめください。
+このエラーが継続的に起こる場合は、Secondlife.com のサポートセクションから
+問題を報告してください。
+
+[https://community.secondlife.com/knowledgebase/english/error-messages-r520/#Section__3 ナレッジベース]
+	</string>
 </strings>
diff --git a/indra/newview/skins/default/xui/pt/notifications.xml b/indra/newview/skins/default/xui/pt/notifications.xml
index 5c848034d8..b4cf0a1b20 100644
--- a/indra/newview/skins/default/xui/pt/notifications.xml
+++ b/indra/newview/skins/default/xui/pt/notifications.xml
@@ -243,6 +243,10 @@ Por favor, selecione apenas um objeto e tente novamente.
 		Nota: Ao ativar esta opção, qualquer pessoa que utilizar este computador poderá ver a sua lista de lugares preferidos.
 		<usetemplate name="okbutton" yestext="OK"/>
 	</notification>
+	<notification name="AllowMultipleViewers">
+		Não é possível executar múltiplos visualizadores Second Life. Pode levar a uma falha, um corrompimento, visuais alterados e falha no desempenho no cache de textura.
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
 	<notification name="GrantModifyRights">
 		Conceder direitos de modificação a outros residentes vai autorizá-los a mudar, apagar ou pegar TODOS os seus objetos. Seja MUITO cuidadoso ao conceder esta autorização.
 Deseja dar direitos de modificação a [NAME]?
@@ -711,9 +715,9 @@ Para aumentar a qualidade do vídeo, vá para Preferências &gt; Vídeo.
 		Você não está autorizado a terraplanar o terreno [PARCEL].
 	</notification>
 	<notification name="CannotCopyWarning">
-		Você não tem autorização para copiar os itens abaixo:
-[ITEMS]
-ao dá-los, você ficará sem eles no seu inventário. Deseja realmente dar estes itens?
+		Não existe autorização para copiar os itens abaixo: 
+&lt;nolink&gt;[ITEMS]&lt;/nolink&gt; 
+e eles sairão do inverntário se sair. Deseja realmente dar estes itens?
 		<usetemplate name="okcancelbuttons" notext="Não" yestext="Sim"/>
 	</notification>
 	<notification name="CannotGiveItem">
@@ -3702,13 +3706,13 @@ ele não está na mesma região que você.
 		Você não pode criar árvores e grama em terrenos que não são sua propriedade.
 	</notification>
 	<notification name="NoCopyPermsNoObject">
-		A cópia falhou porque você não está autorizado a copiar o objeto &apos;[OBJ_NAME]&apos;.
+		Falha na cópia por falta de permissão para copiar o objeto &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;.
 	</notification>
 	<notification name="NoTransPermsNoObject">
-		A cópia falhou porque o objeto &apos;[OBJ_NAME]&apos; não pode ser transferido para você.
+		Falha na cópia, porque o objeto &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; não pode ser transferido para você.
 	</notification>
 	<notification name="AddToNavMeshNoCopy">
-		A cópia falhou porque o objeto &apos;[OBJ_NAME]&apos; contribui para o navmesh.
+		Falha na cópia, porque o objeto &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; contribui para o Navmesh.
 	</notification>
 	<notification name="DupeWithNoRootsSelected">
 		Duplicar sem objetos raiz selecionados.
@@ -3753,34 +3757,34 @@ Tente novamente em instantes.
 		Salvar no inventário foi desativado.
 	</notification>
 	<notification name="NoExistNoSaveToContents">
-		Não é possível salvar &apos;[OBJ_NAME]&apos; no conteúdo do objeto porque o objeto do qual ele foi renderizado não existe mais.
+		Não foi possível salvar &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; para os conteúdos do objeto, porque o objeto foi utilizado e não existe mais.
 	</notification>
 	<notification name="NoModNoSaveToContents">
-		Não é possível salvar &apos;[OBJ_NAME]&apos; no conteúdo do objeto porque você não tem permissão para modificar o objeto &apos;[DEST_NAME]&apos;.
+		Não foi possível salvar &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; para os conteúdos do objeto, porque você não tem permissão para modificar o objeto &lt;nolink&gt;&apos;[DEST_NAME]&apos;&lt;/nolink&gt;.
 	</notification>
 	<notification name="NoSaveBackToInvDisabled">
-		Não é possível salvar &apos;[OBJ_NAME]&apos; no inventário -- essa operação foi desativada.
+		Não é possível salvar &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; no inventário outra vez -- esta operação foi desabilitada.
 	</notification>
 	<notification name="NoCopyNoSelCopy">
-		Você não pode copiar sua seleção porque não está autorizado a copiar o objeto &apos;[OBJ_NAME]&apos;.
+		Não é possível copiar a seleção porque você não tem permissão para copiar o objeto &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;.
 	</notification>
 	<notification name="NoTransNoSelCopy">
-		Você não pode copiar a seleção porque o objeto &apos;[OBJ_NAME]&apos; não é transferível.
+		Não é possível copiar a seleção porque o objeto &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; não é transferível.
 	</notification>
 	<notification name="NoTransNoCopy">
-		Você não pode copiar a seleção porque o objeto &apos;[OBJ_NAME]&apos; não é transferível.
+		Não é possível copiar a seleção porque o objeto &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; não é transferível.
 	</notification>
 	<notification name="NoPermsNoRemoval">
-		A remoção do objeto &apos;[OBJ_NAME]&apos; do simulador é proibida pelo sistema de permissões.
+		A remoção do objeto &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; do simulador não é permitida pelo sistema de permissão.
 	</notification>
 	<notification name="NoModNoSaveSelection">
-		Você não pode salvar sua seleção porque não está autorizado a modificar o objeto &apos;[OBJ_NAME]&apos;.
+		Não é possível salvar a seleção porque você não tem permissão para modificar o objeto &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;.
 	</notification>
 	<notification name="NoCopyNoSaveSelection">
-		Não é possível salvar sua seleção porque o objeto &apos;[OBJ_NAME]&apos; não é copiável.
+		Não é possível salvar a seleção porque o objeto &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; não é copiável.
 	</notification>
 	<notification name="NoModNoTaking">
-		Você não pode levar sua seleção porque não está autorizado a modificar o objeto &apos;[OBJ_NAME]&apos;.
+		Não é possível realizar a seleção porque você não tem permissão para modificar o objeto &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;.
 	</notification>
 	<notification name="RezDestInternalError">
 		Erro interno: tipo de destino desconhecido.
diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml
index ecf90ef787..4151ef36ac 100644
--- a/indra/newview/skins/default/xui/pt/strings.xml
+++ b/indra/newview/skins/default/xui/pt/strings.xml
@@ -5615,4 +5615,25 @@ Tente colocar o caminho do editor entre aspas.
 	<string name="Mav_Details_MAV_UNKNOWN_VERSION">
 		A forma física não tem a versão correta. Defina a versão correta para o modelo físico.
 	</string>
+	<string name="couldnt_resolve_host">
+		O DNS não pode resolver o nome do host([HOSTNAME]). 
+Verifique se você pode conectar ao site www.secondlife.com . Se você 
+puder, mas se continuar recebendo esta mensagem de erro, vá à sessão 
+Suporte no site Secondlife.com e informe o problema.
+	</string>
+	<string name="ssl_peer_certificate">
+		O servidor de acesso não pôde verificá-lo pelo SSL. 
+Se você continuar recebendo esta mensagem de erro, 
+vá à sessão Suporte no site Secondlife.com 
+e informe o problema.
+	</string>
+	<string name="ssl_connect_error">
+		Geralmente, esse erro significa que o relógio do seu computador não está com o horário correto. 
+Vá em Painel de Controles e certifique-se de que a hora e data estejam corretos. 
+Além disso, verifique se a sua rede e firewall estejam corretos. Se você continuar 
+recebendo esta mensagem de erro, vá à sessão Suporte no site Secondlife.com 
+e informe o problema. 
+
+[https://community.secondlife.com/knowledgebase/english/error-messages-r520/#Section__3 Base de conhecimento]
+	</string>
 </strings>
diff --git a/indra/newview/skins/default/xui/ru/notifications.xml b/indra/newview/skins/default/xui/ru/notifications.xml
index d752bf254e..d6866b6489 100644
--- a/indra/newview/skins/default/xui/ru/notifications.xml
+++ b/indra/newview/skins/default/xui/ru/notifications.xml
@@ -244,6 +244,10 @@
 		Примечание. После включения этой опции все пользователи данного компьютера смогут увидеть список ваших избранных мест.
 		<usetemplate name="okbutton" yestext="OK"/>
 	</notification>
+	<notification name="AllowMultipleViewers">
+		Запуск нескольких приложений Second Life Viewer не поддерживается. Это может привести к конфликтам кэша текстур, повреждению и снижению производительности и визуального отображения.
+		<usetemplate name="okbutton" yestext="ОК"/>
+	</notification>
 	<notification name="GrantModifyRights">
 		Предоставление другому жителю прав на изменение позволит ему изменять, удалять или брать ЛЮБЫЕ ваши объекты. Будьте ОЧЕНЬ осторожны с предоставлением такого разрешения.
 Дать пользователю [NAME] права на изменение?
@@ -717,9 +721,9 @@
 		Вам не разрешено терраформировать участок [PARCEL].
 	</notification>
 	<notification name="CannotCopyWarning">
-		У вас нет разрешения на копирование следующих предметов:
-[ITEMS]
-Если вы отдадите эти вещи, их больше не будет в вашем инвентаре. Вы действительно хотите предложить эти предметы?
+		У вас нет разрешения на копирование следующих предметов: 
+&lt;nolink&gt;[ITEMS]&lt;/nolink&gt; 
+и они пропадут из вашего инвентаря, если вы их отдадите. Вы действительно хотите предложить эти предметы?
 		<usetemplate name="okcancelbuttons" notext="Нет" yestext="Да"/>
 	</notification>
 	<notification name="CannotGiveItem">
@@ -3715,13 +3719,13 @@
 		Вы не можете создавать деревья и траву на чужой земле.
 	</notification>
 	<notification name="NoCopyPermsNoObject">
-		Не удалось скопировать: вам не разрешено копировать объект «[OBJ_NAME]».
+		Не удалось скопировать, потому что у вас нет разрешения на копирование этого предмета &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;.
 	</notification>
 	<notification name="NoTransPermsNoObject">
-		Не удалось скопировать: объект «[OBJ_NAME]» нельзя перенести к вам.
+		Не удалось скопировать, потому что предмет &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; не может быть перемещён к вам.
 	</notification>
 	<notification name="AddToNavMeshNoCopy">
-		Не удалось скопировать: объект «[OBJ_NAME]» относится к навигационной сетке.
+		Не удалось скопировать, потому что предмет &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; относится к навигационной сетке.
 	</notification>
 	<notification name="DupeWithNoRootsSelected">
 		Выбран дубликат без корневых объектов.
@@ -3766,34 +3770,34 @@
 		Сохранение в инвентаре отключено.
 	</notification>
 	<notification name="NoExistNoSaveToContents">
-		Нельзя сохранить «[OBJ_NAME]» в содержимом объекта: объект, из которого оно было выложено, уже не существует.
+		Не удалось сохранить &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; в содержимом предмета, потому что место, в котором был создан предмет, больше не существует.
 	</notification>
 	<notification name="NoModNoSaveToContents">
-		Нельзя сохранить «[OBJ_NAME]» в содержимом объекта: вам не разрешено изменять объект «[DEST_NAME]».
+		Не удалось сохранить &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; в содержимом предмета, потому что у вас нет разрешения на модификацию предмета &lt;nolink&gt;&apos;[DEST_NAME]&apos;&lt;/nolink&gt;.
 	</notification>
 	<notification name="NoSaveBackToInvDisabled">
-		Невозможно сохранить «[OBJ_NAME]» в инвентаре: эта операция запрещена.
+		Не удалось сохранить &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; обратно в инвентаре – эта операция заблокирована.
 	</notification>
 	<notification name="NoCopyNoSelCopy">
-		Нельзя скопировать выбранное: вам не разрешено копировать объект «[OBJ_NAME]».
+		Вы не можете скопировать выбор, потому что у вас нет разрешения на копирование этого предмета &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;.
 	</notification>
 	<notification name="NoTransNoSelCopy">
-		Невозможно скопировать выбранный предмет: объект «[OBJ_NAME]» не переносится.
+		Вы не можете скопировать свой выбор, потому что предмет &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; не может быть перемещён.
 	</notification>
 	<notification name="NoTransNoCopy">
-		Невозможно скопировать выбранный предмет: объект «[OBJ_NAME]» не переносится.
+		Вы не можете скопировать свой выбор, потому что предмет &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; не может быть перемещён.
 	</notification>
 	<notification name="NoPermsNoRemoval">
-		Удаление объекта «[OBJ_NAME]» из симулятора запрещено системой разрешений.
+		Удаление предмета &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; из симулятора не допущено системой прав доступа.
 	</notification>
 	<notification name="NoModNoSaveSelection">
-		Нельзя сохранить выбранное: вам не разрешено изменять объект «[OBJ_NAME]».
+		Копирование выбора невозможно, потому что у вас нет разрешения на модифицирование этого предмета &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;.
 	</notification>
 	<notification name="NoCopyNoSaveSelection">
-		Невозможно сохранить выбранный предмет: объект «[OBJ_NAME]» не копируется.
+		Вы не можете сохранить свой выбор, потому что предмет &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; не поддаётся копированию.
 	</notification>
 	<notification name="NoModNoTaking">
-		Нельзя забрать выбранное: вам не разрешено изменять объект «[OBJ_NAME]».
+		Вы не можете скопировать свой выбор, потому что у вас нет разрешения на модифицирование этого предмета &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;.
 	</notification>
 	<notification name="RezDestInternalError">
 		Внутренняя ошибка: неизвестный тип места назначения.
diff --git a/indra/newview/skins/default/xui/ru/strings.xml b/indra/newview/skins/default/xui/ru/strings.xml
index 267c717189..dcc503f18c 100644
--- a/indra/newview/skins/default/xui/ru/strings.xml
+++ b/indra/newview/skins/default/xui/ru/strings.xml
@@ -5747,4 +5747,25 @@ support@secondlife.com.
 	<string name="Mav_Details_MAV_UNKNOWN_VERSION">
 		У физической формы нет правильной версии. Задайте правильную версию для физической модели.
 	</string>
+	<string name="couldnt_resolve_host">
+		DNS не удалось разрешить имя узла([HOSTNAME]). 
+Проверьте возможность подключения к веб-сайту www.secondlife.com. 
+Если вы продолжаете получать эту ошибку, перейдите в раздел 
+поддержки и сообщите о проблеме.
+	</string>
+	<string name="ssl_peer_certificate">
+		Серверу входа в систему не удалось пройти аутентификацию с помощью 
+протокола SSL. Если вы продолжаете получать эту ошибку, 
+перейдите в раздел поддержки на веб-сайте SecondLife.com 
+и сообщите о проблеме.
+	</string>
+	<string name="ssl_connect_error">
+		Часто это означает, что часы компьютера установлены неправильно. 
+Перейдите, пожалуйста, на Панели управления и убедитесь в правильной 
+установке времени и даты. Также проверьте правильность настройки сети 
+и брандмауэра. Если вы продолжаете получать эту ошибку, перейдите в 
+раздел поддержки на веб-сайте SecondLife.com и сообщите о проблеме. 
+
+[https://community.secondlife.com/knowledgebase/english/error-messages-r520/#Section__3 База знаний]
+	</string>
 </strings>
diff --git a/indra/newview/skins/default/xui/tr/notifications.xml b/indra/newview/skins/default/xui/tr/notifications.xml
index d72d89f1f5..fce5bbfcab 100644
--- a/indra/newview/skins/default/xui/tr/notifications.xml
+++ b/indra/newview/skins/default/xui/tr/notifications.xml
@@ -244,6 +244,10 @@ Lütfen sadece bir nesne seçin ve tekrar deneyin.
 		Not: Bu seçeneği etkinleştirdiğinizde, bu bilgisayarı kullanan herkes en sevdiğiniz konumlar listenizi görebilecek.
 		<usetemplate name="okbutton" yestext="Tamam"/>
 	</notification>
+	<notification name="AllowMultipleViewers">
+		Birden çok Second Life görüntüleyiciyi çalıştırma özelliği desteklenmiyor. Bu durum doku önbelleği çakışmalarına, görsellerin bozulmasına ve performansın düşmesine yol açabilir.
+		<usetemplate name="okbutton" yestext="Tamam"/>
+	</notification>
 	<notification name="GrantModifyRights">
 		Başka bir Sakine değişiklik yapma hakkı verdiğinizde, SL dünyasında sahip olduğunuz HERHANGİ BİR nesneyi değiştirebilme, silebilme veya alabilmelerine izin vermiş olursunuz. Bu izni verirken ÇOK dikkatli olun.
 [NAME] adlı kişiye değişiklik yapma hakkı vermek istiyor musunuz?
@@ -718,9 +722,9 @@ Grafik Kalitesi, Tercihler &gt; Grafikler sekmesinden yükseltilebilir.
 		[PARCEL] parseli üzerinde yer şekillendirmesi yapma izniniz bulunmuyor.
 	</notification>
 	<notification name="CannotCopyWarning">
-		Aşağıdaki öğeleri kopyalamak için gerekli izne sahip değilsiniz:
-[ITEMS]
-Bu öğeleri verdiğiniz takdirde envanterinizden çıkacaklar. Bu öğeleri teklif etmeyi gerçekten istiyor musunuz?
+		Aşağıdaki öğeleri kopyalama izniniz yok: 
+&lt;nolink&gt;[ITEMS]&lt;/nolink&gt; 
+ve bunları elden çıkardığınız takdirde envanterinizden kaybolacaktır. Bu öğeleri sunmayı gerçekten istiyor musunuz?
 		<usetemplate name="okcancelbuttons" notext="Hayır" yestext="Evet"/>
 	</notification>
 	<notification name="CannotGiveItem">
@@ -3714,13 +3718,13 @@ Girişim iptal edildi.
 		Sahibi olmadığınız arazide ağaçlar ve çimen oluşturamazsınız.
 	</notification>
 	<notification name="NoCopyPermsNoObject">
-		&apos;[OBJ_NAME]&apos; nesnesini kopyalama izniniz olmadığı için kopyalama başarılamadı.
+		&lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; nesnesini kopyalama izniniz olmadığından kopyalama başarısız oldu.
 	</notification>
 	<notification name="NoTransPermsNoObject">
-		&apos;[OBJ_NAME]&apos; nesnesi size aktarılamadığı için kopyalama başarılamadı.
+		&lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; nesnesi size devredilemediğinden kopyalama başarısız oldu.
 	</notification>
 	<notification name="AddToNavMeshNoCopy">
-		&apos;[OBJ_NAME]&apos; nesnesi navmesh&apos;e katkıda bulunduğu için kopyalama başarılamadı.
+		&lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; nesnesi navigasyon örgüsüne katkıda bulunduğundan kopyalama başarısız oldu.
 	</notification>
 	<notification name="DupeWithNoRootsSelected">
 		Kök nesne seçili olmayan kopya.
@@ -3765,34 +3769,34 @@ Lütfen bir dakika sonra tekrar deneyin.
 		Envantere Geri Kaydet devre dışı bırakıldı.
 	</notification>
 	<notification name="NoExistNoSaveToContents">
-		&apos;[OBJ_NAME]&apos; nesne içeriğine kaydedilemedi, çünkü oluşturulurken temel alınan nesne artık mevcut değil.
+		Yeniden canlandırıldığı nesne artık mevcut olmadığından &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; nesne içeriklerine kaydedilemiyor.
 	</notification>
 	<notification name="NoModNoSaveToContents">
-		&apos;[DEST_NAME]&apos; nesnesini değiştirme izniniz olmadığı için &apos;[OBJ_NAME]&apos; nesne içeriğine kaydedilemedi.
+		&lt;nolink&gt;&apos;[DEST_NAME]&apos;&lt;/nolink&gt; nesnesini değiştirme izniniz olmadığından &lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; nesne içeriklerine kaydedilemiyor.
 	</notification>
 	<notification name="NoSaveBackToInvDisabled">
-		&apos;[OBJ_NAME]&apos; envantere geri kaydedilemez -- bu işlem devre dışı bırakıldı.
+		&lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; envantere tekrar kaydedilemiyor -- bu işlem devre dışı bırakılmış.
 	</notification>
 	<notification name="NoCopyNoSelCopy">
-		&apos;[OBJ_NAME]&apos; nesnesini kopyalama izniniz olmadığı için seçiminizi kopyalamayazsınız.
+		&lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; nesnesini kopyalama izniniz olmadığından seçiminizi kopyalayamazsınız.
 	</notification>
 	<notification name="NoTransNoSelCopy">
-		&apos;[OBJ_NAME]&apos; nesnesi aktarılamaz olduğu için seçiminizi kopyalayamazsınız.
+		&lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; nesnesi devredilebilir olmadığından seçiminizi kopyalayamazsınız.
 	</notification>
 	<notification name="NoTransNoCopy">
-		&apos;[OBJ_NAME]&apos; nesnesi aktarılamaz olduğu için seçiminizi kopyalayamazsınız.
+		&lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; nesnesi devredilebilir olmadığından seçiminizi kopyalayamazsınız.
 	</notification>
 	<notification name="NoPermsNoRemoval">
-		Benzeticiden &apos;[OBJ_NAME]&apos; nesnesinin kaldırılmasına izinler sistemi izin vermiyor.
+		&lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; nesnesinin simülatörden kaldırılmasına izin sistemi tarafından izin verilmiyor.
 	</notification>
 	<notification name="NoModNoSaveSelection">
-		&apos;[OBJ_NAME]&apos; nesnesini değiştirme izniniz olmadığı için seçiminizi kaydedemezsiniz.
+		&lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; nesnesini değiştirme izniniz olmadığından seçiminiz kaydedilemiyor.
 	</notification>
 	<notification name="NoCopyNoSaveSelection">
-		&apos;[OBJ_NAME]&apos; nesnesi kopyalanamaz olduğu için seçiminizi kaydedemezsiniz.
+		&lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; nesnesi kopyalanabilir olmadığından seçiminiz kaydedilemiyor.
 	</notification>
 	<notification name="NoModNoTaking">
-		&apos;[OBJ_NAME]&apos; nesnesini değiştirme izniniz olmadığı için seçiminizi alamazsınız.
+		&lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt; nesnesini değiştirme izniniz olmadığından seçiminizi alamazsınız.
 	</notification>
 	<notification name="RezDestInternalError">
 		Dahili Hata: Bilinmeyen hedef türü.
diff --git a/indra/newview/skins/default/xui/tr/strings.xml b/indra/newview/skins/default/xui/tr/strings.xml
index b574420793..ea6f2115e4 100644
--- a/indra/newview/skins/default/xui/tr/strings.xml
+++ b/indra/newview/skins/default/xui/tr/strings.xml
@@ -5748,4 +5748,25 @@ Düzenleyici yolunu çift tırnakla çevrelemeyi deneyin.
 	<string name="Mav_Details_MAV_UNKNOWN_VERSION">
 		Fiziksel şekil doğru sürüme sahip değil. Fiziksel model için doğru sürümü ayarlayın.
 	</string>
+	<string name="couldnt_resolve_host">
+		DNS sunucusu ana bilgisayar adını çözümleyemedi ([HOSTNAME]). 
+Lütfen www.secondlife.com web sitesine bağlanabildiğinizi doğrulayın. 
+Bağlanabiliyor, ancak bu hatayı almaya devam ediyorsanız, lütfen 
+destek bölümüne gidin ve bu sorunu bildirin.
+	</string>
+	<string name="ssl_peer_certificate">
+		Oturum açma sunucusu SSL aracılığıyla kendini doğrulayamadı. 
+Bu hatayı almaya devam ederseniz, lütfen 
+SecondLife.com web sitesinin Destek 
+bölümüne gidin ve sorunu bildirin.
+	</string>
+	<string name="ssl_connect_error">
+		Çoğunlukla, bu durum, bilgisayarınızın saatinin yanlış ayarlandığı anlamına gelir. 
+Lütfen Denetim Masası&apos;na gidin ve tarih ve saat ayarlarının doğru yapıldığından emin olun. 
+Ayrıca, ağınızın ve güvenlik duvarınızın doğru şekilde ayarlanıp ayarlanmadığını kontrol edin. 
+Bu hatayı almaya devam ederseniz, lütfen SecondLife.com web sitesinin Destek bölümüne 
+gidin ve sorunu bildirin. 
+
+[https://community.secondlife.com/knowledgebase/english/error-messages-r520/#Section__3 Bilgi Bankası]
+	</string>
 </strings>
diff --git a/indra/newview/skins/default/xui/zh/notifications.xml b/indra/newview/skins/default/xui/zh/notifications.xml
index 9fe7b5acae..120ed1e7d2 100644
--- a/indra/newview/skins/default/xui/zh/notifications.xml
+++ b/indra/newview/skins/default/xui/zh/notifications.xml
@@ -244,6 +244,10 @@
 		注意:你一旦同意這選項,任何使用這部電腦的人都可看到你有哪些「最愛」地點。
 		<usetemplate name="okbutton" yestext="確定"/>
 	</notification>
+	<notification name="AllowMultipleViewers">
+		不支援同時執行多個Second Life瀏覽器。 這麼做可能導致材質快取相互碰撞、毀損,並降低視覺效果及性能。
+		<usetemplate name="okbutton" yestext="確定"/>
+	</notification>
 	<notification name="GrantModifyRights">
 		賦予另一居民「修改」權,將允許他更改、刪除或拿取你在虛擬世界裡擁有的任何物件。 賦予這項權限時,敬請慎重考慮。
 你仍要賦予 [NAME] 修改權嗎?
@@ -719,7 +723,7 @@
 	</notification>
 	<notification name="CannotCopyWarning">
 		你沒有權限複製以下項目:
-[ITEMS]
+&lt;nolink&gt;[ITEMS]&lt;/nolink&gt;
 如果你將它送人,它將無法續留在收納區。 你確定要送出這些東西嗎?
 		<usetemplate name="okcancelbuttons" notext="否" yestext="是"/>
 	</notification>
@@ -3714,13 +3718,13 @@ SHA1 指紋:[MD5_DIGEST]
 		你無法在別人的土地上建立樹和草。
 	</notification>
 	<notification name="NoCopyPermsNoObject">
-		複製失敗,你無權複製物件 &apos;[OBJ_NAME]&apos;。
+		複製失敗,你無權複製物件&lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;。
 	</notification>
 	<notification name="NoTransPermsNoObject">
-		複製失敗,因為物件 &apos;[OBJ_NAME]&apos; 無法轉移給你。
+		複製失敗,因為物件&lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;無法轉移給你。
 	</notification>
 	<notification name="AddToNavMeshNoCopy">
-		複製失敗,因為物件 &apos;[OBJ_NAME]&apos; 對導航網面有貢獻。
+		複製失敗,因為物件&lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;對導航網面有貢獻。
 	</notification>
 	<notification name="DupeWithNoRootsSelected">
 		選取了沒有根的重覆物件。
@@ -3765,34 +3769,34 @@ SHA1 指紋:[MD5_DIGEST]
 		「儲存回收納區」功能已被停用。
 	</notification>
 	<notification name="NoExistNoSaveToContents">
-		無法將 &apos;[OBJ_NAME]&apos; 儲存到物件內容,因為產生它的來源物件已不存在。
+		無法將&lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;儲存到物件內容,因為產生它的來源物件已不存在。
 	</notification>
 	<notification name="NoModNoSaveToContents">
-		無法儲存 [OBJ_NAME] 到物件內容,你無權修改 &apos;[DEST_NAME]&apos; 物件。
+		無法儲存&lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;到物件內容,因爲你無權修改&lt;nolink&gt;&apos;[DEST_NAME]&apos;&lt;/nolink&gt;物件。
 	</notification>
 	<notification name="NoSaveBackToInvDisabled">
-		無法將 &apos;[OBJ_NAME]&apos; 儲存回收納區,此動作已被停用。
+		無法將&lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;儲存回收納區,此動作已被停用。
 	</notification>
 	<notification name="NoCopyNoSelCopy">
-		無法複製你所選的,因為你無權複製物件 &apos;[OBJ_NAME]&apos;。
+		無法複製你所選的,因為你無權複製物件&lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;。
 	</notification>
 	<notification name="NoTransNoSelCopy">
-		無法選取複製,因為物件 &apos;[OBJ_NAME]&apos; 不可轉移。
+		無法選取複製,因為物件&lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;不可轉移。
 	</notification>
 	<notification name="NoTransNoCopy">
-		無法選取複製,因為物件 &apos;[OBJ_NAME]&apos; 不可轉移。
+		無法選取複製,因為物件&lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;不可轉移。
 	</notification>
 	<notification name="NoPermsNoRemoval">
-		權限系統不允許從模擬器移除物件 &apos;[OBJ_NAME]&apos;。
+		權限系統不允許從模擬器移除物件&lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;。
 	</notification>
 	<notification name="NoModNoSaveSelection">
-		無法儲存你所選的,因為你無權修改 &apos;[OBJ_NAME]&apos; 物件。
+		無法儲存你所選的,因為你無權修改&lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;物件。
 	</notification>
 	<notification name="NoCopyNoSaveSelection">
-		無法儲存你所選的,因為物件 &apos;[OBJ_NAME]&apos; 不可複製。
+		無法儲存你所選的,因為物件&lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;不可複製。
 	</notification>
 	<notification name="NoModNoTaking">
-		無法拿取你所選的,因為你無權修改 &apos;[OBJ_NAME]&apos; 物件。
+		無法取用你所選的,因為你無權修改物件&lt;nolink&gt;&apos;[OBJ_NAME]&apos;&lt;/nolink&gt;。
 	</notification>
 	<notification name="RezDestInternalError">
 		內部錯誤:未知的目的地類型。
diff --git a/indra/newview/skins/default/xui/zh/strings.xml b/indra/newview/skins/default/xui/zh/strings.xml
index 24d8dc60cb..f8fd727145 100644
--- a/indra/newview/skins/default/xui/zh/strings.xml
+++ b/indra/newview/skins/default/xui/zh/strings.xml
@@ -5746,4 +5746,25 @@ http://secondlife.com/support 求助解決問題。
 	<string name="Mav_Details_MAV_UNKNOWN_VERSION">
 		物理形狀的版本不正確。 請設成正確的物理模型版本。
 	</string>
+	<string name="couldnt_resolve_host">
+		DNS無法解決主機名稱([HOSTNAME])。
+請確認你能夠連通 www.secondlife.com
+網站。  如能連通,但繼續看到這個錯誤,
+請到「支援」部分通報問題。
+	</string>
+	<string name="ssl_peer_certificate">
+		登入伺服器無法透過SSL自我確認。
+如果你繼續看到這個錯誤,請前往
+SecondLife.com網站的「支援」部分
+提報問題。
+	</string>
+	<string name="ssl_connect_error">
+		這通常意味你電腦的時鐘設定不正確。
+請到控制台確定時間和日期設定正確。
+並檢查確定你的網路和防火牆設定正確。
+如果你繼續看到這個錯誤,請前往SecondLife.com
+網站的「支援」部分提報問題。
+
+[https://community.secondlife.com/knowledgebase/english/error-messages-r520/#Section__3 知識庫]
+	</string>
 </strings>
-- 
cgit v1.2.3


From aa1d4c0dc9e1923d3233256b03c414cf1e9205fb Mon Sep 17 00:00:00 2001
From: eli <eli@lindenlab.com>
Date: Thu, 10 Jan 2019 16:53:31 -0800
Subject: FIX INTL-327 German misspellings

---
 .../newview/skins/default/xui/de/floater_pathfinding_console.xml  | 2 +-
 .../newview/skins/default/xui/de/floater_pathfinding_linksets.xml | 8 ++++----
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/indra/newview/skins/default/xui/de/floater_pathfinding_console.xml b/indra/newview/skins/default/xui/de/floater_pathfinding_console.xml
index 27c6b73967..2422e414e0 100644
--- a/indra/newview/skins/default/xui/de/floater_pathfinding_console.xml
+++ b/indra/newview/skins/default/xui/de/floater_pathfinding_console.xml
@@ -96,7 +96,7 @@
 			</combo_box>
 			<check_box label="Begehbare Objekte" name="show_walkables"/>
 			<check_box label="Materialvolumen" name="show_material_volumes"/>
-			<check_box label="Statische Hinternisse" name="show_static_obstacles"/>
+			<check_box label="Statische Hindernisse" name="show_static_obstacles"/>
 			<check_box label="Ausschlussvolumen" name="show_exclusion_volumes"/>
 			<check_box label="Wasserebene" name="show_water_plane"/>
 			<check_box label="Mit Röntgenblick" name="show_xray"/>
diff --git a/indra/newview/skins/default/xui/de/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/de/floater_pathfinding_linksets.xml
index a423f3efea..6729e242ac 100644
--- a/indra/newview/skins/default/xui/de/floater_pathfinding_linksets.xml
+++ b/indra/newview/skins/default/xui/de/floater_pathfinding_linksets.xml
@@ -61,10 +61,10 @@
 		Begehbar
 	</floater.string>
 	<floater.string name="linkset_use_static_obstacle">
-		Statisches Hinternis
+		Statisches Hindernis
 	</floater.string>
 	<floater.string name="linkset_use_dynamic_obstacle">
-		Bewegliches Hinternis
+		Bewegliches Hindernis
 	</floater.string>
 	<floater.string name="linkset_use_material_volume">
 		Materialvolumen
@@ -103,8 +103,8 @@
 		<combo_box name="filter_by_linkset_use">
 			<combo_box.item label="Nach Linkset-Nutzung filtern..." name="filter_by_linkset_use_none"/>
 			<combo_box.item label="Begehbar" name="filter_by_linkset_use_walkable"/>
-			<combo_box.item label="Statisches Hinternis" name="filter_by_linkset_use_static_obstacle"/>
-			<combo_box.item label="Bewegliches Hinternis" name="filter_by_linkset_use_dynamic_obstacle"/>
+			<combo_box.item label="Statisches Hindernis" name="filter_by_linkset_use_static_obstacle"/>
+			<combo_box.item label="Bewegliches Hindernis" name="filter_by_linkset_use_dynamic_obstacle"/>
 			<combo_box.item label="Materialvolumen" name="filter_by_linkset_use_material_volume"/>
 			<combo_box.item label="Ausschlussvolumen" name="filter_by_linkset_use_exclusion_volume"/>
 			<combo_box.item label="Bewegliches Phantom" name="filter_by_linkset_use_dynamic_phantom"/>
-- 
cgit v1.2.3


From 9c8584a3a7562810c83dd5e2d02e42e6d6870d96 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Fri, 11 Jan 2019 17:39:26 +0200
Subject: SL-10327 FIXED Scalable preview of mesh model is shown with black bar
 on top in the Upload Model menu

---
 indra/newview/app_settings/settings.xml               |  2 +-
 indra/newview/llfloatermodelpreview.cpp               | 19 +++++++++++++++++--
 .../skins/default/xui/en/floater_model_preview.xml    |  8 +++-----
 3 files changed, 21 insertions(+), 8 deletions(-)

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 72301e7d14..82087fbe5d 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -8053,7 +8053,7 @@
   <key>PreviewRenderSize</key>  
   <map>
     <key>Comment</key>
-    <string>Resolution of the image rendered for the mesh upload preview</string>
+    <string>Resolution of the image rendered for the mesh upload preview (must be a power of 2)</string>
     <key>Persist</key>
     <integer>1</integer>
     <key>Type</key>
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index c86eed2192..2cc42460a5 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -427,8 +427,23 @@ void LLFloaterModelPreview::initModelPreview()
 	{
 		delete mModelPreview;
 	}
-	auto size = gSavedSettings.getS32("PreviewRenderSize");
-	mModelPreview = new LLModelPreview(size, size, this );
+
+	S32 tex_width = 512;
+	S32 tex_height = 512;
+
+	S32 max_width = llmin(gSavedSettings.getS32("PreviewRenderSize"), (S32)gPipeline.mScreenWidth);
+	S32 max_height = llmin(gSavedSettings.getS32("PreviewRenderSize"), (S32)gPipeline.mScreenHeight);
+	
+	while ((tex_width << 1) <= max_width)
+	{
+		tex_width <<= 1;
+	}
+	while ((tex_height << 1) <= max_height)
+	{
+		tex_height <<= 1;
+	}
+
+	mModelPreview = new LLModelPreview(tex_width, tex_height, this);
 	mModelPreview->setPreviewTarget(16.f);
 	mModelPreview->setDetailsCallback(boost::bind(&LLFloaterModelPreview::setDetails, this, _1, _2, _3, _4, _5));
 	mModelPreview->setModelUpdatedCallback(boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this, _1));
diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml
index a07fe99aef..274e6e6c7a 100644
--- a/indra/newview/skins/default/xui/en/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml
@@ -1490,7 +1490,6 @@ Analysed:
     name="right_panel"
     top="0"
     left="640"
-    background_visible="true"
     width="375">
     <text
       follows="left|top"
@@ -1510,7 +1509,6 @@ Analysed:
       name="right_upper_panel"
       top="8"
       left="60"
-      background_visible="true"
       width="315">
       <combo_box
         top_pad="3"
@@ -1586,7 +1584,7 @@ Analysed:
       layout="topleft"
       left="2"
       name="physics_explode_label"
-      top="85"
+      bottom_pad="2"
       width="150">
       Preview Spread:
     </text>
@@ -1594,8 +1592,8 @@ Analysed:
       name="physics_explode"
       follows="right|bottom"
       valign="center"
-      top="15"
-      left="80"
+      left="105"
+      top_delta="-3"
       min_val="0.0"
       max_val="3.0"
       height="20"
-- 
cgit v1.2.3


From 127ed9c67809b5ad169fbc971e800c7744363c57 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Mon, 14 Jan 2019 13:50:28 +0200
Subject: SL-10352 FIXED 'Search menus' disappears after entering and exiting
 mouselook view

---
 indra/newview/app_settings/settings.xml | 11 +++++++++++
 indra/newview/llstatusbar.cpp           |  4 ++--
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 82087fbe5d..8f7c4601e8 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -11530,6 +11530,17 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+    <key>MenuSearch</key>
+    <map>
+      <key>Comment</key>
+      <string>Show/hide 'Search menus' field</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+  </map>
     <key>GroupListShowIcons</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp
index b893e4a058..f3c270a97b 100644
--- a/indra/newview/llstatusbar.cpp
+++ b/indra/newview/llstatusbar.cpp
@@ -247,11 +247,11 @@ BOOL LLStatusBar::postBuild()
 	mFilterEdit = getChild<LLSearchEditor>( "search_menu_edit" );
 	mSearchPanel = getChild<LLPanel>( "menu_search_panel" );
 
-	//mSearchPanel->setVisible(gSavedSettings.getBOOL("MenuSearch"));
+	mSearchPanel->setVisible(gSavedSettings.getBOOL("MenuSearch"));
 	mFilterEdit->setKeystrokeCallback(boost::bind(&LLStatusBar::onUpdateFilterTerm, this));
 	mFilterEdit->setCommitCallback(boost::bind(&LLStatusBar::onUpdateFilterTerm, this));
 	collectSearchableItems();
-	//gSavedSettings.getControl("MenuSearch")->getCommitSignal()->connect(boost::bind(&LLStatusBar::updateMenuSearchVisibility, this, _2));
+	gSavedSettings.getControl("MenuSearch")->getCommitSignal()->connect(boost::bind(&LLStatusBar::updateMenuSearchVisibility, this, _2));
 
 	return TRUE;
 }
-- 
cgit v1.2.3


From 26fae750ba753f32f58bd56d297f2d98c5759e50 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Mon, 14 Jan 2019 22:04:44 +0200
Subject: SL-10291 Replace apr_mutex with standard C++11 functionality

---
 doc/contributions.txt                          |   1 +
 indra/llcommon/llapr.cpp                       |  79 +------------
 indra/llcommon/llapr.h                         |  57 ++--------
 indra/llcommon/llerror.cpp                     | 148 ++++---------------------
 indra/llcommon/llfixedbuffer.cpp               |   2 +-
 indra/llcommon/llmutex.cpp                     | 130 +++++++++++++---------
 indra/llcommon/llmutex.h                       |  85 +++++++++-----
 indra/llcommon/llthread.cpp                    |   6 +-
 indra/llcommon/lluuid.cpp                      |   2 +-
 indra/llcommon/llworkerthread.cpp              |   4 +-
 indra/llcorehttp/httpcommon.cpp                |   4 +-
 indra/llimage/llimage.cpp                      |   2 +-
 indra/llimage/llimageworker.cpp                |   2 +-
 indra/llmath/llvolumemgr.cpp                   |   4 +-
 indra/llmessage/llbuffer.cpp                   |   2 +-
 indra/llmessage/llproxy.cpp                    |   2 +-
 indra/llplugin/llpluginmessagepipe.cpp         |   4 +-
 indra/llplugin/llpluginprocessparent.cpp       |   4 +-
 indra/llvfs/llvfs.cpp                          |   2 +-
 indra/newview/llappviewer.cpp                  |   2 +-
 indra/newview/lldirpicker.cpp                  |   2 +-
 indra/newview/llfloaterconversationpreview.cpp |   2 +-
 indra/newview/llfloatermodelpreview.cpp        |   4 +-
 indra/newview/lllogchat.cpp                    |   6 +-
 indra/newview/llmeshrepository.cpp             |  14 +--
 indra/newview/lltexturecache.cpp               |   8 +-
 indra/newview/lltexturefetch.cpp               |   6 +-
 indra/newview/llviewermenufile.cpp             |   2 +-
 indra/newview/llwatchdog.cpp                   |   4 +-
 29 files changed, 221 insertions(+), 369 deletions(-)

diff --git a/doc/contributions.txt b/doc/contributions.txt
index 66323a38c6..6146689fb0 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -1070,6 +1070,7 @@ Nicky Dasmijn
     STORM-2010
 	STORM-2082
 	MAINT-6665
+	SL-10291
 	SL-10293
 Nicky Perian
 	OPEN-1
diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp
index d353d06de2..29f0c7da9a 100644
--- a/indra/llcommon/llapr.cpp
+++ b/indra/llcommon/llapr.cpp
@@ -28,13 +28,12 @@
 
 #include "linden_common.h"
 #include "llapr.h"
+#include "llmutex.h"
 #include "apr_dso.h"
 #include "llthreadlocalstorage.h"
 
 apr_pool_t *gAPRPoolp = NULL; // Global APR memory pool
 LLVolatileAPRPool *LLAPRFile::sAPRFilePoolp = NULL ; //global volatile APR memory pool.
-apr_thread_mutex_t *gLogMutexp = NULL;
-apr_thread_mutex_t *gCallStacksLogMutexp = NULL;
 
 const S32 FULL_VOLATILE_APR_POOL = 1024 ; //number of references to LLVolatileAPRPool
 
@@ -48,10 +47,6 @@ void ll_init_apr()
 	if (!gAPRPoolp)
 	{
 		apr_pool_create(&gAPRPoolp, NULL);
-		
-		// Initialize the logging mutex
-		apr_thread_mutex_create(&gLogMutexp, APR_THREAD_MUTEX_UNNESTED, gAPRPoolp);
-		apr_thread_mutex_create(&gCallStacksLogMutexp, APR_THREAD_MUTEX_UNNESTED, gAPRPoolp);
 	}
 
 	if(!LLAPRFile::sAPRFilePoolp)
@@ -75,23 +70,6 @@ void ll_cleanup_apr()
 
 	LL_INFOS("APR") << "Cleaning up APR" << LL_ENDL;
 
-	if (gLogMutexp)
-	{
-		// Clean up the logging mutex
-
-		// All other threads NEED to be done before we clean up APR, so this is okay.
-		apr_thread_mutex_destroy(gLogMutexp);
-		gLogMutexp = NULL;
-	}
-	if (gCallStacksLogMutexp)
-	{
-		// Clean up the logging mutex
-
-		// All other threads NEED to be done before we clean up APR, so this is okay.
-		apr_thread_mutex_destroy(gCallStacksLogMutexp);
-		gCallStacksLogMutexp = NULL;
-	}
-
 	LLThreadLocalPointerBase::destroyAllThreadLocalStorage();
 
 	if (gAPRPoolp)
@@ -168,26 +146,19 @@ apr_pool_t* LLAPRPool::getAPRPool()
 LLVolatileAPRPool::LLVolatileAPRPool(BOOL is_local, apr_pool_t *parent, apr_size_t size, BOOL releasePoolFlag) 
 				  : LLAPRPool(parent, size, releasePoolFlag),
 				  mNumActiveRef(0),
-				  mNumTotalRef(0),
-				  mMutexPool(NULL),
-				  mMutexp(NULL)
+				  mNumTotalRef(0)
 {
 	//create mutex
 	if(!is_local) //not a local apr_pool, that is: shared by multiple threads.
 	{
-		apr_pool_create(&mMutexPool, NULL); // Create a pool for mutex
-		apr_thread_mutex_create(&mMutexp, APR_THREAD_MUTEX_UNNESTED, mMutexPool);
+		mMutexp.reset(new std::mutex());
 	}
 }
 
 LLVolatileAPRPool::~LLVolatileAPRPool()
 {
 	//delete mutex
-	if(mMutexp)
-	{
-		apr_thread_mutex_destroy(mMutexp);
-		apr_pool_destroy(mMutexPool);
-	}
+    mMutexp.reset();
 }
 
 //
@@ -201,7 +172,7 @@ apr_pool_t* LLVolatileAPRPool::getAPRPool()
 
 apr_pool_t* LLVolatileAPRPool::getVolatileAPRPool() 
 {	
-	LLScopedLock lock(mMutexp) ;
+	LLScopedLock lock(mMutexp.get()) ;
 
 	mNumTotalRef++ ;
 	mNumActiveRef++ ;
@@ -216,7 +187,7 @@ apr_pool_t* LLVolatileAPRPool::getVolatileAPRPool()
 
 void LLVolatileAPRPool::clearVolatileAPRPool() 
 {
-	LLScopedLock lock(mMutexp) ;
+    LLScopedLock lock(mMutexp.get());
 
 	if(mNumActiveRef > 0)
 	{
@@ -250,44 +221,6 @@ BOOL LLVolatileAPRPool::isFull()
 {
 	return mNumTotalRef > FULL_VOLATILE_APR_POOL ;
 }
-//---------------------------------------------------------------------
-//
-// LLScopedLock
-//
-LLScopedLock::LLScopedLock(apr_thread_mutex_t* mutex) : mMutex(mutex)
-{
-	if(mutex)
-	{
-		if(ll_apr_warn_status(apr_thread_mutex_lock(mMutex)))
-		{
-			mLocked = false;
-		}
-		else
-		{
-			mLocked = true;
-		}
-	}
-	else
-	{
-		mLocked = false;
-	}
-}
-
-LLScopedLock::~LLScopedLock()
-{
-	unlock();
-}
-
-void LLScopedLock::unlock()
-{
-	if(mLocked)
-	{
-		if(!ll_apr_warn_status(apr_thread_mutex_unlock(mMutex)))
-		{
-			mLocked = false;
-		}
-	}
-}
 
 //---------------------------------------------------------------------
 
diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h
index 1ac5c4e9b2..73d1d180ef 100644
--- a/indra/llcommon/llapr.h
+++ b/indra/llcommon/llapr.h
@@ -36,15 +36,23 @@
 #include <boost/noncopyable.hpp>
 #include "llwin32headerslean.h"
 #include "apr_thread_proc.h"
-#include "apr_thread_mutex.h"
 #include "apr_getopt.h"
 #include "apr_signal.h"
 #include "apr_atomic.h"
 
 #include "llstring.h"
 
-extern LL_COMMON_API apr_thread_mutex_t* gLogMutexp;
-extern apr_thread_mutex_t* gCallStacksLogMutexp;
+#if LL_WINDOWS
+#pragma warning (push)
+#pragma warning (disable:4265)
+#endif
+// warning C4265: 'std::_Pad' : class has virtual functions, but destructor is not virtual
+
+#include <mutex>
+
+#if LL_WINDOWS
+#pragma warning (pop)
+#endif
 
 struct apr_dso_handle_t;
 /**
@@ -120,50 +128,9 @@ private:
 	S32 mNumActiveRef ; //number of active pointers pointing to the apr_pool.
 	S32 mNumTotalRef ;  //number of total pointers pointing to the apr_pool since last creating.  
 
-	apr_thread_mutex_t *mMutexp;
-	apr_pool_t         *mMutexPool;
+	std::unique_ptr<std::mutex> mMutexp;
 } ;
 
-/** 
- * @class LLScopedLock
- * @brief Small class to help lock and unlock mutexes.
- *
- * This class is used to have a stack level lock once you already have
- * an apr mutex handy. The constructor handles the lock, and the
- * destructor handles the unlock. Instances of this class are
- * <b>not</b> thread safe.
- */
-class LL_COMMON_API LLScopedLock : private boost::noncopyable
-{
-public:
-	/**
-	 * @brief Constructor which accepts a mutex, and locks it.
-	 *
-	 * @param mutex An allocated APR mutex. If you pass in NULL,
-	 * this wrapper will not lock.
-	 */
-	LLScopedLock(apr_thread_mutex_t* mutex);
-
-	/**
-	 * @brief Destructor which unlocks the mutex if still locked.
-	 */
-	~LLScopedLock();
-
-	/** 
-	 * @brief Check lock.
-	 */
-	bool isLocked() const { return mLocked; }
-
-	/** 
-	 * @brief This method unlocks the mutex.
-	 */
-	void unlock();
-
-protected:
-	bool mLocked;
-	apr_thread_mutex_t* mMutex;
-};
-
 template <typename Type> class LLAtomic32
 {
 public:
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index 17d8164289..3db6705985 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -1096,6 +1096,9 @@ namespace
 }
 
 namespace {
+	LLMutex gLogMutex;
+	LLMutex gCallStacksLogMutex;
+
 	bool checkLevelMap(const LevelMap& map, const std::string& key,
 						LLError::ELevel& level)
 	{
@@ -1135,56 +1138,6 @@ namespace {
 		}
 		return found_level;
 	}
-	
-	class LogLock
-	{
-	public:
-		LogLock();
-		~LogLock();
-		bool ok() const { return mOK; }
-	private:
-		bool mLocked;
-		bool mOK;
-	};
-	
-	LogLock::LogLock()
-		: mLocked(false), mOK(false)
-	{
-		if (!gLogMutexp)
-		{
-			mOK = true;
-			return;
-		}
-		
-		const int MAX_RETRIES = 5;
-		for (int attempts = 0; attempts < MAX_RETRIES; ++attempts)
-		{
-			apr_status_t s = apr_thread_mutex_trylock(gLogMutexp);
-			if (!APR_STATUS_IS_EBUSY(s))
-			{
-				mLocked = true;
-				mOK = true;
-				return;
-			}
-
-			ms_sleep(1);
-			//apr_thread_yield();
-				// Just yielding won't necessarily work, I had problems with
-				// this on Linux - doug 12/02/04
-		}
-
-		// We're hosed, we can't get the mutex.  Blah.
-		std::cerr << "LogLock::LogLock: failed to get mutex for log"
-					<< std::endl;
-	}
-	
-	LogLock::~LogLock()
-	{
-		if (mLocked)
-		{
-			apr_thread_mutex_unlock(gLogMutexp);
-		}
-	}
 }
 
 namespace LLError
@@ -1192,8 +1145,8 @@ namespace LLError
 
 	bool Log::shouldLog(CallSite& site)
 	{
-		LogLock lock;
-		if (!lock.ok())
+		LLMutexTrylock lock(&gLogMutex, 5);
+		if (!lock.isLocked())
 		{
 			return false;
 		}
@@ -1243,11 +1196,11 @@ namespace LLError
 
 	std::ostringstream* Log::out()
 	{
-		LogLock lock;
+		LLMutexTrylock lock(&gLogMutex,5);
 		// If we hit a logging request very late during shutdown processing,
 		// when either of the relevant LLSingletons has already been deleted,
 		// DO NOT resurrect them.
-		if (lock.ok() && ! (Settings::wasDeleted() || Globals::wasDeleted()))
+		if (lock.isLocked() && ! (Settings::wasDeleted() || Globals::wasDeleted()))
 		{
 			Globals* g = Globals::getInstance();
 
@@ -1263,8 +1216,8 @@ namespace LLError
 
 	void Log::flush(std::ostringstream* out, char* message)
 	{
-		LogLock lock;
-		if (!lock.ok())
+		LLMutexTrylock lock(&gLogMutex,5);
+		if (!lock.isLocked())
 		{
 			return;
 		}
@@ -1303,8 +1256,8 @@ namespace LLError
 
 	void Log::flush(std::ostringstream* out, const CallSite& site)
 	{
-		LogLock lock;
-		if (!lock.ok())
+		LLMutexTrylock lock(&gLogMutex,5);
+		if (!lock.isLocked())
 		{
 			return;
 		}
@@ -1469,69 +1422,6 @@ namespace LLError
 	char** LLCallStacks::sBuffer = NULL ;
 	S32    LLCallStacks::sIndex  = 0 ;
 
-#define SINGLE_THREADED 1
-
-	class CallStacksLogLock
-	{
-	public:
-		CallStacksLogLock();
-		~CallStacksLogLock();
-
-#if SINGLE_THREADED
-		bool ok() const { return true; }
-#else
-		bool ok() const { return mOK; }
-	private:
-		bool mLocked;
-		bool mOK;
-#endif
-	};
-	
-#if SINGLE_THREADED
-	CallStacksLogLock::CallStacksLogLock()
-	{
-	}
-	CallStacksLogLock::~CallStacksLogLock()
-	{
-	}
-#else
-	CallStacksLogLock::CallStacksLogLock()
-		: mLocked(false), mOK(false)
-	{
-		if (!gCallStacksLogMutexp)
-		{
-			mOK = true;
-			return;
-		}
-		
-		const int MAX_RETRIES = 5;
-		for (int attempts = 0; attempts < MAX_RETRIES; ++attempts)
-		{
-			apr_status_t s = apr_thread_mutex_trylock(gCallStacksLogMutexp);
-			if (!APR_STATUS_IS_EBUSY(s))
-			{
-				mLocked = true;
-				mOK = true;
-				return;
-			}
-
-			ms_sleep(1);
-		}
-
-		// We're hosed, we can't get the mutex.  Blah.
-		std::cerr << "CallStacksLogLock::CallStacksLogLock: failed to get mutex for log"
-					<< std::endl;
-	}
-	
-	CallStacksLogLock::~CallStacksLogLock()
-	{
-		if (mLocked)
-		{
-			apr_thread_mutex_unlock(gCallStacksLogMutexp);
-		}
-	}
-#endif
-
 	//static
    void LLCallStacks::allocateStackBuffer()
    {
@@ -1560,8 +1450,8 @@ namespace LLError
    //static
    void LLCallStacks::push(const char* function, const int line)
    {
-	   CallStacksLogLock lock;
-       if (!lock.ok())
+       LLMutexTrylock lock(&gCallStacksLogMutex, 5);
+       if (!lock.isLocked())
        {
            return;
        }
@@ -1595,8 +1485,8 @@ namespace LLError
    //static
    void LLCallStacks::end(std::ostringstream* _out)
    {
-	   CallStacksLogLock lock;
-       if (!lock.ok())
+       LLMutexTrylock lock(&gCallStacksLogMutex, 5);
+       if (!lock.isLocked())
        {
            return;
        }
@@ -1617,8 +1507,8 @@ namespace LLError
    //static
    void LLCallStacks::print()
    {
-	   CallStacksLogLock lock;
-       if (!lock.ok())
+       LLMutexTrylock lock(&gCallStacksLogMutex, 5);
+       if (!lock.isLocked())
        {
            return;
        }
@@ -1655,8 +1545,8 @@ namespace LLError
 
 bool debugLoggingEnabled(const std::string& tag)
 {
-    LogLock lock;
-    if (!lock.ok())
+    LLMutexTrylock lock(&gLogMutex, 5);
+    if (!lock.isLocked())
     {
         return false;
     }
diff --git a/indra/llcommon/llfixedbuffer.cpp b/indra/llcommon/llfixedbuffer.cpp
index d394f179fb..bd4db8be84 100644
--- a/indra/llcommon/llfixedbuffer.cpp
+++ b/indra/llcommon/llfixedbuffer.cpp
@@ -31,7 +31,7 @@
 LLFixedBuffer::LLFixedBuffer(const U32 max_lines)
 	: LLLineBuffer(),
 	  mMaxLines(max_lines),
-	  mMutex(NULL)
+	  mMutex()
 {
 	mTimer.reset();
 }
diff --git a/indra/llcommon/llmutex.cpp b/indra/llcommon/llmutex.cpp
index 9c13ef9e30..cf84e50953 100644
--- a/indra/llcommon/llmutex.cpp
+++ b/indra/llcommon/llmutex.cpp
@@ -30,41 +30,19 @@
 
 #include "llmutex.h"
 #include "llthread.h"
+#include "lltimer.h"
 
 //============================================================================
 
-LLMutex::LLMutex(apr_pool_t *poolp) :
-	mAPRMutexp(NULL), mCount(0), mLockingThread(NO_THREAD)
+LLMutex::LLMutex() :
+ mCount(0),
+ mLockingThread(NO_THREAD)
 {
-	//if (poolp)
-	//{
-	//	mIsLocalPool = FALSE;
-	//	mAPRPoolp = poolp;
-	//}
-	//else
-	{
-		mIsLocalPool = TRUE;
-		apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread
-	}
-	apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mAPRPoolp);
 }
 
 
 LLMutex::~LLMutex()
 {
-#if MUTEX_DEBUG
-	//bad assertion, the subclass LLSignal might be "locked", and that's OK
-	//llassert_always(!isLocked()); // better not be locked!
-#endif
-	if (ll_apr_is_initialized())
-	{
-		apr_thread_mutex_destroy(mAPRMutexp);
-		if (mIsLocalPool)
-		{
-			apr_pool_destroy(mAPRPoolp);
-		}
-	}
-	mAPRMutexp = NULL;
 }
 
 
@@ -76,7 +54,7 @@ void LLMutex::lock()
 		return;
 	}
 	
-	apr_thread_mutex_lock(mAPRMutexp);
+	mMutex.lock();
 	
 #if MUTEX_DEBUG
 	// Have to have the lock before we can access the debug info
@@ -106,19 +84,18 @@ void LLMutex::unlock()
 #endif
 
 	mLockingThread = NO_THREAD;
-	apr_thread_mutex_unlock(mAPRMutexp);
+	mMutex.unlock();
 }
 
 bool LLMutex::isLocked()
 {
-	apr_status_t status = apr_thread_mutex_trylock(mAPRMutexp);
-	if (APR_STATUS_IS_EBUSY(status))
+	if (!mMutex.try_lock())
 	{
 		return true;
 	}
 	else
 	{
-		apr_thread_mutex_unlock(mAPRMutexp);
+		mMutex.unlock();
 		return false;
 	}
 }
@@ -141,8 +118,7 @@ bool LLMutex::trylock()
 		return true;
 	}
 	
-	apr_status_t status(apr_thread_mutex_trylock(mAPRMutexp));
-	if (APR_STATUS_IS_EBUSY(status))
+	if (!mMutex.try_lock())
 	{
 		return false;
 	}
@@ -161,45 +137,95 @@ bool LLMutex::trylock()
 
 //============================================================================
 
-LLCondition::LLCondition(apr_pool_t *poolp) :
-	LLMutex(poolp)
+LLCondition::LLCondition() :
+	LLMutex()
 {
-	// base class (LLMutex) has already ensured that mAPRPoolp is set up.
-
-	apr_thread_cond_create(&mAPRCondp, mAPRPoolp);
 }
 
 
 LLCondition::~LLCondition()
 {
-	apr_thread_cond_destroy(mAPRCondp);
-	mAPRCondp = NULL;
 }
 
 
 void LLCondition::wait()
 {
-	if (!isLocked())
-	{ //mAPRMutexp MUST be locked before calling apr_thread_cond_wait
-		apr_thread_mutex_lock(mAPRMutexp);
-#if MUTEX_DEBUG
-		// avoid asserts on destruction in non-release builds
-		U32 id = LLThread::currentID();
-		mIsLocked[id] = TRUE;
-#endif
-	}
-	apr_thread_cond_wait(mAPRCondp, mAPRMutexp);
+	std::unique_lock< std::mutex > lock(mMutex);
+	mCond.wait(lock);
 }
 
 void LLCondition::signal()
 {
-	apr_thread_cond_signal(mAPRCondp);
+	mCond.notify_one();
 }
 
 void LLCondition::broadcast()
 {
-	apr_thread_cond_broadcast(mAPRCondp);
+	mCond.notify_all();
 }
 
 
+
+LLMutexTrylock::LLMutexTrylock(LLMutex* mutex)
+    : mMutex(mutex),
+    mLocked(false)
+{
+    if (mMutex)
+        mLocked = mMutex->trylock();
+}
+
+LLMutexTrylock::LLMutexTrylock(LLMutex* mutex, U32 aTries, U32 delay_ms)
+    : mMutex(mutex),
+    mLocked(false)
+{
+    if (!mMutex)
+        return;
+
+    for (U32 i = 0; i < aTries; ++i)
+    {
+        mLocked = mMutex->trylock();
+        if (mLocked)
+            break;
+        ms_sleep(delay_ms);
+    }
+}
+
+LLMutexTrylock::~LLMutexTrylock()
+{
+    if (mMutex && mLocked)
+        mMutex->unlock();
+}
+
+
+//---------------------------------------------------------------------
+//
+// LLScopedLock
+//
+LLScopedLock::LLScopedLock(std::mutex* mutex) : mMutex(mutex)
+{
+	if(mutex)
+	{
+		mutex->lock();
+		mLocked = true;
+	}
+	else
+	{
+		mLocked = false;
+	}
+}
+
+LLScopedLock::~LLScopedLock()
+{
+	unlock();
+}
+
+void LLScopedLock::unlock()
+{
+	if(mLocked)
+	{
+		mMutex->unlock();
+		mLocked = false;
+	}
+}
+
 //============================================================================
diff --git a/indra/llcommon/llmutex.h b/indra/llcommon/llmutex.h
index ea535cee86..f841d7f950 100644
--- a/indra/llcommon/llmutex.h
+++ b/indra/llcommon/llmutex.h
@@ -28,6 +28,19 @@
 #define LL_LLMUTEX_H
 
 #include "stdtypes.h"
+#include <boost/noncopyable.hpp>
+
+#if LL_WINDOWS
+#pragma warning (push)
+#pragma warning (disable:4265)
+#endif
+// 'std::_Pad' : class has virtual functions, but destructor is not virtual
+#include <mutex>
+#include <condition_variable>
+
+#if LL_WINDOWS
+#pragma warning (pop)
+#endif
 
 //============================================================================
 
@@ -37,10 +50,6 @@
 #include <map>
 #endif
 
-struct apr_thread_mutex_t;
-struct apr_pool_t;
-struct apr_thread_cond_t;
-
 class LL_COMMON_API LLMutex
 {
 public:
@@ -49,7 +58,7 @@ public:
 		NO_THREAD = 0xFFFFFFFF
 	} e_locking_thread;
 
-	LLMutex(apr_pool_t *apr_poolp = NULL); // NULL pool constructs a new pool for the mutex
+	LLMutex();
 	virtual ~LLMutex();
 	
 	void lock();		// blocks
@@ -60,13 +69,10 @@ public:
 	U32 lockingThread() const; //get ID of locking thread
 	
 protected:
-	apr_thread_mutex_t *mAPRMutexp;
+	std::mutex			mMutex;
 	mutable U32			mCount;
 	mutable U32			mLockingThread;
 	
-	apr_pool_t			*mAPRPoolp;
-	BOOL				mIsLocalPool;
-	
 #if MUTEX_DEBUG
 	std::map<U32, BOOL> mIsLocked;
 #endif
@@ -76,7 +82,7 @@ protected:
 class LL_COMMON_API LLCondition : public LLMutex
 {
 public:
-	LLCondition(apr_pool_t* apr_poolp); // Defaults to global pool, could use the thread pool as well.
+	LLCondition();
 	~LLCondition();
 	
 	void wait();		// blocks
@@ -84,7 +90,7 @@ public:
 	void broadcast();
 	
 protected:
-	apr_thread_cond_t* mAPRCondp;
+	std::condition_variable mCond;
 };
 
 class LLMutexLock
@@ -119,19 +125,9 @@ private:
 class LLMutexTrylock
 {
 public:
-	LLMutexTrylock(LLMutex* mutex)
-		: mMutex(mutex),
-		  mLocked(false)
-	{
-		if (mMutex)
-			mLocked = mMutex->trylock();
-	}
-
-	~LLMutexTrylock()
-	{
-		if (mMutex && mLocked)
-			mMutex->unlock();
-	}
+	LLMutexTrylock(LLMutex* mutex);
+	LLMutexTrylock(LLMutex* mutex, U32 aTries, U32 delay_ms = 10);
+	~LLMutexTrylock();
 
 	bool isLocked() const
 	{
@@ -142,4 +138,43 @@ private:
 	LLMutex*	mMutex;
 	bool		mLocked;
 };
-#endif // LL_LLTHREAD_H
+
+/**
+* @class LLScopedLock
+* @brief Small class to help lock and unlock mutexes.
+*
+* The constructor handles the lock, and the destructor handles
+* the unlock. Instances of this class are <b>not</b> thread safe.
+*/
+class LL_COMMON_API LLScopedLock : private boost::noncopyable
+{
+public:
+    /**
+    * @brief Constructor which accepts a mutex, and locks it.
+    *
+    * @param mutex An allocated mutex. If you pass in NULL,
+    * this wrapper will not lock.
+    */
+    LLScopedLock(std::mutex* mutex);
+
+    /**
+    * @brief Destructor which unlocks the mutex if still locked.
+    */
+    ~LLScopedLock();
+
+    /**
+    * @brief Check lock.
+    */
+    bool isLocked() const { return mLocked; }
+
+    /**
+    * @brief This method unlocks the mutex.
+    */
+    void unlock();
+
+protected:
+    bool mLocked;
+    std::mutex* mMutex;
+};
+
+#endif // LL_LLMUTEX_H
diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index f066e9a4cd..860415bb22 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -186,8 +186,8 @@ LLThread::LLThread(const std::string& name, apr_pool_t *poolp) :
         mIsLocalPool = TRUE;
         apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread
     }
-    mRunCondition = new LLCondition(mAPRPoolp);
-    mDataLock = new LLMutex(mAPRPoolp);
+    mRunCondition = new LLCondition();
+    mDataLock = new LLMutex();
     mLocalAPRFilePoolp = NULL ;
 }
 
@@ -413,7 +413,7 @@ void LLThreadSafeRefCount::initThreadSafeRefCount()
 {
     if (!sMutex)
     {
-        sMutex = new LLMutex(0);
+        sMutex = new LLMutex();
     }
 }
 
diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp
index d4af2c6b01..8f33d789eb 100644
--- a/indra/llcommon/lluuid.cpp
+++ b/indra/llcommon/lluuid.cpp
@@ -738,7 +738,7 @@ void LLUUID::getCurrentTime(uuid_time_t *timestamp)
       getSystemTime(&time_last);
       uuids_this_tick = uuids_per_tick;
       init = TRUE;
-	  mMutex = new LLMutex(NULL);
+	  mMutex = new LLMutex();
    }
 
    uuid_time_t time_now = {0,0};
diff --git a/indra/llcommon/llworkerthread.cpp b/indra/llcommon/llworkerthread.cpp
index 4c197dc1d6..4b91b2caca 100644
--- a/indra/llcommon/llworkerthread.cpp
+++ b/indra/llcommon/llworkerthread.cpp
@@ -37,7 +37,7 @@
 LLWorkerThread::LLWorkerThread(const std::string& name, bool threaded, bool should_pause) :
 	LLQueuedThread(name, threaded, should_pause)
 {
-	mDeleteMutex = new LLMutex(NULL);
+	mDeleteMutex = new LLMutex();
 
 	if(!mLocalAPRFilePoolp)
 	{
@@ -204,7 +204,7 @@ LLWorkerClass::LLWorkerClass(LLWorkerThread* workerthread, const std::string& na
 	  mWorkerClassName(name),
 	  mRequestHandle(LLWorkerThread::nullHandle()),
 	  mRequestPriority(LLWorkerThread::PRIORITY_NORMAL),
-	  mMutex(NULL),
+	  mMutex(),
 	  mWorkFlags(0)
 {
 	if (!mWorkerThread)
diff --git a/indra/llcorehttp/httpcommon.cpp b/indra/llcorehttp/httpcommon.cpp
index 1829062af6..7c93c54cdf 100644
--- a/indra/llcorehttp/httpcommon.cpp
+++ b/indra/llcorehttp/httpcommon.cpp
@@ -333,7 +333,7 @@ LLMutex *getCurlMutex()
 
     if (!sHandleMutexp)
     {
-        sHandleMutexp = new LLMutex(NULL);
+        sHandleMutexp = new LLMutex();
     }
 
     return sHandleMutexp;
@@ -389,7 +389,7 @@ void initialize()
     S32 mutex_count = CRYPTO_num_locks();
     for (S32 i = 0; i < mutex_count; i++)
     {
-        sSSLMutex.push_back(LLMutex_ptr(new LLMutex(NULL)));
+        sSSLMutex.push_back(LLMutex_ptr(new LLMutex()));
     }
     CRYPTO_set_id_callback(&ssl_thread_id);
     CRYPTO_set_locking_callback(&ssl_locking_callback);
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 1a4dd2ca99..680fbf548f 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -594,7 +594,7 @@ void LLImage::initClass(bool use_new_byte_range, S32 minimal_reverse_byte_range_
 {
 	sUseNewByteRange = use_new_byte_range;
     sMinimalReverseByteRangePercent = minimal_reverse_byte_range_percent;
-	sMutex = new LLMutex(NULL);
+	sMutex = new LLMutex();
 }
 
 //static
diff --git a/indra/llimage/llimageworker.cpp b/indra/llimage/llimageworker.cpp
index 4875fe7001..5f42fba866 100644
--- a/indra/llimage/llimageworker.cpp
+++ b/indra/llimage/llimageworker.cpp
@@ -35,7 +35,7 @@
 LLImageDecodeThread::LLImageDecodeThread(bool threaded)
 	: LLQueuedThread("imagedecode", threaded)
 {
-	mCreationMutex = new LLMutex(getAPRPool());
+	mCreationMutex = new LLMutex();
 }
 
 //virtual 
diff --git a/indra/llmath/llvolumemgr.cpp b/indra/llmath/llvolumemgr.cpp
index 3b8f08e0c6..89cdb1c6b9 100644
--- a/indra/llmath/llvolumemgr.cpp
+++ b/indra/llmath/llvolumemgr.cpp
@@ -48,7 +48,7 @@ LLVolumeMgr::LLVolumeMgr()
 {
 	// the LLMutex magic interferes with easy unit testing,
 	// so you now must manually call useMutex() to use it
-	//mDataMutex = new LLMutex(gAPRPoolp);
+	//mDataMutex = new LLMutex();
 }
 
 LLVolumeMgr::~LLVolumeMgr()
@@ -214,7 +214,7 @@ void LLVolumeMgr::useMutex()
 { 
 	if (!mDataMutex)
 	{
-		mDataMutex = new LLMutex(gAPRPoolp);
+		mDataMutex = new LLMutex();
 	}
 }
 
diff --git a/indra/llmessage/llbuffer.cpp b/indra/llmessage/llbuffer.cpp
index d07d9980c3..1a0eceba0f 100644
--- a/indra/llmessage/llbuffer.cpp
+++ b/indra/llmessage/llbuffer.cpp
@@ -265,7 +265,7 @@ void LLBufferArray::setThreaded(bool threaded)
 	{
 		if(!mMutexp)
 		{
-			mMutexp = new LLMutex(NULL);
+			mMutexp = new LLMutex();
 		}
 	}
 	else
diff --git a/indra/llmessage/llproxy.cpp b/indra/llmessage/llproxy.cpp
index 537efa69d8..5730a36267 100644
--- a/indra/llmessage/llproxy.cpp
+++ b/indra/llmessage/llproxy.cpp
@@ -48,7 +48,7 @@ static void tcp_close_channel(LLSocket::ptr_t* handle_ptr); // Close an open TCP
 
 LLProxy::LLProxy():
 		mHTTPProxyEnabled(false),
-		mProxyMutex(NULL),
+		mProxyMutex(),
 		mUDPProxy(),
 		mTCPProxy(),
 		mHTTPProxy(),
diff --git a/indra/llplugin/llpluginmessagepipe.cpp b/indra/llplugin/llpluginmessagepipe.cpp
index 9468696507..9766e1bfed 100644
--- a/indra/llplugin/llpluginmessagepipe.cpp
+++ b/indra/llplugin/llpluginmessagepipe.cpp
@@ -92,8 +92,8 @@ void LLPluginMessagePipeOwner::killMessagePipe(void)
 }
 
 LLPluginMessagePipe::LLPluginMessagePipe(LLPluginMessagePipeOwner *owner, LLSocket::ptr_t socket):
-	mInputMutex(gAPRPoolp),
-	mOutputMutex(gAPRPoolp),
+	mInputMutex(),
+	mOutputMutex(),
 	mOutputStartIndex(0),
 	mOwner(owner),
 	mSocket(socket)
diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp
index 0a8e58ac90..eb6cb1b503 100644
--- a/indra/llplugin/llpluginprocessparent.cpp
+++ b/indra/llplugin/llpluginprocessparent.cpp
@@ -80,11 +80,11 @@ protected:
 };
 
 LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner):
-	mIncomingQueueMutex(gAPRPoolp)
+	mIncomingQueueMutex()
 {
 	if(!sInstancesMutex)
 	{
-		sInstancesMutex = new LLMutex(gAPRPoolp);
+		sInstancesMutex = new LLMutex();
 	}
 	
 	mOwner = owner;
diff --git a/indra/llvfs/llvfs.cpp b/indra/llvfs/llvfs.cpp
index d5bd1834c2..617056d94d 100644
--- a/indra/llvfs/llvfs.cpp
+++ b/indra/llvfs/llvfs.cpp
@@ -234,7 +234,7 @@ LLVFS::LLVFS(const std::string& index_filename, const std::string& data_filename
 	mDataFP(NULL),
 	mIndexFP(NULL)
 {
-	mDataMutex = new LLMutex(0);
+	mDataMutex = new LLMutex();
 
 	S32 i;
 	for (i = 0; i < VFSLOCK_COUNT; i++)
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 7c79cc7ddf..f8fa06b527 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -2148,7 +2148,7 @@ bool LLAppViewer::initThreads()
 
 	if (LLTrace::BlockTimer::sLog || LLTrace::BlockTimer::sMetricLog)
 	{
-		LLTrace::BlockTimer::setLogLock(new LLMutex(NULL));
+		LLTrace::BlockTimer::setLogLock(new LLMutex());
 		mFastTimerLogThread = new LLFastTimerLogThread(LLTrace::BlockTimer::sLogName);
 		mFastTimerLogThread->start();
 	}
diff --git a/indra/newview/lldirpicker.cpp b/indra/newview/lldirpicker.cpp
index 5443afe60c..b8e6e81ee6 100644
--- a/indra/newview/lldirpicker.cpp
+++ b/indra/newview/lldirpicker.cpp
@@ -315,7 +315,7 @@ void LLDirPickerThread::run()
 //static
 void LLDirPickerThread::initClass()
 {
-	sMutex = new LLMutex(NULL);
+	sMutex = new LLMutex();
 }
 
 //static
diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp
index b48ecc8f31..66198b3bf6 100644
--- a/indra/newview/llfloaterconversationpreview.cpp
+++ b/indra/newview/llfloaterconversationpreview.cpp
@@ -46,7 +46,7 @@ LLFloaterConversationPreview::LLFloaterConversationPreview(const LLSD& session_i
 	mPageSize(gSavedSettings.getS32("ConversationHistoryPageSize")),
 	mAccountName(session_id[LL_FCP_ACCOUNT_NAME]),
 	mCompleteName(session_id[LL_FCP_COMPLETE_NAME]),
-	mMutex(NULL),
+	mMutex(),
 	mShowHistory(false),
 	mMessages(NULL),
 	mHistoryThreadsBusy(false),
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 2cc42460a5..616bee84fd 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -266,7 +266,7 @@ mCalculateBtn(NULL)
 	sInstance = this;
 	mLastMouseX = 0;
 	mLastMouseY = 0;
-	mStatusLock = new LLMutex(NULL);
+	mStatusLock = new LLMutex();
 	mModelPreview = NULL;
 
 	mLODMode[LLModel::LOD_HIGH] = 0;
@@ -1265,7 +1265,7 @@ void LLFloaterModelPreview::onMouseCaptureLostModelPreview(LLMouseHandler* handl
 //-----------------------------------------------------------------------------
 
 LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp)
-: LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE), LLMutex(NULL)
+: LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE), LLMutex()
 , mLodsQuery()
 , mLodsWithParsingError()
 , mPelvisZOffset( 0.0f )
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index c535fc1cdf..c9889667b4 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -516,7 +516,7 @@ LLMutex* LLLogChat::historyThreadsMutex()
 {
 	if (sHistoryThreadsMutex == NULL)
 	{
-		sHistoryThreadsMutex = new LLMutex(NULL);
+		sHistoryThreadsMutex = new LLMutex();
 	}
 	return sHistoryThreadsMutex;
 }
@@ -1012,8 +1012,8 @@ void LLDeleteHistoryThread::run()
 
 LLActionThread::LLActionThread(const std::string& name)
 	: LLThread(name),
-	mMutex(NULL),
-	mRunCondition(NULL),
+	mMutex(),
+	mRunCondition(),
 	mFinished(false)
 {
 }
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index f32dad7f55..a6002bd57f 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -830,9 +830,9 @@ LLMeshRepoThread::LLMeshRepoThread()
 {
 	LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp());
 
-	mMutex = new LLMutex(NULL);
-	mHeaderMutex = new LLMutex(NULL);
-	mSignal = new LLCondition(NULL);
+	mMutex = new LLMutex();
+	mHeaderMutex = new LLMutex();
+	mSignal = new LLCondition();
 	mHttpRequest = new LLCore::HttpRequest;
 	mHttpOptions = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions);
 	mHttpOptions->setTransferTimeout(SMALL_MESH_XFER_TIMEOUT);
@@ -2039,7 +2039,7 @@ LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data,
 	mUploadSkin = upload_skin;
 	mUploadJoints = upload_joints;
     mLockScaleIfJointPosition = lock_scale_if_joint_position;
-	mMutex = new LLMutex(NULL);
+	mMutex = new LLMutex();
 	mPendingUploads = 0;
 	mFinished = false;
 	mOrigin = gAgent.getPositionAgent();
@@ -3446,7 +3446,7 @@ LLMeshRepository::LLMeshRepository()
 
 void LLMeshRepository::init()
 {
-	mMeshMutex = new LLMutex(NULL);
+	mMeshMutex = new LLMutex();
 	
 	LLConvexDecomposition::getInstance()->initSystem();
 
@@ -4588,8 +4588,8 @@ LLPhysicsDecomp::LLPhysicsDecomp()
 	mQuitting = false;
 	mDone = false;
 
-	mSignal = new LLCondition(NULL);
-	mMutex = new LLMutex(NULL);
+	mSignal = new LLCondition();
+	mMutex = new LLMutex();
 }
 
 LLPhysicsDecomp::~LLPhysicsDecomp()
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index eb4b914e18..e5af47ab6c 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -825,10 +825,10 @@ void LLTextureCacheWorker::endWork(S32 param, bool aborted)
 
 LLTextureCache::LLTextureCache(bool threaded)
 	: LLWorkerThread("TextureCache", threaded),
-	  mWorkersMutex(NULL),
-	  mHeaderMutex(NULL),
-	  mListMutex(NULL),
-	  mFastCacheMutex(NULL),
+	  mWorkersMutex(),
+	  mHeaderMutex(),
+	  mListMutex(),
+	  mFastCacheMutex(),
 	  mHeaderAPRFile(NULL),
 	  mReadOnly(TRUE), //do not allow to change the texture cache until setReadOnly() is called.
 	  mTexturesSizeTotal(0),
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index 1f69939c46..ca401f5c17 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -925,7 +925,7 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
 	  mCanUseHTTP(true),
 	  mRetryAttempt(0),
 	  mActiveCount(0),
-	  mWorkMutex(NULL),
+	  mWorkMutex(),
 	  mFirstPacket(0),
 	  mLastPacket(-1),
 	  mTotalPackets(0),
@@ -2543,8 +2543,8 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
 	  mDebugPause(FALSE),
 	  mPacketCount(0),
 	  mBadPacketCount(0),
-	  mQueueMutex(getAPRPool()),
-	  mNetworkQueueMutex(getAPRPool()),
+	  mQueueMutex(),
+	  mNetworkQueueMutex(),
 	  mTextureCache(cache),
 	  mImageDecodeThread(imagedecodethread),
 	  mTextureBandwidth(0),
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index d2a5578568..a9a91b158b 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -175,7 +175,7 @@ void LLFilePickerThread::run()
 //static
 void LLFilePickerThread::initClass()
 {
-	sMutex = new LLMutex(NULL);
+	sMutex = new LLMutex();
 }
 
 //static
diff --git a/indra/newview/llwatchdog.cpp b/indra/newview/llwatchdog.cpp
index 2782cd9545..dd6c77ca7d 100644
--- a/indra/newview/llwatchdog.cpp
+++ b/indra/newview/llwatchdog.cpp
@@ -155,7 +155,7 @@ void LLWatchdogTimeout::ping(const std::string& state)
 
 // LLWatchdog
 LLWatchdog::LLWatchdog() :
-	mSuspectsAccessMutex(NULL),
+	mSuspectsAccessMutex(),
 	mTimer(NULL),
 	mLastClockCount(0),
 	mKillerCallback(&default_killer_callback)
@@ -185,7 +185,7 @@ void LLWatchdog::init(killer_event_callback func)
 	mKillerCallback = func;
 	if(!mSuspectsAccessMutex && !mTimer)
 	{
-		mSuspectsAccessMutex = new LLMutex(NULL);
+		mSuspectsAccessMutex = new LLMutex();
 		mTimer = new LLWatchdogTimerThread();
 		mTimer->setSleepTime(WATCHDOG_SLEEP_TIME_USEC / 1000);
 		mLastClockCount = LLTimer::getTotalTime();
-- 
cgit v1.2.3


From 346fc435f1b12e47b8bf51d15c70ceca4615de41 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Thu, 17 Jan 2019 01:53:27 +0200
Subject: SL-10291 cleanup-mutex

---
 indra/llcommon/llrefcount.cpp  | 109 -----------------------------------------
 indra/llcommon/llrefcount.h    |  18 +------
 indra/llmessage/llpumpio.cpp   |  54 --------------------
 indra/llmessage/llpumpio.h     |  11 -----
 indra/llvfs/lllfsthread.h      |   1 -
 indra/llvfs/llvfsthread.h      |   2 -
 indra/newview/lltexturefetch.h |   1 -
 7 files changed, 1 insertion(+), 195 deletions(-)

diff --git a/indra/llcommon/llrefcount.cpp b/indra/llcommon/llrefcount.cpp
index a638df2c7c..29a5ca6f24 100644
--- a/indra/llcommon/llrefcount.cpp
+++ b/indra/llcommon/llrefcount.cpp
@@ -29,25 +29,9 @@
 
 #include "llerror.h"
 
-#if LL_REF_COUNT_DEBUG
-#include "llthread.h"
-#include "llapr.h"
-#endif
-
 LLRefCount::LLRefCount(const LLRefCount& other)
 :	mRef(0)
 {
-#if LL_REF_COUNT_DEBUG
-	if(gAPRPoolp)
-	{
-		mMutexp = new LLMutex(gAPRPoolp) ;
-	}
-	else
-	{
-		mMutexp = NULL ;
-	}
-	mCrashAtUnlock = FALSE ;
-#endif
 }
 
 LLRefCount& LLRefCount::operator=(const LLRefCount&)
@@ -59,17 +43,6 @@ LLRefCount& LLRefCount::operator=(const LLRefCount&)
 LLRefCount::LLRefCount() :
 	mRef(0)
 {
-#if LL_REF_COUNT_DEBUG
-	if(gAPRPoolp)
-	{
-		mMutexp = new LLMutex(gAPRPoolp) ;
-	}
-	else
-	{
-		mMutexp = NULL ;
-	}
-	mCrashAtUnlock = FALSE ;
-#endif
 }
 
 LLRefCount::~LLRefCount()
@@ -78,87 +51,5 @@ LLRefCount::~LLRefCount()
 	{
 		LL_ERRS() << "deleting non-zero reference" << LL_ENDL;
 	}
-
-#if LL_REF_COUNT_DEBUG
-	if(gAPRPoolp)
-	{
-		delete mMutexp ;
-	}
-#endif
 }
 
-#if LL_REF_COUNT_DEBUG
-void LLRefCount::ref() const
-{ 
-	if(mMutexp)
-	{
-		if(mMutexp->isLocked()) 
-		{
-			mCrashAtUnlock = TRUE ;
-			LL_ERRS() << "the mutex is locked by the thread: " << mLockedThreadID 
-				<< " Current thread: " << LLThread::currentID() << LL_ENDL ;
-		}
-
-		mMutexp->lock() ;
-		mLockedThreadID = LLThread::currentID() ;
-
-		mRef++; 
-
-		if(mCrashAtUnlock)
-		{
-			while(1); //crash here.
-		}
-		mMutexp->unlock() ;
-	}
-	else
-	{
-		mRef++; 
-	}
-} 
-
-S32 LLRefCount::unref() const
-{
-	if(mMutexp)
-	{
-		if(mMutexp->isLocked()) 
-		{
-			mCrashAtUnlock = TRUE ;
-			LL_ERRS() << "the mutex is locked by the thread: " << mLockedThreadID 
-				<< " Current thread: " << LLThread::currentID() << LL_ENDL ;
-		}
-
-		mMutexp->lock() ;
-		mLockedThreadID = LLThread::currentID() ;
-		
-		llassert(mRef >= 1);
-		if (0 == --mRef) 
-		{
-			if(mCrashAtUnlock)
-			{
-				while(1); //crash here.
-			}
-			mMutexp->unlock() ;
-
-			delete this; 
-			return 0;
-		}
-
-		if(mCrashAtUnlock)
-		{
-			while(1); //crash here.
-		}
-		mMutexp->unlock() ;
-		return mRef;
-	}
-	else
-	{
-		llassert(mRef >= 1);
-		if (0 == --mRef) 
-		{
-			delete this; 
-			return 0;
-		}
-		return mRef;
-	}
-}	
-#endif
diff --git a/indra/llcommon/llrefcount.h b/indra/llcommon/llrefcount.h
index 1107973569..cdc60fa54f 100644
--- a/indra/llcommon/llrefcount.h
+++ b/indra/llcommon/llrefcount.h
@@ -31,11 +31,6 @@
 #include "llmutex.h"
 #include "llapr.h"
 
-#define LL_REF_COUNT_DEBUG 0
-#if LL_REF_COUNT_DEBUG
-class LLMutex ;
-#endif
-
 //----------------------------------------------------------------------------
 // RefCount objects should generally only be accessed by way of LLPointer<>'s
 // see llthread.h for LLThreadSafeRefCount
@@ -51,10 +46,6 @@ protected:
 public:
 	LLRefCount();
 
-#if LL_REF_COUNT_DEBUG
-	void ref() const ;
-	S32 unref() const ;
-#else
 	inline void ref() const
 	{ 
 		mRef++; 
@@ -69,8 +60,7 @@ public:
 			return 0;
 		}
 		return mRef;
-	}	
-#endif
+	}
 
 	//NOTE: when passing around a const LLRefCount object, this can return different results
 	// at different types, since mRef is mutable
@@ -81,12 +71,6 @@ public:
 
 private: 
 	mutable S32	mRef; 
-
-#if LL_REF_COUNT_DEBUG
-	LLMutex*  mMutexp ;
-	mutable U32  mLockedThreadID ;
-	mutable BOOL mCrashAtUnlock ; 
-#endif
 };
 
 
diff --git a/indra/llmessage/llpumpio.cpp b/indra/llmessage/llpumpio.cpp
index 506ccc98a4..a2524e9804 100644
--- a/indra/llmessage/llpumpio.cpp
+++ b/indra/llmessage/llpumpio.cpp
@@ -54,11 +54,7 @@
 
 // constants for poll timeout. if we are threading, we want to have a
 // longer poll timeout.
-#if LL_THREADS_APR
-static const S32 DEFAULT_POLL_TIMEOUT = 1000;
-#else
 static const S32 DEFAULT_POLL_TIMEOUT = 0;
-#endif
 
 // The default (and fallback) expiration time for chains
 const F32 DEFAULT_CHAIN_EXPIRY_SECS = 30.0f;
@@ -169,8 +165,6 @@ LLPumpIO::LLPumpIO(apr_pool_t* pool) :
 	mPool(NULL),
 	mCurrentPool(NULL),
 	mCurrentPoolReallocCount(0),
-	mChainsMutex(NULL),
-	mCallbackMutex(NULL),
 	mCurrentChain(mRunningChains.end())
 {
 	mCurrentChain = mRunningChains.end();
@@ -194,9 +188,6 @@ bool LLPumpIO::addChain(const chain_t& chain, F32 timeout, bool has_curl_request
 {
 	if(chain.empty()) return false;
 
-#if LL_THREADS_APR
-	LLScopedLock lock(mChainsMutex);
-#endif
 	LLChainInfo info;
 	info.mHasCurlRequest = has_curl_request;
 	info.setTimeoutSeconds(timeout);
@@ -234,9 +225,6 @@ bool LLPumpIO::addChain(
 	if(!data) return false;
 	if(links.empty()) return false;
 
-#if LL_THREADS_APR
-	LLScopedLock lock(mChainsMutex);
-#endif
 #if LL_DEBUG_PIPE_TYPE_IN_PUMP
 	LL_DEBUGS() << "LLPumpIO::addChain() " << links[0].mPipe << " '"
 		<< typeid(*(links[0].mPipe)).name() << "'" << LL_ENDL;
@@ -391,9 +379,6 @@ void LLPumpIO::clearLock(S32 key)
 	// therefore won't be treading into deleted memory. I think we can
 	// also clear the lock on the chain safely since the pump only
 	// reads that value.
-#if LL_THREADS_APR
-	LLScopedLock lock(mChainsMutex);
-#endif
 	mClearLocks.insert(key);
 }
 
@@ -457,9 +442,6 @@ void LLPumpIO::pump(const S32& poll_timeout)
 	PUMP_DEBUG;
 	if(true)
 	{
-#if LL_THREADS_APR
-		LLScopedLock lock(mChainsMutex);
-#endif
 		// bail if this pump is paused.
 		if(PAUSING == mState)
 		{
@@ -724,25 +706,10 @@ void LLPumpIO::pump(const S32& poll_timeout)
 	END_PUMP_DEBUG;
 }
 
-//bool LLPumpIO::respond(const chain_t& pipes)
-//{
-//#if LL_THREADS_APR
-//	LLScopedLock lock(mCallbackMutex);
-//#endif
-//	LLChainInfo info;
-//	links_t links;
-//	
-//	mPendingCallbacks.push_back(info);
-//	return true;
-//}
-
 bool LLPumpIO::respond(LLIOPipe* pipe)
 {
 	if(NULL == pipe) return false;
 
-#if LL_THREADS_APR
-	LLScopedLock lock(mCallbackMutex);
-#endif
 	LLChainInfo info;
 	LLLinkInfo link;
 	link.mPipe = pipe;
@@ -761,10 +728,6 @@ bool LLPumpIO::respond(
 	if(!data) return false;
 	if(links.empty()) return false;
 
-#if LL_THREADS_APR
-	LLScopedLock lock(mCallbackMutex);
-#endif
-
 	// Add the callback response
 	LLChainInfo info;
 	info.mChainLinks = links;
@@ -781,9 +744,6 @@ void LLPumpIO::callback()
 	//LL_INFOS() << "LLPumpIO::callback()" << LL_ENDL;
 	if(true)
 	{
-#if LL_THREADS_APR
-		LLScopedLock lock(mCallbackMutex);
-#endif
 		std::copy(
 			mPendingCallbacks.begin(),
 			mPendingCallbacks.end(),
@@ -809,9 +769,6 @@ void LLPumpIO::callback()
 
 void LLPumpIO::control(LLPumpIO::EControl op)
 {
-#if LL_THREADS_APR
-	LLScopedLock lock(mChainsMutex);
-#endif
 	switch(op)
 	{
 	case PAUSE:
@@ -829,22 +786,11 @@ void LLPumpIO::control(LLPumpIO::EControl op)
 void LLPumpIO::initialize(apr_pool_t* pool)
 {
 	if(!pool) return;
-#if LL_THREADS_APR
-	// SJB: Windows defaults to NESTED and OSX defaults to UNNESTED, so use UNNESTED explicitly.
-	apr_thread_mutex_create(&mChainsMutex, APR_THREAD_MUTEX_UNNESTED, pool);
-	apr_thread_mutex_create(&mCallbackMutex, APR_THREAD_MUTEX_UNNESTED, pool);
-#endif
 	mPool = pool;
 }
 
 void LLPumpIO::cleanup()
 {
-#if LL_THREADS_APR
-	if(mChainsMutex) apr_thread_mutex_destroy(mChainsMutex);
-	if(mCallbackMutex) apr_thread_mutex_destroy(mCallbackMutex);
-#endif
-	mChainsMutex = NULL;
-	mCallbackMutex = NULL;
 	if(mPollset)
 	{
 //		LL_DEBUGS() << "cleaning up pollset" << LL_ENDL;
diff --git a/indra/llmessage/llpumpio.h b/indra/llmessage/llpumpio.h
index d2c5d37571..b9eabee710 100644
--- a/indra/llmessage/llpumpio.h
+++ b/indra/llmessage/llpumpio.h
@@ -40,9 +40,6 @@
 #include "lliopipe.h"
 #include "llrun.h"
 
-// Define this to enable use with the APR thread library.
-//#define LL_THREADS_APR 1
-
 // some simple constants to help with timeouts
 extern const F32 DEFAULT_CHAIN_EXPIRY_SECS;
 extern const F32 SHORT_CHAIN_EXPIRY_SECS;
@@ -393,14 +390,6 @@ protected:
 	apr_pool_t* mCurrentPool;
 	S32 mCurrentPoolReallocCount;
 
-#if LL_THREADS_APR
-	apr_thread_mutex_t* mChainsMutex;
-	apr_thread_mutex_t* mCallbackMutex;
-#else
-	int* mChainsMutex;
-	int* mCallbackMutex;
-#endif
-
 protected:
 	void initialize(apr_pool_t* pool);
 	void cleanup();
diff --git a/indra/llvfs/lllfsthread.h b/indra/llvfs/lllfsthread.h
index cdb5c75946..58f658f7ba 100644
--- a/indra/llvfs/lllfsthread.h
+++ b/indra/llvfs/lllfsthread.h
@@ -32,7 +32,6 @@
 #include <map>
 #include <set>
 
-#include "llapr.h"
 #include "llpointer.h"
 #include "llqueuedthread.h"
 
diff --git a/indra/llvfs/llvfsthread.h b/indra/llvfs/llvfsthread.h
index 95f3c857c6..7814de4a2d 100644
--- a/indra/llvfs/llvfsthread.h
+++ b/indra/llvfs/llvfsthread.h
@@ -32,8 +32,6 @@
 #include <map>
 #include <set>
 
-#include "llapr.h"
-
 #include "llqueuedthread.h"
 
 #include "llvfs.h"
diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h
index cfa312ccd9..19369137b7 100644
--- a/indra/newview/lltexturefetch.h
+++ b/indra/newview/lltexturefetch.h
@@ -35,7 +35,6 @@
 #include "lluuid.h"
 #include "llworkerthread.h"
 #include "lltextureinfo.h"
-#include "llapr.h"
 #include "llimageworker.h"
 #include "httprequest.h"
 #include "httpoptions.h"
-- 
cgit v1.2.3


From fa15830e02ed249186625e845e2ac19749d10193 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Tue, 15 Jan 2019 18:31:17 +0200
Subject: SL-10291 Replace apr_atomic with standard C++11 functionality

---
 indra/llcommon/CMakeLists.txt        |  2 ++
 indra/llcommon/llapp.h               |  3 +-
 indra/llcommon/llapr.h               | 28 ---------------
 indra/llcommon/llatomic.cpp          | 28 +++++++++++++++
 indra/llcommon/llatomic.h            | 69 ++++++++++++++++++++++++++++++++++++
 indra/llcommon/llinstancetracker.cpp |  7 ++--
 indra/llcommon/llinstancetracker.h   |  9 +++--
 indra/llcommon/llmutex.cpp           |  3 --
 indra/llcommon/llqueuedthread.h      |  6 ++--
 indra/llcommon/llrefcount.h          |  8 ++---
 indra/llcommon/llworkerthread.h      |  2 +-
 indra/llcorehttp/_httpservice.h      |  2 +-
 indra/llcorehttp/_refcounted.h       |  2 +-
 indra/llcorehttp/_thread.h           |  1 +
 indra/llcrashlogger/llcrashlock.cpp  |  1 +
 indra/llmessage/llproxy.h            |  2 +-
 indra/llvfs/llpidlock.cpp            |  1 +
 indra/newview/llappviewer.h          |  1 +
 indra/newview/llmeshrepository.cpp   |  3 +-
 indra/newview/lltexturecache.h       |  2 +-
 20 files changed, 128 insertions(+), 52 deletions(-)
 create mode 100644 indra/llcommon/llatomic.cpp
 create mode 100644 indra/llcommon/llatomic.h

diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index d9eb13d65a..ac19e6d025 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -35,6 +35,7 @@ set(llcommon_SOURCE_FILES
     llapp.cpp
     llapr.cpp
     llassettype.cpp
+    llatomic.cpp
     llbase32.cpp
     llbase64.cpp
     llbitpack.cpp
@@ -135,6 +136,7 @@ set(llcommon_HEADER_FILES
     llapp.h
     llapr.h
     llassettype.h
+    llatomic.h
     llbase32.h
     llbase64.h
     llbitpack.h
diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h
index acd829d864..245c73e3a2 100644
--- a/indra/llcommon/llapp.h
+++ b/indra/llcommon/llapp.h
@@ -30,9 +30,8 @@
 #include <map>
 #include "llrun.h"
 #include "llsd.h"
+#include <atomic>
 // Forward declarations
-template <typename Type> class LLAtomic32;
-typedef LLAtomic32<U32> LLAtomicU32;
 class LLErrorThread;
 class LLLiveFile;
 #if LL_LINUX
diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h
index 73d1d180ef..da50dda103 100644
--- a/indra/llcommon/llapr.h
+++ b/indra/llcommon/llapr.h
@@ -38,7 +38,6 @@
 #include "apr_thread_proc.h"
 #include "apr_getopt.h"
 #include "apr_signal.h"
-#include "apr_atomic.h"
 
 #include "llstring.h"
 
@@ -131,33 +130,6 @@ private:
 	std::unique_ptr<std::mutex> mMutexp;
 } ;
 
-template <typename Type> class LLAtomic32
-{
-public:
-	LLAtomic32<Type>() {};
-	LLAtomic32<Type>(Type x) {apr_atomic_set32(&mData, apr_uint32_t(x)); };
-	~LLAtomic32<Type>() {};
-
-	operator const Type() { apr_uint32_t data = apr_atomic_read32(&mData); return Type(data); }
-	
-	Type	CurrentValue() const { apr_uint32_t data = apr_atomic_read32(const_cast< volatile apr_uint32_t* >(&mData)); return Type(data); }
-
-	Type operator =(const Type& x) { apr_atomic_set32(&mData, apr_uint32_t(x)); return Type(mData); }
-	void operator -=(Type x) { apr_atomic_sub32(&mData, apr_uint32_t(x)); }
-	void operator +=(Type x) { apr_atomic_add32(&mData, apr_uint32_t(x)); }
-	Type operator ++(int) { return apr_atomic_inc32(&mData); } // Type++
-	Type operator --(int) { return apr_atomic_dec32(&mData); } // approximately --Type (0 if final is 0, non-zero otherwise)
-
-	Type operator ++() { return apr_atomic_inc32(&mData); } // Type++
-	Type operator --() { return apr_atomic_dec32(&mData); } // approximately --Type (0 if final is 0, non-zero otherwise)
-	
-private:
-	volatile apr_uint32_t mData;
-};
-
-typedef LLAtomic32<U32> LLAtomicU32;
-typedef LLAtomic32<S32> LLAtomicS32;
-
 // File IO convenience functions.
 // Returns NULL if the file fails to open, sets *sizep to file size if not NULL
 // abbreviated flags
diff --git a/indra/llcommon/llatomic.cpp b/indra/llcommon/llatomic.cpp
new file mode 100644
index 0000000000..93aba1f460
--- /dev/null
+++ b/indra/llcommon/llatomic.cpp
@@ -0,0 +1,28 @@
+/** 
+ * @file llatomic.cpp
+ *
+ * $LicenseInfo:firstyear=2018&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2018, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llatomic.h"
+
+//============================================================================
diff --git a/indra/llcommon/llatomic.h b/indra/llcommon/llatomic.h
new file mode 100644
index 0000000000..8de773846c
--- /dev/null
+++ b/indra/llcommon/llatomic.h
@@ -0,0 +1,69 @@
+/** 
+ * @file llatomic.h
+ * @brief Base classes for atomic.
+ *
+ * $LicenseInfo:firstyear=2018&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2018, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLATOMIC_H
+#define LL_LLATOMIC_H
+
+#include "stdtypes.h"
+
+#include <atomic>
+
+template <typename Type, typename AtomicType = std::atomic< Type > > class LLAtomicBase
+{
+public:
+    LLAtomicBase() {};
+    LLAtomicBase(Type x) { mData.store(x); }
+    ~LLAtomicBase() {};
+
+    operator const Type() { return mData; }
+
+    Type	CurrentValue() const { return mData; }
+
+    Type operator =(const Type& x) { mData.store(x); return mData; }
+    void operator -=(Type x) { mData -= x; }
+    void operator +=(Type x) { mData += x; }
+    Type operator ++(int) { return mData++; }
+    Type operator --(int) { return mData--; }
+
+    Type operator ++() { return ++mData; }
+    Type operator --() { return --mData; }
+
+private:
+    AtomicType mData;
+};
+
+// Typedefs for specialized versions. Using std::atomic_(u)int32_t to get the optimzed implementation.
+#ifdef LL_WINDOWS
+typedef LLAtomicBase<U32, std::atomic_uint32_t> LLAtomicU32;
+typedef LLAtomicBase<S32, std::atomic_int32_t> LLAtomicS32;
+#else
+typedef LLAtomicBase<U32, std::atomic_uint> LLAtomicU32;
+typedef LLAtomicBase<S32, std::atomic_int> LLAtomicS32;
+#endif
+
+typedef LLAtomicBase<bool, std::atomic_bool> LLAtomicBool;
+
+#endif // LL_LLATOMIC_H
diff --git a/indra/llcommon/llinstancetracker.cpp b/indra/llcommon/llinstancetracker.cpp
index 11fc53f8c8..3f990f4869 100644
--- a/indra/llcommon/llinstancetracker.cpp
+++ b/indra/llcommon/llinstancetracker.cpp
@@ -36,17 +36,16 @@
 
 void LLInstanceTrackerBase::StaticBase::incrementDepth()
 {
-	apr_atomic_inc32(&sIterationNestDepth);
+	++sIterationNestDepth;
 }
 
 void LLInstanceTrackerBase::StaticBase::decrementDepth()
 {
 	llassert(sIterationNestDepth);
-	apr_atomic_dec32(&sIterationNestDepth);
+	--sIterationNestDepth;
 }
 
 U32 LLInstanceTrackerBase::StaticBase::getDepth()
 {
-	apr_uint32_t data = apr_atomic_read32(&sIterationNestDepth);
-	return data;
+	return sIterationNestDepth;
 }
diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h
index 910c8dbd99..363d0bcbd5 100644
--- a/indra/llcommon/llinstancetracker.h
+++ b/indra/llcommon/llinstancetracker.h
@@ -28,6 +28,7 @@
 #ifndef LL_LLINSTANCETRACKER_H
 #define LL_LLINSTANCETRACKER_H
 
+#include <atomic>
 #include <map>
 #include <typeinfo>
 
@@ -81,8 +82,12 @@ protected:
 		void decrementDepth();
 		U32 getDepth();
 	private:
-		U32 sIterationNestDepth;
-    };
+#ifdef LL_WINDOWS
+		std::atomic_uint32_t sIterationNestDepth;
+#else
+		std::atomic_uint sIterationNestDepth;
+#endif
+	};
 };
 
 LL_COMMON_API void assert_main_thread();
diff --git a/indra/llcommon/llmutex.cpp b/indra/llcommon/llmutex.cpp
index cf84e50953..75f43a4704 100644
--- a/indra/llcommon/llmutex.cpp
+++ b/indra/llcommon/llmutex.cpp
@@ -24,9 +24,6 @@
  */
 
 #include "linden_common.h"
-#include "llapr.h"
-
-#include "apr_portable.h"
 
 #include "llmutex.h"
 #include "llthread.h"
diff --git a/indra/llcommon/llqueuedthread.h b/indra/llcommon/llqueuedthread.h
index d3704b0fe2..5d3f873646 100644
--- a/indra/llcommon/llqueuedthread.h
+++ b/indra/llcommon/llqueuedthread.h
@@ -32,7 +32,7 @@
 #include <map>
 #include <set>
 
-#include "llapr.h"
+#include "llatomic.h"
 
 #include "llthread.h"
 #include "llsimplehash.h"
@@ -128,7 +128,7 @@ public:
 		};
 		
 	protected:
-		LLAtomic32<status_t> mStatus;
+		LLAtomicBase<status_t> mStatus;
 		U32 mPriority;
 		U32 mFlags;
 	};
@@ -198,7 +198,7 @@ public:
 protected:
 	BOOL mThreaded;  // if false, run on main thread and do updates during update()
 	BOOL mStarted;  // required when mThreaded is false to call startThread() from update()
-	LLAtomic32<BOOL> mIdleThread; // request queue is empty (or we are quitting) and the thread is idle
+	LLAtomicBool mIdleThread; // request queue is empty (or we are quitting) and the thread is idle
 	
 	typedef std::set<QueuedRequest*, queued_request_less> request_queue_t;
 	request_queue_t mRequestQueue;
diff --git a/indra/llcommon/llrefcount.h b/indra/llcommon/llrefcount.h
index cdc60fa54f..fb0411d27b 100644
--- a/indra/llcommon/llrefcount.h
+++ b/indra/llcommon/llrefcount.h
@@ -29,7 +29,7 @@
 #include <boost/noncopyable.hpp>
 #include <boost/intrusive_ptr.hpp>
 #include "llmutex.h"
-#include "llapr.h"
+#include "llatomic.h"
 
 //----------------------------------------------------------------------------
 // RefCount objects should generally only be accessed by way of LLPointer<>'s
@@ -107,8 +107,8 @@ public:
 	void unref()
 	{
 		llassert(mRef >= 1);
-		if ((--mRef) == 0)		// See note in llapr.h on atomic decrement operator return value.  
-		{	
+		if ((--mRef) == 0)
+		{
 			// If we hit zero, the caller should be the only smart pointer owning the object and we can delete it.
 			// It is technically possible for a vanilla pointer to mess this up, or another thread to
 			// jump in, find this object, create another smart pointer and end up dangling, but if
@@ -124,7 +124,7 @@ public:
 	}
 
 private: 
-	LLAtomic32< S32	> mRef; 
+	LLAtomicS32 mRef; 
 };
 
 /**
diff --git a/indra/llcommon/llworkerthread.h b/indra/llcommon/llworkerthread.h
index 09776816a8..b1a6f61360 100644
--- a/indra/llcommon/llworkerthread.h
+++ b/indra/llcommon/llworkerthread.h
@@ -33,7 +33,7 @@
 #include <string>
 
 #include "llqueuedthread.h"
-#include "llapr.h"
+#include "llatomic.h"
 
 #define USE_FRAME_CALLBACK_MANAGER 0
 
diff --git a/indra/llcorehttp/_httpservice.h b/indra/llcorehttp/_httpservice.h
index ac518a5de7..d0c37ac195 100644
--- a/indra/llcorehttp/_httpservice.h
+++ b/indra/llcorehttp/_httpservice.h
@@ -31,7 +31,7 @@
 #include <vector>
 
 #include "linden_common.h"
-#include "llapr.h"
+#include "llatomic.h"
 #include "httpcommon.h"
 #include "httprequest.h"
 #include "_httppolicyglobal.h"
diff --git a/indra/llcorehttp/_refcounted.h b/indra/llcorehttp/_refcounted.h
index 7f713f2298..5cc8914395 100644
--- a/indra/llcorehttp/_refcounted.h
+++ b/indra/llcorehttp/_refcounted.h
@@ -34,7 +34,7 @@
 #include <boost/thread.hpp>
 #include <boost/intrusive_ptr.hpp>
 
-#include "llapr.h"
+#include "llatomic.h"
 
 
 namespace LLCoreInt
diff --git a/indra/llcorehttp/_thread.h b/indra/llcorehttp/_thread.h
index e058d660e5..22b7750bad 100644
--- a/indra/llcorehttp/_thread.h
+++ b/indra/llcorehttp/_thread.h
@@ -33,6 +33,7 @@
 #include <boost/function.hpp>
 #include <boost/date_time/posix_time/posix_time_types.hpp>
 
+#include "apr.h" // thread-related functions
 #include "_refcounted.h"
 
 namespace LLCoreInt
diff --git a/indra/llcrashlogger/llcrashlock.cpp b/indra/llcrashlogger/llcrashlock.cpp
index 77abfbcf0f..18d164abde 100644
--- a/indra/llcrashlogger/llcrashlock.cpp
+++ b/indra/llcrashlogger/llcrashlock.cpp
@@ -27,6 +27,7 @@
 
 #include "linden_common.h"
 
+#include "llapr.h" // thread-related functions
 #include "llcrashlock.h"
 #include "lldir.h"
 #include "llsd.h"
diff --git a/indra/llmessage/llproxy.h b/indra/llmessage/llproxy.h
index 688dff7c83..87891901ad 100644
--- a/indra/llmessage/llproxy.h
+++ b/indra/llmessage/llproxy.h
@@ -298,7 +298,7 @@ private:
 private:
 	// Is the HTTP proxy enabled? Safe to read in any thread, but do not write directly.
 	// Instead use enableHTTPProxy() and disableHTTPProxy() instead.
-	mutable LLAtomic32<bool> mHTTPProxyEnabled;
+	mutable LLAtomicBool mHTTPProxyEnabled;
 
 	// Mutex to protect shared members in non-main thread calls to applyProxySettings().
 	mutable LLMutex mProxyMutex;
diff --git a/indra/llvfs/llpidlock.cpp b/indra/llvfs/llpidlock.cpp
index 6572edead3..f770e93d45 100644
--- a/indra/llvfs/llpidlock.cpp
+++ b/indra/llvfs/llpidlock.cpp
@@ -27,6 +27,7 @@
 
 #include "linden_common.h"
 
+#include "llapr.h" // thread-related functions
 #include "llpidlock.h"
 #include "lldir.h"
 #include "llsd.h"
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index e607b4a994..788fe6a19b 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -43,6 +43,7 @@
 #define LL_LLAPPVIEWER_H
 
 #include "llallocator.h"
+#include "llapr.h"
 #include "llcontrol.h"
 #include "llsys.h"			// for LLOSInfo
 #include "lltimer.h"
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index a6002bd57f..2e7141bcfc 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -26,10 +26,11 @@
 
 #include "llviewerprecompiledheaders.h"
 
+#include "llapr.h"
+#include "apr_portable.h"
 #include "apr_pools.h"
 #include "apr_dso.h"
 #include "llhttpconstants.h"
-#include "llapr.h"
 #include "llmeshrepository.h"
 
 #include "llagent.h"
diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h
index 987b9375c0..81ea7aeee2 100644
--- a/indra/newview/lltexturecache.h
+++ b/indra/newview/lltexturecache.h
@@ -221,7 +221,7 @@ private:
 	typedef std::map<LLUUID,S32> size_map_t;
 	size_map_t mTexturesSizeMap;
 	S64 mTexturesSizeTotal;
-	LLAtomic32<BOOL> mDoPurge;
+	LLAtomicBool mDoPurge;
 
 	typedef std::map<S32, Entry> idx_entry_map_t;
 	idx_entry_map_t mUpdatedEntryMap;
-- 
cgit v1.2.3


From 3527e9c0423f8a3c10c9d6e93805540315b285b6 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Fri, 18 Jan 2019 16:12:49 +0200
Subject: SL-3488 Remove "Disable Selected" and "Disable All" Buttons

---
 indra/newview/llfloatertopobjects.cpp              | 41 +++-------------------
 indra/newview/llfloatertopobjects.h                | 11 +-----
 .../skins/default/xui/en/floater_top_objects.xml   | 26 +-------------
 3 files changed, 6 insertions(+), 72 deletions(-)

diff --git a/indra/newview/llfloatertopobjects.cpp b/indra/newview/llfloatertopobjects.cpp
index 3e6fc3dc0d..9b5b3a0fc9 100644
--- a/indra/newview/llfloatertopobjects.cpp
+++ b/indra/newview/llfloatertopobjects.cpp
@@ -78,8 +78,6 @@ LLFloaterTopObjects::LLFloaterTopObjects(const LLSD& key)
 	mCommitCallbackRegistrar.add("TopObjects.ShowBeacon",		boost::bind(&LLFloaterTopObjects::onClickShowBeacon, this));
 	mCommitCallbackRegistrar.add("TopObjects.ReturnSelected",	boost::bind(&LLFloaterTopObjects::onReturnSelected, this));
 	mCommitCallbackRegistrar.add("TopObjects.ReturnAll",		boost::bind(&LLFloaterTopObjects::onReturnAll, this));
-	mCommitCallbackRegistrar.add("TopObjects.DisableSelected",	boost::bind(&LLFloaterTopObjects::onDisableSelected, this));
-	mCommitCallbackRegistrar.add("TopObjects.DisableAll",		boost::bind(&LLFloaterTopObjects::onDisableAll, this));
 	mCommitCallbackRegistrar.add("TopObjects.Refresh",			boost::bind(&LLFloaterTopObjects::onRefresh, this));
 	mCommitCallbackRegistrar.add("TopObjects.GetByObjectName",	boost::bind(&LLFloaterTopObjects::onGetByObjectName, this));
 	mCommitCallbackRegistrar.add("TopObjects.GetByOwnerName",	boost::bind(&LLFloaterTopObjects::onGetByOwnerName, this));
@@ -332,7 +330,7 @@ void LLFloaterTopObjects::onClickShowBeacon()
 	showBeacon();
 }
 
-void LLFloaterTopObjects::doToObjects(int action, bool all)
+void LLFloaterTopObjects::returnObjects(bool all)
 {
 	LLMessageSystem *msg = gMessageSystem;
 
@@ -356,14 +354,7 @@ void LLFloaterTopObjects::doToObjects(int action, bool all)
 		}
 		if (start_message)
 		{
-			if (action == ACTION_RETURN)
-			{
-				msg->newMessageFast(_PREHASH_ParcelReturnObjects);
-			}
-			else
-			{
-				msg->newMessageFast(_PREHASH_ParcelDisableObjects);
-			}
+			msg->newMessageFast(_PREHASH_ParcelReturnObjects);
 			msg->nextBlockFast(_PREHASH_AgentData);
 			msg->addUUIDFast(_PREHASH_AgentID,	gAgent.getID());
 			msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID());
@@ -397,7 +388,7 @@ bool LLFloaterTopObjects::callbackReturnAll(const LLSD& notification, const LLSD
 	if(!instance) return false;
 	if (option == 0)
 	{
-		instance->doToObjects(ACTION_RETURN, true);
+		instance->returnObjects(true);
 	}
 	return false;
 }
@@ -410,31 +401,7 @@ void LLFloaterTopObjects::onReturnAll()
 
 void LLFloaterTopObjects::onReturnSelected()
 {
-	doToObjects(ACTION_RETURN, false);
-}
-
-
-//static
-bool LLFloaterTopObjects::callbackDisableAll(const LLSD& notification, const LLSD& response)
-{
-	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-	LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance<LLFloaterTopObjects>("top_objects");
-	if(!instance) return false;
-	if (option == 0)
-	{
-		instance->doToObjects(ACTION_DISABLE, true);
-	}
-	return false;
-}
-
-void LLFloaterTopObjects::onDisableAll()
-{
-	LLNotificationsUtil::add("DisableAllTopObjects", LLSD(), LLSD(), callbackDisableAll);
-}
-
-void LLFloaterTopObjects::onDisableSelected()
-{
-	doToObjects(ACTION_DISABLE, false);
+	returnObjects(false);
 }
 
 
diff --git a/indra/newview/llfloatertopobjects.h b/indra/newview/llfloatertopobjects.h
index dbbe9ac521..3138249c7a 100644
--- a/indra/newview/llfloatertopobjects.h
+++ b/indra/newview/llfloatertopobjects.h
@@ -78,15 +78,12 @@ private:
 	static void onDoubleClickObjectsList(void* data);
 	void onClickShowBeacon();
 
-	void doToObjects(int action, bool all);
+	void returnObjects(bool all);
 
 	void onReturnAll();
 	void onReturnSelected();
-	void onDisableAll();
-	void onDisableSelected();
 
 	static bool callbackReturnAll(const LLSD& notification, const LLSD& response);
-	static bool callbackDisableAll(const LLSD& notification, const LLSD& response);
 
 	void onGetByOwnerName();
 	void onGetByObjectName();
@@ -108,12 +105,6 @@ private:
 
 	F32 mtotalScore;
 
-	enum
-	{
-		ACTION_RETURN = 0,
-		ACTION_DISABLE
-	};
-
 	static LLFloaterTopObjects* sInstance;
 };
 
diff --git a/indra/newview/skins/default/xui/en/floater_top_objects.xml b/indra/newview/skins/default/xui/en/floater_top_objects.xml
index 36ceddd305..ceef541290 100644
--- a/indra/newview/skins/default/xui/en/floater_top_objects.xml
+++ b/indra/newview/skins/default/xui/en/floater_top_objects.xml
@@ -2,7 +2,7 @@
 <floater
  legacy_header_height="18"
  can_resize="true"
- height="372"
+ height="350"
  layout="topleft"
  min_height="300"
  min_width="450"
@@ -273,28 +273,4 @@
       <button.commit_callback
           function="TopObjects.ReturnAll" />
     </button>
-    <button
-     follows="bottom|left"
-     height="23"
-     label="Disable Selected"
-     layout="topleft"
-
-     left="112"
-     name="disable_selected_btn"
-     width="130">
-      <button.commit_callback
-          function="TopObjects.DisableSelected" />
-    </button>
-    <button
-     follows="bottom|left"
-     height="23"
-     label="Disable All"
-     layout="topleft"
-     left_pad="10"
-     name="disable_all_btn"
-     top_delta="0"
-     width="130">
-      <button.commit_callback
-          function="TopObjects.DisableAll" />
-    </button>
 </floater>
-- 
cgit v1.2.3


From af0e498293c86dc7bb1ae7911bf932b7b287e115 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Mon, 21 Jan 2019 17:45:26 +0200
Subject: =?UTF-8?q?SL-10338=20FIXED=20The=20=E2=80=9Cadd=20friend=E2=80=9D?=
 =?UTF-8?q?=20button=20is=20available=20when=20user=20is=20already=20at=20?=
 =?UTF-8?q?your=20friends=20list?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 indra/newview/llchatitemscontainerctrl.cpp | 2 ++
 indra/newview/llfloaterland.cpp            | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp
index eddc87efcd..4f42868f1a 100644
--- a/indra/newview/llchatitemscontainerctrl.cpp
+++ b/indra/newview/llchatitemscontainerctrl.cpp
@@ -29,6 +29,7 @@
 #include "llchatitemscontainerctrl.h"
 #include "lltextbox.h"
 
+#include "llavataractions.h"
 #include "llavatariconctrl.h"
 #include "llcommandhandler.h"
 #include "llfloaterreg.h"
@@ -204,6 +205,7 @@ void LLFloaterIMNearbyChatToastPanel::init(LLSD& notification)
 	
 	mMsgText = getChild<LLChatMsgBox>("msg_text", false);
 	mMsgText->setContentTrusted(false);
+	mMsgText->setIsFriendCallback(LLAvatarActions::isFriend);
 
 	mMsgText->setText(std::string(""));
 
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index 88b3fb7b96..a462f391ca 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -415,6 +415,7 @@ BOOL LLPanelLandGeneral::postBuild()
 	mTextSalePending = getChild<LLTextBox>("SalePending");
 	mTextOwnerLabel = getChild<LLTextBox>("Owner:");
 	mTextOwner = getChild<LLTextBox>("OwnerText");
+	mTextOwner->setIsFriendCallback(LLAvatarActions::isFriend);
 	
 	mContentRating = getChild<LLTextBox>("ContentRatingText");
 	mLandType = getChild<LLTextBox>("LandTypeText");
@@ -1191,6 +1192,7 @@ BOOL LLPanelLandObjects::postBuild()
 	mIconGroup = LLUIImageList::getInstance()->getUIImage("icon_group.tga", 0);
 
 	mOwnerList = getChild<LLNameListCtrl>("owner list");
+	mOwnerList->setIsFriendCallback(LLAvatarActions::isFriend);
 	mOwnerList->sortByColumnIndex(3, FALSE);
 	childSetCommitCallback("owner list", onCommitList, this);
 	mOwnerList->setDoubleClickCallback(onDoubleClickOwner, this);
-- 
cgit v1.2.3


From 8a92a771ba547d9d6a8bd1234e2e0b144a8bfcf5 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Tue, 15 Jan 2019 22:27:28 +0200
Subject: SL-10291 Replace apr thread with standard C++11 functionality

---
 indra/llcommon/llthread.cpp          |  77 +++++++-------------
 indra/llcommon/llthread.h            |  12 ++--
 indra/llcommon/llthreadsafequeue.cpp |  81 ---------------------
 indra/llcommon/llthreadsafequeue.h   | 135 +++++++++++++++++++----------------
 indra/newview/llmainlooprepeater.cpp |   2 +-
 5 files changed, 104 insertions(+), 203 deletions(-)

diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index 860415bb22..a4171729db 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -116,29 +116,27 @@ void LLThread::registerThreadID()
 //
 // Handed to the APR thread creation function
 //
-void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap)
+void LLThread::threadRun()
 {
-    LLThread *threadp = (LLThread *)datap;
-
 #ifdef LL_WINDOWS
-    set_thread_name(-1, threadp->mName.c_str());
+    set_thread_name(-1, mName.c_str());
 #endif
 
     // for now, hard code all LLThreads to report to single master thread recorder, which is known to be running on main thread
-    threadp->mRecorder = new LLTrace::ThreadRecorder(*LLTrace::get_master_thread_recorder());
+    mRecorder = new LLTrace::ThreadRecorder(*LLTrace::get_master_thread_recorder());
 
-    sThreadID = threadp->mID;
+    sThreadID = mID;
 
     // Run the user supplied function
     do 
     {
         try
         {
-            threadp->run();
+            run();
         }
         catch (const LLContinueError &e)
         {
-            LL_WARNS("THREAD") << "ContinueException on thread '" << threadp->mName <<
+            LL_WARNS("THREAD") << "ContinueException on thread '" << mName <<
                 "' reentering run(). Error what is: '" << e.what() << "'" << LL_ENDL;
             //output possible call stacks to log file.
             LLError::LLCallStacks::print();
@@ -153,39 +151,25 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap
     //LL_INFOS() << "LLThread::staticRun() Exiting: " << threadp->mName << LL_ENDL;
 
 
-    delete threadp->mRecorder;
-    threadp->mRecorder = NULL;
+    delete mRecorder;
+    mRecorder = NULL;
 
     // We're done with the run function, this thread is done executing now.
     //NB: we are using this flag to sync across threads...we really need memory barriers here
     // Todo: add LLMutex per thread instead of flag?
     // We are using "while (mStatus != STOPPED) {ms_sleep();}" everywhere.
-    threadp->mStatus = STOPPED;
-
-    return NULL;
+    mStatus = STOPPED;
 }
 
 LLThread::LLThread(const std::string& name, apr_pool_t *poolp) :
     mPaused(FALSE),
     mName(name),
-    mAPRThreadp(NULL),
+    mThreadp(NULL),
     mStatus(STOPPED),
     mRecorder(NULL)
 {
 
     mID = ++sIDIter;
-
-    // Thread creation probably CAN be paranoid about APR being initialized, if necessary
-    if (poolp)
-    {
-        mIsLocalPool = FALSE;
-        mAPRPoolp = poolp;
-    }
-    else
-    {
-        mIsLocalPool = TRUE;
-        apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread
-    }
     mRunCondition = new LLCondition();
     mDataLock = new LLMutex();
     mLocalAPRFilePoolp = NULL ;
@@ -217,7 +201,7 @@ void LLThread::shutdown()
 
     // Warning!  If you somehow call the thread destructor from itself,
     // the thread will die in an unclean fashion!
-    if (mAPRThreadp)
+    if (mThreadp)
     {
         if (!isStopped())
         {
@@ -248,14 +232,19 @@ void LLThread::shutdown()
         {
             // This thread just wouldn't stop, even though we gave it time
             //LL_WARNS() << "LLThread::~LLThread() exiting thread before clean exit!" << LL_ENDL;
-            // Put a stake in its heart.
-            apr_thread_exit(mAPRThreadp, -1);
+            // Put a stake in its heart. (A very hostile method to force a thread to quit)
+#if		LL_WINDOWS
+            TerminateThread(mNativeHandle, 0);
+#else
+            pthread_cancel(mNativeHandle);
+#endif
+
             delete mRecorder;
             mRecorder = NULL;
             mStatus = STOPPED;
             return;
         }
-        mAPRThreadp = NULL;
+        mThreadp = NULL;
     }
 
     delete mRunCondition;
@@ -263,12 +252,6 @@ void LLThread::shutdown()
 
     delete mDataLock;
     mDataLock = NULL;
-    
-    if (mIsLocalPool && mAPRPoolp)
-    {
-        apr_pool_destroy(mAPRPoolp);
-        mAPRPoolp = 0;
-    }
 
     if (mRecorder)
     {
@@ -287,19 +270,15 @@ void LLThread::start()
     // Set thread state to running
     mStatus = RUNNING;
 
-    apr_status_t status =
-        apr_thread_create(&mAPRThreadp, NULL, staticRun, (void *)this, mAPRPoolp);
-    
-    if(status == APR_SUCCESS)
-    {   
-        // We won't bother joining
-        apr_thread_detach(mAPRThreadp);
+    try
+    {
+        mThreadp = new std::thread(std::bind(&LLThread::threadRun, this));
+        mNativeHandle = mThreadp->native_handle();
     }
-    else
+    catch (std::system_error& ex)
     {
         mStatus = STOPPED;
-        LL_WARNS() << "failed to start thread " << mName << LL_ENDL;
-        ll_apr_warn_status(status);
+        LL_WARNS() << "failed to start thread " << mName << " " << ex.what() << LL_ENDL;
     }
 
 }
@@ -376,11 +355,7 @@ U32 LLThread::currentID()
 // static
 void LLThread::yield()
 {
-#if LL_LINUX || LL_SOLARIS
-    sched_yield(); // annoyingly, apr_thread_yield  is a noop on linux...
-#else
-    apr_thread_yield();
-#endif
+    std::this_thread::yield();
 }
 
 void LLThread::wake()
diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h
index dda7fa8ffb..863c9051f3 100644
--- a/indra/llcommon/llthread.h
+++ b/indra/llcommon/llthread.h
@@ -29,10 +29,10 @@
 
 #include "llapp.h"
 #include "llapr.h"
-#include "apr_thread_cond.h"
 #include "boost/intrusive_ptr.hpp"
 #include "llmutex.h"
 #include "llrefcount.h"
+#include <thread>
 
 LL_COMMON_API void assert_main_thread();
 
@@ -86,7 +86,6 @@ public:
     // this kicks off the apr thread
     void start(void);
 
-    apr_pool_t *getAPRPool() { return mAPRPoolp; }
     LLVolatileAPRPool* getLocalAPRFilePool() { return mLocalAPRFilePoolp ; }
 
     U32 getID() const { return mID; }
@@ -97,19 +96,18 @@ public:
     static void registerThreadID();
     
 private:
-    BOOL                mPaused;
+    bool                mPaused;
+    std::thread::native_handle_type mNativeHandle; // for termination in case of issues
     
     // static function passed to APR thread creation routine
-    static void *APR_THREAD_FUNC staticRun(struct apr_thread_t *apr_threadp, void *datap);
+    void threadRun();
 
 protected:
     std::string         mName;
     class LLCondition*  mRunCondition;
     LLMutex*            mDataLock;
 
-    apr_thread_t        *mAPRThreadp;
-    apr_pool_t          *mAPRPoolp;
-    BOOL                mIsLocalPool;
+    std::thread        *mThreadp;
     EThreadStatus       mStatus;
     U32                 mID;
     LLTrace::ThreadRecorder* mRecorder;
diff --git a/indra/llcommon/llthreadsafequeue.cpp b/indra/llcommon/llthreadsafequeue.cpp
index 491f920c0f..bde36999ba 100644
--- a/indra/llcommon/llthreadsafequeue.cpp
+++ b/indra/llcommon/llthreadsafequeue.cpp
@@ -24,87 +24,6 @@
  */
 
 #include "linden_common.h"
-#include <apr_pools.h>
-#include <apr_queue.h>
 #include "llthreadsafequeue.h"
-#include "llexception.h"
 
 
-
-// LLThreadSafeQueueImplementation
-//-----------------------------------------------------------------------------
-
-
-LLThreadSafeQueueImplementation::LLThreadSafeQueueImplementation(apr_pool_t * pool, unsigned int capacity):
-	mOwnsPool(pool == 0),
-	mPool(pool),
-	mQueue(0)
-{
-	if(mOwnsPool) {
-		apr_status_t status = apr_pool_create(&mPool, 0);
-		if(status != APR_SUCCESS) LLTHROW(LLThreadSafeQueueError("failed to allocate pool"));
-	} else {
-		; // No op.
-	}
-	
-	apr_status_t status = apr_queue_create(&mQueue, capacity, mPool);
-	if(status != APR_SUCCESS) LLTHROW(LLThreadSafeQueueError("failed to allocate queue"));
-}
-
-
-LLThreadSafeQueueImplementation::~LLThreadSafeQueueImplementation()
-{
-	if(mQueue != 0) {
-		if(apr_queue_size(mQueue) != 0) LL_WARNS() << 
-			"terminating queue which still contains " << apr_queue_size(mQueue) <<
-			" elements;" << "memory will be leaked" << LL_ENDL;
-		apr_queue_term(mQueue);
-	}
-	if(mOwnsPool && (mPool != 0)) apr_pool_destroy(mPool);
-}
-
-
-void LLThreadSafeQueueImplementation::pushFront(void * element)
-{
-	apr_status_t status = apr_queue_push(mQueue, element);
-	
-	if(status == APR_EINTR) {
-		LLTHROW(LLThreadSafeQueueInterrupt());
-	} else if(status != APR_SUCCESS) {
-		LLTHROW(LLThreadSafeQueueError("push failed"));
-	} else {
-		; // Success.
-	}
-}
-
-
-bool LLThreadSafeQueueImplementation::tryPushFront(void * element){
-	return apr_queue_trypush(mQueue, element) == APR_SUCCESS;
-}
-
-
-void * LLThreadSafeQueueImplementation::popBack(void)
-{
-	void * element;
-	apr_status_t status = apr_queue_pop(mQueue, &element);
-
-	if(status == APR_EINTR) {
-		LLTHROW(LLThreadSafeQueueInterrupt());
-	} else if(status != APR_SUCCESS) {
-		LLTHROW(LLThreadSafeQueueError("pop failed"));
-	} else {
-		return element;
-	}
-}
-
-
-bool LLThreadSafeQueueImplementation::tryPopBack(void *& element)
-{
-	return apr_queue_trypop(mQueue, &element) == APR_SUCCESS;
-}
-
-
-size_t LLThreadSafeQueueImplementation::size()
-{
-	return apr_queue_size(mQueue);
-}
diff --git a/indra/llcommon/llthreadsafequeue.h b/indra/llcommon/llthreadsafequeue.h
index 45289ef0b4..b0bddac8e5 100644
--- a/indra/llcommon/llthreadsafequeue.h
+++ b/indra/llcommon/llthreadsafequeue.h
@@ -28,12 +28,20 @@
 #define LL_LLTHREADSAFEQUEUE_H
 
 #include "llexception.h"
+#include <deque>
 #include <string>
 
+#if LL_WINDOWS
+#pragma warning (push)
+#pragma warning (disable:4265)
+#endif
+// 'std::_Pad' : class has virtual functions, but destructor is not virtual
+#include <mutex>
+#include <condition_variable>
 
-struct apr_pool_t; // From apr_pools.h
-class LLThreadSafeQueueImplementation; // See below.
-
+#if LL_WINDOWS
+#pragma warning (pop)
+#endif
 
 //
 // A general queue exception.
@@ -64,31 +72,6 @@ public:
 	}
 };
 
-
-struct apr_queue_t; // From apr_queue.h
-
-
-//
-// Implementation details. 
-//
-class LL_COMMON_API LLThreadSafeQueueImplementation
-{
-public:
-	LLThreadSafeQueueImplementation(apr_pool_t * pool, unsigned int capacity);
-	~LLThreadSafeQueueImplementation();
-	void pushFront(void * element);
-	bool tryPushFront(void * element);
-	void * popBack(void);
-	bool tryPopBack(void *& element);
-	size_t size();
-	
-private:
-	bool mOwnsPool;
-	apr_pool_t * mPool;
-	apr_queue_t * mQueue;
-};
-
-
 //
 // Implements a thread safe FIFO.
 //
@@ -100,7 +83,7 @@ public:
 	
 	// If the pool is set to NULL one will be allocated and managed by this
 	// queue.
-	LLThreadSafeQueue(apr_pool_t * pool = 0, unsigned int capacity = 1024);
+	LLThreadSafeQueue(U32 capacity = 1024);
 	
 	// Add an element to the front of queue (will block if the queue has
 	// reached capacity).
@@ -128,77 +111,103 @@ public:
 	size_t size();
 
 private:
-	LLThreadSafeQueueImplementation mImplementation;
-};
-
+	std::deque< ElementT > mStorage;
+	U32 mCapacity;
 
+	std::mutex mLock;
+	std::condition_variable mCapacityCond;
+	std::condition_variable mEmptyCond;
+};
 
 // LLThreadSafeQueue
 //-----------------------------------------------------------------------------
 
-
 template<typename ElementT>
-LLThreadSafeQueue<ElementT>::LLThreadSafeQueue(apr_pool_t * pool, unsigned int capacity):
-	mImplementation(pool, capacity)
+LLThreadSafeQueue<ElementT>::LLThreadSafeQueue(U32 capacity) :
+mCapacity(capacity)
 {
-	; // No op.
 }
 
 
 template<typename ElementT>
 void LLThreadSafeQueue<ElementT>::pushFront(ElementT const & element)
 {
-	ElementT * elementCopy = new ElementT(element);
-	try {
-		mImplementation.pushFront(elementCopy);
-	} catch (LLThreadSafeQueueInterrupt) {
-		delete elementCopy;
-		throw;
-	}
+    while (true)
+    {
+        std::unique_lock<std::mutex> lock1(mLock);
+
+        if (mStorage.size() < mCapacity)
+        {
+            mStorage.push_front(element);
+            mEmptyCond.notify_one();
+            return;
+        }
+
+        // Storage Full. Wait for signal.
+        mCapacityCond.wait(lock1);
+    }
 }
 
 
 template<typename ElementT>
 bool LLThreadSafeQueue<ElementT>::tryPushFront(ElementT const & element)
 {
-	ElementT * elementCopy = new ElementT(element);
-	bool result = mImplementation.tryPushFront(elementCopy);
-	if(!result) delete elementCopy;
-	return result;
+    std::unique_lock<std::mutex> lock1(mLock, std::defer_lock);
+    if (!lock1.try_lock())
+        return false;
+
+    if (mStorage.size() >= mCapacity)
+        return false;
+
+    mStorage.push_front(element);
+    mEmptyCond.notify_one();
+    return true;
 }
 
 
 template<typename ElementT>
 ElementT LLThreadSafeQueue<ElementT>::popBack(void)
 {
-	ElementT * element = reinterpret_cast<ElementT *> (mImplementation.popBack());
-	ElementT result(*element);
-	delete element;
-	return result;
+    while (true)
+    {
+        std::unique_lock<std::mutex> lock1(mLock);
+
+        if (!mStorage.empty())
+        {
+            ElementT value = mStorage.back();
+            mStorage.pop_back();
+            mCapacityCond.notify_one();
+            return value;
+        }
+
+        // Storage empty. Wait for signal.
+        mEmptyCond.wait(lock1);
+    }
 }
 
 
 template<typename ElementT>
 bool LLThreadSafeQueue<ElementT>::tryPopBack(ElementT & element)
 {
-	void * storedElement;
-	bool result = mImplementation.tryPopBack(storedElement);
-	if(result) {
-		ElementT * elementPtr = reinterpret_cast<ElementT *>(storedElement); 
-		element = *elementPtr;
-		delete elementPtr;
-	} else {
-		; // No op.
-	}
-	return result;
+    std::unique_lock<std::mutex> lock1(mLock, std::defer_lock);
+    if (!lock1.try_lock())
+        return false;
+
+    if (mStorage.empty())
+        return false;
+
+    element = mStorage.back();
+    mStorage.pop_back();
+    mCapacityCond.notify_one();
+    return true;
 }
 
 
 template<typename ElementT>
 size_t LLThreadSafeQueue<ElementT>::size(void)
 {
-	return mImplementation.size();
+    std::lock_guard<std::mutex> lock(mLock);
+    return mStorage.size();
 }
 
-
 #endif
diff --git a/indra/newview/llmainlooprepeater.cpp b/indra/newview/llmainlooprepeater.cpp
index db8d2e4ede..6736e9a950 100644
--- a/indra/newview/llmainlooprepeater.cpp
+++ b/indra/newview/llmainlooprepeater.cpp
@@ -46,7 +46,7 @@ void LLMainLoopRepeater::start(void)
 {
 	if(mQueue != 0) return;
 
-	mQueue = new LLThreadSafeQueue<LLSD>(gAPRPoolp, 1024);
+	mQueue = new LLThreadSafeQueue<LLSD>(1024);
 	mMainLoopConnection = LLEventPumps::instance().
 		obtain("mainloop").listen(LLEventPump::inventName(), boost::bind(&LLMainLoopRepeater::onMainLoop, this, _1));
 	mRepeaterConnection = LLEventPumps::instance().
-- 
cgit v1.2.3


From 2448856c63c9024501209473fb09dd91f858655d Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 16 Jan 2019 14:47:19 -0500
Subject: SL-10153: Update to viewer-manager build 523251

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index a353ddbbbe..382506d8ea 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3138,9 +3138,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>e2bef561238448fe512146baa6dacabc</string>
+              <string>146537bed5c358f69af08b811b3920a1</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28859/240421/viewer_manager-2.0.522507-darwin64-522507.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/30016/253294/viewer_manager-2.0.523251-darwin64-523251.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3162,9 +3162,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>75cdf1afc293423553b6d190ce422412</string>
+              <string>fcf98bac94a5145c4f772e6e90a0a78b</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/28858/240427/viewer_manager-2.0.522507-windows-522507.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/30018/253302/viewer_manager-2.0.523251-windows-523251.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3175,7 +3175,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.522507</string>
+        <string>2.0.523251</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From b44fa5b970fea34fac2cfb429cd93300b4ae6707 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 16 Jan 2019 14:56:37 -0500
Subject: SL-10341: Fix Mojave mic permission problem - thanks Tonya Souther!

---
 indra/newview/Info-SecondLife.plist | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist
index 9482f07524..cfe9d991c5 100644
--- a/indra/newview/Info-SecondLife.plist
+++ b/indra/newview/Info-SecondLife.plist
@@ -32,6 +32,8 @@
 	<true/>
 	<key>NSHumanReadableCopyright</key>
 	<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
+	<key>NSMicrophoneUsageDescription</key>
+	<string>For voice chat, you must grant permission for Second Life to use the microphone.</string>
 	<key>CFBundleDocumentTypes</key>
 	<array>
 		<dict>
-- 
cgit v1.2.3


From 7204f166369a71cbdc5858e2cab7fa39ccc53f20 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 18 Jan 2019 12:45:40 -0500
Subject: SL-10153: Update to viewer-manager build 523332

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 382506d8ea..11f7685219 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3138,9 +3138,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>146537bed5c358f69af08b811b3920a1</string>
+              <string>2757602c6f834beade37af5c44649936</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/30016/253294/viewer_manager-2.0.523251-darwin64-523251.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/30130/254747/viewer_manager-2.0.523332-darwin64-523332.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3162,9 +3162,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>fcf98bac94a5145c4f772e6e90a0a78b</string>
+              <string>f1e63c7ae1951d93e5dfd98bdb1a4bed</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/30018/253302/viewer_manager-2.0.523251-windows-523251.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/30131/254755/viewer_manager-2.0.523332-windows-523332.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3175,7 +3175,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.523251</string>
+        <string>2.0.523332</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From 5b64f1939c5e2374a9157796de1ef6891258bbea Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Fri, 18 Jan 2019 20:04:44 +0200
Subject: SL-10153 bat file no longer should be in instal directory

---
 indra/newview/viewer_manifest.py | 1 -
 1 file changed, 1 deletion(-)

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 4e8df5ce29..32773b2c36 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -498,7 +498,6 @@ class WindowsManifest(ViewerManifest):
             with self.prefix(src=os.path.join(pkgdir, "VMP")):
                 # include the compiled launcher scripts so that it gets included in the file_list
                 self.path('SLVersionChecker.exe')
-                self.path('nextviewer.bat')
 
             with self.prefix(dst="vmp_icons"):
                 with self.prefix(src=self.icon_path()):
-- 
cgit v1.2.3


From d785c87d620cb17681ea6d3011461154d96ab9d5 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Tue, 29 Jan 2019 21:33:31 +0200
Subject: SL-2364 Fixed Viewer Caches Login Host DNS Entries Indefinetely

---
 indra/llcorehttp/_httpoprequest.cpp   | 5 +++++
 indra/newview/lllogininstance.cpp     | 7 ++++++-
 indra/newview/llxmlrpctransaction.cpp | 4 ++++
 3 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp
index cc49a2af80..0f76ff23ea 100644
--- a/indra/llcorehttp/_httpoprequest.cpp
+++ b/indra/llcorehttp/_httpoprequest.cpp
@@ -555,6 +555,11 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
 	// about 700 or so requests and starts issuing TCP RSTs to
 	// new connections.  Reuse the DNS lookups for even a few
 	// seconds and no RSTs.
+	//
+	// -1 stores forever
+	// 0  never stores
+	// any other positive number specifies seconds
+	// supposedly curl 7.62.0 can use TTL by default, otherwise default is 60 seconds
 	check_curl_easy_setopt(mCurlHandle, CURLOPT_DNS_CACHE_TIMEOUT, dnsCacheTimeout);
 
 	if (gpolicy.mUseLLProxy)
diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp
index bc93fa2c20..bf4fc029ee 100644
--- a/indra/newview/lllogininstance.cpp
+++ b/indra/newview/lllogininstance.cpp
@@ -63,6 +63,9 @@
 #include <sstream>
 
 const S32 LOGIN_MAX_RETRIES = 3;
+const F32 LOGIN_SRV_TIMEOUT_MIN = 10;
+const F32 LOGIN_SRV_TIMEOUT_MAX = 120;
+const F32 LOGIN_DNS_TIMEOUT_FACTOR = 0.9; // make DNS wait shorter then retry time
 
 class LLLoginInstance::Disposable {
 public:
@@ -232,8 +235,10 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia
 
 	// Specify desired timeout/retry options
 	LLSD http_params;
-	http_params["timeout"] = gSavedSettings.getF32("LoginSRVTimeout");
+	F32 srv_timeout = llclamp(gSavedSettings.getF32("LoginSRVTimeout"), LOGIN_SRV_TIMEOUT_MIN, LOGIN_SRV_TIMEOUT_MAX);
+	http_params["timeout"] = srv_timeout;
 	http_params["retries"] = LOGIN_MAX_RETRIES;
+	http_params["DNSCacheTimeout"] = srv_timeout * LOGIN_DNS_TIMEOUT_FACTOR; //Default: indefinite
 
 	mRequestData.clear();
 	mRequestData["method"] = "login_to_simulator";
diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp
index cc223c1f48..8e2539606b 100644
--- a/indra/newview/llxmlrpctransaction.cpp
+++ b/indra/newview/llxmlrpctransaction.cpp
@@ -362,6 +362,10 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip, const
 	{
 		httpOpts->setRetries(httpParams["retries"].asInteger());
 	}
+	if (httpParams.has("DNSCacheTimeout"))
+	{
+		httpOpts->setDNSCacheTimeout(httpParams["DNSCacheTimeout"].asInteger());
+	}
 
 	bool vefifySSLCert = !gSavedSettings.getBOOL("NoVerifySSLCert");
 	mCertStore = gSavedSettings.getString("CertStore");
-- 
cgit v1.2.3


From aabca008adb91e28c810d7ed50e1ad86f53b7765 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Sat, 2 Feb 2019 13:53:57 -0500
Subject: DRTVWR-447: Comment out Danish and Polish in one more file.

---
 indra/newview/installers/windows/language_menu.nsi | Bin 1448 -> 1464 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)

diff --git a/indra/newview/installers/windows/language_menu.nsi b/indra/newview/installers/windows/language_menu.nsi
index 08ad42532f..2f426a0f47 100644
Binary files a/indra/newview/installers/windows/language_menu.nsi and b/indra/newview/installers/windows/language_menu.nsi differ
-- 
cgit v1.2.3


From cfbe33d7c72c7677836d362fa4026f88df4c9f76 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Sat, 2 Feb 2019 14:01:39 -0500
Subject: SL-10396: Disable per-user installs: require Admin for all-users.

---
 .../installers/windows/installer_template.nsi      | 46 ++++++++++++++++++----
 1 file changed, 39 insertions(+), 7 deletions(-)

diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index 9a304559e1..4afef4630c 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -32,7 +32,7 @@ SetCompress auto			# Compress if saves space
 SetCompressor /solid lzma	# Compress whole installer as one block
 SetDatablockOptimize off	# Only saves us 0.1%, not worth it
 XPStyle on                  # Add an XP manifest to the installer
-RequestExecutionLevel highest           # match MULTIUSER_EXECUTIONLEVEL
+RequestExecutionLevel admin	# For when we write to Program Files
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Project flags
@@ -106,11 +106,12 @@ AutoCloseWindow true					# After all files install, close window
 !define MSUNINSTALL_KEY "${MSCURRVER_KEY}\Uninstall\${INSTNAME}"
 
 # from http://nsis.sourceforge.net/Docs/MultiUser/Readme.html
-# Highest level permitted for user: Admin for Admin, Standard for Standard
-!define MULTIUSER_EXECUTIONLEVEL Highest
+### Highest level permitted for user: Admin for Admin, Standard for Standard
+##!define MULTIUSER_EXECUTIONLEVEL Highest
+!define MULTIUSER_EXECUTIONLEVEL Admin
 !define MULTIUSER_MUI
-# Look for /AllUsers or /CurrentUser switches
-!define MULTIUSER_INSTALLMODE_COMMANDLINE
+### Look for /AllUsers or /CurrentUser switches
+##!define MULTIUSER_INSTALLMODE_COMMANDLINE
 # appended to $PROGRAMFILES, as affected by MULTIUSER_USE_PROGRAMFILES64
 !define MULTIUSER_INSTALLMODE_INSTDIR "${INSTNAME}"
 # expands to !define MULTIUSER_USE_PROGRAMFILES64 or nothing
@@ -131,7 +132,7 @@ AutoCloseWindow true					# After all files install, close window
 
 UninstallText $(UninstallTextMsg)
 DirText $(DirectoryChooseTitle) $(DirectoryChooseSetup)
-!insertmacro MULTIUSER_PAGE_INSTALLMODE
+##!insertmacro MULTIUSER_PAGE_INSTALLMODE
 !define MUI_PAGE_CUSTOMFUNCTION_PRE dirPre
 !insertmacro MUI_PAGE_DIRECTORY
 !insertmacro MUI_PAGE_INSTFILES
@@ -326,6 +327,7 @@ StrCpy $INSTEXE "${INSTEXE}"
 StrCpy $VIEWER_EXE "${VIEWER_EXE}"
 StrCpy $INSTSHORTCUT "${SHORTCUT}"
 
+Call CheckIfAdministrator		# Make sure the user can install/uninstall
 Call CloseSecondLife			# Make sure Second Life not currently running
 Call CheckWillUninstallV2		# Check if Second Life is already installed
 
@@ -433,7 +435,7 @@ StrCpy $INSTSHORTCUT "${SHORTCUT}"
 # SetShellVarContext per the mode saved at install time in registry at
 # MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY
 # MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME
-# Couln't get NSIS to expand $MultiUser.InstallMode into the function name at Call time
+# Couldn't get NSIS to expand $MultiUser.InstallMode into the function name at Call time
 ${If} $MultiUser.InstallMode == 'AllUsers'
 ##MessageBox MB_OK "Uninstalling for all users"
   Call un.MultiUser.InstallMode.AllUsers
@@ -469,6 +471,36 @@ Call un.UserSettingsFiles
 
 SectionEnd
 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Make sure the user can install
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+Function CheckIfAdministrator
+    DetailPrint $(CheckAdministratorInstDP)
+    UserInfo::GetAccountType
+    Pop $R0
+    StrCmp $R0 "Admin" lbl_is_admin
+        MessageBox MB_OK $(CheckAdministratorInstMB)
+        Quit
+lbl_is_admin:
+    Return
+
+FunctionEnd
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Make sure the user can uninstall
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+Function un.CheckIfAdministrator
+    DetailPrint $(CheckAdministratorUnInstDP)
+    UserInfo::GetAccountType
+    Pop $R0
+    StrCmp $R0 "Admin" lbl_is_admin
+        MessageBox MB_OK $(CheckAdministratorUnInstMB)
+        Quit
+lbl_is_admin:
+    Return
+
+FunctionEnd
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Function CheckWillUninstallV2               
 ;;
-- 
cgit v1.2.3


From 899cdb8a1b32d7d39b3a4b78ba41a0f4d87cb52f Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Sat, 2 Feb 2019 16:32:22 -0500
Subject: SL-9980: Update to viewer-manager 524014 to drop Admin for viewer.

But since that viewer-manager build depends on being able to read the
application name from build_data.json (to locate the shortcut), add an AppName
key to build_data.json.
---
 autobuild.xml                    | 10 +++++-----
 indra/newview/viewer_manifest.py |  3 ++-
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 11f7685219..0773491363 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3138,9 +3138,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>2757602c6f834beade37af5c44649936</string>
+              <string>0aa5e6a12d9777ab85b8534cfce5de30</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/30130/254747/viewer_manager-2.0.523332-darwin64-523332.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/31625/264561/viewer_manager-2.0.524014-darwin64-524014.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3162,9 +3162,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>f1e63c7ae1951d93e5dfd98bdb1a4bed</string>
+              <string>6858cac5abba956fe9dd5c86caff809c</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/30131/254755/viewer_manager-2.0.523332-windows-523332.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/31626/264568/viewer_manager-2.0.524014-windows-524014.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3175,7 +3175,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.523332</string>
+        <string>2.0.524014</string>
       </map>
       <key>vlc-bin</key>
       <map>
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 32773b2c36..c0f642c852 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -431,7 +431,8 @@ class WindowsManifest(ViewerManifest):
 
     def finish_build_data_dict(self, build_data_dict):
         #MAINT-7294: Windows exe names depend on channel name, so write that in also
-        build_data_dict.update({'Executable':self.final_exe()})
+        build_data_dict['Executable'] = self.final_exe()
+        build_data_dict['AppName']    = self.app_name()
         return build_data_dict
 
     def test_msvcrt_and_copy_action(self, src, dst):
-- 
cgit v1.2.3


From 35bc6df9699da11c826843e4b81a0d0216e2ca54 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 4 Feb 2019 13:15:22 -0500
Subject: SL-9980: Update to viewer-manager build 524032

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 0773491363..58b08142f4 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3138,9 +3138,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>0aa5e6a12d9777ab85b8534cfce5de30</string>
+              <string>b902cbd59c65246051ae849a62db2c9d</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/31625/264561/viewer_manager-2.0.524014-darwin64-524014.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/31663/264771/viewer_manager-2.0.524032-darwin64-524032.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3162,9 +3162,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>6858cac5abba956fe9dd5c86caff809c</string>
+              <string>a56f0df71a04e868e4b992de3fe917e3</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/31626/264568/viewer_manager-2.0.524014-windows-524014.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/31664/264779/viewer_manager-2.0.524032-windows-524032.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3175,7 +3175,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.524014</string>
+        <string>2.0.524032</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From d903f8c1a1509c87af9bf5c173cab685be7dee03 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Tue, 5 Feb 2019 16:14:27 +0200
Subject: SL-10470 Fixed freeze due to extensive logging

---
 indra/newview/llinventorybridge.cpp |  2 +-
 indra/newview/llinventorymodel.cpp  | 16 +++++++++++++---
 indra/newview/llinventorypanel.cpp  |  3 ++-
 3 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index e7367d5ced..00b7732ee9 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -1415,7 +1415,7 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type,
 			break;
 
 		default:
-			LL_INFOS() << "Unhandled asset type (llassetstorage.h): "
+			LL_INFOS_ONCE() << "Unhandled asset type (llassetstorage.h): "
 					<< (S32)asset_type << " (" << LLAssetType::lookup(asset_type) << ")" << LL_ENDL;
 			break;
 	}
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index a520e0171e..b140c7c38e 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -1820,9 +1820,19 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item)
 
 		if (LLAssetType::lookup(item->getType()) == LLAssetType::badLookup())
 		{
-			LL_WARNS(LOG_INV) << "Got unknown asset type for item [ name: " << item->getName()
-				<< " type: " << item->getType()
-				<< " inv-type: " << item->getInventoryType() << " ]." << LL_ENDL;
+			if (item->getType() >= LLAssetType::AT_COUNT)
+			{
+				// Not yet supported.
+				LL_DEBUGS(LOG_INV) << "Got unknown asset type for item [ name: " << item->getName()
+					<< " type: " << item->getType()
+					<< " inv-type: " << item->getInventoryType() << " ]." << LL_ENDL;
+			}
+			else
+			{
+				LL_WARNS(LOG_INV) << "Got unknown asset type for item [ name: " << item->getName()
+					<< " type: " << item->getType()
+					<< " inv-type: " << item->getInventoryType() << " ]." << LL_ENDL;
+			}
 		}
 
 		// This condition means that we tried to add a link without the baseobj being in memory.
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 3992b506e9..d4993a1091 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -871,7 +871,8 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
 			
 			if (objectp->getType() >= LLAssetType::AT_COUNT)
   			{
-  				LL_WARNS() << "LLInventoryPanel::buildNewViews called with unknown objectp->mType : "
+				// Example: Happens when we add assets of new, not yet supported type to library
+				LL_DEBUGS() << "LLInventoryPanel::buildNewViews called with unknown objectp->mType : "
 				<< ((S32) objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID()
 				<< LL_ENDL;
 
-- 
cgit v1.2.3


From c0abc508f9bdedf05748186472ea433cd8ddd9c6 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Tue, 5 Feb 2019 17:30:24 +0200
Subject: SL-10466 Viewer throwing misleading notification

---
 indra/newview/llviewermessage.cpp                  | 29 ++++++----------------
 .../newview/skins/default/xui/en/notifications.xml | 22 ----------------
 2 files changed, 7 insertions(+), 44 deletions(-)

diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 981d226824..e50c8ee9f0 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -5531,17 +5531,6 @@ void notify_cautioned_script_question(const LLSD& notification, const LLSD& resp
 
 void script_question_mute(const LLUUID& item_id, const std::string& object_name);
 
-bool unknown_script_question_cb(const LLSD& notification, const LLSD& response)
-{
-	// Only care if they muted the object here.
-	if ( response["Mute"] ) // mute
-	{
-		LLUUID task_id = notification["payload"]["task_id"].asUUID();
-		script_question_mute(task_id,notification["payload"]["object_name"].asString());
-	}
-	return false;
-}
-
 void experiencePermissionBlock(LLUUID experience, LLSD result)
 {
     LLSD permission;
@@ -5647,8 +5636,7 @@ void script_question_mute(const LLUUID& task_id, const std::string& object_name)
       	bool matches(const LLNotificationPtr notification) const
         {
             if (notification->getName() == "ScriptQuestionCaution"
-                || notification->getName() == "ScriptQuestion"
-				|| notification->getName() == "UnknownScriptQuestion")
+                || notification->getName() == "ScriptQuestion")
             {
                 return (notification->getPayload()["task_id"].asUUID() == blocked_id);
             }
@@ -5665,7 +5653,6 @@ void script_question_mute(const LLUUID& task_id, const std::string& object_name)
 static LLNotificationFunctorRegistration script_question_cb_reg_1("ScriptQuestion", script_question_cb);
 static LLNotificationFunctorRegistration script_question_cb_reg_2("ScriptQuestionCaution", script_question_cb);
 static LLNotificationFunctorRegistration script_question_cb_reg_3("ScriptQuestionExperience", script_question_cb);
-static LLNotificationFunctorRegistration unknown_script_question_cb_reg("UnknownScriptQuestion", unknown_script_question_cb);
 
 void process_script_experience_details(const LLSD& experience_details, LLSD args, LLSD payload)
 {
@@ -5778,14 +5765,12 @@ void process_script_question(LLMessageSystem *msg, void **user_data)
 		args["QUESTIONS"] = script_question;
 
 		if (known_questions != questions)
-		{	// This is in addition to the normal dialog.
-			LLSD payload;
-			payload["task_id"] = taskid;
-			payload["item_id"] = itemid;
-			payload["object_name"] = object_name;
-			
-			args["DOWNLOADURL"] = LLTrans::getString("ViewerDownloadURL");
-			LLNotificationsUtil::add("UnknownScriptQuestion",args,payload);
+		{
+			// This is in addition to the normal dialog.
+			// Viewer got a request for not supported/implemented permission 
+			LL_WARNS("Messaging") << "Object \"" << object_name << "\" requested " << script_question
+								<< " permission. Permission is unknown and can't be granted. Item id: " << itemid
+								<< " taskid:" << taskid << LL_ENDL;
 		}
 		
 		if (known_questions)
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 23a8d21f8a..efc5a30b63 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -7766,28 +7766,6 @@ Do not allow access if you do not fully understand why it wants access to your a
     </footer>
   </notification>
 
-  <notification
-   icon="notify.tga"
-	 name="UnknownScriptQuestion"
-	 persist="false"
-	 type="notify">
-The runtime script permission requested by &apos;&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;&apos;, an object owned by &apos;[NAME]&apos;, isn&apos;t recognized by the viewer and can&apos;t be granted.
-
-To grant this permission please update your viewer to the latest version from [DOWNLOADURL].
-		<tag>confirm</tag>
-		<form name="form">
-			<button
-			 default="true"
-			 index="1"
-			 name="Deny"
-			 text="Ok"/>
-			<button
-			 index="2"
-			 name="Mute"
-			 text="Block"/>
-		</form>
-	</notification>
-
 	<notification
    icon="notify.tga"
    name="ScriptDialog"
-- 
cgit v1.2.3


From d588660db1a1232731e3fb29eadc1c3951bf5dc3 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 5 Feb 2019 14:35:36 -0500
Subject: SL-10469: Remove any similar shortcuts for old per-user install.

---
 .../newview/installers/windows/installer_template.nsi  | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index 4afef4630c..8af0f057ae 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -602,6 +602,24 @@ RMDir /r "$INSTDIR\skins"
 Delete "$SMPROGRAMS\$INSTSHORTCUT\SL Release Notes.lnk"
 Delete "$INSTDIR\releasenotes.txt"
 
+# SL-10469: During the brief period when the BugSplat RC supported "current
+# user" installs, we might have put a shortcut with this same $INSTSHORTCUT
+# name in the Start menu folder for "current user" programs. Even though we're
+# about to write our new shortcut to the Start menu folder for "all users,"
+# apparently Windows 7 only shows one of them. (Windows 10 reportedly shows
+# both.) Try temporarily setting "current user," just long enough to delete
+# any such old shortcuts.
+SetShellVarContext current
+
+# This stanza should match the $SMPROGRAMS and $DESKTOP deletions in the
+# "clean up shortcuts" passage in Section Uninstall. Don't bother with the
+# shortcuts in $INSTDIR because we're just about to (over)write those.
+Delete "$SMPROGRAMS\$INSTSHORTCUT\*.*"
+RMDir  "$SMPROGRAMS\$INSTSHORTCUT"
+Delete "$DESKTOP\$INSTSHORTCUT.lnk"
+
+SetShellVarContext all
+
 FunctionEnd
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-- 
cgit v1.2.3


From a77344516ce00ed7b447626c1d57195dd183b7f9 Mon Sep 17 00:00:00 2001
From: "Brad Payne (Vir Linden)" <vir@lindenlab.com>
Date: Tue, 5 Feb 2019 21:38:00 +0000
Subject: SL-10471 - animation validation for constraints

---
 indra/llappearance/llavatarappearance.cpp |  2 +-
 indra/llcharacter/llkeyframemotion.cpp    | 14 ++++++++++++++
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp
index 92217c60ff..c28b5f8081 100644
--- a/indra/llappearance/llavatarappearance.cpp
+++ b/indra/llappearance/llavatarappearance.cpp
@@ -1350,7 +1350,7 @@ LLVector3 LLAvatarAppearance::getVolumePos(S32 joint_index, LLVector3& volume_of
 //-----------------------------------------------------------------------------
 LLJoint* LLAvatarAppearance::findCollisionVolume(U32 volume_id)
 {
-	if ((S32)volume_id > mNumCollisionVolumes)
+	if (((S32)volume_id >= mNumCollisionVolumes) || ((S32)volume_id < 0))
 	{
 		return NULL;
 	}
diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp
index 330d812985..5d323ed5d6 100644
--- a/indra/llcharacter/llkeyframemotion.cpp
+++ b/indra/llcharacter/llkeyframemotion.cpp
@@ -1772,6 +1772,13 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id)
 			bin_data[BIN_DATA_LENGTH] = 0; // Ensure null termination
 			str = (char*)bin_data;
 			constraintp->mSourceConstraintVolume = mCharacter->getCollisionVolumeID(str);
+			if (constraintp->mSourceConstraintVolume == -1)
+			{
+				LL_WARNS() << "not a valid source constraint volume " << str
+						   << " for animation " << asset_id << LL_ENDL;
+				delete constraintp;
+				return FALSE;
+			}
 
 			if (!dp.unpackVector3(constraintp->mSourceConstraintOffset, "source_offset"))
 			{
@@ -1808,6 +1815,13 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id)
 			{
 				constraintp->mConstraintTargetType = CONSTRAINT_TARGET_TYPE_BODY;
 				constraintp->mTargetConstraintVolume = mCharacter->getCollisionVolumeID(str);
+				if (constraintp->mTargetConstraintVolume == -1)
+				{
+					LL_WARNS() << "not a valid target constraint volume " << str
+							   << " for animation " << asset_id << LL_ENDL;
+					delete constraintp;
+					return FALSE;
+				}
 			}
 
 			if (!dp.unpackVector3(constraintp->mTargetConstraintOffset, "target_offset"))
-- 
cgit v1.2.3


From 2d3b805b949a294d3f298eb3d786aac777ebb51e Mon Sep 17 00:00:00 2001
From: "Brad Payne (Vir Linden)" <vir@lindenlab.com>
Date: Wed, 6 Feb 2019 13:44:54 +0000
Subject: SL-10471 - collision volume api

---
 indra/llappearance/llavatarappearance.cpp | 4 ++--
 indra/llappearance/llavatarappearance.h   | 2 +-
 indra/llcharacter/llcharacter.h           | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp
index c28b5f8081..38cda2e2f1 100644
--- a/indra/llappearance/llavatarappearance.cpp
+++ b/indra/llappearance/llavatarappearance.cpp
@@ -1348,9 +1348,9 @@ LLVector3 LLAvatarAppearance::getVolumePos(S32 joint_index, LLVector3& volume_of
 //-----------------------------------------------------------------------------
 // findCollisionVolume()
 //-----------------------------------------------------------------------------
-LLJoint* LLAvatarAppearance::findCollisionVolume(U32 volume_id)
+LLJoint* LLAvatarAppearance::findCollisionVolume(S32 volume_id)
 {
-	if (((S32)volume_id >= mNumCollisionVolumes) || ((S32)volume_id < 0))
+	if ((volume_id < 0) || (volume_id >= mNumCollisionVolumes))
 	{
 		return NULL;
 	}
diff --git a/indra/llappearance/llavatarappearance.h b/indra/llappearance/llavatarappearance.h
index 7815c1844b..6a4dbf3726 100644
--- a/indra/llappearance/llavatarappearance.h
+++ b/indra/llappearance/llavatarappearance.h
@@ -93,7 +93,7 @@ public:
 
 	/*virtual*/ const char*		getAnimationPrefix() { return "avatar"; }
 	/*virtual*/ LLVector3		getVolumePos(S32 joint_index, LLVector3& volume_offset);
-	/*virtual*/ LLJoint*		findCollisionVolume(U32 volume_id);
+	/*virtual*/ LLJoint*		findCollisionVolume(S32 volume_id);
 	/*virtual*/ S32				getCollisionVolumeID(std::string &name);
 	/*virtual*/ LLPolyMesh*		getHeadMesh();
 	/*virtual*/ LLPolyMesh*		getUpperBodyMesh();
diff --git a/indra/llcharacter/llcharacter.h b/indra/llcharacter/llcharacter.h
index 1a3e307663..2fac5f53a6 100644
--- a/indra/llcharacter/llcharacter.h
+++ b/indra/llcharacter/llcharacter.h
@@ -177,7 +177,7 @@ public:
 
 	virtual LLVector3 getVolumePos(S32 joint_index, LLVector3& volume_offset) { return LLVector3::zero; }
 	
-	virtual LLJoint* findCollisionVolume(U32 volume_id) { return NULL; }
+	virtual LLJoint* findCollisionVolume(S32 volume_id) { return NULL; }
 
 	virtual S32 getCollisionVolumeID(std::string &name) { return -1; }
 
-- 
cgit v1.2.3


From d779a03f0bee51110a30a52eecc352f5074fa30a Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 6 Feb 2019 09:17:06 -0500
Subject: SL-10469: Add diagnostic popup when trying to delete old shortcuts.

---
 .../installers/windows/installer_template.nsi      | 26 ++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index 8af0f057ae..6bf4dba142 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -611,6 +611,32 @@ Delete "$INSTDIR\releasenotes.txt"
 # any such old shortcuts.
 SetShellVarContext current
 
+Push $0 # FindFirst context
+Push $1 # FindFirst/FindNext filename
+Push $2 # cumulative filenames
+
+StrCpy $2 "Checking $SMPROGRAMS\$INSTSHORTCUT$\nAbout to delete:"
+
+ClearErrors
+FindFirst $0 $1 "$SMPROGRAMS\$INSTSHORTCUT\*.*"
+loop:
+IfErrors done
+  StrCpy $2 "$2$\n$SMPROGRAMS\$INSTSHORTCUT\$1"
+  FindNext $0 $1
+  Goto loop
+done:
+FindClose $0
+
+StrCpy $2 "$2$\n$\nChecking $DESKTOP\$INSTSHORTCUT.lnk"
+IfFileExists   "$DESKTOP\$INSTSHORTCUT.lnk" 0 +2
+StrCpy $2 "$2$\n$DESKTOP\$INSTSHORTCUT.lnk"
+
+MessageBox MB_OK "$2"
+
+Pop $2
+Pop $1
+Pop $0
+
 # This stanza should match the $SMPROGRAMS and $DESKTOP deletions in the
 # "clean up shortcuts" passage in Section Uninstall. Don't bother with the
 # shortcuts in $INSTDIR because we're just about to (over)write those.
-- 
cgit v1.2.3


From 5196bab897a2ef5810718409b98919c0642dc97e Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 6 Feb 2019 13:14:17 -0500
Subject: SL-10469: Remove old-shortcut cleanup cruft: only works for Admin.

The installer is (once again) running with Admin privilege elevation even for
a Standard Windows user, so it can't determine the underlying Standard user.
Therefore it can't clean up any per-user shortcuts left over for that Standard
user. Moved the kludge to SLVersionChecker.
---
 .../installers/windows/installer_template.nsi      | 44 ----------------------
 1 file changed, 44 deletions(-)

diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index 6bf4dba142..4afef4630c 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -602,50 +602,6 @@ RMDir /r "$INSTDIR\skins"
 Delete "$SMPROGRAMS\$INSTSHORTCUT\SL Release Notes.lnk"
 Delete "$INSTDIR\releasenotes.txt"
 
-# SL-10469: During the brief period when the BugSplat RC supported "current
-# user" installs, we might have put a shortcut with this same $INSTSHORTCUT
-# name in the Start menu folder for "current user" programs. Even though we're
-# about to write our new shortcut to the Start menu folder for "all users,"
-# apparently Windows 7 only shows one of them. (Windows 10 reportedly shows
-# both.) Try temporarily setting "current user," just long enough to delete
-# any such old shortcuts.
-SetShellVarContext current
-
-Push $0 # FindFirst context
-Push $1 # FindFirst/FindNext filename
-Push $2 # cumulative filenames
-
-StrCpy $2 "Checking $SMPROGRAMS\$INSTSHORTCUT$\nAbout to delete:"
-
-ClearErrors
-FindFirst $0 $1 "$SMPROGRAMS\$INSTSHORTCUT\*.*"
-loop:
-IfErrors done
-  StrCpy $2 "$2$\n$SMPROGRAMS\$INSTSHORTCUT\$1"
-  FindNext $0 $1
-  Goto loop
-done:
-FindClose $0
-
-StrCpy $2 "$2$\n$\nChecking $DESKTOP\$INSTSHORTCUT.lnk"
-IfFileExists   "$DESKTOP\$INSTSHORTCUT.lnk" 0 +2
-StrCpy $2 "$2$\n$DESKTOP\$INSTSHORTCUT.lnk"
-
-MessageBox MB_OK "$2"
-
-Pop $2
-Pop $1
-Pop $0
-
-# This stanza should match the $SMPROGRAMS and $DESKTOP deletions in the
-# "clean up shortcuts" passage in Section Uninstall. Don't bother with the
-# shortcuts in $INSTDIR because we're just about to (over)write those.
-Delete "$SMPROGRAMS\$INSTSHORTCUT\*.*"
-RMDir  "$SMPROGRAMS\$INSTSHORTCUT"
-Delete "$DESKTOP\$INSTSHORTCUT.lnk"
-
-SetShellVarContext all
-
 FunctionEnd
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-- 
cgit v1.2.3


From 0d27cb37bfea618896b0b4c5a422880e1a882210 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 6 Feb 2019 13:20:26 -0500
Subject: SL-10469: Update to viewer-manager build 524157

---
 autobuild.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 58b08142f4..9b7ff39334 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3138,9 +3138,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>b902cbd59c65246051ae849a62db2c9d</string>
+              <string>aaf04f5ed1d28477781d976dc04871ee</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/31663/264771/viewer_manager-2.0.524032-darwin64-524032.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/31904/266163/viewer_manager-2.0.524157-darwin64-524157.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3162,9 +3162,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>a56f0df71a04e868e4b992de3fe917e3</string>
+              <string>4604624f11b215b052f4a840f4da4bf8</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/31664/264779/viewer_manager-2.0.524032-windows-524032.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/31906/266177/viewer_manager-2.0.524157-windows-524157.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3175,7 +3175,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.524032</string>
+        <string>2.0.524157</string>
       </map>
       <key>vlc-bin</key>
       <map>
-- 
cgit v1.2.3


From 59e47021a0a39324bd318ffb974730f253f753e9 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Thu, 7 Feb 2019 18:38:42 +0200
Subject: SL-10349 Tooltips consistency

---
 indra/newview/skins/default/xui/en/floater_bulk_perms.xml  | 6 +++++-
 indra/newview/skins/default/xui/en/floater_tools.xml       | 6 +++++-
 indra/newview/skins/default/xui/en/sidepanel_item_info.xml | 5 ++++-
 indra/newview/skins/default/xui/en/sidepanel_task_info.xml | 4 ++++
 4 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/indra/newview/skins/default/xui/en/floater_bulk_perms.xml b/indra/newview/skins/default/xui/en/floater_bulk_perms.xml
index e7ab3cacdc..9fa93b640f 100644
--- a/indra/newview/skins/default/xui/en/floater_bulk_perms.xml
+++ b/indra/newview/skins/default/xui/en/floater_bulk_perms.xml
@@ -213,6 +213,7 @@
      layout="topleft"
      top_pad="0"
      name="share_with_group"
+     tool_tip="Allow all members of the set group to share your modify permissions for this object. You must Deed to enable role restrictions."
      width="92" />
         <text
      type="string"
@@ -234,6 +235,7 @@
      layout="topleft"
      top_pad="0"
      name="everyone_copy"
+     tool_tip="Anyone can take a copy of the object. Object and all of its contents must be copy and transfer permissive"
      width="92" />
     <text
      type="string"
@@ -254,6 +256,7 @@
      label="Modify"
      layout="topleft"
      name="next_owner_modify"
+     tool_tip="Next owner can edit properties like item name or scale of this object."
      top_pad="0"
      width="92" />
     <check_box
@@ -263,6 +266,7 @@
      layout="topleft"
      top_pad="0"
      name="next_owner_copy"
+     tool_tip="Next owner can make unlimited copies of this object. Copies maintain creator information, and can never be more permissive than the item being copied."
      width="92">
       <check_box.commit_callback
        function="BulkPermission.CommitCopy"/>
@@ -276,7 +280,7 @@
      label="Transfer"
      layout="topleft"
      name="next_owner_transfer"
-     tool_tip="Next owner can give away or resell this object"
+     tool_tip="Next owner can give away or resell this object."
      width="92" />
     <scroll_list
      enabled="false"
diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml
index d9a15fed9e..ae0820c3ac 100644
--- a/indra/newview/skins/default/xui/en/floater_tools.xml
+++ b/indra/newview/skins/default/xui/en/floater_tools.xml
@@ -1219,6 +1219,7 @@ even though the user gets a free copy.
              label="Move"
              layout="topleft"
              name="checkbox allow everyone move"
+             tool_tip="Anyone can move the object."
              left="10"
              width="85" />
             <check_box
@@ -1227,6 +1228,7 @@ even though the user gets a free copy.
              layout="topleft"
              left_pad="0"
              name="checkbox allow everyone copy"
+             tool_tip="Anyone can take a copy of the object. Object and all of its contents must be copy and transfer permissive."
              width="90" />
             <text
                type="string"
@@ -1244,6 +1246,7 @@ even though the user gets a free copy.
              left="10"
              height="10"
              name="checkbox next owner can modify"
+             tool_tip="Next owner can edit properties like item name or scale of this object."
              width="85" />
             <check_box
              follows="left|top|right"
@@ -1252,6 +1255,7 @@ even though the user gets a free copy.
              layout="topleft"
              left_pad="0"
              name="checkbox next owner can copy"
+             tool_tip="Next owner can make unlimited copies of this object. Copies maintain creator information, and can never be more permissive than the item being copied."
              width="80" />
             <check_box
              follows="left|top|right"
@@ -1261,7 +1265,7 @@ even though the user gets a free copy.
              name="checkbox next owner can transfer"
              left_pad="0"
              top_delta="0"
-             tool_tip="Next owner can give away or resell this object"
+             tool_tip="Next owner can give away or resell this object."
              width="100" />
 <!-- *NOTE: These "B/O/G/E/N/F fields may overlap "perm_modify" above, 
      but that's OK, this is used only for debugging. -->
diff --git a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
index fd14b13ed6..ca1dc87134 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
@@ -351,6 +351,7 @@
           layout="topleft"
           left_pad="0"
           name="CheckEveryoneCopy"
+          tool_tip="Anyone can take a copy of the object . Object and all of its contents must be copy and transfer permissive."
           top_delta="-2"
           width="150" />
         <text
@@ -394,6 +395,7 @@
           left="20"
           top_pad="0"
           name="CheckNextOwnerModify"
+          tool_tip="Next owner can edit properties like item name or scale of this object."
           width="90" />
         <check_box
           height="18"
@@ -401,6 +403,7 @@
           layout="topleft"
           left_pad="0"
           name="CheckNextOwnerCopy"
+          tool_tip="Next owner can make unlimited copies of this object. Copies maintain creator information, and can never be more permissive than the item being copied."
           width="90" />
         <check_box
           height="18"
@@ -408,7 +411,7 @@
           layout="topleft"
           left_pad="0"
           name="CheckNextOwnerTransfer"
-          tool_tip="Next owner can give away or resell this object"
+          tool_tip="Next owner can give away or resell this object."
           width="106" />
       </panel>
       <check_box
diff --git a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
index efedb9559e..713d5f94bb 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
@@ -344,6 +344,7 @@
 			 layout="topleft"
 			 left_pad="0"
              name="checkbox allow everyone copy"
+             tool_tip="Anyone can take a copy of the object. Object and all of its contents must be copy and transfer permissive."
 			 top_delta="-2"
 			 width="90" />
 	    <check_box
@@ -351,6 +352,7 @@
              label="Move"
              layout="topleft"
              name="checkbox allow everyone move"
+             tool_tip="Anyone can move the object."
 			 left_pad="0"
              width="150" />
 	       	<text
@@ -394,6 +396,7 @@
 			 left="20"
 			 top_pad="0"
              name="checkbox next owner can modify"
+             tool_tip="Next owner can edit properties like item name or scale of this object."
 			 width="90" />
 	    <check_box
 			 height="18"
@@ -401,6 +404,7 @@
 			 layout="topleft"
 			 left_pad="0"
              name="checkbox next owner can copy"
+             tool_tip="Next owner can make unlimited copies of this object. Copies maintain creator information, and can never be more permissive than the item being copied."
 			 width="90" />
 	    <check_box
 			 height="18"
-- 
cgit v1.2.3


From eb1c3c5cbbbe687235dc7db2d527e04578ea1d54 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Fri, 8 Feb 2019 22:22:06 +0200
Subject: Fix for teamcity W64 build freeze.

---
 indra/llcorehttp/tests/test_httprequest.hpp | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/indra/llcorehttp/tests/test_httprequest.hpp b/indra/llcorehttp/tests/test_httprequest.hpp
index b450f3502e..4ac3f6f991 100644
--- a/indra/llcorehttp/tests/test_httprequest.hpp
+++ b/indra/llcorehttp/tests/test_httprequest.hpp
@@ -2903,6 +2903,9 @@ void HttpRequestTestObjectType::test<22>()
 	
 	set_test_name("BUG-2295");
 
+#if LL_WINDOWS && ADDRESS_SIZE == 64
+	skip("BUG-2295 - partial load on W64 causes freeze");
+#endif
 	// Handler can be stack-allocated *if* there are no dangling
 	// references to it after completion of this method.
 	// Create before memory record as the string copy will bump numbers.
@@ -2921,6 +2924,7 @@ void HttpRequestTestObjectType::test<22>()
         // options set
         options = HttpOptions::ptr_t(new HttpOptions());
 		options->setRetries(1);			// Partial_File is retryable and can timeout in here
+		options->setDNSCacheTimeout(30);
 
 		// Get singletons created
 		HttpRequest::createService();
-- 
cgit v1.2.3


From 1ff58087a9b4fcc7482079ca88523eace37f264c Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Sat, 9 Feb 2019 10:51:00 -0500
Subject: SL-10506: Disregard any previous installation. Start from scratch.

---
 indra/newview/installers/windows/installer_template.nsi | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index 4afef4630c..ff064b5f1e 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -117,8 +117,9 @@ AutoCloseWindow true					# After all files install, close window
 # expands to !define MULTIUSER_USE_PROGRAMFILES64 or nothing
 %%PROGRAMFILES%%
 # should make MultiUser.nsh initialization read existing INSTDIR from registry
-!define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY "${INSTNAME_KEY}"
-!define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME ""
+## SL-10506: don't
+##!define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY "${INSTNAME_KEY}"
+##!define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME ""
 # Don't set MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY and
 # MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME to cause the installer to
 # write $MultiUser.InstallMode to the registry, because when the user installs
-- 
cgit v1.2.3


From b31cd0a7e927920fae820582fcff78078e6f3bfc Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Mon, 11 Feb 2019 17:40:41 +0200
Subject: SL-10347 Fixed Users can't exchange text messages after moderator
 click on "Mute everyone"

---
 indra/newview/llconversationmodel.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index ebbbf23dee..bea1f78284 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -605,16 +605,16 @@ void LLConversationItemParticipant::muteVoice(bool mute_voice)
 	LLAvatarName av_name;
 	LLAvatarNameCache::get(mUUID, &av_name);
 	LLMuteList * mute_listp = LLMuteList::getInstance();
-	bool voice_already_muted = mute_listp->isMuted(mUUID, av_name.getUserName());
+	bool voice_already_muted = mute_listp->isMuted(mUUID, av_name.getUserName(), LLMute::flagVoiceChat);
 
 	LLMute mute(mUUID, av_name.getUserName(), LLMute::AGENT);
 	if (voice_already_muted && !mute_voice)
 	{
-		mute_listp->remove(mute);
+		mute_listp->remove(mute, LLMute::flagVoiceChat);
 	}
 	else if (!voice_already_muted && mute_voice)
 	{
-		mute_listp->add(mute);
+		mute_listp->add(mute, LLMute::flagVoiceChat);
 	}
 }
 
-- 
cgit v1.2.3


From 3a8053eb9fc0db52b9fb5ae02f1807acbb4e072d Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Mon, 11 Feb 2019 19:01:28 +0200
Subject: SL-10351 Fixed Avatars muted by Group moderator become Blocked
 forever

---
 indra/newview/llconversationmodel.cpp |  6 ++++--
 indra/newview/llconversationmodel.h   |  3 +++
 indra/newview/llconversationview.cpp  | 14 ++++++++++++++
 indra/newview/llconversationview.h    |  1 +
 indra/newview/lloutputmonitorctrl.cpp |  5 +++--
 indra/newview/lloutputmonitorctrl.h   |  6 +++++-
 6 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index bea1f78284..c715815208 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -351,7 +351,7 @@ void LLConversationItemSession::setParticipantIsMuted(const LLUUID& participant_
 	LLConversationItemParticipant* participant = findParticipant(participant_id);
 	if (participant)
 	{
-		participant->muteVoice(is_muted);
+		participant->moderateVoice(is_muted);
 	}
 }
 
@@ -498,6 +498,7 @@ void LLConversationItemSession::onAvatarNameCache(const LLAvatarName& av_name)
 
 LLConversationItemParticipant::LLConversationItemParticipant(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
 	LLConversationItem(display_name,uuid,root_view_model),
+	mIsModeratorMuted(false),
 	mIsModerator(false),
 	mDisplayModeratorLabel(false),
 	mDistToAgent(-1.0)
@@ -508,6 +509,7 @@ LLConversationItemParticipant::LLConversationItemParticipant(std::string display
 
 LLConversationItemParticipant::LLConversationItemParticipant(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
 	LLConversationItem(uuid,root_view_model),
+	mIsModeratorMuted(false),
 	mIsModerator(false),
 	mDisplayModeratorLabel(false),
 	mDistToAgent(-1.0)
@@ -597,7 +599,7 @@ void LLConversationItemParticipant::setDisplayModeratorRole(bool displayRole)
 
 bool LLConversationItemParticipant::isVoiceMuted()
 {
-	return LLMuteList::getInstance()->isMuted(mUUID, LLMute::flagVoiceChat);
+	return mIsModeratorMuted || LLMuteList::getInstance()->isMuted(mUUID, LLMute::flagVoiceChat);
 }
 
 void LLConversationItemParticipant::muteVoice(bool mute_voice)
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 3868bafae4..2da9f03c6c 100644
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -194,8 +194,10 @@ public:
 	virtual const std::string& getDisplayName() const { return mDisplayName; }
 
 	bool isVoiceMuted();
+	bool isModeratorMuted() { return mIsModeratorMuted; }
 	bool isModerator() const { return mIsModerator; }
 	void muteVoice(bool mute_voice);
+	void moderateVoice(bool mute_voice) { mIsModeratorMuted = mute_voice; }
 	void setIsModerator(bool is_moderator) { mIsModerator = is_moderator; mNeedsRefresh = true; }
 	void setTimeNow() { mLastActiveTime = LLFrameTimer::getElapsedSeconds(); mNeedsRefresh = true; }
 	void setDistance(F64 dist) { mDistToAgent = dist; mNeedsRefresh = true; }
@@ -216,6 +218,7 @@ private:
 	void onAvatarNameCache(const LLAvatarName& av_name);	// callback used by fetchAvatarName
 	void updateName(const LLAvatarName& av_name);
 
+	bool mIsModeratorMuted;	         // default is false
 	bool mIsModerator;	         // default is false
 	bool mDisplayModeratorLabel; // default is false
 	std::string mDisplayName;
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 15a8aacd37..dee0a52ce8 100644
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -605,6 +605,20 @@ S32 LLConversationViewParticipant::arrange(S32* width, S32* height)
     return arranged;
 }
 
+// virtual
+void LLConversationViewParticipant::refresh()
+{
+	// Refresh the participant view from its model data
+	LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(getViewModelItem());
+	participant_model->resetRefresh();
+	
+	// *TODO: We should also do something with vmi->isModerator() to echo that state in the UI somewhat
+	mSpeakingIndicator->setIsModeratorMuted(participant_model->isModeratorMuted());
+	
+	// Do the regular upstream refresh
+	LLFolderViewItem::refresh();
+}
+
 void LLConversationViewParticipant::addToFolder(LLFolderViewFolder* folder)
 {
     // Add the item to the folder (conversation)
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index 5a74974302..06ffb517bb 100644
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -136,6 +136,7 @@ public:
     virtual ~LLConversationViewParticipant( void );
 
     bool hasSameValue(const LLUUID& uuid) { return (uuid == mUUID); }
+    /*virtual*/ void refresh();
     void addToFolder(LLFolderViewFolder* folder);
 	void addToSession(const LLUUID& session_id);
 
diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp
index 6c26073d5b..c5e4593b79 100644
--- a/indra/newview/lloutputmonitorctrl.cpp
+++ b/indra/newview/lloutputmonitorctrl.cpp
@@ -72,6 +72,7 @@ LLOutputMonitorCtrl::LLOutputMonitorCtrl(const LLOutputMonitorCtrl::Params& p)
 	mImageLevel3(p.image_level_3),
 	mAutoUpdate(p.auto_update),
 	mSpeakerId(p.speaker_id),
+	mIsModeratorMuted(false),
 	mIsAgentControl(false),
 	mIndicatorToggled(false),
 	mShowParticipantsSpeaking(false)
@@ -124,7 +125,7 @@ void LLOutputMonitorCtrl::draw()
 	const F32 LEVEL_1 = LLVoiceClient::OVERDRIVEN_POWER_LEVEL * 2.f / 3.f;
 	const F32 LEVEL_2 = LLVoiceClient::OVERDRIVEN_POWER_LEVEL;
 
-	if (getVisible() && mAutoUpdate && !mIsMuted && mSpeakerId.notNull())
+	if (getVisible() && mAutoUpdate && !getIsMuted() && mSpeakerId.notNull())
 	{
 		setPower(LLVoiceClient::getInstance()->getCurrentPower(mSpeakerId));
 		if(mIsAgentControl)
@@ -156,7 +157,7 @@ void LLOutputMonitorCtrl::draw()
 	}
 
 	LLPointer<LLUIImage> icon;
-	if (mIsMuted)
+	if (getIsMuted())
 	{
 		icon = mImageMute;
 	}
diff --git a/indra/newview/lloutputmonitorctrl.h b/indra/newview/lloutputmonitorctrl.h
index 0682af1278..af52a81b04 100644
--- a/indra/newview/lloutputmonitorctrl.h
+++ b/indra/newview/lloutputmonitorctrl.h
@@ -72,7 +72,10 @@ public:
 
 	void			setPower(F32 val);
 	F32				getPower(F32 val) const { return mPower; }
-	
+
+	bool			getIsMuted() const { return (mIsMuted || mIsModeratorMuted); }
+	void			setIsModeratorMuted(bool val) { mIsModeratorMuted = val; }
+
 	// For the current user, need to know the PTT state to show
 	// correct button image.
 	void			setIsAgentControl(bool val) { mIsAgentControl = val; }
@@ -131,6 +134,7 @@ private:
 
 	F32				mPower;
 	bool			mIsAgentControl;
+	bool			mIsModeratorMuted;
 	bool			mIsMuted;
 	bool			mIsTalking;
 	bool			mShowParticipantsSpeaking;
-- 
cgit v1.2.3


From 3e17a3c84b6b50f729396d227224129781f9b8d7 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 11 Feb 2019 14:20:02 -0500
Subject: SL-10506: Try again to attain desired behavior.

---
 indra/newview/installers/windows/installer_template.nsi | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index ff064b5f1e..4f9a1b7804 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -184,9 +184,20 @@ Function .onInit
 
 %%ENGAGEREGISTRY%%
 
-# Setting MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY and
+# SL-10506: Setting MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY and
 # MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME should
 # read the current location of the install for this version into INSTDIR.
+# However, SL-10506 complains about the resulting behavior, so the logic below
+# is adapted from before we introduced MultiUser.nsh.
+
+# if $0 is empty, this is the first time for this viewer name
+ReadRegStr $0 SHELL_CONTEXT "${INSTNAME_KEY}" ""
+
+# viewer with this name was installed before
+${If} $0 != ""
+	# use the value we got from registry as install location
+    StrCpy $INSTDIR $0
+${EndIf}
 
 Call CheckCPUFlags							# Make sure we have SSE2 support
 Call CheckWindowsVersion					# Don't install On unsupported systems
-- 
cgit v1.2.3


From 6f1e08f22d6cf9330899fd355cb7433897b93b48 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Tue, 12 Feb 2019 11:24:37 +0200
Subject: SL-10505 FIXED Right clicking on any name in Friends list accesses
 every chat .txt file stored

---
 indra/newview/lllogchat.cpp | 139 +++++++++++++++++---------------------------
 indra/newview/lllogchat.h   |   1 +
 2 files changed, 53 insertions(+), 87 deletions(-)

diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index c9889667b4..1bdeddbcfe 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -573,40 +573,10 @@ void LLLogChat::findTranscriptFiles(std::string pattern, std::vector<std::string
 	while (iter.next(filename))
 	{
 		std::string fullname = gDirUtilp->add(dirname, filename);
-
-		LLFILE * filep = LLFile::fopen(fullname, "rb");
-		if (NULL != filep)
+		if (isTranscriptFileFound(fullname))
 		{
-			if(makeLogFileName("chat")== fullname)
-			{
-				//Add Nearby chat history to the list of transcriptions
-				list_of_transcriptions.push_back(gDirUtilp->add(dirname, filename));
-				LLFile::close(filep);
-				continue;
-			}
-			char buffer[LOG_RECALL_SIZE];
-
-			fseek(filep, 0, SEEK_END);			// seek to end of file
-			S32 bytes_to_read = ftell(filep);	// get current file pointer
-			fseek(filep, 0, SEEK_SET);			// seek back to beginning of file
-
-			// limit the number characters to read from file
-			if (bytes_to_read >= LOG_RECALL_SIZE)
-			{
-				bytes_to_read = LOG_RECALL_SIZE - 1;
-			}
-
-			if (bytes_to_read > 0 && NULL != fgets(buffer, bytes_to_read, filep))
-			{
-				//matching a timestamp
-				boost::match_results<std::string::const_iterator> matches;
-				if (boost::regex_match(std::string(buffer), matches, TIMESTAMP))
-				{
-					list_of_transcriptions.push_back(gDirUtilp->add(dirname, filename));
-				}
-			}
-			LLFile::close(filep);
-		}
+			list_of_transcriptions.push_back(fullname);
+		}		
 	}
 }
 
@@ -756,75 +726,70 @@ void LLLogChat::deleteTranscripts()
 // static
 bool LLLogChat::isTranscriptExist(const LLUUID& avatar_id, bool is_group)
 {
-	std::vector<std::string> list_of_transcriptions;
-	LLLogChat::getListOfTranscriptFiles(list_of_transcriptions);
-
-	if (list_of_transcriptions.size() > 0)
+	LLAvatarName avatar_name;
+	LLAvatarNameCache::get(avatar_id, &avatar_name);
+	std::string avatar_user_name = avatar_name.getAccountName();
+	if(!is_group)
 	{
-		LLAvatarName avatar_name;
-		LLAvatarNameCache::get(avatar_id, &avatar_name);
-		std::string avatar_user_name = avatar_name.getAccountName();
-		if(!is_group)
-		{
-			std::replace(avatar_user_name.begin(), avatar_user_name.end(), '.', '_');
-			BOOST_FOREACH(std::string& transcript_file_name, list_of_transcriptions)
-			{
-				if (std::string::npos != transcript_file_name.find(avatar_user_name))
-				{
-					return true;
-				}
-			}
-		}
-		else
-		{
-			std::string file_name;
-			gCacheName->getGroupName(avatar_id, file_name);
-			file_name = makeLogFileName(file_name);
-			BOOST_FOREACH(std::string& transcript_file_name, list_of_transcriptions)
-			{
-				if (transcript_file_name == file_name)
-				{
-					return true;
-				}
-			}
-		}
-
+		std::replace(avatar_user_name.begin(), avatar_user_name.end(), '.', '_');
+		return isTranscriptFileFound(makeLogFileName(avatar_user_name));
+	}
+	else
+	{
+		std::string file_name;
+		gCacheName->getGroupName(avatar_id, file_name);
+		file_name = makeLogFileName(file_name);
+		return isTranscriptFileFound(makeLogFileName(file_name));
 	}
-
 	return false;
 }
 
 bool LLLogChat::isNearbyTranscriptExist()
 {
-	std::vector<std::string> list_of_transcriptions;
-	LLLogChat::getListOfTranscriptFiles(list_of_transcriptions);
-
-	std::string file_name;
-	file_name = makeLogFileName("chat");
-	BOOST_FOREACH(std::string& transcript_file_name, list_of_transcriptions)
-	{
-	   	if (transcript_file_name == file_name)
-	   	{
-			return true;
-		 }
-	}
-	return false;
+	return isTranscriptFileFound(makeLogFileName("chat"));;
 }
 
 bool LLLogChat::isAdHocTranscriptExist(std::string file_name)
 {
-	std::vector<std::string> list_of_transcriptions;
-	LLLogChat::getListOfTranscriptFiles(list_of_transcriptions);
+	return isTranscriptFileFound(makeLogFileName(file_name));;
+}
 
-	file_name = makeLogFileName(file_name);
-	BOOST_FOREACH(std::string& transcript_file_name, list_of_transcriptions)
+// static
+bool LLLogChat::isTranscriptFileFound(std::string fullname)
+{
+	bool result = false;
+	LLFILE * filep = LLFile::fopen(fullname, "rb");
+	if (NULL != filep)
 	{
-	   	if (transcript_file_name == file_name)
-	   	{
-	   		return true;
+		if (makeLogFileName("chat") == fullname)
+		{
+			LLFile::close(filep);
+			return true;
+		}
+		char buffer[LOG_RECALL_SIZE];
+
+		fseek(filep, 0, SEEK_END);			// seek to end of file
+		S32 bytes_to_read = ftell(filep);	// get current file pointer
+		fseek(filep, 0, SEEK_SET);			// seek back to beginning of file
+
+		// limit the number characters to read from file
+		if (bytes_to_read >= LOG_RECALL_SIZE)
+		{
+			bytes_to_read = LOG_RECALL_SIZE - 1;
 		}
+
+		if (bytes_to_read > 0 && NULL != fgets(buffer, bytes_to_read, filep))
+		{
+			//matching a timestamp
+			boost::match_results<std::string::const_iterator> matches;
+			if (boost::regex_match(std::string(buffer), matches, TIMESTAMP))
+			{
+				result = true;
+			}
+		}
+		LLFile::close(filep);
 	}
-	return false;
+	return result;
 }
 
 //*TODO mark object's names in a special way so that they will be distinguishable form avatar name 
diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h
index 6022e539a9..fcbd38a044 100644
--- a/indra/newview/lllogchat.h
+++ b/indra/newview/lllogchat.h
@@ -121,6 +121,7 @@ public:
 	static bool isTranscriptExist(const LLUUID& avatar_id, bool is_group=false);
 	static bool isNearbyTranscriptExist();
 	static bool isAdHocTranscriptExist(std::string file_name);
+	static bool isTranscriptFileFound(std::string fullname);
 
 	static bool historyThreadsFinished(LLUUID session_id);
 	static LLLoadHistoryThread* getLoadHistoryThread(LLUUID session_id);
-- 
cgit v1.2.3


From 00a6c069f21a7dcde52247e8bdf902e50369cc00 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Wed, 13 Feb 2019 16:55:22 +0200
Subject: SL-10328 FIXED Some parameters are not reset in the Upload Model menu
 when pressing button 'Clear settings & reset form'

---
 indra/newview/llfloatermodelpreview.cpp | 62 ++++++++++++++++++++++++++-------
 indra/newview/llfloatermodelpreview.h   |  5 ++-
 2 files changed, 53 insertions(+), 14 deletions(-)

diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 616bee84fd..e39e210939 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -304,10 +304,10 @@ BOOL LLFloaterModelPreview::postBuild()
 		getChild<LLSpinCtrl>("lod_triangle_limit_" + lod_name[lod])->setCommitCallback(boost::bind(&LLFloaterModelPreview::onLODParamCommit, this, lod, true));
 	}
 
-	childSetCommitCallback("upload_skin", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL);
-	childSetCommitCallback("upload_joints", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL);
-	childSetCommitCallback("lock_scale_if_joint_position", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL);
-	childSetCommitCallback("upload_textures", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL);
+	childSetCommitCallback("upload_skin", boost::bind(&LLFloaterModelPreview::onUploadOptionChecked, this, _1), NULL);
+	childSetCommitCallback("upload_joints", boost::bind(&LLFloaterModelPreview::onUploadOptionChecked, this, _1), NULL);
+	childSetCommitCallback("lock_scale_if_joint_position", boost::bind(&LLFloaterModelPreview::onUploadOptionChecked, this, _1), NULL);
+	childSetCommitCallback("upload_textures", boost::bind(&LLFloaterModelPreview::onUploadOptionChecked, this, _1), NULL);
 
 	childSetTextArg("status", "[STATUS]", getString("status_idle"));
 
@@ -449,6 +449,16 @@ void LLFloaterModelPreview::initModelPreview()
 	mModelPreview->setModelUpdatedCallback(boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this, _1));
 }
 
+void LLFloaterModelPreview::onUploadOptionChecked(LLUICtrl* ctrl)
+{
+	if (mModelPreview)
+	{
+		auto name = ctrl->getName();
+		mModelPreview->mViewOption[name] = !mModelPreview->mViewOption[name];
+	}
+	toggleCalculateButton(true);
+}
+
 void LLFloaterModelPreview::onViewOptionChecked(LLUICtrl* ctrl)
 {
 	if (mModelPreview)
@@ -631,6 +641,7 @@ void LLFloaterModelPreview::onGenerateNormalsCommit(LLUICtrl* ctrl, void* userda
 void LLFloaterModelPreview::toggleGenarateNormals()
 {
 	bool enabled = childGetValue("gen_normals").asBoolean();
+	mModelPreview->mViewOption["gen_normals"] = enabled;
 	childSetEnabled("crease_angle", enabled);
 	if(enabled) {
 		mModelPreview->generateNormals();
@@ -1156,10 +1167,8 @@ void LLFloaterModelPreview::initDecompControls()
 							std::string label = llformat("%.1f", value);
 							combo_box->add(label, value, ADD_BOTTOM, true);
 						}
-						combo_box->setValue(param[i].mDefault.mFloat);
-
 					}
-
+					combo_box->setValue(param[i].mDefault.mFloat);
 					combo_box->setCommitCallback(onPhysicsParamCommit, (void*) &param[i]);
 				}
 			}
@@ -1231,7 +1240,7 @@ void LLFloaterModelPreview::initDecompControls()
 			//LL_INFOS() << "-----------------------------" << LL_ENDL;
 		}
 	}
-
+	mDefaultDecompParams = mDecompParams;
 	childSetCommitCallback("physics_explode", LLFloaterModelPreview::onExplodeCommit, this);
 }
 
@@ -4420,6 +4429,7 @@ void LLFloaterModelPreview::onReset(void* user_data)
 	std::string filename = mp->mLODFile[LLModel::LOD_HIGH]; 
 
 	fmp->resetDisplayOptions();
+	fmp->resetUploadOptions();
 	//reset model preview
 	fmp->initModelPreview();
 
@@ -4533,11 +4543,6 @@ void LLFloaterModelPreview::setStatusMessage(const std::string& msg)
 	mStatusMessage = msg;
 }
 
-void LLFloaterModelPreview::toggleCalculateButton()
-{
-	toggleCalculateButton(true);
-}
-
 void LLFloaterModelPreview::toggleCalculateButton(bool visible)
 {
 	mCalculateBtn->setVisible(visible);
@@ -4599,6 +4604,37 @@ void LLFloaterModelPreview::resetDisplayOptions()
 	}
 }
 
+void LLFloaterModelPreview::resetUploadOptions()
+{
+	childSetValue("import_scale", 1);
+	childSetValue("pelvis_offset", 0);
+	childSetValue("physics_explode", 0);
+	childSetValue("physics_file", "");
+	childSetVisible("Retain%", false);
+	childSetVisible("Retain%_label", false);
+	childSetVisible("Detail Scale", true);
+	childSetVisible("Detail Scale label", true);
+
+	getChild<LLComboBox>("lod_source_" + lod_name[NUM_LOD - 1])->setCurrentByIndex(LLModelPreview::LOD_FROM_FILE);
+	for (S32 lod = 0; lod < NUM_LOD - 1; ++lod)
+	{
+		getChild<LLComboBox>("lod_source_" + lod_name[lod])->setCurrentByIndex(LLModelPreview::GENERATE);
+		childSetValue("lod_file_" + lod_name[lod], "");
+	}
+
+	getChild<LLComboBox>("physics_lod_combo")->setCurrentByIndex(0);
+
+	for(auto& p : mDefaultDecompParams)
+	{
+		std::string ctrl_name(p.first);
+		LLUICtrl* ctrl = getChild<LLUICtrl>(ctrl_name);
+		if (ctrl)
+		{
+			ctrl->setValue(p.second);
+		}
+	}
+}
+
 void LLFloaterModelPreview::onModelPhysicsFeeReceived(const LLSD& result, std::string upload_url)
 {
 	mModelPhysicsFee = result;
diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h
index 564f4c39de..41208daa64 100644
--- a/indra/newview/llfloatermodelpreview.h
+++ b/indra/newview/llfloatermodelpreview.h
@@ -109,6 +109,7 @@ public:
 	void 			loadModel(S32 lod, const std::string& file_name, bool force_disable_slm = false);
 	
 	void onViewOptionChecked(LLUICtrl* ctrl);
+	void onUploadOptionChecked(LLUICtrl* ctrl);
 	bool isViewOptionChecked(const LLSD& userdata);
 	bool isViewOptionEnabled(const LLSD& userdata);
 	void setViewOptionEnabled(const std::string& option, bool enabled);
@@ -179,6 +180,7 @@ protected:
 	LLModelPreview*	mModelPreview;
 	
 	LLPhysicsDecomp::decomp_params mDecompParams;
+	LLPhysicsDecomp::decomp_params mDefaultDecompParams;
 	
 	S32				mLastMouseX;
 	S32				mLastMouseY;
@@ -203,7 +205,6 @@ protected:
 
 private:
 	void onClickCalculateBtn();
-	void toggleCalculateButton();
 
 	void onLoDSourceCommit(S32 lod);
 
@@ -213,6 +214,8 @@ private:
 	// resets display options of model preview to their defaults.
 	void resetDisplayOptions();
 
+	void resetUploadOptions();
+
 	void createSmoothComboBox(LLComboBox* combo_box, float min, float max);
 
 	LLButton* mUploadBtn;
-- 
cgit v1.2.3


From ffc64187940c5df230d9dcead5c8716c10f109a9 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Thu, 14 Feb 2019 16:37:11 +0200
Subject: SL-10545 Provide summary memory information in Top Scripts

---
 indra/newview/llfloatertopobjects.cpp                      | 6 +++++-
 indra/newview/skins/default/xui/en/floater_top_objects.xml | 2 +-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/indra/newview/llfloatertopobjects.cpp b/indra/newview/llfloatertopobjects.cpp
index 9b5b3a0fc9..bd49405f34 100644
--- a/indra/newview/llfloatertopobjects.cpp
+++ b/indra/newview/llfloatertopobjects.cpp
@@ -143,6 +143,7 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
 {
     U32 request_flags;
 	U32 total_count;
+	U64 total_memory = 0;
 
 	msg->getU32Fast(_PREHASH_RequestData, _PREHASH_RequestFlags, request_flags);
 	msg->getU32Fast(_PREHASH_RequestData, _PREHASH_TotalObjectCount, total_count);
@@ -190,6 +191,7 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
 			{
 				parcel_buf = parcel_name;
 				script_memory = script_size;
+				total_memory += script_size;
 			}
 		}
 
@@ -263,8 +265,10 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
 	{
 		setTitle(getString("top_scripts_title"));
 		list->setColumnLabel("score", getString("scripts_score_label"));
-		
+
 		LLUIString format = getString("top_scripts_text");
+		total_memory /= 1024;
+		format.setArg("[MEMORY]", llformat("%ld", total_memory));
 		format.setArg("[COUNT]", llformat("%d", total_count));
 		format.setArg("[TIME]", llformat("%0.3f", mtotalScore));
 		getChild<LLUICtrl>("title_text")->setValue(LLSD(format));
diff --git a/indra/newview/skins/default/xui/en/floater_top_objects.xml b/indra/newview/skins/default/xui/en/floater_top_objects.xml
index ceef541290..b82fe43e74 100644
--- a/indra/newview/skins/default/xui/en/floater_top_objects.xml
+++ b/indra/newview/skins/default/xui/en/floater_top_objects.xml
@@ -16,7 +16,7 @@
     </floater.string>
     <floater.string
      name="top_scripts_text">
-        [COUNT] scripts taking a total of [TIME] ms
+        [COUNT] scripts taking a total of [TIME] ms and using [MEMORY] KB
     </floater.string>
     <floater.string
      name="scripts_score_label">
-- 
cgit v1.2.3


From fb085b8e61832bfc5222636f96fb802cec5ca9a2 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Thu, 14 Feb 2019 20:36:34 +0200
Subject: SL-1005 Changed media event is not firing when the URL is amended by
 a '#' since Alex-Ivy

---
 indra/newview/llviewermedia.cpp | 35 +++++++++++++++++++++++++++++++++--
 1 file changed, 33 insertions(+), 2 deletions(-)

diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index f4e1524371..d8745b1eca 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -3320,8 +3320,39 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla
 			}
 			else
 			{
-				// Don't track redirects.
-				setNavState(MEDIANAVSTATE_NONE);
+				bool internal_nav = false;
+				if (url != mCurrentMediaURL)
+				{
+					// Check if it is internal navigation
+					// Note: Not sure if we should detect internal navigations as 'address change',
+					// but they are not redirects and do not cause NAVIGATE_BEGIN (also see SL-1005)
+					size_t pos = url.find("#");
+					if (pos != std::string::npos)
+					{
+						// assume that new link always have '#', so this is either
+						// transfer from 'link#1' to 'link#2' or from link to 'link#2'
+						// filter out cases like 'redirect?link'
+						std::string base_url = url.substr(0, pos);
+						pos = mCurrentMediaURL.find(base_url);
+						if (pos == 0)
+						{
+							// base link hasn't changed
+							internal_nav = true;
+						}
+					}
+				}
+
+				if (internal_nav)
+				{
+					// Internal navigation by '#'
+					mCurrentMediaURL = url;
+					setNavState(MEDIANAVSTATE_FIRST_LOCATION_CHANGED);
+				}
+				else
+				{
+					// Don't track redirects.
+					setNavState(MEDIANAVSTATE_NONE);
+				}
 			}
 		}
 		break;
-- 
cgit v1.2.3


From d6a4504cd86de0ffa86c7b0341f729e913b1a15e Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Fri, 15 Feb 2019 14:55:56 +0200
Subject: SL-10549 FIXED The 'Save' button remains disabled after changing the
 classified image

---
 indra/newview/llpanelclassified.cpp | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp
index b9b97f4cce..6d0c30fbf3 100644
--- a/indra/newview/llpanelclassified.cpp
+++ b/indra/newview/llpanelclassified.cpp
@@ -628,12 +628,9 @@ BOOL LLPanelClassifiedEdit::postBuild()
 {
 	LLPanelClassifiedInfo::postBuild();
 
-	LLTextureCtrl* snapshot = getChild<LLTextureCtrl>("classified_snapshot");
-	snapshot->setOnSelectCallback(boost::bind(&LLPanelClassifiedEdit::onChange, this));
-
 	LLUICtrl* edit_icon = getChild<LLUICtrl>("edit_icon");
-	snapshot->setMouseEnterCallback(boost::bind(&LLPanelClassifiedEdit::onTexturePickerMouseEnter, this, edit_icon));
-	snapshot->setMouseLeaveCallback(boost::bind(&LLPanelClassifiedEdit::onTexturePickerMouseLeave, this, edit_icon));
+	mSnapshotCtrl->setMouseEnterCallback(boost::bind(&LLPanelClassifiedEdit::onTexturePickerMouseEnter, this, edit_icon));
+	mSnapshotCtrl->setMouseLeaveCallback(boost::bind(&LLPanelClassifiedEdit::onTexturePickerMouseLeave, this, edit_icon));
 	edit_icon->setVisible(false);
 
 	LLLineEditor* line_edit = getChild<LLLineEditor>("classified_name");
@@ -1130,6 +1127,7 @@ void LLPanelClassifiedEdit::onTexturePickerMouseLeave(LLUICtrl* ctrl)
 void LLPanelClassifiedEdit::onTextureSelected()
 {
 	setSnapshotId(mSnapshotCtrl->getValue().asUUID());
+	onChange();
 }
 
 //////////////////////////////////////////////////////////////////////////
-- 
cgit v1.2.3


From a8afd345a0ad36eda4b9edb0664004dbdd0b2082 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Fri, 15 Feb 2019 15:03:27 +0200
Subject: SL-10351 Cleanup

---
 indra/newview/llconversationmodel.cpp | 18 ------------------
 indra/newview/llconversationmodel.h   |  1 -
 2 files changed, 19 deletions(-)

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index c715815208..c258136889 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -602,24 +602,6 @@ bool LLConversationItemParticipant::isVoiceMuted()
 	return mIsModeratorMuted || LLMuteList::getInstance()->isMuted(mUUID, LLMute::flagVoiceChat);
 }
 
-void LLConversationItemParticipant::muteVoice(bool mute_voice)
-{
-	LLAvatarName av_name;
-	LLAvatarNameCache::get(mUUID, &av_name);
-	LLMuteList * mute_listp = LLMuteList::getInstance();
-	bool voice_already_muted = mute_listp->isMuted(mUUID, av_name.getUserName(), LLMute::flagVoiceChat);
-
-	LLMute mute(mUUID, av_name.getUserName(), LLMute::AGENT);
-	if (voice_already_muted && !mute_voice)
-	{
-		mute_listp->remove(mute, LLMute::flagVoiceChat);
-	}
-	else if (!voice_already_muted && mute_voice)
-	{
-		mute_listp->add(mute, LLMute::flagVoiceChat);
-	}
-}
-
 //
 // LLConversationSort
 // 
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 2da9f03c6c..80385fad5f 100644
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -196,7 +196,6 @@ public:
 	bool isVoiceMuted();
 	bool isModeratorMuted() { return mIsModeratorMuted; }
 	bool isModerator() const { return mIsModerator; }
-	void muteVoice(bool mute_voice);
 	void moderateVoice(bool mute_voice) { mIsModeratorMuted = mute_voice; }
 	void setIsModerator(bool is_moderator) { mIsModerator = is_moderator; mNeedsRefresh = true; }
 	void setTimeNow() { mLastActiveTime = LLFrameTimer::getElapsedSeconds(); mNeedsRefresh = true; }
-- 
cgit v1.2.3


From fddfe50ac125c1b25592ce30dbbb34363047cea1 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Fri, 15 Feb 2019 16:12:43 +0200
Subject: SL-10550 Update attachment location strings

---
 indra/newview/skins/default/xui/en/strings.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index e8fdb2d5b1..d91f3ac095 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2675,14 +2675,14 @@ If you continue to receive this message, please contact Second Life support for
 
 	<string name="SITTING_ON">Sitting On</string>
 	<string name="ATTACH_CHEST">Chest</string>
-	<string name="ATTACH_HEAD">Head</string>
+	<string name="ATTACH_HEAD">Skull</string>
 	<string name="ATTACH_LSHOULDER">Left Shoulder</string>
 	<string name="ATTACH_RSHOULDER">Right Shoulder</string>
 	<string name="ATTACH_LHAND">Left Hand</string>
 	<string name="ATTACH_RHAND">Right Hand</string>
 	<string name="ATTACH_LFOOT">Left Foot</string>
 	<string name="ATTACH_RFOOT">Right Foot</string>
-	<string name="ATTACH_BACK">Back</string>
+	<string name="ATTACH_BACK">Spine</string>
 	<string name="ATTACH_PELVIS">Pelvis</string>
 	<string name="ATTACH_MOUTH">Mouth</string>
 	<string name="ATTACH_CHIN">Chin</string>
@@ -2692,16 +2692,16 @@ If you continue to receive this message, please contact Second Life support for
 	<string name="ATTACH_REYE">Right Eye</string>
 	<string name="ATTACH_NOSE">Nose</string>
 	<string name="ATTACH_RUARM">Right Upper Arm</string>
-	<string name="ATTACH_RLARM">Right Lower Arm</string>
+	<string name="ATTACH_RLARM">Right Forearm</string>
 	<string name="ATTACH_LUARM">Left Upper Arm</string>
-	<string name="ATTACH_LLARM">Left Lower Arm</string>
+	<string name="ATTACH_LLARM">Left Forearm</string>
 	<string name="ATTACH_RHIP">Right Hip</string>
 	<string name="ATTACH_RULEG">Right Upper Leg</string>
 	<string name="ATTACH_RLLEG">Right Lower Leg</string>
 	<string name="ATTACH_LHIP">Left Hip</string>
 	<string name="ATTACH_LULEG">Left Upper Leg</string>
 	<string name="ATTACH_LLLEG">Left Lower Leg</string>
-	<string name="ATTACH_BELLY">Belly</string>
+	<string name="ATTACH_BELLY">Stomach</string>
 	<string name="ATTACH_LEFT_PEC">Left Pec</string>
 	<string name="ATTACH_RIGHT_PEC">Right Pec</string>
 	<string name="ATTACH_HUD_CENTER_2">HUD Center 2</string>
-- 
cgit v1.2.3


From 0c8d51b8c8bdca567e349755393c57cd113a81f0 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Fri, 15 Feb 2019 20:41:03 +0200
Subject: SL-10234 Fixed The viewer shows installation language as system
 default

---
 indra/llui/llcombobox.cpp                          | 36 ++++++++--
 indra/newview/CMakeLists.txt                       |  1 +
 indra/newview/llfloaterpreference.cpp              | 81 ++++++++++++++++++++++
 indra/newview/llfloaterpreference.h                |  1 +
 indra/newview/skins/default/default_languages.xml  | 39 +++++++++++
 .../default/xui/da/panel_preferences_general.xml   |  1 -
 .../default/xui/de/panel_preferences_general.xml   |  1 -
 .../default/xui/en/panel_preferences_general.xml   |  5 --
 .../default/xui/es/panel_preferences_general.xml   |  1 -
 .../default/xui/fr/panel_preferences_general.xml   |  1 -
 .../default/xui/it/panel_preferences_general.xml   |  1 -
 .../default/xui/ja/panel_preferences_general.xml   |  1 -
 .../default/xui/pl/panel_preferences_general.xml   |  1 -
 .../default/xui/pt/panel_preferences_general.xml   |  1 -
 .../default/xui/ru/panel_preferences_general.xml   |  1 -
 .../default/xui/tr/panel_preferences_general.xml   |  1 -
 .../default/xui/zh/panel_preferences_general.xml   |  1 -
 17 files changed, 154 insertions(+), 20 deletions(-)
 create mode 100644 indra/newview/skins/default/default_languages.xml

diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp
index 00a933a0bb..b2ad38bddf 100644
--- a/indra/llui/llcombobox.cpp
+++ b/indra/llui/llcombobox.cpp
@@ -243,7 +243,14 @@ LLScrollListItem* LLComboBox::add(const std::string& name, EAddPosition pos, BOO
 	item->setEnabled(enabled);
 	if (!mAllowTextEntry && mLabel.empty())
 	{
-		selectFirstItem();
+		if (mControlVariable)
+		{
+			setValue(mControlVariable->getValue()); // selects the appropriate item
+		}
+		else
+		{
+			selectFirstItem();
+		}
 	}
 	return item;
 }
@@ -255,7 +262,14 @@ LLScrollListItem* LLComboBox::add(const std::string& name, const LLUUID& id, EAd
 	item->setEnabled(enabled);
 	if (!mAllowTextEntry && mLabel.empty())
 	{
-		selectFirstItem();
+		if (mControlVariable)
+		{
+			setValue(mControlVariable->getValue()); // selects the appropriate item
+		}
+		else
+		{
+			selectFirstItem();
+		}
 	}
 	return item;
 }
@@ -268,7 +282,14 @@ LLScrollListItem* LLComboBox::add(const std::string& name, void* userdata, EAddP
 	item->setUserdata( userdata );
 	if (!mAllowTextEntry && mLabel.empty())
 	{
-		selectFirstItem();
+		if (mControlVariable)
+		{
+			setValue(mControlVariable->getValue()); // selects the appropriate item
+		}
+		else
+		{
+			selectFirstItem();
+		}
 	}
 	return item;
 }
@@ -280,7 +301,14 @@ LLScrollListItem* LLComboBox::add(const std::string& name, LLSD value, EAddPosit
 	item->setEnabled(enabled);
 	if (!mAllowTextEntry && mLabel.empty())
 	{
-		selectFirstItem();
+		if (mControlVariable)
+		{
+			setValue(mControlVariable->getValue()); // selects the appropriate item
+		}
+		else
+		{
+			selectFirstItem();
+		}
 	}
 	return item;
 }
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index a8019ee168..60c27665bf 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1587,6 +1587,7 @@ endif (WINDOWS)
 # from within the IDE.
 set(viewer_XUI_FILES
     skins/default/colors.xml
+    skins/default/default_languages.xml
     skins/default/textures/textures.xml
     )
 file(GLOB DEFAULT_XUI_FILE_GLOB_LIST
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index c3dea73c05..a3821ef21a 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -138,6 +138,25 @@ static const F32 MIN_ARC_LOG = log(MIN_ARC_LIMIT);
 static const F32 MAX_ARC_LOG = log(MAX_ARC_LIMIT);
 static const F32 ARC_LIMIT_MAP_SCALE = (MAX_ARC_LOG - MIN_ARC_LOG) / (MAX_INDIRECT_ARC_LIMIT - MIN_INDIRECT_ARC_LIMIT);
 
+struct LabelDef : public LLInitParam::Block<LabelDef>
+{
+    Mandatory<std::string> name;
+    Mandatory<std::string> value;
+
+    LabelDef()
+        : name("name"),
+        value("value")
+    {}
+};
+
+struct LabelTable : public LLInitParam::Block<LabelTable>
+{
+    Multiple<LabelDef> labels;
+    LabelTable()
+        : labels("label")
+    {}
+};
+
 class LLVoiceSetKeyDialog : public LLModalDialog
 {
 public:
@@ -514,6 +533,29 @@ BOOL LLFloaterPreference::postBuild()
 	mFilterEdit = getChild<LLSearchEditor>("search_prefs_edit");
 	mFilterEdit->setKeystrokeCallback(boost::bind(&LLFloaterPreference::onUpdateFilterTerm, this, false));
 
+	// Load and assign label for 'default language'
+	std::string user_filename = gDirUtilp->getExpandedFilename(LL_PATH_DEFAULT_SKIN, "default_languages.xml");
+	std::map<std::string, std::string> labels;
+	if (loadFromFilename(user_filename, labels))
+	{
+		std::string system_lang = gSavedSettings.getString("SystemLanguage");
+		std::map<std::string, std::string>::iterator iter = labels.find(system_lang);
+		if (iter != labels.end())
+		{
+			getChild<LLComboBox>("language_combobox")->add(iter->second, LLSD("default"), ADD_TOP, true);
+		}
+		else
+		{
+			LL_WARNS() << "Language \"" << system_lang << "\" is not in default_languages.xml" << LL_ENDL;
+			getChild<LLComboBox>("language_combobox")->add("System default", LLSD("default"), ADD_TOP, true);
+		}
+	}
+	else
+	{
+		LL_WARNS() << "Failed to load labels from " << user_filename << ". Using default." << LL_ENDL;
+		getChild<LLComboBox>("language_combobox")->add("System default", LLSD("default"), ADD_TOP, true);
+	}
+
 	return TRUE;
 }
 
@@ -1979,6 +2021,45 @@ void LLFloaterPreference::updateMaxComplexity()
         getChild<LLTextBox>("IndirectMaxComplexityText"));
 }
 
+bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map<std::string, std::string> &label_map)
+{
+    LLXMLNodePtr root;
+
+    if (!LLXMLNode::parseFile(filename, root, NULL))
+    {
+        LL_WARNS() << "Unable to parse file " << filename << LL_ENDL;
+        return false;
+    }
+
+    if (!root->hasName("labels"))
+    {
+        LL_WARNS() << filename << " is not a valid definition file" << LL_ENDL;
+        return false;
+    }
+
+    LabelTable params;
+    LLXUIParser parser;
+    parser.readXUI(root, params, filename);
+
+    if (params.validateBlock())
+    {
+        for (LLInitParam::ParamIterator<LabelDef>::const_iterator it = params.labels.begin();
+            it != params.labels.end();
+            ++it)
+        {
+            LabelDef label_entry = *it;
+            label_map[label_entry.name] = label_entry.value;
+        }
+    }
+    else
+    {
+        LL_WARNS() << filename << " failed to load" << LL_ENDL;
+        return false;
+    }
+
+    return true;
+}
+
 void LLFloaterPreferenceGraphicsAdvanced::updateMaxComplexity()
 {
 	// Called when the IndirectMaxComplexity control changes
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index d609c42ebe..1b8229ada6 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -198,6 +198,7 @@ private:
 	void onDeleteTranscriptsResponse(const LLSD& notification, const LLSD& response);
 	void updateDeleteTranscriptsButton();
 	void updateMaxComplexity();
+	static bool loadFromFilename(const std::string& filename, std::map<std::string, std::string> &label_map);
 
 	static std::string sSkin;
 	notifications_map mNotificationOptions;
diff --git a/indra/newview/skins/default/default_languages.xml b/indra/newview/skins/default/default_languages.xml
new file mode 100644
index 0000000000..357930e1c5
--- /dev/null
+++ b/indra/newview/skins/default/default_languages.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<labels>
+	<label
+	 name="en"
+	 value="System default" />
+	<label
+	 name="it"
+	 value="Default di sistema" />
+	<label
+	 name="ja"
+	 value="システムデフォルト" />
+	<label
+	 name="pl"
+	 value="Domyślny" />
+	<label
+	 name="pt"
+	 value="Padrão" />
+	<label
+	 name="ru"
+	 value="Язык системы" />
+	<label
+	 name="tr"
+	 value="Sistem varsayılanı" />
+	<label
+	 name="zh"
+	 value="系統預設" />
+	<label
+	 name="da"
+	 value="System standard" />
+	<label
+	 name="de"
+	 value="Systemvorgabe" />
+	<label
+	 name="es"
+	 value="Predeterminado del sistema" />
+	<label
+	 name="fr"
+	 value="Choix par défaut" />
+</labels>
diff --git a/indra/newview/skins/default/xui/da/panel_preferences_general.xml b/indra/newview/skins/default/xui/da/panel_preferences_general.xml
index 5702d48e97..624c6634cc 100644
--- a/indra/newview/skins/default/xui/da/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/da/panel_preferences_general.xml
@@ -4,7 +4,6 @@
 		Sprog:
 	</text>
 	<combo_box name="language_combobox">
-		<combo_box.item label="System standard" name="System Default Language"/>
 		<combo_box.item label="English (Engelsk)" name="English"/>
 		<combo_box.item label="Dansk - Beta" name="Danish"/>
 		<combo_box.item label="Deutsch (Tysk) - Beta" name="Deutsch(German)"/>
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_general.xml b/indra/newview/skins/default/xui/de/panel_preferences_general.xml
index 201998f220..c4705d7283 100644
--- a/indra/newview/skins/default/xui/de/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/de/panel_preferences_general.xml
@@ -4,7 +4,6 @@
 		Sprache:
 	</text>
 	<combo_box name="language_combobox">
-		<combo_box.item label="Systemvorgabe" name="System Default Language"/>
 		<combo_box.item label="English (Englisch)" name="English"/>
 		<combo_box.item label="Dansk (Dänisch) - Beta" name="Danish"/>
 		<combo_box.item label="Deutsch - Beta" name="Deutsch(German)"/>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_general.xml b/indra/newview/skins/default/xui/en/panel_preferences_general.xml
index 9da044ab64..335d7caa51 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_general.xml
@@ -30,11 +30,6 @@
      max_chars="135"
      name="language_combobox"
      width="200">
-        <combo_box.item
-         enabled="true"
-         label="System default"
-         name="System Default Language"
-         value="default" />
         <combo_box.item
          enabled="true"
          label="English"
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_general.xml b/indra/newview/skins/default/xui/es/panel_preferences_general.xml
index 7d3c33a781..d2246630d8 100644
--- a/indra/newview/skins/default/xui/es/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/es/panel_preferences_general.xml
@@ -4,7 +4,6 @@
 		Idioma:
 	</text>
 	<combo_box name="language_combobox">
-		<combo_box.item label="Predeterminado del sistema" name="System Default Language"/>
 		<combo_box.item label="English (Inglés)" name="English"/>
 		<combo_box.item label="Dansk (danés) - Beta" name="Danish"/>
 		<combo_box.item label="Deutsch (Alemán) - Beta" name="Deutsch(German)"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_general.xml b/indra/newview/skins/default/xui/fr/panel_preferences_general.xml
index 11b1bd9b87..b75567a40f 100644
--- a/indra/newview/skins/default/xui/fr/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_general.xml
@@ -4,7 +4,6 @@
 		Langue :
 	</text>
 	<combo_box name="language_combobox">
-		<combo_box.item label="Choix par défaut" name="System Default Language"/>
 		<combo_box.item label="English (Anglais)" name="English"/>
 		<combo_box.item label="Dansk (Danois) - Bêta" name="Danish"/>
 		<combo_box.item label="Deutsch (Allemand) - Bêta" name="Deutsch(German)"/>
diff --git a/indra/newview/skins/default/xui/it/panel_preferences_general.xml b/indra/newview/skins/default/xui/it/panel_preferences_general.xml
index ef999d03c0..49edc0aa12 100644
--- a/indra/newview/skins/default/xui/it/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/it/panel_preferences_general.xml
@@ -4,7 +4,6 @@
 		Lingua:
 	</text>
 	<combo_box name="language_combobox">
-		<combo_box.item label="Default di sistema" name="System Default Language"/>
 		<combo_box.item label="English" name="English"/>
 		<combo_box.item label="Dansk (Danese) - Beta" name="Danish"/>
 		<combo_box.item label="Deutsch (Tedesco) - Beta" name="Deutsch(German)"/>
diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_general.xml b/indra/newview/skins/default/xui/ja/panel_preferences_general.xml
index e2b74354fa..378cf8652e 100644
--- a/indra/newview/skins/default/xui/ja/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/ja/panel_preferences_general.xml
@@ -4,7 +4,6 @@
 		言語:
 	</text>
 	<combo_box name="language_combobox">
-		<combo_box.item label="システムデフォルト" name="System Default Language"/>
 		<combo_box.item label="English (英語)" name="English"/>
 		<combo_box.item label="Dansk (デンマーク語) - ベータ" name="Danish"/>
 		<combo_box.item label="Deutsch (ドイツ語) – ベータ" name="Deutsch(German)"/>
diff --git a/indra/newview/skins/default/xui/pl/panel_preferences_general.xml b/indra/newview/skins/default/xui/pl/panel_preferences_general.xml
index 082dc0687e..55df13e7ac 100644
--- a/indra/newview/skins/default/xui/pl/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/pl/panel_preferences_general.xml
@@ -4,7 +4,6 @@
 		Język:
 	</text>
 	<combo_box name="language_combobox">
-		<combo_box.item label="Domyślny" name="System Default Language" />
 		<combo_box.item label="English (Angielski)" name="English" />
 		<combo_box.item label="Dansk (Duński) - Beta" name="Danish" />
 		<combo_box.item label="Deutsch (Niemiecki) - Beta" name="Deutsch(German)" />
diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_general.xml b/indra/newview/skins/default/xui/pt/panel_preferences_general.xml
index 68fbd049b1..915d695605 100644
--- a/indra/newview/skins/default/xui/pt/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/pt/panel_preferences_general.xml
@@ -4,7 +4,6 @@
 		Idioma:
 	</text>
 	<combo_box name="language_combobox">
-		<combo_box.item label="Padrão" name="System Default Language"/>
 		<combo_box.item label="English (Inglês)" name="English"/>
 		<combo_box.item label="Dansk (Dinamarquês) - Beta" name="Danish"/>
 		<combo_box.item label="Deutsch (Alemão) - Beta" name="Deutsch(German)"/>
diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_general.xml b/indra/newview/skins/default/xui/ru/panel_preferences_general.xml
index b15d0e3abf..918b042dd7 100644
--- a/indra/newview/skins/default/xui/ru/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/ru/panel_preferences_general.xml
@@ -4,7 +4,6 @@
 		Язык:
 	</text>
 	<combo_box name="language_combobox">
-		<combo_box.item label="Язык системы" name="System Default Language"/>
 		<combo_box.item label="English - Английский" name="English"/>
 		<combo_box.item label="Dansk – датский (бета-версия)" name="Danish"/>
 		<combo_box.item label="Deutsch – немецкий (бета-версия)" name="Deutsch(German)"/>
diff --git a/indra/newview/skins/default/xui/tr/panel_preferences_general.xml b/indra/newview/skins/default/xui/tr/panel_preferences_general.xml
index 2c05e8a47a..cec7a67f2f 100644
--- a/indra/newview/skins/default/xui/tr/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/tr/panel_preferences_general.xml
@@ -4,7 +4,6 @@
 		Dil:
 	</text>
 	<combo_box name="language_combobox">
-		<combo_box.item label="Sistem varsayılanı" name="System Default Language"/>
 		<combo_box.item label="English (İngilizce)" name="English"/>
 		<combo_box.item label="Dansk (Danca) - Beta" name="Danish"/>
 		<combo_box.item label="Deutsch (Almanca) - Beta" name="Deutsch(German)"/>
diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_general.xml b/indra/newview/skins/default/xui/zh/panel_preferences_general.xml
index 20335d82ae..87c38e4346 100644
--- a/indra/newview/skins/default/xui/zh/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/zh/panel_preferences_general.xml
@@ -4,7 +4,6 @@
 		語言:
 	</text>
 	<combo_box name="language_combobox">
-		<combo_box.item label="系統預設" name="System Default Language"/>
 		<combo_box.item label="英語" name="English"/>
 		<combo_box.item label="Dansk(丹麥語)- 試用版" name="Danish"/>
 		<combo_box.item label="Deutsch(德語)- 試用版" name="Deutsch(German)"/>
-- 
cgit v1.2.3


From 344a3a040fb1c664108830ac784c6e4593a57553 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Fri, 15 Feb 2019 22:05:44 +0200
Subject: Teamcity W64 build freeze.

---
 indra/llcorehttp/tests/test_httprequest.hpp | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/indra/llcorehttp/tests/test_httprequest.hpp b/indra/llcorehttp/tests/test_httprequest.hpp
index 4ac3f6f991..e65588e48f 100644
--- a/indra/llcorehttp/tests/test_httprequest.hpp
+++ b/indra/llcorehttp/tests/test_httprequest.hpp
@@ -2904,7 +2904,11 @@ void HttpRequestTestObjectType::test<22>()
 	set_test_name("BUG-2295");
 
 #if LL_WINDOWS && ADDRESS_SIZE == 64
-	skip("BUG-2295 - partial load on W64 causes freeze");
+	// teamcity win64 builds freeze on this test, if you figure out the cause, please fix it
+	if (getenv("TEAMCITY_PROJECT_NAME"))
+	{
+		skip("BUG-2295 - partial load on W64 causes freeze");
+	}
 #endif
 	// Handler can be stack-allocated *if* there are no dangling
 	// references to it after completion of this method.
@@ -3095,7 +3099,11 @@ void HttpRequestTestObjectType::test<23>()
 	set_test_name("HttpRequest GET 503s with 'Retry-After'");
 
 #if LL_WINDOWS && ADDRESS_SIZE == 64
-	skip("llcorehttp 503-with-retry test hangs on Windows 64");
+	// teamcity win64 builds freeze on this test, if you figure out the cause, please fix it
+	if (getenv("TEAMCITY_PROJECT_NAME"))
+	{
+		skip("llcorehttp 503-with-retry test hangs on Windows 64");
+	}
 #endif
 
 	// This tests mainly that the code doesn't fall over if
-- 
cgit v1.2.3


From 54818e189404e0d8444a7731c0082e03a5f12ef7 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Tue, 19 Feb 2019 18:24:06 +0200
Subject: SL-10412 Move My Avatar/Scripts to Me drop down menu

---
 indra/newview/CMakeLists.txt                       |   2 +
 indra/newview/llfloatermyscripts.cpp               | 294 ++++++++++++++++++++
 indra/newview/llfloatermyscripts.h                 |  60 +++++
 indra/newview/llfloaterscriptlimits.cpp            | 299 +--------------------
 indra/newview/llfloaterscriptlimits.h              |  47 ----
 indra/newview/llviewerfloaterreg.cpp               |   2 +
 .../skins/default/xui/en/floater_my_scripts.xml    |  22 ++
 indra/newview/skins/default/xui/en/menu_viewer.xml |   7 +
 8 files changed, 389 insertions(+), 344 deletions(-)
 create mode 100644 indra/newview/llfloatermyscripts.cpp
 create mode 100644 indra/newview/llfloatermyscripts.h
 create mode 100644 indra/newview/skins/default/xui/en/floater_my_scripts.xml

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 60c27665bf..c389de1232 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -265,6 +265,7 @@ set(viewer_SOURCE_FILES
     llfloatermemleak.cpp
     llfloatermodelpreview.cpp
     llfloatermodeluploadbase.cpp
+    llfloatermyscripts.cpp
     llfloaternamedesc.cpp
     llfloaternotificationsconsole.cpp
     llfloaternotificationstabbed.cpp
@@ -893,6 +894,7 @@ set(viewer_HEADER_FILES
     llfloatermemleak.h
     llfloatermodelpreview.h
     llfloatermodeluploadbase.h
+    llfloatermyscripts.h
     llfloaternamedesc.h
     llfloaternotificationsconsole.h
     llfloaternotificationstabbed.h
diff --git a/indra/newview/llfloatermyscripts.cpp b/indra/newview/llfloatermyscripts.cpp
new file mode 100644
index 0000000000..fa2de21a8f
--- /dev/null
+++ b/indra/newview/llfloatermyscripts.cpp
@@ -0,0 +1,294 @@
+/** 
+ * @file llfloatermyscripts.cpp
+ * @brief LLFloaterMyScripts class implementation.
+ *
+ * $LicenseInfo:firstyear=2004&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2019, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llfloatermyscripts.h"
+
+#include "llagent.h"
+#include "llcorehttputil.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
+#include "llfloaterreg.h"
+#include "llscrolllistctrl.h"
+#include "lltrans.h"
+#include "llviewerregion.h"
+
+const S32 SIZE_OF_ONE_KB = 1024;
+
+LLFloaterMyScripts::LLFloaterMyScripts(const LLSD& seed)
+	: LLFloater(seed), 
+	mGotAttachmentMemoryUsed(false),
+	mAttachmentMemoryMax(0),
+	mAttachmentMemoryUsed(0),
+	mGotAttachmentURLsUsed(false),
+	mAttachmentURLsMax(0),
+	mAttachmentURLsUsed(0)
+{
+}
+
+BOOL LLFloaterMyScripts::postBuild()
+{
+	childSetAction("refresh_list_btn", onClickRefresh, this);
+
+	std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestWaiting");
+	getChild<LLUICtrl>("loading_text")->setValue(LLSD(msg_waiting));
+	return requestAttachmentDetails();
+}
+
+BOOL LLFloaterMyScripts::requestAttachmentDetails()
+{
+	if (!gAgent.getRegion()) return FALSE;
+
+	LLSD body;
+	std::string url = gAgent.getRegion()->getCapability("AttachmentResources");
+	if (!url.empty())
+	{
+		LLCoros::instance().launch("LLFloaterMyScripts::getAttachmentLimitsCoro",
+			boost::bind(&LLFloaterMyScripts::getAttachmentLimitsCoro, this, url));
+		return TRUE;
+	}
+	else
+	{
+		return FALSE;
+	}
+}
+
+void LLFloaterMyScripts::getAttachmentLimitsCoro(std::string url)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("getAttachmentLimitsCoro", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+    LLSD result = httpAdapter->getAndSuspend(httpRequest, url);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status)
+    {
+        LL_WARNS() << "Unable to retrieve attachment limits." << LL_ENDL;
+        return;
+    }
+
+    LLFloaterMyScripts* instance = LLFloaterReg::getTypedInstance<LLFloaterMyScripts>("my_scripts");
+
+    if (!instance)
+    {
+        LL_WARNS() << "Failed to get LLFloaterMyScripts instance" << LL_ENDL;
+        return;
+    }
+
+	instance->getChild<LLUICtrl>("loading_text")->setValue(LLSD(std::string("")));
+
+	LLButton* btn = instance->getChild<LLButton>("refresh_list_btn");
+    if (btn)
+    {
+        btn->setEnabled(true);
+    }
+
+    result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+	instance->setAttachmentDetails(result);
+}
+
+
+void LLFloaterMyScripts::setAttachmentDetails(LLSD content)
+{
+	LLScrollListCtrl *list = getChild<LLScrollListCtrl>("scripts_list");
+	
+	if(!list)
+	{
+		return;
+	}
+	
+	S32 number_attachments = content["attachments"].size();
+
+	for(int i = 0; i < number_attachments; i++)
+	{
+		std::string humanReadableLocation = "";
+		if(content["attachments"][i].has("location"))
+		{
+			std::string actualLocation = content["attachments"][i]["location"];
+			humanReadableLocation = LLTrans::getString(actualLocation.c_str());
+		}
+		
+		S32 number_objects = content["attachments"][i]["objects"].size();
+		for(int j = 0; j < number_objects; j++)
+		{
+			LLUUID task_id = content["attachments"][i]["objects"][j]["id"].asUUID();
+			S32 size = 0;
+			if(content["attachments"][i]["objects"][j]["resources"].has("memory"))
+			{
+				size = content["attachments"][i]["objects"][j]["resources"]["memory"].asInteger() / SIZE_OF_ONE_KB;
+			}
+			S32 urls = 0;
+			if(content["attachments"][i]["objects"][j]["resources"].has("urls"))
+			{
+				urls = content["attachments"][i]["objects"][j]["resources"]["urls"].asInteger();
+			}
+			std::string name = content["attachments"][i]["objects"][j]["name"].asString();
+			
+			LLSD element;
+
+			element["id"] = task_id;
+			element["columns"][0]["column"] = "size";
+			element["columns"][0]["value"] = llformat("%d", size);
+			element["columns"][0]["font"] = "SANSSERIF";
+			element["columns"][0]["halign"] = LLFontGL::RIGHT;
+
+			element["columns"][1]["column"] = "urls";
+			element["columns"][1]["value"] = llformat("%d", urls);
+			element["columns"][1]["font"] = "SANSSERIF";
+			element["columns"][1]["halign"] = LLFontGL::RIGHT;
+			
+			element["columns"][2]["column"] = "name";
+			element["columns"][2]["value"] = name;
+			element["columns"][2]["font"] = "SANSSERIF";
+			
+			element["columns"][3]["column"] = "location";
+			element["columns"][3]["value"] = humanReadableLocation;
+			element["columns"][3]["font"] = "SANSSERIF";
+
+			list->addElement(element);
+		}
+	}
+	
+	setAttachmentSummary(content);
+
+	getChild<LLUICtrl>("loading_text")->setValue(LLSD(std::string("")));
+
+	LLButton* btn = getChild<LLButton>("refresh_list_btn");
+	if(btn)
+	{
+		btn->setEnabled(true);
+	}
+}
+
+void LLFloaterMyScripts::clearList()
+{
+	LLCtrlListInterface *list = childGetListInterface("scripts_list");
+
+	if (list)
+	{
+		list->operateOnAll(LLCtrlListInterface::OP_DELETE);
+	}
+
+	std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestWaiting");
+	getChild<LLUICtrl>("loading_text")->setValue(LLSD(msg_waiting));
+}
+
+void LLFloaterMyScripts::setAttachmentSummary(LLSD content)
+{
+	if(content["summary"]["used"][0]["type"].asString() == std::string("memory"))
+	{
+		mAttachmentMemoryUsed = content["summary"]["used"][0]["amount"].asInteger() / SIZE_OF_ONE_KB;
+		mAttachmentMemoryMax = content["summary"]["available"][0]["amount"].asInteger() / SIZE_OF_ONE_KB;
+		mGotAttachmentMemoryUsed = true;
+	}
+	else if(content["summary"]["used"][1]["type"].asString() == std::string("memory"))
+	{
+		mAttachmentMemoryUsed = content["summary"]["used"][1]["amount"].asInteger() / SIZE_OF_ONE_KB;
+		mAttachmentMemoryMax = content["summary"]["available"][1]["amount"].asInteger() / SIZE_OF_ONE_KB;
+		mGotAttachmentMemoryUsed = true;
+	}
+	else
+	{
+		LL_WARNS() << "attachment details don't contain memory summary info" << LL_ENDL;
+		return;
+	}
+	
+	if(content["summary"]["used"][0]["type"].asString() == std::string("urls"))
+	{
+		mAttachmentURLsUsed = content["summary"]["used"][0]["amount"].asInteger();
+		mAttachmentURLsMax = content["summary"]["available"][0]["amount"].asInteger();
+		mGotAttachmentURLsUsed = true;
+	}
+	else if(content["summary"]["used"][1]["type"].asString() == std::string("urls"))
+	{
+		mAttachmentURLsUsed = content["summary"]["used"][1]["amount"].asInteger();
+		mAttachmentURLsMax = content["summary"]["available"][1]["amount"].asInteger();
+		mGotAttachmentURLsUsed = true;
+	}
+	else
+	{
+		LL_WARNS() << "attachment details don't contain urls summary info" << LL_ENDL;
+		return;
+	}
+
+	if((mAttachmentMemoryUsed >= 0) && (mAttachmentMemoryMax >= 0))
+	{
+		LLStringUtil::format_map_t args_attachment_memory;
+		args_attachment_memory["[COUNT]"] = llformat ("%d", mAttachmentMemoryUsed);
+		std::string translate_message = "ScriptLimitsMemoryUsedSimple";
+
+		if (0 < mAttachmentMemoryMax)
+		{
+			S32 attachment_memory_available = mAttachmentMemoryMax - mAttachmentMemoryUsed;
+
+			args_attachment_memory["[MAX]"] = llformat ("%d", mAttachmentMemoryMax);
+			args_attachment_memory["[AVAILABLE]"] = llformat ("%d", attachment_memory_available);
+			translate_message = "ScriptLimitsMemoryUsed";
+		}
+
+		getChild<LLUICtrl>("memory_used")->setValue(LLTrans::getString(translate_message, args_attachment_memory));
+	}
+
+	if((mAttachmentURLsUsed >= 0) && (mAttachmentURLsMax >= 0))
+	{
+		S32 attachment_urls_available = mAttachmentURLsMax - mAttachmentURLsUsed;
+
+		LLStringUtil::format_map_t args_attachment_urls;
+		args_attachment_urls["[COUNT]"] = llformat ("%d", mAttachmentURLsUsed);
+		args_attachment_urls["[MAX]"] = llformat ("%d", mAttachmentURLsMax);
+		args_attachment_urls["[AVAILABLE]"] = llformat ("%d", attachment_urls_available);
+		std::string msg_attachment_urls = LLTrans::getString("ScriptLimitsURLsUsed", args_attachment_urls);
+		getChild<LLUICtrl>("urls_used")->setValue(LLSD(msg_attachment_urls));
+	}
+}
+
+// static
+void LLFloaterMyScripts::onClickRefresh(void* userdata)
+{
+	LLFloaterMyScripts* instance = LLFloaterReg::getTypedInstance<LLFloaterMyScripts>("my_scripts");
+	if(instance)
+	{
+		LLButton* btn = instance->getChild<LLButton>("refresh_list_btn");
+		
+		//To stop people from hammering the refesh button and accidentally dosing themselves - enough requests can crash the viewer!
+		//turn the button off, then turn it on when we get a response
+		if(btn)
+		{
+			btn->setEnabled(false);
+		}
+		instance->clearList();
+		instance->requestAttachmentDetails();
+	}
+	else
+	{
+		LL_WARNS() << "could not find LLFloaterMyScripts instance after refresh button clicked" << LL_ENDL;
+	}
+}
+
diff --git a/indra/newview/llfloatermyscripts.h b/indra/newview/llfloatermyscripts.h
new file mode 100644
index 0000000000..fe33ab90ae
--- /dev/null
+++ b/indra/newview/llfloatermyscripts.h
@@ -0,0 +1,60 @@
+/** 
+ * @file llfloatermyscripts.h
+ * @brief LLFloaterMyScripts class definition.
+ *
+ * $LicenseInfo:firstyear=2004&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2019, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERMYSCRIPTS_H
+#define LL_LLFLOATERMYSCRIPTS_H
+
+#include "llfloater.h"
+#include "llpanel.h"
+
+class LLFloaterMyScripts : public LLFloater
+{
+public:
+	LLFloaterMyScripts(const LLSD& seed);
+
+	BOOL postBuild();
+	void setAttachmentDetails(LLSD content);
+	void setAttachmentSummary(LLSD content);
+	BOOL requestAttachmentDetails();
+	void clearList();
+
+private:
+	void getAttachmentLimitsCoro(std::string url);
+
+	bool mGotAttachmentMemoryUsed;
+	S32 mAttachmentMemoryMax;
+	S32 mAttachmentMemoryUsed;
+
+	bool mGotAttachmentURLsUsed;
+	S32 mAttachmentURLsMax;
+	S32 mAttachmentURLsUsed;
+
+protected:
+	
+	static void onClickRefresh(void* userdata);
+};
+
+#endif
diff --git a/indra/newview/llfloaterscriptlimits.cpp b/indra/newview/llfloaterscriptlimits.cpp
index 21df769d0c..3746b9b6c2 100644
--- a/indra/newview/llfloaterscriptlimits.cpp
+++ b/indra/newview/llfloaterscriptlimits.cpp
@@ -90,19 +90,6 @@ LLFloaterScriptLimits::LLFloaterScriptLimits(const LLSD& seed)
 
 BOOL LLFloaterScriptLimits::postBuild()
 {
-	// a little cheap and cheerful - if there's an about land panel open default to showing parcel info,
-	// otherwise default to showing attachments (avatar appearance)
-	bool selectParcelPanel = false;
-	
-	LLFloaterLand* instance = LLFloaterReg::getTypedInstance<LLFloaterLand>("about_land");
-	if(instance)
-	{
-		if(instance->isShown())
-		{
-			selectParcelPanel = true;
-		}
-	}
-
 	mTab = getChild<LLTabContainer>("scriptlimits_panels");
 	
 	if(!mTab)
@@ -111,28 +98,12 @@ BOOL LLFloaterScriptLimits::postBuild()
 		return FALSE;
 	}
 
-	// contruct the panels
+	// contruct the panel
 	LLPanelScriptLimitsRegionMemory* panel_memory = new LLPanelScriptLimitsRegionMemory;
 	mInfoPanels.push_back(panel_memory);
 	panel_memory->buildFromFile( "panel_script_limits_region_memory.xml");
 	mTab->addTabPanel(panel_memory);
-
-	LLPanelScriptLimitsAttachment* panel_attachments = new LLPanelScriptLimitsAttachment;
-	mInfoPanels.push_back(panel_attachments);
-	panel_attachments->buildFromFile("panel_script_limits_my_avatar.xml");
-	mTab->addTabPanel(panel_attachments);
-
-	
-	if(mInfoPanels.size() > 0)
-	{
-		mTab->selectTab(0);
-	}
-
-	if(!selectParcelPanel && (mInfoPanels.size() > 1))
-	{
-		mTab->selectTab(1);
-	}
-
+	mTab->selectTab(0);
 	return TRUE;
 }
 
@@ -969,269 +940,3 @@ void LLPanelScriptLimitsRegionMemory::onClickReturn(void* userdata)
 	}
 }
 
-///----------------------------------------------------------------------------
-// Attachment Panel
-///----------------------------------------------------------------------------
-
-BOOL LLPanelScriptLimitsAttachment::requestAttachmentDetails()
-{
-	if (!gAgent.getRegion()) return FALSE;
-
-	LLSD body;
-	std::string url = gAgent.getRegion()->getCapability("AttachmentResources");
-	if (!url.empty())
-	{
-        LLCoros::instance().launch("LLPanelScriptLimitsAttachment::getAttachmentLimitsCoro",
-            boost::bind(&LLPanelScriptLimitsAttachment::getAttachmentLimitsCoro, this, url));
-		return TRUE;
-	}
-	else
-	{
-		return FALSE;
-	}
-}
-
-void LLPanelScriptLimitsAttachment::getAttachmentLimitsCoro(std::string url)
-{
-    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
-    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
-        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("getAttachmentLimitsCoro", httpPolicy));
-    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
-
-    LLSD result = httpAdapter->getAndSuspend(httpRequest, url);
-
-    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
-    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
-    if (!status)
-    {
-        LL_WARNS() << "Unable to retrieve attachment limits." << LL_ENDL;
-        return;
-    }
-
-    LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits");
-
-    if (!instance)
-    {
-        LL_WARNS() << "Failed to get llfloaterscriptlimits instance" << LL_ENDL;
-        return;
-    }
-
-    LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels");
-    if (!tab)
-    {
-        LL_WARNS() << "Failed to get scriptlimits_panels" << LL_ENDL;
-        return;
-    }
-
-    LLPanelScriptLimitsAttachment* panel = (LLPanelScriptLimitsAttachment*)tab->getChild<LLPanel>("script_limits_my_avatar_panel");
-    if (!panel)
-    {
-        LL_WARNS() << "Failed to get script_limits_my_avatar_panel" << LL_ENDL;
-        return;
-    }
-
-    panel->getChild<LLUICtrl>("loading_text")->setValue(LLSD(std::string("")));
-
-    LLButton* btn = panel->getChild<LLButton>("refresh_list_btn");
-    if (btn)
-    {
-        btn->setEnabled(true);
-    }
-
-    result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
-    panel->setAttachmentDetails(result);
-}
-
-
-void LLPanelScriptLimitsAttachment::setAttachmentDetails(LLSD content)
-{
-	LLScrollListCtrl *list = getChild<LLScrollListCtrl>("scripts_list");
-	
-	if(!list)
-	{
-		return;
-	}
-	
-	S32 number_attachments = content["attachments"].size();
-
-	for(int i = 0; i < number_attachments; i++)
-	{
-		std::string humanReadableLocation = "";
-		if(content["attachments"][i].has("location"))
-		{
-			std::string actualLocation = content["attachments"][i]["location"];
-			humanReadableLocation = LLTrans::getString(actualLocation.c_str());
-		}
-		
-		S32 number_objects = content["attachments"][i]["objects"].size();
-		for(int j = 0; j < number_objects; j++)
-		{
-			LLUUID task_id = content["attachments"][i]["objects"][j]["id"].asUUID();
-			S32 size = 0;
-			if(content["attachments"][i]["objects"][j]["resources"].has("memory"))
-			{
-				size = content["attachments"][i]["objects"][j]["resources"]["memory"].asInteger() / SIZE_OF_ONE_KB;
-			}
-			S32 urls = 0;
-			if(content["attachments"][i]["objects"][j]["resources"].has("urls"))
-			{
-				urls = content["attachments"][i]["objects"][j]["resources"]["urls"].asInteger();
-			}
-			std::string name = content["attachments"][i]["objects"][j]["name"].asString();
-			
-			LLSD element;
-
-			element["id"] = task_id;
-			element["columns"][0]["column"] = "size";
-			element["columns"][0]["value"] = llformat("%d", size);
-			element["columns"][0]["font"] = "SANSSERIF";
-			element["columns"][0]["halign"] = LLFontGL::RIGHT;
-
-			element["columns"][1]["column"] = "urls";
-			element["columns"][1]["value"] = llformat("%d", urls);
-			element["columns"][1]["font"] = "SANSSERIF";
-			element["columns"][1]["halign"] = LLFontGL::RIGHT;
-			
-			element["columns"][2]["column"] = "name";
-			element["columns"][2]["value"] = name;
-			element["columns"][2]["font"] = "SANSSERIF";
-			
-			element["columns"][3]["column"] = "location";
-			element["columns"][3]["value"] = humanReadableLocation;
-			element["columns"][3]["font"] = "SANSSERIF";
-
-			list->addElement(element);
-		}
-	}
-	
-	setAttachmentSummary(content);
-
-	getChild<LLUICtrl>("loading_text")->setValue(LLSD(std::string("")));
-
-	LLButton* btn = getChild<LLButton>("refresh_list_btn");
-	if(btn)
-	{
-		btn->setEnabled(true);
-	}
-}
-
-BOOL LLPanelScriptLimitsAttachment::postBuild()
-{
-	childSetAction("refresh_list_btn", onClickRefresh, this);
-		
-	std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestWaiting");
-	getChild<LLUICtrl>("loading_text")->setValue(LLSD(msg_waiting));
-	return requestAttachmentDetails();
-}
-
-void LLPanelScriptLimitsAttachment::clearList()
-{
-	LLCtrlListInterface *list = childGetListInterface("scripts_list");
-
-	if (list)
-	{
-		list->operateOnAll(LLCtrlListInterface::OP_DELETE);
-	}
-
-	std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestWaiting");
-	getChild<LLUICtrl>("loading_text")->setValue(LLSD(msg_waiting));
-}
-
-void LLPanelScriptLimitsAttachment::setAttachmentSummary(LLSD content)
-{
-	if(content["summary"]["used"][0]["type"].asString() == std::string("memory"))
-	{
-		mAttachmentMemoryUsed = content["summary"]["used"][0]["amount"].asInteger() / SIZE_OF_ONE_KB;
-		mAttachmentMemoryMax = content["summary"]["available"][0]["amount"].asInteger() / SIZE_OF_ONE_KB;
-		mGotAttachmentMemoryUsed = true;
-	}
-	else if(content["summary"]["used"][1]["type"].asString() == std::string("memory"))
-	{
-		mAttachmentMemoryUsed = content["summary"]["used"][1]["amount"].asInteger() / SIZE_OF_ONE_KB;
-		mAttachmentMemoryMax = content["summary"]["available"][1]["amount"].asInteger() / SIZE_OF_ONE_KB;
-		mGotAttachmentMemoryUsed = true;
-	}
-	else
-	{
-		LL_WARNS() << "attachment details don't contain memory summary info" << LL_ENDL;
-		return;
-	}
-	
-	if(content["summary"]["used"][0]["type"].asString() == std::string("urls"))
-	{
-		mAttachmentURLsUsed = content["summary"]["used"][0]["amount"].asInteger();
-		mAttachmentURLsMax = content["summary"]["available"][0]["amount"].asInteger();
-		mGotAttachmentURLsUsed = true;
-	}
-	else if(content["summary"]["used"][1]["type"].asString() == std::string("urls"))
-	{
-		mAttachmentURLsUsed = content["summary"]["used"][1]["amount"].asInteger();
-		mAttachmentURLsMax = content["summary"]["available"][1]["amount"].asInteger();
-		mGotAttachmentURLsUsed = true;
-	}
-	else
-	{
-		LL_WARNS() << "attachment details don't contain urls summary info" << LL_ENDL;
-		return;
-	}
-
-	if((mAttachmentMemoryUsed >= 0) && (mAttachmentMemoryMax >= 0))
-	{
-		LLStringUtil::format_map_t args_attachment_memory;
-		args_attachment_memory["[COUNT]"] = llformat ("%d", mAttachmentMemoryUsed);
-		std::string translate_message = "ScriptLimitsMemoryUsedSimple";
-
-		if (0 < mAttachmentMemoryMax)
-		{
-			S32 attachment_memory_available = mAttachmentMemoryMax - mAttachmentMemoryUsed;
-
-			args_attachment_memory["[MAX]"] = llformat ("%d", mAttachmentMemoryMax);
-			args_attachment_memory["[AVAILABLE]"] = llformat ("%d", attachment_memory_available);
-			translate_message = "ScriptLimitsMemoryUsed";
-		}
-
-		getChild<LLUICtrl>("memory_used")->setValue(LLTrans::getString(translate_message, args_attachment_memory));
-	}
-
-	if((mAttachmentURLsUsed >= 0) && (mAttachmentURLsMax >= 0))
-	{
-		S32 attachment_urls_available = mAttachmentURLsMax - mAttachmentURLsUsed;
-
-		LLStringUtil::format_map_t args_attachment_urls;
-		args_attachment_urls["[COUNT]"] = llformat ("%d", mAttachmentURLsUsed);
-		args_attachment_urls["[MAX]"] = llformat ("%d", mAttachmentURLsMax);
-		args_attachment_urls["[AVAILABLE]"] = llformat ("%d", attachment_urls_available);
-		std::string msg_attachment_urls = LLTrans::getString("ScriptLimitsURLsUsed", args_attachment_urls);
-		getChild<LLUICtrl>("urls_used")->setValue(LLSD(msg_attachment_urls));
-	}
-}
-
-// static
-void LLPanelScriptLimitsAttachment::onClickRefresh(void* userdata)
-{
-	LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits");
-	if(instance)
-	{
-		LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels");
-		LLPanelScriptLimitsAttachment* panel_attachments = (LLPanelScriptLimitsAttachment*)tab->getChild<LLPanel>("script_limits_my_avatar_panel");
-		LLButton* btn = panel_attachments->getChild<LLButton>("refresh_list_btn");
-		
-		//To stop people from hammering the refesh button and accidentally dosing themselves - enough requests can crash the viewer!
-		//turn the button off, then turn it on when we get a response
-		if(btn)
-		{
-			btn->setEnabled(false);
-		}
-		panel_attachments->clearList();
-		panel_attachments->requestAttachmentDetails();
-		
-		return;
-	}
-	else
-	{
-		LL_WARNS() << "could not find LLPanelScriptLimitsRegionMemory instance after refresh button clicked" << LL_ENDL;
-		return;
-	}
-}
-
diff --git a/indra/newview/llfloaterscriptlimits.h b/indra/newview/llfloaterscriptlimits.h
index 16450c6527..d2192f9d01 100644
--- a/indra/newview/llfloaterscriptlimits.h
+++ b/indra/newview/llfloaterscriptlimits.h
@@ -152,51 +152,4 @@ protected:
 	static void onClickReturn(void* userdata);
 };
 
-/////////////////////////////////////////////////////////////////////////////
-// Attachment panel
-/////////////////////////////////////////////////////////////////////////////
-
-class LLPanelScriptLimitsAttachment : public LLPanelScriptLimitsInfo
-{
-	
-public:
-	LLPanelScriptLimitsAttachment()
-		:	LLPanelScriptLimitsInfo(),
-		mGotAttachmentMemoryUsed(false),
-		mAttachmentMemoryMax(0),
-		mAttachmentMemoryUsed(0),
-		mGotAttachmentURLsUsed(false),
-		mAttachmentURLsMax(0),
-		mAttachmentURLsUsed(0)
-		{};
-
-	~LLPanelScriptLimitsAttachment()
-	{
-	};
-	
-	// LLPanel
-	virtual BOOL postBuild();
-
-	void setAttachmentDetails(LLSD content);
-
-	void setAttachmentSummary(LLSD content);
-	BOOL requestAttachmentDetails();
-	void clearList();
-
-private:
-    void getAttachmentLimitsCoro(std::string url);
-
-	bool mGotAttachmentMemoryUsed;
-	S32 mAttachmentMemoryMax;
-	S32 mAttachmentMemoryUsed;
-
-	bool mGotAttachmentURLsUsed;
-	S32 mAttachmentURLsMax;
-	S32 mAttachmentURLsUsed;
-
-protected:
-	
-	static void onClickRefresh(void* userdata);
-};
-
 #endif
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 0ebacddd9b..a7b2fafddf 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -90,6 +90,7 @@
 #include "llfloatermediasettings.h"
 #include "llfloatermemleak.h"
 #include "llfloatermodelpreview.h"
+#include "llfloatermyscripts.h"
 #include "llfloaternamedesc.h"
 #include "llfloaternotificationsconsole.h"
 #include "llfloaternotificationstabbed.h"
@@ -335,6 +336,7 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("script_debug_output", "floater_script_debug_panel.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterScriptDebugOutput>);
 	LLFloaterReg::add("script_floater", "floater_script.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLScriptFloater>);
 	LLFloaterReg::add("script_limits", "floater_script_limits.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterScriptLimits>);
+	LLFloaterReg::add("my_scripts", "floater_my_scripts.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMyScripts>);
 	LLFloaterReg::add("sell_land", "floater_sell_land.xml", &LLFloaterSellLand::buildFloater);
 	LLFloaterReg::add("settings_debug", "floater_settings_debug.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSettingsDebug>);
 	LLFloaterReg::add("sound_devices", "floater_sound_devices.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSoundDevices>);
diff --git a/indra/newview/skins/default/xui/en/floater_my_scripts.xml b/indra/newview/skins/default/xui/en/floater_my_scripts.xml
new file mode 100644
index 0000000000..3b0b6723c7
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_my_scripts.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ legacy_header_height="18"
+ can_resize="true"
+ height="570"
+ help_topic="scriptlimits"
+ layout="topleft"
+ name="myscripts"
+ save_rect="true"
+ title="My Scripts"
+ min_width="620"
+ width="620">
+  <panel
+   filename="panel_script_limits_my_avatar.xml"
+   follows="all"
+   bottom="555"
+   layout="topleft"
+   left="3"
+   right="-2"
+   name="script_limits_my_avatar_panel"
+   top="20"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 42744b561f..cac84cfccf 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -73,6 +73,13 @@
           function="Floater.ToggleOrBringToFront"
           parameter="experiences"/>
       </menu_item_call>
+      <menu_item_call
+        label="My Scripts..."
+        name="MyScripts">
+        <menu_item_call.on_click
+          function="Floater.ToggleOrBringToFront"
+          parameter="my_scripts"/>
+      </menu_item_call>
       <menu_item_separator/>
       <menu_item_call
        label="Camera Controls..."
-- 
cgit v1.2.3


From 58adb333680042bedefcd41674d5c91c52862575 Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Thu, 21 Feb 2019 14:23:36 +0200
Subject: SL-5366 Add Simplified Chinese fonts for Mac and Win10

---
 indra/newview/skins/default/xui/en/fonts.xml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/indra/newview/skins/default/xui/en/fonts.xml b/indra/newview/skins/default/xui/en/fonts.xml
index 82027d9e7c..8b1d50e58f 100644
--- a/indra/newview/skins/default/xui/en/fonts.xml
+++ b/indra/newview/skins/default/xui/en/fonts.xml
@@ -9,6 +9,7 @@
       <file>gulim.ttc</file>
       <file>simhei.ttf</file>
       <file>ArialUni.ttf</file>
+      <file>msyh.ttc</file>
     </os>
     <os name="Mac">
       <file>ヒラギノ角ゴシック W3.ttc</file>  
@@ -19,6 +20,7 @@
       <file>AppleGothic.ttf</file>
       <file>AppleSDGothicNeo-Regular.otf</file>
       <file>华文细黑.ttf</file>
+      <file>PingFang.ttc</file>
     </os>
   </font>
 
-- 
cgit v1.2.3


From 86d28366b1f53f56c444e5a5ccc025cd6b136b36 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Wed, 20 Feb 2019 20:30:43 +0200
Subject: SL-1811 Slight chat optimization

---
 indra/llui/lllayoutstack.cpp           |   8 ++-
 indra/newview/llconversationview.cpp   |  13 +++--
 indra/newview/llfloaterimcontainer.cpp | 104 ++++++++++++++++++++-------------
 indra/newview/llfloaterimcontainer.h   |   4 ++
 4 files changed, 83 insertions(+), 46 deletions(-)

diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index 69246a2f57..b1ba725c2f 100644
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -251,8 +251,14 @@ void LLLayoutStack::draw()
 
 	// always clip to stack itself
 	LLLocalClipRect clip(getLocalRect());
-	BOOST_FOREACH(LLLayoutPanel* panelp, mPanels)
+	for (LLLayoutPanel* panelp : mPanels)
 	{
+		if ((!panelp->getVisible() || panelp->mCollapsed)
+			&& (panelp->mVisibleAmt < 0.001f || !mAnimate))
+		{
+			// essentially invisible
+			continue;
+		}
 		// clip to layout rectangle, not bounding rectangle
 		LLRect clip_rect = panelp->getRect();
 		// scale clipping rectangle by visible amount
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index dee0a52ce8..59bb9af744 100644
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -234,6 +234,8 @@ void LLConversationViewSession::draw()
 	// Draw children if root folder, or any other folder that is open. Do not draw children when animating to closed state or you get rendering overlap.
 	bool draw_children = getRoot() == static_cast<LLFolderViewFolder*>(this) || isOpen();
 
+	// Todo/fix this: arrange hides children 'out of bonds', session 'slowly' adjusts container size, unhides children
+	// this process repeats until children fit
 	for (folders_t::iterator iter = mFolders.begin();
 		iter != mFolders.end();)
 	{
@@ -254,9 +256,6 @@ void LLConversationViewSession::draw()
 		updateLabelRotation();
 		drawOpenFolderArrow(default_params, sFgColor);
 	}
-
-	refresh();        
-
 	LLView::draw();
 }
 
@@ -568,6 +567,7 @@ void LLConversationViewParticipant::draw()
     F32 text_left = (F32)getLabelXPos();
 	
 	LLColor4 color;
+
 	LLLocalSpeakerMgr *speakerMgr = LLLocalSpeakerMgr::getInstance();
 
 	if (speakerMgr && speakerMgr->isSpeakerToBeRemoved(mUUID))
@@ -579,9 +579,14 @@ void LLConversationViewParticipant::draw()
 		color = mIsSelected ? sHighlightFgColor : sFgColor;
 	}
 
+	LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(getViewModelItem());
+	if (participant_model)
+	{
+		mSpeakingIndicator->setIsModeratorMuted(participant_model->isModeratorMuted());
+	}
+
     drawHighlight(show_context, mIsSelected, sHighlightBgColor, sFlashBgColor, sFocusOutlineColor, sMouseOverColor);
     drawLabel(font, text_left, y, color, right_x);
-	refresh();
 
     LLView::draw();
 }
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 3cfa1133df..30d05ae287 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -269,6 +269,9 @@ BOOL LLFloaterIMContainer::postBuild()
 	// When display name option change, we need to reload all participant names
 	LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLFloaterIMContainer::processParticipantsStyleUpdate, this));
 
+    mParticipantRefreshTimer.setTimerExpirySec(0);
+    mParticipantRefreshTimer.start();
+
 	return TRUE;
 }
 
@@ -420,14 +423,66 @@ void LLFloaterIMContainer::processParticipantsStyleUpdate()
 void LLFloaterIMContainer::idle(void* user_data)
 {
 	LLFloaterIMContainer* self = static_cast<LLFloaterIMContainer*>(user_data);
-	
-	// Update the distance to agent in the nearby chat session if required
-	// Note: it makes no sense of course to update the distance in other session
-	if (self->mConversationViewModel.getSorter().getSortOrderParticipants() == LLConversationFilter::SO_DISTANCE)
-	{
-		self->setNearbyDistances();
-	}
-	self->mConversationsRoot->update();
+
+    if (!self->getVisible() || self->isMinimized())
+    {
+        return;
+    }
+    self->idleUpdate();
+}
+
+void LLFloaterIMContainer::idleUpdate()
+{
+    if (mTabContainer->getTabCount() == 0)
+    {
+        // Do not close the container when every conversation is torn off because the user
+        // still needs the conversation list. Simply collapse the message pane in that case.
+        collapseMessagesPane(true);
+    }
+
+    U32 sort_order = mConversationViewModel.getSorter().getSortOrderParticipants();
+
+    if (mParticipantRefreshTimer.hasExpired())
+    {
+        const LLConversationItem *current_session = getCurSelectedViewModelItem();
+        if (current_session)
+        {
+            // Update moderator options visibility
+            LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = current_session->getChildrenBegin();
+            LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = current_session->getChildrenEnd();
+            bool is_moderator = isGroupModerator();
+            bool can_ban = haveAbilityToBan();
+            while (current_participant_model != end_participant_model)
+            {
+                LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
+                participant_model->setModeratorOptionsVisible(is_moderator && participant_model->getUUID() != gAgentID);
+                participant_model->setGroupBanVisible(can_ban && participant_model->getUUID() != gAgentID);
+
+                current_participant_model++;
+            }
+            // Update floater's title as required by the currently selected session or use the default title
+            LLFloaterIMSession * conversation_floaterp = LLFloaterIMSession::findInstance(current_session->getUUID());
+            setTitle(conversation_floaterp && conversation_floaterp->needsTitleOverwrite() ? conversation_floaterp->getTitle() : mGeneralTitle);
+        }
+
+        mParticipantRefreshTimer.setTimerExpirySec(1.0f);
+    }
+
+    // Update the distance to agent in the nearby chat session if required
+    // Note: it makes no sense of course to update the distance in other session
+    if (sort_order == LLConversationFilter::SO_DISTANCE)
+    {
+        // almost real-time updates
+        setNearbyDistances(); //calls arrange all
+    }
+    mConversationsRoot->update(); //arranges, resizes, heavy
+
+    // "Manually" resize of mConversationsPane: same as temporarity cancellation of the flag "auto_resize=false" for it
+    if (!mConversationsPane->isCollapsed() && mMessagesPane->isCollapsed())
+    {
+        LLRect stack_rect = mConversationsStack->getRect();
+        mConversationsPane->reshape(stack_rect.getWidth(), stack_rect.getHeight(), true);
+    }
 }
 
 bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event)
@@ -526,39 +581,6 @@ bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event)
 
 void LLFloaterIMContainer::draw()
 {
-	if (mTabContainer->getTabCount() == 0)
-	{
-		// Do not close the container when every conversation is torn off because the user
-		// still needs the conversation list. Simply collapse the message pane in that case.
-		collapseMessagesPane(true);
-	}
-	
-	const LLConversationItem *current_session = getCurSelectedViewModelItem();
-	if (current_session)
-	{
-		// Update moderator options visibility
-		LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = current_session->getChildrenBegin();
-		LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = current_session->getChildrenEnd();
-		while (current_participant_model != end_participant_model)
-		{
-			LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
-			participant_model->setModeratorOptionsVisible(isGroupModerator() && participant_model->getUUID() != gAgentID);
-			participant_model->setGroupBanVisible(haveAbilityToBan() && participant_model->getUUID() != gAgentID);
-
-			current_participant_model++;
-		}
-		// Update floater's title as required by the currently selected session or use the default title
-		LLFloaterIMSession * conversation_floaterp = LLFloaterIMSession::findInstance(current_session->getUUID());
-		setTitle(conversation_floaterp && conversation_floaterp->needsTitleOverwrite() ? conversation_floaterp->getTitle() : mGeneralTitle);
-	}
-
-    // "Manually" resize of mConversationsPane: same as temporarity cancellation of the flag "auto_resize=false" for it
-	if (!mConversationsPane->isCollapsed() && mMessagesPane->isCollapsed())
-	{
-		LLRect stack_rect = mConversationsStack->getRect();
-		mConversationsPane->reshape(stack_rect.getWidth(), stack_rect.getHeight(), true);
-	}
-
 	LLFloater::draw();
 }
 
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index 90fc0c2bdd..78b3572111 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -180,6 +180,8 @@ private:
 	void openNearbyChat();
 	bool isParticipantListExpanded();
 
+	void idleUpdate(); // for convenience (self) from static idle
+
 	LLButton* mExpandCollapseBtn;
 	LLButton* mStubCollapseBtn;
     LLButton* mSpeakBtn;
@@ -226,6 +228,8 @@ private:
 	LLConversationViewModel mConversationViewModel;
 	LLFolderView* mConversationsRoot;
 	LLEventStream mConversationsEventStream; 
+
+	LLTimer mParticipantRefreshTimer;
 };
 
 #endif // LL_LLFLOATERIMCONTAINER_H
-- 
cgit v1.2.3


From 9719841f63d9e9846bbe954d2bf182428129eb20 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Mon, 25 Feb 2019 11:36:28 +0200
Subject: SL-10326 Restore ability to select own avatar and move it via
 manipulation arrows

---
 indra/newview/llselectmgr.cpp    | 8 ++++++++
 indra/newview/llselectmgr.h      | 2 ++
 indra/newview/llviewerwindow.cpp | 2 +-
 3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 4a2d545b33..02093fa6bd 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -3857,6 +3857,14 @@ BOOL LLSelectMgr::selectGetAggregateTexturePermissions(LLAggregatePermissions& r
 	return TRUE;
 }
 
+BOOL LLSelectMgr::isSelfAvatarSelected()
+{
+	if (mAllowSelectAvatar)
+	{
+		return (getSelection()->getObjectCount() == 1) && (getSelection()->getFirstRootObject() == gAgentAvatarp);
+	}
+	return FALSE;
+}
 
 //--------------------------------------------------------------------
 // Duplicate objects
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index caf104178f..9f2ac857a5 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -709,6 +709,8 @@ public:
 
 	LLPermissions* findObjectPermissions(const LLViewerObject* object);
 
+	BOOL isSelfAvatarSelected();
+
 	void selectDelete();							// Delete on simulator
 	void selectForceDelete();			// just delete, no into trash
 	void selectDuplicate(const LLVector3& offset, BOOL select_copy);	// Duplicate on simulator
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index e53ccd7b8d..3b12816c99 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -3845,7 +3845,7 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls,
 
 					BOOL draw_handles = TRUE;
 
-					if (tool == LLToolCompTranslate::getInstance() && !all_selected_objects_move)
+					if (tool == LLToolCompTranslate::getInstance() && !all_selected_objects_move && !LLSelectMgr::getInstance()->isSelfAvatarSelected())
 					{
 						draw_handles = FALSE;
 					}
-- 
cgit v1.2.3


From 394615c62f8256adba3191f1bc01d93c747b974b Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Thu, 21 Feb 2019 19:51:32 +0200
Subject: SL-10565 LLMachineID crashes

---
 indra/newview/llmachineid.cpp | 35 ++++++++++++++++++++---------------
 1 file changed, 20 insertions(+), 15 deletions(-)

diff --git a/indra/newview/llmachineid.cpp b/indra/newview/llmachineid.cpp
index b0ee8e7fcb..2001359e50 100644
--- a/indra/newview/llmachineid.cpp
+++ b/indra/newview/llmachineid.cpp
@@ -65,11 +65,11 @@ public:
 
 S32 LLMachineID::init()
 {
-    memset(static_unique_id,0,sizeof(static_unique_id));
+    size_t len = sizeof(static_unique_id);
+    memset(static_unique_id, 0, len);
     S32 ret_code = 0;
 #if	LL_WINDOWS
 # pragma comment(lib, "wbemuuid.lib")
-        size_t len = sizeof(static_unique_id);
 
         // algorithm to detect BIOS serial number found at:
         // http://msdn.microsoft.com/en-us/library/aa394077%28VS.85%29.aspx
@@ -218,16 +218,19 @@ S32 LLMachineID::init()
             // Get the value of the Name property
             hr = pclsObj->Get(L"SerialNumber", 0, &vtProp, 0, 0);
             LL_INFOS("AppInit") << " Serial Number : " << vtProp.bstrVal << LL_ENDL;
+
             // use characters in the returned Serial Number to create a byte array of size len
             BSTR serialNumber ( vtProp.bstrVal);
+            unsigned int serial_size = SysStringLen(serialNumber);
             unsigned int j = 0;
-            while( vtProp.bstrVal[j] != 0)
+
+            while (j < serial_size)
             {
                 for (unsigned int i = 0; i < len; i++)
                 {
-                    if (vtProp.bstrVal[j] == 0)
+                    if (j >= serial_size)
                         break;
-                    
+
                     static_unique_id[i] = (unsigned int)(static_unique_id[i] + serialNumber[j]);
                     j++;
                 }
@@ -254,16 +257,8 @@ S32 LLMachineID::init()
         ret_code = LLUUID::getNodeID(staticPtr);
 #endif
         has_static_unique_id = true;
-        return ret_code;
-}
-
 
-S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len)
-{
-    if (has_static_unique_id)
-    {
-        memcpy ( unique_id, &static_unique_id, len);
-        LL_INFOS_ONCE("AppInit") << "UniqueID: 0x";
+        LL_INFOS("AppInit") << "UniqueID: 0x";
         // Code between here and LL_ENDL is not executed unless the LL_DEBUGS
         // actually produces output
         for (size_t i = 0; i < len; ++i)
@@ -271,11 +266,21 @@ S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len)
             // Copy each char to unsigned int to hexify. Sending an unsigned
             // char to a std::ostream tries to represent it as a char, not
             // what we want here.
-            unsigned byte = unique_id[i];
+            unsigned byte = static_unique_id[i];
             LL_CONT << std::hex << std::setw(2) << std::setfill('0') << byte;
         }
         // Reset default output formatting to avoid nasty surprises!
         LL_CONT << std::dec << std::setw(0) << std::setfill(' ') << LL_ENDL;
+
+        return ret_code;
+}
+
+
+S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len)
+{
+    if (has_static_unique_id)
+    {
+        memcpy ( unique_id, &static_unique_id, len);
         return 1;
     }
     return 0;
-- 
cgit v1.2.3


From b3e4a3177353971a62d9d2509466ca25d9a6d4bd Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Thu, 21 Feb 2019 19:50:48 +0200
Subject: SL-10567 Fix confusing declaration

---
 indra/newview/llpreviewnotecard.h | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/indra/newview/llpreviewnotecard.h b/indra/newview/llpreviewnotecard.h
index 46a6d0ef50..8908078c63 100644
--- a/indra/newview/llpreviewnotecard.h
+++ b/indra/newview/llpreviewnotecard.h
@@ -47,18 +47,18 @@ public:
 	virtual ~LLPreviewNotecard();
 	
 	bool saveItem();
-	void setObjectID(const LLUUID& object_id);
+	void setObjectID(const LLUUID& object_id) override;
 
 	// llview
-	virtual void draw();
-	virtual BOOL handleKeyHere(KEY key, MASK mask);
-	virtual void setEnabled( BOOL enabled );
+	void draw() override;
+	BOOL handleKeyHere(KEY key, MASK mask) override;
+	void setEnabled( BOOL enabled ) override;
 
 	// llfloater
-	virtual BOOL canClose();
+	BOOL canClose() override;
 
 	// llpanel
-	virtual BOOL postBuild();
+	BOOL postBuild() override;
 
 	// reach into the text editor, and grab the drag item
 	const LLInventoryItem* getDragItem();
@@ -74,8 +74,8 @@ public:
 
 protected:
 
-	void updateTitleButtons();
-	virtual void loadAsset();
+	void updateTitleButtons() override;
+	void loadAsset() override;
 	bool saveIfNeeded(LLInventoryItem* copyitem = NULL);
 
 	void deleteNotecard();
-- 
cgit v1.2.3


From df840bde0f83c6ecf3b67c39bedf7f67a71b3dcd Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 21 Feb 2019 19:45:09 -1000
Subject: INTL-318: Add translations for new Windows installer messages.

---
 indra/newview/installers/windows/lang_de.nsi    | Bin 12582 -> 13014 bytes
 indra/newview/installers/windows/lang_es.nsi    | Bin 12630 -> 12744 bytes
 indra/newview/installers/windows/lang_fr.nsi    | Bin 12990 -> 13262 bytes
 indra/newview/installers/windows/lang_it.nsi    | Bin 12278 -> 12480 bytes
 indra/newview/installers/windows/lang_ja.nsi    | Bin 9988 -> 9644 bytes
 indra/newview/installers/windows/lang_pt-br.nsi | Bin 12748 -> 12892 bytes
 indra/newview/installers/windows/lang_ru.nsi    | Bin 11940 -> 12216 bytes
 indra/newview/installers/windows/lang_tr.nsi    | Bin 12044 -> 12128 bytes
 indra/newview/installers/windows/lang_zh.nsi    | Bin 9708 -> 9082 bytes
 9 files changed, 0 insertions(+), 0 deletions(-)
 mode change 100644 => 100755 indra/newview/installers/windows/lang_de.nsi
 mode change 100644 => 100755 indra/newview/installers/windows/lang_es.nsi
 mode change 100644 => 100755 indra/newview/installers/windows/lang_fr.nsi
 mode change 100644 => 100755 indra/newview/installers/windows/lang_it.nsi
 mode change 100644 => 100755 indra/newview/installers/windows/lang_ja.nsi
 mode change 100644 => 100755 indra/newview/installers/windows/lang_pt-br.nsi
 mode change 100644 => 100755 indra/newview/installers/windows/lang_ru.nsi
 mode change 100644 => 100755 indra/newview/installers/windows/lang_tr.nsi
 mode change 100644 => 100755 indra/newview/installers/windows/lang_zh.nsi

diff --git a/indra/newview/installers/windows/lang_de.nsi b/indra/newview/installers/windows/lang_de.nsi
old mode 100644
new mode 100755
index 6abd496849..8bb20476b3
Binary files a/indra/newview/installers/windows/lang_de.nsi and b/indra/newview/installers/windows/lang_de.nsi differ
diff --git a/indra/newview/installers/windows/lang_es.nsi b/indra/newview/installers/windows/lang_es.nsi
old mode 100644
new mode 100755
index 5daac908c9..b45f0520c7
Binary files a/indra/newview/installers/windows/lang_es.nsi and b/indra/newview/installers/windows/lang_es.nsi differ
diff --git a/indra/newview/installers/windows/lang_fr.nsi b/indra/newview/installers/windows/lang_fr.nsi
old mode 100644
new mode 100755
index c437a0bdb4..f038c0e419
Binary files a/indra/newview/installers/windows/lang_fr.nsi and b/indra/newview/installers/windows/lang_fr.nsi differ
diff --git a/indra/newview/installers/windows/lang_it.nsi b/indra/newview/installers/windows/lang_it.nsi
old mode 100644
new mode 100755
index 78be4a3464..bd16d8318f
Binary files a/indra/newview/installers/windows/lang_it.nsi and b/indra/newview/installers/windows/lang_it.nsi differ
diff --git a/indra/newview/installers/windows/lang_ja.nsi b/indra/newview/installers/windows/lang_ja.nsi
old mode 100644
new mode 100755
index 2eb40e280b..71edde1992
Binary files a/indra/newview/installers/windows/lang_ja.nsi and b/indra/newview/installers/windows/lang_ja.nsi differ
diff --git a/indra/newview/installers/windows/lang_pt-br.nsi b/indra/newview/installers/windows/lang_pt-br.nsi
old mode 100644
new mode 100755
index 79c2b7b114..0e7cbeacda
Binary files a/indra/newview/installers/windows/lang_pt-br.nsi and b/indra/newview/installers/windows/lang_pt-br.nsi differ
diff --git a/indra/newview/installers/windows/lang_ru.nsi b/indra/newview/installers/windows/lang_ru.nsi
old mode 100644
new mode 100755
index 0ef1023d88..8a362ba02a
Binary files a/indra/newview/installers/windows/lang_ru.nsi and b/indra/newview/installers/windows/lang_ru.nsi differ
diff --git a/indra/newview/installers/windows/lang_tr.nsi b/indra/newview/installers/windows/lang_tr.nsi
old mode 100644
new mode 100755
index 4bb4e14bfa..8b8a69a024
Binary files a/indra/newview/installers/windows/lang_tr.nsi and b/indra/newview/installers/windows/lang_tr.nsi differ
diff --git a/indra/newview/installers/windows/lang_zh.nsi b/indra/newview/installers/windows/lang_zh.nsi
old mode 100644
new mode 100755
index fccf119625..397bd0ac81
Binary files a/indra/newview/installers/windows/lang_zh.nsi and b/indra/newview/installers/windows/lang_zh.nsi differ
-- 
cgit v1.2.3


From f235317cb2c0713530e2459ab6ca9556f2ac9904 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 21 Feb 2019 20:45:18 -1000
Subject: INTL-318: Fix syntax error in lang_es.nsi.

---
 indra/newview/installers/windows/lang_es.nsi | Bin 12744 -> 12744 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)

diff --git a/indra/newview/installers/windows/lang_es.nsi b/indra/newview/installers/windows/lang_es.nsi
index b45f0520c7..8a81110069 100755
Binary files a/indra/newview/installers/windows/lang_es.nsi and b/indra/newview/installers/windows/lang_es.nsi differ
-- 
cgit v1.2.3


From c505cf1914110785b94268afbbfa8ecb0505c462 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 22 Feb 2019 05:20:09 -1000
Subject: INTL-318: Fix similar syntax error in lang_ru.nsi.

---
 indra/newview/installers/windows/lang_ru.nsi | Bin 12216 -> 12216 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)

diff --git a/indra/newview/installers/windows/lang_ru.nsi b/indra/newview/installers/windows/lang_ru.nsi
index 8a362ba02a..d55aacc971 100755
Binary files a/indra/newview/installers/windows/lang_ru.nsi and b/indra/newview/installers/windows/lang_ru.nsi differ
-- 
cgit v1.2.3


From 765259b20060b51e236e326ae2ebe0a219c80864 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 22 Feb 2019 06:03:32 -1000
Subject: INTL-318: Fix syntax error in lang_tr.nsi.

---
 indra/newview/installers/windows/lang_tr.nsi | Bin 12128 -> 12126 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)

diff --git a/indra/newview/installers/windows/lang_tr.nsi b/indra/newview/installers/windows/lang_tr.nsi
index 8b8a69a024..4746f84482 100755
Binary files a/indra/newview/installers/windows/lang_tr.nsi and b/indra/newview/installers/windows/lang_tr.nsi differ
-- 
cgit v1.2.3


From ba8f261fdf83108cf5bc48442876916d7c32b666 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Fri, 22 Feb 2019 21:02:51 +0200
Subject: SL-10422 Validate loaded mesh

---
 indra/newview/llmeshrepository.cpp | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 2e7141bcfc..c4e7b17322 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -1823,7 +1823,17 @@ bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* dat
 			return false;
 		}
 
-		header_size += stream.tellg();
+		if (!header.isMap() || !header.has("version"))
+		{
+			LL_WARNS(LOG_MESH) << "Mesh header is invalid for ID: " << mesh_id << LL_ENDL;
+			return false;
+		}
+
+		// make sure there is at least one lod, function returns -1 and marks as 404 otherwise
+		if (LLMeshRepository::getActualMeshLOD(header, 0) >= 0)
+		{
+			header_size += stream.tellg();
+		}
 	}
 	else
 	{
@@ -2908,9 +2918,14 @@ S32 LLMeshRepository::getActualMeshLOD(LLSD& header, S32 lod)
 {
 	lod = llclamp(lod, 0, 3);
 
+	if (header.has("404"))
+	{
+		return -1;
+	}
+
 	S32 version = header["version"];
 
-	if (header.has("404") || version > MAX_MESH_VERSION)
+	if (version > MAX_MESH_VERSION)
 	{
 		return -1;
 	}
-- 
cgit v1.2.3


From 54b444c5d5e4e7ee80801e5eeed6b32227096580 Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Sat, 23 Feb 2019 20:05:15 +0200
Subject: Backed out changeset: d531bea24d6e

---
 indra/newview/llfloatermodelpreview.cpp | 62 +++++++--------------------------
 indra/newview/llfloatermodelpreview.h   |  5 +--
 2 files changed, 14 insertions(+), 53 deletions(-)

diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index e39e210939..616bee84fd 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -304,10 +304,10 @@ BOOL LLFloaterModelPreview::postBuild()
 		getChild<LLSpinCtrl>("lod_triangle_limit_" + lod_name[lod])->setCommitCallback(boost::bind(&LLFloaterModelPreview::onLODParamCommit, this, lod, true));
 	}
 
-	childSetCommitCallback("upload_skin", boost::bind(&LLFloaterModelPreview::onUploadOptionChecked, this, _1), NULL);
-	childSetCommitCallback("upload_joints", boost::bind(&LLFloaterModelPreview::onUploadOptionChecked, this, _1), NULL);
-	childSetCommitCallback("lock_scale_if_joint_position", boost::bind(&LLFloaterModelPreview::onUploadOptionChecked, this, _1), NULL);
-	childSetCommitCallback("upload_textures", boost::bind(&LLFloaterModelPreview::onUploadOptionChecked, this, _1), NULL);
+	childSetCommitCallback("upload_skin", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL);
+	childSetCommitCallback("upload_joints", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL);
+	childSetCommitCallback("lock_scale_if_joint_position", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL);
+	childSetCommitCallback("upload_textures", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL);
 
 	childSetTextArg("status", "[STATUS]", getString("status_idle"));
 
@@ -449,16 +449,6 @@ void LLFloaterModelPreview::initModelPreview()
 	mModelPreview->setModelUpdatedCallback(boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this, _1));
 }
 
-void LLFloaterModelPreview::onUploadOptionChecked(LLUICtrl* ctrl)
-{
-	if (mModelPreview)
-	{
-		auto name = ctrl->getName();
-		mModelPreview->mViewOption[name] = !mModelPreview->mViewOption[name];
-	}
-	toggleCalculateButton(true);
-}
-
 void LLFloaterModelPreview::onViewOptionChecked(LLUICtrl* ctrl)
 {
 	if (mModelPreview)
@@ -641,7 +631,6 @@ void LLFloaterModelPreview::onGenerateNormalsCommit(LLUICtrl* ctrl, void* userda
 void LLFloaterModelPreview::toggleGenarateNormals()
 {
 	bool enabled = childGetValue("gen_normals").asBoolean();
-	mModelPreview->mViewOption["gen_normals"] = enabled;
 	childSetEnabled("crease_angle", enabled);
 	if(enabled) {
 		mModelPreview->generateNormals();
@@ -1167,8 +1156,10 @@ void LLFloaterModelPreview::initDecompControls()
 							std::string label = llformat("%.1f", value);
 							combo_box->add(label, value, ADD_BOTTOM, true);
 						}
+						combo_box->setValue(param[i].mDefault.mFloat);
+
 					}
-					combo_box->setValue(param[i].mDefault.mFloat);
+
 					combo_box->setCommitCallback(onPhysicsParamCommit, (void*) &param[i]);
 				}
 			}
@@ -1240,7 +1231,7 @@ void LLFloaterModelPreview::initDecompControls()
 			//LL_INFOS() << "-----------------------------" << LL_ENDL;
 		}
 	}
-	mDefaultDecompParams = mDecompParams;
+
 	childSetCommitCallback("physics_explode", LLFloaterModelPreview::onExplodeCommit, this);
 }
 
@@ -4429,7 +4420,6 @@ void LLFloaterModelPreview::onReset(void* user_data)
 	std::string filename = mp->mLODFile[LLModel::LOD_HIGH]; 
 
 	fmp->resetDisplayOptions();
-	fmp->resetUploadOptions();
 	//reset model preview
 	fmp->initModelPreview();
 
@@ -4543,6 +4533,11 @@ void LLFloaterModelPreview::setStatusMessage(const std::string& msg)
 	mStatusMessage = msg;
 }
 
+void LLFloaterModelPreview::toggleCalculateButton()
+{
+	toggleCalculateButton(true);
+}
+
 void LLFloaterModelPreview::toggleCalculateButton(bool visible)
 {
 	mCalculateBtn->setVisible(visible);
@@ -4604,37 +4599,6 @@ void LLFloaterModelPreview::resetDisplayOptions()
 	}
 }
 
-void LLFloaterModelPreview::resetUploadOptions()
-{
-	childSetValue("import_scale", 1);
-	childSetValue("pelvis_offset", 0);
-	childSetValue("physics_explode", 0);
-	childSetValue("physics_file", "");
-	childSetVisible("Retain%", false);
-	childSetVisible("Retain%_label", false);
-	childSetVisible("Detail Scale", true);
-	childSetVisible("Detail Scale label", true);
-
-	getChild<LLComboBox>("lod_source_" + lod_name[NUM_LOD - 1])->setCurrentByIndex(LLModelPreview::LOD_FROM_FILE);
-	for (S32 lod = 0; lod < NUM_LOD - 1; ++lod)
-	{
-		getChild<LLComboBox>("lod_source_" + lod_name[lod])->setCurrentByIndex(LLModelPreview::GENERATE);
-		childSetValue("lod_file_" + lod_name[lod], "");
-	}
-
-	getChild<LLComboBox>("physics_lod_combo")->setCurrentByIndex(0);
-
-	for(auto& p : mDefaultDecompParams)
-	{
-		std::string ctrl_name(p.first);
-		LLUICtrl* ctrl = getChild<LLUICtrl>(ctrl_name);
-		if (ctrl)
-		{
-			ctrl->setValue(p.second);
-		}
-	}
-}
-
 void LLFloaterModelPreview::onModelPhysicsFeeReceived(const LLSD& result, std::string upload_url)
 {
 	mModelPhysicsFee = result;
diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h
index 41208daa64..564f4c39de 100644
--- a/indra/newview/llfloatermodelpreview.h
+++ b/indra/newview/llfloatermodelpreview.h
@@ -109,7 +109,6 @@ public:
 	void 			loadModel(S32 lod, const std::string& file_name, bool force_disable_slm = false);
 	
 	void onViewOptionChecked(LLUICtrl* ctrl);
-	void onUploadOptionChecked(LLUICtrl* ctrl);
 	bool isViewOptionChecked(const LLSD& userdata);
 	bool isViewOptionEnabled(const LLSD& userdata);
 	void setViewOptionEnabled(const std::string& option, bool enabled);
@@ -180,7 +179,6 @@ protected:
 	LLModelPreview*	mModelPreview;
 	
 	LLPhysicsDecomp::decomp_params mDecompParams;
-	LLPhysicsDecomp::decomp_params mDefaultDecompParams;
 	
 	S32				mLastMouseX;
 	S32				mLastMouseY;
@@ -205,6 +203,7 @@ protected:
 
 private:
 	void onClickCalculateBtn();
+	void toggleCalculateButton();
 
 	void onLoDSourceCommit(S32 lod);
 
@@ -214,8 +213,6 @@ private:
 	// resets display options of model preview to their defaults.
 	void resetDisplayOptions();
 
-	void resetUploadOptions();
-
 	void createSmoothComboBox(LLComboBox* combo_box, float min, float max);
 
 	LLButton* mUploadBtn;
-- 
cgit v1.2.3


From 3de1f3e59e54d88ee5cff9607d9eebe9eb9950b5 Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Sat, 23 Feb 2019 20:05:29 +0200
Subject: Backed out changeset: ce6ac58d801c

---
 indra/newview/app_settings/settings.xml               |  2 +-
 indra/newview/llfloatermodelpreview.cpp               | 19 ++-----------------
 .../skins/default/xui/en/floater_model_preview.xml    |  8 +++++---
 3 files changed, 8 insertions(+), 21 deletions(-)

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 8f7c4601e8..5f6bfec842 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -8053,7 +8053,7 @@
   <key>PreviewRenderSize</key>  
   <map>
     <key>Comment</key>
-    <string>Resolution of the image rendered for the mesh upload preview (must be a power of 2)</string>
+    <string>Resolution of the image rendered for the mesh upload preview</string>
     <key>Persist</key>
     <integer>1</integer>
     <key>Type</key>
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 616bee84fd..79b9df2fa6 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -427,23 +427,8 @@ void LLFloaterModelPreview::initModelPreview()
 	{
 		delete mModelPreview;
 	}
-
-	S32 tex_width = 512;
-	S32 tex_height = 512;
-
-	S32 max_width = llmin(gSavedSettings.getS32("PreviewRenderSize"), (S32)gPipeline.mScreenWidth);
-	S32 max_height = llmin(gSavedSettings.getS32("PreviewRenderSize"), (S32)gPipeline.mScreenHeight);
-	
-	while ((tex_width << 1) <= max_width)
-	{
-		tex_width <<= 1;
-	}
-	while ((tex_height << 1) <= max_height)
-	{
-		tex_height <<= 1;
-	}
-
-	mModelPreview = new LLModelPreview(tex_width, tex_height, this);
+	auto size = gSavedSettings.getS32("PreviewRenderSize");
+	mModelPreview = new LLModelPreview(size, size, this );
 	mModelPreview->setPreviewTarget(16.f);
 	mModelPreview->setDetailsCallback(boost::bind(&LLFloaterModelPreview::setDetails, this, _1, _2, _3, _4, _5));
 	mModelPreview->setModelUpdatedCallback(boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this, _1));
diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml
index 274e6e6c7a..a07fe99aef 100644
--- a/indra/newview/skins/default/xui/en/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml
@@ -1490,6 +1490,7 @@ Analysed:
     name="right_panel"
     top="0"
     left="640"
+    background_visible="true"
     width="375">
     <text
       follows="left|top"
@@ -1509,6 +1510,7 @@ Analysed:
       name="right_upper_panel"
       top="8"
       left="60"
+      background_visible="true"
       width="315">
       <combo_box
         top_pad="3"
@@ -1584,7 +1586,7 @@ Analysed:
       layout="topleft"
       left="2"
       name="physics_explode_label"
-      bottom_pad="2"
+      top="85"
       width="150">
       Preview Spread:
     </text>
@@ -1592,8 +1594,8 @@ Analysed:
       name="physics_explode"
       follows="right|bottom"
       valign="center"
-      left="105"
-      top_delta="-3"
+      top="15"
+      left="80"
       min_val="0.0"
       max_val="3.0"
       height="20"
-- 
cgit v1.2.3


From d9b09b3868ccc52655c00d547f2e4b849161d966 Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Sat, 23 Feb 2019 20:06:06 +0200
Subject: Backed out changeset: c923a62e9b5f

---
 indra/newview/skins/default/xui/en/floater_model_preview.xml | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml
index a07fe99aef..e073268b0a 100644
--- a/indra/newview/skins/default/xui/en/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml
@@ -34,6 +34,7 @@
   <string name="mesh_status_invalid_material_list">LOD materials are not a subset of reference model.</string>
   <string name="phys_status_vertex_limit_exceeded">Some physical hulls exceed vertex limitations.</string>
   <string name="phys_status_degenerate_triangles">The physics mesh too dense remove the small thin triangles (see preview)</string>
+  <string name="phys_status_no_havok">The Firestorm OpenSim build is not supported for physics upload in SL.</string>
   <string name="layer_all">All</string> <!-- Text to display in physics layer combo box for "all layers" -->
   <string name="decomposing">Analyzing...</string>
   <string name="simplifying">Simplifying...</string>
@@ -1222,7 +1223,7 @@
     <panel
      follows="top|left|bottom"
      layout="topleft"
-     height="197"
+     height="184"
      left="4"
      border="true"
      name="weights_and_warning_panel"
@@ -1411,7 +1412,7 @@ Lowest:
         border="true"
         layout="topleft"
         left_pad="265"
-        name="physics_costs_panel"
+        name="price_breakdown_panel"
         width="120"
         height="100">
         <text
@@ -1479,7 +1480,7 @@ Analysed:
          visible="false">
          You dont have rights to upload mesh models. [[VURL] Find out how] to get certified.
        </text>
-       <text text_color="Yellow" layout="topleft" top_pad="-1" left="6" name="status">
+       <text text_color="Yellow" layout="topleft" top_delta="5" left="6" name="status">
 [STATUS]
        </text>
     </panel>
-- 
cgit v1.2.3


From 150faaf53c3b59ff65aaa40a47d6678c741c4eaf Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Sat, 23 Feb 2019 20:06:46 +0200
Subject: Backed out changeset: f1fa95a76b9a

---
 .../shaders/class1/objects/previewV.glsl           |   2 +
 indra/newview/lldynamictexture.cpp                 |  15 ++-
 indra/newview/llfloatermodelpreview.cpp            | 118 +++++++++++++++++----
 3 files changed, 114 insertions(+), 21 deletions(-)

diff --git a/indra/newview/app_settings/shaders/class1/objects/previewV.glsl b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl
index de2ea2a065..3424613e94 100644
--- a/indra/newview/app_settings/shaders/class1/objects/previewV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl
@@ -91,7 +91,9 @@ void main()
 
 	// Collect normal lights (need to be divided by two, as we later multiply by 2)
 	col.rgb += light_diffuse[1].rgb * calcDirectionalLight(norm, light_position[1].xyz);
+//	col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].z);
 	col.rgb += light_diffuse[2].rgb * calcDirectionalLight(norm, light_position[2].xyz);
+//	col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].z);
 	col.rgb += light_diffuse[3].rgb * calcDirectionalLight(norm, light_position[3].xyz);
 	col /= 2.0;
 	vertex_color = col*color;
diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp
index e180d91461..af6977d3cd 100644
--- a/indra/newview/lldynamictexture.cpp
+++ b/indra/newview/lldynamictexture.cpp
@@ -125,11 +125,17 @@ BOOL LLViewerDynamicTexture::render()
 //-----------------------------------------------------------------------------
 void LLViewerDynamicTexture::preRender(BOOL clear_depth)
 {
+	// <FS:Beq> changes to support higher resolution rendering in the preview
+	////only images up to 512x512 are supported
+	//llassert(mFullHeight <= 512);
+	//llassert(mFullWidth <= 512);
 	gPipeline.allocatePhysicsBuffer();
 	llassert(mFullWidth <= static_cast<S32>(gPipeline.mPhysicsDisplay.getWidth()));
 	llassert(mFullHeight <= static_cast<S32>(gPipeline.mPhysicsDisplay.getHeight()));
 
+//	if (gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI)
 	if (gGLManager.mHasFramebufferObject && gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsATI)
+// </FS:Beq>
 	{ //using offscreen render target, just use the bottom left corner
 		mOrigin.set(0, 0);
 	}
@@ -215,13 +221,15 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
 	{
 		return TRUE;
 	}
-
+	// <FS:Beq> changes to support higher resolution rendering in the preview
+	//	bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI;
 	bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsATI;
 	if (use_fbo)
 	{
+//		gPipeline.mWaterDis.bindTarget();
 		gPipeline.mPhysicsDisplay.bindTarget();
 	}
-
+	// </FS:Beq>
 	LLGLSLShader::bindNoShader();
 	LLVertexBuffer::unbind();
 	
@@ -257,7 +265,10 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
 
 	if (use_fbo)
 	{
+		// <FS:Beq> changes to support higher resolution rendering in the preview
+		// gPipeline.mWaterDis.flush();
 		gPipeline.mPhysicsDisplay.flush();
+		// </FS:Beq>
 	}
 
 	return ret;
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 79b9df2fa6..7624245c16 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -427,8 +427,11 @@ void LLFloaterModelPreview::initModelPreview()
 	{
 		delete mModelPreview;
 	}
+	// <FS:Beq> mesh uploader changes to allow higher resolution render
+	//	mModelPreview = new LLModelPreview(512, 512, this);
 	auto size = gSavedSettings.getS32("PreviewRenderSize");
 	mModelPreview = new LLModelPreview(size, size, this );
+	// </FS:Beq>
 	mModelPreview->setPreviewTarget(16.f);
 	mModelPreview->setDetailsCallback(boost::bind(&LLFloaterModelPreview::setDetails, this, _1, _2, _3, _4, _5));
 	mModelPreview->setModelUpdatedCallback(boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this, _1));
@@ -438,6 +441,8 @@ void LLFloaterModelPreview::onViewOptionChecked(LLUICtrl* ctrl)
 {
 	if (mModelPreview)
 	{
+		// <FS:Beq> only show explode when phsyics is on
+		//		mModelPreview->mViewOption[ctrl->getName()] = !mModelPreview->mViewOption[ctrl->getName()];
 		auto name = ctrl->getName();
 		mModelPreview->mViewOption[name] = !mModelPreview->mViewOption[name];
 		if (name == "show_physics")
@@ -659,6 +664,7 @@ void LLFloaterModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit)
 	}
 }
 
+// <FS:Beq> extracted method to simplify changes in layout
 void LLFloaterModelPreview::draw3dPreview()
 {
 	gGL.color3f(1.f, 1.f, 1.f);
@@ -1260,7 +1266,7 @@ LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp)
 , mResetJoints( false )
 , mModelNoErrors( true )
 , mLastJointUpdate( false )
-, mHasDegenerate( false )
+, mHasDegenerate( false ) // <FS:Beq>
 {
 	mNeedsUpdate = TRUE;
 	mCameraDistance = 0.f;
@@ -2750,7 +2756,7 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim
 
 void LLModelPreview::updateStatusMessages()
 {
-// bit mask values for physics errors. used to prevent overwrite of single line status
+// <FS:Beq> bit mask values for physics errors. used to prevent overwrite of single line status
 // TODO: use this to provied multiline status
 	enum PhysicsError
 	{
@@ -2760,10 +2766,10 @@ void LLModelPreview::updateStatusMessages()
 		TOOMANYHULLS=4,
 		TOOMANYVERTSINHULL=8
 	};
-
+// </FS:Beq>
 	assert_main_thread();
 
-	U32 has_physics_error{ PhysicsError::NONE }; // physics error bitmap
+	U32 has_physics_error{ PhysicsError::NONE }; // <FS:Beq> physics error bitmap
 	//triangle/vertex/submesh count for each mesh asset for each lod
 	std::vector<S32> tris[LLModel::NUM_LODS];
 	std::vector<S32> verts[LLModel::NUM_LODS];
@@ -2852,25 +2858,38 @@ void LLModelPreview::updateStatusMessages()
 	{
 		mMaxTriangleLimit = total_tris[LLModel::LOD_HIGH];
 	}
-
+	// <FS:Beq> make has_degenerate a member so that we can use it in the render method
+	// has_degenerate = false
 	mHasDegenerate = false;
 	{//check for degenerate triangles in physics mesh
 		U32 lod = LLModel::LOD_PHYSICS;
 		const LLVector4a scale(0.5f);
-		for (U32 i = 0; i < mModel[lod].size() && !mHasDegenerate; ++i)
+		for (U32 i = 0; i < mModel[lod].size() && !mHasDegenerate; ++i)// <FS:Beq> make has_degenerate a member 
 		{ //for each model in the lod
 			if (mModel[lod][i] && mModel[lod][i]->mPhysics.mHull.empty())
 			{ //no decomp exists
 				S32 cur_submeshes = mModel[lod][i]->getNumVolumeFaces();
-				for (S32 j = 0; j < cur_submeshes && !mHasDegenerate; ++j)
+				for (S32 j = 0; j < cur_submeshes && !mHasDegenerate; ++j)// <FS:Beq> make has_degenerate a member 
 				{ //for each submesh (face), add triangles and vertices to current total
 					LLVolumeFace& face = mModel[lod][i]->getVolumeFace(j);
-					for (S32 k = 0; (k < face.mNumIndices) && !mHasDegenerate; )
+					for (S32 k = 0; (k < face.mNumIndices) && !mHasDegenerate; )// <FS:Beq> make has_degenerate a member 
 					{
 						U16 index_a = face.mIndices[k + 0];
 						U16 index_b = face.mIndices[k + 1];
 						U16 index_c = face.mIndices[k + 2];
-
+						// <FS:Beq> FIRE-23367/23387 - Allow forced empty triangle placeholders created by the LOD processing.
+						//	LLVector4a v1; v1.setMul(face.mPositions[index_a], scale);
+						//	LLVector4a v2; v2.setMul(face.mPositions[index_b], scale);
+						//	LLVector4a v3; v3.setMul(face.mPositions[index_c], scale);
+
+						//	if (ll_is_degenerate(v1, v2, v3))
+						//	{
+						//		mHasDegenerate = true;// <FS:Beq> make has_degenerate a member 
+						//	}
+						//	else
+						//	{
+						//		k += 3;
+						//	}
 						if (index_c == 0 && index_b == 0 && index_a == 0) // test in reverse as 3rd index is less likely to be 0 in a normal case
 						{
 							LL_DEBUGS("MeshValidation") << "Empty placeholder triangle (3 identical index 0 verts) ignored" << LL_ENDL;
@@ -2882,7 +2901,7 @@ void LLModelPreview::updateStatusMessages()
 							LLVector4a v3; v3.setMul(face.mPositions[index_c], scale);
 							if (ll_is_degenerate(v1, v2, v3))
 							{
-								mHasDegenerate = true;
+								mHasDegenerate = true;// <FS:Beq> make has_degenerate a member 
 							}
 						}
 						k += 3;
@@ -2892,7 +2911,7 @@ void LLModelPreview::updateStatusMessages()
 		}
 	}
 
-	// flag degenerates here rather than deferring to a MAV error later
+	// <FS:Beq> flag degenerates here rather than deferring to a MAV error later
 	mFMP->childSetVisible("physics_status_message_text", mHasDegenerate); //display or clear
 	auto degenerateIcon = mFMP->getChild<LLIconCtrl>("physics_status_message_icon");
 	degenerateIcon->setVisible(mHasDegenerate);
@@ -2903,6 +2922,7 @@ void LLModelPreview::updateStatusMessages()
 		LLUIImagePtr img = LLUI::getUIImage("ModelImport_Status_Error");
 		degenerateIcon->setImage(img);
 	}
+	// </FS:Beq>
 
 	mFMP->childSetTextArg("submeshes_info", "[SUBMESHES]", llformat("%d", total_submeshes[LLModel::LOD_HIGH]));
 
@@ -3072,7 +3092,12 @@ void LLModelPreview::updateStatusMessages()
 			mModelNoErrors = false;
 		}
 	}
-
+	// <FS:Beq> Improve the error checking the TO DO here is no longer applicable but not an FS comment so edited to stop it being picked up
+	//// To do investigate use of has_degenerate and include into mModelNoErrors upload blocking mechanics
+	//// current use of has_degenerate won't block upload permanently - later checks will restore the button
+	//if (!mModelNoErrors || mHasDegenerate)
+	//{
+	//	mFMP->childDisable("ok_btn");
 	if (!mModelNoErrors || mHasDegenerate)
 	{
 		mFMP->childDisable("ok_btn");
@@ -3697,7 +3722,7 @@ BOOL LLModelPreview::render()
 	bool textures = mViewOption["show_textures"];
 	bool physics = mViewOption["show_physics"];
 
-	// Extra configurability, to be exposed later as controls?
+	// <FS:Beq> Extra configurability, to be exposed later as controls?
 	static LLCachedControl<LLColor4> canvas_col(gSavedSettings, "MeshPreviewCanvasColor");
 	static LLCachedControl<LLColor4> edge_col(gSavedSettings, "MeshPreviewEdgeColor");
 	static LLCachedControl<LLColor4> base_col(gSavedSettings, "MeshPreviewBaseColor");
@@ -3710,12 +3735,16 @@ BOOL LLModelPreview::render()
 	static LLCachedControl<LLColor4> deg_fill_col(gSavedSettings, "MeshPreviewDegenerateFillColor");	
 	static LLCachedControl<F32> deg_edge_width(gSavedSettings, "MeshPreviewDegenerateEdgeWidth");
 	static LLCachedControl<F32> deg_point_size(gSavedSettings, "MeshPreviewDegeneratePointSize");
-
+	// </FS:Beq>
 	S32 width = getWidth();
 	S32 height = getHeight();
 
 	LLGLSUIDefault def;
 	LLGLDisable no_blend(GL_BLEND);
+// <FS:Beq> Clean up render of mesh preview
+//	LLGLEnable blend(GL_BLEND);
+//	gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
+// </FS:Beq> 
 
 	LLGLEnable cull(GL_CULL_FACE);
 	LLGLDepthTest depth(GL_TRUE);
@@ -3735,7 +3764,8 @@ BOOL LLModelPreview::render()
 		gGL.matrixMode(LLRender::MM_MODELVIEW);
 		gGL.pushMatrix();
 		gGL.loadIdentity();
-
+		// <FS:Beq> uploader improvements
+		//gGL.color4f(0.169f, 0.169f, 0.169f, 1.f);
 		gGL.color4fv(static_cast<LLColor4>(canvas_col).mV);
 		gl_rect_2d_simple( width, height );
 
@@ -3884,7 +3914,11 @@ BOOL LLModelPreview::render()
 	stop_glerror();
 
 	gGL.pushMatrix();
+	// <FS:Beq> mesh uploader improvements configurable brightness
+	//const F32 BRIGHTNESS = 0.9f;
+	//gGL.color3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS);
 	gGL.color4fv(edge_col().mV);
+	// </FS:Beq>
 
 	const U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0;
 
@@ -3969,12 +4003,19 @@ BOOL LLModelPreview::render()
 						}
 						else
 						{
+						// <FS:Beq> improved mesh uploader
+						//	gGL.diffuseColor4f(1,1,1,1);
 							gGL.diffuseColor4fv(static_cast<LLColor4>(base_col).mV);
+						// </FS:Beq>
+
 						}
 
 						buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
 						gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+						// <FS:Beq> improved mesh uploader
+						//gGL.diffuseColor3f(0.4f, 0.4f, 0.4f);
 						gGL.diffuseColor4fv(static_cast<LLColor4>(edge_col).mV);
+						// </FS:Beq> 
 						if (edges)
 						{
 							glLineWidth(edge_width);
@@ -3989,10 +4030,25 @@ BOOL LLModelPreview::render()
 
 			if (physics)
 			{
+				// <FS:Beq> model upload improvements - use the settings
+				////Vector4a physicsFillColour(0.4, 0.4, 0.4, 0.4);
+				//const LLColor4 physicsFillColour(0.0, 0.5, 1.0, 0.5);
+				////LLVector4a physicsEdgeColour(1.0, 1.0, 0.0, 1.0);
+				//const LLColor4 physicsEdgeColour=physicsFillColour*0.5;
+				//const LLColor4 degenerateFill(1.0, 0.0, 0.0, 0.5);
+				//const LLColor4 degenerateEdge(1.0,0.0,0.0,1.0);
+				// </FS:Beq> 
+
 				glClear(GL_DEPTH_BUFFER_BIT);
+				//<FS:Beq> refactor to remove silly variable names
+				//				for (U32 i = 0; i < 2; i++)
 				for (U32 pass = 0; pass < 2; pass++)
+				//</FS:Beq>
 				{
+					//<FS:Beq> refactor to remove silly variable names
+					//if (i == 0)
 					if (pass == 0)
+					//</FS:Beq>
 					{ //depth only pass
 						gGL.setColorMask(false, false);
 					}
@@ -4002,7 +4058,10 @@ BOOL LLModelPreview::render()
 					}
 
 					//enable alpha blending on second pass but not first pass
+					//<FS:Beq> refactor to remove silly variable names
+					//LLGLState blend(GL_BLEND, i);
 					LLGLState blend(GL_BLEND, pass);
+					//</FS:Beq>
 
 					gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
 
@@ -4106,11 +4165,16 @@ BOOL LLModelPreview::render()
 						gGL.popMatrix();
 					}
 
-					// only do this if mDegenerate was set in the preceding mesh checks [Check this if the ordering ever breaks]
+					//<FS:Beq> refactor to remove silly variable names
+					// also only do this if mDegenerate was set in the preceding mesh checks [Check this if the ordering ever breaks]
+					//if (i > 0)
 					if (pass > 0 && mHasDegenerate)
+					//</FS:Beq>
 					{
 						glLineWidth(deg_edge_width);
 						glPointSize(deg_point_size);
+// <FS:Beq> This single line is why the degenerate triangles display has been crap forever. 
+// 						gPipeline.enableLightsFullbright(LLColor4::white);
 						//show degenerate triangles
 						LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
 						LLGLDisable cull(GL_CULL_FACE);
@@ -4148,10 +4212,13 @@ BOOL LLModelPreview::render()
 									}
 
 									auto num_degenerate = 0;
+									//<FS:Beq> More nested i variable silliness
+									//									for (U32 i = 0; i < mVertexBuffer[LLModel::LOD_PHYSICS][model].size(); ++i)
 									auto num_models = mVertexBuffer[LLModel::LOD_PHYSICS][model].size();
 									for (U32 v = 0; v < num_models; ++v)
 									{
 										LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][v];
+									//</FS:Beq>
 										if(buffer->getNumVerts() < 3)continue;
 
 										buffer->setBuffer(type_mask & buffer->getTypeMask());
@@ -4164,6 +4231,7 @@ BOOL LLModelPreview::render()
 										buffer->getIndexStrider(idx, 0);
 
 										LLVector4a v1, v2, v3;
+										//<FS:Beq> rename inner most i to avoid merge confusion
 										for (U32 indices_offset = 0; indices_offset < buffer->getNumIndices(); indices_offset += 3)
 										{
 											v1.setMul(pos[*idx++], scale);
@@ -4274,6 +4342,8 @@ BOOL LLModelPreview::render()
 							}
 						
 							buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0);
+							// <FS:Beq> configurable colour and width
+							//gGL.diffuseColor3f(0.4f, 0.4f, 0.4f);
 
 							if (edges)
 							{
@@ -4284,6 +4354,7 @@ BOOL LLModelPreview::render()
 								glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
 								glLineWidth(1.f);
 							}
+							// </FS:Beq>
 						}
 					}
 				}
@@ -4341,9 +4412,11 @@ void LLModelPreview::rotate(F32 yaw_radians, F32 pitch_radians)
 void LLModelPreview::zoom(F32 zoom_amt)
 {
 	F32 new_zoom = mCameraZoom+zoom_amt;
-	// TODO: stop clamping in render
+	// <FS:Beq> add configurable zoom TODO: stop clamping in render
+	// mCameraZoom = llclamp(new_zoom, 1.f, 10.f);
 	static LLCachedControl<F32> zoom_limit(gSavedSettings, "MeshPreviewZoomLimit");
 	mCameraZoom	= llclamp(new_zoom, 1.f, zoom_limit());
+	// </FS:Beq>
 }
 
 void LLModelPreview::pan(F32 right, F32 up)
@@ -4549,6 +4622,12 @@ void LLFloaterModelPreview::toggleCalculateButton(bool visible)
 		childSetTextArg("server_weight", "[SIM]", tbd);
 		childSetTextArg("physics_weight", "[PH]", tbd);
 		childSetTextArg("upload_fee", "[FEE]", tbd);
+		// <FS:Beq> add extended info fields
+		//childSetTextArg("price_breakdown", "[STREAMING]", dashes);
+		//childSetTextArg("price_breakdown", "[PHYSICS]", dashes);
+		//childSetTextArg("price_breakdown", "[INSTANCES]", dashes);
+		//childSetTextArg("price_breakdown", "[TEXTURES]", dashes);
+		//childSetTextArg("price_breakdown", "[MODEL]", dashes);
 		std::string dashes = hasString("--") ? getString("--") : "--";
 		childSetTextArg("price_breakdown", "[STREAMING]", dashes);
 		childSetTextArg("price_breakdown", "[PHYSICS]", dashes);
@@ -4558,6 +4637,7 @@ void LLFloaterModelPreview::toggleCalculateButton(bool visible)
 		childSetTextArg("physics_breakdown", "[PCH]", dashes);
 		childSetTextArg("physics_breakdown", "[PM]", dashes);
 		childSetTextArg("physics_breakdown", "[PHU]", dashes);
+		// </FS:Beq>
 	}
 }
 
@@ -4607,7 +4687,7 @@ void LLFloaterModelPreview::handleModelPhysicsFeeReceived()
 	childSetTextArg("price_breakdown", "[INSTANCES]", llformat("%d", result["upload_price_breakdown"]["mesh_instance"].asInteger()));
 	childSetTextArg("price_breakdown", "[TEXTURES]", llformat("%d", result["upload_price_breakdown"]["texture"].asInteger()));
 	childSetTextArg("price_breakdown", "[MODEL]", llformat("%d", result["upload_price_breakdown"]["model"].asInteger()));
-
+//<FS:Beq> Updates for enhanced Mesh feedback at upload
 	childSetTextArg("physics_breakdown", "[PCH]", llformat("%0.3f", result["model_physics_cost"]["hull"].asReal()));
 	childSetTextArg("physics_breakdown", "[PM]", llformat("%0.3f", result["model_physics_cost"]["mesh"].asReal()));
 	childSetTextArg("physics_breakdown", "[PHU]", llformat("%0.3f", result["model_physics_cost"]["decomposition"].asReal()));
@@ -4616,7 +4696,7 @@ void LLFloaterModelPreview::handleModelPhysicsFeeReceived()
 	childSetTextArg("streaming_breakdown", "[STR_MED]", llformat("%d", result["streaming_params"]["medium_lod"].asInteger()));
 	childSetTextArg("streaming_breakdown", "[STR_LOW]", llformat("%d", result["streaming_params"]["low_lod"].asInteger()));
 	childSetTextArg("streaming_breakdown", "[STR_LOWEST]", llformat("%d", result["streaming_params"]["lowest_lod"].asInteger()));
-
+//</FS:Beq>
 	childSetVisible("upload_fee", true);
 	childSetVisible("price_breakdown", true);
 	mUploadBtn->setEnabled(isModelUploadAllowed());
-- 
cgit v1.2.3


From 020c5c956168abc8b38a8da8d2cff4306c4acdb6 Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Sat, 23 Feb 2019 20:07:42 +0200
Subject: Backed out changeset: 3abc812c6f48

---
 indra/newview/app_settings/settings.xml | 2 --
 1 file changed, 2 deletions(-)

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 5f6bfec842..b2f86fa301 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -6810,7 +6810,6 @@
     <key>Value</key>
     <real>10.0</real>
   </map>
-  <key>MigrateCacheDirectory</key>
   <map>
       <key>Comment</key>
       <string>Check for old version of disk cache to migrate to current location</string>
@@ -16492,4 +16491,3 @@
 </map>
 </llsd>
 
-
-- 
cgit v1.2.3


From 599e08181544f214142703928a6d242a0ae72e60 Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Sat, 23 Feb 2019 20:08:03 +0200
Subject: Backed out changeset: d5795c04fecc

---
 doc/contributions.txt                              |   2 -
 indra/newview/app_settings/settings.xml            | 199 +-------
 .../shaders/class1/objects/previewV.glsl           |   8 +-
 indra/newview/lldynamictexture.cpp                 |  30 +-
 indra/newview/llfloatermodelpreview.cpp            | 527 +++++++--------------
 indra/newview/llfloatermodelpreview.h              |   2 -
 indra/newview/pipeline.cpp                         |   6 +-
 .../skins/default/xui/en/floater_model_preview.xml | 369 +++++----------
 8 files changed, 299 insertions(+), 844 deletions(-)

diff --git a/doc/contributions.txt b/doc/contributions.txt
index 6146689fb0..365ae544b1 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -256,8 +256,6 @@ Benja Kepler
 	VWR-746
 Benjamin Bigdipper
 Beth Walcher
-Beq Janus
-	SL-10288
 Bezilon Kasei
 Biancaluce Robbiani
 	CT-225
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index b2f86fa301..8e525aceda 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -6628,189 +6628,8 @@
     <key>Value</key>
     <integer>600</integer>
   </map>
-  <key>MeshPreviewCanvasColor</key>
-  <map>
-    <key>Comment</key>
-    <string>Canvas colour for the Mesh uploader</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>Color4</string>
-    <key>Value</key>
-    <array>
-      <real>0.169</real>
-      <real>0.169</real>
-      <real>0.169</real>
-      <real>1.0</real>
-    </array>
-  </map>
-  <key>MeshPreviewEdgeColor</key>
-  <map>
-    <key>Comment</key>
-    <string>Edge colour for the Mesh uploader preview</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>Color4</string>
-    <key>Value</key>
-    <array>
-      <real>0.4</real>
-      <real>0.4</real>
-      <real>0.4</real>
-      <real>1.0</real>
-    </array>
-  </map>
-  <key>MeshPreviewBaseColor</key>
-  <map>
-    <key>Comment</key>
-    <string>base diffuse colour for the Mesh uploader</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>Color4</string>
-    <key>Value</key>
-    <array>
-      <real>1.0</real>
-      <real>1.0</real>
-      <real>1.0</real>
-      <real>1.0</real>
-    </array>
-  </map>
-  <key>MeshPreviewBrightnessColor</key>
-  <map>
-    <key>Comment</key>
-    <string>Brightness modifier</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>Color3</string>
-    <key>Value</key>
-    <array>
-      <real>0.9</real>
-      <real>0.9</real>
-      <real>0.9</real>
-    </array>
-  </map>
-  <key>MeshPreviewEdgeWidth</key>
-  <map>
-    <key>Comment</key>
-    <string>line thickness used when display edges is selected in mesh preview</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>F32</string>
-    <key>Value</key>
-      <real>1.0</real>
-  </map>
-  <key>MeshPreviewPhysicsEdgeColor</key>
-  <map>
-    <key>Comment</key>
-    <string>Edge colour for the Mesh uploader physics preview</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>Color4</string>
-    <key>Value</key>
-    <array>
-      <real>0.0</real>
-      <real>0.25</real>
-      <real>0.5</real>
-      <real>0.25</real>
-    </array>
-  </map>
-  <key>MeshPreviewPhysicsFillColor</key>
-  <map>
-    <key>Comment</key>
-    <string>Fill colour for the Mesh uploader physics preview</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>Color4</string>
-    <key>Value</key>
-    <array>
-      <real>0.0</real>
-      <real>0.5</real>
-      <real>1.0</real>
-      <real>0.5</real>
-    </array>
-  </map>
-  <key>MeshPreviewPhysicsEdgeWidth</key>
-  <map>
-    <key>Comment</key>
-    <string>line thickness used when display physics is selected in mesh preview</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>F32</string>
-    <key>Value</key>
-    <real>1.0</real>
-  </map>
-  <key>MeshPreviewDegenerateEdgeColor</key>
-  <map>
-    <key>Comment</key>
-    <string>Edge colour for the Mesh uploader Degenerate preview</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>Color4</string>
-    <key>Value</key>
-    <array>
-      <real>1.0</real>
-      <real>0.0</real>
-      <real>0.0</real>
-      <real>1.0</real>
-    </array>
-  </map>
-  <key>MeshPreviewDegenerateFillColor</key>
-  <map>
-    <key>Comment</key>
-    <string>Fill colour for the Mesh uploader Degenerate preview</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>Color4</string>
-    <key>Value</key>
-    <array>
-      <real>1.0</real>
-      <real>0.0</real>
-      <real>0.0</real>
-      <real>0.5</real>
-    </array>
-  </map>
-  <key>MeshPreviewDegenerateEdgeWidth</key>
-  <map>
-    <key>Comment</key>
-    <string>line thickness used when display Degenerate is selected in mesh preview</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>F32</string>
-    <key>Value</key>
-    <real>3.0</real>
-  </map>
-  <key>MeshPreviewDegeneratePointSize</key>
-  <map>
-    <key>Comment</key>
-    <string>Large point size used to highlight degenerate triangle vertices in Mesh preview</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>F32</string>
-    <key>Value</key>
-    <real>8.0</real>
-  </map>
-  <key>MeshPreviewZoomLimit</key>
-  <map>
-    <key>Comment</key>
-    <string>Maximum Zoom level in preview</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>F32</string>
-    <key>Value</key>
-    <real>10.0</real>
-  </map>
-  <map>
+  <key>MigrateCacheDirectory</key>
+    <map>
       <key>Comment</key>
       <string>Check for old version of disk cache to migrate to current location</string>
       <key>Persist</key>
@@ -8049,17 +7868,7 @@
       <key>Value</key>
 	  <integer>13</integer>
     </map>
-  <key>PreviewRenderSize</key>  
-  <map>
-    <key>Comment</key>
-    <string>Resolution of the image rendered for the mesh upload preview</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>S32</string>
-    <key>Value</key>
-    <integer>1024</integer>
-  </map>
+
   <key>PreviewAmbientColor</key>
   <map>
     <key>Comment</key>
@@ -8076,6 +7885,8 @@
       <real>1.0</real>
     </array>
   </map>
+
+
   <key>PreviewDiffuse0</key>
   <map>
     <key>Comment</key>
diff --git a/indra/newview/app_settings/shaders/class1/objects/previewV.glsl b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl
index 3424613e94..7f3f84398b 100644
--- a/indra/newview/app_settings/shaders/class1/objects/previewV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl
@@ -91,10 +91,8 @@ void main()
 
 	// Collect normal lights (need to be divided by two, as we later multiply by 2)
 	col.rgb += light_diffuse[1].rgb * calcDirectionalLight(norm, light_position[1].xyz);
-//	col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].z);
-	col.rgb += light_diffuse[2].rgb * calcDirectionalLight(norm, light_position[2].xyz);
-//	col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].z);
-	col.rgb += light_diffuse[3].rgb * calcDirectionalLight(norm, light_position[3].xyz);
-	col /= 2.0;
+	col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].z);
+	col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].z);
+		
 	vertex_color = col*color;
 }
diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp
index af6977d3cd..fa9a0712fa 100644
--- a/indra/newview/lldynamictexture.cpp
+++ b/indra/newview/lldynamictexture.cpp
@@ -125,17 +125,11 @@ BOOL LLViewerDynamicTexture::render()
 //-----------------------------------------------------------------------------
 void LLViewerDynamicTexture::preRender(BOOL clear_depth)
 {
-	// <FS:Beq> changes to support higher resolution rendering in the preview
-	////only images up to 512x512 are supported
-	//llassert(mFullHeight <= 512);
-	//llassert(mFullWidth <= 512);
-	gPipeline.allocatePhysicsBuffer();
-	llassert(mFullWidth <= static_cast<S32>(gPipeline.mPhysicsDisplay.getWidth()));
-	llassert(mFullHeight <= static_cast<S32>(gPipeline.mPhysicsDisplay.getHeight()));
+	//only images up to 512x512 are supported
+	llassert(mFullHeight <= 512);
+	llassert(mFullWidth <= 512);
 
-//	if (gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI)
-	if (gGLManager.mHasFramebufferObject && gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsATI)
-// </FS:Beq>
+	if (gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI)
 	{ //using offscreen render target, just use the bottom left corner
 		mOrigin.set(0, 0);
 	}
@@ -221,15 +215,14 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
 	{
 		return TRUE;
 	}
-	// <FS:Beq> changes to support higher resolution rendering in the preview
-	//	bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI;
-	bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsATI;
+
+	bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI;
+
 	if (use_fbo)
 	{
-//		gPipeline.mWaterDis.bindTarget();
-		gPipeline.mPhysicsDisplay.bindTarget();
+		gPipeline.mWaterDis.bindTarget();
 	}
-	// </FS:Beq>
+
 	LLGLSLShader::bindNoShader();
 	LLVertexBuffer::unbind();
 	
@@ -265,10 +258,7 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
 
 	if (use_fbo)
 	{
-		// <FS:Beq> changes to support higher resolution rendering in the preview
-		// gPipeline.mWaterDis.flush();
-		gPipeline.mPhysicsDisplay.flush();
-		// </FS:Beq>
+		gPipeline.mWaterDis.flush();
 	}
 
 	return ret;
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 7624245c16..4f1ea4a89e 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -427,11 +427,8 @@ void LLFloaterModelPreview::initModelPreview()
 	{
 		delete mModelPreview;
 	}
-	// <FS:Beq> mesh uploader changes to allow higher resolution render
-	//	mModelPreview = new LLModelPreview(512, 512, this);
-	auto size = gSavedSettings.getS32("PreviewRenderSize");
-	mModelPreview = new LLModelPreview(size, size, this );
-	// </FS:Beq>
+
+	mModelPreview = new LLModelPreview(512, 512, this );
 	mModelPreview->setPreviewTarget(16.f);
 	mModelPreview->setDetailsCallback(boost::bind(&LLFloaterModelPreview::setDetails, this, _1, _2, _3, _4, _5));
 	mModelPreview->setModelUpdatedCallback(boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this, _1));
@@ -441,16 +438,8 @@ void LLFloaterModelPreview::onViewOptionChecked(LLUICtrl* ctrl)
 {
 	if (mModelPreview)
 	{
-		// <FS:Beq> only show explode when phsyics is on
-		//		mModelPreview->mViewOption[ctrl->getName()] = !mModelPreview->mViewOption[ctrl->getName()];
-		auto name = ctrl->getName();
-		mModelPreview->mViewOption[name] = !mModelPreview->mViewOption[name];
-		if (name == "show_physics")
-		{
-			auto enabled = mModelPreview->mViewOption[name];
-			childSetEnabled("physics_explode", enabled);
-			childSetVisible("physics_explode", enabled);
-		}
+		mModelPreview->mViewOption[ctrl->getName()] = !mModelPreview->mViewOption[ctrl->getName()];
+		
 		mModelPreview->refresh();
 	}
 }
@@ -664,43 +653,6 @@ void LLFloaterModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit)
 	}
 }
 
-// <FS:Beq> extracted method to simplify changes in layout
-void LLFloaterModelPreview::draw3dPreview()
-{
-	gGL.color3f(1.f, 1.f, 1.f);
-
-	gGL.getTexUnit(0)->bind(mModelPreview);
-
-
-	LLView* preview_panel = getChild<LLView>("preview_panel");
-
-	if (!preview_panel)
-	{
-		LL_WARNS() << "preview_panel not found in floater definition" << LL_ENDL;
-	}
-	LLRect rect = preview_panel->getRect();
-
-	if (rect != mPreviewRect)
-	{
-		mModelPreview->refresh();
-		mPreviewRect = preview_panel->getRect();
-	}
-
-	gGL.begin( LLRender::QUADS );
-	{
-		gGL.texCoord2f(0.f, 1.f);
-		gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mTop-1);
-		gGL.texCoord2f(0.f, 0.f);
-		gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mBottom);
-		gGL.texCoord2f(1.f, 0.f);
-		gGL.vertex2i(mPreviewRect.mRight-1, mPreviewRect.mBottom);
-		gGL.texCoord2f(1.f, 1.f);
-		gGL.vertex2i(mPreviewRect.mRight-1, mPreviewRect.mTop-1);
-	}
-	gGL.end();
-
-	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-}
 
 //-----------------------------------------------------------------------------
 // draw()
@@ -1266,7 +1218,6 @@ LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp)
 , mResetJoints( false )
 , mModelNoErrors( true )
 , mLastJointUpdate( false )
-, mHasDegenerate( false ) // <FS:Beq>
 {
 	mNeedsUpdate = TRUE;
 	mCameraDistance = 0.f;
@@ -2756,20 +2707,8 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim
 
 void LLModelPreview::updateStatusMessages()
 {
-// <FS:Beq> bit mask values for physics errors. used to prevent overwrite of single line status
-// TODO: use this to provied multiline status
-	enum PhysicsError
-	{
-		NONE=0,
-		NOHAVOK=1,
-		DEGENERATE=2,
-		TOOMANYHULLS=4,
-		TOOMANYVERTSINHULL=8
-	};
-// </FS:Beq>
 	assert_main_thread();
 
-	U32 has_physics_error{ PhysicsError::NONE }; // <FS:Beq> physics error bitmap
 	//triangle/vertex/submesh count for each mesh asset for each lod
 	std::vector<S32> tris[LLModel::NUM_LODS];
 	std::vector<S32> verts[LLModel::NUM_LODS];
@@ -2858,72 +2797,44 @@ void LLModelPreview::updateStatusMessages()
 	{
 		mMaxTriangleLimit = total_tris[LLModel::LOD_HIGH];
 	}
-	// <FS:Beq> make has_degenerate a member so that we can use it in the render method
-	// has_degenerate = false
-	mHasDegenerate = false;
+
+	bool has_degenerate = false;
+
 	{//check for degenerate triangles in physics mesh
 		U32 lod = LLModel::LOD_PHYSICS;
 		const LLVector4a scale(0.5f);
-		for (U32 i = 0; i < mModel[lod].size() && !mHasDegenerate; ++i)// <FS:Beq> make has_degenerate a member 
+		for (U32 i = 0; i < mModel[lod].size() && !has_degenerate; ++i)
 		{ //for each model in the lod
 			if (mModel[lod][i] && mModel[lod][i]->mPhysics.mHull.empty())
 			{ //no decomp exists
 				S32 cur_submeshes = mModel[lod][i]->getNumVolumeFaces();
-				for (S32 j = 0; j < cur_submeshes && !mHasDegenerate; ++j)// <FS:Beq> make has_degenerate a member 
+				for (S32 j = 0; j < cur_submeshes && !has_degenerate; ++j)
 				{ //for each submesh (face), add triangles and vertices to current total
 					LLVolumeFace& face = mModel[lod][i]->getVolumeFace(j);
-					for (S32 k = 0; (k < face.mNumIndices) && !mHasDegenerate; )// <FS:Beq> make has_degenerate a member 
+					for (S32 k = 0; (k < face.mNumIndices) && !has_degenerate; )
 					{
-						U16 index_a = face.mIndices[k + 0];
-						U16 index_b = face.mIndices[k + 1];
-						U16 index_c = face.mIndices[k + 2];
-						// <FS:Beq> FIRE-23367/23387 - Allow forced empty triangle placeholders created by the LOD processing.
-						//	LLVector4a v1; v1.setMul(face.mPositions[index_a], scale);
-						//	LLVector4a v2; v2.setMul(face.mPositions[index_b], scale);
-						//	LLVector4a v3; v3.setMul(face.mPositions[index_c], scale);
-
-						//	if (ll_is_degenerate(v1, v2, v3))
-						//	{
-						//		mHasDegenerate = true;// <FS:Beq> make has_degenerate a member 
-						//	}
-						//	else
-						//	{
-						//		k += 3;
-						//	}
-						if (index_c == 0 && index_b == 0 && index_a == 0) // test in reverse as 3rd index is less likely to be 0 in a normal case
+						U16 index_a = face.mIndices[k+0];
+						U16 index_b = face.mIndices[k+1];
+						U16 index_c = face.mIndices[k+2];
+
+						LLVector4a v1; v1.setMul(face.mPositions[index_a], scale);
+						LLVector4a v2; v2.setMul(face.mPositions[index_b], scale);
+						LLVector4a v3; v3.setMul(face.mPositions[index_c], scale);
+
+						if (ll_is_degenerate(v1,v2,v3))
 						{
-							LL_DEBUGS("MeshValidation") << "Empty placeholder triangle (3 identical index 0 verts) ignored" << LL_ENDL;
+							has_degenerate = true;
 						}
 						else
 						{
-							LLVector4a v1; v1.setMul(face.mPositions[index_a], scale);
-							LLVector4a v2; v2.setMul(face.mPositions[index_b], scale);
-							LLVector4a v3; v3.setMul(face.mPositions[index_c], scale);
-							if (ll_is_degenerate(v1, v2, v3))
-							{
-								mHasDegenerate = true;// <FS:Beq> make has_degenerate a member 
-							}
+							k += 3;
 						}
-						k += 3;
 					}
 				}
 			}
 		}
 	}
 
-	// <FS:Beq> flag degenerates here rather than deferring to a MAV error later
-	mFMP->childSetVisible("physics_status_message_text", mHasDegenerate); //display or clear
-	auto degenerateIcon = mFMP->getChild<LLIconCtrl>("physics_status_message_icon");
-	degenerateIcon->setVisible(mHasDegenerate);
-	if (mHasDegenerate)
-	{
-		has_physics_error |= PhysicsError::DEGENERATE;
-		mFMP->childSetValue("physics_status_message_text", mFMP->getString("phys_status_degenerate_triangles"));
-		LLUIImagePtr img = LLUI::getUIImage("ModelImport_Status_Error");
-		degenerateIcon->setImage(img);
-	}
-	// </FS:Beq>
-
 	mFMP->childSetTextArg("submeshes_info", "[SUBMESHES]", llformat("%d", total_submeshes[LLModel::LOD_HIGH]));
 
 	std::string mesh_status_na = mFMP->getString("mesh_status_na");
@@ -3048,22 +2959,14 @@ void LLModelPreview::updateStatusMessages()
 			}
 		}
 	}
-
+	mFMP->childSetVisible("physics_status_message_text", physExceededVertexLimit);
+	LLIconCtrl* physStatusIcon = mFMP->getChild<LLIconCtrl>("physics_status_message_icon");
+	physStatusIcon->setVisible(physExceededVertexLimit);
 	if (physExceededVertexLimit)
 	{
-		has_physics_error |= PhysicsError::TOOMANYVERTSINHULL;
-	}
-
-	if (!(has_physics_error & PhysicsError::DEGENERATE)){ // only update this field (incluides clearing it) if it is not already in use.
-		mFMP->childSetVisible("physics_status_message_text", physExceededVertexLimit);
-		LLIconCtrl* physStatusIcon = mFMP->getChild<LLIconCtrl>("physics_status_message_icon");
-		physStatusIcon->setVisible(physExceededVertexLimit);
-		if (physExceededVertexLimit)
-		{
-			mFMP->childSetValue("physics_status_message_text", mFMP->getString("phys_status_vertex_limit_exceeded"));
-			LLUIImagePtr img = LLUI::getUIImage("ModelImport_Status_Warning");
-			physStatusIcon->setImage(img);
-		}
+		mFMP->childSetValue("physics_status_message_text", mFMP->getString("phys_status_vertex_limit_exceeded"));
+		LLUIImagePtr img = LLUI::getUIImage("ModelImport_Status_Warning");
+		physStatusIcon->setImage(img);
 	}
 
 	if (getLoadState() >= LLModelLoader::ERROR_PARSING)
@@ -3092,21 +2995,12 @@ void LLModelPreview::updateStatusMessages()
 			mModelNoErrors = false;
 		}
 	}
-	// <FS:Beq> Improve the error checking the TO DO here is no longer applicable but not an FS comment so edited to stop it being picked up
-	//// To do investigate use of has_degenerate and include into mModelNoErrors upload blocking mechanics
-	//// current use of has_degenerate won't block upload permanently - later checks will restore the button
-	//if (!mModelNoErrors || mHasDegenerate)
-	//{
-	//	mFMP->childDisable("ok_btn");
-	if (!mModelNoErrors || mHasDegenerate)
+
+	// Todo: investigate use of has_degenerate and include into mModelNoErrors upload blocking mechanics
+	// current use of has_degenerate won't block upload permanently - later checks will restore the button
+	if (!mModelNoErrors || has_degenerate)
 	{
 		mFMP->childDisable("ok_btn");
-		mFMP->childDisable("calculate_btn");
-	}
-	else
-	{
-		mFMP->childEnable("ok_btn");
-		mFMP->childEnable("calculate_btn");
 	}
 	
 	//add up physics triangles etc
@@ -3722,30 +3616,11 @@ BOOL LLModelPreview::render()
 	bool textures = mViewOption["show_textures"];
 	bool physics = mViewOption["show_physics"];
 
-	// <FS:Beq> Extra configurability, to be exposed later as controls?
-	static LLCachedControl<LLColor4> canvas_col(gSavedSettings, "MeshPreviewCanvasColor");
-	static LLCachedControl<LLColor4> edge_col(gSavedSettings, "MeshPreviewEdgeColor");
-	static LLCachedControl<LLColor4> base_col(gSavedSettings, "MeshPreviewBaseColor");
-	static LLCachedControl<LLColor3> brightness(gSavedSettings, "MeshPreviewBrightnessColor");
-	static LLCachedControl<F32> edge_width(gSavedSettings, "MeshPreviewEdgeWidth");
-	static LLCachedControl<LLColor4> phys_edge_col(gSavedSettings, "MeshPreviewPhysicsEdgeColor");
-	static LLCachedControl<LLColor4> phys_fill_col(gSavedSettings, "MeshPreviewPhysicsFillColor");
-	static LLCachedControl<F32> phys_edge_width(gSavedSettings, "MeshPreviewPhysicsEdgeWidth");
-	static LLCachedControl<LLColor4> deg_edge_col(gSavedSettings, "MeshPreviewDegenerateEdgeColor");
-	static LLCachedControl<LLColor4> deg_fill_col(gSavedSettings, "MeshPreviewDegenerateFillColor");	
-	static LLCachedControl<F32> deg_edge_width(gSavedSettings, "MeshPreviewDegenerateEdgeWidth");
-	static LLCachedControl<F32> deg_point_size(gSavedSettings, "MeshPreviewDegeneratePointSize");
-	// </FS:Beq>
 	S32 width = getWidth();
 	S32 height = getHeight();
 
 	LLGLSUIDefault def;
 	LLGLDisable no_blend(GL_BLEND);
-// <FS:Beq> Clean up render of mesh preview
-//	LLGLEnable blend(GL_BLEND);
-//	gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
-// </FS:Beq> 
-
 	LLGLEnable cull(GL_CULL_FACE);
 	LLGLDepthTest depth(GL_TRUE);
 	LLGLDisable fog(GL_FOG);
@@ -3764,9 +3639,9 @@ BOOL LLModelPreview::render()
 		gGL.matrixMode(LLRender::MM_MODELVIEW);
 		gGL.pushMatrix();
 		gGL.loadIdentity();
-		// <FS:Beq> uploader improvements
-		//gGL.color4f(0.169f, 0.169f, 0.169f, 1.f);
-		gGL.color4fv(static_cast<LLColor4>(canvas_col).mV);
+
+		gGL.color4f(0.169f, 0.169f, 0.169f, 1.f);
+
 		gl_rect_2d_simple( width, height );
 
 		gGL.matrixMode(LLRender::MM_PROJECTION);
@@ -3914,11 +3789,8 @@ BOOL LLModelPreview::render()
 	stop_glerror();
 
 	gGL.pushMatrix();
-	// <FS:Beq> mesh uploader improvements configurable brightness
-	//const F32 BRIGHTNESS = 0.9f;
-	//gGL.color3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS);
-	gGL.color4fv(edge_col().mV);
-	// </FS:Beq>
+	const F32 BRIGHTNESS = 0.9f;
+	gGL.color3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS);
 
 	const U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0;
 
@@ -4003,22 +3875,16 @@ BOOL LLModelPreview::render()
 						}
 						else
 						{
-						// <FS:Beq> improved mesh uploader
-						//	gGL.diffuseColor4f(1,1,1,1);
-							gGL.diffuseColor4fv(static_cast<LLColor4>(base_col).mV);
-						// </FS:Beq>
-
+							gGL.diffuseColor4f(1,1,1,1);
 						}
 
 						buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
 						gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-						// <FS:Beq> improved mesh uploader
-						//gGL.diffuseColor3f(0.4f, 0.4f, 0.4f);
-						gGL.diffuseColor4fv(static_cast<LLColor4>(edge_col).mV);
-						// </FS:Beq> 
+						gGL.diffuseColor3f(0.4f, 0.4f, 0.4f);
+
 						if (edges)
 						{
-							glLineWidth(edge_width);
+							glLineWidth(3.f);
 							glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
 							buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
 							glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
@@ -4030,25 +3896,11 @@ BOOL LLModelPreview::render()
 
 			if (physics)
 			{
-				// <FS:Beq> model upload improvements - use the settings
-				////Vector4a physicsFillColour(0.4, 0.4, 0.4, 0.4);
-				//const LLColor4 physicsFillColour(0.0, 0.5, 1.0, 0.5);
-				////LLVector4a physicsEdgeColour(1.0, 1.0, 0.0, 1.0);
-				//const LLColor4 physicsEdgeColour=physicsFillColour*0.5;
-				//const LLColor4 degenerateFill(1.0, 0.0, 0.0, 0.5);
-				//const LLColor4 degenerateEdge(1.0,0.0,0.0,1.0);
-				// </FS:Beq> 
-
 				glClear(GL_DEPTH_BUFFER_BIT);
-				//<FS:Beq> refactor to remove silly variable names
-				//				for (U32 i = 0; i < 2; i++)
-				for (U32 pass = 0; pass < 2; pass++)
-				//</FS:Beq>
+				
+				for (U32 i = 0; i < 2; i++)
 				{
-					//<FS:Beq> refactor to remove silly variable names
-					//if (i == 0)
-					if (pass == 0)
-					//</FS:Beq>
+					if (i == 0)
 					{ //depth only pass
 						gGL.setColorMask(false, false);
 					}
@@ -4058,11 +3910,8 @@ BOOL LLModelPreview::render()
 					}
 
 					//enable alpha blending on second pass but not first pass
-					//<FS:Beq> refactor to remove silly variable names
-					//LLGLState blend(GL_BLEND, i);
-					LLGLState blend(GL_BLEND, pass);
-					//</FS:Beq>
-
+					LLGLState blend(GL_BLEND, i); 
+					
 					gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
 
 					for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
@@ -4071,196 +3920,175 @@ BOOL LLModelPreview::render()
 
 						LLModel* model = instance.mLOD[LLModel::LOD_PHYSICS];
 
-						if (!model)
-						{
-							continue;
-						}
-
-						gGL.pushMatrix();
-						LLMatrix4 mat = instance.mTransform;
+							if (!model)
+							{
+								continue;
+							}
 
-						gGL.multMatrix((GLfloat*)mat.mMatrix);
+							gGL.pushMatrix();
+							LLMatrix4 mat = instance.mTransform;
 
+						gGL.multMatrix((GLfloat*) mat.mMatrix);
 
-						bool render_mesh = true;
-						LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread;
-						if (decomp)
-						{
-							LLMutexLock(decomp->mMutex);
 
-							LLModel::Decomposition& physics = model->mPhysics;
+							bool render_mesh = true;
 
-							if (!physics.mHull.empty())
+							LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread;
+							if (decomp)
 							{
-								render_mesh = false;
+								LLMutexLock(decomp->mMutex);
 
-								if (physics.mMesh.empty())
-								{ //build vertex buffer for physics mesh
-									gMeshRepo.buildPhysicsMesh(physics);
-								}
+								LLModel::Decomposition& physics = model->mPhysics;
 
-								if (!physics.mMesh.empty())
-								{ //render hull instead of mesh
-									for (U32 i = 0; i < physics.mMesh.size(); ++i)
-									{
-										if (explode > 0.f)
+								if (!physics.mHull.empty())
+								{
+									render_mesh = false;
+
+									if (physics.mMesh.empty())
+									{ //build vertex buffer for physics mesh
+										gMeshRepo.buildPhysicsMesh(physics);
+									}
+						
+									if (!physics.mMesh.empty())
+									{ //render hull instead of mesh
+										for (U32 i = 0; i < physics.mMesh.size(); ++i)
 										{
-											gGL.pushMatrix();
+											if (explode > 0.f)
+											{
+												gGL.pushMatrix();
 
-											LLVector3 offset = model->mHullCenter[i] - model->mCenterOfHullCenters;
-											offset *= explode;
+												LLVector3 offset = model->mHullCenter[i]-model->mCenterOfHullCenters;
+												offset *= explode;
 
-											gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]);
-										}
+												gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]);
+											}
 
-										static std::vector<LLColor4U> hull_colors;
+											static std::vector<LLColor4U> hull_colors;
 
-										if (i + 1 >= hull_colors.size())
-										{
-											hull_colors.push_back(LLColor4U(rand() % 128 + 127, rand() % 128 + 127, rand() % 128 + 127, 128));
-										}
+											if (i+1 >= hull_colors.size())
+											{
+												hull_colors.push_back(LLColor4U(rand()%128+127, rand()%128+127, rand()%128+127, 128));
+											}
 
-										gGL.diffuseColor4ubv(hull_colors[i].mV);
-										LLVertexBuffer::drawArrays(LLRender::TRIANGLES, physics.mMesh[i].mPositions, physics.mMesh[i].mNormals);
+											gGL.diffuseColor4ubv(hull_colors[i].mV);
+											LLVertexBuffer::drawArrays(LLRender::TRIANGLES, physics.mMesh[i].mPositions, physics.mMesh[i].mNormals);
 
-										if (explode > 0.f)
-										{
-											gGL.popMatrix();
+											if (explode > 0.f)
+											{
+												gGL.popMatrix();
+											}
 										}
 									}
 								}
 							}
-						}
-
-						if (render_mesh)
-						{
-							if (mVertexBuffer[LLModel::LOD_PHYSICS].empty())
+						
+							if (render_mesh)
 							{
-								genBuffers(LLModel::LOD_PHYSICS, false);
-							}
+								if (mVertexBuffer[LLModel::LOD_PHYSICS].empty())
+								{
+									genBuffers(LLModel::LOD_PHYSICS, false);
+								}
 
-							U32 num_models = mVertexBuffer[LLModel::LOD_PHYSICS][model].size();
-							if (pass > 0){
+								U32 num_models = mVertexBuffer[LLModel::LOD_PHYSICS][model].size();
 								for (U32 i = 0; i < num_models; ++i)
 								{
 									LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i];
 
 									gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-									gGL.diffuseColor4fv(phys_fill_col().mV);
+									gGL.diffuseColor4f(0.4f, 0.4f, 0.0f, 0.4f);
 
 									buffer->setBuffer(type_mask & buffer->getTypeMask());
-									buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts() - 1, buffer->getNumIndices(), 0);
+									buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
+
+									gGL.diffuseColor3f(1.f, 1.f, 0.f);
 
-									gGL.diffuseColor4fv(phys_edge_col().mV);
-									glLineWidth(phys_edge_width);
+									glLineWidth(2.f);
 									glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-									buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts() - 1, buffer->getNumIndices(), 0);
+									buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
 
 									glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
 									glLineWidth(1.f);
 								}
 							}
+
+							gGL.popMatrix();
 						}
 
-						gGL.popMatrix();
-					}
+					glLineWidth(3.f);
+					glPointSize(8.f);
+					gPipeline.enableLightsFullbright(LLColor4::white);
+					//show degenerate triangles
+					LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
+					LLGLDisable cull(GL_CULL_FACE);
+					gGL.diffuseColor4f(1.f,0.f,0.f,1.f);
+					const LLVector4a scale(0.5f);
 
-					//<FS:Beq> refactor to remove silly variable names
-					// also only do this if mDegenerate was set in the preceding mesh checks [Check this if the ordering ever breaks]
-					//if (i > 0)
-					if (pass > 0 && mHasDegenerate)
-					//</FS:Beq>
+					for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
 					{
-						glLineWidth(deg_edge_width);
-						glPointSize(deg_point_size);
-// <FS:Beq> This single line is why the degenerate triangles display has been crap forever. 
-// 						gPipeline.enableLightsFullbright(LLColor4::white);
-						//show degenerate triangles
-						LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
-						LLGLDisable cull(GL_CULL_FACE);
-						const LLVector4a scale(0.5f);
-
-						for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
-						{
-							LLModelInstance& instance = *iter;
+						LLModelInstance& instance = *iter;
 
-							LLModel* model = instance.mLOD[LLModel::LOD_PHYSICS];
+						LLModel* model = instance.mLOD[LLModel::LOD_PHYSICS];
 
-							if (!model)
-							{
-								continue;
-							}
+						if (!model)
+						{
+							continue;
+						}
 
-							gGL.pushMatrix();
-							LLMatrix4 mat = instance.mTransform;
+						gGL.pushMatrix();
+						LLMatrix4 mat = instance.mTransform;
 
-							gGL.multMatrix((GLfloat*)mat.mMatrix);
+						gGL.multMatrix((GLfloat*) mat.mMatrix);
 
 
-							LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread;
-							if (decomp)
-							{
-								LLMutexLock(decomp->mMutex);
+						LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread;
+						if (decomp)
+						{
+							LLMutexLock(decomp->mMutex);
 
-								LLModel::Decomposition& physics = model->mPhysics;
+							LLModel::Decomposition& physics = model->mPhysics;
 
-								if (physics.mHull.empty())
+							if (physics.mHull.empty())
+							{
+								if (mVertexBuffer[LLModel::LOD_PHYSICS].empty())
 								{
-									if (mVertexBuffer[LLModel::LOD_PHYSICS].empty())
-									{
-										genBuffers(LLModel::LOD_PHYSICS, false);
-									}
-
-									auto num_degenerate = 0;
-									//<FS:Beq> More nested i variable silliness
-									//									for (U32 i = 0; i < mVertexBuffer[LLModel::LOD_PHYSICS][model].size(); ++i)
-									auto num_models = mVertexBuffer[LLModel::LOD_PHYSICS][model].size();
-									for (U32 v = 0; v < num_models; ++v)
-									{
-										LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][v];
-									//</FS:Beq>
-										if(buffer->getNumVerts() < 3)continue;
+									genBuffers(LLModel::LOD_PHYSICS, false);
+								}
+							
+								for (U32 i = 0; i < mVertexBuffer[LLModel::LOD_PHYSICS][model].size(); ++i)
+								{
+									LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i];
 
-										buffer->setBuffer(type_mask & buffer->getTypeMask());
+									buffer->setBuffer(type_mask & buffer->getTypeMask());
 
-										LLStrider<LLVector3> pos_strider;
-										buffer->getVertexStrider(pos_strider, 0);
-										LLVector4a* pos = (LLVector4a*)pos_strider.get();
+									LLStrider<LLVector3> pos_strider; 
+									buffer->getVertexStrider(pos_strider, 0);
+									LLVector4a* pos = (LLVector4a*) pos_strider.get();
+							
+									LLStrider<U16> idx;
+									buffer->getIndexStrider(idx, 0);
 
-										LLStrider<U16> idx;
-										buffer->getIndexStrider(idx, 0);
+									for (U32 i = 0; i < buffer->getNumIndices(); i += 3)
+									{
+										LLVector4a v1; v1.setMul(pos[*idx++], scale);
+										LLVector4a v2; v2.setMul(pos[*idx++], scale);
+										LLVector4a v3; v3.setMul(pos[*idx++], scale);
 
-										LLVector4a v1, v2, v3;
-										//<FS:Beq> rename inner most i to avoid merge confusion
-										for (U32 indices_offset = 0; indices_offset < buffer->getNumIndices(); indices_offset += 3)
+										if (ll_is_degenerate(v1,v2,v3))
 										{
-											v1.setMul(pos[*idx++], scale);
-											v2.setMul(pos[*idx++], scale);
-											v3.setMul(pos[*idx++], scale);
-
-											if (ll_is_degenerate(v1, v2, v3))
-											{
-												num_degenerate++;
-												glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-												gGL.diffuseColor3fv(deg_edge_col().mV);
-												buffer->drawRange(LLRender::TRIANGLES, 0, 2, 3, indices_offset);
-												buffer->drawRange(LLRender::POINTS, 0, 2, 3, indices_offset);
-												glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-												gGL.diffuseColor3fv(deg_fill_col().mV);
-												buffer->drawRange(LLRender::TRIANGLES, 0, 2, 3, indices_offset);
-											}
+											buffer->draw(LLRender::LINE_LOOP, 3, i);
+											buffer->draw(LLRender::POINTS, 3, i);
 										}
 									}
 								}
 							}
-
-							gGL.popMatrix();
 						}
-						glLineWidth(1.f);
-						glPointSize(1.f);
-						gPipeline.enableLightsPreview();
-						gGL.setSceneBlendType(LLRender::BT_ALPHA);
+
+						gGL.popMatrix();
 					}
+					glLineWidth(1.f);
+					glPointSize(1.f);
+					gPipeline.enableLightsPreview();
+					gGL.setSceneBlendType(LLRender::BT_ALPHA);
 				}
 			}
 		}
@@ -4342,19 +4170,16 @@ BOOL LLModelPreview::render()
 							}
 						
 							buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0);
-							// <FS:Beq> configurable colour and width
-							//gGL.diffuseColor3f(0.4f, 0.4f, 0.4f);
+							gGL.diffuseColor3f(0.4f, 0.4f, 0.4f);
 
 							if (edges)
 							{
-								gGL.diffuseColor4fv(edge_col().mV);
-								glLineWidth(edge_width);
+								glLineWidth(3.f);
 								glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
 								buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0);
 								glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
 								glLineWidth(1.f);
 							}
-							// </FS:Beq>
 						}
 					}
 				}
@@ -4412,11 +4237,8 @@ void LLModelPreview::rotate(F32 yaw_radians, F32 pitch_radians)
 void LLModelPreview::zoom(F32 zoom_amt)
 {
 	F32 new_zoom = mCameraZoom+zoom_amt;
-	// <FS:Beq> add configurable zoom TODO: stop clamping in render
-	// mCameraZoom = llclamp(new_zoom, 1.f, 10.f);
-	static LLCachedControl<F32> zoom_limit(gSavedSettings, "MeshPreviewZoomLimit");
-	mCameraZoom	= llclamp(new_zoom, 1.f, zoom_limit());
-	// </FS:Beq>
+
+	mCameraZoom	= llclamp(new_zoom, 1.f, 10.f);
 }
 
 void LLModelPreview::pan(F32 right, F32 up)
@@ -4622,22 +4444,11 @@ void LLFloaterModelPreview::toggleCalculateButton(bool visible)
 		childSetTextArg("server_weight", "[SIM]", tbd);
 		childSetTextArg("physics_weight", "[PH]", tbd);
 		childSetTextArg("upload_fee", "[FEE]", tbd);
-		// <FS:Beq> add extended info fields
-		//childSetTextArg("price_breakdown", "[STREAMING]", dashes);
-		//childSetTextArg("price_breakdown", "[PHYSICS]", dashes);
-		//childSetTextArg("price_breakdown", "[INSTANCES]", dashes);
-		//childSetTextArg("price_breakdown", "[TEXTURES]", dashes);
-		//childSetTextArg("price_breakdown", "[MODEL]", dashes);
-		std::string dashes = hasString("--") ? getString("--") : "--";
-		childSetTextArg("price_breakdown", "[STREAMING]", dashes);
-		childSetTextArg("price_breakdown", "[PHYSICS]", dashes);
-		childSetTextArg("price_breakdown", "[INSTANCES]", dashes);
-		childSetTextArg("price_breakdown", "[TEXTURES]", dashes);
-		childSetTextArg("price_breakdown", "[MODEL]", dashes);
-		childSetTextArg("physics_breakdown", "[PCH]", dashes);
-		childSetTextArg("physics_breakdown", "[PM]", dashes);
-		childSetTextArg("physics_breakdown", "[PHU]", dashes);
-		// </FS:Beq>
+		childSetTextArg("price_breakdown", "[STREAMING]", tbd);
+		childSetTextArg("price_breakdown", "[PHYSICS]", tbd);
+		childSetTextArg("price_breakdown", "[INSTANCES]", tbd);
+		childSetTextArg("price_breakdown", "[TEXTURES]", tbd);
+		childSetTextArg("price_breakdown", "[MODEL]", tbd);
 	}
 }
 
@@ -4687,16 +4498,6 @@ void LLFloaterModelPreview::handleModelPhysicsFeeReceived()
 	childSetTextArg("price_breakdown", "[INSTANCES]", llformat("%d", result["upload_price_breakdown"]["mesh_instance"].asInteger()));
 	childSetTextArg("price_breakdown", "[TEXTURES]", llformat("%d", result["upload_price_breakdown"]["texture"].asInteger()));
 	childSetTextArg("price_breakdown", "[MODEL]", llformat("%d", result["upload_price_breakdown"]["model"].asInteger()));
-//<FS:Beq> Updates for enhanced Mesh feedback at upload
-	childSetTextArg("physics_breakdown", "[PCH]", llformat("%0.3f", result["model_physics_cost"]["hull"].asReal()));
-	childSetTextArg("physics_breakdown", "[PM]", llformat("%0.3f", result["model_physics_cost"]["mesh"].asReal()));
-	childSetTextArg("physics_breakdown", "[PHU]", llformat("%0.3f", result["model_physics_cost"]["decomposition"].asReal()));
-	childSetTextArg("streaming_breakdown", "[STR_TOTAL]", llformat("%d", result["streaming_cost"].asInteger()));
-	childSetTextArg("streaming_breakdown", "[STR_HIGH]", llformat("%d", result["streaming_params"]["high_lod"].asInteger()));
-	childSetTextArg("streaming_breakdown", "[STR_MED]", llformat("%d", result["streaming_params"]["medium_lod"].asInteger()));
-	childSetTextArg("streaming_breakdown", "[STR_LOW]", llformat("%d", result["streaming_params"]["low_lod"].asInteger()));
-	childSetTextArg("streaming_breakdown", "[STR_LOWEST]", llformat("%d", result["streaming_params"]["lowest_lod"].asInteger()));
-//</FS:Beq>
 	childSetVisible("upload_fee", true);
 	childSetVisible("price_breakdown", true);
 	mUploadBtn->setEnabled(isModelUploadAllowed());
diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h
index 564f4c39de..7ec6a58ac7 100644
--- a/indra/newview/llfloatermodelpreview.h
+++ b/indra/newview/llfloatermodelpreview.h
@@ -152,7 +152,6 @@ protected:
 	static void		onAutoFillCommit(LLUICtrl*,void*);
 	
 	void onLODParamCommit(S32 lod, bool enforce_tri_limit);
-	void draw3dPreview();
 
 	static void		onExplodeCommit(LLUICtrl*, void*);
 	
@@ -311,7 +310,6 @@ public:
 	static bool 		sIgnoreLoadedCallback;
     std::vector<S32> mLodsQuery;
     std::vector<S32> mLodsWithParsingError;
-	bool mHasDegenerate;
 
 protected:
 
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index c7626304ed..40d6d325ba 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -6582,7 +6582,7 @@ void LLPipeline::enableLightsPreview()
 	light->enable();
 	light->setPosition(light_pos);
 	light->setDiffuse(diffuse0);
-	light->setAmbient(ambient);
+	light->setAmbient(LLColor4::black);
 	light->setSpecular(specular0);
 	light->setSpotExponent(0.f);
 	light->setSpotCutoff(180.f);
@@ -6593,7 +6593,7 @@ void LLPipeline::enableLightsPreview()
 	light->enable();
 	light->setPosition(light_pos);
 	light->setDiffuse(diffuse1);
-	light->setAmbient(ambient);
+	light->setAmbient(LLColor4::black);
 	light->setSpecular(specular1);
 	light->setSpotExponent(0.f);
 	light->setSpotCutoff(180.f);
@@ -6603,7 +6603,7 @@ void LLPipeline::enableLightsPreview()
 	light->enable();
 	light->setPosition(light_pos);
 	light->setDiffuse(diffuse2);
-	light->setAmbient(ambient);
+	light->setAmbient(LLColor4::black);
 	light->setSpecular(specular2);
 	light->setSpotExponent(0.f);
 	light->setSpotCutoff(180.f);
diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml
index e073268b0a..5a86eb06fb 100644
--- a/indra/newview/skins/default/xui/en/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml
@@ -2,12 +2,12 @@
 <floater
  can_close="true"
  can_drag_on_left="false"
- can_minimize="true"
- can_resize="true"
- height="600"
- min_height="600"
- width="1024"
- min_width="1024"
+ can_minimize="false"
+ can_resize="false"
+ height="480"
+ min_height="480"
+ width="980"
+ min_width="980"
  name="Model Preview"
  title="UPLOAD MODEL"
  help_topic="upload_model" >
@@ -33,21 +33,19 @@
   <string name="mesh_status_missing_lod">Missing required level of detail.</string>
   <string name="mesh_status_invalid_material_list">LOD materials are not a subset of reference model.</string>
   <string name="phys_status_vertex_limit_exceeded">Some physical hulls exceed vertex limitations.</string>
-  <string name="phys_status_degenerate_triangles">The physics mesh too dense remove the small thin triangles (see preview)</string>
-  <string name="phys_status_no_havok">The Firestorm OpenSim build is not supported for physics upload in SL.</string>
   <string name="layer_all">All</string> <!-- Text to display in physics layer combo box for "all layers" -->
   <string name="decomposing">Analyzing...</string>
   <string name="simplifying">Simplifying...</string>
   <string name="tbd">TBD</string>
 
-  <panel
-    follows="top|left"
-    height="580"
-    layout="topleft"
-    left="3"
-    name="left_panel"
-    top_pad="0"
-    width="630">
+<panel
+  follows="top|left"
+  height="455"
+  layout="topleft"
+  left="3"
+  name="left_panel"
+  top_pad="10"
+  width="630">
     <panel
       follows="all"
       height="50"
@@ -757,9 +755,8 @@
                       name="first_step_name"
                       text_color="White"
                       top_pad="0"
-                      width="210"
-                      valign="center">
-                      Step 1: Pick a physics model :
+                      width="210">
+                      Step 1: Level of Detail
                     </text>
                     <combo_box
                       follows="left|top"
@@ -801,7 +798,7 @@
               layout="topleft"
               left="18"
               name="physics_tab_border"
-              top_pad="10"
+              top_pad="15"
               width="589"/>
                 <panel
                   bg_alpha_color="0 0 0 0"
@@ -810,7 +807,7 @@
                   follows="top|left"
                   left="18"
                   name="physics analysis"
-                  top_pad="10"
+                  top_pad="15"
                   visible="true"
                   width="589">
                     <text
@@ -822,7 +819,7 @@
                       name="method_label"
                       text_color="White"
                       top_pad="0">
-                      Step 2: Convert to hulls (optional)
+                      Step 2: Analyze
                     </text>
                     <text
                       follows="top|left"
@@ -908,7 +905,7 @@
               layout="topleft"
               left="18"
               name="physics_tab_border"
-              top_pad="10"
+              top_pad="15"
               width="589"/>
                 <panel
                   bg_alpha_color="0 0 0 0"
@@ -917,7 +914,7 @@
                   height="66"
                   left="18"
                   name="physics simplification"
-                  top_pad="10"
+                  top_pad="15"
                   width="589">
                     <text
                       text_color="White"
@@ -1016,7 +1013,7 @@
               layout="topleft"
               left="18"
               name="physics_tab_border"
-              top_pad="10"
+              top_pad="15"
               width="589"/>
                 <panel
                   bg_alpha_color="0 0 0 0"
@@ -1078,9 +1075,10 @@
                  follows="left|top"
                  height="19"
                  layout="topleft"
-                 top_pad="5"
+                 left_pad="5"
+                 top_delta="0"
                  name="physics message"
-                 width="589">
+                 width="270">
                      <icon
                       follows="left|top"
                       height="16"
@@ -1095,7 +1093,7 @@
                       layout="topleft"
                       left_pad="2"
                       name="physics_status_message_text"
-                      width="573"
+                      width="252"
                       top_delta="3"/>
                 </panel>
         </panel>
@@ -1221,14 +1219,13 @@
      </panel>
     </tab_container>
     <panel
-     follows="top|left|bottom"
-     layout="topleft"
-     height="184"
-     left="4"
-     border="true"
+     follows="top|left"
+     height="80"
+     layout="top|left"
+     left="0"
      name="weights_and_warning_panel"
      top_pad="3"
-     width="629">
+     width="625">
        <button
          follows="top|left"
          label="Calculate weights &amp; fee"
@@ -1268,10 +1265,10 @@
          label_color="White"
          layout="topleft"
          name="reset_btn"
-         right="-5"
+         right="-2"
          top="3"
          height="20"
-         width="265"/>
+         width="275"/>
        <!-- ========== WEIGHTS ==========-->
        <text
          follows="top|left"
@@ -1290,7 +1287,7 @@
          left_pad="0"
          name="prim_weight"
          top_delta="0"
-         width="130"
+         width="120"
          word_wrap="true">
          Land impact: [EQ]
        </text>
@@ -1300,7 +1297,7 @@
          left_pad="0"
          name="download_weight"
          top_delta="0"
-         width="130"
+         width="100"
          word_wrap="true">
          Download: [ST]
        </text>
@@ -1310,7 +1307,7 @@
          layout="topleft"
          left_pad="0"
          name="physics_weight"
-         width="130"
+         width="90"
          word_wrap="true">
          Physics: [PH]
        </text>
@@ -1320,148 +1317,17 @@
          layout="topleft"
          left_pad="0"
          name="server_weight"
-         width="130"
+         width="83"
          word_wrap="true">
          Server: [SIM]
        </text>
-       <!-- =========== Cost breakdown ======== -->
-      <panel
-        border="true"
-        top_pad="5"
-        layout="topleft"
-        left="6"
-        name="price_breakdown_panel"
-        width="120"
-        height="100">
-        <text
-          layout="topleft"
-          left="3">
-          Price Breakdown
-        </text>
-        <view_border
-          bevel_style="none"
-          follows="top|left"
-          height="0"
-          layout="topleft"
-          left="3"
-          name="price_breakdown_border"
-          top_pad="5"
-          width="110"/>
-        <text
-          height="80"
-          top_pad="5"
-          layout="topleft"
-          left="3"
-          name="price_breakdown_labels"
-          width="70"
-          word_wrap="false">
-Download:
-Physics:
-Instances:
-Textures:
-Model:
-        </text>
-        <text
-          height="80"
-          top_delta="0"
-          layout="topleft"
-          halign="right"
-          left_pad="0"
-          name="price_breakdown"
-          width="40"
-          word_wrap="false">
-[STREAMING]
-[PHYSICS]
-[INSTANCES]
-[TEXTURES]
-[MODEL]
-        </text>
-      </panel>
-       <!-- 
-       Streaming breakdown numbers are available but not fully understood
-       uncommenting the following sections will display the numbers for debugging purposes
-       <text
-        height="80"
-        top_delta="0"
-        layout="topleft"
-        left="130"
-        name="streaming_breakdown_labels"
-        width="65"
-        word_wrap="true">
-Streaming/Download:
-High:
-Medium:
-Low:
-Lowest:
-      </text>
+       <!-- ========== NOTE MESSAGE ========== -->
        <text
-        height="80"
-        top_delta="0"
-        layout="topleft"
-        left_pad="0"
-        name="streaming_breakdown"
-        width="95"
-        word_wrap="true">
-[STR_TOTAL]
-[STR_HIGH]
-[STR_MED]
-[STR_LOW]
-[STR_LOWEST]
-      </text>-->
-      <panel
-        border="true"
-        layout="topleft"
-        left_pad="265"
-        name="price_breakdown_panel"
-        width="120"
-        height="100">
-        <text
-          layout="topleft"
-          left="3">
-          Physics Costs
-        </text>
-        <view_border
-          bevel_style="none"
-          follows="top|left"
-          height="0"
-          layout="topleft"
-          left="3"
-          name="price_breakdown_border"
-          top_pad="5"
-          width="110"/>
-        <text
-         height="80"
-         top_pad="5"
-         layout="topleft"
-         left="5"
-         name="physics_breakdown_labels"
-         width="65">
-Base Hull:
-Mesh:
-Analysed:
-        </text>
-        <text
-         height="80"
-         top_delta="0"
-         layout="topleft"
-         left_pad="0"
-         name="physics_breakdown"
-         width="40"
-         halign="right"
-         word_wrap="false"
-         visible="true">
-[PCH]
-[PM]
-[PHU]
-        </text>-->
-      </panel>
-      <!-- ========== NOTE MESSAGE ========== -->
-      <text
          font="SansSerif"
          layout="topleft"
          left="6"
          name="warning_title"
-         top_pad="5"
+         top_pad="10"
          text_color="DrYellow"
          visible="false"
          width="40">
@@ -1480,110 +1346,104 @@ Analysed:
          visible="false">
          You dont have rights to upload mesh models. [[VURL] Find out how] to get certified.
        </text>
-       <text text_color="Yellow" layout="topleft" top_delta="5" left="6" name="status">
-[STATUS]
-       </text>
+       <text text_color="Yellow" layout="topleft" top_delta="20" left="6" name="status">[STATUS]</text>
+  
     </panel>
-  </panel>
-  <panel
-    follows="top|left|bottom|right"
-    can_resize="true"
-    name="right_panel"
-    top="0"
-    left="640"
-    background_visible="true"
-    width="375">
-    <text
+</panel>
+
+<text 
+ follows="left|top"
+ layout="topleft"
+ left="640"
+ name="lod_label"
+ text_color="White"
+ top="13"
+ height="15"
+ width="290">
+ Preview:
+ </text>
+<panel
+ border="true"
+ bevel_style="none"
+ follows="top|left"
+ name="preview_panel"
+ top_pad="4"
+ width="290"
+ height="290"/>
+
+<panel
+  follows="all"
+  height="130"
+  layout="topleft"
+  name="right_panel"
+  top_pad="5"
+  width="340">
+    <combo_box
+      top_pad="3"
       follows="left|top"
+      height="18"
       layout="topleft"
-      left="0"
-      name="lod_label"
-      text_color="White"
-      top="13"
-      height="15"
-      width="290">
-      Preview:
-    </text>
-    <panel
-      can_resize="false"
-      follows="top|left"
-      height="20"
-      name="right_upper_panel"
-      top="8"
-      left="60"
-      background_visible="true"
-      width="315">
-      <combo_box
-        top_pad="3"
-        can_resize="false"
-        follows="top|left"
-        height="18"
-        layout="topleft"
-        name="preview_lod_combo"
-        width="75"
-        tool_tip="LOD to view in preview render">
+      name="preview_lod_combo"
+      width="150"
+      tool_tip="LOD to view in preview render">
         <combo_item name="high">   High   </combo_item>
         <combo_item name="medium"> Medium </combo_item>
         <combo_item name="low">    Low    </combo_item>
         <combo_item name="lowest"> Lowest </combo_item>
-      </combo_box>
-    </panel>
-  </panel>
-  <panel
-     border="true"
-     bevel_style="none"
-     follows="top|left|right|bottom"
-     layout="topleft"
-     name="preview_panel"
-     top="30"
-     width="375"
-     height="525"/>
-
-   <panel
-     follows="left|right|bottom"
-     layout="topleft"
-     height="40"
-     name="lower_right_panel"
-     top_pad="5"
-     width="375">
-     <check_box
-       follows="right|bottom"
-       label="Edges"
+    </combo_box>
+    <text
+      follows="top|left"
+      layout="topleft"
+      text_color="White"
+      top="5"
+      left_pad="20"
+      name="label_display"
+      width="50">
+      Display...
+    </text>
+    <check_box
+      follows="top|left"
+      label="Edges"
       label_text.text_color="White"
       layout="topleft"
+      left_delta="0"
       name="show_edges"
-      width="70"
-      left="0"
-      top_pad="8"/>
+      top_pad="8">
+    </check_box>
     <check_box
-      follows="right|bottom"
-      left_pad="8"
+      follows="top|left"
       label="Physics"
       label_text.text_color="White"
-      name="show_physics"/>
+      layout="topleft"
+      name="show_physics"
+      top_pad="8">
+    </check_box>
     <check_box
-      follows="right|bottom"
+      follows="top|left"
       label="Textures"
       label_text.text_color="White"
       layout="topleft"
       name="show_textures"
-      left_pad="0"/>
+      top_pad="8">
+    </check_box>
     <check_box
-      follows="right|bottom"
-      label="Weights"
+      follows="top|left"
+      label="Skin weights"
       label_text.text_color="White"
       layout="topleft"
       name="show_skin_weight"
-      left_pad="0"/>
+      top_pad="8">
+    </check_box>
     <check_box
-      follows="right|bottom"
+      follows="top|left"
       label="Joints"
       label_text.text_color="White"
       layout="topleft"
       name="show_joint_positions"
-      left_pad="0"/>
+      top_pad="8">
+    </check_box>
     <text
-      follows="right|bottom"
+      follows="top|left"
       layout="topleft"
       left="2"
       name="physics_explode_label"
@@ -1593,13 +1453,12 @@ Analysed:
     </text>
     <slider
       name="physics_explode"
-      follows="right|bottom"
-      valign="center"
-      top="15"
-      left="80"
+      follows="top|left"
+      top="100"
+      left="0"
       min_val="0.0"
       max_val="3.0"
       height="20"
-      width="120"/>
-  </panel>
+      width="150"/>
+</panel>
 </floater>
-- 
cgit v1.2.3


From 7953162907ed35d57e79b2b71c2093ae1f758c98 Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Mon, 25 Feb 2019 20:30:38 +0200
Subject: SL-10614 FIXED Don't hide the tear-off menu items when filtering

---
 indra/newview/llsearchableui.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/llsearchableui.cpp b/indra/newview/llsearchableui.cpp
index de90896548..cfe93a777e 100644
--- a/indra/newview/llsearchableui.cpp
+++ b/indra/newview/llsearchableui.cpp
@@ -127,7 +127,7 @@ void ll::statusbar::SearchableItem::setNotHighlighted( )
 
 bool ll::statusbar::SearchableItem::hightlightAndHide( LLWString const &aFilter )
 {
-	if( mMenu && !mMenu->getVisible() && !mWasHiddenBySearch )
+	if ((mMenu && !mMenu->getVisible() && !mWasHiddenBySearch) || dynamic_cast<LLMenuItemTearOffGL*>(mMenu))
 		return false;
 
 	setNotHighlighted( );
-- 
cgit v1.2.3


From a985e54f03ed05e1b8920da695c4533870dd3463 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Tue, 26 Feb 2019 11:21:07 +0200
Subject: SL-10615 FIXED Main menus drop-down lists can't be opened while
 searching its title

---
 indra/newview/llsearchableui.cpp | 17 +++++++++--------
 indra/newview/llsearchableui.h   |  2 +-
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/indra/newview/llsearchableui.cpp b/indra/newview/llsearchableui.cpp
index cfe93a777e..93143eb33f 100644
--- a/indra/newview/llsearchableui.cpp
+++ b/indra/newview/llsearchableui.cpp
@@ -125,17 +125,13 @@ void ll::statusbar::SearchableItem::setNotHighlighted( )
 	}
 }
 
-bool ll::statusbar::SearchableItem::hightlightAndHide( LLWString const &aFilter )
+bool ll::statusbar::SearchableItem::hightlightAndHide(LLWString const &aFilter, bool hide)
 {
 	if ((mMenu && !mMenu->getVisible() && !mWasHiddenBySearch) || dynamic_cast<LLMenuItemTearOffGL*>(mMenu))
 		return false;
 
 	setNotHighlighted( );
 
-	bool bVisible(false);
-	for( tSearchableItemList::iterator itr = mChildren.begin(); itr  != mChildren.end(); ++itr )
-		bVisible |= (*itr)->hightlightAndHide( aFilter );
-
 	if( aFilter.empty() )
 	{
 		if( mCtrl )
@@ -143,17 +139,22 @@ bool ll::statusbar::SearchableItem::hightlightAndHide( LLWString const &aFilter
 		return true;
 	}
 
+	bool bHighlighted(!hide);
 	if( mLabel.find( aFilter ) != LLWString::npos )
 	{
 		if( mCtrl )
 			mCtrl->setHighlighted( true );
-		return true;
+		bHighlighted = true;
 	}
 
-	if( mCtrl && !bVisible )
+	bool bVisible(false);
+	for (tSearchableItemList::iterator itr = mChildren.begin(); itr != mChildren.end(); ++itr)
+		bVisible |= (*itr)->hightlightAndHide(aFilter, !bHighlighted);
+
+	if (mCtrl && !bVisible && !bHighlighted)
 	{
 		mWasHiddenBySearch = true;
 		mMenu->setVisible(FALSE);
 	}
-	return bVisible;
+	return bVisible || bHighlighted;
 }
diff --git a/indra/newview/llsearchableui.h b/indra/newview/llsearchableui.h
index 42b2866fb6..9741557e49 100644
--- a/indra/newview/llsearchableui.h
+++ b/indra/newview/llsearchableui.h
@@ -107,7 +107,7 @@ namespace ll
 			SearchableItem();
 
 			void setNotHighlighted( );
-			bool hightlightAndHide( LLWString const &aFilter );
+			bool hightlightAndHide( LLWString const &aFilter, bool hide = true );
 		};
 
 		struct SearchData
-- 
cgit v1.2.3


From 6861adcb3188991867f6b6e101e72ce466b1745b Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Tue, 26 Feb 2019 18:58:02 +0200
Subject: SL-10616 No moving animation if wear linked objects in edit mode and
 change avatar

---
 indra/newview/llselectmgr.cpp | 32 +++++++++++++++++++++++++-------
 1 file changed, 25 insertions(+), 7 deletions(-)

diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 02093fa6bd..56be902254 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -6804,8 +6804,28 @@ void LLSelectMgr::pauseAssociatedAvatars()
 			
         mSelectedObjects->mSelectType = getSelectTypeForObject(object);
 
+        bool is_attached = false;
         if (mSelectedObjects->mSelectType == SELECT_TYPE_ATTACHMENT && 
-            isAgentAvatarValid() && object->getParent() != NULL)
+            isAgentAvatarValid())
+        {
+            // Selection can be obsolete, confirm that this is an attachment
+            LLViewerObject* parent = (LLViewerObject*)object->getParent();
+            while (parent != NULL)
+            {
+                if (parent->isAvatar())
+                {
+                    is_attached = true;
+                    break;
+                }
+                else
+                {
+                    parent = (LLViewerObject*)parent->getParent();
+                }
+            }
+        }
+
+
+        if (is_attached)
         {
             if (object->isAnimatedObject())
             {
@@ -6823,14 +6843,12 @@ void LLSelectMgr::pauseAssociatedAvatars()
                 mPauseRequests.push_back(gAgentAvatarp->requestPause());
             }
         }
-        else
+        else if (object && object->isAnimatedObject() && object->getControlAvatar())
         {
-            if (object && object->isAnimatedObject() && object->getControlAvatar())
-            {
-                // Is a non-attached animated object. Pause the control avatar.
-                mPauseRequests.push_back(object->getControlAvatar()->requestPause());
-            }
+            // Is a non-attached animated object. Pause the control avatar.
+            mPauseRequests.push_back(object->getControlAvatar()->requestPause());
         }
+
     }
 }
 
-- 
cgit v1.2.3


From de91391bdd71dd7c9634cf9a736e1032d0fe983e Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Mon, 25 Feb 2019 20:37:56 +0200
Subject: SL-10349 Added more tooltips

---
 .../newview/skins/default/xui/en/floater_tools.xml | 18 ++++++----
 .../skins/default/xui/en/sidepanel_item_info.xml   | 15 +++++---
 .../skins/default/xui/en/sidepanel_task_info.xml   | 40 ++++++++++++++--------
 3 files changed, 47 insertions(+), 26 deletions(-)

diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml
index ae0820c3ac..0abee2ff80 100644
--- a/indra/newview/skins/default/xui/en/floater_tools.xml
+++ b/indra/newview/skins/default/xui/en/floater_tools.xml
@@ -915,7 +915,8 @@
              name="Object Name"
              select_on_focus="true"
              top_delta="0"
-             width="170" />
+             width="170"
+             tool_tip="The name is limited to 63 characters. Longer prim names are cut short. Names can only consist of printable characters found in the ASCII-7 (non-extended) character set, with the exception of the vertical bar/pipe &apos;|&apos;." />
             <text
              follows="left|top"
              height="10"
@@ -933,7 +934,8 @@
              name="Object Description"
              select_on_focus="true"
              top_delta="0"
-             width="170" />
+             width="170"
+             tool_tip="When people have &apos;Hover Tips on All Objects&apos; selected in the viewer's settings, they'll see the object description pop-up for any object under their mouse pointer. The prim description is limited to 127 bytes any string longer then that will be truncated." />
             <text
              type="string"
              left="10"
@@ -1090,7 +1092,8 @@
              layout="topleft"
              name="clickaction"
              width="130"
-             left_pad="10">
+             left_pad="10"
+             tool_tip="A click action enables you to interact with an object with a single left click. Each click action has a special cursor indicating what it does. Some click actions have requirements to function. For example Touch and Pay require scripts" >
                 <combo_box.item
                  label="Touch  (default)"
                  name="Touch/grab(default)"
@@ -1126,7 +1129,8 @@
              layout="topleft"
              name="checkbox for sale"
              left="7"
-             width="97" />
+             width="97"
+             tool_tip="Lets people buy this object, its content or it copy inworld for specified price." />
   <!-- NEW PRICE SPINNER
 Objects are allowed to be for sale for L$0 to invoke buy UI behavior
 even though the user gets a free copy.
@@ -1144,7 +1148,8 @@ even though the user gets a free copy.
       width="85"
       min_val="0"
       height="20"
-      max_val="999999999" />
+      max_val="999999999"
+      tool_tip="Object cost." />
   <!-- NEW SALE TYPE COMBO BOX -->
       <combo_box
             left_pad="8"
@@ -1157,7 +1162,8 @@ even though the user gets a free copy.
             max_chars="20"
             mouse_opaque="true"
             name="sale type"
-            width="89">
+            width="89"
+            tool_tip="Select whether purchaser will receive a copy, copy of the content or item itself." >
         <combo_box.item
            name="Copy"
            label="Copy"
diff --git a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
index ca1dc87134..acb6f5b42a 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
@@ -130,7 +130,8 @@
         max_length_bytes="63"
         name="LabelItemName"
         top_delta="0"
-        width="210" />
+        width="210"
+        tool_tip="The name is limited to 63 characters. Longer prim names are cut short. Names can only consist of printable characters found in the ASCII-7 (non-extended) character set, with the exception of the vertical bar/pipe &apos;|&apos;." />
       <text
         type="string"
         length="1"
@@ -153,7 +154,8 @@
         max_length_bytes="127"
         name="LabelItemDesc"
         top_delta="-5"
-        width="210" />
+        width="210"
+        tool_tip="When people have &apos;Hover Tips on All Objects&apos; selected in the viewer's settings, they'll see the object description pop-up for any object under their mouse pointer. The prim description is limited to 127 bytes any string longer then that will be truncated." />
       <text
         type="string"
         length="1"
@@ -421,14 +423,16 @@
         left="20"
         name="CheckPurchase"
         top_pad="20"
-        width="100" />
+        width="100"
+        tool_tip="Lets people buy this object, its content or it copy inworld for specified price." />
       <combo_box
         height="23"
         left_pad="0"
         layout="topleft"
         follows="left|top"
         name="ComboBoxSaleType"
-        width="170">
+        width="170"
+        tool_tip="Select whether purchaser will receive a copy, copy of the content or item itself." >
         <combo_box.item
              name="Copy"
              label="Copy"
@@ -455,7 +459,8 @@
         min_val="0"
         height="23"
         max_val="999999999"
-        top_pad="10"/>
+        top_pad="10"
+        tool_tip="Object cost." />
     </panel>
 
   </scroll_container>
diff --git a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
index 713d5f94bb..8a3e18707f 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
@@ -130,7 +130,8 @@
 		     max_length_bytes="63"
              name="Object Name"
 	    	 top_delta="0"
-		     width="225" />
+		     width="225"
+             tool_tip="The name is limited to 63 characters. Longer prim names are cut short. Names can only consist of printable characters found in the ASCII-7 (non-extended) character set, with the exception of the vertical bar/pipe &apos;|&apos;." />
 	    <text
 	    type="string"
 	    length="1"
@@ -154,7 +155,8 @@
     		 left_delta="78"
 		     max_length_bytes="127"
 	    	 top_delta="-5"
-	    	 width="225"/>
+	    	 width="225"
+             tool_tip="When people have &apos;Hover Tips on All Objects&apos; selected in the viewer's settings, they'll see the object description pop-up for any object under their mouse pointer. The prim description is limited to 127 bytes any string longer then that will be truncated." />
 	    <text
 		     type="string"
 		     length="1"
@@ -271,23 +273,24 @@
              layout="topleft"
              name="clickaction"
              width="168"
-             left="81">
+             left="81"
+             tool_tip="A click action enables you to interact with an object with a single left click. Each click action has a special cursor indicating what it does. Some click actions have requirements to function. For example Touch and Pay require scripts" >
                 <combo_box.item
                  label="Touch  (default)"
                  name="Touch/grab(default)"
-          value="Touch" />
+                 value="Touch" />
                 <combo_box.item
                  label="Sit on object"
                  name="Sitonobject"
-          value="Sit" />
+                 value="Sit" />
                 <combo_box.item
                  label="Buy object"
                  name="Buyobject"
-          value="Buy" />
+                 value="Buy" />
                 <combo_box.item
                  label="Pay object"
                  name="Payobject"
-          value="Pay" />
+                 value="Pay" />
                 <combo_box.item
                  label="Open"
                  name="Open"
@@ -422,14 +425,16 @@
 			 left="20"
              name="checkbox for sale"
 			 top_pad="10"
-			 width="100" />
+			 width="100"
+			 tool_tip="Lets people buy this object, its content or it copy inworld for specified price." />
 		<combo_box
 			 height="23"
 			 left_pad="0"
 			 layout="topleft"
 			 follows="left|top"
-            name="sale type"
-			 width="170">
+             name="sale type"
+			 width="170"
+			 tool_tip="Select whether purchaser will receive a copy, copy of the content or item itself.">
         <combo_box.item
            name="Copy"
            label="Copy"
@@ -456,7 +461,8 @@
         width="150"
         min_val="1"
         height="20"
-        max_val="999999999" />
+        max_val="999999999"
+        tool_tip="Object cost." />
       <check_box
 	   height="20"
 	   width="110"
@@ -573,7 +579,8 @@
 		     left="5"
 		     name="open_btn"
 		     top="0"
-		     width="73" />
+		     width="73"
+		     tool_tip="Open to view the Object Contents." />
 	    <button
 		     follows="bottom|left"
 		     height="23"
@@ -582,7 +589,8 @@
 		     left_pad="5"
 		     name="pay_btn"
 		     top="0"
-		     width="73" />
+		     width="73"
+		     tool_tip="Open Pay Window. Object must have pay script for this to work." />
 	    <button
 		     follows="bottom|left"
 		     height="23"
@@ -591,7 +599,8 @@
 		     left_pad="5"
 		     name="buy_btn"
 		     top="0"
-		     width="73" />
+		     width="73"
+		     tool_tip="Open Buy Window. Requires the object to be set for sale." />
         <button
 		     follows="bottom|left"
 		     height="23"
@@ -600,7 +609,8 @@
 		     left_pad="5"
 		     name="details_btn"
 		     top="0"
-		     width="74" />
+		     width="74"
+		     tool_tip="Open Inspect Object Window." />
 
 	</panel>
 </panel>
-- 
cgit v1.2.3


From 1aa013f75b8cbd4fe1d12deec156dcd902df7c44 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 28 Feb 2019 18:12:28 -0500
Subject: Added tag 6.1.0-release for changeset a3143db58a0f

---
 .hgtags | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.hgtags b/.hgtags
index b117cb3016..fcf043b1ea 100755
--- a/.hgtags
+++ b/.hgtags
@@ -544,3 +544,4 @@ ac3b1332ad4f55b7182a8cbcc1254535a0069f75 5.1.7-release
 1cfa567caf5088ae299271be08cc2d9f0801ff6a pre-Poseidon
 821edfcd14919c0e95c590866171c61fb57e8623 6.0.0-release
 21b7604680ef6b6ea67f8bebaaa588d6e263bdc1 6.0.1-release
+a3143db58a0f6b005232bf9018e7fef17ff9ec90 6.1.0-release
-- 
cgit v1.2.3


From 03db2ddc9c27cf842c6185826617b0da0d2b87f5 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 28 Feb 2019 18:12:29 -0500
Subject: increment viewer version to 6.1.1

---
 indra/newview/VIEWER_VERSION.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index dfda3e0b4f..f3b5af39e4 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-6.1.0
+6.1.1
-- 
cgit v1.2.3