Commit Graph

132 Commits (2ea5ac0c43e3e28d2b1774f5367d099271a1da32)

Author SHA1 Message Date
Alexander Gavriliuk 2ea5ac0c43 #1111 Remove xmlrpc-epi 2024-07-01 20:20:04 +02:00
Ansariel 2696b3de08 Introduce LLWStringView to prevent unnecessary memory allocations 2024-05-24 13:55:38 +03:00
Ansariel e2e37cced8 Fix line endlings 2024-05-22 22:40:26 +03:00
Ansariel 1b67dd855c Merge remote-tracking branch 'origin/main' into DRTVWR-600-maint-A
# Conflicts:
#	autobuild.xml
#	indra/cmake/CMakeLists.txt
#	indra/cmake/GoogleMock.cmake
#	indra/llaudio/llaudioengine_fmodstudio.cpp
#	indra/llaudio/llaudioengine_fmodstudio.h
#	indra/llaudio/lllistener_fmodstudio.cpp
#	indra/llaudio/lllistener_fmodstudio.h
#	indra/llaudio/llstreamingaudio_fmodstudio.cpp
#	indra/llaudio/llstreamingaudio_fmodstudio.h
#	indra/llcharacter/llmultigesture.cpp
#	indra/llcharacter/llmultigesture.h
#	indra/llimage/llimage.cpp
#	indra/llimage/llimagepng.cpp
#	indra/llimage/llimageworker.cpp
#	indra/llimage/tests/llimageworker_test.cpp
#	indra/llmessage/tests/llmockhttpclient.h
#	indra/llprimitive/llgltfmaterial.h
#	indra/llrender/llfontfreetype.cpp
#	indra/llui/llcombobox.cpp
#	indra/llui/llfolderview.cpp
#	indra/llui/llfolderviewmodel.h
#	indra/llui/lllineeditor.cpp
#	indra/llui/lllineeditor.h
#	indra/llui/lltextbase.cpp
#	indra/llui/lltextbase.h
#	indra/llui/lltexteditor.cpp
#	indra/llui/lltextvalidate.cpp
#	indra/llui/lltextvalidate.h
#	indra/llui/lluictrl.h
#	indra/llui/llview.cpp
#	indra/llwindow/llwindowmacosx.cpp
#	indra/newview/app_settings/settings.xml
#	indra/newview/llappearancemgr.cpp
#	indra/newview/llappearancemgr.h
#	indra/newview/llavatarpropertiesprocessor.cpp
#	indra/newview/llavatarpropertiesprocessor.h
#	indra/newview/llbreadcrumbview.cpp
#	indra/newview/llbreadcrumbview.h
#	indra/newview/llbreastmotion.cpp
#	indra/newview/llbreastmotion.h
#	indra/newview/llconversationmodel.h
#	indra/newview/lldensityctrl.cpp
#	indra/newview/lldensityctrl.h
#	indra/newview/llface.inl
#	indra/newview/llfloatereditsky.cpp
#	indra/newview/llfloatereditwater.cpp
#	indra/newview/llfloateremojipicker.h
#	indra/newview/llfloaterimsessiontab.cpp
#	indra/newview/llfloaterprofiletexture.cpp
#	indra/newview/llfloaterprofiletexture.h
#	indra/newview/llgesturemgr.cpp
#	indra/newview/llgesturemgr.h
#	indra/newview/llimpanel.cpp
#	indra/newview/llimpanel.h
#	indra/newview/llinventorybridge.cpp
#	indra/newview/llinventorybridge.h
#	indra/newview/llinventoryclipboard.cpp
#	indra/newview/llinventoryclipboard.h
#	indra/newview/llinventoryfunctions.cpp
#	indra/newview/llinventoryfunctions.h
#	indra/newview/llinventorygallery.cpp
#	indra/newview/lllistbrowser.cpp
#	indra/newview/lllistbrowser.h
#	indra/newview/llpanelobjectinventory.cpp
#	indra/newview/llpanelprofile.cpp
#	indra/newview/llpanelprofile.h
#	indra/newview/llpreviewgesture.cpp
#	indra/newview/llsavedsettingsglue.cpp
#	indra/newview/llsavedsettingsglue.h
#	indra/newview/lltooldraganddrop.cpp
#	indra/newview/llurllineeditorctrl.cpp
#	indra/newview/llvectorperfoptions.cpp
#	indra/newview/llvectorperfoptions.h
#	indra/newview/llviewerparceloverlay.cpp
#	indra/newview/llviewertexlayer.cpp
#	indra/newview/llviewertexturelist.cpp
#	indra/newview/macmain.h
#	indra/test/test.cpp
2024-05-22 19:04:52 +02:00
Alexander Gavriliuk f9473e8afc secondlife/viewer#1333 BOOL to bool conversion leftovers: ternaries 2024-05-07 10:18:51 +02:00
Andrey Lihatskiy 38c2a5bde9 Merge branch 'marchcat/w-whitespace' into marchcat/x-ws-merge 2024-05-01 08:16:58 +03:00
Andrey Lihatskiy 1b68f71348 #824 Process source files in bulk: replace tabs with spaces, convert CRLF to LF, and trim trailing whitespaces as needed 2024-04-29 07:56:09 +03:00
Andrey Lihatskiy 85f2447b3d Merge branch 'main' into marchcat/a-merge
# Conflicts:
#	autobuild.xml
#	indra/llimage/llimage.cpp
#	indra/llui/llsearcheditor.cpp
#	indra/llui/llview.cpp
#	indra/newview/llagent.cpp
#	indra/newview/llappviewer.cpp
#	indra/newview/llfloatercamera.cpp
#	indra/newview/llfloatereditsky.cpp
#	indra/newview/llfloatereditwater.cpp
#	indra/newview/llinventoryfunctions.cpp
#	indra/newview/lloutfitgallery.cpp
#	indra/newview/lloutfitslist.cpp
#	indra/newview/llpanelgroupbulkban.cpp
#	indra/newview/llsidepanelappearance.cpp
#	indra/newview/llvovolume.cpp
2024-04-24 19:28:15 +03:00
Andrey Lihatskiy 428f21cf79 Merge branch 'main' into marchcat/x-merge 2024-04-24 18:45:54 +03:00
Henri Beauchamp 2f452d06e6 Proposal #2 to restore how UI/dialogs used to render by prioritizing fallback fonts.
With the emojis support, a new font was added, which not only provides emojis
but also fancy colorful replacements for UTF-8 characters that used to be
supported by our fallback (monochrome) fonts: this causes discrepancies and
unwanted/undesired changes in scripted objects menus (e.g. an empty circle or
square may render as a black, full one, a heart may render red instead of white),
not to mention the larger font size used by the emoji characters...

This patch restores the aspect of such menus/dialogs/UI elements with UTF-8
characters that *are* supported by the usual fallback fonts (fonts which may
also vary from one viewer to another, and from one OS to another), so that
everything keeps working/rendering as it always did so far, while not impairing
the use of new colorful emojis.

This second proposal ensures that:
- "genuine" emojis (in the 0x1f000-0x1ffff range), will *always* be rendered
  using the new emojis font (this solves, for example, the monochrome "yellow
  faces" issue seen with some characters in my first proposal).
- Special UTF-8 characters (in the 0x2000-0x32FF range) which have been used by
  scripters so far, will render as they used to, using the monochrome fallback
  fonts (this repairs scripted dialogs menus).
- Remaining special characters, that do not have a corresponding glyph in the
  monochrome font, but do have one in the emojis font, will use the latter font
  to render.

It also got the nice side-effect of removing the dependency on the ICU4C library.

Note however that the recent commit:
326055ba82
will need to be reverted to allow this patch to actually fix scripted dialogs.

Also, some cleanup might be needed in skins/default/xui/*/emoji_characters.xml to
remove from it the special UTF-8 characters that will no longer be rendered with
fanciful colors, but instead with the monochrome font glyphs.
2024-03-14 01:47:14 +02:00
Ansariel eb1ed3896f Merge branch 'main' of https://github.com/secondlife/viewer into DRTVWR-600-maint-A
# Conflicts:
#	autobuild.xml
#	indra/llrender/llfontbitmapcache.cpp
#	indra/llrender/llfontbitmapcache.h
#	indra/llrender/llfontfreetype.cpp
#	indra/llrender/llfontfreetype.h
#	indra/llrender/llfontgl.cpp
#	indra/llrender/llfontgl.h
#	indra/llui/llbutton.h
#	indra/llui/llfloater.cpp
#	indra/llui/llfloater.h
#	indra/llui/llfolderviewitem.cpp
#	indra/llui/lllineeditor.cpp
#	indra/llui/lllineeditor.h
#	indra/llui/llscrollcontainer.cpp
#	indra/llui/llscrollingpanellist.cpp
#	indra/llui/llscrollingpanellist.h
#	indra/llui/llscrolllistctrl.h
#	indra/llui/lltextbase.cpp
#	indra/llui/lltextbase.h
#	indra/llui/lltexteditor.cpp
#	indra/llui/lltexteditor.h
#	indra/llui/lluictrl.cpp
#	indra/llui/llview.cpp
#	indra/llui/llview.h
#	indra/newview/llchicletbar.h
#	indra/newview/llconversationlog.h
#	indra/newview/llfloaterimsessiontab.cpp
#	indra/newview/llfloaterimsessiontab.h
#	indra/newview/llfloateruipreview.cpp
#	indra/newview/llnavigationbar.h
#	indra/newview/llpaneltopinfobar.h
#	indra/newview/llpathfindingpathtool.h
#	indra/newview/lltextureview.cpp
#	indra/newview/lltoolbrush.h
#	indra/newview/lltoolcomp.h
#	indra/newview/lltooldraganddrop.h
#	indra/newview/lltoolface.h
#	indra/newview/lltoolfocus.h
#	indra/newview/lltoolindividual.h
#	indra/newview/lltoolobjpicker.h
#	indra/newview/lltoolpie.h
#	indra/newview/lltoolpipette.h
#	indra/newview/lltoolselectland.h
#	indra/newview/llviewermediafocus.h
#	indra/newview/llviewerparcelmediaautoplay.h
#	indra/newview/llviewerwindow.cpp
#	indra/newview/llvoicechannel.h
#	indra/newview/llvoicevivox.h
#	indra/newview/llworldmapview.cpp
2024-03-12 16:52:30 +01:00
Andrey Lihatskiy b68a05e7c3 Merge branch 'main' into marchcat/x-merge
# Conflicts:
#	indra/llcommon/llstring.cpp
#	indra/llcommon/llstring.h
2024-03-04 18:01:05 +02:00
Andrey Lihatskiy faf69f407f Merge branch 'main' into marchcat/yz-merge
# Conflicts:
#	indra/newview/llinventorygallery.cpp
2024-03-01 18:02:48 +02:00
Ansariel 3ffe63b8a4 Convert remaining BOOLs in llxml and introduce std::string_view 2024-02-21 19:02:58 +02:00
Lars Næsbye Christensen 9e854b697a misc: BOOL to bool 2024-02-17 12:23:07 +02:00
Ansariel 9480a98cff Replace most of BOOL with bool in llmath 2024-02-16 10:17:55 +02:00
Lars Næsbye Christensen 70f8dc7a4f miscellaneous: BOOL (int) to real bool 2024-02-12 23:17:22 +02:00
Lars Næsbye Christensen 04a02e83e9 misc: BOOL (int) to real bool 2024-02-12 23:17:22 +02:00
Alexander Gavriliuk afc9252372 SL-20363 Option 'Debug Unicode' - show unicode values 2024-02-09 09:16:17 +03:00
Alexander Gavriliuk 7075717b7c SL-20363 Add Advanced option 'Debug Unicode' 2024-02-08 13:17:18 +03:00
AiraYumi 7c8907522f replace boost library to standard 2024-01-08 23:29:21 +02:00
Alexander Gavriliuk 2fad5a770b SL-19801 Log unicode characters for debug 2023-11-30 14:08:29 +01:00
Alexander Gavriliuk ddb2c93818 SL-20463 Rename outfit dialog box accepts emoji characters 2023-10-18 13:32:39 +02:00
Alexander Gavriliuk 16f0329d18 SL-19951 Collect used icons in a special group 'Recently used' 2023-07-10 13:11:58 +02:00
Alexander Gavriliuk 97b0ba2a6d SL-19575 LLFloaterEmojiPicker - Add filter by category 2023-04-20 03:55:02 +02:00
Callum Prentice fb00bce81a Merge branch 'xcode-14.1' into DRTVWR-489-emoji 2023-01-26 10:37:59 -08:00
Andrey Kleshchev 20b16ddf05 MacOS Build fix 2023-01-16 20:43:12 +02:00
Andrey Kleshchev de77dc3ed3 MacOS Build fix 2023-01-16 19:52:35 +02:00
Fawrsk 9e743c99fb Cleanup for loops in llcommon to use C++11 range based for loops 2023-01-07 00:38:12 -04:00
Kitty Barnett 7ebaa2d2e5 Merge branch contribution/emoji into DRTVWR-489-emoji 2022-11-09 23:25:02 +01:00
Nat Goodspeed 9522a0b7c1 DRTVWR-575: Fix llcommon assumptions that size_t fits in 4 bytes.
It's a little distressing how often we have historically coded S32 or U32 to
pass a length or index.

There are more such assumptions in other viewer subdirectories, but this is a
start.
2022-11-03 14:58:32 -04:00
Kitty Barnett 5440464a9c Merge branch 'contribution/emoji' 2022-08-28 00:08:38 +02:00
Nat Goodspeed 30cf50e6af SL-16094: Support ll_convert<std::string>(const char*)
and correspondingly, ll_convert<std::wstring>(const wchar_t*).

Now that we're using ll_convert() for single-argument stringize(arg), make
sure it can efficiently handle the simple case of constructing a string from a
const char pointer.
2021-11-23 14:25:16 -05:00
Nat Goodspeed 95958bc8b2 SL-16207: Guess Microsoft compiler isn't smart about default params?
clang allows us to specify, as a default function parameter, an expression
involving a preceding parameter, e.g. (char* ptr, size_t len=strlen(ptr)). The
Microsoft compiler produces errors, requiring more overloads to address that.

Also #undef llstring.h's declaration helper macros at the bottom of the file.
Once we've used them to declare stuff, they need not (should not) be visible
to the consuming source file.
2021-11-02 11:31:47 -04:00
Nat Goodspeed 10692ab4a4 SL-16207: Create uniform overload sets for wide-string conversions.
Use new ll_convert_forms() macro in llstring.h to declare, for each
wide-string conversion function of interest, four overloads. The real one, the
nontrivial one, is (const char*, size_t len), implemented in llstring.cpp. Then
(const string&, size_t len), (const char*) and (const string&) are each
trivially implemented with an inline call to (const char*, size_t len).

Notably, we change all S32 len parameters to size_t. Using S32 is old skool.

Tweak each nontrivial implementation in llstring.cpp to accept (const char*,
size_t len) instead of (const string&) with or without explicit length.
Eliminate from llstring.cpp trivial overloads (deriving length from either a
const char* or from a string), since those are now inline in the header.

Of course three of those overloads will be unified once we enable C++17 and
change each relevant parameter to std::string_view, but we're not yet there.
Meanwhile, this suite of overloads minimizes, to the best of our ability, new
string allocations solely for parameter passing. And use of a macro means we
need only change the macro once we get std::string_view.

We take this step because some use cases require (const char*), some require
(const string&, size_t len), others (const char*, size_t len) ... We were
missing some key overloads, and had to work around them by instantiating new
string objects (necessitating both allocation and character copying) just to
pass the desired parameter. Using the macro ensures this consistent set of
overloads for every wide-string conversion function.

Additionally, knowing that the ugly-name overloads exist, ll_convert_forms()
implicitly defines corresponding ll_convert<TARGET>() overloads.

Streamline declarations of utf16str_to_wstring(), wstring_to_utf16str(),
utf8str_to_utf16str(), utf16str_to_utf8str(), utf8str_to_wstring(),
wstring_to_utf8str(), ll_convert_wide_to_wstring() and
ll_convert_wstring_to_wide() using ll_convert_forms().

Use corresponding new ll_convert_cp_forms() macro to declare consistent
overloads for conversion functions accepting an optional unsigned int
code_page parameter. We used to delegate to the .cpp file the implementation
of each overload accepting code_page so llstring.h need not include the
Windows header defining the CP_UTF8 default; this is more simply accomplished
by introducing a small ll_wstring_default_code_page() function to retrieve it
from the .cpp file. That lets us specify the code_page parameter as optional,
using that function as its default value.

Use ll_convert_cp_forms() to streamline declarations of
ll_convert_wide_to_string() and ll_convert_string_to_wide().

Introduce real implementations of ll_convert_wide_to_wstring() and
ll_convert_wstring_to_wide(). The previous implementations merely copied
individual characters, which is wrong: when we convert UTF16LE to UTF32, we
can and should fold multi-character UTF16LE encodings to the corresponding
single UTF32 character. The real implemenations leverage our awareness that
both llutf16string and Windows std::wstring (either variant) use UTF16LE
encoding, so we can reuse the corresponding llutf16string conversions.

Introduce generic ll_convert_length() function, specialized as either
std::strlen() or std::wcslen() depending on parameter type. (Even if
std::wcslen() is derived from classic C, why doesn't the C++ standard library
define a std::strlen(const wchar_t*) overload to call it?)

Fix ll_convert_alias()'s ll_convert_impl specialization's operator() to accept
boost::call_traits::param_type, so we can pass (e.g.) const std::wstring& but
also const wchar_t* instead of const wchar_t*&.
2021-11-02 10:35:34 -04:00
Nat Goodspeed af5c5a994b SL-16207: Update llstring.h handling of different string types.
In llpreprocessor.h, consider the case of clang on Windows: #define
LL_WCHAR_T_NATIVE there as well as for the Microsoft compiler with /Zc:wchar_t
switch.

In stdtypes.h, inject a LLWCHAR_IS_WCHAR_T symbol to allow the preprocessor to
make decisions about when the types are identical.

llstring.h's conversion logic deals with three types of wide strings
(LLWString, std::wstring and utf16string) based on three types of wide char
(llwchar, wchar_t and U16, respectively). Sometimes they're three distinct
types, sometimes wchar_t is identical to llwchar and sometimes wchar_t is
identical to U16. Rationalize the three cases using ll_convert_u16_alias() and
new ll_convert_wstr_alias() macros.

stringize.h was directly calling wstring_to_utf8str() and utf8str_to_wstring(),
which was producing errors with VS 2019 clang since there isn't actually a
wstring_to_utf8str(std::wstring) overload. Use ll_convert<std::string>()
instead, since that redirects to the relevant ll_convert_wide_to_string()
function. (And now you see why we've been trying to migrate to the uniform
ll_convert<target>() wrapper!) Similarly, call ll_convert<std::wstring>()
instead of a two-step conversion from utf8str_to_wstring(), producing LLWString,
then a character-by-character copy from LLWString to std::wstring. That
isn't even correct: on Windows, we should be encoding from UTF32 to UTF16.
2021-10-27 13:01:37 -04:00
Dave Houlton 7cd076c796 DRTVWR-510 remove all LL_SOLARIS conditionals 2020-10-08 17:16:22 -06:00
Nat Goodspeed cbbe655f27 DRTVWR-476: Eliminate snprintf_hack::snprintf(). Use MS snprintf().
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/snprintf-snprintf-snprintf-l-snwprintf-snwprintf-l?view=vs-2017
"Beginning with the UCRT in Visual Studio 2015 and Windows 10, snprintf is no
longer identical to _snprintf. The snprintf function behavior is now C99
standard compliant."

In other words, VS 2015 et ff. snprintf() now promises to nul-terminate the
buffer even in the overflow case, which is what snprintf_hack::snprintf() was
for.

This removal was motivated by ambiguous-call errors generated by VS 2017 for
library snprintf() vs. snprintf_hack::snprintf().
2020-03-25 16:12:45 -04:00
Kitty Barnett 5a6ddb2ea6 Fallback fonts can have first crack at adding an unknown character + set Twemoji as the viewer's fallback for all emoji blocks 2019-11-07 17:15:21 +01:00
andreykproductengine 29f0a7808f SL-10930 LLStringUtil pointlessly scan the string 2019-04-16 21:58:22 +03:00
Nat Goodspeed 4a13657285 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.
2018-12-15 09:13:24 -05:00
Nat Goodspeed 3c53f8abde SL-10153: VS 2013 isn't so fond of ?: involving std::string. 2018-12-14 16:00:09 -05:00
Nat Goodspeed 132e708fec 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.
2018-12-14 12:01:51 -05:00
Nat Goodspeed 9ffcafb64b 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>().
2018-12-14 10:48:43 -05:00
Nat Goodspeed 4e894eb2a7 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.
2018-12-11 20:48:20 -05:00
Brad Payne (Vir Linden) e36745eb98 merge 2018-01-17 16:06:27 +00:00
Brad Payne (Vir Linden) 36c4424213 SL-808 - more work on arc display. area calculations still have some issues, especially for animated objects. 2017-10-03 22:26:00 +01:00
Oz Linden 01e0b78c59 merge changes for DRTVWR-439 2017-08-16 15:43:58 -04:00
Mnikolenko Productengine 65208b7741 MAINT-7488 FIXED [Windows] Viewer crashes when pasting empty string from clipboard 2017-06-16 17:46:12 +03:00
Nat Goodspeed fe64db61d6 Automated merge with ssh://bitbucket.org/lindenlab/viewer-release 2017-05-22 21:30:26 -04:00