summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2018-06-26 09:12:08 -0400
committerNat Goodspeed <nat@lindenlab.com>2018-06-26 09:12:08 -0400
commit3a7513b5875b86c247dd49fe78b8fab955ba5e0a (patch)
tree3f942d50b41fd090550541af01bb50d23d845c09
parent06954294b8739dd51abe75e3710da6e496b353d4 (diff)
parentdc07de2f4a4c49d1877bf743b6f0d209392f6eb6 (diff)
DRTVWR-453: Merge up to latest viewer-release.
-rwxr-xr-x.hgtags3
-rw-r--r--autobuild.xml34
-rwxr-xr-xdoc/contributions.txt3
-rw-r--r--indra/llappearance/lltexlayer.cpp7
-rw-r--r--indra/llappearance/llwearable.cpp12
-rw-r--r--indra/llcommon/llfile.cpp4
-rw-r--r--indra/llcommon/llfile.h2
-rw-r--r--indra/llcommon/llmemory.cpp1732
-rw-r--r--indra/llcommon/llmemory.h321
-rw-r--r--indra/llcommon/llsdserialize.cpp61
-rw-r--r--indra/llcommon/llsdserialize.h38
-rw-r--r--indra/llcommon/llsdserialize_xml.cpp2
-rw-r--r--indra/llcommon/llthread.cpp9
-rw-r--r--indra/llcommon/tests/llsdserialize_test.cpp184
-rw-r--r--indra/llcorehttp/CMakeLists.txt39
-rw-r--r--indra/llimage/llimage.cpp36
-rw-r--r--indra/llimage/llimage.h7
-rw-r--r--indra/llimage/llimagedxt.cpp2
-rw-r--r--indra/llimage/llimagej2c.cpp4
-rw-r--r--indra/llkdu/tests/llimagej2ckdu_test.cpp47
-rw-r--r--indra/llmath/llvolume.cpp65
-rw-r--r--indra/llmath/llvolume.h7
-rw-r--r--indra/llmessage/llavatarnamecache.cpp16
-rw-r--r--indra/llmessage/llinstantmessage.cpp208
-rw-r--r--indra/llmessage/llinstantmessage.h53
-rw-r--r--indra/llmessage/llxfer.cpp58
-rw-r--r--indra/llmessage/llxfer.h7
-rw-r--r--indra/llmessage/llxfer_file.cpp68
-rw-r--r--indra/llmessage/llxfer_file.h6
-rw-r--r--indra/llmessage/llxfer_mem.cpp22
-rw-r--r--indra/llmessage/llxfer_mem.h1
-rw-r--r--indra/llmessage/llxfer_vfile.cpp92
-rw-r--r--indra/llmessage/llxfer_vfile.h8
-rw-r--r--indra/llmessage/llxfermanager.cpp735
-rw-r--r--indra/llmessage/llxfermanager.h50
-rw-r--r--indra/llplugin/llpluginclassmedia.cpp2
-rw-r--r--indra/llplugin/llpluginclassmedia.h2
-rw-r--r--indra/llprimitive/llmaterialid.cpp5
-rw-r--r--indra/llprimitive/llmaterialid.h1
-rw-r--r--indra/llprimitive/llprimitive.cpp10
-rw-r--r--indra/llprimitive/llprimitive.h5
-rw-r--r--indra/llrender/CMakeLists.txt2
-rw-r--r--indra/llrender/llfontfreetype.cpp79
-rw-r--r--indra/llrender/llfontfreetype.h7
-rw-r--r--indra/llrender/llfontregistry.cpp2
-rw-r--r--indra/llrender/llgl.cpp11
-rw-r--r--indra/llrender/llgl.h17
-rw-r--r--indra/llrender/llglcommonfunc.cpp37
-rw-r--r--indra/llrender/llglcommonfunc.h30
-rw-r--r--indra/llrender/llglslshader.cpp62
-rw-r--r--indra/llrender/llglslshader.h11
-rw-r--r--indra/llrender/llgltexture.h1
-rw-r--r--indra/llrender/llrender.cpp1
-rw-r--r--indra/llrender/llrender.h10
-rw-r--r--indra/llrender/llvertexbuffer.cpp40
-rw-r--r--indra/llrender/llvertexbuffer.h4
-rw-r--r--indra/llui/llbadge.cpp10
-rw-r--r--indra/llui/llbadge.h3
-rw-r--r--indra/llui/llbadgeowner.cpp8
-rw-r--r--indra/llui/llbadgeowner.h1
-rw-r--r--indra/llui/llcombobox.cpp8
-rw-r--r--indra/llui/llcombobox.h1
-rw-r--r--indra/llui/lllineeditor.cpp9
-rw-r--r--indra/llui/lllineeditor.h2
-rw-r--r--indra/llui/llscrolllistctrl.cpp4
-rw-r--r--indra/llui/lltexteditor.cpp4
-rw-r--r--indra/llui/lltrans.cpp60
-rw-r--r--indra/llui/lltrans.h9
-rw-r--r--indra/llui/llurlentry.cpp5
-rw-r--r--indra/llui/llurlentry.h1
-rw-r--r--indra/llui/llviewereventrecorder.cpp4
-rw-r--r--indra/llvfs/lldir_linux.cpp2
-rw-r--r--indra/llvfs/lldir_mac.cpp2
-rw-r--r--indra/llvfs/lldir_solaris.cpp2
-rw-r--r--indra/llvfs/lldir_win32.cpp2
-rw-r--r--indra/llvfs/lllfsthread.cpp4
-rw-r--r--indra/llvfs/llvfs.cpp6
-rw-r--r--indra/llwindow/llwindowmacosx.cpp2
-rw-r--r--indra/llwindow/llwindowwin32.cpp17
-rw-r--r--indra/llxml/llcontrol.h3
-rw-r--r--indra/media_plugins/cef/media_plugin_cef.cpp7
-rw-r--r--indra/newview/CMakeLists.txt7
-rw-r--r--indra/newview/Info-SecondLife.plist2
-rw-r--r--indra/newview/VIEWER_VERSION.txt2
-rw-r--r--indra/newview/app_settings/settings.xml43
-rw-r--r--indra/newview/app_settings/settings_per_account.xml22
-rw-r--r--indra/newview/ca-bundle.crt3899
-rw-r--r--indra/newview/cursors_mac/UI_CURSOR_PIPETTE.tifbin0 -> 326 bytes
-rw-r--r--indra/newview/llagent.cpp5
-rw-r--r--indra/newview/llappearancemgr.cpp2
-rw-r--r--indra/newview/llappviewer.cpp261
-rw-r--r--indra/newview/llappviewer.h7
-rw-r--r--indra/newview/llavatarrenderinfoaccountant.cpp6
-rw-r--r--indra/newview/llchathistory.cpp73
-rw-r--r--indra/newview/lldrawable.cpp43
-rw-r--r--indra/newview/lldrawable.h3
-rw-r--r--indra/newview/lldrawpool.cpp5
-rw-r--r--indra/newview/lldrawpoolalpha.cpp19
-rw-r--r--indra/newview/lldrawpoolavatar.cpp11
-rw-r--r--indra/newview/lldrawpoolmaterials.cpp4
-rw-r--r--indra/newview/llface.cpp22
-rw-r--r--indra/newview/llfacebookconnect.cpp3
-rw-r--r--indra/newview/llfasttimerview.cpp25
-rw-r--r--indra/newview/llfilepicker.cpp77
-rw-r--r--indra/newview/llfilepicker.h6
-rw-r--r--indra/newview/llfilteredwearablelist.cpp6
-rw-r--r--indra/newview/llflickrconnect.cpp3
-rw-r--r--indra/newview/llfloaterauction.cpp552
-rw-r--r--indra/newview/llfloaterauction.h86
-rw-r--r--indra/newview/llfloaterautoreplacesettings.cpp108
-rw-r--r--indra/newview/llfloaterautoreplacesettings.h3
-rw-r--r--indra/newview/llfloateravatartextures.cpp4
-rw-r--r--indra/newview/llfloaterhoverheight.cpp10
-rw-r--r--indra/newview/llfloaterhoverheight.h2
-rw-r--r--indra/newview/llfloaterimagepreview.cpp2
-rw-r--r--indra/newview/llfloaterimcontainer.cpp1
-rw-r--r--indra/newview/llfloaterimsession.cpp25
-rw-r--r--indra/newview/llfloaterimsession.h8
-rw-r--r--indra/newview/llfloaterland.cpp25
-rw-r--r--indra/newview/llfloatermemleak.cpp7
-rw-r--r--indra/newview/llfloatermodelpreview.cpp12
-rw-r--r--indra/newview/llfloatermodelpreview.h2
-rw-r--r--indra/newview/llfloaterpreference.cpp33
-rw-r--r--indra/newview/llfloaterpreference.h1
-rw-r--r--indra/newview/llfloaterproperties.cpp4
-rw-r--r--indra/newview/llfloaterreporter.cpp99
-rw-r--r--indra/newview/llfloaterreporter.h5
-rw-r--r--indra/newview/llfloatersnapshot.cpp9
-rw-r--r--indra/newview/llfloatersnapshot.h2
-rw-r--r--indra/newview/llfloaterspellchecksettings.cpp16
-rw-r--r--indra/newview/llfloaterspellchecksettings.h1
-rw-r--r--indra/newview/llfloatertools.cpp13
-rw-r--r--indra/newview/llfloatertopobjects.cpp2
-rw-r--r--indra/newview/llfloaterwebcontent.cpp4
-rw-r--r--indra/newview/llfloaterwebprofile.cpp6
-rw-r--r--indra/newview/llfloaterworldmap.cpp4
-rw-r--r--indra/newview/llfloaterworldmap.h2
-rw-r--r--indra/newview/llglsandbox.cpp4
-rw-r--r--indra/newview/llimprocessing.cpp1589
-rw-r--r--indra/newview/llimprocessing.h63
-rw-r--r--indra/newview/llimview.cpp14
-rw-r--r--indra/newview/llimview.h6
-rw-r--r--indra/newview/llinspectavatar.cpp4
-rw-r--r--indra/newview/llinventorybridge.cpp30
-rw-r--r--indra/newview/llinventoryfilter.cpp2
-rw-r--r--indra/newview/llinventoryfunctions.cpp77
-rw-r--r--indra/newview/llinventoryfunctions.h2
-rw-r--r--indra/newview/llinventorymodel.cpp52
-rw-r--r--indra/newview/llinventorymodel.h4
-rw-r--r--indra/newview/llinventorypanel.cpp14
-rw-r--r--indra/newview/lllocalbitmaps.cpp44
-rw-r--r--indra/newview/lllocalbitmaps.h2
-rw-r--r--indra/newview/lllogininstance.cpp6
-rw-r--r--indra/newview/llmaniprotate.cpp1
-rw-r--r--indra/newview/llmanipscale.cpp1
-rw-r--r--indra/newview/llmaniptranslate.cpp5
-rw-r--r--indra/newview/llmaterialmgr.cpp38
-rw-r--r--indra/newview/llmaterialmgr.h6
-rw-r--r--indra/newview/llmediadataclient.cpp15
-rw-r--r--indra/newview/llmeshrepository.cpp502
-rw-r--r--indra/newview/llmeshrepository.h63
-rw-r--r--indra/newview/llmoveview.cpp14
-rw-r--r--indra/newview/llnavigationbar.cpp2
-rw-r--r--indra/newview/llnotificationlistitem.cpp4
-rw-r--r--indra/newview/lloutfitgallery.cpp11
-rw-r--r--indra/newview/lloutfitslist.cpp4
-rw-r--r--indra/newview/llpaneleditwearable.cpp2
-rw-r--r--indra/newview/llpanelface.cpp13
-rw-r--r--indra/newview/llpanelgroup.cpp10
-rw-r--r--indra/newview/llpanelgroup.h1
-rw-r--r--indra/newview/llpanelgroupgeneral.cpp1
-rw-r--r--indra/newview/llpanelgroupnotices.cpp1
-rw-r--r--indra/newview/llpanelgrouproles.cpp77
-rw-r--r--indra/newview/llpanelgrouproles.h8
-rw-r--r--indra/newview/llpanellogin.cpp14
-rw-r--r--indra/newview/llpanellogin.h1
-rw-r--r--indra/newview/llpanelmarketplaceinboxinventory.cpp7
-rw-r--r--indra/newview/llpanelmarketplaceinboxinventory.h1
-rw-r--r--indra/newview/llpanelnearbymedia.cpp3
-rw-r--r--indra/newview/llpanelobject.cpp33
-rw-r--r--indra/newview/llpanelobjectinventory.cpp248
-rw-r--r--indra/newview/llpaneloutfitedit.cpp5
-rw-r--r--indra/newview/llpaneloutfitedit.h1
-rw-r--r--indra/newview/llpanelpeople.cpp1
-rw-r--r--indra/newview/llpanelpermissions.cpp82
-rw-r--r--indra/newview/llpanelpermissions.h12
-rw-r--r--indra/newview/llpanelvolume.cpp7
-rw-r--r--indra/newview/llpanelvolumepulldown.cpp31
-rw-r--r--indra/newview/llpanelvolumepulldown.h4
-rw-r--r--indra/newview/llpanelwearing.cpp39
-rw-r--r--indra/newview/llpanelwearing.h1
-rw-r--r--indra/newview/llphysicsmotion.cpp16
-rw-r--r--indra/newview/llpreviewscript.cpp58
-rw-r--r--indra/newview/llpreviewscript.h5
-rw-r--r--indra/newview/llpreviewtexture.cpp25
-rw-r--r--indra/newview/llpreviewtexture.h2
-rw-r--r--indra/newview/llsculptidsize.cpp154
-rw-r--r--indra/newview/llsculptidsize.h134
-rw-r--r--indra/newview/llsechandler_basic.cpp2
-rw-r--r--indra/newview/llselectmgr.cpp167
-rw-r--r--indra/newview/llsidepanelappearance.cpp16
-rw-r--r--indra/newview/llsidepanelappearance.h2
-rw-r--r--indra/newview/llsidepanelinventory.cpp7
-rw-r--r--indra/newview/llsidepanelinventory.h2
-rw-r--r--indra/newview/llsidepanelinventorysubpanel.cpp26
-rw-r--r--indra/newview/llsidepanelinventorysubpanel.h2
-rw-r--r--indra/newview/llsidepaneliteminfo.cpp18
-rw-r--r--indra/newview/llsidepaneltaskinfo.cpp23
-rw-r--r--indra/newview/llsidepaneltaskinfo.h6
-rw-r--r--indra/newview/llspatialpartition.cpp4
-rw-r--r--indra/newview/llspatialpartition.h4
-rw-r--r--indra/newview/llstartup.cpp10
-rw-r--r--indra/newview/llstatusbar.cpp6
-rw-r--r--indra/newview/llstatusbar.h2
-rw-r--r--indra/newview/lltexturecache.cpp38
-rw-r--r--indra/newview/lltexturectrl.cpp7
-rw-r--r--indra/newview/lltexturectrl.h4
-rw-r--r--indra/newview/lltexturefetch.cpp8
-rw-r--r--indra/newview/lltextureview.cpp4
-rw-r--r--indra/newview/lltoast.cpp15
-rw-r--r--indra/newview/lltoast.h4
-rw-r--r--indra/newview/lltoastimpanel.cpp21
-rw-r--r--indra/newview/lltooldraganddrop.cpp2
-rw-r--r--indra/newview/lltoolfocus.cpp2
-rw-r--r--indra/newview/lltoolselect.cpp9
-rw-r--r--indra/newview/lltwitterconnect.cpp3
-rw-r--r--indra/newview/llviewerassetupload.cpp24
-rw-r--r--indra/newview/llviewercamera.cpp10
-rw-r--r--indra/newview/llviewercamera.h3
-rw-r--r--indra/newview/llviewercontrol.cpp15
-rw-r--r--indra/newview/llviewerdisplay.cpp4
-rw-r--r--indra/newview/llviewerfloaterreg.cpp2
-rw-r--r--indra/newview/llviewermedia.cpp77
-rw-r--r--indra/newview/llviewermedia.h4
-rw-r--r--indra/newview/llviewermediafocus.cpp12
-rw-r--r--indra/newview/llviewermediafocus.h2
-rw-r--r--indra/newview/llviewermenu.cpp21
-rw-r--r--indra/newview/llviewermenufile.cpp287
-rw-r--r--indra/newview/llviewermenufile.h37
-rw-r--r--indra/newview/llviewermessage.cpp1421
-rw-r--r--indra/newview/llviewerobject.cpp38
-rw-r--r--indra/newview/llviewerobject.h1
-rw-r--r--indra/newview/llviewerobjectlist.cpp9
-rw-r--r--indra/newview/llvieweroctree.cpp2
-rw-r--r--indra/newview/llviewerpartsim.cpp3
-rw-r--r--indra/newview/llviewerpartsource.cpp28
-rw-r--r--indra/newview/llviewerpartsource.h2
-rw-r--r--indra/newview/llviewerregion.cpp11
-rw-r--r--indra/newview/llviewershadermgr.cpp1
-rw-r--r--indra/newview/llviewertexture.cpp73
-rw-r--r--indra/newview/llviewertexture.h12
-rw-r--r--indra/newview/llviewertextureanim.cpp2
-rw-r--r--indra/newview/llviewertexturelist.cpp6
-rw-r--r--indra/newview/llviewerthrottle.cpp2
-rw-r--r--indra/newview/llviewerwearable.cpp2
-rw-r--r--indra/newview/llviewerwindow.cpp123
-rw-r--r--indra/newview/llviewerwindow.h11
-rw-r--r--indra/newview/llvoavatar.cpp56
-rw-r--r--indra/newview/llvoavatarself.cpp6
-rw-r--r--indra/newview/llvograss.cpp2
-rw-r--r--indra/newview/llvoicevivox.cpp45
-rw-r--r--indra/newview/llvopartgroup.cpp24
-rw-r--r--indra/newview/llvopartgroup.h3
-rw-r--r--indra/newview/llvovolume.cpp277
-rw-r--r--indra/newview/llvovolume.h15
-rw-r--r--indra/newview/llwearableitemslist.cpp2
-rw-r--r--indra/newview/pipeline.cpp43
-rw-r--r--indra/newview/pipeline.h2
-rw-r--r--indra/newview/skins/default/xui/da/floater_tos.xml4
-rw-r--r--indra/newview/skins/default/xui/de/notifications.xml14
-rw-r--r--indra/newview/skins/default/xui/de/panel_main_inventory.xml6
-rw-r--r--indra/newview/skins/default/xui/de/strings.xml8
-rw-r--r--indra/newview/skins/default/xui/en/floater_about_land.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_auction.xml96
-rw-r--r--indra/newview/skins/default/xui/en/floater_buy_land.xml19
-rw-r--r--indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml25
-rw-r--r--indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml7
-rw-r--r--indra/newview/skins/default/xui/en/floater_report_abuse.xml1
-rw-r--r--indra/newview/skins/default/xui/en/floater_snapshot.xml4
-rw-r--r--indra/newview/skins/default/xui/en/fonts.xml1
-rw-r--r--indra/newview/skins/default/xui/en/menu_inventory.xml8
-rw-r--r--indra/newview/skins/default/xui/en/menu_people_blocked_gear.xml2
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml13
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml10
-rw-r--r--indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_notices.xml16
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_roles.xml74
-rw-r--r--indra/newview/skins/default/xui/en/panel_people.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_uploads.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_tools_texture.xml8
-rw-r--r--indra/newview/skins/default/xui/en/panel_volume_pulldown.xml20
-rw-r--r--indra/newview/skins/default/xui/en/role_actions.xml20
-rw-r--r--indra/newview/skins/default/xui/en/sidepanel_appearance.xml9
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml6
-rw-r--r--indra/newview/skins/default/xui/es/notifications.xml14
-rw-r--r--indra/newview/skins/default/xui/es/panel_main_inventory.xml6
-rw-r--r--indra/newview/skins/default/xui/es/strings.xml8
-rw-r--r--indra/newview/skins/default/xui/fr/notifications.xml12
-rw-r--r--indra/newview/skins/default/xui/fr/panel_main_inventory.xml6
-rw-r--r--indra/newview/skins/default/xui/fr/strings.xml8
-rw-r--r--indra/newview/skins/default/xui/it/notifications.xml14
-rw-r--r--indra/newview/skins/default/xui/it/panel_main_inventory.xml6
-rw-r--r--indra/newview/skins/default/xui/it/strings.xml8
-rw-r--r--indra/newview/skins/default/xui/ja/notifications.xml12
-rw-r--r--indra/newview/skins/default/xui/ja/panel_main_inventory.xml6
-rw-r--r--indra/newview/skins/default/xui/ja/strings.xml6
-rw-r--r--indra/newview/skins/default/xui/pl/floater_tos.xml4
-rw-r--r--indra/newview/skins/default/xui/pt/notifications.xml12
-rw-r--r--indra/newview/skins/default/xui/pt/panel_main_inventory.xml6
-rw-r--r--indra/newview/skins/default/xui/pt/strings.xml6
-rw-r--r--indra/newview/skins/default/xui/ru/notifications.xml16
-rw-r--r--indra/newview/skins/default/xui/ru/panel_main_inventory.xml6
-rw-r--r--indra/newview/skins/default/xui/ru/strings.xml8
-rw-r--r--indra/newview/skins/default/xui/tr/notifications.xml14
-rw-r--r--indra/newview/skins/default/xui/tr/panel_main_inventory.xml6
-rw-r--r--indra/newview/skins/default/xui/tr/strings.xml8
-rw-r--r--indra/newview/skins/default/xui/zh/notifications.xml12
-rw-r--r--indra/newview/skins/default/xui/zh/panel_main_inventory.xml6
-rw-r--r--indra/newview/skins/default/xui/zh/strings.xml5
-rw-r--r--indra/newview/tests/lldateutil_test.cpp2
-rw-r--r--indra/newview/tests/llsechandler_basic_test.cpp538
-rw-r--r--indra/newview/tests/llslurl_test.cpp4
-rw-r--r--indra/newview/tests/llviewernetwork_test.cpp4
-rw-r--r--indra/newview/tests/llworldmap_test.cpp2
-rwxr-xr-xindra/newview/viewer_manifest.py13
325 files changed, 6661 insertions, 11269 deletions
diff --git a/.hgtags b/.hgtags
index 091e54ebf1..4b169ffba1 100755
--- a/.hgtags
+++ b/.hgtags
@@ -535,3 +535,6 @@ ad0e15543836d64d6399d28b32852510435e344a 5.1.0-release
26d9e9bb166a9a417f35b1863223a597af8185fd 5.1.1-release
2eb917875efdfe920680b9049302d0f03721245d 5.1.2-release
7c00e5b6cb3d95712e9d8e29277c805bca2bda90 5.1.3-release
+7b6b020fd5ad9a8dc3670c5c92d1ca92e55fc485 5.1.4-release
+2ea47f358b171178eb9a95503a1670d519c2886f 5.1.5-release
+04538b8157c1f5cdacd9403f0a395452d4a93689 5.1.6-release
diff --git a/autobuild.xml b/autobuild.xml
index a06ec14fd3..fb45343440 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -1692,11 +1692,11 @@
<key>darwin</key>
<map>
<key>archive</key>
- <map>
+ <map>
<key>hash</key>
- <string>7b769c4284bdbd5fce536395d1eab695</string>
+ <string>3855bd40f950e3c22739ae8f3ee2afc9</string>
<key>url</key>
- <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4054/11304/kdu-7.9.1.504041-darwin-504041.tar.bz2</string>
+ <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/15258/98444/kdu-7.10.4.513518-darwin-513518.tar.bz2</string>
</map>
<key>name</key>
<string>darwin</string>
@@ -1705,10 +1705,10 @@
<map>
<key>archive</key>
<map>
- <key>hash</key>
- <string>a48db5cf79a4631090bfc968572d9953</string>
+ <key>hash</key>
+ <string>d1521becaf21bf7233173722af63f57d</string>
<key>url</key>
- <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4052/11292/kdu-7.9.1.504041-darwin64-504041.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>
@@ -1717,10 +1717,10 @@
<map>
<key>archive</key>
<map>
- <key>hash</key>
- <string>ed952c0cb86329e63a8db190953962d8</string>
+ <key>hash</key>
+ <string>43d7a6a69a54534a736f132e9c81795b</string>
<key>url</key>
- <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/kdu_3p-update-kdu/rev/296932/arch/Linux/installer/kdu-7.2.296932-linux-296932.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>
@@ -1730,9 +1730,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>99b0b22f87cebdd02c4cc954a7b3b465</string>
+ <string>a705a665810a71e7b0114a97ae9a2224</string>
<key>url</key>
- <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4053/11298/kdu-7.9.1.504041-linux64-504041.tar.bz2</string>
+ <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/15256/98457/kdu-7.10.4.513518-linux64-513518.tar.bz2</string>
</map>
<key>name</key>
<string>linux64</string>
@@ -1742,9 +1742,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>f3ff5982b3b5f02738044432dd77a2c1</string>
+ <string>0e5b37a03a3f873d15142473b193ec5f</string>
<key>url</key>
- <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4055/11310/kdu-7.9.1.504041-windows-504041.tar.bz2</string>
+ <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/15259/98463/kdu-7.10.4.513518-windows-513518.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -1752,18 +1752,18 @@
<key>windows64</key>
<map>
<key>archive</key>
- <map>
+ <map>
<key>hash</key>
- <string>3010fa35f412b36296342b07de06f1ca</string>
+ <string>da3b1ea90797b189d80ab5d50fdf05d4</string>
<key>url</key>
- <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4056/11316/kdu-7.9.1.504041-windows64-504041.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>
</map>
</map>
<key>version</key>
- <string>7.9.1.504041</string>
+ <string>7.A.4.513518</string>
</map>
<key>libhunspell</key>
<map>
diff --git a/doc/contributions.txt b/doc/contributions.txt
index 92198918d3..039d00cbbf 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -218,6 +218,9 @@ Ansariel Hiller
MAINT-7899
STORM-2105
STORM-2151
+ MAINT-6917
+ MAINT-8085
+ STORM-2122
Aralara Rajal
Arare Chantilly
CHUIBUG-191
diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp
index 2cf86bb4fe..3f2fcce429 100644
--- a/indra/llappearance/lltexlayer.cpp
+++ b/indra/llappearance/lltexlayer.cpp
@@ -1577,7 +1577,12 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
}
alpha_data = new U8[width * height];
mAlphaCache[cache_index] = alpha_data;
- glReadPixels(x, y, width, height, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_data);
+
+ // nSight doesn't support use of glReadPixels
+ if (!LLRender::sNsightDebugSupport)
+ {
+ glReadPixels(x, y, width, height, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_data);
+ }
}
getTexLayerSet()->getAvatarAppearance()->dirtyMesh();
diff --git a/indra/llappearance/llwearable.cpp b/indra/llappearance/llwearable.cpp
index 63069adcc8..6079913a8e 100644
--- a/indra/llappearance/llwearable.cpp
+++ b/indra/llappearance/llwearable.cpp
@@ -184,7 +184,7 @@ void LLWearable::createLayers(S32 te, LLAvatarAppearance *avatarp)
{
LLTexLayerSet *layer_set = NULL;
const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)te);
- if (texture_dict->mIsUsedByBakedTexture)
+ if (texture_dict && texture_dict->mIsUsedByBakedTexture)
{
const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
@@ -197,7 +197,7 @@ void LLWearable::createLayers(S32 te, LLAvatarAppearance *avatarp)
}
else
{
- LL_ERRS() << "could not find layerset for LTO in wearable!" << LL_ENDL;
+ LL_WARNS() << "could not find layerset for LTO in wearable!" << LL_ENDL;
}
}
@@ -437,7 +437,13 @@ LLWearable::EImportResult LLWearable::importStream( std::istream& input_stream,
LL_WARNS() << "Bad Wearable asset: bad texture, #" << i << LL_ENDL;
return LLWearable::FAILURE;
}
-
+
+ if (te >= ETextureIndex::TEX_NUM_INDICES) //createLayers() converts to ETextureIndex
+ {
+ LL_WARNS() << "Bad Wearable asset: bad texture index: " << te << LL_ENDL;
+ return LLWearable::FAILURE;
+ }
+
if( !LLUUID::validate( uuid_buffer ) )
{
LL_WARNS() << "Bad Wearable asset: bad texture uuid: "
diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp
index 8aa41035b9..fc203f78e1 100644
--- a/indra/llcommon/llfile.cpp
+++ b/indra/llcommon/llfile.cpp
@@ -258,7 +258,7 @@ int LLFile::remove(const std::string& filename, int supress_error)
return warnif("remove", filename, rc, supress_error);
}
-int LLFile::rename(const std::string& filename, const std::string& newname)
+int LLFile::rename(const std::string& filename, const std::string& newname, int supress_error)
{
#if LL_WINDOWS
std::string utf8filename = filename;
@@ -269,7 +269,7 @@ int LLFile::rename(const std::string& filename, const std::string& newname)
#else
int rc = ::rename(filename.c_str(),newname.c_str());
#endif
- return warnif(STRINGIZE("rename to '" << newname << "' from"), filename, rc);
+ return warnif(STRINGIZE("rename to '" << newname << "' from"), filename, rc, supress_error);
}
bool LLFile::copy(const std::string from, const std::string to)
diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h
index ba935b8714..398938b729 100644
--- a/indra/llcommon/llfile.h
+++ b/indra/llcommon/llfile.h
@@ -74,7 +74,7 @@ public:
static int rmdir(const std::string& filename);
static int remove(const std::string& filename, int supress_error = 0);
- static int rename(const std::string& filename,const std::string& newname);
+ static int rename(const std::string& filename,const std::string& newname, int supress_error = 0);
static bool copy(const std::string from, const std::string to);
static int stat(const std::string& filename,llstat* file_status);
diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp
index 049e962638..b3debf3550 100644
--- a/indra/llcommon/llmemory.cpp
+++ b/indra/llcommon/llmemory.cpp
@@ -57,10 +57,6 @@ U32Kilobytes LLMemory::sAllocatedPageSizeInKB(0);
U32Kilobytes LLMemory::sMaxHeapSizeInKB(U32_MAX);
BOOL LLMemory::sEnableMemoryFailurePrevention = FALSE;
-#if __DEBUG_PRIVATE_MEM__
-LLPrivateMemoryPoolManager::mem_allocation_info_t LLPrivateMemoryPoolManager::sMemAllocationTracker;
-#endif
-
void ll_assert_aligned_func(uintptr_t ptr,U32 alignment)
{
#if defined(LL_WINDOWS) && defined(LL_DEBUG_BUFFER_OVERRUN)
@@ -154,17 +150,12 @@ void LLMemory::logMemoryInfo(BOOL update)
if(update)
{
updateMemoryInfo() ;
- LLPrivateMemoryPoolManager::getInstance()->updateStatistics() ;
}
LL_INFOS() << "Current allocated physical memory(KB): " << sAllocatedMemInKB << LL_ENDL ;
LL_INFOS() << "Current allocated page size (KB): " << sAllocatedPageSizeInKB << LL_ENDL ;
LL_INFOS() << "Current available physical memory(KB): " << sAvailPhysicalMemInKB << LL_ENDL ;
LL_INFOS() << "Current max usable memory(KB): " << sMaxPhysicalMemInKB << LL_ENDL ;
-
- LL_INFOS() << "--- private pool information -- " << LL_ENDL ;
- LL_INFOS() << "Total reserved (KB): " << LLPrivateMemoryPoolManager::getInstance()->mTotalReservedSize / 1024 << LL_ENDL ;
- LL_INFOS() << "Total allocated (KB): " << LLPrivateMemoryPoolManager::getInstance()->mTotalAllocatedSize / 1024 << LL_ENDL ;
}
//return 0: everything is normal;
@@ -356,1729 +347,6 @@ U64 LLMemory::getCurrentRSS()
#endif
-//--------------------------------------------------------------------------------------------------
-//--------------------------------------------------------------------------------------------------
-//minimum slot size and minimal slot size interval
-const U32 ATOMIC_MEM_SLOT = 16 ; //bytes
-
-//minimum block sizes (page size) for small allocation, medium allocation, large allocation
-const U32 MIN_BLOCK_SIZES[LLPrivateMemoryPool::SUPER_ALLOCATION] = {2 << 10, 4 << 10, 16 << 10} ; //
-
-//maximum block sizes for small allocation, medium allocation, large allocation
-const U32 MAX_BLOCK_SIZES[LLPrivateMemoryPool::SUPER_ALLOCATION] = {64 << 10, 1 << 20, 4 << 20} ;
-
-//minimum slot sizes for small allocation, medium allocation, large allocation
-const U32 MIN_SLOT_SIZES[LLPrivateMemoryPool::SUPER_ALLOCATION] = {ATOMIC_MEM_SLOT, 2 << 10, 512 << 10};
-
-//maximum slot sizes for small allocation, medium allocation, large allocation
-const U32 MAX_SLOT_SIZES[LLPrivateMemoryPool::SUPER_ALLOCATION] = {(2 << 10) - ATOMIC_MEM_SLOT, (512 - 2) << 10, 4 << 20};
-
-//size of a block with multiple slots can not exceed CUT_OFF_SIZE
-const U32 CUT_OFF_SIZE = (64 << 10) ; //64 KB
-
-//max number of slots in a block
-const U32 MAX_NUM_SLOTS_IN_A_BLOCK = llmin(MIN_BLOCK_SIZES[0] / ATOMIC_MEM_SLOT, ATOMIC_MEM_SLOT * 8) ;
-
-//-------------------------------------------------------------
-//align val to be integer times of ATOMIC_MEM_SLOT
-U32 align(U32 val)
-{
- U32 aligned = (val / ATOMIC_MEM_SLOT) * ATOMIC_MEM_SLOT ;
- if(aligned < val)
- {
- aligned += ATOMIC_MEM_SLOT ;
- }
-
- return aligned ;
-}
-
-//-------------------------------------------------------------
-//class LLPrivateMemoryPool::LLMemoryBlock
-//-------------------------------------------------------------
-//
-//each memory block could fit for two page sizes: 0.75 * mSlotSize, which starts from the beginning of the memory chunk and grow towards the end of the
-//the block; another is mSlotSize, which starts from the end of the block and grows towards the beginning of the block.
-//
-LLPrivateMemoryPool::LLMemoryBlock::LLMemoryBlock()
-{
- //empty
-}
-
-LLPrivateMemoryPool::LLMemoryBlock::~LLMemoryBlock()
-{
- //empty
-}
-
-//create and initialize a memory block
-void LLPrivateMemoryPool::LLMemoryBlock::init(char* buffer, U32 buffer_size, U32 slot_size)
-{
- mBuffer = buffer ;
- mBufferSize = buffer_size ;
- mSlotSize = slot_size ;
- mTotalSlots = buffer_size / mSlotSize ;
-
- llassert_always(buffer_size / mSlotSize <= MAX_NUM_SLOTS_IN_A_BLOCK) ; //max number is 128
-
- mAllocatedSlots = 0 ;
- mDummySize = 0 ;
-
- //init the bit map.
- //mark free bits
- if(mTotalSlots > 32) //reserve extra space from mBuffer to store bitmap if needed.
- {
- mDummySize = ATOMIC_MEM_SLOT ;
- mTotalSlots -= (mDummySize + mSlotSize - 1) / mSlotSize ;
- mUsageBits = 0 ;
-
- S32 usage_bit_len = (mTotalSlots + 31) / 32 ;
-
- for(S32 i = 0 ; i < usage_bit_len - 1 ; i++)
- {
- *((U32*)mBuffer + i) = 0 ;
- }
- for(S32 i = usage_bit_len - 1 ; i < mDummySize / sizeof(U32) ; i++)
- {
- *((U32*)mBuffer + i) = 0xffffffff ;
- }
-
- if(mTotalSlots & 31)
- {
- *((U32*)mBuffer + usage_bit_len - 2) = (0xffffffff << (mTotalSlots & 31)) ;
- }
- }
- else//no extra bitmap space reserved
- {
- mUsageBits = 0 ;
- if(mTotalSlots & 31)
- {
- mUsageBits = (0xffffffff << (mTotalSlots & 31)) ;
- }
- }
-
- mSelf = this ;
- mNext = NULL ;
- mPrev = NULL ;
-
- llassert_always(mTotalSlots > 0) ;
-}
-
-//mark this block to be free with the memory [mBuffer, mBuffer + mBufferSize).
-void LLPrivateMemoryPool::LLMemoryBlock::setBuffer(char* buffer, U32 buffer_size)
-{
- mBuffer = buffer ;
- mBufferSize = buffer_size ;
- mSelf = NULL ;
- mTotalSlots = 0 ; //set the block is free.
-}
-
-//reserve a slot
-char* LLPrivateMemoryPool::LLMemoryBlock::allocate()
-{
- llassert_always(mAllocatedSlots < mTotalSlots) ;
-
- //find a free slot
- U32* bits = NULL ;
- U32 k = 0 ;
- if(mUsageBits != 0xffffffff)
- {
- bits = &mUsageBits ;
- }
- else if(mDummySize > 0)//go to extra space
- {
- for(S32 i = 0 ; i < mDummySize / sizeof(U32); i++)
- {
- if(*((U32*)mBuffer + i) != 0xffffffff)
- {
- bits = (U32*)mBuffer + i ;
- k = i + 1 ;
- break ;
- }
- }
- }
- S32 idx = 0 ;
- U32 tmp = *bits ;
- for(; tmp & 1 ; tmp >>= 1, idx++) ;
-
- //set the slot reserved
- if(!idx)
- {
- *bits |= 1 ;
- }
- else
- {
- *bits |= (1 << idx) ;
- }
-
- mAllocatedSlots++ ;
-
- return mBuffer + mDummySize + (k * 32 + idx) * mSlotSize ;
-}
-
-//free a slot
-void LLPrivateMemoryPool::LLMemoryBlock::freeMem(void* addr)
-{
- //bit index
- uintptr_t idx = ((uintptr_t)addr - (uintptr_t)mBuffer - mDummySize) / mSlotSize ;
-
- U32* bits = &mUsageBits ;
- if(idx >= 32)
- {
- bits = (U32*)mBuffer + (idx - 32) / 32 ;
- }
-
- //reset the bit
- if(idx & 31)
- {
- *bits &= ~(1 << (idx & 31)) ;
- }
- else
- {
- *bits &= ~1 ;
- }
-
- mAllocatedSlots-- ;
-}
-
-//for debug use: reset the entire bitmap.
-void LLPrivateMemoryPool::LLMemoryBlock::resetBitMap()
-{
- for(S32 i = 0 ; i < mDummySize / sizeof(U32) ; i++)
- {
- *((U32*)mBuffer + i) = 0 ;
- }
- mUsageBits = 0 ;
-}
-//-------------------------------------------------------------------
-//class LLMemoryChunk
-//--------------------------------------------------------------------
-LLPrivateMemoryPool::LLMemoryChunk::LLMemoryChunk()
-{
- //empty
-}
-
-LLPrivateMemoryPool::LLMemoryChunk::~LLMemoryChunk()
-{
- //empty
-}
-
-//create and init a memory chunk
-void LLPrivateMemoryPool::LLMemoryChunk::init(char* buffer, U32 buffer_size, U32 min_slot_size, U32 max_slot_size, U32 min_block_size, U32 max_block_size)
-{
- mBuffer = buffer ;
- mBufferSize = buffer_size ;
- mAlloatedSize = 0 ;
-
- mMetaBuffer = mBuffer + sizeof(LLMemoryChunk) ;
-
- mMinBlockSize = min_block_size; //page size
- mMinSlotSize = min_slot_size;
- mMaxSlotSize = max_slot_size ;
- mBlockLevels = mMaxSlotSize / mMinSlotSize ;
- mPartitionLevels = max_block_size / mMinBlockSize + 1 ;
-
- S32 max_num_blocks = (buffer_size - sizeof(LLMemoryChunk) - mBlockLevels * sizeof(LLMemoryBlock*) - mPartitionLevels * sizeof(LLMemoryBlock*)) /
- (mMinBlockSize + sizeof(LLMemoryBlock)) ;
- //meta data space
- mBlocks = (LLMemoryBlock*)mMetaBuffer ; //space reserved for all memory blocks.
- mAvailBlockList = (LLMemoryBlock**)((char*)mBlocks + sizeof(LLMemoryBlock) * max_num_blocks) ;
- mFreeSpaceList = (LLMemoryBlock**)((char*)mAvailBlockList + sizeof(LLMemoryBlock*) * mBlockLevels) ;
-
- //data buffer, which can be used for allocation
- mDataBuffer = (char*)mFreeSpaceList + sizeof(LLMemoryBlock*) * mPartitionLevels ;
-
- //alignmnet
- mDataBuffer = mBuffer + align(mDataBuffer - mBuffer) ;
-
- //init
- for(U32 i = 0 ; i < mBlockLevels; i++)
- {
- mAvailBlockList[i] = NULL ;
- }
- for(U32 i = 0 ; i < mPartitionLevels ; i++)
- {
- mFreeSpaceList[i] = NULL ;
- }
-
- //assign the entire chunk to the first block
- mBlocks[0].mPrev = NULL ;
- mBlocks[0].mNext = NULL ;
- mBlocks[0].setBuffer(mDataBuffer, buffer_size - (mDataBuffer - mBuffer)) ;
- addToFreeSpace(&mBlocks[0]) ;
-
- mNext = NULL ;
- mPrev = NULL ;
-}
-
-//static
-U32 LLPrivateMemoryPool::LLMemoryChunk::getMaxOverhead(U32 data_buffer_size, U32 min_slot_size,
- U32 max_slot_size, U32 min_block_size, U32 max_block_size)
-{
- //for large allocations, reserve some extra memory for meta data to avoid wasting much
- if(data_buffer_size / min_slot_size < 64) //large allocations
- {
- U32 overhead = sizeof(LLMemoryChunk) + (data_buffer_size / min_block_size) * sizeof(LLMemoryBlock) +
- sizeof(LLMemoryBlock*) * (max_slot_size / min_slot_size) + sizeof(LLMemoryBlock*) * (max_block_size / min_block_size + 1) ;
-
- //round to integer times of min_block_size
- overhead = ((overhead + min_block_size - 1) / min_block_size) * min_block_size ;
- return overhead ;
- }
- else
- {
- return 0 ; //do not reserve extra overhead if for small allocations
- }
-}
-
-char* LLPrivateMemoryPool::LLMemoryChunk::allocate(U32 size)
-{
- if(mMinSlotSize > size)
- {
- size = mMinSlotSize ;
- }
- if(mAlloatedSize + size > mBufferSize - (mDataBuffer - mBuffer))
- {
- return NULL ; //no enough space in this chunk.
- }
-
- char* p = NULL ;
- U32 blk_idx = getBlockLevel(size);
-
- LLMemoryBlock* blk = NULL ;
-
- //check if there is free block available
- if(mAvailBlockList[blk_idx])
- {
- blk = mAvailBlockList[blk_idx] ;
- p = blk->allocate() ;
-
- if(blk->isFull())
- {
- popAvailBlockList(blk_idx) ;
- }
- }
-
- //ask for a new block
- if(!p)
- {
- blk = addBlock(blk_idx) ;
- if(blk)
- {
- p = blk->allocate() ;
-
- if(blk->isFull())
- {
- popAvailBlockList(blk_idx) ;
- }
- }
- }
-
- //ask for space from larger blocks
- if(!p)
- {
- for(S32 i = blk_idx + 1 ; i < mBlockLevels; i++)
- {
- if(mAvailBlockList[i])
- {
- blk = mAvailBlockList[i] ;
- p = blk->allocate() ;
-
- if(blk->isFull())
- {
- popAvailBlockList(i) ;
- }
- break ;
- }
- }
- }
-
- if(p && blk)
- {
- mAlloatedSize += blk->getSlotSize() ;
- }
- return p ;
-}
-
-void LLPrivateMemoryPool::LLMemoryChunk::freeMem(void* addr)
-{
- U32 blk_idx = getPageIndex((uintptr_t)addr) ;
- LLMemoryBlock* blk = (LLMemoryBlock*)(mMetaBuffer + blk_idx * sizeof(LLMemoryBlock)) ;
- blk = blk->mSelf ;
-
- bool was_full = blk->isFull() ;
- blk->freeMem(addr) ;
- mAlloatedSize -= blk->getSlotSize() ;
-
- if(blk->empty())
- {
- removeBlock(blk) ;
- }
- else if(was_full)
- {
- addToAvailBlockList(blk) ;
- }
-}
-
-bool LLPrivateMemoryPool::LLMemoryChunk::empty()
-{
- return !mAlloatedSize ;
-}
-
-bool LLPrivateMemoryPool::LLMemoryChunk::containsAddress(const char* addr) const
-{
- return (uintptr_t)mBuffer <= (uintptr_t)addr && (uintptr_t)mBuffer + mBufferSize > (uintptr_t)addr ;
-}
-
-//debug use
-void LLPrivateMemoryPool::LLMemoryChunk::dump()
-{
-#if 0
- //sanity check
- //for(S32 i = 0 ; i < mBlockLevels ; i++)
- //{
- // LLMemoryBlock* blk = mAvailBlockList[i] ;
- // while(blk)
- // {
- // blk_list.push_back(blk) ;
- // blk = blk->mNext ;
- // }
- //}
- for(S32 i = 0 ; i < mPartitionLevels ; i++)
- {
- LLMemoryBlock* blk = mFreeSpaceList[i] ;
- while(blk)
- {
- blk_list.push_back(blk) ;
- blk = blk->mNext ;
- }
- }
-
- std::sort(blk_list.begin(), blk_list.end(), LLMemoryBlock::CompareAddress());
-
- U32 total_size = blk_list[0]->getBufferSize() ;
- for(U32 i = 1 ; i < blk_list.size(); i++)
- {
- total_size += blk_list[i]->getBufferSize() ;
- if((uintptr_t)blk_list[i]->getBuffer() < (uintptr_t)blk_list[i-1]->getBuffer() + blk_list[i-1]->getBufferSize())
- {
- LL_ERRS() << "buffer corrupted." << LL_ENDL ;
- }
- }
-
- llassert_always(total_size + mMinBlockSize >= mBufferSize - ((uintptr_t)mDataBuffer - (uintptr_t)mBuffer)) ;
-
- U32 blk_num = (mBufferSize - (mDataBuffer - mBuffer)) / mMinBlockSize ;
- for(U32 i = 0 ; i < blk_num ; )
- {
- LLMemoryBlock* blk = &mBlocks[i] ;
- if(blk->mSelf)
- {
- U32 end = blk->getBufferSize() / mMinBlockSize ;
- for(U32 j = 0 ; j < end ; j++)
- {
- llassert_always(blk->mSelf == blk || !blk->mSelf) ;
- }
- i += end ;
- }
- else
- {
- LL_ERRS() << "gap happens" << LL_ENDL ;
- }
- }
-#endif
-#if 0
- LL_INFOS() << "---------------------------" << LL_ENDL ;
- LL_INFOS() << "Chunk buffer: " << (uintptr_t)getBuffer() << " size: " << getBufferSize() << LL_ENDL ;
-
- LL_INFOS() << "available blocks ... " << LL_ENDL ;
- for(S32 i = 0 ; i < mBlockLevels ; i++)
- {
- LLMemoryBlock* blk = mAvailBlockList[i] ;
- while(blk)
- {
- LL_INFOS() << "blk buffer " << (uintptr_t)blk->getBuffer() << " size: " << blk->getBufferSize() << LL_ENDL ;
- blk = blk->mNext ;
- }
- }
-
- LL_INFOS() << "free blocks ... " << LL_ENDL ;
- for(S32 i = 0 ; i < mPartitionLevels ; i++)
- {
- LLMemoryBlock* blk = mFreeSpaceList[i] ;
- while(blk)
- {
- LL_INFOS() << "blk buffer " << (uintptr_t)blk->getBuffer() << " size: " << blk->getBufferSize() << LL_ENDL ;
- blk = blk->mNext ;
- }
- }
-#endif
-}
-
-//compute the size for a block, the size is round to integer times of mMinBlockSize.
-U32 LLPrivateMemoryPool::LLMemoryChunk::calcBlockSize(U32 slot_size)
-{
- //
- //Note: we try to make a block to have 32 slots if the size is not over 32 pages
- //32 is the number of bits of an integer in a 32-bit system
- //
-
- U32 block_size;
- U32 cut_off_size = llmin(CUT_OFF_SIZE, (U32)(mMinBlockSize << 5)) ;
-
- if((slot_size << 5) <= mMinBlockSize)//for small allocations, return one page
- {
- block_size = mMinBlockSize ;
- }
- else if(slot_size >= cut_off_size)//for large allocations, return one-slot block
- {
- block_size = (slot_size / mMinBlockSize) * mMinBlockSize ;
- if(block_size < slot_size)
- {
- block_size += mMinBlockSize ;
- }
- }
- else //medium allocations
- {
- if((slot_size << 5) >= cut_off_size)
- {
- block_size = cut_off_size ;
- }
- else
- {
- block_size = ((slot_size << 5) / mMinBlockSize) * mMinBlockSize ;
- }
- }
-
- llassert_always(block_size >= slot_size) ;
-
- return block_size ;
-}
-
-//create a new block in the chunk
-LLPrivateMemoryPool::LLMemoryBlock* LLPrivateMemoryPool::LLMemoryChunk::addBlock(U32 blk_idx)
-{
- U32 slot_size = mMinSlotSize * (blk_idx + 1) ;
- U32 preferred_block_size = calcBlockSize(slot_size) ;
- U16 idx = getPageLevel(preferred_block_size);
- LLMemoryBlock* blk = NULL ;
-
- if(mFreeSpaceList[idx])//if there is free slot for blk_idx
- {
- blk = createNewBlock(mFreeSpaceList[idx], preferred_block_size, slot_size, blk_idx) ;
- }
- else if(mFreeSpaceList[mPartitionLevels - 1]) //search free pool
- {
- blk = createNewBlock(mFreeSpaceList[mPartitionLevels - 1], preferred_block_size, slot_size, blk_idx) ;
- }
- else //search for other non-preferred but enough space slot.
- {
- S32 min_idx = 0 ;
- if(slot_size > mMinBlockSize)
- {
- min_idx = getPageLevel(slot_size) ;
- }
- for(S32 i = (S32)idx - 1 ; i >= min_idx ; i--) //search the small slots first
- {
- if(mFreeSpaceList[i])
- {
- U32 new_preferred_block_size = mFreeSpaceList[i]->getBufferSize();
- new_preferred_block_size = (new_preferred_block_size / mMinBlockSize) * mMinBlockSize ; //round to integer times of mMinBlockSize.
-
- //create a NEW BLOCK THERE.
- if(new_preferred_block_size >= slot_size) //at least there is space for one slot.
- {
-
- blk = createNewBlock(mFreeSpaceList[i], new_preferred_block_size, slot_size, blk_idx) ;
- }
- break ;
- }
- }
-
- if(!blk)
- {
- for(U16 i = idx + 1 ; i < mPartitionLevels - 1; i++) //search the large slots
- {
- if(mFreeSpaceList[i])
- {
- //create a NEW BLOCK THERE.
- blk = createNewBlock(mFreeSpaceList[i], preferred_block_size, slot_size, blk_idx) ;
- break ;
- }
- }
- }
- }
-
- return blk ;
-}
-
-//create a new block at the designed location
-LLPrivateMemoryPool::LLMemoryBlock* LLPrivateMemoryPool::LLMemoryChunk::createNewBlock(LLMemoryBlock* blk, U32 buffer_size, U32 slot_size, U32 blk_idx)
-{
- //unlink from the free space
- removeFromFreeSpace(blk) ;
-
- //check the rest space
- U32 new_free_blk_size = blk->getBufferSize() - buffer_size ;
- if(new_free_blk_size < mMinBlockSize) //can not partition the memory into size smaller than mMinBlockSize
- {
- new_free_blk_size = 0 ; //discard the last small extra space.
- }
-
- //add the rest space back to the free list
- if(new_free_blk_size > 0) //blk still has free space
- {
- LLMemoryBlock* next_blk = blk + (buffer_size / mMinBlockSize) ;
- next_blk->mPrev = NULL ;
- next_blk->mNext = NULL ;
- next_blk->setBuffer(blk->getBuffer() + buffer_size, new_free_blk_size) ;
- addToFreeSpace(next_blk) ;
- }
-
- blk->init(blk->getBuffer(), buffer_size, slot_size) ;
- //insert to the available block list...
- mAvailBlockList[blk_idx] = blk ;
-
- //mark the address map: all blocks covered by this block space pointing back to this block.
- U32 end = (buffer_size / mMinBlockSize) ;
- for(U32 i = 1 ; i < end ; i++)
- {
- (blk + i)->mSelf = blk ;
- }
-
- return blk ;
-}
-
-//delete a block, release the block to the free pool.
-void LLPrivateMemoryPool::LLMemoryChunk::removeBlock(LLMemoryBlock* blk)
-{
- //remove from the available block list
- if(blk->mPrev)
- {
- blk->mPrev->mNext = blk->mNext ;
- }
- if(blk->mNext)
- {
- blk->mNext->mPrev = blk->mPrev ;
- }
- U32 blk_idx = getBlockLevel(blk->getSlotSize());
- if(mAvailBlockList[blk_idx] == blk)
- {
- mAvailBlockList[blk_idx] = blk->mNext ;
- }
-
- blk->mNext = NULL ;
- blk->mPrev = NULL ;
-
- //mark it free
- blk->setBuffer(blk->getBuffer(), blk->getBufferSize()) ;
-
-#if 1
- //merge blk with neighbors if possible
- if(blk->getBuffer() > mDataBuffer) //has the left neighbor
- {
- if((blk - 1)->mSelf->isFree())
- {
- LLMemoryBlock* left_blk = (blk - 1)->mSelf ;
- removeFromFreeSpace((blk - 1)->mSelf);
- left_blk->setBuffer(left_blk->getBuffer(), left_blk->getBufferSize() + blk->getBufferSize()) ;
- blk = left_blk ;
- }
- }
- if(blk->getBuffer() + blk->getBufferSize() <= mBuffer + mBufferSize - mMinBlockSize) //has the right neighbor
- {
- U32 d = blk->getBufferSize() / mMinBlockSize ;
- if((blk + d)->isFree())
- {
- LLMemoryBlock* right_blk = blk + d ;
- removeFromFreeSpace(blk + d) ;
- blk->setBuffer(blk->getBuffer(), blk->getBufferSize() + right_blk->getBufferSize()) ;
- }
- }
-#endif
-
- addToFreeSpace(blk) ;
-
- return ;
-}
-
-//the top block in the list is full, pop it out of the list
-void LLPrivateMemoryPool::LLMemoryChunk::popAvailBlockList(U32 blk_idx)
-{
- if(mAvailBlockList[blk_idx])
- {
- LLMemoryBlock* next = mAvailBlockList[blk_idx]->mNext ;
- if(next)
- {
- next->mPrev = NULL ;
- }
- mAvailBlockList[blk_idx]->mPrev = NULL ;
- mAvailBlockList[blk_idx]->mNext = NULL ;
- mAvailBlockList[blk_idx] = next ;
- }
-}
-
-//add the block back to the free pool
-void LLPrivateMemoryPool::LLMemoryChunk::addToFreeSpace(LLMemoryBlock* blk)
-{
- llassert_always(!blk->mPrev) ;
- llassert_always(!blk->mNext) ;
-
- U16 free_idx = blk->getBufferSize() / mMinBlockSize - 1;
-
- (blk + free_idx)->mSelf = blk ; //mark the end pointing back to the head.
- free_idx = llmin(free_idx, (U16)(mPartitionLevels - 1)) ;
-
- blk->mNext = mFreeSpaceList[free_idx] ;
- if(mFreeSpaceList[free_idx])
- {
- mFreeSpaceList[free_idx]->mPrev = blk ;
- }
- mFreeSpaceList[free_idx] = blk ;
- blk->mPrev = NULL ;
- blk->mSelf = blk ;
-
- return ;
-}
-
-//remove the space from the free pool
-void LLPrivateMemoryPool::LLMemoryChunk::removeFromFreeSpace(LLMemoryBlock* blk)
-{
- U16 free_idx = blk->getBufferSize() / mMinBlockSize - 1;
- free_idx = llmin(free_idx, (U16)(mPartitionLevels - 1)) ;
-
- if(mFreeSpaceList[free_idx] == blk)
- {
- mFreeSpaceList[free_idx] = blk->mNext ;
- }
- if(blk->mPrev)
- {
- blk->mPrev->mNext = blk->mNext ;
- }
- if(blk->mNext)
- {
- blk->mNext->mPrev = blk->mPrev ;
- }
- blk->mNext = NULL ;
- blk->mPrev = NULL ;
- blk->mSelf = NULL ;
-
- return ;
-}
-
-void LLPrivateMemoryPool::LLMemoryChunk::addToAvailBlockList(LLMemoryBlock* blk)
-{
- llassert_always(!blk->mPrev) ;
- llassert_always(!blk->mNext) ;
-
- U32 blk_idx = getBlockLevel(blk->getSlotSize());
-
- blk->mNext = mAvailBlockList[blk_idx] ;
- if(blk->mNext)
- {
- blk->mNext->mPrev = blk ;
- }
- blk->mPrev = NULL ;
- mAvailBlockList[blk_idx] = blk ;
-
- return ;
-}
-
-U32 LLPrivateMemoryPool::LLMemoryChunk::getPageIndex(uintptr_t addr)
-{
- return (addr - (uintptr_t)mDataBuffer) / mMinBlockSize ;
-}
-
-//for mAvailBlockList
-U32 LLPrivateMemoryPool::LLMemoryChunk::getBlockLevel(U32 size)
-{
- llassert(size >= mMinSlotSize && size <= mMaxSlotSize) ;
-
- //start from 0
- return (size + mMinSlotSize - 1) / mMinSlotSize - 1 ;
-}
-
-//for mFreeSpaceList
-U16 LLPrivateMemoryPool::LLMemoryChunk::getPageLevel(U32 size)
-{
- //start from 0
- U16 level = size / mMinBlockSize - 1 ;
- if(level >= mPartitionLevels)
- {
- level = mPartitionLevels - 1 ;
- }
- return level ;
-}
-
-//-------------------------------------------------------------------
-//class LLPrivateMemoryPool
-//--------------------------------------------------------------------
-const U32 CHUNK_SIZE = 4 << 20 ; //4 MB
-const U32 LARGE_CHUNK_SIZE = 4 * CHUNK_SIZE ; //16 MB
-LLPrivateMemoryPool::LLPrivateMemoryPool(S32 type, U32 max_pool_size) :
- mMutexp(NULL),
- mReservedPoolSize(0),
- mHashFactor(1),
- mType(type),
- mMaxPoolSize(max_pool_size)
-{
- if(type == STATIC_THREADED || type == VOLATILE_THREADED)
- {
- mMutexp = new LLMutex(NULL) ;
- }
-
- for(S32 i = 0 ; i < SUPER_ALLOCATION ; i++)
- {
- mChunkList[i] = NULL ;
- }
-
- mNumOfChunks = 0 ;
-}
-
-LLPrivateMemoryPool::~LLPrivateMemoryPool()
-{
- destroyPool();
- delete mMutexp ;
-}
-
-char* LLPrivateMemoryPool::allocate(U32 size)
-{
- if(!size)
- {
- return NULL ;
- }
-
- //if the asked size larger than MAX_BLOCK_SIZE, fetch from heap directly, the pool does not manage it
- if(size >= CHUNK_SIZE)
- {
- return (char*)ll_aligned_malloc_16(size) ;
- }
-
- char* p = NULL ;
-
- //find the appropriate chunk
- S32 chunk_idx = getChunkIndex(size) ;
-
- lock() ;
-
- LLMemoryChunk* chunk = mChunkList[chunk_idx];
- while(chunk)
- {
- if((p = chunk->allocate(size)))
- {
- break ;
- }
- chunk = chunk->mNext ;
- }
-
- //fetch new memory chunk
- if(!p)
- {
- if(mReservedPoolSize + CHUNK_SIZE > mMaxPoolSize)
- {
- chunk = mChunkList[chunk_idx];
- while(chunk)
- {
- if((p = chunk->allocate(size)))
- {
- break ;
- }
- chunk = chunk->mNext ;
- }
- }
- else
- {
- chunk = addChunk(chunk_idx) ;
- if(chunk)
- {
- p = chunk->allocate(size) ;
- }
- }
- }
-
- unlock() ;
-
- if(!p) //to get memory from the private pool failed, try the heap directly
- {
- static bool to_log = true ;
-
- if(to_log)
- {
- LL_WARNS() << "The memory pool overflows, now using heap directly!" << LL_ENDL ;
- to_log = false ;
- }
-
- return (char*)ll_aligned_malloc_16(size) ;
- }
-
- return p ;
-}
-
-void LLPrivateMemoryPool::freeMem(void* addr)
-{
- if(!addr)
- {
- return ;
- }
-
- lock() ;
-
- LLMemoryChunk* chunk = findChunk((char*)addr) ;
-
- if(!chunk)
- {
- ll_aligned_free_16(addr) ; //release from heap
- }
- else
- {
- chunk->freeMem(addr) ;
-
- if(chunk->empty())
- {
- removeChunk(chunk) ;
- }
- }
-
- unlock() ;
-}
-
-void LLPrivateMemoryPool::dump()
-{
-}
-
-U32 LLPrivateMemoryPool::getTotalAllocatedSize()
-{
- U32 total_allocated = 0 ;
-
- LLMemoryChunk* chunk ;
- for(S32 i = 0 ; i < SUPER_ALLOCATION ; i++)
- {
- chunk = mChunkList[i];
- while(chunk)
- {
- total_allocated += chunk->getAllocatedSize() ;
- chunk = chunk->mNext ;
- }
- }
-
- return total_allocated ;
-}
-
-void LLPrivateMemoryPool::lock()
-{
- if(mMutexp)
- {
- mMutexp->lock() ;
- }
-}
-
-void LLPrivateMemoryPool::unlock()
-{
- if(mMutexp)
- {
- mMutexp->unlock() ;
- }
-}
-
-S32 LLPrivateMemoryPool::getChunkIndex(U32 size)
-{
- S32 i ;
- for(i = 0 ; size > MAX_SLOT_SIZES[i]; i++);
-
- llassert_always(i < SUPER_ALLOCATION);
-
- return i ;
-}
-
-//destroy the entire pool
-void LLPrivateMemoryPool::destroyPool()
-{
- lock() ;
-
- if(mNumOfChunks > 0)
- {
- LL_WARNS() << "There is some memory not freed when destroy the memory pool!" << LL_ENDL ;
- }
-
- mNumOfChunks = 0 ;
- mChunkHashList.clear() ;
- mHashFactor = 1 ;
- for(S32 i = 0 ; i < SUPER_ALLOCATION ; i++)
- {
- mChunkList[i] = NULL ;
- }
-
- unlock() ;
-}
-
-bool LLPrivateMemoryPool::checkSize(U32 asked_size)
-{
- if(mReservedPoolSize + asked_size > mMaxPoolSize)
- {
- LL_INFOS() << "Max pool size: " << mMaxPoolSize << LL_ENDL ;
- LL_INFOS() << "Total reserved size: " << mReservedPoolSize + asked_size << LL_ENDL ;
- LL_INFOS() << "Total_allocated Size: " << getTotalAllocatedSize() << LL_ENDL ;
-
- //LL_ERRS() << "The pool is overflowing..." << LL_ENDL ;
-
- return false ;
- }
-
- return true ;
-}
-
-LLPrivateMemoryPool::LLMemoryChunk* LLPrivateMemoryPool::addChunk(S32 chunk_index)
-{
- U32 preferred_size ;
- U32 overhead ;
- if(chunk_index < LARGE_ALLOCATION)
- {
- preferred_size = CHUNK_SIZE ; //4MB
- overhead = LLMemoryChunk::getMaxOverhead(preferred_size, MIN_SLOT_SIZES[chunk_index],
- MAX_SLOT_SIZES[chunk_index], MIN_BLOCK_SIZES[chunk_index], MAX_BLOCK_SIZES[chunk_index]) ;
- }
- else
- {
- preferred_size = LARGE_CHUNK_SIZE ; //16MB
- overhead = LLMemoryChunk::getMaxOverhead(preferred_size, MIN_SLOT_SIZES[chunk_index],
- MAX_SLOT_SIZES[chunk_index], MIN_BLOCK_SIZES[chunk_index], MAX_BLOCK_SIZES[chunk_index]) ;
- }
-
- if(!checkSize(preferred_size + overhead))
- {
- return NULL ;
- }
-
- mReservedPoolSize += preferred_size + overhead ;
-
- char* buffer = (char*)ll_aligned_malloc_16(preferred_size + overhead) ;
- if(!buffer)
- {
- return NULL ;
- }
-
- LLMemoryChunk* chunk = new (buffer) LLMemoryChunk() ;
- chunk->init(buffer, preferred_size + overhead, MIN_SLOT_SIZES[chunk_index],
- MAX_SLOT_SIZES[chunk_index], MIN_BLOCK_SIZES[chunk_index], MAX_BLOCK_SIZES[chunk_index]) ;
-
- //add to the tail of the linked list
- {
- if(!mChunkList[chunk_index])
- {
- mChunkList[chunk_index] = chunk ;
- }
- else
- {
- LLMemoryChunk* cur = mChunkList[chunk_index] ;
- while(cur->mNext)
- {
- cur = cur->mNext ;
- }
- cur->mNext = chunk ;
- chunk->mPrev = cur ;
- }
- }
-
- //insert into the hash table
- addToHashTable(chunk) ;
-
- mNumOfChunks++;
-
- return chunk ;
-}
-
-void LLPrivateMemoryPool::removeChunk(LLMemoryChunk* chunk)
-{
- if(!chunk)
- {
- return ;
- }
-
- //remove from the linked list
- for(S32 i = 0 ; i < SUPER_ALLOCATION ; i++)
- {
- if(mChunkList[i] == chunk)
- {
- mChunkList[i] = chunk->mNext ;
- }
- }
-
- if(chunk->mPrev)
- {
- chunk->mPrev->mNext = chunk->mNext ;
- }
- if(chunk->mNext)
- {
- chunk->mNext->mPrev = chunk->mPrev ;
- }
-
- //remove from the hash table
- removeFromHashTable(chunk) ;
-
- mNumOfChunks--;
- mReservedPoolSize -= chunk->getBufferSize() ;
-
- //release memory
- ll_aligned_free_16(chunk->getBuffer()) ;
-}
-
-U16 LLPrivateMemoryPool::findHashKey(const char* addr)
-{
- return (((uintptr_t)addr) / CHUNK_SIZE) % mHashFactor ;
-}
-
-LLPrivateMemoryPool::LLMemoryChunk* LLPrivateMemoryPool::findChunk(const char* addr)
-{
- U16 key = findHashKey(addr) ;
- if(mChunkHashList.size() <= key)
- {
- return NULL ;
- }
-
- return mChunkHashList[key].findChunk(addr) ;
-}
-
-void LLPrivateMemoryPool::addToHashTable(LLMemoryChunk* chunk)
-{
- static const U16 HASH_FACTORS[] = {41, 83, 193, 317, 419, 523, 719, 997, 1523, 0xFFFF};
-
- U16 i ;
- if(mChunkHashList.empty())
- {
- mHashFactor = HASH_FACTORS[0] ;
- rehash() ;
- }
-
- U16 start_key = findHashKey(chunk->getBuffer()) ;
- U16 end_key = findHashKey(chunk->getBuffer() + chunk->getBufferSize() - 1) ;
- bool need_rehash = false ;
-
- if(mChunkHashList[start_key].hasElement(chunk))
- {
- return; //already inserted.
- }
- need_rehash = mChunkHashList[start_key].add(chunk) ;
-
- if(start_key == end_key && !need_rehash)
- {
- return ; //done
- }
-
- if(!need_rehash)
- {
- need_rehash = mChunkHashList[end_key].add(chunk) ;
- }
-
- if(!need_rehash)
- {
- if(end_key < start_key)
- {
- need_rehash = fillHashTable(start_key + 1, mHashFactor, chunk) ;
- if(!need_rehash)
- {
- need_rehash = fillHashTable(0, end_key, chunk) ;
- }
- }
- else
- {
- need_rehash = fillHashTable(start_key + 1, end_key, chunk) ;
- }
- }
-
- if(need_rehash)
- {
- i = 0 ;
- while(HASH_FACTORS[i] <= mHashFactor) i++;
-
- mHashFactor = HASH_FACTORS[i] ;
- llassert_always(mHashFactor != 0xFFFF) ;//stop point to prevent endlessly recursive calls
-
- rehash() ;
- }
-}
-
-void LLPrivateMemoryPool::removeFromHashTable(LLMemoryChunk* chunk)
-{
- U16 start_key = findHashKey(chunk->getBuffer()) ;
- U16 end_key = findHashKey(chunk->getBuffer() + chunk->getBufferSize() - 1) ;
-
- mChunkHashList[start_key].remove(chunk) ;
- if(start_key == end_key)
- {
- return ; //done
- }
-
- mChunkHashList[end_key].remove(chunk) ;
-
- if(end_key < start_key)
- {
- for(U16 i = start_key + 1 ; i < mHashFactor; i++)
- {
- mChunkHashList[i].remove(chunk) ;
- }
- for(U16 i = 0 ; i < end_key; i++)
- {
- mChunkHashList[i].remove(chunk) ;
- }
- }
- else
- {
- for(U16 i = start_key + 1 ; i < end_key; i++)
- {
- mChunkHashList[i].remove(chunk) ;
- }
- }
-}
-
-void LLPrivateMemoryPool::rehash()
-{
- LL_INFOS() << "new hash factor: " << mHashFactor << LL_ENDL ;
-
- mChunkHashList.clear() ;
- mChunkHashList.resize(mHashFactor) ;
-
- LLMemoryChunk* chunk ;
- for(U16 i = 0 ; i < SUPER_ALLOCATION ; i++)
- {
- chunk = mChunkList[i] ;
- while(chunk)
- {
- addToHashTable(chunk) ;
- chunk = chunk->mNext ;
- }
- }
-}
-
-bool LLPrivateMemoryPool::fillHashTable(U16 start, U16 end, LLMemoryChunk* chunk)
-{
- for(U16 i = start; i < end; i++)
- {
- if(mChunkHashList[i].add(chunk))
- {
- return true ;
- }
- }
-
- return false ;
-}
-
-//--------------------------------------------------------------------
-// class LLChunkHashElement
-//--------------------------------------------------------------------
-LLPrivateMemoryPool::LLMemoryChunk* LLPrivateMemoryPool::LLChunkHashElement::findChunk(const char* addr)
-{
- if(mFirst && mFirst->containsAddress(addr))
- {
- return mFirst ;
- }
- else if(mSecond && mSecond->containsAddress(addr))
- {
- return mSecond ;
- }
-
- return NULL ;
-}
-
-//return false if successfully inserted to the hash slot.
-bool LLPrivateMemoryPool::LLChunkHashElement::add(LLPrivateMemoryPool::LLMemoryChunk* chunk)
-{
- llassert_always(!hasElement(chunk)) ;
-
- if(!mFirst)
- {
- mFirst = chunk ;
- }
- else if(!mSecond)
- {
- mSecond = chunk ;
- }
- else
- {
- return true ; //failed
- }
-
- return false ;
-}
-
-void LLPrivateMemoryPool::LLChunkHashElement::remove(LLPrivateMemoryPool::LLMemoryChunk* chunk)
-{
- if(mFirst == chunk)
- {
- mFirst = NULL ;
- }
- else if(mSecond ==chunk)
- {
- mSecond = NULL ;
- }
- else
- {
- LL_ERRS() << "This slot does not contain this chunk!" << LL_ENDL ;
- }
-}
-
-//--------------------------------------------------------------------
-//class LLPrivateMemoryPoolManager
-//--------------------------------------------------------------------
-LLPrivateMemoryPoolManager* LLPrivateMemoryPoolManager::sInstance = NULL ;
-BOOL LLPrivateMemoryPoolManager::sPrivatePoolEnabled = FALSE ;
-std::vector<LLPrivateMemoryPool*> LLPrivateMemoryPoolManager::sDanglingPoolList ;
-
-LLPrivateMemoryPoolManager::LLPrivateMemoryPoolManager(BOOL enabled, U32 max_pool_size)
-{
- mPoolList.resize(LLPrivateMemoryPool::MAX_TYPES) ;
-
- for(S32 i = 0 ; i < LLPrivateMemoryPool::MAX_TYPES; i++)
- {
- mPoolList[i] = NULL ;
- }
-
- sPrivatePoolEnabled = enabled ;
-
- const U32 MAX_POOL_SIZE = 256 * 1024 * 1024 ; //256 MB
- mMaxPrivatePoolSize = llmax(max_pool_size, MAX_POOL_SIZE) ;
-}
-
-LLPrivateMemoryPoolManager::~LLPrivateMemoryPoolManager()
-{
-
-#if __DEBUG_PRIVATE_MEM__
- if(!sMemAllocationTracker.empty())
- {
- LL_WARNS() << "there is potential memory leaking here. The list of not freed memory blocks are from: " <<LL_ENDL ;
-
- S32 k = 0 ;
- for(mem_allocation_info_t::iterator iter = sMemAllocationTracker.begin() ; iter != sMemAllocationTracker.end() ; ++iter)
- {
- LL_INFOS() << k++ << ", " << (uintptr_t)iter->first << " : " << iter->second << LL_ENDL ;
- }
- sMemAllocationTracker.clear() ;
- }
-#endif
-
-#if 0
- //all private pools should be released by their owners before reaching here.
- for(S32 i = 0 ; i < LLPrivateMemoryPool::MAX_TYPES; i++)
- {
- llassert_always(!mPoolList[i]) ;
- }
- mPoolList.clear() ;
-
-#else
- //forcefully release all memory
- for(S32 i = 0 ; i < LLPrivateMemoryPool::MAX_TYPES; i++)
- {
- if(mPoolList[i])
- {
- if(mPoolList[i]->isEmpty())
- {
- delete mPoolList[i] ;
- }
- else
- {
- //can not delete this pool because it has alloacted memory to be freed.
- //move it to the dangling list.
- sDanglingPoolList.push_back(mPoolList[i]) ;
- }
-
- mPoolList[i] = NULL ;
- }
- }
- mPoolList.clear() ;
-#endif
-}
-
-//static
-void LLPrivateMemoryPoolManager::initClass(BOOL enabled, U32 max_pool_size)
-{
- llassert_always(!sInstance) ;
-
- sInstance = new LLPrivateMemoryPoolManager(enabled, max_pool_size) ;
-}
-
-//static
-LLPrivateMemoryPoolManager* LLPrivateMemoryPoolManager::getInstance()
-{
- //if(!sInstance)
- //{
- // sInstance = new LLPrivateMemoryPoolManager(FALSE) ;
- //}
- return sInstance ;
-}
-
-//static
-void LLPrivateMemoryPoolManager::destroyClass()
-{
- if(sInstance)
- {
- delete sInstance ;
- sInstance = NULL ;
- }
-}
-
-LLPrivateMemoryPool* LLPrivateMemoryPoolManager::newPool(S32 type)
-{
- if(!sPrivatePoolEnabled)
- {
- return NULL ;
- }
-
- if(!mPoolList[type])
- {
- mPoolList[type] = new LLPrivateMemoryPool(type, mMaxPrivatePoolSize) ;
- }
-
- return mPoolList[type] ;
-}
-
-void LLPrivateMemoryPoolManager::deletePool(LLPrivateMemoryPool* pool)
-{
- if(pool && pool->isEmpty())
- {
- mPoolList[pool->getType()] = NULL ;
- delete pool;
- }
-}
-
-//debug
-void LLPrivateMemoryPoolManager::updateStatistics()
-{
- mTotalReservedSize = 0 ;
- mTotalAllocatedSize = 0 ;
-
- for(U32 i = 0; i < mPoolList.size(); i++)
- {
- if(mPoolList[i])
- {
- mTotalReservedSize += mPoolList[i]->getTotalReservedSize() ;
- mTotalAllocatedSize += mPoolList[i]->getTotalAllocatedSize() ;
- }
- }
-}
-
-#if __DEBUG_PRIVATE_MEM__
-//static
-char* LLPrivateMemoryPoolManager::allocate(LLPrivateMemoryPool* poolp, U32 size, const char* function, const int line)
-{
- char* p ;
-
- if(!poolp)
- {
- p = (char*)ll_aligned_malloc_16(size) ;
- }
- else
- {
- p = poolp->allocate(size) ;
- }
-
- if(p)
- {
- char num[16] ;
- sprintf(num, " line: %d ", line) ;
- std::string str(function) ;
- str += num;
-
- sMemAllocationTracker[p] = str ;
- }
-
- return p ;
-}
-#else
-//static
-char* LLPrivateMemoryPoolManager::allocate(LLPrivateMemoryPool* poolp, U32 size)
-{
- if(poolp)
- {
- return poolp->allocate(size) ;
- }
- else
- {
- return (char*)ll_aligned_malloc_16(size) ;
- }
-}
-#endif
-
-//static
-void LLPrivateMemoryPoolManager::freeMem(LLPrivateMemoryPool* poolp, void* addr)
-{
- if(!addr)
- {
- return ;
- }
-
-#if __DEBUG_PRIVATE_MEM__
- sMemAllocationTracker.erase((char*)addr) ;
-#endif
-
- if(poolp)
- {
- poolp->freeMem(addr) ;
- }
- else
- {
- if(!sPrivatePoolEnabled)
- {
- ll_aligned_free_16(addr) ; //private pool is disabled.
- }
- else if(!sInstance) //the private memory manager is destroyed, try the dangling list
- {
- for(S32 i = 0 ; i < sDanglingPoolList.size(); i++)
- {
- if(sDanglingPoolList[i]->findChunk((char*)addr))
- {
- sDanglingPoolList[i]->freeMem(addr) ;
- if(sDanglingPoolList[i]->isEmpty())
- {
- delete sDanglingPoolList[i] ;
-
- if(i < sDanglingPoolList.size() - 1)
- {
- sDanglingPoolList[i] = sDanglingPoolList[sDanglingPoolList.size() - 1] ;
- }
- sDanglingPoolList.pop_back() ;
- }
-
- addr = NULL ;
- break ;
- }
- }
- llassert_always(!addr) ; //addr should be release before hitting here!
- }
- else
- {
- LL_ERRS() << "private pool is used before initialized.!" << LL_ENDL ;
- }
- }
-}
-
-//--------------------------------------------------------------------
-//class LLPrivateMemoryPoolTester
-//--------------------------------------------------------------------
-#if 0
-LLPrivateMemoryPoolTester* LLPrivateMemoryPoolTester::sInstance = NULL ;
-LLPrivateMemoryPool* LLPrivateMemoryPoolTester::sPool = NULL ;
-LLPrivateMemoryPoolTester::LLPrivateMemoryPoolTester()
-{
-}
-
-LLPrivateMemoryPoolTester::~LLPrivateMemoryPoolTester()
-{
-}
-
-//static
-LLPrivateMemoryPoolTester* LLPrivateMemoryPoolTester::getInstance()
-{
- if(!sInstance)
- {
- sInstance = ::new LLPrivateMemoryPoolTester() ;
- }
- return sInstance ;
-}
-
-//static
-void LLPrivateMemoryPoolTester::destroy()
-{
- if(sInstance)
- {
- ::delete sInstance ;
- sInstance = NULL ;
- }
-
- if(sPool)
- {
- LLPrivateMemoryPoolManager::getInstance()->deletePool(sPool) ;
- sPool = NULL ;
- }
-}
-
-void LLPrivateMemoryPoolTester::run(S32 type)
-{
- if(sPool)
- {
- LLPrivateMemoryPoolManager::getInstance()->deletePool(sPool) ;
- }
- sPool = LLPrivateMemoryPoolManager::getInstance()->newPool(type) ;
-
- //run the test
- correctnessTest() ;
- performanceTest() ;
- //fragmentationtest() ;
-
- //release pool.
- LLPrivateMemoryPoolManager::getInstance()->deletePool(sPool) ;
- sPool = NULL ;
-}
-
-void LLPrivateMemoryPoolTester::test(U32 min_size, U32 max_size, U32 stride, U32 times,
- bool random_deletion, bool output_statistics)
-{
- U32 levels = (max_size - min_size) / stride + 1 ;
- char*** p ;
- U32 i, j ;
- U32 total_allocated_size = 0 ;
-
- //allocate space for p ;
- if(!(p = ::new char**[times]) || !(*p = ::new char*[times * levels]))
- {
- LL_ERRS() << "memory initialization for p failed" << LL_ENDL ;
- }
-
- //init
- for(i = 0 ; i < times; i++)
- {
- p[i] = *p + i * levels ;
- for(j = 0 ; j < levels; j++)
- {
- p[i][j] = NULL ;
- }
- }
-
- //allocation
- U32 size ;
- for(i = 0 ; i < times ; i++)
- {
- for(j = 0 ; j < levels; j++)
- {
- size = min_size + j * stride ;
- p[i][j] = ALLOCATE_MEM(sPool, size) ;
-
- total_allocated_size+= size ;
-
- *(U32*)p[i][j] = i ;
- *((U32*)p[i][j] + 1) = j ;
- //p[i][j][size - 1] = '\0' ; //access the last element to verify the success of the allocation.
-
- //randomly release memory
- if(random_deletion)
- {
- S32 k = rand() % levels ;
-
- if(p[i][k])
- {
- llassert_always(*(U32*)p[i][k] == i && *((U32*)p[i][k] + 1) == k) ;
- FREE_MEM(sPool, p[i][k]) ;
- total_allocated_size -= min_size + k * stride ;
- p[i][k] = NULL ;
- }
- }
- }
- }
-
- //output pool allocation statistics
- if(output_statistics)
- {
- }
-
- //release all memory allocations
- for(i = 0 ; i < times; i++)
- {
- for(j = 0 ; j < levels; j++)
- {
- if(p[i][j])
- {
- llassert_always(*(U32*)p[i][j] == i && *((U32*)p[i][j] + 1) == j) ;
- FREE_MEM(sPool, p[i][j]) ;
- total_allocated_size -= min_size + j * stride ;
- p[i][j] = NULL ;
- }
- }
- }
-
- ::delete[] *p ;
- ::delete[] p ;
-}
-
-void LLPrivateMemoryPoolTester::testAndTime(U32 size, U32 times)
-{
- LLTimer timer ;
-
- LL_INFOS() << " -**********************- " << LL_ENDL ;
- LL_INFOS() << "test size: " << size << " test times: " << times << LL_ENDL ;
-
- timer.reset() ;
- char** p = new char*[times] ;
-
- //using the customized memory pool
- //allocation
- for(U32 i = 0 ; i < times; i++)
- {
- p[i] = ALLOCATE_MEM(sPool, size) ;
- if(!p[i])
- {
- LL_ERRS() << "allocation failed" << LL_ENDL ;
- }
- }
- //de-allocation
- for(U32 i = 0 ; i < times; i++)
- {
- FREE_MEM(sPool, p[i]) ;
- p[i] = NULL ;
- }
- LL_INFOS() << "time spent using customized memory pool: " << timer.getElapsedTimeF32() << LL_ENDL ;
-
- timer.reset() ;
-
- //using the standard allocator/de-allocator:
- //allocation
- for(U32 i = 0 ; i < times; i++)
- {
- p[i] = ::new char[size] ;
- if(!p[i])
- {
- LL_ERRS() << "allocation failed" << LL_ENDL ;
- }
- }
- //de-allocation
- for(U32 i = 0 ; i < times; i++)
- {
- ::delete[] p[i] ;
- p[i] = NULL ;
- }
- LL_INFOS() << "time spent using standard allocator/de-allocator: " << timer.getElapsedTimeF32() << LL_ENDL ;
-
- delete[] p;
-}
-
-void LLPrivateMemoryPoolTester::correctnessTest()
-{
- //try many different sized allocation, and all kinds of edge cases, access the allocated memory
- //to see if allocation is right.
-
- //edge case
- char* p = ALLOCATE_MEM(sPool, 0) ;
- FREE_MEM(sPool, p) ;
-
- //small sized
- // [8 bytes, 2KB), each asks for 256 allocations and deallocations
- test(8, 2040, 8, 256, true, true) ;
-
- //medium sized
- //[2KB, 512KB), each asks for 16 allocations and deallocations
- test(2048, 512 * 1024 - 2048, 2048, 16, true, true) ;
-
- //large sized
- //[512KB, 4MB], each asks for 8 allocations and deallocations
- test(512 * 1024, 4 * 1024 * 1024, 64 * 1024, 6, true, true) ;
-}
-
-void LLPrivateMemoryPoolTester::performanceTest()
-{
- U32 test_size[3] = {768, 3* 1024, 3* 1024 * 1024};
-
- //small sized
- testAndTime(test_size[0], 8) ;
-
- //medium sized
- testAndTime(test_size[1], 8) ;
-
- //large sized
- testAndTime(test_size[2], 8) ;
-}
-
-void LLPrivateMemoryPoolTester::fragmentationtest()
-{
- //for internal fragmentation statistics:
- //every time when asking for a new chunk during correctness test, and performance test,
- //print out the chunk usage statistices.
-}
-#endif
//--------------------------------------------------------------------
#if defined(LL_WINDOWS) && defined(LL_DEBUG_BUFFER_OVERRUN)
diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h
index c37967e10e..5b17d9e3a4 100644
--- a/indra/llcommon/llmemory.h
+++ b/indra/llcommon/llmemory.h
@@ -356,327 +356,6 @@ private:
static BOOL sEnableMemoryFailurePrevention;
};
-//
-//class LLPrivateMemoryPool defines a private memory pool for an application to use, so the application does not
-//need to access the heap directly fro each memory allocation. Throught this, the allocation speed is faster,
-//and reduces virtaul address space gragmentation problem.
-//Note: this class is thread-safe by passing true to the constructor function. However, you do not need to do this unless
-//you are sure the memory allocation and de-allocation will happen in different threads. To make the pool thread safe
-//increases allocation and deallocation cost.
-//
-class LL_COMMON_API LLPrivateMemoryPool
-{
- friend class LLPrivateMemoryPoolManager ;
-
-public:
- class LL_COMMON_API LLMemoryBlock //each block is devided into slots uniformly
- {
- public:
- LLMemoryBlock() ;
- ~LLMemoryBlock() ;
-
- void init(char* buffer, U32 buffer_size, U32 slot_size) ;
- void setBuffer(char* buffer, U32 buffer_size) ;
-
- char* allocate() ;
- void freeMem(void* addr) ;
-
- bool empty() {return !mAllocatedSlots;}
- bool isFull() {return mAllocatedSlots == mTotalSlots;}
- bool isFree() {return !mTotalSlots;}
-
- U32 getSlotSize()const {return mSlotSize;}
- U32 getTotalSlots()const {return mTotalSlots;}
- U32 getBufferSize()const {return mBufferSize;}
- char* getBuffer() const {return mBuffer;}
-
- //debug use
- void resetBitMap() ;
- private:
- char* mBuffer;
- U32 mSlotSize ; //when the block is not initialized, it is the buffer size.
- U32 mBufferSize ;
- U32 mUsageBits ;
- U8 mTotalSlots ;
- U8 mAllocatedSlots ;
- U8 mDummySize ; //size of extra bytes reserved for mUsageBits.
-
- public:
- LLMemoryBlock* mPrev ;
- LLMemoryBlock* mNext ;
- LLMemoryBlock* mSelf ;
-
- struct CompareAddress
- {
- bool operator()(const LLMemoryBlock* const& lhs, const LLMemoryBlock* const& rhs)
- {
- return (uintptr_t)lhs->getBuffer() < (uintptr_t)rhs->getBuffer();
- }
- };
- };
-
- class LL_COMMON_API LLMemoryChunk //is divided into memory blocks.
- {
- public:
- LLMemoryChunk() ;
- ~LLMemoryChunk() ;
-
- void init(char* buffer, U32 buffer_size, U32 min_slot_size, U32 max_slot_size, U32 min_block_size, U32 max_block_size) ;
- void setBuffer(char* buffer, U32 buffer_size) ;
-
- bool empty() ;
-
- char* allocate(U32 size) ;
- void freeMem(void* addr) ;
-
- char* getBuffer() const {return mBuffer;}
- U32 getBufferSize() const {return mBufferSize;}
- U32 getAllocatedSize() const {return mAlloatedSize;}
-
- bool containsAddress(const char* addr) const;
-
- static U32 getMaxOverhead(U32 data_buffer_size, U32 min_slot_size,
- U32 max_slot_size, U32 min_block_size, U32 max_block_size) ;
-
- void dump() ;
-
- private:
- U32 getPageIndex(uintptr_t addr) ;
- U32 getBlockLevel(U32 size) ;
- U16 getPageLevel(U32 size) ;
- LLMemoryBlock* addBlock(U32 blk_idx) ;
- void popAvailBlockList(U32 blk_idx) ;
- void addToFreeSpace(LLMemoryBlock* blk) ;
- void removeFromFreeSpace(LLMemoryBlock* blk) ;
- void removeBlock(LLMemoryBlock* blk) ;
- void addToAvailBlockList(LLMemoryBlock* blk) ;
- U32 calcBlockSize(U32 slot_size);
- LLMemoryBlock* createNewBlock(LLMemoryBlock* blk, U32 buffer_size, U32 slot_size, U32 blk_idx) ;
-
- private:
- LLMemoryBlock** mAvailBlockList ;//256 by mMinSlotSize
- LLMemoryBlock** mFreeSpaceList;
- LLMemoryBlock* mBlocks ; //index of blocks by address.
-
- char* mBuffer ;
- U32 mBufferSize ;
- char* mDataBuffer ;
- char* mMetaBuffer ;
- U32 mMinBlockSize ;
- U32 mMinSlotSize ;
- U32 mMaxSlotSize ;
- U32 mAlloatedSize ;
- U16 mBlockLevels;
- U16 mPartitionLevels;
-
- public:
- //form a linked list
- LLMemoryChunk* mNext ;
- LLMemoryChunk* mPrev ;
- } ;
-
-private:
- LLPrivateMemoryPool(S32 type, U32 max_pool_size) ;
- ~LLPrivateMemoryPool() ;
-
- char *allocate(U32 size) ;
- void freeMem(void* addr) ;
-
- void dump() ;
- U32 getTotalAllocatedSize() ;
- U32 getTotalReservedSize() {return mReservedPoolSize;}
- S32 getType() const {return mType; }
- bool isEmpty() const {return !mNumOfChunks; }
-
-private:
- void lock() ;
- void unlock() ;
- S32 getChunkIndex(U32 size) ;
- LLMemoryChunk* addChunk(S32 chunk_index) ;
- bool checkSize(U32 asked_size) ;
- void removeChunk(LLMemoryChunk* chunk) ;
- U16 findHashKey(const char* addr);
- void addToHashTable(LLMemoryChunk* chunk) ;
- void removeFromHashTable(LLMemoryChunk* chunk) ;
- void rehash() ;
- bool fillHashTable(U16 start, U16 end, LLMemoryChunk* chunk) ;
- LLMemoryChunk* findChunk(const char* addr) ;
-
- void destroyPool() ;
-
-public:
- enum
- {
- SMALL_ALLOCATION = 0, //from 8 bytes to 2KB(exclusive), page size 2KB, max chunk size is 4MB.
- MEDIUM_ALLOCATION, //from 2KB to 512KB(exclusive), page size 32KB, max chunk size 4MB
- LARGE_ALLOCATION, //from 512KB to 4MB(inclusive), page size 64KB, max chunk size 16MB
- SUPER_ALLOCATION //allocation larger than 4MB.
- };
-
- enum
- {
- STATIC = 0 , //static pool(each alllocation stays for a long time) without threading support
- VOLATILE, //Volatile pool(each allocation stays for a very short time) without threading support
- STATIC_THREADED, //static pool with threading support
- VOLATILE_THREADED, //volatile pool with threading support
- MAX_TYPES
- }; //pool types
-
-private:
- LLMutex* mMutexp ;
- U32 mMaxPoolSize;
- U32 mReservedPoolSize ;
-
- LLMemoryChunk* mChunkList[SUPER_ALLOCATION] ; //all memory chunks reserved by this pool, sorted by address
- U16 mNumOfChunks ;
- U16 mHashFactor ;
-
- S32 mType ;
-
- class LLChunkHashElement
- {
- public:
- LLChunkHashElement() {mFirst = NULL ; mSecond = NULL ;}
-
- bool add(LLMemoryChunk* chunk) ;
- void remove(LLMemoryChunk* chunk) ;
- LLMemoryChunk* findChunk(const char* addr) ;
-
- bool empty() {return !mFirst && !mSecond; }
- bool full() {return mFirst && mSecond; }
- bool hasElement(LLMemoryChunk* chunk) {return mFirst == chunk || mSecond == chunk;}
-
- private:
- LLMemoryChunk* mFirst ;
- LLMemoryChunk* mSecond ;
- };
- std::vector<LLChunkHashElement> mChunkHashList ;
-};
-
-class LL_COMMON_API LLPrivateMemoryPoolManager
-{
-private:
- LLPrivateMemoryPoolManager(BOOL enabled, U32 max_pool_size) ;
- ~LLPrivateMemoryPoolManager() ;
-
-public:
- static LLPrivateMemoryPoolManager* getInstance() ;
- static void initClass(BOOL enabled, U32 pool_size) ;
- static void destroyClass() ;
-
- LLPrivateMemoryPool* newPool(S32 type) ;
- void deletePool(LLPrivateMemoryPool* pool) ;
-
-private:
- std::vector<LLPrivateMemoryPool*> mPoolList ;
- U32 mMaxPrivatePoolSize;
-
- static LLPrivateMemoryPoolManager* sInstance ;
- static BOOL sPrivatePoolEnabled;
- static std::vector<LLPrivateMemoryPool*> sDanglingPoolList ;
-public:
- //debug and statistics info.
- void updateStatistics() ;
-
- U32 mTotalReservedSize ;
- U32 mTotalAllocatedSize ;
-
-public:
-#if __DEBUG_PRIVATE_MEM__
- static char* allocate(LLPrivateMemoryPool* poolp, U32 size, const char* function, const int line) ;
-
- typedef std::map<char*, std::string> mem_allocation_info_t ;
- static mem_allocation_info_t sMemAllocationTracker;
-#else
- static char* allocate(LLPrivateMemoryPool* poolp, U32 size) ;
-#endif
- static void freeMem(LLPrivateMemoryPool* poolp, void* addr) ;
-};
-
-//-------------------------------------------------------------------------------------
-#if __DEBUG_PRIVATE_MEM__
-#define ALLOCATE_MEM(poolp, size) LLPrivateMemoryPoolManager::allocate((poolp), (size), __FUNCTION__, __LINE__)
-#else
-#define ALLOCATE_MEM(poolp, size) LLPrivateMemoryPoolManager::allocate((poolp), (size))
-#endif
-#define FREE_MEM(poolp, addr) LLPrivateMemoryPoolManager::freeMem((poolp), (addr))
-//-------------------------------------------------------------------------------------
-
-//
-//the below singleton is used to test the private memory pool.
-//
-#if 0
-class LL_COMMON_API LLPrivateMemoryPoolTester
-{
-private:
- LLPrivateMemoryPoolTester() ;
- ~LLPrivateMemoryPoolTester() ;
-
-public:
- static LLPrivateMemoryPoolTester* getInstance() ;
- static void destroy() ;
-
- void run(S32 type) ;
-
-private:
- void correctnessTest() ;
- void performanceTest() ;
- void fragmentationtest() ;
-
- void test(U32 min_size, U32 max_size, U32 stride, U32 times, bool random_deletion, bool output_statistics) ;
- void testAndTime(U32 size, U32 times) ;
-
-#if 0
-public:
- void* operator new(size_t size)
- {
- return (void*)sPool->allocate(size) ;
- }
- void operator delete(void* addr)
- {
- sPool->freeMem(addr) ;
- }
- void* operator new[](size_t size)
- {
- return (void*)sPool->allocate(size) ;
- }
- void operator delete[](void* addr)
- {
- sPool->freeMem(addr) ;
- }
-#endif
-
-private:
- static LLPrivateMemoryPoolTester* sInstance;
- static LLPrivateMemoryPool* sPool ;
- static LLPrivateMemoryPool* sThreadedPool ;
-};
-#if 0
-//static
-void* LLPrivateMemoryPoolTester::operator new(size_t size)
-{
- return (void*)sPool->allocate(size) ;
-}
-
-//static
-void LLPrivateMemoryPoolTester::operator delete(void* addr)
-{
- sPool->free(addr) ;
-}
-
-//static
-void* LLPrivateMemoryPoolTester::operator new[](size_t size)
-{
- return (void*)sPool->allocate(size) ;
-}
-
-//static
-void LLPrivateMemoryPoolTester::operator delete[](void* addr)
-{
- sPool->free(addr) ;
-}
-#endif
-#endif
// LLRefCount moved to llrefcount.h
// LLPointer moved to llpointer.h
diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp
index be54ed053b..1aaff5628f 100644
--- a/indra/llcommon/llsdserialize.cpp
+++ b/indra/llcommon/llsdserialize.cpp
@@ -51,6 +51,7 @@
// File constants
static const int MAX_HDR_LEN = 20;
+static const S32 UNZIP_LLSD_MAX_DEPTH = 96;
static const char LEGACY_NON_HEADER[] = "<llsd>";
const std::string LLSD_BINARY_HEADER("LLSD/Binary");
const std::string LLSD_XML_HEADER("LLSD/XML");
@@ -317,11 +318,11 @@ LLSDParser::LLSDParser()
LLSDParser::~LLSDParser()
{ }
-S32 LLSDParser::parse(std::istream& istr, LLSD& data, S32 max_bytes)
+S32 LLSDParser::parse(std::istream& istr, LLSD& data, S32 max_bytes, S32 max_depth)
{
mCheckLimits = (LLSDSerialize::SIZE_UNLIMITED == max_bytes) ? false : true;
mMaxBytesLeft = max_bytes;
- return doParse(istr, data);
+ return doParse(istr, data, max_depth);
}
@@ -403,7 +404,7 @@ LLSDNotationParser::~LLSDNotationParser()
{ }
// virtual
-S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data) const
+S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data, S32 max_depth) const
{
// map: { string:object, string:object }
// array: [ object, object, object ]
@@ -418,6 +419,10 @@ S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data) const
// binary: b##"ff3120ab1" | b(size)"raw data"
char c;
c = istr.peek();
+ if (max_depth == 0)
+ {
+ return PARSE_FAILURE;
+ }
while(isspace(c))
{
// pop the whitespace.
@@ -434,7 +439,7 @@ S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data) const
{
case '{':
{
- S32 child_count = parseMap(istr, data);
+ S32 child_count = parseMap(istr, data, max_depth - 1);
if((child_count == PARSE_FAILURE) || data.isUndefined())
{
parse_count = PARSE_FAILURE;
@@ -453,7 +458,7 @@ S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data) const
case '[':
{
- S32 child_count = parseArray(istr, data);
+ S32 child_count = parseArray(istr, data, max_depth - 1);
if((child_count == PARSE_FAILURE) || data.isUndefined())
{
parse_count = PARSE_FAILURE;
@@ -658,7 +663,7 @@ S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data) const
return parse_count;
}
-S32 LLSDNotationParser::parseMap(std::istream& istr, LLSD& map) const
+S32 LLSDNotationParser::parseMap(std::istream& istr, LLSD& map, S32 max_depth) const
{
// map: { string:object, string:object }
map = LLSD::emptyMap();
@@ -693,7 +698,7 @@ S32 LLSDNotationParser::parseMap(std::istream& istr, LLSD& map) const
}
putback(istr, c);
LLSD child;
- S32 count = doParse(istr, child);
+ S32 count = doParse(istr, child, max_depth);
if(count > 0)
{
// There must be a value for every key, thus
@@ -718,7 +723,7 @@ S32 LLSDNotationParser::parseMap(std::istream& istr, LLSD& map) const
return parse_count;
}
-S32 LLSDNotationParser::parseArray(std::istream& istr, LLSD& array) const
+S32 LLSDNotationParser::parseArray(std::istream& istr, LLSD& array, S32 max_depth) const
{
// array: [ object, object, object ]
array = LLSD::emptyArray();
@@ -737,7 +742,7 @@ S32 LLSDNotationParser::parseArray(std::istream& istr, LLSD& array) const
continue;
}
putback(istr, c);
- S32 count = doParse(istr, child);
+ S32 count = doParse(istr, child, max_depth);
if(PARSE_FAILURE == count)
{
return PARSE_FAILURE;
@@ -869,7 +874,7 @@ LLSDBinaryParser::~LLSDBinaryParser()
}
// virtual
-S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data) const
+S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data, S32 max_depth) const
{
/**
* Undefined: '!'<br>
@@ -893,12 +898,16 @@ S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data) const
{
return 0;
}
+ if (max_depth == 0)
+ {
+ return PARSE_FAILURE;
+ }
S32 parse_count = 1;
switch(c)
{
case '{':
{
- S32 child_count = parseMap(istr, data);
+ S32 child_count = parseMap(istr, data, max_depth - 1);
if((child_count == PARSE_FAILURE) || data.isUndefined())
{
parse_count = PARSE_FAILURE;
@@ -917,7 +926,7 @@ S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data) const
case '[':
{
- S32 child_count = parseArray(istr, data);
+ S32 child_count = parseArray(istr, data, max_depth - 1);
if((child_count == PARSE_FAILURE) || data.isUndefined())
{
parse_count = PARSE_FAILURE;
@@ -1098,7 +1107,7 @@ S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data) const
return parse_count;
}
-S32 LLSDBinaryParser::parseMap(std::istream& istr, LLSD& map) const
+S32 LLSDBinaryParser::parseMap(std::istream& istr, LLSD& map, S32 max_depth) const
{
map = LLSD::emptyMap();
U32 value_nbo = 0;
@@ -1128,7 +1137,7 @@ S32 LLSDBinaryParser::parseMap(std::istream& istr, LLSD& map) const
}
}
LLSD child;
- S32 child_count = doParse(istr, child);
+ S32 child_count = doParse(istr, child, max_depth);
if(child_count > 0)
{
// There must be a value for every key, thus child_count
@@ -1152,7 +1161,7 @@ S32 LLSDBinaryParser::parseMap(std::istream& istr, LLSD& map) const
return parse_count;
}
-S32 LLSDBinaryParser::parseArray(std::istream& istr, LLSD& array) const
+S32 LLSDBinaryParser::parseArray(std::istream& istr, LLSD& array, S32 max_depth) const
{
array = LLSD::emptyArray();
U32 value_nbo = 0;
@@ -1168,7 +1177,7 @@ S32 LLSDBinaryParser::parseArray(std::istream& istr, LLSD& array) const
while((c != ']') && (count < size) && istr.good())
{
LLSD child;
- S32 child_count = doParse(istr, child);
+ S32 child_count = doParse(istr, child, max_depth);
if(PARSE_FAILURE == child_count)
{
return PARSE_FAILURE;
@@ -2238,7 +2247,7 @@ LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, std::istream& is,
return ZR_MEM_ERROR;
}
- if (!LLSDSerialize::fromBinary(data, istr, cur_size))
+ if (!LLSDSerialize::fromBinary(data, istr, cur_size, UNZIP_LLSD_MAX_DEPTH))
{
free(result);
return ZR_PARSE_ERROR;
@@ -2253,13 +2262,24 @@ LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, std::istream& is,
//and trailers are different for the formats.
U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize, std::istream& is, S32 size )
{
+ if (size == 0)
+ {
+ LL_WARNS() << "No data to unzip." << LL_ENDL;
+ return NULL;
+ }
+
U8* result = NULL;
U32 cur_size = 0;
z_stream strm;
const U32 CHUNK = 0x4000;
- U8 *in = new U8[size];
+ U8 *in = new(std::nothrow) U8[size];
+ if (in == NULL)
+ {
+ LL_WARNS() << "Memory allocation failure." << LL_ENDL;
+ return NULL;
+ }
is.read((char*) in, size);
U8 out[CHUNK];
@@ -2303,7 +2323,10 @@ U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize, std::istream& is, S32
U8* new_result = (U8*) realloc(result, cur_size + have);
if (new_result == NULL)
{
- LL_WARNS() << "Failed to unzip LLSD NavMesh block: can't reallocate memory, current size: " << cur_size << " bytes; requested " << cur_size + have << " bytes." << LL_ENDL;
+ LL_WARNS() << "Failed to unzip LLSD NavMesh block: can't reallocate memory, current size: " << cur_size
+ << " bytes; requested " << cur_size + have
+ << " bytes; total syze: ." << size << " bytes."
+ << LL_ENDL;
inflateEnd(&strm);
if (result)
{
diff --git a/indra/llcommon/llsdserialize.h b/indra/llcommon/llsdserialize.h
index 9f58d44fe7..8165410e80 100644
--- a/indra/llcommon/llsdserialize.h
+++ b/indra/llcommon/llsdserialize.h
@@ -77,7 +77,7 @@ public:
* @return Returns the number of LLSD objects parsed into
* data. Returns PARSE_FAILURE (-1) on parse failure.
*/
- S32 parse(std::istream& istr, LLSD& data, S32 max_bytes);
+ S32 parse(std::istream& istr, LLSD& data, S32 max_bytes, S32 max_depth = -1);
/** Like parse(), but uses a different call (istream.getline()) to read by lines
* This API is better suited for XML, where the parse cannot tell
@@ -103,10 +103,12 @@ protected:
* caller.
* @param istr The input stream.
* @param data[out] The newly parse structured data.
+ * @param max_depth Max depth parser will check before exiting
+ * with parse error, -1 - unlimited.
* @return Returns the number of LLSD objects parsed into
* data. Returns PARSE_FAILURE (-1) on parse failure.
*/
- virtual S32 doParse(std::istream& istr, LLSD& data) const = 0;
+ virtual S32 doParse(std::istream& istr, LLSD& data, S32 max_depth = -1) const = 0;
/**
* @brief Virtual default function for resetting the parser
@@ -241,10 +243,12 @@ protected:
* caller.
* @param istr The input stream.
* @param data[out] The newly parse structured data. Undefined on failure.
+ * @param max_depth Max depth parser will check before exiting
+ * with parse error, -1 - unlimited.
* @return Returns the number of LLSD objects parsed into
* data. Returns PARSE_FAILURE (-1) on parse failure.
*/
- virtual S32 doParse(std::istream& istr, LLSD& data) const;
+ virtual S32 doParse(std::istream& istr, LLSD& data, S32 max_depth = -1) const;
private:
/**
@@ -252,18 +256,20 @@ private:
*
* @param istr The input stream.
* @param map The map to add the parsed data.
+ * @param max_depth Allowed parsing depth.
* @return Returns The number of LLSD objects parsed into data.
*/
- S32 parseMap(std::istream& istr, LLSD& map) const;
+ S32 parseMap(std::istream& istr, LLSD& map, S32 max_depth) const;
/**
* @brief Parse an array from the istream.
*
* @param istr The input stream.
* @param array The array to append the parsed data.
+ * @param max_depth Allowed parsing depth.
* @return Returns The number of LLSD objects parsed into data.
*/
- S32 parseArray(std::istream& istr, LLSD& array) const;
+ S32 parseArray(std::istream& istr, LLSD& array, S32 max_depth) const;
/**
* @brief Parse a string from the istream and assign it to data.
@@ -314,10 +320,12 @@ protected:
* caller.
* @param istr The input stream.
* @param data[out] The newly parse structured data.
+ * @param max_depth Max depth parser will check before exiting
+ * with parse error, -1 - unlimited.
* @return Returns the number of LLSD objects parsed into
* data. Returns PARSE_FAILURE (-1) on parse failure.
*/
- virtual S32 doParse(std::istream& istr, LLSD& data) const;
+ virtual S32 doParse(std::istream& istr, LLSD& data, S32 max_depth = -1) const;
/**
* @brief Virtual default function for resetting the parser
@@ -362,10 +370,12 @@ protected:
* caller.
* @param istr The input stream.
* @param data[out] The newly parse structured data.
+ * @param max_depth Max depth parser will check before exiting
+ * with parse error, -1 - unlimited.
* @return Returns the number of LLSD objects parsed into
* data. Returns -1 on parse failure.
*/
- virtual S32 doParse(std::istream& istr, LLSD& data) const;
+ virtual S32 doParse(std::istream& istr, LLSD& data, S32 max_depth = -1) const;
private:
/**
@@ -373,18 +383,20 @@ private:
*
* @param istr The input stream.
* @param map The map to add the parsed data.
+ * @param max_depth Allowed parsing depth.
* @return Returns The number of LLSD objects parsed into data.
*/
- S32 parseMap(std::istream& istr, LLSD& map) const;
+ S32 parseMap(std::istream& istr, LLSD& map, S32 max_depth) const;
/**
* @brief Parse an array from the istream.
*
* @param istr The input stream.
* @param array The array to append the parsed data.
+ * @param max_depth Allowed parsing depth.
* @return Returns The number of LLSD objects parsed into data.
*/
- S32 parseArray(std::istream& istr, LLSD& array) const;
+ S32 parseArray(std::istream& istr, LLSD& array, S32 max_depth) const;
/**
* @brief Parse a string from the istream and assign it to data.
@@ -800,16 +812,16 @@ public:
LLPointer<LLSDBinaryFormatter> f = new LLSDBinaryFormatter;
return f->format(sd, str, LLSDFormatter::OPTIONS_NONE);
}
- static S32 fromBinary(LLSD& sd, std::istream& str, S32 max_bytes)
+ static S32 fromBinary(LLSD& sd, std::istream& str, S32 max_bytes, S32 max_depth = -1)
{
LLPointer<LLSDBinaryParser> p = new LLSDBinaryParser;
- return p->parse(str, sd, max_bytes);
+ return p->parse(str, sd, max_bytes, max_depth);
}
- static LLSD fromBinary(std::istream& str, S32 max_bytes)
+ static LLSD fromBinary(std::istream& str, S32 max_bytes, S32 max_depth = -1)
{
LLPointer<LLSDBinaryParser> p = new LLSDBinaryParser;
LLSD sd;
- (void)p->parse(str, sd, max_bytes);
+ (void)p->parse(str, sd, max_bytes, max_depth);
return sd;
}
};
diff --git a/indra/llcommon/llsdserialize_xml.cpp b/indra/llcommon/llsdserialize_xml.cpp
index 8d72a1c329..6d0fe862b9 100644
--- a/indra/llcommon/llsdserialize_xml.cpp
+++ b/indra/llcommon/llsdserialize_xml.cpp
@@ -917,7 +917,7 @@ void LLSDXMLParser::parsePart(const char *buf, int len)
}
// virtual
-S32 LLSDXMLParser::doParse(std::istream& input, LLSD& data) const
+S32 LLSDXMLParser::doParse(std::istream& input, LLSD& data, S32 max_depth) const
{
#ifdef XML_PARSER_PERFORMANCE_TESTS
XML_Timer timer( &parseTime );
diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index 32e8ea9682..1f4aa9b3a6 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -152,13 +152,16 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap
//LL_INFOS() << "LLThread::staticRun() Exiting: " << threadp->mName << LL_ENDL;
- // 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
- threadp->mStatus = STOPPED;
delete threadp->mRecorder;
threadp->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;
}
diff --git a/indra/llcommon/tests/llsdserialize_test.cpp b/indra/llcommon/tests/llsdserialize_test.cpp
index 8836230640..745e3a168c 100644
--- a/indra/llcommon/tests/llsdserialize_test.cpp
+++ b/indra/llcommon/tests/llsdserialize_test.cpp
@@ -513,19 +513,20 @@ namespace tut
const std::string& msg,
const std::string& in,
const LLSD& expected_value,
- S32 expected_count)
+ S32 expected_count,
+ S32 depth_limit = -1)
{
std::stringstream input;
input.str(in);
LLSD parsed_result;
mParser->reset(); // reset() call is needed since test code re-uses mParser
- S32 parsed_count = mParser->parse(input, parsed_result, in.size());
+ S32 parsed_count = mParser->parse(input, parsed_result, in.size(), depth_limit);
ensure_equals(msg.c_str(), parsed_result, expected_value);
// This count check is really only useful for expected
// parse failures, since the ensures equal will already
- // require eqality.
+ // require equality.
std::string count_msg(msg);
count_msg += " (count)";
ensure_equals(count_msg, parsed_count, expected_count);
@@ -714,6 +715,43 @@ namespace tut
expected,
1);
}
+
+ template<> template<>
+ void TestLLSDXMLParsingObject::test<5>()
+ {
+ // test deeper nested levels
+ LLSD level_5 = LLSD::emptyMap(); level_5["level_5"] = 42.f;
+ LLSD level_4 = LLSD::emptyMap(); level_4["level_4"] = level_5;
+ LLSD level_3 = LLSD::emptyMap(); level_3["level_3"] = level_4;
+ LLSD level_2 = LLSD::emptyMap(); level_2["level_2"] = level_3;
+ LLSD level_1 = LLSD::emptyMap(); level_1["level_1"] = level_2;
+ LLSD level_0 = LLSD::emptyMap(); level_0["level_0"] = level_1;
+
+ LLSD v;
+ v["deep"] = level_0;
+
+ ensureParse(
+ "deep llsd xml map",
+ "<llsd><map>"
+ "<key>deep</key><map>"
+ "<key>level_0</key><map>"
+ "<key>level_1</key><map>"
+ "<key>level_2</key><map>"
+ "<key>level_3</key><map>"
+ "<key>level_4</key><map>"
+ "<key>level_5</key><real>42.0</real>"
+ "</map>"
+ "</map>"
+ "</map>"
+ "</map>"
+ "</map>"
+ "</map>"
+ "</map></llsd>",
+ v,
+ 8);
+ }
+
+
/*
TODO:
test XML parsing
@@ -975,6 +1013,146 @@ namespace tut
LLSDParser::PARSE_FAILURE);
}
+ template<> template<>
+ void TestLLSDNotationParsingObject::test<18>()
+ {
+ LLSD level_1 = LLSD::emptyMap(); level_1["level_2"] = 99;
+ LLSD level_0 = LLSD::emptyMap(); level_0["level_1"] = level_1;
+
+ LLSD deep = LLSD::emptyMap();
+ deep["level_0"] = level_0;
+
+ LLSD root = LLSD::emptyMap();
+ root["deep"] = deep;
+
+ ensureParse(
+ "nested notation 3 deep",
+ "{'deep' : {'level_0':{'level_1':{'level_2': i99} } } }",
+ root,
+ 5,
+ 5); // 4 '{' plus i99 also counts as llsd, so real depth is 5
+ }
+
+ template<> template<>
+ void TestLLSDNotationParsingObject::test<19>()
+ {
+ LLSD level_9 = LLSD::emptyMap(); level_9["level_9"] = (S32)99;
+ LLSD level_8 = LLSD::emptyMap(); level_8["level_8"] = level_9;
+ LLSD level_7 = LLSD::emptyMap(); level_7["level_7"] = level_8;
+ LLSD level_6 = LLSD::emptyMap(); level_6["level_6"] = level_7;
+ LLSD level_5 = LLSD::emptyMap(); level_5["level_5"] = level_6;
+ LLSD level_4 = LLSD::emptyMap(); level_4["level_4"] = level_5;
+ LLSD level_3 = LLSD::emptyMap(); level_3["level_3"] = level_4;
+ LLSD level_2 = LLSD::emptyMap(); level_2["level_2"] = level_3;
+ LLSD level_1 = LLSD::emptyMap(); level_1["level_1"] = level_2;
+ LLSD level_0 = LLSD::emptyMap(); level_0["level_0"] = level_1;
+
+ LLSD deep = LLSD::emptyMap();
+ deep["deep"] = level_0;
+
+ ensureParse(
+ "nested notation 10 deep",
+ "{'deep' : {'level_0':{'level_1':{'level_2':{'level_3':{'level_4':{'level_5':{'level_6':{'level_7':{'level_8':{'level_9':i99}"
+ "} } } } } } } } } }",
+ deep,
+ 12,
+ 15);
+ }
+
+ template<> template<>
+ void TestLLSDNotationParsingObject::test<20>()
+ {
+ LLSD end = LLSD::emptyMap(); end["end"] = (S32)99;
+
+ LLSD level_49 = LLSD::emptyMap(); level_49["level_49"] = end;
+ LLSD level_48 = LLSD::emptyMap(); level_48["level_48"] = level_49;
+ LLSD level_47 = LLSD::emptyMap(); level_47["level_47"] = level_48;
+ LLSD level_46 = LLSD::emptyMap(); level_46["level_46"] = level_47;
+ LLSD level_45 = LLSD::emptyMap(); level_45["level_45"] = level_46;
+ LLSD level_44 = LLSD::emptyMap(); level_44["level_44"] = level_45;
+ LLSD level_43 = LLSD::emptyMap(); level_43["level_43"] = level_44;
+ LLSD level_42 = LLSD::emptyMap(); level_42["level_42"] = level_43;
+ LLSD level_41 = LLSD::emptyMap(); level_41["level_41"] = level_42;
+ LLSD level_40 = LLSD::emptyMap(); level_40["level_40"] = level_41;
+
+ LLSD level_39 = LLSD::emptyMap(); level_39["level_39"] = level_40;
+ LLSD level_38 = LLSD::emptyMap(); level_38["level_38"] = level_39;
+ LLSD level_37 = LLSD::emptyMap(); level_37["level_37"] = level_38;
+ LLSD level_36 = LLSD::emptyMap(); level_36["level_36"] = level_37;
+ LLSD level_35 = LLSD::emptyMap(); level_35["level_35"] = level_36;
+ LLSD level_34 = LLSD::emptyMap(); level_34["level_34"] = level_35;
+ LLSD level_33 = LLSD::emptyMap(); level_33["level_33"] = level_34;
+ LLSD level_32 = LLSD::emptyMap(); level_32["level_32"] = level_33;
+ LLSD level_31 = LLSD::emptyMap(); level_31["level_31"] = level_32;
+ LLSD level_30 = LLSD::emptyMap(); level_30["level_30"] = level_31;
+
+ LLSD level_29 = LLSD::emptyMap(); level_29["level_29"] = level_30;
+ LLSD level_28 = LLSD::emptyMap(); level_28["level_28"] = level_29;
+ LLSD level_27 = LLSD::emptyMap(); level_27["level_27"] = level_28;
+ LLSD level_26 = LLSD::emptyMap(); level_26["level_26"] = level_27;
+ LLSD level_25 = LLSD::emptyMap(); level_25["level_25"] = level_26;
+ LLSD level_24 = LLSD::emptyMap(); level_24["level_24"] = level_25;
+ LLSD level_23 = LLSD::emptyMap(); level_23["level_23"] = level_24;
+ LLSD level_22 = LLSD::emptyMap(); level_22["level_22"] = level_23;
+ LLSD level_21 = LLSD::emptyMap(); level_21["level_21"] = level_22;
+ LLSD level_20 = LLSD::emptyMap(); level_20["level_20"] = level_21;
+
+ LLSD level_19 = LLSD::emptyMap(); level_19["level_19"] = level_20;
+ LLSD level_18 = LLSD::emptyMap(); level_18["level_18"] = level_19;
+ LLSD level_17 = LLSD::emptyMap(); level_17["level_17"] = level_18;
+ LLSD level_16 = LLSD::emptyMap(); level_16["level_16"] = level_17;
+ LLSD level_15 = LLSD::emptyMap(); level_15["level_15"] = level_16;
+ LLSD level_14 = LLSD::emptyMap(); level_14["level_14"] = level_15;
+ LLSD level_13 = LLSD::emptyMap(); level_13["level_13"] = level_14;
+ LLSD level_12 = LLSD::emptyMap(); level_12["level_12"] = level_13;
+ LLSD level_11 = LLSD::emptyMap(); level_11["level_11"] = level_12;
+ LLSD level_10 = LLSD::emptyMap(); level_10["level_10"] = level_11;
+
+ LLSD level_9 = LLSD::emptyMap(); level_9["level_9"] = level_10;
+ LLSD level_8 = LLSD::emptyMap(); level_8["level_8"] = level_9;
+ LLSD level_7 = LLSD::emptyMap(); level_7["level_7"] = level_8;
+ LLSD level_6 = LLSD::emptyMap(); level_6["level_6"] = level_7;
+ LLSD level_5 = LLSD::emptyMap(); level_5["level_5"] = level_6;
+ LLSD level_4 = LLSD::emptyMap(); level_4["level_4"] = level_5;
+ LLSD level_3 = LLSD::emptyMap(); level_3["level_3"] = level_4;
+ LLSD level_2 = LLSD::emptyMap(); level_2["level_2"] = level_3;
+ LLSD level_1 = LLSD::emptyMap(); level_1["level_1"] = level_2;
+ LLSD level_0 = LLSD::emptyMap(); level_0["level_0"] = level_1;
+
+ LLSD deep = LLSD::emptyMap();
+ deep["deep"] = level_0;
+
+ ensureParse(
+ "nested notation deep",
+ "{'deep':"
+ "{'level_0' :{'level_1' :{'level_2' :{'level_3' :{'level_4' :{'level_5' :{'level_6' :{'level_7' :{'level_8' :{'level_9' :"
+ "{'level_10':{'level_11':{'level_12':{'level_13':{'level_14':{'level_15':{'level_16':{'level_17':{'level_18':{'level_19':"
+ "{'level_20':{'level_21':{'level_22':{'level_23':{'level_24':{'level_25':{'level_26':{'level_27':{'level_28':{'level_29':"
+ "{'level_30':{'level_31':{'level_32':{'level_33':{'level_34':{'level_35':{'level_36':{'level_37':{'level_38':{'level_39':"
+ "{'level_40':{'level_41':{'level_42':{'level_43':{'level_44':{'level_45':{'level_46':{'level_47':{'level_48':{'level_49':"
+ "{'end':i99}"
+ "} } } } } } } } } }"
+ "} } } } } } } } } }"
+ "} } } } } } } } } }"
+ "} } } } } } } } } }"
+ "} } } } } } } } } }"
+ "}",
+ deep,
+ 53);
+ }
+
+ template<> template<>
+ void TestLLSDNotationParsingObject::test<21>()
+ {
+ ensureParse(
+ "nested notation 10 deep",
+ "{'deep' : {'level_0':{'level_1':{'level_2':{'level_3':{'level_4':{'level_5':{'level_6':{'level_7':{'level_8':{'level_9':i99}"
+ "} } } } } } } } } }",
+ LLSD(),
+ LLSDParser::PARSE_FAILURE,
+ 9);
+ }
+
/**
* @class TestLLSDBinaryParsing
* @brief Concrete instance of a parse tester.
diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt
index bff329f4a5..9dbc6f447e 100644
--- a/indra/llcorehttp/CMakeLists.txt
+++ b/indra/llcorehttp/CMakeLists.txt
@@ -167,29 +167,26 @@ if (DARWIN)
COMMENT "Creating Resources directory in app bundle."
)
- # Copy the required libraries to the package app
- add_custom_command(TARGET INTEGRATION_TEST_llcorehttp PRE_BUILD
- COMMAND ${CMAKE_COMMAND} -E copy ${AUTOBUILD_INSTALL_DIR}/lib/release/libapr-1.0.dylib ${LL_TEST_DESTINATION_DIR}
- DEPENDS ${AUTOBUILD_INSTALL_DIR}/lib/release/libapr-1.0.dylib
- )
- add_custom_command(TARGET INTEGRATION_TEST_llcorehttp PRE_BUILD
- COMMAND ${CMAKE_COMMAND} -E copy ${AUTOBUILD_INSTALL_DIR}/lib/release/libaprutil-1.0.dylib ${LL_TEST_DESTINATION_DIR}
- DEPENDS ${AUTOBUILD_INSTALL_DIR}/lib/release/libaprutil-1.0.dylib
- )
- add_custom_command(TARGET INTEGRATION_TEST_llcorehttp PRE_BUILD
- COMMAND ${CMAKE_COMMAND} -E copy ${AUTOBUILD_INSTALL_DIR}/lib/release/libexception_handler.dylib ${LL_TEST_DESTINATION_DIR}
- DEPENDS ${AUTOBUILD_INSTALL_DIR}/lib/release/libexception_handler.dylib
- )
+ # Copy the required libraries to the package app. We used to use a sequence
+ # of '${CMAKE_COMMAND} -E copy' commands, but 'cmake -E copy' does only a
+ # single file at a time: it doesn't understand wildcards. 'cmake -E copy' is
+ # for portability. This operation is Darwin-specific. We can count on the
+ # 'cp' command.
+ set(copy_dylibs
+ libapr-1.0.dylib
+ libaprutil-1.0.dylib
+ libexception_handler.dylib
+ libnghttp2*.dylib
+ ${EXPAT_COPY}
+ )
+
add_custom_command(TARGET INTEGRATION_TEST_llcorehttp PRE_BUILD
- COMMAND ${CMAKE_COMMAND} -E copy ${AUTOBUILD_INSTALL_DIR}/lib/release/libnghttp2*.dylib ${LL_TEST_DESTINATION_DIR}
- DEPENDS ${AUTOBUILD_INSTALL_DIR}/lib/release/libnghttp2.dylib
+ WORKING_DIRECTORY "${AUTOBUILD_INSTALL_DIR}/lib/release"
+ COMMAND cp -v
+ ${copy_dylibs}
+ ${LL_TEST_DESTINATION_DIR}
+ DEPENDS ${copy_dylibs}
)
- foreach(expat ${EXPAT_COPY})
- add_custom_command(TARGET INTEGRATION_TEST_llcorehttp PRE_BUILD
- COMMAND ${CMAKE_COMMAND} -E copy ${AUTOBUILD_INSTALL_DIR}/lib/release/${expat} ${LL_TEST_DESTINATION_DIR}
- DEPENDS ${AUTOBUILD_INSTALL_DIR}/lib/release/${expat}
- )
- endforeach(expat)
endif (DARWIN)
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 4a76d15096..dca03cfe04 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -588,7 +588,6 @@ std::string LLImage::sLastErrorMessage;
LLMutex* LLImage::sMutex = NULL;
bool LLImage::sUseNewByteRange = false;
S32 LLImage::sMinimalReverseByteRangePercent = 75;
-LLPrivateMemoryPool* LLImageBase::sPrivatePoolp = NULL ;
//static
void LLImage::initClass(bool use_new_byte_range, S32 minimal_reverse_byte_range_percent)
@@ -596,8 +595,6 @@ 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);
-
- LLImageBase::createPrivatePool() ;
}
//static
@@ -605,8 +602,6 @@ void LLImage::cleanupClass()
{
delete sMutex;
sMutex = NULL;
-
- LLImageBase::destroyPrivatePool() ;
}
//static
@@ -644,25 +639,6 @@ LLImageBase::~LLImageBase()
deleteData(); // virtual
}
-//static
-void LLImageBase::createPrivatePool()
-{
- if(!sPrivatePoolp)
- {
- sPrivatePoolp = LLPrivateMemoryPoolManager::getInstance()->newPool(LLPrivateMemoryPool::STATIC_THREADED) ;
- }
-}
-
-//static
-void LLImageBase::destroyPrivatePool()
-{
- if(sPrivatePoolp)
- {
- LLPrivateMemoryPoolManager::getInstance()->deletePool(sPrivatePoolp) ;
- sPrivatePoolp = NULL ;
- }
-}
-
// virtual
void LLImageBase::dump()
{
@@ -696,7 +672,7 @@ void LLImageBase::sanityCheck()
// virtual
void LLImageBase::deleteData()
{
- FREE_MEM(sPrivatePoolp, mData) ;
+ ll_aligned_free_16(mData);
disclaimMem(mDataSize);
mDataSize = 0;
mData = NULL;
@@ -736,7 +712,7 @@ U8* LLImageBase::allocateData(S32 size)
if (!mBadBufferAllocation && (!mData || size != mDataSize))
{
deleteData(); // virtual
- mData = (U8*)ALLOCATE_MEM(sPrivatePoolp, size);
+ mData = (U8*)ll_aligned_malloc_16(size);
if (!mData)
{
LL_WARNS() << "Failed to allocate image data size [" << size << "]" << LL_ENDL;
@@ -763,7 +739,7 @@ U8* LLImageBase::allocateData(S32 size)
// virtual
U8* LLImageBase::reallocateData(S32 size)
{
- U8 *new_datap = (U8*)ALLOCATE_MEM(sPrivatePoolp, size);
+ U8 *new_datap = (U8*)ll_aligned_malloc_16(size);
if (!new_datap)
{
LL_WARNS() << "Out of memory in LLImageBase::reallocateData" << LL_ENDL;
@@ -773,7 +749,7 @@ U8* LLImageBase::reallocateData(S32 size)
{
S32 bytes = llmin(mDataSize, size);
memcpy(new_datap, mData, bytes); /* Flawfinder: ignore */
- FREE_MEM(sPrivatePoolp, mData) ;
+ ll_aligned_free_16(mData) ;
}
mData = new_datap;
disclaimMem(mDataSize);
@@ -1470,7 +1446,7 @@ bool LLImageRaw::scale( S32 new_width, S32 new_height, bool scale_image_data )
if (new_data_size > 0)
{
- U8 *new_data = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), new_data_size);
+ U8 *new_data = (U8*)ll_aligned_malloc_16(new_data_size);
if(NULL == new_data)
{
return false;
@@ -2169,7 +2145,7 @@ void LLImageFormatted::appendData(U8 *data, S32 size)
S32 newsize = cursize + size;
reallocateData(newsize);
memcpy(getData() + cursize, data, size);
- FREE_MEM(LLImageBase::getPrivatePool(), data);
+ ll_aligned_free_16(data);
}
}
}
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index 958c9fad3d..8ec49d3f0f 100644
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -71,7 +71,6 @@ const S32 HTTP_PACKET_SIZE = 1496;
class LLImageFormatted;
class LLImageRaw;
class LLColor4U;
-class LLPrivateMemoryPool;
typedef enum e_image_codec
{
@@ -160,10 +159,6 @@ public:
static F32 calc_download_priority(F32 virtual_size, F32 visible_area, S32 bytes_sent);
static EImageCodec getCodecFromExtension(const std::string& exten);
-
- static void createPrivatePool() ;
- static void destroyPrivatePool() ;
- static LLPrivateMemoryPool* getPrivatePool() {return sPrivatePoolp;}
//static LLTrace::MemStatHandle sMemStat;
@@ -178,8 +173,6 @@ private:
bool mBadBufferAllocation ;
bool mAllowOverSize ;
-
- static LLPrivateMemoryPool* sPrivatePoolp ;
};
// Raw representation of an image (used for textures, and other uncompressed formats
diff --git a/indra/llimage/llimagedxt.cpp b/indra/llimage/llimagedxt.cpp
index 0ec83415a0..3a7319d765 100644
--- a/indra/llimage/llimagedxt.cpp
+++ b/indra/llimage/llimagedxt.cpp
@@ -430,7 +430,7 @@ bool LLImageDXT::convertToDXR()
S32 nmips = calcNumMips(width,height);
S32 total_bytes = getDataSize();
U8* olddata = getData();
- U8* newdata = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), total_bytes);
+ U8* newdata = (U8*)ll_aligned_malloc_16(total_bytes);
if (!newdata)
{
LL_ERRS() << "Out of memory in LLImageDXT::convertToDXR()" << LL_ENDL;
diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp
index c40df009d8..4bff21610f 100644
--- a/indra/llimage/llimagej2c.cpp
+++ b/indra/llimage/llimagej2c.cpp
@@ -368,7 +368,7 @@ bool LLImageJ2C::loadAndValidate(const std::string &filename)
}
else
{
- U8 *data = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), file_size);
+ U8 *data = (U8*)ll_aligned_malloc_16(file_size);
if (!data)
{
infile.close();
@@ -383,7 +383,7 @@ bool LLImageJ2C::loadAndValidate(const std::string &filename)
if (s != APR_SUCCESS || (S32)bytes_read != file_size)
{
- FREE_MEM(LLImageBase::getPrivatePool(), data);
+ ll_aligned_free_16(data);
setLastError("Unable to read entire file");
res = false;
}
diff --git a/indra/llkdu/tests/llimagej2ckdu_test.cpp b/indra/llkdu/tests/llimagej2ckdu_test.cpp
index e386a9f71b..79ed566d00 100644
--- a/indra/llkdu/tests/llimagej2ckdu_test.cpp
+++ b/indra/llkdu/tests/llimagej2ckdu_test.cpp
@@ -119,6 +119,10 @@ bool LLKDUMemIn::get(int, kdu_core::kdu_line_buf&, int) { return false; }
// Stub Kakadu Library calls
// they're all namespaced now
+namespace kdu_core_local
+{
+ class kd_coremem;
+}
namespace kdu_core {
kdu_tile_comp kdu_tile::access_component(int ) { kdu_tile_comp a; return a; }
kdu_block_encoder::kdu_block_encoder() { }
@@ -140,7 +144,8 @@ void kdu_resolution::get_dims(kdu_dims& ) { }
int kdu_resolution::which() { return 0; }
int kdu_resolution::get_valid_band_indices(int &) { return 1; }
kdu_synthesis::kdu_synthesis(kdu_resolution, kdu_sample_allocator*, bool, float, kdu_thread_env*, kdu_thread_queue*) { }
-kdu_params::kdu_params(const char*, bool, bool, bool, bool, bool) { }
+//kdu_params::kdu_params(const char*, bool, bool, bool, bool, bool) { }
+kdu_params::kdu_params(const char*, bool, bool, bool, bool, bool, kd_core_local::kd_coremem*) {}
kdu_params::~kdu_params() { }
void kdu_params::set(const char* , int , int , bool ) { }
void kdu_params::set(const char* , int , int , int ) { }
@@ -164,39 +169,61 @@ void kdu_codestream::destroy() { }
void kdu_codestream::collect_timing_stats(int ) { }
void kdu_codestream::set_max_bytes(kdu_long, bool, bool ) { }
void kdu_codestream::get_valid_tiles(kdu_dims& ) { }
-void kdu_codestream::create(kdu_compressed_source*, kdu_thread_env*) { }
+void kdu_codestream::create(
+ siz_params*,
+ kdu_compressed_target*,
+ kdu_dims*,
+ int,
+ kdu_long,
+ kdu_thread_env*,
+ kdu_membroker*) {}
+void kdu_codestream::create(kdu_compressed_source *,kdu_thread_env *, kdu_membroker *) {}
void kdu_codestream::apply_input_restrictions(int, int, int, int, kdu_dims const *, kdu_component_access_mode, kdu_thread_env *, kdu_quality_limiter const *) {}
void kdu_codestream::get_subsampling(int , kdu_coords&, bool ) { }
void kdu_codestream::flush(kdu_long *, int, kdu_uint16 *, bool, bool, double, kdu_thread_env*, int) { }
void kdu_codestream::set_resilient(bool ) { }
int kdu_codestream::get_num_components(bool ) { return 0; }
kdu_long kdu_codestream::get_total_bytes(bool ) { return 0; }
-kdu_long kdu_codestream::get_compressed_data_memory(bool ) {return 0; }
+kdu_long kdu_codestream::get_compressed_data_memory(bool ) const {return 0; }
void kdu_codestream::share_buffering(kdu_codestream ) { }
int kdu_codestream::get_num_tparts() { return 0; }
int kdu_codestream::trans_out(kdu_long, kdu_long*, int, bool, kdu_thread_env* ) { return 0; }
bool kdu_codestream::ready_for_flush(kdu_thread_env*) { return false; }
siz_params* kdu_codestream::access_siz() { return NULL; }
kdu_tile kdu_codestream::open_tile(kdu_coords , kdu_thread_env* ) { kdu_tile a; return a; }
-kdu_codestream_comment kdu_codestream::add_comment() { kdu_codestream_comment a; return a; }
+kdu_codestream_comment kdu_codestream::add_comment(kdu_thread_env*) { kdu_codestream_comment a; return a; }
void kdu_subband::close_block(kdu_block*, kdu_thread_env*) { }
void kdu_subband::get_valid_blocks(kdu_dims &indices) const { }
kdu_block * kdu_subband::open_block(kdu_coords, int *, kdu_thread_env *, int, bool) { return NULL; }
bool kdu_codestream_comment::put_text(const char*) { return false; }
void kdu_customize_warnings(kdu_message*) { }
void kdu_customize_errors(kdu_message*) { }
-kdu_long kdu_multi_analysis::create(kdu_codestream, kdu_tile, kdu_thread_env *,kdu_thread_queue *, int, kdu_roi_image *, int, kdu_sample_allocator *, kdu_push_pull_params const *) { return kdu_long(0); }
+kdu_long kdu_multi_analysis::create(
+ kdu_codestream,
+ kdu_tile,
+ kdu_thread_env*,
+ kdu_thread_queue*,
+ int,
+ kdu_roi_image*,
+ int,
+ kdu_sample_allocator*,
+ const kdu_push_pull_params*,
+ kdu_membroker*) { return kdu_long(0); }
void kdu_multi_analysis::destroy(kdu_thread_env *) {}
-siz_params::siz_params() : kdu_params(NULL, false, false, false, false, false) { }
+siz_params::siz_params(kd_core_local::kd_coremem*) : kdu_params(NULL, false, false, false, false, false) { }
siz_params::~siz_params() {}
void siz_params::finalize(bool ) { }
void siz_params::copy_with_xforms(kdu_params*, int, int, bool, bool, bool) { }
int siz_params::write_marker_segment(kdu_output*, kdu_params*, int) { return 0; }
bool siz_params::check_marker_segment(kdu_uint16, int, kdu_byte a[], int&) { return false; }
bool siz_params::read_marker_segment(kdu_uint16, int, kdu_byte a[], int) { return false; }
-
-kdu_decoder::kdu_decoder(kdu_subband , kdu_sample_allocator*, bool , float, int, kdu_thread_env*, kdu_thread_queue*, int) { }
-void kdu_codestream::create(siz_params*, kdu_compressed_target*, kdu_dims*, int, kdu_long, kdu_thread_env* ) { }
+kdu_decoder::kdu_decoder(
+ kdu_subband subband,
+ kdu_sample_allocator*,
+ bool, float, int,
+ kdu_thread_env*,
+ kdu_thread_queue*,
+ int, float*) {}
kdu_sample_allocator::~kdu_sample_allocator() {}
void kdu_sample_allocator::do_finalize(kdu_codestream) {}
void (*kdu_convert_ycc_to_rgb_rev16)(kdu_int16*,kdu_int16*,kdu_int16*,int);
@@ -205,6 +232,8 @@ void (*kdu_convert_ycc_to_rgb_rev32)(kdu_int32*,kdu_int32*,kdu_int32*,int);
void (*kdu_convert_ycc_to_rgb_irrev32)(float*,float*,float*,int);
bool kdu_core_sample_alignment_checker(int, int, int, int, bool, bool) { return false; }
void kdu_pull_ifc::destroy() {}
+void kdu_sample_allocator::advance_pre_frag() {}
+void kdu_params::operator delete(void *) {}
} // namespace kdu_core
// -------------------------------------------------------------------------------------------
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 24f46d720b..6b6cd65ce2 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -545,7 +545,7 @@ void LLProfile::genNGon(const LLProfileParams& params, S32 sides, F32 offset, F3
{
// Generate an n-sided "circular" path.
// 0 is (1,0), and we go counter-clockwise along a circular path from there.
- const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f };
+ static const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f };
F32 scale = 0.5f;
F32 t, t_step, t_first, t_fraction, ang, ang_step;
LLVector4a pt1,pt2;
@@ -1304,7 +1304,7 @@ S32 LLPath::getNumNGonPoints(const LLPathParams& params, S32 sides, F32 startOff
void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 end_scale, F32 twist_scale)
{
// Generates a circular path, starting at (1, 0, 0), counterclockwise along the xz plane.
- const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f };
+ static const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f };
F32 revolutions = params.getRevolutions();
F32 skew = params.getSkew();
@@ -1602,7 +1602,8 @@ BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split,
if (is_sculpted)
sides = llmax(sculpt_size, 1);
- genNGon(params, sides);
+ if (0 < sides)
+ genNGon(params, sides);
}
break;
@@ -2921,28 +2922,54 @@ F32 LLVolume::sculptGetSurfaceArea()
return area;
}
-// create placeholder shape
-void LLVolume::sculptGeneratePlaceholder()
+// create empty placeholder shape
+void LLVolume::sculptGenerateEmptyPlaceholder()
{
S32 sizeS = mPathp->mPath.size();
S32 sizeT = mProfilep->mProfile.size();
-
+
S32 line = 0;
- // for now, this is a sphere.
for (S32 s = 0; s < sizeS; s++)
{
for (S32 t = 0; t < sizeT; t++)
{
S32 i = t + line;
LLVector4a& pt = mMesh[i];
+
+ F32* p = pt.getF32ptr();
-
- F32 u = (F32)s/(sizeS-1);
- F32 v = (F32)t/(sizeT-1);
+ p[0] = 0;
+ p[1] = 0;
+ p[2] = 0;
+
+ llassert(pt.isFinite3());
+ }
+ line += sizeT;
+ }
+}
+
+// create sphere placeholder shape
+void LLVolume::sculptGenerateSpherePlaceholder()
+{
+ S32 sizeS = mPathp->mPath.size();
+ S32 sizeT = mProfilep->mProfile.size();
+
+ S32 line = 0;
+
+ for (S32 s = 0; s < sizeS; s++)
+ {
+ for (S32 t = 0; t < sizeT; t++)
+ {
+ S32 i = t + line;
+ LLVector4a& pt = mMesh[i];
+
+
+ F32 u = (F32)s / (sizeS - 1);
+ F32 v = (F32)t / (sizeT - 1);
const F32 RADIUS = (F32) 0.3;
-
+
F32* p = pt.getF32ptr();
p[0] = (F32)(sin(F_PI * v) * cos(2.0 * F_PI * u) * RADIUS);
@@ -2950,7 +2977,6 @@ void LLVolume::sculptGeneratePlaceholder()
p[2] = (F32)(cos(F_PI * v) * RADIUS);
llassert(pt.isFinite3());
-
}
line += sizeT;
}
@@ -3113,9 +3139,9 @@ void sculpt_calc_mesh_resolution(U16 width, U16 height, U8 type, F32 detail, S32
}
// sculpt replaces generate() for sculpted surfaces
-void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level)
+void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level, bool visible_placeholder)
{
- U8 sculpt_type = mParams.getSculptType();
+ U8 sculpt_type = mParams.getSculptType();
BOOL data_is_empty = FALSE;
@@ -3163,13 +3189,22 @@ void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components,
if (area < SCULPT_MIN_AREA || area > SCULPT_MAX_AREA)
{
data_is_empty = TRUE;
+ visible_placeholder = true;
}
}
}
if (data_is_empty)
{
- sculptGeneratePlaceholder();
+ if (visible_placeholder)
+ {
+ // Object should be visible since there will be nothing else to display
+ sculptGenerateSpherePlaceholder();
+ }
+ else
+ {
+ sculptGenerateEmptyPlaceholder();
+ }
}
diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h
index a8089f3709..d3c1ac46fe 100644
--- a/indra/llmath/llvolume.h
+++ b/indra/llmath/llvolume.h
@@ -1059,7 +1059,7 @@ public:
U32 mFaceMask; // bit array of which faces exist in this volume
LLVector3 mLODScaleBias; // vector for biasing LOD based on scale
- void sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level);
+ void sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level, bool visible_placeholder);
void copyVolumeFaces(const LLVolume* volume);
void copyFacesTo(std::vector<LLVolumeFace> &faces) const;
void copyFacesFrom(const std::vector<LLVolumeFace> &faces);
@@ -1068,7 +1068,8 @@ public:
private:
void sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, U8 sculpt_type);
F32 sculptGetSurfaceArea();
- void sculptGeneratePlaceholder();
+ void sculptGenerateEmptyPlaceholder();
+ void sculptGenerateSpherePlaceholder();
void sculptCalcMeshResolution(U16 width, U16 height, U8 type, S32& s, S32& t);
@@ -1088,7 +1089,7 @@ public:
F32 mSurfaceArea; //unscaled surface area
BOOL mIsMeshAssetLoaded;
- LLVolumeParams mParams;
+ const LLVolumeParams mParams;
LLPath *mPathp;
LLProfile *mProfilep;
LLAlignedArray<LLVector4a,64> mMesh;
diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp
index abe0e46e5d..ba1a2a035e 100644
--- a/indra/llmessage/llavatarnamecache.cpp
+++ b/indra/llmessage/llavatarnamecache.cpp
@@ -192,13 +192,21 @@ void LLAvatarNameCache::requestAvatarNameCache_(std::string url, std::vector<LLU
LL_DEBUGS("AvNameCache") << "Entering coroutine " << LLCoros::instance().getName()
<< " with url '" << url << "', requesting " << agentIds.size() << " Agent Ids" << LL_ENDL;
+ // Check pointer that can be cleaned up by cleanupClass()
+ if (!sHttpRequest || !sHttpOptions || !sHttpHeaders)
+ {
+ LL_WARNS("AvNameCache") << " Trying to request name cache when http pointers are not initialized." << LL_ENDL;
+ return;
+ }
+
+ LLSD httpResults;
+
try
{
bool success = true;
LLCoreHttpUtil::HttpCoroutineAdapter httpAdapter("NameCache", LLAvatarNameCache::sHttpPolicy);
LLSD results = httpAdapter.getAndSuspend(sHttpRequest, url);
- LLSD httpResults;
LL_DEBUGS() << results << LL_ENDL;
@@ -237,6 +245,7 @@ void LLAvatarNameCache::requestAvatarNameCache_(std::string url, std::vector<LLU
{
LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << LLCoros::instance().getName()
<< "('" << url << "', " << agentIds.size()
+ << " http result: " << httpResults.asString()
<< " Agent Ids)"));
throw;
}
@@ -326,6 +335,11 @@ void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id)
void LLAvatarNameCache::processName(const LLUUID& agent_id, const LLAvatarName& av_name)
{
+ if (agent_id.isNull())
+ {
+ return;
+ }
+
// Add to the cache
sCache[agent_id] = av_name;
diff --git a/indra/llmessage/llinstantmessage.cpp b/indra/llmessage/llinstantmessage.cpp
index b7f3e6e4f7..dd5a655d7e 100644
--- a/indra/llmessage/llinstantmessage.cpp
+++ b/indra/llmessage/llinstantmessage.cpp
@@ -51,98 +51,6 @@ const std::string INTERACTIVE_SYSTEM_FROM("F387446C-37C4-45f2-A438-D99CBDBB563B"
const S32 IM_TTL = 1;
-/**
- * LLIMInfo
- */
-LLIMInfo::LLIMInfo() :
- mFromGroup(FALSE),
- mParentEstateID(0),
- mOffline(0),
- mViewerThinksToIsOnline(false),
- mIMType(IM_NOTHING_SPECIAL),
- mTimeStamp(0),
- mTTL(IM_TTL)
-{
-}
-
-LLIMInfo::LLIMInfo(
- const LLUUID& from_id,
- BOOL from_group,
- const LLUUID& to_id,
- EInstantMessage im_type,
- const std::string& name,
- const std::string& message,
- const LLUUID& id,
- U32 parent_estate_id,
- const LLUUID& region_id,
- const LLVector3& position,
- LLSD data,
- U8 offline,
- U32 timestamp,
- S32 ttl) :
- mFromID(from_id),
- mFromGroup(from_group),
- mToID(to_id),
- mParentEstateID(0),
- mRegionID(region_id),
- mPosition(position),
- mOffline(offline),
- mViewerThinksToIsOnline(false),
- mIMType(im_type),
- mID(id),
- mTimeStamp(timestamp),
- mName(name),
- mMessage(message),
- mData(data),
- mTTL(ttl)
-{
-}
-
-LLIMInfo::LLIMInfo(LLMessageSystem* msg, S32 ttl) :
- mViewerThinksToIsOnline(false),
- mTTL(ttl)
-{
- unpackMessageBlock(msg);
-}
-
-LLIMInfo::~LLIMInfo()
-{
-}
-
-void LLIMInfo::packInstantMessage(LLMessageSystem* msg) const
-{
- LL_DEBUGS() << "LLIMInfo::packInstantMessage()" << LL_ENDL;
- msg->newMessageFast(_PREHASH_ImprovedInstantMessage);
- packMessageBlock(msg);
-}
-
-void LLIMInfo::packMessageBlock(LLMessageSystem* msg) const
-{
- // Construct binary bucket
- std::vector<U8> bucket;
- if (mData.has("binary_bucket"))
- {
- bucket = mData["binary_bucket"].asBinary();
- }
- pack_instant_message_block(
- msg,
- mFromID,
- mFromGroup,
- LLUUID::null,
- mToID,
- mName,
- mMessage,
- mOffline,
- mIMType,
- mID,
- mParentEstateID,
- mRegionID,
- mPosition,
- mTimeStamp,
- &bucket[0],
- bucket.size());
-}
-
void pack_instant_message(
LLMessageSystem* msg,
const LLUUID& from_id,
@@ -253,120 +161,4 @@ void pack_instant_message_block(
msg->addBinaryDataFast(_PREHASH_BinaryBucket, bb, binary_bucket_size);
}
-void LLIMInfo::unpackMessageBlock(LLMessageSystem* msg)
-{
- msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, mFromID);
- msg->getBOOLFast(_PREHASH_MessageBlock, _PREHASH_FromGroup, mFromGroup);
- msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_ToAgentID, mToID);
- msg->getU32Fast(_PREHASH_MessageBlock, _PREHASH_ParentEstateID, mParentEstateID);
- msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_RegionID, mRegionID);
- msg->getVector3Fast(_PREHASH_MessageBlock, _PREHASH_Position, mPosition);
- msg->getU8Fast(_PREHASH_MessageBlock, _PREHASH_Offline, mOffline);
- U8 dialog;
- msg->getU8Fast(_PREHASH_MessageBlock, _PREHASH_Dialog, dialog);
- mIMType = (EInstantMessage) dialog;
- msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_ID, mID);
- msg->getU32Fast(_PREHASH_MessageBlock, _PREHASH_Timestamp, mTimeStamp);
- msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_FromAgentName, mName);
-
- msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_Message, mMessage);
-
- S32 binary_bucket_size = llmin(
- MTUBYTES,
- msg->getSizeFast(
- _PREHASH_MessageBlock,
- _PREHASH_BinaryBucket));
- if(binary_bucket_size > 0)
- {
- std::vector<U8> bucket;
- bucket.resize(binary_bucket_size);
-
- msg->getBinaryDataFast(
- _PREHASH_MessageBlock,
- _PREHASH_BinaryBucket,
- &bucket[0],
- 0,
- 0,
- binary_bucket_size);
- mData["binary_bucket"] = bucket;
- }
- else
- {
- mData.clear();
- }
-}
-
-LLSD im_info_to_llsd(LLPointer<LLIMInfo> im_info)
-{
- LLSD param_version;
- param_version["version"] = 1;
- LLSD param_message;
- param_message["from_id"] = im_info->mFromID;
- param_message["from_group"] = im_info->mFromGroup;
- param_message["to_id"] = im_info->mToID;
- param_message["from_name"] = im_info->mName;
- param_message["message"] = im_info->mMessage;
- param_message["type"] = (S32)im_info->mIMType;
- param_message["id"] = im_info->mID;
- param_message["timestamp"] = (S32)im_info->mTimeStamp;
- param_message["offline"] = (S32)im_info->mOffline;
- param_message["parent_estate_id"] = (S32)im_info->mParentEstateID;
- param_message["region_id"] = im_info->mRegionID;
- param_message["position"] = ll_sd_from_vector3(im_info->mPosition);
- param_message["data"] = im_info->mData;
- param_message["ttl"] = im_info->mTTL;
-
- LLSD param_agent;
- param_agent["agent_id"] = im_info->mFromID;
-
- LLSD params;
- params["version_params"] = param_version;
- params["message_params"] = param_message;
- params["agent_params"] = param_agent;
-
- return params;
-}
-
-LLPointer<LLIMInfo> llsd_to_im_info(const LLSD& im_info_sd)
-{
- LLSD param_message = im_info_sd["message_params"];
- LLSD param_agent = im_info_sd["agent_params"];
-
- LLPointer<LLIMInfo> im_info = new LLIMInfo(
- param_message["from_id"].asUUID(),
- param_message["from_group"].asBoolean(),
- param_message["to_id"].asUUID(),
- (EInstantMessage) param_message["type"].asInteger(),
- param_message["from_name"].asString(),
- param_message["message"].asString(),
- param_message["id"].asUUID(),
- (U32) param_message["parent_estate_id"].asInteger(),
- param_message["region_id"].asUUID(),
- ll_vector3_from_sd(param_message["position"]),
- param_message["data"],
- (U8) param_message["offline"].asInteger(),
- (U32) param_message["timestamp"].asInteger(),
- param_message["ttl"].asInteger());
-
- return im_info;
-}
-
-LLPointer<LLIMInfo> LLIMInfo::clone()
-{
- return new LLIMInfo(
- mFromID,
- mFromGroup,
- mToID,
- mIMType,
- mName,
- mMessage,
- mID,
- mParentEstateID,
- mRegionID,
- mPosition,
- mData,
- mOffline,
- mTimeStamp,
- mTTL);
-}
diff --git a/indra/llmessage/llinstantmessage.h b/indra/llmessage/llinstantmessage.h
index f7118f8ccf..55cda15405 100644
--- a/indra/llmessage/llinstantmessage.h
+++ b/indra/llmessage/llinstantmessage.h
@@ -177,59 +177,6 @@ extern const std::string INTERACTIVE_SYSTEM_FROM;
// Number of retry attempts on sending the im.
extern const S32 IM_TTL;
-
-class LLIMInfo : public LLRefCount
-{
-protected:
- LLIMInfo();
- ~LLIMInfo();
-
-public:
- LLIMInfo(LLMessageSystem* msg,
- S32 ttl = IM_TTL);
-
- LLIMInfo(
- const LLUUID& from_id,
- BOOL from_group,
- const LLUUID& to_id,
- EInstantMessage im_type,
- const std::string& name,
- const std::string& message,
- const LLUUID& id,
- U32 parent_estate_id,
- const LLUUID& region_id,
- const LLVector3& position,
- LLSD data,
- U8 offline,
- U32 timestamp,
- S32 ttl = IM_TTL);
-
- void packInstantMessage(LLMessageSystem* msg) const;
- void packMessageBlock(LLMessageSystem* msg) const;
- void unpackMessageBlock(LLMessageSystem* msg);
- LLPointer<LLIMInfo> clone();
-public:
- LLUUID mFromID;
- BOOL mFromGroup;
- LLUUID mToID;
- U32 mParentEstateID;
- LLUUID mRegionID;
- LLVector3 mPosition;
- U8 mOffline;
- bool mViewerThinksToIsOnline;
- EInstantMessage mIMType;
- LLUUID mID;
- U32 mTimeStamp;
- std::string mName;
- std::string mMessage;
- LLSD mData;
-
- S32 mTTL;
-};
-
-LLPointer<LLIMInfo> llsd_to_im_info(const LLSD& im_info_sd);
-LLSD im_info_to_llsd(LLPointer<LLIMInfo> im_info);
-
void pack_instant_message(
LLMessageSystem* msgsystem,
const LLUUID& from_id,
diff --git a/indra/llmessage/llxfer.cpp b/indra/llmessage/llxfer.cpp
index e0590dfdff..c8b9d5d19f 100644
--- a/indra/llmessage/llxfer.cpp
+++ b/indra/llmessage/llxfer.cpp
@@ -63,7 +63,6 @@ void LLXfer::init (S32 chunk_size)
mXferSize = 0;
mStatus = e_LL_XFER_UNINITIALIZED;
- mNext = NULL;
mWaitingForACK = FALSE;
mCallback = NULL;
@@ -99,7 +98,22 @@ void LLXfer::cleanup ()
S32 LLXfer::startSend (U64 xfer_id, const LLHost &remote_host)
{
- LL_WARNS() << "undifferentiated LLXfer::startSend for " << getFileName() << LL_ENDL;
+ LL_WARNS("Xfer") << "unexpected call to base class LLXfer::startSend for " << getFileName() << LL_ENDL;
+ return (-1);
+}
+
+///////////////////////////////////////////////////////////
+
+void LLXfer::closeFileHandle()
+{
+ LL_WARNS("Xfer") << "unexpected call to base class LLXfer::closeFileHandle for " << getFileName() << LL_ENDL;
+}
+
+///////////////////////////////////////////////////////////
+
+S32 LLXfer::reopenFileHandle()
+{
+ LL_WARNS("Xfer") << "unexpected call to base class LLXfer::reopenFileHandle for " << getFileName() << LL_ENDL;
return (-1);
}
@@ -115,7 +129,7 @@ void LLXfer::setXferSize (S32 xfer_size)
S32 LLXfer::startDownload()
{
- LL_WARNS() << "undifferentiated LLXfer::startDownload for " << getFileName()
+ LL_WARNS("Xfer") << "undifferentiated LLXfer::startDownload for " << getFileName()
<< LL_ENDL;
return (-1);
}
@@ -127,20 +141,20 @@ S32 LLXfer::receiveData (char *datap, S32 data_size)
S32 retval = 0;
if (((S32) mBufferLength + data_size) > getMaxBufferSize())
- {
+ { // Write existing data to disk if it's larger than the buffer size
retval = flush();
}
if (!retval)
{
if (datap != NULL)
- {
+ { // Append new data to mBuffer
memcpy(&mBuffer[mBufferLength],datap,data_size); /*Flawfinder: ignore*/
mBufferLength += data_size;
}
else
{
- LL_ERRS() << "NULL data passed in receiveData" << LL_ENDL;
+ LL_ERRS("Xfer") << "NULL data passed in receiveData" << LL_ENDL;
}
}
@@ -163,7 +177,7 @@ S32 LLXfer::flush()
S32 LLXfer::suck(S32 start_position)
{
- LL_WARNS() << "Attempted to send a packet outside the buffer bounds in LLXfer::suck()" << LL_ENDL;
+ LL_WARNS("Xfer") << "Attempted to send a packet outside the buffer bounds in LLXfer::suck()" << LL_ENDL;
return (-1);
}
@@ -196,7 +210,7 @@ void LLXfer::sendPacket(S32 packet_num)
if (fdata_size < 0)
{
- LL_WARNS() << "negative data size in xfer send, aborting" << LL_ENDL;
+ LL_WARNS("Xfer") << "negative data size in xfer send, aborting" << LL_ENDL;
abort(LL_ERR_EOF);
return;
}
@@ -248,7 +262,12 @@ void LLXfer::sendPacket(S32 packet_num)
gMessageSystem->nextBlockFast(_PREHASH_DataPacket);
gMessageSystem->addBinaryDataFast(_PREHASH_Data, &fdata_buf,fdata_size);
- gMessageSystem->sendMessage(mRemoteHost);
+ S32 sent_something = gMessageSystem->sendMessage(mRemoteHost);
+ if (sent_something == 0)
+ {
+ abort(LL_ERR_CIRCUIT_GONE);
+ return;
+ }
ACKTimer.reset();
mWaitingForACK = TRUE;
@@ -289,12 +308,12 @@ S32 LLXfer::processEOF()
if (LL_ERR_NOERR == mCallbackResult)
{
- LL_INFOS() << "xfer from " << mRemoteHost << " complete: " << getFileName()
+ LL_INFOS("Xfer") << "xfer from " << mRemoteHost << " complete: " << getFileName()
<< LL_ENDL;
}
else
{
- LL_INFOS() << "xfer from " << mRemoteHost << " failed or aborted, code "
+ LL_INFOS("Xfer") << "xfer from " << mRemoteHost << " failed, code "
<< mCallbackResult << ": " << getFileName() << LL_ENDL;
}
@@ -323,15 +342,18 @@ void LLXfer::abort (S32 result_code)
{
mCallbackResult = result_code;
- LL_INFOS() << "Aborting xfer from " << mRemoteHost << " named " << getFileName()
+ LL_INFOS("Xfer") << "Aborting xfer from " << mRemoteHost << " named " << getFileName()
<< " - error: " << result_code << LL_ENDL;
- gMessageSystem->newMessageFast(_PREHASH_AbortXfer);
- gMessageSystem->nextBlockFast(_PREHASH_XferID);
- gMessageSystem->addU64Fast(_PREHASH_ID, mID);
- gMessageSystem->addS32Fast(_PREHASH_Result, result_code);
-
- gMessageSystem->sendMessage(mRemoteHost);
+ if (result_code != LL_ERR_CIRCUIT_GONE)
+ {
+ gMessageSystem->newMessageFast(_PREHASH_AbortXfer);
+ gMessageSystem->nextBlockFast(_PREHASH_XferID);
+ gMessageSystem->addU64Fast(_PREHASH_ID, mID);
+ gMessageSystem->addS32Fast(_PREHASH_Result, result_code);
+
+ gMessageSystem->sendMessage(mRemoteHost);
+ }
mStatus = e_LL_XFER_ABORTED;
}
diff --git a/indra/llmessage/llxfer.h b/indra/llmessage/llxfer.h
index edf5eeb82d..a906674dec 100644
--- a/indra/llmessage/llxfer.h
+++ b/indra/llmessage/llxfer.h
@@ -54,7 +54,6 @@ class LLXfer
S32 mChunkSize;
public:
- LLXfer *mNext;
U64 mID;
S32 mPacketNum;
@@ -62,7 +61,7 @@ class LLXfer
S32 mXferSize;
char *mBuffer;
- U32 mBufferLength;
+ U32 mBufferLength; // Size of valid data, not actual allocated buffer size
U32 mBufferStartOffset;
BOOL mBufferContainsEOF;
@@ -90,7 +89,9 @@ class LLXfer
void init(S32 chunk_size);
virtual void cleanup();
- virtual S32 startSend (U64 xfer_id, const LLHost &remote_host);
+ virtual S32 startSend(U64 xfer_id, const LLHost &remote_host);
+ virtual void closeFileHandle();
+ virtual S32 reopenFileHandle();
virtual void sendPacket(S32 packet_num);
virtual void sendNextPacket();
virtual void resendLastPacket();
diff --git a/indra/llmessage/llxfer_file.cpp b/indra/llmessage/llxfer_file.cpp
index 8e2ed890e7..7fd4222fb7 100644
--- a/indra/llmessage/llxfer_file.cpp
+++ b/indra/llmessage/llxfer_file.cpp
@@ -102,12 +102,12 @@ void LLXfer_File::cleanup ()
if (mDeleteLocalOnCompletion)
{
- LL_DEBUGS() << "Removing file: " << mLocalFilename << LL_ENDL;
+ LL_DEBUGS("Xfer") << "Removing file: " << mLocalFilename << LL_ENDL;
LLFile::remove(mLocalFilename, ENOENT);
}
else
{
- LL_DEBUGS() << "Keeping local file: " << mLocalFilename << LL_ENDL;
+ LL_DEBUGS("Xfer") << "Keeping local file: " << mLocalFilename << LL_ENDL;
}
LLXfer::cleanup();
@@ -139,7 +139,7 @@ S32 LLXfer_File::initializeRequest(U64 xfer_id,
mCallbackDataHandle = user_data;
mCallbackResult = LL_ERR_NOERR;
- LL_INFOS() << "Requesting xfer from " << remote_host << " for file: " << mLocalFilename << LL_ENDL;
+ LL_INFOS("Xfer") << "Requesting xfer from " << remote_host << " for file: " << mLocalFilename << LL_ENDL;
if (mBuffer)
{
@@ -167,6 +167,7 @@ S32 LLXfer_File::startDownload()
fclose(mFp);
mFp = NULL;
+ // tbd - is it premature to send this message if the queue is backed up?
gMessageSystem->newMessageFast(_PREHASH_RequestXfer);
gMessageSystem->nextBlockFast(_PREHASH_XferID);
gMessageSystem->addU64Fast(_PREHASH_ID, mID);
@@ -182,7 +183,7 @@ S32 LLXfer_File::startDownload()
}
else
{
- LL_WARNS() << "Couldn't create file to be received!" << LL_ENDL;
+ LL_WARNS("Xfer") << "Couldn't create file to be received!" << LL_ENDL;
retval = -1;
}
@@ -206,7 +207,8 @@ S32 LLXfer_File::startSend (U64 xfer_id, const LLHost &remote_host)
mBufferLength = 0;
mBufferStartOffset = 0;
-
+
+ // We leave the file open, assuming we'll start reading and sending soon
mFp = LLFile::fopen(mLocalFilename,"rb"); /* Flawfinder : ignore */
if (mFp)
{
@@ -223,7 +225,7 @@ S32 LLXfer_File::startSend (U64 xfer_id, const LLHost &remote_host)
}
else
{
- LL_INFOS() << "Warning: " << mLocalFilename << " not found." << LL_ENDL;
+ LL_INFOS("Xfer") << "Warning: " << mLocalFilename << " not found." << LL_ENDL;
return (LL_ERR_FILE_NOT_FOUND);
}
@@ -233,6 +235,36 @@ S32 LLXfer_File::startSend (U64 xfer_id, const LLHost &remote_host)
}
///////////////////////////////////////////////////////////
+void LLXfer_File::closeFileHandle()
+{
+ if (mFp)
+ {
+ fclose(mFp);
+ mFp = NULL;
+ }
+}
+
+///////////////////////////////////////////////////////////
+
+S32 LLXfer_File::reopenFileHandle()
+{
+ S32 retval = LL_ERR_NOERR; // presume success
+
+ if (mFp == NULL)
+ {
+ mFp = LLFile::fopen(mLocalFilename,"rb"); /* Flawfinder : ignore */
+ if (mFp == NULL)
+ {
+ LL_INFOS("Xfer") << "Warning: " << mLocalFilename << " not found when re-opening file" << LL_ENDL;
+ retval = LL_ERR_FILE_NOT_FOUND;
+ }
+ }
+
+ return retval;
+}
+
+
+///////////////////////////////////////////////////////////
S32 LLXfer_File::getMaxBufferSize ()
{
@@ -279,18 +311,21 @@ S32 LLXfer_File::flush()
{
if (mFp)
{
- LL_ERRS() << "Overwriting open file pointer!" << LL_ENDL;
+ LL_ERRS("Xfer") << "Overwriting open file pointer!" << LL_ENDL;
}
mFp = LLFile::fopen(mTempFilename,"a+b"); /* Flawfinder : ignore */
if (mFp)
{
- if (fwrite(mBuffer,1,mBufferLength,mFp) != mBufferLength)
+ S32 write_size = fwrite(mBuffer,1,mBufferLength,mFp);
+ if (write_size != mBufferLength)
{
- LL_WARNS() << "Short write" << LL_ENDL;
+ LL_WARNS("Xfer") << "Non-matching write size, requested " << mBufferLength
+ << " but wrote " << write_size
+ << LL_ENDL;
}
-// LL_INFOS() << "******* wrote " << mBufferLength << " bytes of file xfer" << LL_ENDL;
+// LL_INFOS("Xfer") << "******* wrote " << mBufferLength << " bytes of file xfer" << LL_ENDL;
fclose(mFp);
mFp = NULL;
@@ -298,7 +333,7 @@ S32 LLXfer_File::flush()
}
else
{
- LL_WARNS() << "LLXfer_File::flush() unable to open " << mTempFilename << " for writing!" << LL_ENDL;
+ LL_WARNS("Xfer") << "LLXfer_File::flush() unable to open " << mTempFilename << " for writing!" << LL_ENDL;
retval = LL_ERR_CANNOT_OPEN_FILE;
}
}
@@ -329,18 +364,18 @@ S32 LLXfer_File::processEOF()
{
#if !LL_WINDOWS
S32 error_number = errno;
- LL_INFOS() << "Rename failure (" << error_number << ") - "
+ LL_INFOS("Xfer") << "Rename failure (" << error_number << ") - "
<< mTempFilename << " to " << mLocalFilename << LL_ENDL;
if(EXDEV == error_number)
{
if(copy_file(mTempFilename, mLocalFilename) == 0)
{
- LL_INFOS() << "Rename across mounts; copying+unlinking the file instead." << LL_ENDL;
+ LL_INFOS("Xfer") << "Rename across mounts; copying+unlinking the file instead." << LL_ENDL;
unlink(mTempFilename.c_str());
}
else
{
- LL_WARNS() << "Copy failure - " << mTempFilename << " to "
+ LL_WARNS("Xfer") << "Copy failure - " << mTempFilename << " to "
<< mLocalFilename << LL_ENDL;
}
}
@@ -354,11 +389,11 @@ S32 LLXfer_File::processEOF()
//LL_WARNS() << "File " << mLocalFilename << " does "
// << (!fp ? "not" : "" ) << " exit." << LL_ENDL;
//if(fp) fclose(fp);
- LL_WARNS() << "Rename fatally failed, can only handle EXDEV ("
+ LL_WARNS("Xfer") << "Rename fatally failed, can only handle EXDEV ("
<< EXDEV << ")" << LL_ENDL;
}
#else
- LL_WARNS() << "Rename failure - " << mTempFilename << " to "
+ LL_WARNS("Xfer") << "Rename failure - " << mTempFilename << " to "
<< mLocalFilename << LL_ENDL;
#endif
}
@@ -437,3 +472,4 @@ S32 copy_file(const std::string& from, const std::string& to)
return rv;
}
#endif
+
diff --git a/indra/llmessage/llxfer_file.h b/indra/llmessage/llxfer_file.h
index a37dda6732..ab9374549e 100644
--- a/indra/llmessage/llxfer_file.h
+++ b/indra/llmessage/llxfer_file.h
@@ -61,8 +61,10 @@ class LLXfer_File : public LLXfer
virtual S32 startDownload();
virtual S32 processEOF();
-
- virtual S32 startSend (U64 xfer_id, const LLHost &remote_host);
+
+ virtual S32 startSend(U64 xfer_id, const LLHost &remote_host);
+ virtual void closeFileHandle();
+ virtual S32 reopenFileHandle();
virtual S32 suck(S32 start_position);
virtual S32 flush();
diff --git a/indra/llmessage/llxfer_mem.cpp b/indra/llmessage/llxfer_mem.cpp
index 3bea08f2e5..78a3e4f558 100644
--- a/indra/llmessage/llxfer_mem.cpp
+++ b/indra/llmessage/llxfer_mem.cpp
@@ -80,28 +80,6 @@ void LLXfer_Mem::setXferSize (S32 xfer_size)
///////////////////////////////////////////////////////////
-U64 LLXfer_Mem::registerXfer(U64 xfer_id, const void *datap, const S32 length)
-{
- mID = xfer_id;
-
- if (datap)
- {
- setXferSize(length);
- if (mBuffer)
- {
- memcpy(mBuffer,datap,length); /* Flawfinder : ignore */
- mBufferLength = length;
- }
- else
- {
- xfer_id = 0;
- }
- }
-
- mStatus = e_LL_XFER_REGISTERED;
- return (xfer_id);
-}
-
S32 LLXfer_Mem::startSend (U64 xfer_id, const LLHost &remote_host)
{
S32 retval = LL_ERR_NOERR; // presume success
diff --git a/indra/llmessage/llxfer_mem.h b/indra/llmessage/llxfer_mem.h
index b5adf837df..d07779de87 100644
--- a/indra/llmessage/llxfer_mem.h
+++ b/indra/llmessage/llxfer_mem.h
@@ -53,7 +53,6 @@ class LLXfer_Mem : public LLXfer
virtual void cleanup();
virtual S32 startSend (U64 xfer_id, const LLHost &remote_host);
- virtual U64 registerXfer(U64 xfer_id, const void *datap, const S32 length);
virtual void setXferSize (S32 data_size);
virtual S32 initializeRequest(U64 xfer_id,
diff --git a/indra/llmessage/llxfer_vfile.cpp b/indra/llmessage/llxfer_vfile.cpp
index 4a378d1d34..ddc24342f6 100644
--- a/indra/llmessage/llxfer_vfile.cpp
+++ b/indra/llmessage/llxfer_vfile.cpp
@@ -79,8 +79,20 @@ void LLXfer_VFile::init (LLVFS *vfs, const LLUUID &local_id, LLAssetType::EType
void LLXfer_VFile::cleanup ()
{
- LLVFile file(mVFS, mTempID, mType, LLVFile::WRITE);
- file.remove();
+ if (mTempID.notNull() &&
+ mDeleteTempFile)
+ {
+ if (mVFS->getExists(mTempID, mType))
+ {
+ LLVFile file(mVFS, mTempID, mType, LLVFile::WRITE);
+ file.remove();
+ }
+ else
+ {
+ LL_WARNS("Xfer") << "LLXfer_VFile::cleanup() can't open to delete VFS file " << mTempID << "." << LLAssetType::lookup(mType)
+ << ", mRemoteID is " << mRemoteID << LL_ENDL;
+ }
+ }
delete mVFile;
mVFile = NULL;
@@ -118,7 +130,7 @@ S32 LLXfer_VFile::initializeRequest(U64 xfer_id,
mName = llformat("VFile %s:%s", id_string.c_str(), LLAssetType::lookup(mType));
- LL_INFOS() << "Requesting " << mName << LL_ENDL;
+ LL_INFOS("Xfer") << "Requesting " << mName << LL_ENDL;
if (mBuffer)
{
@@ -131,6 +143,7 @@ S32 LLXfer_VFile::initializeRequest(U64 xfer_id,
mBufferLength = 0;
mPacketNum = 0;
mTempID.generate();
+ mDeleteTempFile = TRUE;
mStatus = e_LL_XFER_PENDING;
return retval;
}
@@ -140,7 +153,8 @@ S32 LLXfer_VFile::initializeRequest(U64 xfer_id,
S32 LLXfer_VFile::startDownload()
{
S32 retval = 0; // presume success
- LLVFile file(mVFS, mTempID, mType, LLVFile::APPEND);
+
+ // Don't need to create the file here, it will happen when data arrives
gMessageSystem->newMessageFast(_PREHASH_RequestXfer);
gMessageSystem->nextBlockFast(_PREHASH_XferID);
@@ -184,6 +198,8 @@ S32 LLXfer_VFile::startSend (U64 xfer_id, const LLHost &remote_host)
if (mVFile->getSize() <= 0)
{
+ LL_WARNS("Xfer") << "LLXfer_VFile::startSend() VFS file " << mLocalID << "." << LLAssetType::lookup(mType)
+ << " has unexpected file size of " << mVFile->getSize() << LL_ENDL;
delete mVFile;
mVFile = NULL;
@@ -198,6 +214,7 @@ S32 LLXfer_VFile::startSend (U64 xfer_id, const LLHost &remote_host)
}
else
{
+ LL_WARNS("Xfer") << "LLXfer_VFile::startSend() can't read VFS file " << mLocalID << "." << LLAssetType::lookup(mType) << LL_ENDL;
retval = LL_ERR_FILE_NOT_FOUND;
}
@@ -205,6 +222,41 @@ S32 LLXfer_VFile::startSend (U64 xfer_id, const LLHost &remote_host)
}
///////////////////////////////////////////////////////////
+
+void LLXfer_VFile::closeFileHandle()
+{
+ if (mVFile)
+ {
+ delete mVFile;
+ mVFile = NULL;
+ }
+}
+
+///////////////////////////////////////////////////////////
+
+S32 LLXfer_VFile::reopenFileHandle()
+{
+ S32 retval = LL_ERR_NOERR; // presume success
+
+ if (mVFile == NULL)
+ {
+ if (mVFS->getExists(mLocalID, mType))
+ {
+ mVFile = new LLVFile(mVFS, mLocalID, mType, LLVFile::READ);
+ }
+ else
+ {
+ LL_WARNS("Xfer") << "LLXfer_VFile::reopenFileHandle() can't read VFS file " << mLocalID << "." << LLAssetType::lookup(mType) << LL_ENDL;
+ retval = LL_ERR_FILE_NOT_FOUND;
+ }
+ }
+
+ return retval;
+}
+
+
+///////////////////////////////////////////////////////////
+
void LLXfer_VFile::setXferSize (S32 xfer_size)
{
LLXfer::setXferSize(xfer_size);
@@ -236,8 +288,8 @@ S32 LLXfer_VFile::suck(S32 start_position)
// grab a buffer from the right place in the file
if (! mVFile->seek(start_position, 0))
{
- LL_WARNS() << "VFile Xfer Can't seek to position " << start_position << ", file length " << mVFile->getSize() << LL_ENDL;
- LL_WARNS() << "While sending file " << mLocalID << LL_ENDL;
+ LL_WARNS("Xfer") << "VFile Xfer Can't seek to position " << start_position << ", file length " << mVFile->getSize() << LL_ENDL;
+ LL_WARNS("Xfer") << "While sending file " << mLocalID << LL_ENDL;
return -1;
}
@@ -288,12 +340,31 @@ S32 LLXfer_VFile::processEOF()
if (!mCallbackResult)
{
- LLVFile file(mVFS, mTempID, mType, LLVFile::WRITE);
- if (! file.rename(mLocalID, mType))
+ if (mVFS->getExists(mTempID, mType))
{
- LL_INFOS() << "copy from temp file failed: unable to rename to " << mLocalID << LL_ENDL;
+ LLVFile file(mVFS, mTempID, mType, LLVFile::WRITE);
+ if (!file.rename(mLocalID, mType))
+ {
+ LL_WARNS("Xfer") << "VFS rename of temp file failed: unable to rename " << mTempID << " to " << mLocalID << LL_ENDL;
+ }
+ else
+ {
+ #ifdef VFS_SPAM
+ // Debugging spam
+ LL_INFOS("Xfer") << "VFS rename of temp file done: renamed " << mTempID << " to " << mLocalID
+ << " LLVFile size is " << file.getSize()
+ << LL_ENDL;
+ #endif
+
+ // Rename worked: the original file is gone. Clear mDeleteTempFile
+ // so we don't attempt to delete the file in cleanup()
+ mDeleteTempFile = FALSE;
+ }
+ }
+ else
+ {
+ LL_WARNS("Xfer") << "LLXfer_VFile::processEOF() can't open for renaming VFS file " << mTempID << "." << LLAssetType::lookup(mType) << LL_ENDL;
}
-
}
if (mVFile)
@@ -336,3 +407,4 @@ U32 LLXfer_VFile::getXferTypeTag()
{
return LLXfer::XFER_VFILE;
}
+
diff --git a/indra/llmessage/llxfer_vfile.h b/indra/llmessage/llxfer_vfile.h
index 048bf49dcc..5bf9a5cfba 100644
--- a/indra/llmessage/llxfer_vfile.h
+++ b/indra/llmessage/llxfer_vfile.h
@@ -47,6 +47,8 @@ class LLXfer_VFile : public LLXfer
std::string mName;
+ BOOL mDeleteTempFile;
+
public:
LLXfer_VFile ();
LLXfer_VFile (LLVFS *vfs, const LLUUID &local_id, LLAssetType::EType type);
@@ -66,8 +68,10 @@ class LLXfer_VFile : public LLXfer
virtual S32 startDownload();
virtual S32 processEOF();
-
- virtual S32 startSend (U64 xfer_id, const LLHost &remote_host);
+
+ virtual S32 startSend(U64 xfer_id, const LLHost &remote_host);
+ virtual void closeFileHandle();
+ virtual S32 reopenFileHandle();
virtual S32 suck(S32 start_position);
virtual S32 flush();
diff --git a/indra/llmessage/llxfermanager.cpp b/indra/llmessage/llxfermanager.cpp
index 2ceb64ce8f..4cea886c8a 100644
--- a/indra/llmessage/llxfermanager.cpp
+++ b/indra/llmessage/llxfermanager.cpp
@@ -44,9 +44,15 @@ const S32 LL_PACKET_RETRY_LIMIT = 10; // packet retransmission limit
const S32 LL_DEFAULT_MAX_SIMULTANEOUS_XFERS = 10;
const S32 LL_DEFAULT_MAX_REQUEST_FIFO_XFERS = 1000;
-#define LL_XFER_PROGRESS_MESSAGES 0
-#define LL_XFER_TEST_REXMIT 0
+// Kills the connection if a viewer download queue hits this many requests backed up
+// Also set in simulator.xml at "hard_limit_outgoing_xfers_per_circuit"
+const S32 LL_DEFAULT_MAX_HARD_LIMIT_SIMULTANEOUS_XFERS = 500;
+// Use this to show sending some ConfirmXferPacket messages
+//#define LL_XFER_PROGRESS_MESSAGES 1
+
+// Use this for lots of diagnostic spam
+//#define LL_XFER_DIAGNOISTIC_LOGGING 1
///////////////////////////////////////////////////////////
@@ -66,10 +72,10 @@ LLXferManager::~LLXferManager ()
void LLXferManager::init (LLVFS *vfs)
{
- mSendList = NULL;
- mReceiveList = NULL;
+ cleanup();
setMaxOutgoingXfersPerCircuit(LL_DEFAULT_MAX_SIMULTANEOUS_XFERS);
+ setHardLimitOutgoingXfersPerCircuit(LL_DEFAULT_MAX_HARD_LIMIT_SIMULTANEOUS_XFERS);
setMaxIncomingXfers(LL_DEFAULT_MAX_REQUEST_FIFO_XFERS);
mVFS = vfs;
@@ -83,29 +89,14 @@ void LLXferManager::init (LLVFS *vfs)
void LLXferManager::cleanup ()
{
- LLXfer *xferp;
- LLXfer *delp;
-
for_each(mOutgoingHosts.begin(), mOutgoingHosts.end(), DeletePointer());
mOutgoingHosts.clear();
- delp = mSendList;
- while (delp)
- {
- xferp = delp->mNext;
- delete delp;
- delp = xferp;
- }
- mSendList = NULL;
+ for_each(mSendList.begin(), mSendList.end(), DeletePointer());
+ mSendList.clear();
- delp = mReceiveList;
- while (delp)
- {
- xferp = delp->mNext;
- delete delp;
- delp = xferp;
- }
- mReceiveList = NULL;
+ for_each(mReceiveList.begin(), mReceiveList.end(), DeletePointer());
+ mReceiveList.clear();
}
///////////////////////////////////////////////////////////
@@ -122,6 +113,11 @@ void LLXferManager::setMaxOutgoingXfersPerCircuit(S32 max_num)
mMaxOutgoingXfersPerCircuit = max_num;
}
+void LLXferManager::setHardLimitOutgoingXfersPerCircuit(S32 max_num)
+{
+ mHardLimitOutgoingXfersPerCircuit = max_num;
+}
+
void LLXferManager::setUseAckThrottling(const BOOL use)
{
mUseAckThrottling = use;
@@ -140,6 +136,11 @@ void LLXferManager::setAckThrottleBPS(const F32 bps)
F32 actual_rate = llmax(min_bps*1.1f, bps);
LL_DEBUGS("AppInit") << "LLXferManager ack throttle min rate: " << min_bps << LL_ENDL;
LL_DEBUGS("AppInit") << "LLXferManager ack throttle actual rate: " << actual_rate << LL_ENDL;
+ #ifdef LL_XFER_DIAGNOISTIC_LOGGING
+ LL_INFOS("Xfer") << "LLXferManager ack throttle min rate: " << min_bps << LL_ENDL;
+ LL_INFOS("Xfer") << "LLXferManager ack throttle actual rate: " << actual_rate << LL_ENDL;
+ #endif // LL_XFER_DIAGNOISTIC_LOGGING
+
mAckThrottle.setRate(actual_rate);
}
@@ -148,45 +149,71 @@ void LLXferManager::setAckThrottleBPS(const F32 bps)
void LLXferManager::updateHostStatus()
{
- LLXfer *xferp;
- LLHostStatus *host_statusp = NULL;
-
+ // Clear the outgoing host list
for_each(mOutgoingHosts.begin(), mOutgoingHosts.end(), DeletePointer());
mOutgoingHosts.clear();
-
- for (xferp = mSendList; xferp; xferp = xferp->mNext)
+
+ // Loop through all outgoing xfers and re-build mOutgoingHosts
+ for (xfer_list_t::iterator send_iter = mSendList.begin();
+ send_iter != mSendList.end(); ++send_iter)
{
+ LLHostStatus *host_statusp = NULL;
for (status_list_t::iterator iter = mOutgoingHosts.begin();
iter != mOutgoingHosts.end(); ++iter)
{
- host_statusp = *iter;
- if (host_statusp->mHost == xferp->mRemoteHost)
- {
+ if ((*iter)->mHost == (*send_iter)->mRemoteHost)
+ { // Already have this host
+ host_statusp = *iter;
break;
}
}
if (!host_statusp)
- {
+ { // Don't have this host, so add it
host_statusp = new LLHostStatus();
if (host_statusp)
{
- host_statusp->mHost = xferp->mRemoteHost;
+ host_statusp->mHost = (*send_iter)->mRemoteHost;
mOutgoingHosts.push_front(host_statusp);
}
}
if (host_statusp)
- {
- if (xferp->mStatus == e_LL_XFER_PENDING)
+ { // Do the accounting
+ if ((*send_iter)->mStatus == e_LL_XFER_PENDING)
{
host_statusp->mNumPending++;
}
- else if (xferp->mStatus == e_LL_XFER_IN_PROGRESS)
+ else if ((*send_iter)->mStatus == e_LL_XFER_IN_PROGRESS)
{
host_statusp->mNumActive++;
}
}
-
}
+
+#ifdef LL_XFER_DIAGNOISTIC_LOGGING
+ for (xfer_list_t::iterator send_iter = mSendList.begin();
+ send_iter != mSendList.end(); ++send_iter)
+ {
+ LLXfer * xferp = *send_iter;
+ LL_INFOS("Xfer") << "xfer to host " << xferp->mRemoteHost
+ << " is " << xferp->mXferSize << " bytes"
+ << ", status " << (S32)(xferp->mStatus)
+ << ", waiting for ACK: " << (S32)(xferp->mWaitingForACK)
+ << " in frame " << (S32) LLFrameTimer::getFrameCount()
+ << LL_ENDL;
+ }
+
+ for (status_list_t::iterator iter = mOutgoingHosts.begin();
+ iter != mOutgoingHosts.end(); ++iter)
+ {
+ LL_INFOS("Xfer") << "LLXfer host " << (*iter)->mHost.getIPandPort()
+ << " has " << (*iter)->mNumActive
+ << " active, " << (*iter)->mNumPending
+ << " pending"
+ << " in frame " << (S32) LLFrameTimer::getFrameCount()
+ << LL_ENDL;
+ }
+#endif // LL_XFER_DIAGNOISTIC_LOGGING
+
}
///////////////////////////////////////////////////////////
@@ -196,27 +223,28 @@ void LLXferManager::printHostStatus()
LLHostStatus *host_statusp = NULL;
if (!mOutgoingHosts.empty())
{
- LL_INFOS() << "Outgoing Xfers:" << LL_ENDL;
+ LL_INFOS("Xfer") << "Outgoing Xfers:" << LL_ENDL;
for (status_list_t::iterator iter = mOutgoingHosts.begin();
iter != mOutgoingHosts.end(); ++iter)
{
host_statusp = *iter;
- LL_INFOS() << " " << host_statusp->mHost << " active: " << host_statusp->mNumActive << " pending: " << host_statusp->mNumPending << LL_ENDL;
+ LL_INFOS("Xfer") << " " << host_statusp->mHost << " active: " << host_statusp->mNumActive << " pending: " << host_statusp->mNumPending << LL_ENDL;
}
}
}
///////////////////////////////////////////////////////////
-LLXfer *LLXferManager::findXfer (U64 id, LLXfer *list_head)
+LLXfer * LLXferManager::findXferByID(U64 id, xfer_list_t & xfer_list)
{
- LLXfer *xferp;
- for (xferp = list_head; xferp; xferp = xferp->mNext)
+ for (xfer_list_t::iterator iter = xfer_list.begin();
+ iter != xfer_list.end();
+ ++iter)
{
- if (xferp->mID == id)
+ if ((*iter)->mID == id)
{
- return(xferp);
+ return(*iter);
}
}
return(NULL);
@@ -225,29 +253,34 @@ LLXfer *LLXferManager::findXfer (U64 id, LLXfer *list_head)
///////////////////////////////////////////////////////////
-void LLXferManager::removeXfer (LLXfer *delp, LLXfer **list_head)
+// WARNING: this invalidates iterators from xfer_list
+void LLXferManager::removeXfer(LLXfer *delp, xfer_list_t & xfer_list)
{
- // This function assumes that delp will only occur in the list
- // zero or one times.
if (delp)
- {
- if (*list_head == delp)
+ {
+ std::string direction = "send";
+ if (&xfer_list == &mReceiveList)
{
- *list_head = delp->mNext;
- delete (delp);
+ direction = "receive";
}
- else
+
+ // This assumes that delp will occur in the list once at most
+ // Find the pointer in the list
+ for (xfer_list_t::iterator iter = xfer_list.begin();
+ iter != xfer_list.end();
+ ++iter)
{
- LLXfer *xferp = *list_head;
- while (xferp->mNext)
+ if ((*iter) == delp)
{
- if (xferp->mNext == delp)
- {
- xferp->mNext = delp->mNext;
- delete (delp);
- break;
- }
- xferp = xferp->mNext;
+ LL_DEBUGS("Xfer") << "Deleting xfer to host " << (*iter)->mRemoteHost
+ << " of " << (*iter)->mXferSize << " bytes"
+ << ", status " << (S32)((*iter)->mStatus)
+ << " from the " << direction << " list"
+ << LL_ENDL;
+
+ xfer_list.erase(iter);
+ delete (delp);
+ break;
}
}
}
@@ -255,35 +288,30 @@ void LLXferManager::removeXfer (LLXfer *delp, LLXfer **list_head)
///////////////////////////////////////////////////////////
-U32 LLXferManager::numActiveListEntries(LLXfer *list_head)
+LLHostStatus * LLXferManager::findHostStatus(const LLHost &host)
{
- U32 num_entries = 0;
+ LLHostStatus *host_statusp = NULL;
- while (list_head)
+ for (status_list_t::iterator iter = mOutgoingHosts.begin();
+ iter != mOutgoingHosts.end(); ++iter)
{
- if (list_head->mStatus == e_LL_XFER_IN_PROGRESS)
+ host_statusp = *iter;
+ if (host_statusp->mHost == host)
{
- num_entries++;
+ return (host_statusp);
}
- list_head = list_head->mNext;
}
- return(num_entries);
+ return 0;
}
///////////////////////////////////////////////////////////
-
+
S32 LLXferManager::numPendingXfers(const LLHost &host)
{
- LLHostStatus *host_statusp = NULL;
-
- for (status_list_t::iterator iter = mOutgoingHosts.begin();
- iter != mOutgoingHosts.end(); ++iter)
+ LLHostStatus *host_statusp = findHostStatus(host);
+ if (host_statusp)
{
- host_statusp = *iter;
- if (host_statusp->mHost == host)
- {
- return (host_statusp->mNumPending);
- }
+ return host_statusp->mNumPending;
}
return 0;
}
@@ -292,16 +320,10 @@ S32 LLXferManager::numPendingXfers(const LLHost &host)
S32 LLXferManager::numActiveXfers(const LLHost &host)
{
- LLHostStatus *host_statusp = NULL;
-
- for (status_list_t::iterator iter = mOutgoingHosts.begin();
- iter != mOutgoingHosts.end(); ++iter)
+ LLHostStatus *host_statusp = findHostStatus(host);
+ if (host_statusp)
{
- host_statusp = *iter;
- if (host_statusp->mHost == host)
- {
- return (host_statusp->mNumActive);
- }
+ return host_statusp->mNumActive;
}
return 0;
}
@@ -372,35 +394,6 @@ BOOL LLXferManager::isLastPacket(S32 packet_num)
///////////////////////////////////////////////////////////
-U64 LLXferManager::registerXfer(const void *datap, const S32 length)
-{
- LLXfer *xferp;
- U64 xfer_id = getNextID();
-
- xferp = (LLXfer *) new LLXfer_Mem();
- if (xferp)
- {
- xferp->mNext = mSendList;
- mSendList = xferp;
-
- xfer_id = ((LLXfer_Mem *)xferp)->registerXfer(xfer_id, datap,length);
-
- if (!xfer_id)
- {
- removeXfer(xferp,&mSendList);
- }
- }
- else
- {
- LL_ERRS() << "Xfer allocation error" << LL_ENDL;
- xfer_id = 0;
- }
-
- return(xfer_id);
-}
-
-///////////////////////////////////////////////////////////
-
U64 LLXferManager::requestFile(const std::string& local_filename,
const std::string& remote_filename,
ELLPath remote_path,
@@ -411,43 +404,46 @@ U64 LLXferManager::requestFile(const std::string& local_filename,
BOOL is_priority,
BOOL use_big_packets)
{
- LLXfer *xferp;
+ LLXfer_File* file_xfer_p = NULL;
- for (xferp = mReceiveList; xferp ; xferp = xferp->mNext)
+ // First check to see if it's already requested
+ for (xfer_list_t::iterator iter = mReceiveList.begin();
+ iter != mReceiveList.end(); ++iter)
{
- if (xferp->getXferTypeTag() == LLXfer::XFER_FILE
- && (((LLXfer_File*)xferp)->matchesLocalFilename(local_filename))
- && (((LLXfer_File*)xferp)->matchesRemoteFilename(remote_filename, remote_path))
- && (remote_host == xferp->mRemoteHost)
- && (callback == xferp->mCallback)
- && (user_data == xferp->mCallbackDataHandle))
-
+ if ((*iter)->getXferTypeTag() == LLXfer::XFER_FILE)
{
- // cout << "requested a xfer already in progress" << endl;
- return xferp->mID;
+ file_xfer_p = (LLXfer_File*)(*iter);
+ if (file_xfer_p->matchesLocalFilename(local_filename)
+ && file_xfer_p->matchesRemoteFilename(remote_filename, remote_path)
+ && (remote_host == file_xfer_p->mRemoteHost)
+ && (callback == file_xfer_p->mCallback)
+ && (user_data == file_xfer_p->mCallbackDataHandle))
+ {
+ // Already have the request (already in progress)
+ return (*iter)->mID;
+ }
}
}
U64 xfer_id = 0;
S32 chunk_size = use_big_packets ? LL_XFER_LARGE_PAYLOAD : -1;
- xferp = (LLXfer *) new LLXfer_File(chunk_size);
- if (xferp)
+ file_xfer_p = new LLXfer_File(chunk_size);
+ if (file_xfer_p)
{
- addToList(xferp, mReceiveList, is_priority);
+ addToList(file_xfer_p, mReceiveList, is_priority);
// Remove any file by the same name that happens to be lying
// around.
// Note: according to AaronB, this is here to deal with locks on files that were
// in transit during a crash,
- if( delete_remote_on_completion
- && (remote_filename.substr(remote_filename.length()-4) == ".tmp")
- && gDirUtilp->fileExists(local_filename))
+ if(delete_remote_on_completion &&
+ (remote_filename.substr(remote_filename.length()-4) == ".tmp"))
{
LLFile::remove(local_filename, ENOENT);
}
xfer_id = getNextID();
- ((LLXfer_File *)xferp)->initializeRequest(
+ file_xfer_p->initializeRequest(
xfer_id,
local_filename,
remote_filename,
@@ -459,39 +455,11 @@ U64 LLXferManager::requestFile(const std::string& local_filename,
}
else
{
- LL_ERRS() << "Xfer allocation error" << LL_ENDL;
+ LL_ERRS("Xfer") << "Xfer allocation error" << LL_ENDL;
}
return xfer_id;
}
-void LLXferManager::requestFile(const std::string& remote_filename,
- ELLPath remote_path,
- const LLHost& remote_host,
- BOOL delete_remote_on_completion,
- void (*callback)(void*,S32,void**,S32,LLExtStat),
- void** user_data,
- BOOL is_priority)
-{
- LLXfer *xferp;
-
- xferp = (LLXfer *) new LLXfer_Mem();
- if (xferp)
- {
- addToList(xferp, mReceiveList, is_priority);
- ((LLXfer_Mem *)xferp)->initializeRequest(getNextID(),
- remote_filename,
- remote_path,
- remote_host,
- delete_remote_on_completion,
- callback, user_data);
- startPendingDownloads();
- }
- else
- {
- LL_ERRS() << "Xfer allocation error" << LL_ENDL;
- }
-}
-
void LLXferManager::requestVFile(const LLUUID& local_id,
const LLUUID& remote_id,
LLAssetType::EType type, LLVFS* vfs,
@@ -500,28 +468,46 @@ void LLXferManager::requestVFile(const LLUUID& local_id,
void** user_data,
BOOL is_priority)
{
- LLXfer *xferp;
-
- for (xferp = mReceiveList; xferp ; xferp = xferp->mNext)
- {
- if (xferp->getXferTypeTag() == LLXfer::XFER_VFILE
- && (((LLXfer_VFile*)xferp)->matchesLocalFile(local_id, type))
- && (((LLXfer_VFile*)xferp)->matchesRemoteFile(remote_id, type))
- && (remote_host == xferp->mRemoteHost)
- && (callback == xferp->mCallback)
- && (user_data == xferp->mCallbackDataHandle))
+ LLXfer_VFile * xfer_p = NULL;
+ for (xfer_list_t::iterator iter = mReceiveList.begin();
+ iter != mReceiveList.end(); ++iter)
+ { // Find any matching existing requests
+ if ((*iter)->getXferTypeTag() == LLXfer::XFER_VFILE)
{
- // cout << "requested a xfer already in progress" << endl;
- return;
+ xfer_p = (LLXfer_VFile*) (*iter);
+ if (xfer_p->matchesLocalFile(local_id, type)
+ && xfer_p->matchesRemoteFile(remote_id, type)
+ && (remote_host == xfer_p->mRemoteHost)
+ && (callback == xfer_p->mCallback)
+ && (user_data == xfer_p->mCallbackDataHandle))
+
+ { // Have match, don't add a duplicate
+ #ifdef LL_XFER_DIAGNOISTIC_LOGGING
+ LL_INFOS("Xfer") << "Dropping duplicate xfer request for " << remote_id
+ << " on " << remote_host.getIPandPort()
+ << " local id " << local_id
+ << LL_ENDL;
+ #endif // LL_XFER_DIAGNOISTIC_LOGGING
+
+ return;
+ }
}
}
- xferp = (LLXfer *) new LLXfer_VFile();
- if (xferp)
+ xfer_p = new LLXfer_VFile();
+ if (xfer_p)
{
- addToList(xferp, mReceiveList, is_priority);
- ((LLXfer_VFile *)xferp)->initializeRequest(getNextID(),
+ #ifdef LL_XFER_DIAGNOISTIC_LOGGING
+ LL_INFOS("Xfer") << "Starting file xfer for " << remote_id
+ << " type " << LLAssetType::lookupHumanReadable(type)
+ << " from " << xfer_p->mRemoteHost.getIPandPort()
+ << ", local id " << local_id
+ << LL_ENDL;
+ #endif // LL_XFER_DIAGNOISTIC_LOGGING
+
+ addToList(xfer_p, mReceiveList, is_priority);
+ ((LLXfer_VFile *)xfer_p)->initializeRequest(getNextID(),
vfs,
local_id,
remote_id,
@@ -533,78 +519,18 @@ void LLXferManager::requestVFile(const LLUUID& local_id,
}
else
{
- LL_ERRS() << "Xfer allocation error" << LL_ENDL;
- }
-
-}
-
-/*
-void LLXferManager::requestXfer(
- const std::string& local_filename,
- BOOL delete_remote_on_completion,
- U64 xfer_id,
- const LLHost &remote_host,
- void (*callback)(void **,S32),
- void **user_data)
-{
- LLXfer *xferp;
-
- for (xferp = mReceiveList; xferp ; xferp = xferp->mNext)
- {
- if (xferp->getXferTypeTag() == LLXfer::XFER_FILE
- && (((LLXfer_File*)xferp)->matchesLocalFilename(local_filename))
- && (xfer_id == xferp->mID)
- && (remote_host == xferp->mRemoteHost)
- && (callback == xferp->mCallback)
- && (user_data == xferp->mCallbackDataHandle))
-
- {
- // cout << "requested a xfer already in progress" << endl;
- return;
- }
+ LL_ERRS("Xfer") << "Xfer allocation error" << LL_ENDL;
}
- xferp = (LLXfer *) new LLXfer_File();
- if (xferp)
- {
- xferp->mNext = mReceiveList;
- mReceiveList = xferp;
-
- ((LLXfer_File *)xferp)->initializeRequest(xfer_id,local_filename,"",LL_PATH_NONE,remote_host,delete_remote_on_completion,callback,user_data);
- startPendingDownloads();
- }
- else
- {
- LL_ERRS() << "Xfer allcoation error" << LL_ENDL;
- }
}
-void LLXferManager::requestXfer(U64 xfer_id, const LLHost &remote_host, BOOL delete_remote_on_completion, void (*callback)(void *,S32,void **,S32),void **user_data)
-{
- LLXfer *xferp;
-
- xferp = (LLXfer *) new LLXfer_Mem();
- if (xferp)
- {
- xferp->mNext = mReceiveList;
- mReceiveList = xferp;
-
- ((LLXfer_Mem *)xferp)->initializeRequest(xfer_id,"",LL_PATH_NONE,remote_host,delete_remote_on_completion,callback,user_data);
- startPendingDownloads();
- }
- else
- {
- LL_ERRS() << "Xfer allcoation error" << LL_ENDL;
- }
-}
-*/
///////////////////////////////////////////////////////////
void LLXferManager::processReceiveData (LLMessageSystem *mesgsys, void ** /*user_data*/)
{
// there's sometimes an extra 4 bytes added to an xfer payload
const S32 BUF_SIZE = LL_XFER_LARGE_PAYLOAD + 4;
- char fdata_buf[LL_XFER_LARGE_PAYLOAD + 4]; /* Flawfinder : ignore */
+ char fdata_buf[BUF_SIZE]; /* Flawfinder : ignore */
S32 fdata_size;
U64 id;
S32 packetnum;
@@ -614,14 +540,24 @@ void LLXferManager::processReceiveData (LLMessageSystem *mesgsys, void ** /*user
mesgsys->getS32Fast(_PREHASH_XferID, _PREHASH_Packet, packetnum);
fdata_size = mesgsys->getSizeFast(_PREHASH_DataPacket,_PREHASH_Data);
- mesgsys->getBinaryDataFast(_PREHASH_DataPacket, _PREHASH_Data, fdata_buf, 0, 0, BUF_SIZE);
-
- xferp = findXfer(id, mReceiveList);
+ if (fdata_size < 0 ||
+ fdata_size > BUF_SIZE)
+ {
+ char U64_BUF[MAX_STRING]; /* Flawfinder : ignore */
+ LL_WARNS("Xfer") << "Received invalid xfer data size of " << fdata_size
+ << " in packet number " << packetnum
+ << " from " << mesgsys->getSender()
+ << " for xfer id: " << U64_to_str(id, U64_BUF, sizeof(U64_BUF))
+ << LL_ENDL;
+ return;
+ }
+ mesgsys->getBinaryDataFast(_PREHASH_DataPacket, _PREHASH_Data, fdata_buf, fdata_size, 0, BUF_SIZE);
- if (!xferp)
+ xferp = findXferByID(id, mReceiveList);
+ if (!xferp)
{
char U64_BUF[MAX_STRING]; /* Flawfinder : ignore */
- LL_INFOS() << "received xfer data from " << mesgsys->getSender()
+ LL_WARNS("Xfer") << "received xfer data from " << mesgsys->getSender()
<< " for non-existent xfer id: "
<< U64_to_str(id, U64_BUF, sizeof(U64_BUF)) << LL_ENDL;
return;
@@ -634,11 +570,11 @@ void LLXferManager::processReceiveData (LLMessageSystem *mesgsys, void ** /*user
// confirm it if it was a resend of the last one, since the confirmation might have gotten dropped
if (decodePacketNum(packetnum) == (xferp->mPacketNum - 1))
{
- LL_INFOS() << "Reconfirming xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << " packet " << packetnum << LL_ENDL; sendConfirmPacket(mesgsys, id, decodePacketNum(packetnum), mesgsys->getSender());
+ LL_INFOS("Xfer") << "Reconfirming xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << " packet " << packetnum << LL_ENDL; sendConfirmPacket(mesgsys, id, decodePacketNum(packetnum), mesgsys->getSender());
}
else
{
- LL_INFOS() << "Ignoring xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << " recv'd packet " << packetnum << "; expecting " << xferp->mPacketNum << LL_ENDL;
+ LL_INFOS("Xfer") << "Ignoring xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << " recv'd packet " << packetnum << "; expecting " << xferp->mPacketNum << LL_ENDL;
}
return;
}
@@ -663,7 +599,7 @@ void LLXferManager::processReceiveData (LLMessageSystem *mesgsys, void ** /*user
if (result == LL_ERR_CANNOT_OPEN_FILE)
{
xferp->abort(LL_ERR_CANNOT_OPEN_FILE);
- removeXfer(xferp,&mReceiveList);
+ removeXfer(xferp,mReceiveList);
startPendingDownloads();
return;
}
@@ -688,7 +624,7 @@ void LLXferManager::processReceiveData (LLMessageSystem *mesgsys, void ** /*user
if (isLastPacket(packetnum))
{
xferp->processEOF();
- removeXfer(xferp,&mReceiveList);
+ removeXfer(xferp,mReceiveList);
startPendingDownloads();
}
}
@@ -697,7 +633,7 @@ void LLXferManager::processReceiveData (LLMessageSystem *mesgsys, void ** /*user
void LLXferManager::sendConfirmPacket (LLMessageSystem *mesgsys, U64 id, S32 packetnum, const LLHost &remote_host)
{
-#if LL_XFER_PROGRESS_MESSAGES
+#ifdef LL_XFER_PROGRESS_MESSAGES
if (!(packetnum % 50))
{
cout << "confirming xfer packet #" << packetnum << endl;
@@ -708,6 +644,7 @@ void LLXferManager::sendConfirmPacket (LLMessageSystem *mesgsys, U64 id, S32 pac
mesgsys->addU64Fast(_PREHASH_ID, id);
mesgsys->addU32Fast(_PREHASH_Packet, packetnum);
+ // Ignore a circuit failure here, we'll catch it with another message
mesgsys->sendMessage(remote_host);
}
@@ -746,6 +683,28 @@ bool LLXferManager::validateFileForTransfer(const std::string& filename)
return find_and_remove(mExpectedTransfers, filename);
}
+/* Present in fireengine, not used by viewer
+void LLXferManager::expectVFileForRequest(const std::string& filename)
+{
+ mExpectedVFileRequests.insert(filename);
+}
+
+bool LLXferManager::validateVFileForRequest(const std::string& filename)
+{
+ return find_and_remove(mExpectedVFileRequests, filename);
+}
+
+void LLXferManager::expectVFileForTransfer(const std::string& filename)
+{
+ mExpectedVFileTransfers.insert(filename);
+}
+
+bool LLXferManager::validateVFileForTransfer(const std::string& filename)
+{
+ return find_and_remove(mExpectedVFileTransfers, filename);
+}
+*/
+
static bool remove_prefix(std::string& filename, const std::string& prefix)
{
if (std::equal(prefix.begin(), prefix.end(), filename.begin()))
@@ -807,7 +766,7 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user
mesgsys->getU64Fast(_PREHASH_XferID, _PREHASH_ID, id);
char U64_BUF[MAX_STRING]; /* Flawfinder : ignore */
- LL_INFOS() << "xfer request id: " << U64_to_str(id, U64_BUF, sizeof(U64_BUF))
+ LL_INFOS("Xfer") << "xfer request id: " << U64_to_str(id, U64_BUF, sizeof(U64_BUF))
<< " to " << mesgsys->getSender() << LL_ENDL;
mesgsys->getStringFast(_PREHASH_XferID, _PREHASH_Filename, local_filename);
@@ -825,36 +784,45 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user
LLXfer *xferp;
if (uuid != LLUUID::null)
- {
+ { // Request for an asset - use a VFS file
if(NULL == LLAssetType::lookup(type))
{
- LL_WARNS() << "Invalid type for xfer request: " << uuid << ":"
+ LL_WARNS("Xfer") << "Invalid type for xfer request: " << uuid << ":"
<< type_s16 << " to " << mesgsys->getSender() << LL_ENDL;
return;
}
- LL_INFOS() << "starting vfile transfer: " << uuid << "," << LLAssetType::lookup(type) << " to " << mesgsys->getSender() << LL_ENDL;
-
if (! mVFS)
{
- LL_WARNS() << "Attempt to send VFile w/o available VFS" << LL_ENDL;
+ LL_WARNS("Xfer") << "Attempt to send VFile w/o available VFS" << LL_ENDL;
return;
}
+ /* Present in fireengine, not used by viewer
+ if (!validateVFileForTransfer(uuid.asString()))
+ {
+ // it is up to the app sending the file to mark it for expected
+ // transfer before the request arrives or it will be dropped
+ LL_WARNS("Xfer") << "SECURITY: Unapproved VFile '" << uuid << "'" << LL_ENDL;
+ return;
+ }
+ */
+
+ LL_INFOS("Xfer") << "starting vfile transfer: " << uuid << "," << LLAssetType::lookup(type) << " to " << mesgsys->getSender() << LL_ENDL;
+
xferp = (LLXfer *)new LLXfer_VFile(mVFS, uuid, type);
if (xferp)
{
- xferp->mNext = mSendList;
- mSendList = xferp;
+ mSendList.push_front(xferp);
result = xferp->startSend(id,mesgsys->getSender());
}
else
{
- LL_ERRS() << "Xfer allcoation error" << LL_ENDL;
+ LL_ERRS("Xfer") << "Xfer allcoation error" << LL_ENDL;
}
}
else if (!local_filename.empty())
- {
+ { // Was given a file name to send
// See DEV-21775 for detailed security issues
if (local_path == LL_PATH_NONE)
@@ -873,7 +841,7 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user
case LL_PATH_NONE:
if(!validateFileForTransfer(local_filename))
{
- LL_WARNS() << "SECURITY: Unapproved filename '" << local_filename << LL_ENDL;
+ LL_WARNS("Xfer") << "SECURITY: Unapproved filename '" << local_filename << LL_ENDL;
return;
}
break;
@@ -881,13 +849,13 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user
case LL_PATH_CACHE:
if(!verify_cache_filename(local_filename))
{
- LL_WARNS() << "SECURITY: Illegal cache filename '" << local_filename << LL_ENDL;
+ LL_WARNS("Xfer") << "SECURITY: Illegal cache filename '" << local_filename << LL_ENDL;
return;
}
break;
default:
- LL_WARNS() << "SECURITY: Restricted file dir enum: " << (U32)local_path << LL_ENDL;
+ LL_WARNS("Xfer") << "SECURITY: Restricted file dir enum: " << (U32)local_path << LL_ENDL;
return;
}
@@ -902,7 +870,7 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user
{
expanded_filename = local_filename;
}
- LL_INFOS() << "starting file transfer: " << expanded_filename << " to " << mesgsys->getSender() << LL_ENDL;
+ LL_INFOS("Xfer") << "starting file transfer: " << expanded_filename << " to " << mesgsys->getSender() << LL_ENDL;
BOOL delete_local_on_completion = FALSE;
mesgsys->getBOOL("XferID", "DeleteOnCompletion", delete_local_on_completion);
@@ -912,23 +880,22 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user
if (xferp)
{
- xferp->mNext = mSendList;
- mSendList = xferp;
+ mSendList.push_front(xferp);
result = xferp->startSend(id,mesgsys->getSender());
}
else
{
- LL_ERRS() << "Xfer allcoation error" << LL_ENDL;
+ LL_ERRS("Xfer") << "Xfer allcoation error" << LL_ENDL;
}
}
else
- {
+ { // no uuid or filename - use the ID sent
char U64_BUF[MAX_STRING]; /* Flawfinder : ignore */
- LL_INFOS() << "starting memory transfer: "
+ LL_INFOS("Xfer") << "starting memory transfer: "
<< U64_to_str(id, U64_BUF, sizeof(U64_BUF)) << " to "
<< mesgsys->getSender() << LL_ENDL;
- xferp = findXfer(id, mSendList);
+ xferp = findXferByID(id, mSendList);
if (xferp)
{
@@ -936,7 +903,7 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user
}
else
{
- LL_INFOS() << "Warning: " << U64_BUF << " not found." << LL_ENDL;
+ LL_INFOS("Xfer") << "Warning: xfer ID " << U64_BUF << " not found." << LL_ENDL;
result = LL_ERR_FILE_NOT_FOUND;
}
}
@@ -946,11 +913,11 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user
if (xferp)
{
xferp->abort(result);
- removeXfer(xferp,&mSendList);
+ removeXfer(xferp, mSendList);
}
else // can happen with a memory transfer not found
{
- LL_INFOS() << "Aborting xfer to " << mesgsys->getSender() << " with error: " << result << LL_ENDL;
+ LL_INFOS("Xfer") << "Aborting xfer to " << mesgsys->getSender() << " with error: " << result << LL_ENDL;
mesgsys->newMessageFast(_PREHASH_AbortXfer);
mesgsys->nextBlockFast(_PREHASH_XferID);
@@ -960,24 +927,86 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user
mesgsys->sendMessage(mesgsys->getSender());
}
}
- else if(xferp && (numActiveXfers(xferp->mRemoteHost) < mMaxOutgoingXfersPerCircuit))
+ else if(xferp)
{
- xferp->sendNextPacket();
- changeNumActiveXfers(xferp->mRemoteHost,1);
-// LL_INFOS() << "***STARTING XFER IMMEDIATELY***" << LL_ENDL;
- }
- else
- {
- if(xferp)
+ // Figure out how many transfers the host has requested
+ LLHostStatus *host_statusp = findHostStatus(xferp->mRemoteHost);
+ if (host_statusp)
{
- LL_INFOS() << " queueing xfer request, " << numPendingXfers(xferp->mRemoteHost) << " ahead of this one" << LL_ENDL;
+ if (host_statusp->mNumActive < mMaxOutgoingXfersPerCircuit)
+ { // Not many transfers in progress already, so start immediately
+ xferp->sendNextPacket();
+ changeNumActiveXfers(xferp->mRemoteHost,1);
+ LL_DEBUGS("Xfer") << "Starting xfer ID " << U64_to_str(id) << " immediately" << LL_ENDL;
+ }
+ else if (mHardLimitOutgoingXfersPerCircuit == 0 ||
+ (host_statusp->mNumActive + host_statusp->mNumPending) < mHardLimitOutgoingXfersPerCircuit)
+ { // Must close the file handle and wait for earlier ones to complete
+ LL_INFOS("Xfer") << " queueing xfer request id " << U64_to_str(id) << ", "
+ << host_statusp->mNumActive << " active and "
+ << host_statusp->mNumPending << " pending ahead of this one"
+ << LL_ENDL;
+ xferp->closeFileHandle(); // Close the file handle until we're ready to send again
+ }
+ else if (mHardLimitOutgoingXfersPerCircuit > 0)
+ { // Way too many requested ... it's time to stop being nice and kill the circuit
+ xferp->closeFileHandle(); // Close the file handle in any case
+ LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(xferp->mRemoteHost);
+ if (cdp)
+ {
+ if (cdp->getTrusted())
+ { // Trusted internal circuit - don't kill it
+ LL_WARNS("Xfer") << "Trusted circuit to " << xferp->mRemoteHost << " has too many xfer requests in the queue "
+ << host_statusp->mNumActive << " active and "
+ << host_statusp->mNumPending << " pending ahead of this one"
+ << LL_ENDL;
+ }
+ else
+ { // Untrusted circuit - time to stop messing around and kill it
+ LL_WARNS("Xfer") << "Killing circuit to " << xferp->mRemoteHost << " for having too many xfer requests in the queue "
+ << host_statusp->mNumActive << " active and "
+ << host_statusp->mNumPending << " pending ahead of this one"
+ << LL_ENDL;
+ gMessageSystem->disableCircuit(xferp->mRemoteHost);
+ }
+ }
+ else
+ { // WTF? Why can't we find a circuit? Try to kill it off
+ LL_WARNS("Xfer") << "Backlog with circuit to " << xferp->mRemoteHost << " with too many xfer requests in the queue "
+ << host_statusp->mNumActive << " active and "
+ << host_statusp->mNumPending << " pending ahead of this one"
+ << " but no LLCircuitData found???"
+ << LL_ENDL;
+ gMessageSystem->disableCircuit(xferp->mRemoteHost);
+ }
+ }
}
else
{
- LL_WARNS() << "LLXferManager::processFileRequest() - no xfer found!"
- << LL_ENDL;
+ LL_WARNS("Xfer") << "LLXferManager::processFileRequest() - no LLHostStatus found for id " << U64_to_str(id)
+ << " host " << xferp->mRemoteHost << LL_ENDL;
}
}
+ else
+ {
+ LL_WARNS("Xfer") << "LLXferManager::processFileRequest() - no xfer found for id " << U64_to_str(id) << LL_ENDL;
+ }
+}
+
+///////////////////////////////////////////////////////////
+
+// Return true if host is in a transfer-flood sitation. Same check for both internal and external hosts
+bool LLXferManager::isHostFlooded(const LLHost & host)
+{
+ bool flooded = false;
+ LLHostStatus *host_statusp = findHostStatus(host);
+ if (host_statusp)
+ {
+ flooded = (mHardLimitOutgoingXfersPerCircuit > 0 &&
+ (host_statusp->mNumActive + host_statusp->mNumPending) >= (S32)(mHardLimitOutgoingXfersPerCircuit * 0.8f));
+ }
+
+ return flooded;
}
@@ -991,7 +1020,7 @@ void LLXferManager::processConfirmation (LLMessageSystem *mesgsys, void ** /*use
mesgsys->getU64Fast(_PREHASH_XferID, _PREHASH_ID, id);
mesgsys->getS32Fast(_PREHASH_XferID, _PREHASH_Packet, packetNum);
- LLXfer* xferp = findXfer(id, mSendList);
+ LLXfer* xferp = findXferByID(id, mSendList);
if (xferp)
{
// cout << "confirmed packet #" << packetNum << " ping: "<< xferp->ACKTimer.getElapsedTimeF32() << endl;
@@ -1002,91 +1031,105 @@ void LLXferManager::processConfirmation (LLMessageSystem *mesgsys, void ** /*use
}
else
{
- removeXfer(xferp, &mSendList);
+ removeXfer(xferp, mSendList);
}
}
}
///////////////////////////////////////////////////////////
-void LLXferManager::retransmitUnackedPackets ()
+// Called from LLMessageSystem::processAcks()
+void LLXferManager::retransmitUnackedPackets()
{
LLXfer *xferp;
- LLXfer *delp;
- xferp = mReceiveList;
- while(xferp)
+
+ xfer_list_t::iterator iter = mReceiveList.begin();
+ while (iter != mReceiveList.end())
{
+ xferp = (*iter);
if (xferp->mStatus == e_LL_XFER_IN_PROGRESS)
{
// if the circuit dies, abort
if (! gMessageSystem->mCircuitInfo.isCircuitAlive( xferp->mRemoteHost ))
{
- LL_INFOS() << "Xfer found in progress on dead circuit, aborting" << LL_ENDL;
+ LL_WARNS("Xfer") << "Xfer found in progress on dead circuit, aborting transfer to "
+ << xferp->mRemoteHost.getIPandPort()
+ << LL_ENDL;
xferp->mCallbackResult = LL_ERR_CIRCUIT_GONE;
xferp->processEOF();
- delp = xferp;
- xferp = xferp->mNext;
- removeXfer(delp,&mReceiveList);
+
+ iter = mReceiveList.erase(iter); // iter is set to next one after the deletion point
+ delete (xferp);
continue;
}
}
- xferp = xferp->mNext;
+ ++iter;
}
- xferp = mSendList;
+ // Re-build mOutgoingHosts data
updateHostStatus();
+
F32 et;
- while (xferp)
+ iter = mSendList.begin();
+ while (iter != mSendList.end())
{
+ xferp = (*iter);
if (xferp->mWaitingForACK && ( (et = xferp->ACKTimer.getElapsedTimeF32()) > LL_PACKET_TIMEOUT))
{
if (xferp->mRetries > LL_PACKET_RETRY_LIMIT)
{
- LL_INFOS() << "dropping xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << " packet retransmit limit exceeded, xfer dropped" << LL_ENDL;
+ LL_INFOS("Xfer") << "dropping xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << " packet retransmit limit exceeded, xfer dropped" << LL_ENDL;
xferp->abort(LL_ERR_TCP_TIMEOUT);
- delp = xferp;
- xferp = xferp->mNext;
- removeXfer(delp,&mSendList);
+ iter = mSendList.erase(iter);
+ delete xferp;
+ continue;
}
else
{
- LL_INFOS() << "resending xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << " packet unconfirmed after: "<< et << " sec, packet " << xferp->mPacketNum << LL_ENDL;
+ LL_INFOS("Xfer") << "resending xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << " packet unconfirmed after: "<< et << " sec, packet " << xferp->mPacketNum << LL_ENDL;
xferp->resendLastPacket();
- xferp = xferp->mNext;
}
}
else if ((xferp->mStatus == e_LL_XFER_REGISTERED) && ( (et = xferp->ACKTimer.getElapsedTimeF32()) > LL_XFER_REGISTRATION_TIMEOUT))
{
- LL_INFOS() << "registered xfer never requested, xfer dropped" << LL_ENDL;
+ LL_INFOS("Xfer") << "registered xfer never requested, xfer dropped" << LL_ENDL;
xferp->abort(LL_ERR_TCP_TIMEOUT);
- delp = xferp;
- xferp = xferp->mNext;
- removeXfer(delp,&mSendList);
+ iter = mSendList.erase(iter);
+ delete xferp;
+ continue;
}
else if (xferp->mStatus == e_LL_XFER_ABORTED)
{
- LL_WARNS() << "Removing aborted xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << LL_ENDL;
- delp = xferp;
- xferp = xferp->mNext;
- removeXfer(delp,&mSendList);
+ LL_WARNS("Xfer") << "Removing aborted xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << LL_ENDL;
+ iter = mSendList.erase(iter);
+ delete xferp;
+ continue;
}
else if (xferp->mStatus == e_LL_XFER_PENDING)
{
-// LL_INFOS() << "*** numActiveXfers = " << numActiveXfers(xferp->mRemoteHost) << " mMaxOutgoingXfersPerCircuit = " << mMaxOutgoingXfersPerCircuit << LL_ENDL;
+// LL_INFOS("Xfer") << "*** numActiveXfers = " << numActiveXfers(xferp->mRemoteHost) << " mMaxOutgoingXfersPerCircuit = " << mMaxOutgoingXfersPerCircuit << LL_ENDL;
if (numActiveXfers(xferp->mRemoteHost) < mMaxOutgoingXfersPerCircuit)
{
-// LL_INFOS() << "bumping pending xfer to active" << LL_ENDL;
- xferp->sendNextPacket();
- changeNumActiveXfers(xferp->mRemoteHost,1);
- }
- xferp = xferp->mNext;
- }
- else
- {
- xferp = xferp->mNext;
+ if (xferp->reopenFileHandle())
+ {
+ LL_WARNS("Xfer") << "Error re-opening file handle for xfer ID " << U64_to_str(xferp->mID)
+ << " to host " << xferp->mRemoteHost << LL_ENDL;
+ xferp->abort(LL_ERR_CANNOT_OPEN_FILE);
+ iter = mSendList.erase(iter);
+ delete xferp;
+ continue;
+ }
+ else
+ { // No error re-opening the file, send the first packet
+ LL_DEBUGS("Xfer") << "Moving pending xfer ID " << U64_to_str(xferp->mID) << " to active" << LL_ENDL;
+ xferp->sendNextPacket();
+ changeNumActiveXfers(xferp->mRemoteHost,1);
+ }
+ }
}
- }
+ ++iter;
+ } // end while() loop
//
// HACK - if we're using xfer confirm throttling, throttle our xfer confirms here
@@ -1099,10 +1142,10 @@ void LLXferManager::retransmitUnackedPackets ()
{
break;
}
- //LL_INFOS() << "Confirm packet queue length:" << mXferAckQueue.size() << LL_ENDL;
+ //LL_INFOS("Xfer") << "Confirm packet queue length:" << mXferAckQueue.size() << LL_ENDL;
LLXferAckInfo ack_info = mXferAckQueue.front();
mXferAckQueue.pop_front();
- //LL_INFOS() << "Sending confirm packet" << LL_ENDL;
+ //LL_INFOS("Xfer") << "Sending confirm packet" << LL_ENDL;
sendConfirmPacket(gMessageSystem, ack_info.mID, ack_info.mPacketNum, ack_info.mRemoteHost);
mAckThrottle.throttleOverflow(1000.f*8.f); // Assume 1000 bytes/packet
}
@@ -1112,7 +1155,7 @@ void LLXferManager::retransmitUnackedPackets ()
void LLXferManager::abortRequestById(U64 xfer_id, S32 result_code)
{
- LLXfer * xferp = findXfer(xfer_id, mReceiveList);
+ LLXfer * xferp = findXferByID(xfer_id, mReceiveList);
if (xferp)
{
if (xferp->mStatus == e_LL_XFER_IN_PROGRESS)
@@ -1124,7 +1167,7 @@ void LLXferManager::abortRequestById(U64 xfer_id, S32 result_code)
{
xferp->mCallbackResult = result_code;
xferp->processEOF(); //should notify requester
- removeXfer(xferp, &mReceiveList);
+ removeXfer(xferp, mReceiveList);
}
// Since already removed or marked as aborted no need
// to wait for processAbort() to start new download
@@ -1143,12 +1186,12 @@ void LLXferManager::processAbort (LLMessageSystem *mesgsys, void ** /*user_data*
mesgsys->getU64Fast(_PREHASH_XferID, _PREHASH_ID, id);
mesgsys->getS32Fast(_PREHASH_XferID, _PREHASH_Result, result_code);
- xferp = findXfer(id, mReceiveList);
+ xferp = findXferByID(id, mReceiveList);
if (xferp)
{
xferp->mCallbackResult = result_code;
xferp->processEOF();
- removeXfer(xferp, &mReceiveList);
+ removeXfer(xferp, mReceiveList);
startPendingDownloads();
}
}
@@ -1164,27 +1207,29 @@ void LLXferManager::startPendingDownloads()
// requests get pushed toward the back. Thus, if we didn't do a
// stateful iteration, it would be possible for old requests to
// never start.
- LLXfer* xferp = mReceiveList;
+ LLXfer* xferp;
std::list<LLXfer*> pending_downloads;
S32 download_count = 0;
S32 pending_count = 0;
- while(xferp)
+ for (xfer_list_t::iterator iter = mReceiveList.begin();
+ iter != mReceiveList.end();
+ ++iter)
{
+ xferp = (*iter);
if(xferp->mStatus == e_LL_XFER_PENDING)
- {
+ { // Count and accumulate pending downloads
++pending_count;
pending_downloads.push_front(xferp);
}
else if(xferp->mStatus == e_LL_XFER_IN_PROGRESS)
- {
+ { // Count downloads in progress
++download_count;
}
- xferp = xferp->mNext;
}
S32 start_count = mMaxIncomingXfers - download_count;
- LL_DEBUGS() << "LLXferManager::startPendingDownloads() - XFER_IN_PROGRESS: "
+ LL_DEBUGS("Xfer") << "LLXferManager::startPendingDownloads() - XFER_IN_PROGRESS: "
<< download_count << " XFER_PENDING: " << pending_count
<< " startring " << llmin(start_count, pending_count) << LL_ENDL;
@@ -1209,29 +1254,15 @@ void LLXferManager::startPendingDownloads()
///////////////////////////////////////////////////////////
-void LLXferManager::addToList(LLXfer* xferp, LLXfer*& head, BOOL is_priority)
+void LLXferManager::addToList(LLXfer* xferp, xfer_list_t & xfer_list, BOOL is_priority)
{
if(is_priority)
{
- xferp->mNext = NULL;
- LLXfer* next = head;
- if(next)
- {
- while(next->mNext)
- {
- next = next->mNext;
- }
- next->mNext = xferp;
- }
- else
- {
- head = xferp;
- }
+ xfer_list.push_back(xferp);
}
else
{
- xferp->mNext = head;
- head = xferp;
+ xfer_list.push_front(xferp);
}
}
diff --git a/indra/llmessage/llxfermanager.h b/indra/llmessage/llxfermanager.h
index d258f0a5ce..45ae2ffdd3 100644
--- a/indra/llmessage/llxfermanager.h
+++ b/indra/llmessage/llxfermanager.h
@@ -77,6 +77,7 @@ class LLXferManager
protected:
S32 mMaxOutgoingXfersPerCircuit;
+ S32 mHardLimitOutgoingXfersPerCircuit; // At this limit, kill off the connection
S32 mMaxIncomingXfers;
BOOL mUseAckThrottling; // Use ack throttling to cap file xfer bandwidth
@@ -92,19 +93,22 @@ class LLXferManager
HIGH_PRIORITY = TRUE,
};
- LLXfer *mSendList;
- LLXfer *mReceiveList;
+ // Linked FIFO list, add to the front and pull from back
+ typedef std::deque<LLXfer *> xfer_list_t;
+ xfer_list_t mSendList;
+ xfer_list_t mReceiveList;
typedef std::list<LLHostStatus*> status_list_t;
status_list_t mOutgoingHosts;
- private:
protected:
// implementation methods
virtual void startPendingDownloads();
- virtual void addToList(LLXfer* xferp, LLXfer*& head, BOOL is_priority);
+ virtual void addToList(LLXfer* xferp, xfer_list_t & xfer_list, BOOL is_priority);
std::multiset<std::string> mExpectedTransfers; // files that are authorized to transfer out
std::multiset<std::string> mExpectedRequests; // files that are authorized to be downloaded on top of
+ std::multiset<std::string> mExpectedVFileTransfers; // files that are authorized to transfer out
+ std::multiset<std::string> mExpectedVFileRequests; // files that are authorized to be downloaded on top of
public:
LLXferManager(LLVFS *vfs);
@@ -117,14 +121,17 @@ class LLXferManager
void setAckThrottleBPS(const F32 bps);
// list management routines
- virtual LLXfer *findXfer(U64 id, LLXfer *list_head);
- virtual void removeXfer (LLXfer *delp, LLXfer **list_head);
- virtual U32 numActiveListEntries(LLXfer *list_head);
+ virtual LLXfer *findXferByID(U64 id, xfer_list_t & xfer_list);
+ virtual void removeXfer (LLXfer *delp, xfer_list_t & xfer_list);
+
+ LLHostStatus * findHostStatus(const LLHost &host);
virtual S32 numActiveXfers(const LLHost &host);
virtual S32 numPendingXfers(const LLHost &host);
+
virtual void changeNumActiveXfers(const LLHost &host, S32 delta);
virtual void setMaxOutgoingXfersPerCircuit (S32 max_num);
+ virtual void setHardLimitOutgoingXfersPerCircuit(S32 max_num);
virtual void setMaxIncomingXfers(S32 max_num);
virtual void updateHostStatus();
virtual void printHostStatus();
@@ -136,8 +143,6 @@ class LLXferManager
virtual S32 decodePacketNum(S32 packet_num);
virtual BOOL isLastPacket(S32 packet_num);
- virtual U64 registerXfer(const void *datap, const S32 length);
-
// file requesting routines
// .. to file
virtual U64 requestFile(const std::string& local_filename,
@@ -148,7 +153,7 @@ class LLXferManager
void (*callback)(void**,S32,LLExtStat), void** user_data,
BOOL is_priority = FALSE,
BOOL use_big_packets = FALSE);
-
+ /*
// .. to memory
virtual void requestFile(const std::string& remote_filename,
ELLPath remote_path,
@@ -157,7 +162,7 @@ class LLXferManager
void (*callback)(void*, S32, void**, S32, LLExtStat),
void** user_data,
BOOL is_priority = FALSE);
-
+ */
// vfile requesting
// .. to vfile
virtual void requestVFile(const LLUUID &local_id, const LLUUID& remote_id,
@@ -180,18 +185,15 @@ class LLXferManager
virtual void expectFileForRequest(const std::string& filename);
virtual bool validateFileForRequest(const std::string& filename);
-/*
-// xfer request (may be memory or file)
-// .. to file
- virtual void requestXfer(const char *local_filename, U64 xfer_id,
- BOOL delete_remote_on_completion,
- const LLHost &remote_host, void (*callback)(void **,S32),void **user_data);
-// .. to memory
- virtual void requestXfer(U64 xfer_id,
- const LLHost &remote_host,
- BOOL delete_remote_on_completion,
- void (*callback)(void *, S32, void **, S32),void **user_data);
-*/
+ /**
+ Same idea but for VFiles, kept separate to avoid namespace overlap
+ */
+ /* Present in fireengine, not used by viewer
+ virtual void expectVFileForTransfer(const std::string& filename);
+ virtual bool validateVFileForTransfer(const std::string& filename);
+ virtual void expectVFileForRequest(const std::string& filename);
+ virtual bool validateVFileForRequest(const std::string& filename);
+ */
virtual void processReceiveData (LLMessageSystem *mesgsys, void **user_data);
virtual void sendConfirmPacket (LLMessageSystem *mesgsys, U64 id, S32 packetnum, const LLHost &remote_host);
@@ -204,6 +206,8 @@ class LLXferManager
// error handling
void abortRequestById(U64 xfer_id, S32 result_code);
virtual void processAbort (LLMessageSystem *mesgsys, void **user_data);
+
+ virtual bool isHostFlooded(const LLHost & host);
};
extern LLXferManager* gXferManager;
diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index 78eb6e75bb..9d447b0f37 100644
--- a/indra/llplugin/llpluginclassmedia.cpp
+++ b/indra/llplugin/llpluginclassmedia.cpp
@@ -1101,6 +1101,8 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
}
else if(message_name == "name_text")
{
+ mHistoryBackAvailable = message.getValueBoolean("history_back_available");
+ mHistoryForwardAvailable = message.getValueBoolean("history_forward_available");
mMediaName = message.getValue("name");
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_NAME_CHANGED);
}
diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h
index 3b3075c6bd..4f52afb317 100644
--- a/indra/llplugin/llpluginclassmedia.h
+++ b/indra/llplugin/llpluginclassmedia.h
@@ -317,6 +317,8 @@ public:
// "init_history" message
void initializeUrlHistory(const LLSD& url_history);
+ boost::shared_ptr<LLPluginClassMedia> getSharedPrt() { return boost::dynamic_pointer_cast<LLPluginClassMedia>(shared_from_this()); } // due to enable_shared_from_this
+
protected:
LLPluginClassMediaOwner *mOwner;
diff --git a/indra/llprimitive/llmaterialid.cpp b/indra/llprimitive/llmaterialid.cpp
index 820f62c43c..f88a607c4f 100644
--- a/indra/llprimitive/llmaterialid.cpp
+++ b/indra/llprimitive/llmaterialid.cpp
@@ -61,6 +61,11 @@ LLMaterialID::LLMaterialID(const LLMaterialID& pOtherMaterialID)
copyFromOtherMaterialID(pOtherMaterialID);
}
+LLMaterialID::LLMaterialID(const LLUUID& lluid)
+{
+ set(lluid.mData);
+}
+
LLMaterialID::~LLMaterialID()
{
}
diff --git a/indra/llprimitive/llmaterialid.h b/indra/llprimitive/llmaterialid.h
index b4c82d3b7b..ee663f8f99 100644
--- a/indra/llprimitive/llmaterialid.h
+++ b/indra/llprimitive/llmaterialid.h
@@ -40,6 +40,7 @@ public:
LLMaterialID(const LLSD::Binary& pMaterialID);
LLMaterialID(const void* pMemory);
LLMaterialID(const LLMaterialID& pOtherMaterialID);
+ LLMaterialID(const LLUUID& lluid);
~LLMaterialID();
bool operator == (const LLMaterialID& pOtherMaterialID) const;
diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp
index bfa65666b5..edf7c41e40 100644
--- a/indra/llprimitive/llprimitive.cpp
+++ b/indra/llprimitive/llprimitive.cpp
@@ -732,6 +732,16 @@ S32 face_index_from_id(LLFaceID face_ID, const std::vector<LLProfile::Face>& fac
BOOL LLPrimitive::setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume)
{
+ if (NO_LOD == detail)
+ {
+ // build the new object
+ setChanged(GEOMETRY);
+ sVolumeManager->unrefVolume(mVolumep);
+ mVolumep = new LLVolume(volume_params, 1, TRUE, TRUE);
+ setNumTEs(mVolumep->getNumFaces());
+ return FALSE;
+ }
+
LLVolume *volumep;
if (unique_volume)
{
diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h
index 19d9d52817..99a32e614c 100644
--- a/indra/llprimitive/llprimitive.h
+++ b/indra/llprimitive/llprimitive.h
@@ -489,6 +489,11 @@ protected:
public:
static LLVolumeMgr* sVolumeManager;
+
+ enum
+ {
+ NO_LOD = -1
+ };
};
inline BOOL LLPrimitive::isAvatar() const
diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt
index 331f988382..07a0d8c402 100644
--- a/indra/llrender/CMakeLists.txt
+++ b/indra/llrender/CMakeLists.txt
@@ -51,6 +51,7 @@ set(llrender_SOURCE_FILES
lltexture.cpp
lluiimage.cpp
llvertexbuffer.cpp
+ llglcommonfunc.cpp
)
set(llrender_HEADER_FILES
@@ -78,6 +79,7 @@ set(llrender_HEADER_FILES
lltexture.h
lluiimage.h
llvertexbuffer.h
+ llglcommonfunc.h
)
set_source_files_properties(${llrender_HEADER_FILES}
diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp
index de26d19efc..ab668dc192 100644
--- a/indra/llrender/llfontfreetype.cpp
+++ b/indra/llrender/llfontfreetype.cpp
@@ -31,6 +31,9 @@
// Freetype stuff
#include <ft2build.h>
+#ifdef LL_WINDOWS
+#include <freetype2\freetype\ftsystem.h>
+#endif
// For some reason, this won't work if it's not wrapped in the ifdef
#ifdef FT_FREETYPE_H
@@ -106,6 +109,10 @@ LLFontFreetype::LLFontFreetype()
mAscender(0.f),
mDescender(0.f),
mLineHeight(0.f),
+#ifdef LL_WINDOWS
+ pFileStream(NULL),
+ pFtStream(NULL),
+#endif
mIsFallback(FALSE),
mFTFace(NULL),
mRenderGlyphCount(0),
@@ -127,10 +134,29 @@ LLFontFreetype::~LLFontFreetype()
std::for_each(mCharGlyphInfoMap.begin(), mCharGlyphInfoMap.end(), DeletePairedPointer());
mCharGlyphInfoMap.clear();
+#ifdef LL_WINDOWS
+ delete pFileStream; // closed by FT_Done_Face
+ delete pFtStream;
+#endif
delete mFontBitmapCachep;
// mFallbackFonts cleaned up by LLPointer destructor
}
+#ifdef LL_WINDOWS
+unsigned long ft_read_cb(FT_Stream stream, unsigned long offset, unsigned char *buffer, unsigned long count) {
+ if (count <= 0) return count;
+ llifstream *file_stream = static_cast<llifstream *>(stream->descriptor.pointer);
+ file_stream->seekg(offset, std::ios::beg);
+ file_stream->read((char*)buffer, count);
+ return file_stream->gcount();
+}
+
+void ft_close_cb(FT_Stream stream) {
+ llifstream *file_stream = static_cast<llifstream *>(stream->descriptor.pointer);
+ file_stream->close();
+}
+#endif
+
BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback)
{
// Don't leak face objects. This is also needed to deal with
@@ -143,13 +169,55 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
int error;
+#ifdef LL_WINDOWS
+ pFileStream = new llifstream(filename, std::ios::binary);
+ if (pFileStream->is_open())
+ {
+ std::streampos beg = pFileStream->tellg();
+ pFileStream->seekg(0, std::ios::end);
+ std::streampos end = pFileStream->tellg();
+ std::size_t file_size = end - beg;
+ pFileStream->seekg(0, std::ios::beg);
+
+ pFtStream = new LLFT_Stream();
+ pFtStream->base = 0;
+ pFtStream->pos = 0;
+ pFtStream->size = file_size;
+ pFtStream->descriptor.pointer = pFileStream;
+ pFtStream->read = ft_read_cb;
+ pFtStream->close = ft_close_cb;
+
+ FT_Open_Args args;
+ args.flags = FT_OPEN_STREAM;
+ args.stream = (FT_StreamRec*)pFtStream;
+
+ error = FT_Open_Face(gFTLibrary,
+ &args,
+ 0,
+ &mFTFace);
+ }
+ else
+ {
+ delete pFileStream;
+ pFileStream = NULL;
+ return FALSE;
+ }
+#else
error = FT_New_Face( gFTLibrary,
filename.c_str(),
0,
- &mFTFace );
+ &mFTFace);
+#endif
- if (error)
+ if (error)
{
+#ifdef LL_WINDOWS
+ pFileStream->close();
+ delete pFileStream;
+ delete pFtStream;
+ pFileStream = NULL;
+ pFtStream = NULL;
+#endif
return FALSE;
}
@@ -166,6 +234,13 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
{
// Clean up freetype libs.
FT_Done_Face(mFTFace);
+#ifdef LL_WINDOWS
+ pFileStream->close();
+ delete pFileStream;
+ delete pFtStream;
+ pFileStream = NULL;
+ pFtStream = NULL;
+#endif
mFTFace = NULL;
return FALSE;
}
diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h
index a5ece42b88..aadebf5e70 100644
--- a/indra/llrender/llfontfreetype.h
+++ b/indra/llrender/llfontfreetype.h
@@ -40,6 +40,8 @@
// We'll forward declare the struct here. JC
struct FT_FaceRec_;
typedef struct FT_FaceRec_* LLFT_Face;
+struct FT_StreamRec_;
+typedef struct FT_StreamRec_ LLFT_Stream;
class LLFontManager
{
@@ -159,6 +161,11 @@ private:
LLFT_Face mFTFace;
+#ifdef LL_WINDOWS
+ llifstream *pFileStream;
+ LLFT_Stream *pFtStream;
+#endif
+
BOOL mIsFallback;
font_vector_t mFallbackFonts; // A list of fallback fonts to look for glyphs in (for Unicode chars)
diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp
index d003687415..3c829596ce 100644
--- a/indra/llrender/llfontregistry.cpp
+++ b/indra/llrender/llfontregistry.cpp
@@ -447,7 +447,7 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
if (!fontp->loadFace(font_path, extra_scale * point_size,
LLFontGL::sVertDPI, LLFontGL::sHorizDPI, 2, is_fallback))
{
- LL_INFOS_ONCE("LLFontRegistry") << "Couldn't load font " << *file_name_it << LL_ENDL;
+ LL_INFOS_ONCE("LLFontRegistry") << "Couldn't load font " << *file_name_it << " from path " << local_path << LL_ENDL;
delete fontp;
fontp = NULL;
}
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 155c2402bd..35b6951779 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -1348,8 +1348,19 @@ void LLGLManager::initExtensions()
if (mHasVertexShader)
{
LL_INFOS() << "initExtensions() VertexShader-related procs..." << LL_ENDL;
+
+ // nSight doesn't support use of ARB funcs that have been normalized in the API
+ if (!LLRender::sNsightDebugSupport)
+ {
glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetAttribLocationARB");
glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glBindAttribLocationARB");
+ }
+ else
+ {
+ glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetAttribLocation");
+ glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC)GLH_EXT_GET_PROC_ADDRESS("glBindAttribLocation");
+ }
+
glGetActiveAttribARB = (PFNGLGETACTIVEATTRIBARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetActiveAttribARB");
glVertexAttrib1dARB = (PFNGLVERTEXATTRIB1DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1dARB");
glVertexAttrib1dvARB = (PFNGLVERTEXATTRIB1DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1dvARB");
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index aa98b3f6bc..4c4302d05b 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -256,6 +256,9 @@ void clear_glerror();
if the existing GL state does not match the expected GL state.
*/
+
+#include "boost/function.hpp"
+
class LLGLState
{
public:
@@ -297,6 +300,20 @@ public:
LLGLEnableAlphaReject(bool enable);
};
+// Enable with functor
+class LLGLEnableFunc : LLGLState
+{
+public:
+ LLGLEnableFunc(LLGLenum state, bool enable, boost::function<void()> func)
+ : LLGLState(state, enable)
+ {
+ if (enable)
+ {
+ func();
+ }
+ }
+};
+
/// TODO: Being deprecated.
class LLGLEnable : public LLGLState
{
diff --git a/indra/llrender/llglcommonfunc.cpp b/indra/llrender/llglcommonfunc.cpp
new file mode 100644
index 0000000000..e9ec28927f
--- /dev/null
+++ b/indra/llrender/llglcommonfunc.cpp
@@ -0,0 +1,37 @@
+/**
+* @file llglcommonfunc.cpp
+* @brief Implementation of the LLGLCommonFunc.
+*
+* $LicenseInfo:firstyear=2001&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2010, 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 "llglheaders.h"
+#include "llglcommonfunc.h"
+
+namespace LLGLCommonFunc
+{
+ void selected_stencil_test()
+ {
+ glStencilFunc(GL_ALWAYS, 2, 0xffff);
+ glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
+ }
+}
diff --git a/indra/llrender/llglcommonfunc.h b/indra/llrender/llglcommonfunc.h
new file mode 100644
index 0000000000..f1f8ff7bc4
--- /dev/null
+++ b/indra/llrender/llglcommonfunc.h
@@ -0,0 +1,30 @@
+/**
+* @file llphoenixfunc.h
+* @brief File include common opengl code snippets
+*
+* $LicenseInfo:firstyear=2003&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2010, 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$
+*/
+
+namespace LLGLCommonFunc
+{
+ void selected_stencil_test();
+}
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 970502f2d6..4702042ab9 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -537,7 +537,11 @@ BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString> * attri
mAttribute.clear();
U32 numAttributes = (attributes == NULL) ? 0 : attributes->size();
+#if LL_RELEASE_WITH_DEBUG_INFO
+ mAttribute.resize(LLShaderMgr::instance()->mReservedAttribs.size() + numAttributes, { -1, NULL });
+#else
mAttribute.resize(LLShaderMgr::instance()->mReservedAttribs.size() + numAttributes, -1);
+#endif
if (res)
{ //read back channel locations
@@ -551,7 +555,11 @@ BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString> * attri
S32 index = glGetAttribLocationARB(mProgramObject, (const GLcharARB *)name);
if (index != -1)
{
+#if LL_RELEASE_WITH_DEBUG_INFO
+ mAttribute[i] = { index, name };
+#else
mAttribute[i] = index;
+#endif
mAttributeMask |= 1 << i;
LL_DEBUGS("ShaderLoading") << "Attribute " << name << " assigned to channel " << index << LL_ENDL;
}
@@ -744,24 +752,25 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
, even if the "diffuseMap" will be appear and use first in shader code.
As example where this situation appear see: "Deferred Material Shader 28/29/30/31"
- And tickets: MAINT-4165, MAINT-4839, MAINT-3568
+ And tickets: MAINT-4165, MAINT-4839, MAINT-3568, MAINT-6437
*/
S32 diffuseMap = glGetUniformLocationARB(mProgramObject, "diffuseMap");
+ S32 specularMap = glGetUniformLocationARB(mProgramObject, "specularMap");
S32 bumpMap = glGetUniformLocationARB(mProgramObject, "bumpMap");
S32 environmentMap = glGetUniformLocationARB(mProgramObject, "environmentMap");
std::set<S32> skip_index;
- if (-1 != diffuseMap && (-1 != bumpMap || -1 != environmentMap))
+ if (-1 != diffuseMap && (-1 != specularMap || -1 != bumpMap || -1 != environmentMap))
{
GLenum type;
GLsizei length;
GLint size = -1;
char name[1024];
- diffuseMap = bumpMap = environmentMap = -1;
+ diffuseMap = specularMap = bumpMap = environmentMap = -1;
for (S32 i = 0; i < activeCount; i++)
{
@@ -775,6 +784,18 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
continue;
}
+ if (-1 == specularMap && std::string(name) == "specularMap")
+ {
+ specularMap = i;
+ continue;
+ }
+
+ if (-1 == specularMap && std::string(name) == "specularMap")
+ {
+ specularMap = i;
+ continue;
+ }
+
if (-1 == bumpMap && std::string(name) == "bumpMap")
{
bumpMap = i;
@@ -788,34 +809,29 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
}
}
+ bool specularDiff = specularMap < diffuseMap && -1 != specularMap;
bool bumpLessDiff = bumpMap < diffuseMap && -1 != bumpMap;
bool envLessDiff = environmentMap < diffuseMap && -1 != environmentMap;
- if (bumpLessDiff && envLessDiff)
+ if (specularDiff || bumpLessDiff || envLessDiff)
{
mapUniform(diffuseMap, uniforms);
- mapUniform(bumpMap, uniforms);
- mapUniform(environmentMap, uniforms);
-
skip_index.insert(diffuseMap);
- skip_index.insert(bumpMap);
- skip_index.insert(environmentMap);
- }
- else if (bumpLessDiff)
- {
- mapUniform(diffuseMap, uniforms);
- mapUniform(bumpMap, uniforms);
- skip_index.insert(diffuseMap);
- skip_index.insert(bumpMap);
- }
- else if (envLessDiff)
- {
- mapUniform(diffuseMap, uniforms);
- mapUniform(environmentMap, uniforms);
+ if (-1 != specularMap) {
+ mapUniform(specularMap, uniforms);
+ skip_index.insert(specularMap);
+ }
- skip_index.insert(diffuseMap);
- skip_index.insert(environmentMap);
+ if (-1 != bumpMap) {
+ mapUniform(bumpMap, uniforms);
+ skip_index.insert(bumpMap);
+ }
+
+ if (-1 != environmentMap) {
+ mapUniform(environmentMap, uniforms);
+ skip_index.insert(environmentMap);
+ }
}
}
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index 6f10d122cb..b56b914013 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -167,7 +167,18 @@ public:
U32 mLightHash;
GLhandleARB mProgramObject;
+#if LL_RELEASE_WITH_DEBUG_INFO
+ struct attr_name
+ {
+ GLint loc;
+ const char *name;
+ void operator = (GLint _loc) { loc = _loc; }
+ operator GLint () { return loc; }
+ };
+ std::vector<attr_name> mAttribute; //lookup table of attribute enum to attribute channel
+#else
std::vector<GLint> mAttribute; //lookup table of attribute enum to attribute channel
+#endif
U32 mAttributeMask; //mask of which reserved attributes are set (lines up with LLVertexBuffer::getTypeMask())
std::vector<GLint> mUniform; //lookup table of uniform enum to uniform location
LLStaticStringTable<GLint> mUniformMap; //lookup map of uniform name to uniform location
diff --git a/indra/llrender/llgltexture.h b/indra/llrender/llgltexture.h
index 45592ee077..70610d9626 100644
--- a/indra/llrender/llgltexture.h
+++ b/indra/llrender/llgltexture.h
@@ -49,6 +49,7 @@ public:
enum EBoostLevel
{
BOOST_NONE = 0,
+ BOOST_ALM , //acts like NONE when ALM is on, max discard when ALM is off
BOOST_AVATAR_BAKED ,
BOOST_AVATAR ,
BOOST_CLOUDS ,
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index 76f28bb43f..65d6181920 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -49,6 +49,7 @@ U32 LLRender::sUICalls = 0;
U32 LLRender::sUIVerts = 0;
U32 LLTexUnit::sWhiteTexture = 0;
bool LLRender::sGLCoreProfile = false;
+bool LLRender::sNsightDebugSupport = false;
static const U32 LL_NUM_TEXTURE_LAYERS = 32;
static const U32 LL_NUM_LIGHT_UNITS = 8;
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index a67fb8da52..32bb728d8a 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -269,6 +269,13 @@ public:
SPECULAR_MAP,
NUM_TEXTURE_CHANNELS,
};
+
+ enum eVolumeTexIndex
+ {
+ LIGHT_TEX = 0,
+ SCULPT_TEX,
+ NUM_VOLUME_TEXTURE_CHANNELS,
+ };
typedef enum {
TRIANGLES = 0,
@@ -438,7 +445,8 @@ public:
static U32 sUICalls;
static U32 sUIVerts;
static bool sGLCoreProfile;
-
+ static bool sNsightDebugSupport;
+
private:
friend class LLLightState;
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index f10301b42d..e3e605d040 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -98,7 +98,6 @@ U32 LLVertexBuffer::sCurVAOName = 1;
U32 LLVertexBuffer::sAllocatedIndexBytes = 0;
U32 LLVertexBuffer::sIndexCount = 0;
-LLPrivateMemoryPool* LLVertexBuffer::sPrivatePoolp = NULL;
U32 LLVertexBuffer::sBindCount = 0;
U32 LLVertexBuffer::sSetCount = 0;
S32 LLVertexBuffer::sCount = 0;
@@ -191,6 +190,10 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
if (mUsage != GL_DYNAMIC_COPY_ARB)
{ //data will be provided by application
ret = (U8*) ll_aligned_malloc<64>(size);
+ if (!ret)
+ {
+ LL_ERRS() << "Failed to allocate for LLVBOPool buffer" << LL_ENDL;
+ }
}
}
else
@@ -324,7 +327,7 @@ void LLVBOPool::cleanup()
//NOTE: each component must be AT LEAST 4 bytes in size to avoid a performance penalty on AMD hardware
-S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] =
+const S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] =
{
sizeof(LLVector4), // TYPE_VERTEX,
sizeof(LLVector4), // TYPE_NORMAL,
@@ -341,7 +344,7 @@ S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] =
sizeof(LLVector4), // TYPE_TEXTURE_INDEX (actually exists as position.w), no extra data, but stride is 16 bytes
};
-static std::string vb_type_name[] =
+static const std::string vb_type_name[] =
{
"TYPE_VERTEX",
"TYPE_NORMAL",
@@ -360,7 +363,7 @@ static std::string vb_type_name[] =
"TYPE_INDEX",
};
-U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] =
+const U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] =
{
GL_TRIANGLES,
GL_TRIANGLE_STRIP,
@@ -509,7 +512,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
}
}
- U32 map_tc[] =
+ static const U32 map_tc[] =
{
MAP_TEXCOORD1,
MAP_TEXCOORD2,
@@ -859,11 +862,6 @@ void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping)
{
sEnableVBOs = use_vbo && gGLManager.mHasVertexBufferObject;
sDisableVBOMapping = sEnableVBOs && no_vbo_mapping;
-
- if (!sPrivatePoolp)
- {
- sPrivatePoolp = LLPrivateMemoryPoolManager::getInstance()->newPool(LLPrivateMemoryPool::STATIC);
- }
}
//static
@@ -906,12 +904,6 @@ void LLVertexBuffer::cleanupClass()
sStreamVBOPool.cleanup();
sDynamicVBOPool.cleanup();
sDynamicCopyVBOPool.cleanup();
-
- if(sPrivatePoolp)
- {
- LLPrivateMemoryPoolManager::getInstance()->deletePool(sPrivatePoolp);
- sPrivatePoolp = NULL;
- }
}
//----------------------------------------------------------------------------
@@ -1202,7 +1194,7 @@ bool LLVertexBuffer::createGLBuffer(U32 size)
{
static int gl_buffer_idx = 0;
mGLBuffer = ++gl_buffer_idx;
- mMappedData = (U8*)ALLOCATE_MEM(sPrivatePoolp, size);
+ mMappedData = (U8*)ll_aligned_malloc_16(size);
disclaimMem(mSize);
mSize = size;
claimMem(mSize);
@@ -1244,7 +1236,7 @@ bool LLVertexBuffer::createGLIndices(U32 size)
}
else
{
- mMappedIndexData = (U8*)ALLOCATE_MEM(sPrivatePoolp, size);
+ mMappedIndexData = (U8*)ll_aligned_malloc_16(size);
static int gl_buffer_idx = 0;
mGLIndices = ++gl_buffer_idx;
mIndicesSize = size;
@@ -1267,7 +1259,7 @@ void LLVertexBuffer::destroyGLBuffer()
}
else
{
- FREE_MEM(sPrivatePoolp, (void*) mMappedData);
+ ll_aligned_free_16((void*)mMappedData);
mMappedData = NULL;
mEmpty = true;
}
@@ -1287,7 +1279,7 @@ void LLVertexBuffer::destroyGLIndices()
}
else
{
- FREE_MEM(sPrivatePoolp, (void*) mMappedIndexData);
+ ll_aligned_free_16((void*)mMappedIndexData);
mMappedIndexData = NULL;
mEmpty = true;
}
@@ -1390,7 +1382,7 @@ void LLVertexBuffer::setupVertexArray()
#endif
sGLRenderArray = mGLArray;
- U32 attrib_size[] =
+ static const U32 attrib_size[] =
{
3, //TYPE_VERTEX,
3, //TYPE_NORMAL,
@@ -1407,7 +1399,7 @@ void LLVertexBuffer::setupVertexArray()
1, //TYPE_TEXTURE_INDEX
};
- U32 attrib_type[] =
+ static const U32 attrib_type[] =
{
GL_FLOAT, //TYPE_VERTEX,
GL_FLOAT, //TYPE_NORMAL,
@@ -1424,7 +1416,7 @@ void LLVertexBuffer::setupVertexArray()
GL_UNSIGNED_INT, //TYPE_TEXTURE_INDEX
};
- bool attrib_integer[] =
+ static const bool attrib_integer[] =
{
false, //TYPE_VERTEX,
false, //TYPE_NORMAL,
@@ -1441,7 +1433,7 @@ void LLVertexBuffer::setupVertexArray()
true, //TYPE_TEXTURE_INDEX
};
- U32 attrib_normalized[] =
+ static const U32 attrib_normalized[] =
{
GL_FALSE, //TYPE_VERTEX,
GL_FALSE, //TYPE_NORMAL,
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index bd27296eb6..c89d7e3958 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -341,8 +341,8 @@ public:
static bool sDisableVBOMapping; //disable glMapBufferARB
static bool sEnableVBOs;
- static S32 sTypeSize[TYPE_MAX];
- static U32 sGLMode[LLRender::NUM_MODES];
+ static const S32 sTypeSize[TYPE_MAX];
+ static const U32 sGLMode[LLRender::NUM_MODES];
static U32 sGLRenderBuffer;
static U32 sGLRenderArray;
static U32 sGLRenderIndices;
diff --git a/indra/llui/llbadge.cpp b/indra/llui/llbadge.cpp
index 15b6899d74..589b75ab5b 100644
--- a/indra/llui/llbadge.cpp
+++ b/indra/llui/llbadge.cpp
@@ -102,6 +102,7 @@ LLBadge::LLBadge(const LLBadge::Params& p)
, mPaddingHoriz(p.padding_horiz)
, mPaddingVert(p.padding_vert)
, mParentScroller(NULL)
+ , mDrawAtParentTop(false)
{
if (mImage.isNull())
{
@@ -307,7 +308,14 @@ void LLBadge::draw()
// Compute y position
if (mLocationOffsetVCenter == BADGE_OFFSET_NOT_SPECIFIED)
{
- badge_center_y = owner_rect.mBottom + owner_rect.getHeight() * mLocationPercentVCenter;
+ if(mDrawAtParentTop)
+ {
+ badge_center_y = owner_rect.mTop - badge_height * 0.5f - 1;
+ }
+ else
+ {
+ badge_center_y = owner_rect.mBottom + owner_rect.getHeight() * mLocationPercentVCenter;
+ }
}
else
{
diff --git a/indra/llui/llbadge.h b/indra/llui/llbadge.h
index 4b21a71aaa..55f92e6e34 100644
--- a/indra/llui/llbadge.h
+++ b/indra/llui/llbadge.h
@@ -137,6 +137,8 @@ public:
const std::string getLabel() const { return wstring_to_utf8str(mLabel); }
void setLabel( const LLStringExplicit& label);
+ void setDrawAtParentTop(bool draw_at_top) { mDrawAtParentTop = draw_at_top;}
+
private:
LLPointer< LLUIImage > mBorderImage;
LLUIColor mBorderColor;
@@ -164,6 +166,7 @@ private:
F32 mPaddingVert;
LLScrollContainer* mParentScroller;
+ bool mDrawAtParentTop;
};
// Build time optimization, generate once in .cpp file
diff --git a/indra/llui/llbadgeowner.cpp b/indra/llui/llbadgeowner.cpp
index 55e64bb940..0557cd4375 100644
--- a/indra/llui/llbadgeowner.cpp
+++ b/indra/llui/llbadgeowner.cpp
@@ -64,6 +64,14 @@ void LLBadgeOwner::setBadgeVisibility(bool visible)
}
}
+void LLBadgeOwner::setDrawBadgeAtTop(bool draw_at_top)
+{
+ if (mBadge)
+ {
+ mBadge->setDrawAtParentTop(draw_at_top);
+ }
+}
+
void LLBadgeOwner::addBadgeToParentHolder()
{
LLView * owner_view = mBadgeOwnerView.get();
diff --git a/indra/llui/llbadgeowner.h b/indra/llui/llbadgeowner.h
index 53c2de95c8..01ed95f3a3 100644
--- a/indra/llui/llbadgeowner.h
+++ b/indra/llui/llbadgeowner.h
@@ -45,6 +45,7 @@ public:
bool hasBadgeHolderParent() const { return mHasBadgeHolderParent; };
void setBadgeVisibility(bool visible);
+ void setDrawBadgeAtTop(bool draw_at_top);
private:
diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp
index 559895da1a..00a933a0bb 100644
--- a/indra/llui/llcombobox.cpp
+++ b/indra/llui/llcombobox.cpp
@@ -845,6 +845,14 @@ void LLComboBox::setTextEntry(const LLStringExplicit& text)
}
}
+void LLComboBox::setKeystrokeOnEsc(BOOL enable)
+{
+ if (mTextEntry)
+ {
+ mTextEntry->setKeystrokeOnEsc(enable);
+ }
+}
+
void LLComboBox::onTextEntry(LLLineEditor* line_editor)
{
if (mTextEntryCallback != NULL)
diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h
index c9b1212b70..7d38c051a5 100644
--- a/indra/llui/llcombobox.h
+++ b/indra/llui/llcombobox.h
@@ -126,6 +126,7 @@ public:
virtual LLSD getValue() const;
void setTextEntry(const LLStringExplicit& text);
+ void setKeystrokeOnEsc(BOOL enable);
LLScrollListItem* add(const std::string& name, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE); // add item "name" to menu
LLScrollListItem* add(const std::string& name, const LLUUID& id, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE);
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index becb45fa79..cfab6b7fc8 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -125,6 +125,7 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
mTextLeftEdge(0), // computed in updateTextPadding() below
mTextRightEdge(0), // computed in updateTextPadding() below
mCommitOnFocusLost( p.commit_on_focus_lost ),
+ mKeystrokeOnEsc(FALSE),
mRevertOnEsc( p.revert_on_esc ),
mKeystrokeCallback( p.keystroke_callback() ),
mIsSelecting( FALSE ),
@@ -1494,6 +1495,10 @@ BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask)
{
setText(mPrevText);
// Note, don't set handled, still want to loose focus (won't commit becase text is now unchanged)
+ if (mKeystrokeOnEsc)
+ {
+ onKeystroke();
+ }
}
break;
@@ -1630,12 +1635,12 @@ BOOL LLLineEditor::handleUnicodeCharHere(llwchar uni_char)
BOOL LLLineEditor::canDoDelete() const
{
- return ( !mReadOnly && mText.length() > 0 && (!mPassDelete || (hasSelection() || (getCursor() < mText.length()))) );
+ return ( !mReadOnly && (!mPassDelete || (hasSelection() || (getCursor() < mText.length()))) );
}
void LLLineEditor::doDelete()
{
- if (canDoDelete())
+ if (canDoDelete() && mText.length() > 0)
{
// Prepare for possible rollback
LLLineEditorRollback rollback( this );
diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h
index 88468503df..287837a15c 100644
--- a/indra/llui/lllineeditor.h
+++ b/indra/llui/lllineeditor.h
@@ -214,6 +214,7 @@ public:
void setCommitOnFocusLost( BOOL b ) { mCommitOnFocusLost = b; }
void setRevertOnEsc( BOOL b ) { mRevertOnEsc = b; }
+ void setKeystrokeOnEsc(BOOL b) { mKeystrokeOnEsc = b; }
void setCursorColor(const LLColor4& c) { mCursorColor = c; }
const LLColor4& getCursorColor() const { return mCursorColor.get(); }
@@ -338,6 +339,7 @@ protected:
BOOL mCommitOnFocusLost;
BOOL mRevertOnEsc;
+ BOOL mKeystrokeOnEsc;
keystroke_callback_t mKeystrokeCallback;
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 7c1f4a4dca..212e27477b 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -1964,6 +1964,10 @@ BOOL LLScrollListCtrl::handleClick(S32 x, S32 y, MASK mask)
LLScrollListCell* cellp = item->getColumn(column_index);
cellp->setValue(item_value);
cellp->onCommit();
+ if (mLastSelected == NULL)
+ {
+ break;
+ }
}
}
//FIXME: find a better way to signal cell changes
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 1a49b94c23..134b76c720 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -2493,11 +2493,11 @@ void LLTextEditor::updateLinkSegments()
}
}
}
-
+
// if the link's label (what the user can edit) is a valid Url,
// then update the link's HREF to be the same as the label text.
// This lets users edit Urls in-place.
- if (LLUrlRegistry::instance().hasUrl(url_label))
+ if (acceptsTextInput() && LLUrlRegistry::instance().hasUrl(url_label))
{
std::string new_url = wstring_to_utf8str(url_label);
LLStringUtil::trim(new_url);
diff --git a/indra/llui/lltrans.cpp b/indra/llui/lltrans.cpp
index 4d4ff4236d..a1a8feedaa 100644
--- a/indra/llui/lltrans.cpp
+++ b/indra/llui/lltrans.cpp
@@ -36,6 +36,7 @@
#include <map>
LLTrans::template_map_t LLTrans::sStringTemplates;
+LLTrans::template_map_t LLTrans::sDefaultStringTemplates;
LLStringUtil::format_map_t LLTrans::sDefaultArgs;
struct StringDef : public LLInitParam::Block<StringDef>
@@ -76,7 +77,7 @@ bool LLTrans::parseStrings(LLXMLNodePtr &root, const std::set<std::string>& defa
LL_ERRS() << "Problem reading strings: " << xml_filename << LL_ENDL;
return false;
}
-
+ static bool default_strings_init = false;
sStringTemplates.clear();
sDefaultArgs.clear();
@@ -86,7 +87,10 @@ bool LLTrans::parseStrings(LLXMLNodePtr &root, const std::set<std::string>& defa
{
LLTransTemplate xml_template(it->name, it->value);
sStringTemplates[xml_template.mName] = xml_template;
-
+ if (!default_strings_init)
+ {
+ sDefaultStringTemplates[xml_template.mName] = xml_template;
+ }
std::set<std::string>::const_iterator iter = default_args.find(xml_template.mName);
if (iter != default_args.end())
{
@@ -96,6 +100,7 @@ bool LLTrans::parseStrings(LLXMLNodePtr &root, const std::set<std::string>& defa
sDefaultArgs[name] = xml_template.mText;
}
}
+ default_strings_init = true;
return true;
}
@@ -138,12 +143,17 @@ bool LLTrans::parseLanguageStrings(LLXMLNodePtr &root)
static LLTrace::BlockTimerStatHandle FTM_GET_TRANS("Translate string");
//static
-std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil::format_map_t& msg_args)
+std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil::format_map_t& msg_args, bool def_string)
{
// Don't care about time as much as call count. Make sure we're not
// calling LLTrans::getString() in an inner loop. JC
LL_RECORD_BLOCK_TIME(FTM_GET_TRANS);
+ if (def_string)
+ {
+ return getDefString(xml_desc, msg_args);
+ }
+
template_map_t::iterator iter = sStringTemplates.find(xml_desc);
if (iter != sStringTemplates.end())
{
@@ -161,13 +171,38 @@ std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil::
}
}
+//static
+std::string LLTrans::getDefString(const std::string &xml_desc, const LLStringUtil::format_map_t& msg_args)
+{
+ template_map_t::iterator iter = sDefaultStringTemplates.find(xml_desc);
+ if (iter != sDefaultStringTemplates.end())
+ {
+ std::string text = iter->second.mText;
+ LLStringUtil::format_map_t args = sDefaultArgs;
+ args.insert(msg_args.begin(), msg_args.end());
+ LLStringUtil::format(text, args);
+
+ return text;
+ }
+ else
+ {
+ LL_WARNS_ONCE("configuration") << "Missing String in strings.xml: [" << xml_desc << "]" << LL_ENDL;
+ return "MissingString(" + xml_desc + ")";
+ }
+}
+
//static
-std::string LLTrans::getString(const std::string &xml_desc, const LLSD& msg_args)
+std::string LLTrans::getString(const std::string &xml_desc, const LLSD& msg_args, bool def_string)
{
// Don't care about time as much as call count. Make sure we're not
// calling LLTrans::getString() in an inner loop. JC
LL_RECORD_BLOCK_TIME(FTM_GET_TRANS);
+ if (def_string)
+ {
+ return getDefString(xml_desc, msg_args);
+ }
+
template_map_t::iterator iter = sStringTemplates.find(xml_desc);
if (iter != sStringTemplates.end())
{
@@ -182,6 +217,23 @@ std::string LLTrans::getString(const std::string &xml_desc, const LLSD& msg_args
}
}
+//static
+std::string LLTrans::getDefString(const std::string &xml_desc, const LLSD& msg_args)
+{
+ template_map_t::iterator iter = sDefaultStringTemplates.find(xml_desc);
+ if (iter != sDefaultStringTemplates.end())
+ {
+ std::string text = iter->second.mText;
+ LLStringUtil::format(text, msg_args);
+ return text;
+ }
+ else
+ {
+ LL_WARNS_ONCE("configuration") << "Missing String in strings.xml: [" << xml_desc << "]" << LL_ENDL;
+ return "MissingString(" + xml_desc + ")";
+ }
+}
+
//static
bool LLTrans::findString(std::string &result, const std::string &xml_desc, const LLStringUtil::format_map_t& msg_args)
{
diff --git a/indra/llui/lltrans.h b/indra/llui/lltrans.h
index a47ce94f08..9bd751fc78 100644
--- a/indra/llui/lltrans.h
+++ b/indra/llui/lltrans.h
@@ -76,8 +76,10 @@ public:
* @param args A list of substrings to replace in the string
* @returns Translated string
*/
- static std::string getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args);
- static std::string getString(const std::string &xml_desc, const LLSD& args);
+ static std::string getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args, bool def_string = false);
+ static std::string getDefString(const std::string &xml_desc, const LLStringUtil::format_map_t& args);
+ static std::string getString(const std::string &xml_desc, const LLSD& args, bool def_string = false);
+ static std::string getDefString(const std::string &xml_desc, const LLSD& args);
static bool findString(std::string &result, const std::string &xml_desc, const LLStringUtil::format_map_t& args);
static bool findString(std::string &result, const std::string &xml_desc, const LLSD& args);
@@ -92,7 +94,7 @@ public:
* @param xml_desc String's description
* @returns Translated string
*/
- static std::string getString(const std::string &xml_desc)
+ static std::string getString(const std::string &xml_desc, bool def_string = false)
{
LLStringUtil::format_map_t empty;
return getString(xml_desc, empty);
@@ -128,6 +130,7 @@ public:
private:
typedef std::map<std::string, LLTransTemplate > template_map_t;
static template_map_t sStringTemplates;
+ static template_map_t sDefaultStringTemplates;
static LLStringUtil::format_map_t sDefaultArgs;
};
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index a4dc5bcde1..cd9b52d164 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -298,7 +298,7 @@ std::string LLUrlEntryHTTPLabel::getUrl(const std::string &string) const
LLUrlEntryInvalidSLURL::LLUrlEntryInvalidSLURL()
: LLUrlEntryBase()
{
- mPattern = boost::regex("(http://(maps.secondlife.com|slurl.com)/secondlife/|secondlife://(/app/(worldmap|teleport)/)?)[^ /]+(/-?[0-9]+){1,3}(/?(\\?title|\\?img|\\?msg)=\\S*)?/?",
+ mPattern = boost::regex("(https?://(maps.secondlife.com|slurl.com)/secondlife/|secondlife://(/app/(worldmap|teleport)/)?)[^ /]+(/-?[0-9]+){1,3}(/?(\\?title|\\?img|\\?msg)=\\S*)?/?",
boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_http.xml";
mTooltip = LLTrans::getString("TooltipHttpUrl");
@@ -385,8 +385,9 @@ bool LLUrlEntryInvalidSLURL::isSLURLvalid(const std::string &url) const
LLUrlEntrySLURL::LLUrlEntrySLURL()
{
// see http://slurl.com/about.php for details on the SLURL format
- mPattern = boost::regex("http://(maps.secondlife.com|slurl.com)/secondlife/[^ /]+(/\\d+){0,3}(/?(\\?title|\\?img|\\?msg)=\\S*)?/?",
+ mPattern = boost::regex("https?://(maps.secondlife.com|slurl.com)/secondlife/[^ /]+(/\\d+){0,3}(/?(\\?title|\\?img|\\?msg)=\\S*)?/?",
boost::regex::perl|boost::regex::icase);
+ mIcon = "Hand";
mMenuName = "menu_url_slurl.xml";
mTooltip = LLTrans::getString("TooltipSLURL");
}
diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h
index 28e9931718..78c149d9fd 100644
--- a/indra/llui/llurlentry.h
+++ b/indra/llui/llurlentry.h
@@ -175,6 +175,7 @@ class LLUrlEntrySLURL : public LLUrlEntryBase
{
public:
LLUrlEntrySLURL();
+ /*virtual*/ bool isTrusted() const { return true; }
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
/*virtual*/ std::string getLocation(const std::string &url) const;
};
diff --git a/indra/llui/llviewereventrecorder.cpp b/indra/llui/llviewereventrecorder.cpp
index 9fe6a542b4..8754cfebbb 100644
--- a/indra/llui/llviewereventrecorder.cpp
+++ b/indra/llui/llviewereventrecorder.cpp
@@ -34,11 +34,11 @@ LLViewerEventRecorder::LLViewerEventRecorder() {
logEvents = false;
// Remove any previous event log file
std::string old_log_ui_events_to_llsd_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife_Events_log.old");
- LLFile::remove(old_log_ui_events_to_llsd_file);
+ LLFile::remove(old_log_ui_events_to_llsd_file, ENOENT);
mLogFilename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife_Events_log.llsd");
- LLFile::rename(mLogFilename, old_log_ui_events_to_llsd_file);
+ LLFile::rename(mLogFilename, old_log_ui_events_to_llsd_file, ENOENT);
}
diff --git a/indra/llvfs/lldir_linux.cpp b/indra/llvfs/lldir_linux.cpp
index 5b269eb56b..2cd06b81f8 100644
--- a/indra/llvfs/lldir_linux.cpp
+++ b/indra/llvfs/lldir_linux.cpp
@@ -208,7 +208,7 @@ void LLDir_Linux::initAppDirs(const std::string &app_name,
LL_WARNS() << "Couldn't create LL_PATH_CACHE dir " << getExpandedFilename(LL_PATH_CACHE,"") << LL_ENDL;
}
- mCAFile = getExpandedFilename(LL_PATH_APP_SETTINGS, "ca-bundle.crt");
+ mCAFile = getExpandedFilename(LL_PATH_EXECUTABLE, "ca-bundle.crt");
}
U32 LLDir_Linux::countFilesInDir(const std::string &dirname, const std::string &mask)
diff --git a/indra/llvfs/lldir_mac.cpp b/indra/llvfs/lldir_mac.cpp
index cecc98bbfd..79c4362747 100644
--- a/indra/llvfs/lldir_mac.cpp
+++ b/indra/llvfs/lldir_mac.cpp
@@ -173,7 +173,7 @@ void LLDir_Mac::initAppDirs(const std::string &app_name,
mAppRODataDir = app_read_only_data_dir;
mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins";
}
- mCAFile = getExpandedFilename(LL_PATH_APP_SETTINGS, "ca-bundle.crt");
+ mCAFile = getExpandedFilename(LL_PATH_EXECUTABLE, "../Resources", "ca-bundle.crt");
}
std::string LLDir_Mac::getCurPath()
diff --git a/indra/llvfs/lldir_solaris.cpp b/indra/llvfs/lldir_solaris.cpp
index a773a69d44..d3536a12ee 100644
--- a/indra/llvfs/lldir_solaris.cpp
+++ b/indra/llvfs/lldir_solaris.cpp
@@ -226,7 +226,7 @@ void LLDir_Solaris::initAppDirs(const std::string &app_name,
LL_WARNS() << "Couldn't create LL_PATH_CACHE dir " << getExpandedFilename(LL_PATH_CACHE,"") << LL_ENDL;
}
- mCAFile = getExpandedFilename(LL_PATH_APP_SETTINGS, "ca-bundle.crt");
+ mCAFile = getExpandedFilename(LL_PATH_EXECUTABLE, "ca-bundle.crt");
}
U32 LLDir_Solaris::countFilesInDir(const std::string &dirname, const std::string &mask)
diff --git a/indra/llvfs/lldir_win32.cpp b/indra/llvfs/lldir_win32.cpp
index c4a4c74d1e..9836fa28f2 100644
--- a/indra/llvfs/lldir_win32.cpp
+++ b/indra/llvfs/lldir_win32.cpp
@@ -233,7 +233,7 @@ void LLDir_Win32::initAppDirs(const std::string &app_name,
LL_WARNS() << "Couldn't create LL_PATH_CACHE dir " << getExpandedFilename(LL_PATH_CACHE,"") << LL_ENDL;
}
- mCAFile = getExpandedFilename(LL_PATH_APP_SETTINGS, "ca-bundle.crt");
+ mCAFile = getExpandedFilename( LL_PATH_EXECUTABLE, "ca-bundle.crt" );
}
U32 LLDir_Win32::countFilesInDir(const std::string &dirname, const std::string &mask)
diff --git a/indra/llvfs/lllfsthread.cpp b/indra/llvfs/lllfsthread.cpp
index 2fd2614cce..be8e83a56f 100644
--- a/indra/llvfs/lllfsthread.cpp
+++ b/indra/llvfs/lllfsthread.cpp
@@ -52,13 +52,14 @@ S32 LLLFSThread::updateClass(U32 ms_elapsed)
//static
void LLLFSThread::cleanupClass()
{
+ llassert(sLocal != NULL);
sLocal->setQuitting();
while (sLocal->getPending())
{
sLocal->update(0);
}
delete sLocal;
- sLocal = 0;
+ sLocal = NULL;
}
//----------------------------------------------------------------------------
@@ -75,6 +76,7 @@ LLLFSThread::LLLFSThread(bool threaded) :
LLLFSThread::~LLLFSThread()
{
+ // mLocalAPRFilePoolp cleanup in LLThread
// ~LLQueuedThread() will be called here
}
diff --git a/indra/llvfs/llvfs.cpp b/indra/llvfs/llvfs.cpp
index db0eac7031..d5bd1834c2 100644
--- a/indra/llvfs/llvfs.cpp
+++ b/indra/llvfs/llvfs.cpp
@@ -2120,7 +2120,11 @@ time_t LLVFS::creationTime()
int errors = LLFile::stat(mDataFilename, &data_file_stat);
if (0 == errors)
{
- return data_file_stat.st_ctime;
+ time_t creation_time = data_file_stat.st_ctime;
+#if LL_DARWIN
+ creation_time = data_file_stat.st_birthtime;
+#endif
+ return creation_time;
}
return 0;
}
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 5f35a0f0f9..843294c239 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -1515,6 +1515,7 @@ void LLWindowMacOSX::updateCursor()
case UI_CURSOR_NOLOCKED:
case UI_CURSOR_ARROWLOCKED:
case UI_CURSOR_GRABLOCKED:
+ case UI_CURSOR_PIPETTE:
case UI_CURSOR_TOOLTRANSLATE:
case UI_CURSOR_TOOLROTATE:
case UI_CURSOR_TOOLSCALE:
@@ -1565,6 +1566,7 @@ void LLWindowMacOSX::initCursors()
initPixmapCursor(UI_CURSOR_NOLOCKED, 8, 8);
initPixmapCursor(UI_CURSOR_ARROWLOCKED, 1, 1);
initPixmapCursor(UI_CURSOR_GRABLOCKED, 2, 14);
+ initPixmapCursor(UI_CURSOR_PIPETTE, 3, 29);
initPixmapCursor(UI_CURSOR_TOOLTRANSLATE, 1, 1);
initPixmapCursor(UI_CURSOR_TOOLROTATE, 1, 1);
initPixmapCursor(UI_CURSOR_TOOLSCALE, 1, 1);
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 9fa07d1d34..f98c2423e5 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -69,6 +69,10 @@ const F32 ICON_FLASH_TIME = 0.5f;
#define WM_DPICHANGED 0x02E0
#endif
+#ifndef USER_DEFAULT_SCREEN_DPI
+#define USER_DEFAULT_SCREEN_DPI 96 // Win7
+#endif
+
extern BOOL gDebugWindowProc;
LPWSTR gIconResource = IDI_APPLICATION;
@@ -1545,7 +1549,10 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
(LLRender::sGLCoreProfile ? " core" : " compatibility") << " context." << LL_ENDL;
done = true;
- if (LLRender::sGLCoreProfile)
+ // force sNoFixedFunction iff we're trying to use nsight debugging which does not support many legacy API uses
+
+ // nSight doesn't support use of legacy API funcs in the fixed function pipe
+ if (LLRender::sGLCoreProfile || LLRender::sNsightDebugSupport)
{
LLGLSLShader::sNoFixedFunction = true;
}
@@ -2701,6 +2708,14 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
}
}
break;
+ default:
+ {
+ if (gDebugWindowProc)
+ {
+ LL_INFOS("Window") << "Unhandled windows message code: " << U32(u_msg) << LL_ENDL;
+ }
+ }
+ break;
}
window_imp->mCallbacks->handlePauseWatchdog(window_imp);
diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h
index 77065dcf8d..8136a3e88a 100644
--- a/indra/llxml/llcontrol.h
+++ b/indra/llxml/llcontrol.h
@@ -357,7 +357,8 @@ private:
mCachedValue = convert_from_llsd<T>(controlp->get(), mType, name);
// Add a listener to the controls signal...
- mConnection = controlp->getSignal()->connect(
+ // NOTE: All listeners connected to 0 group, for guaranty that variable handlers (gSavedSettings) call last
+ mConnection = controlp->getSignal()->connect(0,
boost::bind(&LLControlCache<T>::handleValueChange, this, _2)
);
mType = controlp->type();
diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 189beb75ba..2bd5526a86 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -203,6 +203,8 @@ void MediaPluginCEF::onTitleChangeCallback(std::string title)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text");
message.setValue("name", title);
+ message.setValueBoolean("history_back_available", mCEFLib->canGoBack());
+ message.setValueBoolean("history_forward_available", mCEFLib->canGoForward());
sendMessage(message);
}
@@ -808,8 +810,9 @@ void MediaPluginCEF::keyEvent(dullahan::EKeyEvent key_event, LLSD native_key_dat
bool event_isrepeat = native_key_data["event_isrepeat"].asBoolean();
// adding new code below in unicodeInput means we don't send ascii chars
- // here too or we get double key presses on a mac.
- if (((unsigned char)event_chars < 0x20 || (unsigned char)event_chars >= 0x7f ))
+ // here too or we get double key presses on a mac.
+ bool esc_key = (event_umodchars == 27);
+ if (esc_key || ((unsigned char)event_chars < 0x10 || (unsigned char)event_chars >= 0x7f ))
{
mCEFLib->nativeKeyboardEventOSX(key_event, event_modifiers,
event_keycode, event_chars,
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 6b16713add..b7a860aae0 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -201,7 +201,6 @@ set(viewer_SOURCE_FILES
llflickrconnect.cpp
llfloaterabout.cpp
llfloaterbvhpreview.cpp
- llfloaterauction.cpp
llfloaterautoreplacesettings.cpp
llfloateravatar.cpp
llfloateravatarpicker.cpp
@@ -345,6 +344,7 @@ set(viewer_SOURCE_FILES
llhudview.cpp
llimagefiltersmanager.cpp
llimhandler.cpp
+ llimprocessing.cpp
llimview.cpp
llinspect.cpp
llinspectavatar.cpp
@@ -529,6 +529,7 @@ set(viewer_SOURCE_FILES
llscriptfloater.cpp
llscrollingpanelparam.cpp
llscrollingpanelparambase.cpp
+ llsculptidsize.cpp
llsearchcombobox.cpp
llsearchhistory.cpp
llsecapi.cpp
@@ -821,7 +822,6 @@ set(viewer_HEADER_FILES
llflickrconnect.h
llfloaterabout.h
llfloaterbvhpreview.h
- llfloaterauction.h
llfloaterautoreplacesettings.h
llfloateravatar.h
llfloateravatarpicker.h
@@ -966,6 +966,7 @@ set(viewer_HEADER_FILES
llhudtext.h
llhudview.h
llimagefiltersmanager.h
+ llimprocessing.h
llimview.h
llinspect.h
llinspectavatar.h
@@ -1141,6 +1142,7 @@ set(viewer_HEADER_FILES
llscriptruntimeperms.h
llscrollingpanelparam.h
llscrollingpanelparambase.h
+ llsculptidsize.h
llsearchcombobox.h
llsearchhistory.h
llsecapi.h
@@ -1624,7 +1626,6 @@ set(viewer_APPSETTINGS_FILES
app_settings/viewerart.xml
${CMAKE_SOURCE_DIR}/../etc/message.xml
${CMAKE_SOURCE_DIR}/../scripts/messages/message_template.msg
- ${AUTOBUILD_INSTALL_DIR}/ca-bundle.crt
packages-info.txt
)
diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist
index 8aabd6818b..af4cf26ac6 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_SHORT_VERSION_STRING}</string>
+ <string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 76e9e619d6..cbad66a094 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-5.1.4
+5.1.7
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 1689f66e8b..f0782e0bf7 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -2369,7 +2369,7 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>DebugShowPrivateMem</key>
+ <key>DEPRECATED: DebugShowPrivateMem</key> <!-- deprecated (see MAINT-8091) -->
<map>
<key>Comment</key>
<string>Show Private Mem Info</string>
@@ -4646,6 +4646,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>IgnoreFOVZoomForLODs</key>
+ <map>
+ <key>Comment</key>
+ <string>Ignore zoom effect(CTRL+0) when calculating lods.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>IgnoreAllNotifications</key>
<map>
<key>Comment</key>
@@ -4798,7 +4809,7 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
- <integer>0</integer>
+ <integer>1</integer>
</map>
<key>InventoryOutboxDisplayBoth</key>
<map>
@@ -6408,10 +6419,10 @@
<key>Value</key>
<real>600.0</real>
</map>
- <key>MemoryPrivatePoolEnabled</key>
+ <key>MemoryPrivatePoolEnabled</key> <!-- deprecated (see MAINT-8091) -->
<map>
<key>Comment</key>
- <string>Enable the private memory pool management</string>
+ <string>DEPRECATED: Enable the private memory pool management</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -6419,10 +6430,10 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>MemoryPrivatePoolSize</key>
+ <key>MemoryPrivatePoolSize</key> <!-- deprecated (see MAINT-8091) -->
<map>
<key>Comment</key>
- <string>Size of the private memory pool in MB (min. value is 256)</string>
+ <string>DEPRECATED: Size of the private memory pool in MB (min. value is 256)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -8631,7 +8642,19 @@
<key>Value</key>
<integer>0</integer>
</map>
-
+ <key>RenderNsightDebugSupport</key>
+ <map>
+ <key>Comment</key>
+ <string>
+ Disable features which prevent nVidia nSight from being usable with SL. Requires restart.
+ </string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>RenderLocalLights</key>
<map>
<key>Comment</key>
@@ -10158,9 +10181,9 @@
<key>RenderAutoMuteByteLimit</key>
<map>
<key>Comment</key>
- <string>OBSOLETE and UNUSED.</string>
+ <string>If avatar attachment size exceed this value (in bytes) attachment will not be rendered. Excludes attachments worn by own avatar.</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
@@ -12327,7 +12350,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>500.0</real>
+ <real>3000.0</real>
</map>
<key>UpdaterMaximumBandwidth</key>
<map>
diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml
index 92e61d2e86..3d4bd659f1 100644
--- a/indra/newview/app_settings/settings_per_account.xml
+++ b/indra/newview/app_settings/settings_per_account.xml
@@ -392,5 +392,27 @@
<key>Value</key>
<string></string>
</map>
+ <key>SnapshotBaseDir</key>
+ <map>
+ <key>Comment</key>
+ <string>Path to last snapshot save location</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string></string>
+ </map>
+ <key>SnapshotBaseName</key>
+ <map>
+ <key>Comment</key>
+ <string>Pattern for naming snapshots</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>Snapshot</string>
+ </map>
</map>
</llsd>
diff --git a/indra/newview/ca-bundle.crt b/indra/newview/ca-bundle.crt
deleted file mode 100644
index e1c052d6a8..0000000000
--- a/indra/newview/ca-bundle.crt
+++ /dev/null
@@ -1,3899 +0,0 @@
-##
-## /Users/jenkins/slave-jenkins-platform/workspace/sdk-4.6.17-osx/build/release/bin/ca-bundle.crt -- Bundle of CA Root Certificates
-##
-## Certificate data from Mozilla as of: Sat Dec 29 20:03:40 2012
-##
-## This is a bundle of X.509 certificates of public Certificate Authorities
-## (CA). These were automatically extracted from Mozilla's root certificates
-## file (certdata.txt). This file can be found in the mozilla source tree:
-## http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1
-##
-## It contains the certificates in PEM format and therefore
-## can be directly used with curl / libcurl / php_curl, or with
-## an Apache+mod_ssl webserver for SSL client authentication.
-## Just configure this file as the SSLCACertificateFile.
-##
-
-# @(#) $RCSfile: certdata.txt,v $ $Revision: 1.87 $ $Date: 2012/12/29 16:32:45 $
-
-GTE CyberTrust Global Root
-==========================
------BEGIN CERTIFICATE-----
-MIICWjCCAcMCAgGlMA0GCSqGSIb3DQEBBAUAMHUxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9HVEUg
-Q29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNvbHV0aW9ucywgSW5jLjEjMCEG
-A1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJvb3QwHhcNOTgwODEzMDAyOTAwWhcNMTgwODEz
-MjM1OTAwWjB1MQswCQYDVQQGEwJVUzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQL
-Ex5HVEUgQ3liZXJUcnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0
-IEdsb2JhbCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVD6C28FCc6HrHiM3dFw4u
-sJTQGz0O9pTAipTHBsiQl8i4ZBp6fmw8U+E3KHNgf7KXUwefU/ltWJTSr41tiGeA5u2ylc9yMcql
-HHK6XALnZELn+aks1joNrI1CqiQBOeacPwGFVw1Yh0X404Wqk2kmhXBIgD8SFcd5tB8FLztimQID
-AQABMA0GCSqGSIb3DQEBBAUAA4GBAG3rGwnpXtlR22ciYaQqPEh346B8pt5zohQDhT37qw4wxYMW
-M4ETCJ57NE7fQMh017l93PR2VX2bY1QY6fDq81yx2YtCHrnAlU66+tXifPVoYb+O7AWXX1uw16OF
-NMQkpw0PlZPvy5TYnh+dXIVtx6quTx8itc2VrbqnzPmrC3p/
------END CERTIFICATE-----
-
-Thawte Server CA
-================
------BEGIN CERTIFICATE-----
-MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBxDELMAkGA1UEBhMCWkExFTATBgNVBAgT
-DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3Vs
-dGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UE
-AxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5j
-b20wHhcNOTYwODAxMDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkGA1UEBhMCWkExFTATBgNV
-BAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29u
-c3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcG
-A1UEAxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0
-ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANOkUG7I/1Zr5s9dtuoMaHVHoqrC2oQl
-/Kj0R1HahbUgdJSGHg91yekIYfUGbTBuFRkC6VLAYttNmZ7iagxEOM3+vuNkCXDF/rFrKbYvScg7
-1CcEJRCXL+eQbcAoQpnXTEPew/UhbVSfXcNY4cDk2VuwuNy0e982OsK1ZiIS1ocNAgMBAAGjEzAR
-MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAB/pMaVz7lcxG7oWDTSEwjsrZqG9J
-GubaUeNgcGyEYRGhGshIPllDfU+VPaGLtwtimHp1it2ITk6eQNuozDJ0uW8NxuOzRAvZim+aKZuZ
-GCg70eNAKJpaPNW15yAbi8qkq43pUdniTCxZqdq5snUb9kLy78fyGPmJvKP/iiMucEc=
------END CERTIFICATE-----
-
-Thawte Premium Server CA
-========================
------BEGIN CERTIFICATE-----
-MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkExFTATBgNVBAgT
-DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3Vs
-dGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UE
-AxMYVGhhd3RlIFByZW1pdW0gU2VydmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZl
-ckB0aGF3dGUuY29tMB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYT
-AlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsGA1UEChMU
-VGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2
-aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNlcnZlciBDQTEoMCYGCSqGSIb3DQEJARYZ
-cHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2
-aovXwlue2oFBYo847kkEVdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIh
-Udib0GfQug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMRuHM/
-qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQAm
-SCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUIhfzJATj/Tb7yFkJD57taRvvBxhEf
-8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JMpAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7t
-UCemDaYj+bvLpgcUQg==
------END CERTIFICATE-----
-
-Equifax Secure CA
-=================
------BEGIN CERTIFICATE-----
-MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJVUzEQMA4GA1UE
-ChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5
-MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoT
-B0VxdWlmYXgxLTArBgNVBAsTJEVxdWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCB
-nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPR
-fM6fBeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+AcJkVV5MW
-8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kCAwEAAaOCAQkwggEFMHAG
-A1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UE
-CxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoG
-A1UdEAQTMBGBDzIwMTgwODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvS
-spXXR9gjIBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQFMAMB
-Af8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GBAFjOKer89961
-zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y7qj/WsjTVbJmcVfewCHrPSqnI0kB
-BIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee95
-70+sB3c4
------END CERTIFICATE-----
-
-Digital Signature Trust Co. Global CA 1
-=======================================
------BEGIN CERTIFICATE-----
-MIIDKTCCApKgAwIBAgIENnAVljANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQGEwJVUzEkMCIGA1UE
-ChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREwDwYDVQQLEwhEU1RDQSBFMTAeFw05ODEy
-MTAxODEwMjNaFw0xODEyMTAxODQwMjNaMEYxCzAJBgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFs
-IFNpZ25hdHVyZSBUcnVzdCBDby4xETAPBgNVBAsTCERTVENBIEUxMIGdMA0GCSqGSIb3DQEBAQUA
-A4GLADCBhwKBgQCgbIGpzzQeJN3+hijM3oMv+V7UQtLodGBmE5gGHKlREmlvMVW5SXIACH7TpWJE
-NySZj9mDSI+ZbZUTu0M7LklOiDfBu1h//uG9+LthzfNHwJmm8fOR6Hh8AMthyUQncWlVSn5JTe2i
-o74CTADKAqjuAQIxZA9SLRN0dja1erQtcQIBA6OCASQwggEgMBEGCWCGSAGG+EIBAQQEAwIABzBo
-BgNVHR8EYTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0
-dXJlIFRydXN0IENvLjERMA8GA1UECxMIRFNUQ0EgRTExDTALBgNVBAMTBENSTDEwKwYDVR0QBCQw
-IoAPMTk5ODEyMTAxODEwMjNagQ8yMDE4MTIxMDE4MTAyM1owCwYDVR0PBAQDAgEGMB8GA1UdIwQY
-MBaAFGp5fpFpRhgTCgJ3pVlbYJglDqL4MB0GA1UdDgQWBBRqeX6RaUYYEwoCd6VZW2CYJQ6i+DAM
-BgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4GB
-ACIS2Hod3IEGtgllsofIH160L+nEHvI8wbsEkBFKg05+k7lNQseSJqBcNJo4cvj9axY+IO6CizEq
-kzaFI4iKPANo08kJD038bKTaKHKTDomAsH3+gG9lbRgzl4vCa4nuYD3Im+9/KzJic5PLPON74nZ4
-RbyhkwS7hp86W0N6w4pl
------END CERTIFICATE-----
-
-Digital Signature Trust Co. Global CA 3
-=======================================
------BEGIN CERTIFICATE-----
-MIIDKTCCApKgAwIBAgIENm7TzjANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQGEwJVUzEkMCIGA1UE
-ChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREwDwYDVQQLEwhEU1RDQSBFMjAeFw05ODEy
-MDkxOTE3MjZaFw0xODEyMDkxOTQ3MjZaMEYxCzAJBgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFs
-IFNpZ25hdHVyZSBUcnVzdCBDby4xETAPBgNVBAsTCERTVENBIEUyMIGdMA0GCSqGSIb3DQEBAQUA
-A4GLADCBhwKBgQC/k48Xku8zExjrEH9OFr//Bo8qhbxe+SSmJIi2A7fBw18DW9Fvrn5C6mYjuGOD
-VvsoLeE4i7TuqAHhzhy2iCoiRoX7n6dwqUcUP87eZfCocfdPJmyMvMa1795JJ/9IKn3oTQPMx7JS
-xhcxEzu1TdvIxPbDDyQq2gyd55FbgM2UnQIBA6OCASQwggEgMBEGCWCGSAGG+EIBAQQEAwIABzBo
-BgNVHR8EYTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0
-dXJlIFRydXN0IENvLjERMA8GA1UECxMIRFNUQ0EgRTIxDTALBgNVBAMTBENSTDEwKwYDVR0QBCQw
-IoAPMTk5ODEyMDkxOTE3MjZagQ8yMDE4MTIwOTE5MTcyNlowCwYDVR0PBAQDAgEGMB8GA1UdIwQY
-MBaAFB6CTShlgDzJQW6sNS5ay97u+DlbMB0GA1UdDgQWBBQegk0oZYA8yUFurDUuWsve7vg5WzAM
-BgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4GB
-AEeNg61i8tuwnkUiBbmi1gMOOHLnnvx75pO2mqWilMg0HZHRxdf0CiUPPXiBng+xZ8SQTGPdXqfi
-up/1902lMXucKS1M/mQ+7LZT/uqb7YLbdHVLB3luHtgZg3Pe9T7Qtd7nS2h9Qy4qIOF+oHhEngj1
-mPnHfxsb1gYgAlihw6ID
------END CERTIFICATE-----
-
-Verisign Class 3 Public Primary Certification Authority
-=======================================================
------BEGIN CERTIFICATE-----
-MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMx
-FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmltYXJ5
-IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVow
-XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAz
-IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA
-A4GNADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhEBarsAx94
-f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/isI19wKTakyYbnsZogy1Ol
-hec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0GCSqGSIb3DQEBAgUAA4GBALtMEivPLCYA
-TxQT3ab7/AoRhIzzKBxnki98tsX63/Dolbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59Ah
-WM1pF+NEHJwZRDmJXNycAA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2Omuf
-Tqj/ZA1k
------END CERTIFICATE-----
-
-Verisign Class 1 Public Primary Certification Authority - G2
-============================================================
------BEGIN CERTIFICATE-----
-MIIDAjCCAmsCEEzH6qqYPnHTkxD4PTqJkZIwDQYJKoZIhvcNAQEFBQAwgcExCzAJBgNVBAYTAlVT
-MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMSBQdWJsaWMgUHJpbWFy
-eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln
-biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
-dCBOZXR3b3JrMB4XDTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVT
-MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMSBQdWJsaWMgUHJpbWFy
-eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln
-biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
-dCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCq0Lq+Fi24g9TK0g+8djHKlNgd
-k4xWArzZbxpvUjZudVYKVdPfQ4chEWWKfo+9Id5rMj8bhDSVBZ1BNeuS65bdqlk/AVNtmU/t5eIq
-WpDBucSmFc/IReumXY6cPvBkJHalzasab7bYe1FhbqZ/h8jit+U03EGI6glAvnOSPWvndQIDAQAB
-MA0GCSqGSIb3DQEBBQUAA4GBAKlPww3HZ74sy9mozS11534Vnjty637rXC0Jh9ZrbWB85a7FkCMM
-XErQr7Fd88e2CtvgFZMN3QO8x3aKtd1Pw5sTdbgBwObJW2uluIncrKTdcu1OofdPvAbT6shkdHvC
-lUGcZXNY8ZCaPGqxmMnEh7zPRW1F4m4iP/68DzFc6PLZ
------END CERTIFICATE-----
-
-Verisign Class 2 Public Primary Certification Authority - G2
-============================================================
------BEGIN CERTIFICATE-----
-MIIDAzCCAmwCEQC5L2DMiJ+hekYJuFtwbIqvMA0GCSqGSIb3DQEBBQUAMIHBMQswCQYDVQQGEwJV
-UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0NsYXNzIDIgUHVibGljIFByaW1h
-cnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjE6MDgGA1UECxMxKGMpIDE5OTggVmVyaVNp
-Z24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1
-c3QgTmV0d29yazAeFw05ODA1MTgwMDAwMDBaFw0yODA4MDEyMzU5NTlaMIHBMQswCQYDVQQGEwJV
-UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0NsYXNzIDIgUHVibGljIFByaW1h
-cnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjE6MDgGA1UECxMxKGMpIDE5OTggVmVyaVNp
-Z24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1
-c3QgTmV0d29yazCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAp4gBIXQs5xoD8JjhlzwPIQjx
-nNuX6Zr8wgQGE75fUsjMHiwSViy4AWkszJkfrbCWrnkE8hM5wXuYuggs6MKEEyyqaekJ9MepAqRC
-wiNPStjwDqL7MWzJ5m+ZJwf15vRMeJ5t60aG+rmGyVTyssSv1EYcWskVMP8NbPUtDm3Of3cCAwEA
-ATANBgkqhkiG9w0BAQUFAAOBgQByLvl/0fFx+8Se9sVeUYpAmLho+Jscg9jinb3/7aHmZuovCfTK
-1+qlK5X2JGCGTUQug6XELaDTrnhpb3LabK4I8GOSN+a7xDAXrXfMSTWqz9iP0b63GJZHc2pUIjRk
-LbYWm1lbtFFZOrMLFPQS32eg9K0yZF6xRnInjBJ7xUS0rg==
------END CERTIFICATE-----
-
-Verisign Class 3 Public Primary Certification Authority - G2
-============================================================
------BEGIN CERTIFICATE-----
-MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJBgNVBAYTAlVT
-MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy
-eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln
-biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
-dCBOZXR3b3JrMB4XDTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVT
-MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy
-eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln
-biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
-dCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCO
-FoUgRm1HP9SFIIThbbP4pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71
-lSk8UOg013gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwIDAQAB
-MA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSkU01UbSuvDV1Ai2TT
-1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7iF6YM40AIOw7n60RzKprxaZLvcRTD
-Oaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpYoJ2daZH9
------END CERTIFICATE-----
-
-GlobalSign Root CA
-==================
------BEGIN CERTIFICATE-----
-MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx
-GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds
-b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV
-BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD
-VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa
-DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc
-THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb
-Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP
-c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX
-gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
-HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF
-AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj
-Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG
-j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH
-hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC
-X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
------END CERTIFICATE-----
-
-GlobalSign Root CA - R2
-=======================
------BEGIN CERTIFICATE-----
-MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4GA1UECxMXR2xv
-YmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh
-bFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT
-aWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln
-bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6
-ErPLv4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8eoLrvozp
-s6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklqtTleiDTsvHgMCJiEbKjN
-S7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzdC9XZzPnqJworc5HGnRusyMvo4KD0L5CL
-TfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pazq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6C
-ygPCm48CAwEAAaOBnDCBmTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E
-FgQUm+IHV2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5nbG9i
-YWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG3lm0mi3f3BmGLjAN
-BgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4GsJ0/WwbgcQ3izDJr86iw8bmEbTUsp
-9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu
-01yiPqFbQfXf5WRDLenVOavSot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG7
-9G+dwfCMNYxdAfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
-TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
------END CERTIFICATE-----
-
-ValiCert Class 1 VA
-===================
------BEGIN CERTIFICATE-----
-MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp
-b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
-YXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh
-bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNTIy
-MjM0OFoXDTE5MDYyNTIyMjM0OFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0
-d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDEg
-UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0
-LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA
-A4GNADCBiQKBgQDYWYJ6ibiWuqYvaG9YLqdUHAZu9OqNSLwxlBfw8068srg1knaw0KWlAdcAAxIi
-GQj4/xEjm84H9b9pGib+TunRf50sQB1ZaG6m+FiwnRqP0z/x3BkGgagO4DrdyFNFCQbmD3DD+kCm
-DuJWBQ8YTfwggtFzVXSNdnKgHZ0dwN0/cQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFBoPUn0LBwG
-lN+VYH+Wexf+T3GtZMjdd9LvWVXoP+iOBSoh8gfStadS/pyxtuJbdxdA6nLWI8sogTLDAHkY7FkX
-icnGah5xyf23dKUlRWnFSKsZ4UWKJWsZ7uW7EvV/96aNUcPwnXS3qT6gpf+2SQMT2iLM7XGCK5nP
-Orf1LXLI
------END CERTIFICATE-----
-
-ValiCert Class 2 VA
-===================
------BEGIN CERTIFICATE-----
-MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp
-b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
-YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh
-bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAw
-MTk1NFoXDTE5MDYyNjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0
-d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIg
-UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0
-LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA
-A4GNADCBiQKBgQDOOnHK5avIWZJV16vYdA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVC
-CSRrCl6zfN1SLUzm1NZ9WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7Rf
-ZHM047QSv4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9vUJSZ
-SWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTuIYEZoDJJKPTEjlbV
-UjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwCW/POuZ6lcg5Ktz885hZo+L7tdEy8
-W9ViH0Pd
------END CERTIFICATE-----
-
-RSA Root Certificate 1
-======================
------BEGIN CERTIFICATE-----
-MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp
-b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
-YXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh
-bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAw
-MjIzM1oXDTE5MDYyNjAwMjIzM1owgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0
-d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDMg
-UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0
-LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA
-A4GNADCBiQKBgQDjmFGWHOjVsQaBalfDcnWTq8+epvzzFlLWLU2fNUSoLgRNB0mKOCn1dzfnt6td
-3zZxFJmP3MKS8edgkpfs2Ejcv8ECIMYkpChMMFp2bbFc893enhBxoYjHW5tBbcqwuI4V7q0zK89H
-BFx1cQqYJJgpp0lZpd34t0NiYfPT4tBVPwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFa7AliEZwgs
-3x/be0kz9dNnnfS0ChCzycUs4pJqcXgn8nCDQtM+z6lU9PHYkhaM0QTLS6vJn0WuPIqpsHEzXcjF
-V9+vqDWzf4mH6eglkrh/hXqu1rweN1gqZ8mRzyqBPu3GOd/APhmcGcwTTYJBtYze4D1gCCAPRX5r
-on+jjBXu
------END CERTIFICATE-----
-
-Verisign Class 1 Public Primary Certification Authority - G3
-============================================================
------BEGIN CERTIFICATE-----
-MIIEGjCCAwICEQCLW3VWhFSFCwDPrzhIzrGkMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV
-UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
-cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
-IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh
-dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw
-CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy
-dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv
-cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDEgUHVibGljIFByaW1hcnkg
-Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
-ggEBAN2E1Lm0+afY8wR4nN493GwTFtl63SRRZsDHJlkNrAYIwpTRMx/wgzUfbhvI3qpuFU5UJ+/E
-bRrsC+MO8ESlV8dAWB6jRx9x7GD2bZTIGDnt/kIYVt/kTEkQeE4BdjVjEjbdZrwBBDajVWjVojYJ
-rKshJlQGrT/KFOCsyq0GHZXi+J3x4GD/wn91K0zM2v6HmSHquv4+VNfSWXjbPG7PoBMAGrgnoeS+
-Z5bKoMWznN3JdZ7rMJpfo83ZrngZPyPpXNspva1VyBtUjGP26KbqxzcSXKMpHgLZ2x87tNcPVkeB
-FQRKr4Mn0cVYiMHd9qqnoxjaaKptEVHhv2Vrn5Z20T0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
-q2aN17O6x5q25lXQBfGfMY1aqtmqRiYPce2lrVNWYgFHKkTp/j90CxObufRNG7LRX7K20ohcs5/N
-y9Sn2WCVhDr4wTcdYcrnsMXlkdpUpqwxga6X3s0IrLjAl4B/bnKk52kTlWUfxJM8/XmPBNQ+T+r3
-ns7NZ3xPZQL/kYVUc8f/NveGLezQXk//EZ9yBta4GvFMDSZl4kSAHsef493oCtrspSCAaWihT37h
-a88HQfqDjrw43bAuEbFrskLMmrz5SCJ5ShkPshw+IHTZasO+8ih4E1Z5T21Q6huwtVexN2ZYI/Pc
-D98Kh8TvhgXVOBRgmaNL3gaWcSzy27YfpO8/7g==
------END CERTIFICATE-----
-
-Verisign Class 2 Public Primary Certification Authority - G3
-============================================================
------BEGIN CERTIFICATE-----
-MIIEGTCCAwECEGFwy0mMX5hFKeewptlQW3owDQYJKoZIhvcNAQEFBQAwgcoxCzAJBgNVBAYTAlVT
-MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29y
-azE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ug
-b25seTFFMEMGA1UEAxM8VmVyaVNpZ24gQ2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0
-aW9uIEF1dGhvcml0eSAtIEczMB4XDTk5MTAwMTAwMDAwMFoXDTM2MDcxNjIzNTk1OVowgcoxCzAJ
-BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1
-c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9y
-aXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNpZ24gQ2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBD
-ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
-AQEArwoNwtUs22e5LeWUJ92lvuCwTY+zYVY81nzD9M0+hsuiiOLh2KRpxbXiv8GmR1BeRjmL1Za6
-tW8UvxDOJxOeBUebMXoT2B/Z0wI3i60sR/COgQanDTAM6/c8DyAd3HJG7qUCyFvDyVZpTMUYwZF7
-C9UTAJu878NIPkZgIIUq1ZC2zYugzDLdt/1AVbJQHFauzI13TccgTacxdu9okoqQHgiBVrKtaaNS
-0MscxCM9H5n+TOgWY47GCI72MfbS+uV23bUckqNJzc0BzWjNqWm6o+sdDZykIKbBoMXRRkwXbdKs
-Zj+WjOCE1Db/IlnF+RFgqF8EffIa9iVCYQ/ESrg+iQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQA0
-JhU8wI1NQ0kdvekhktdmnLfexbjQ5F1fdiLAJvmEOjr5jLX77GDx6M4EsMjdpwOPMPOY36TmpDHf
-0xwLRtxyID+u7gU8pDM/CzmscHhzS5kr3zDCVLCoO1Wh/hYozUK9dG6A2ydEp85EXdQbkJgNHkKU
-sQAsBNB0owIFImNjzYO1+8FtYmtpdf1dcEG59b98377BMnMiIYtYgXsVkXq642RIsH/7NiXaldDx
-JBQX3RiAa0YjOVT1jmIJBB2UkKab5iXiQkWquJCtvgiPqQtCGJTPcjnhsUPgKM+351psE2tJs//j
-GHyJizNdrDPXp/naOlXJWBD5qu9ats9LS98q
------END CERTIFICATE-----
-
-Verisign Class 3 Public Primary Certification Authority - G3
-============================================================
------BEGIN CERTIFICATE-----
-MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV
-UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
-cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
-IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh
-dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw
-CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy
-dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv
-cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkg
-Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
-ggEBAMu6nFL8eB8aHm8bN3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1
-EUGO+i2tKmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGukxUc
-cLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBmCC+Vk7+qRy+oRpfw
-EuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJXwzw3sJ2zq/3avL6QaaiMxTJ5Xpj
-055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWuimi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
-ERSWwauSCPc/L8my/uRan2Te2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5f
-j267Cz3qWhMeDGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC
-/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565pF4ErWjfJXir0
-xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGtTxzhT5yvDwyd93gN2PQ1VoDa
-t20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ==
------END CERTIFICATE-----
-
-Verisign Class 4 Public Primary Certification Authority - G3
-============================================================
------BEGIN CERTIFICATE-----
-MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV
-UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
-cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
-IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh
-dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw
-CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy
-dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv
-cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFByaW1hcnkg
-Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
-ggEBAK3LpRFpxlmr8Y+1GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaS
-tBO3IFsJ+mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0GbdU6LM
-8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLmNxdLMEYH5IBtptiW
-Lugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XYufTsgsbSPZUd5cBPhMnZo0QoBmrX
-Razwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
-j/ola09b5KROJ1WrIhVZPMq1CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXtt
-mhwwjIDLk5Mqg6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm
-fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c2NU8Qh0XwRJd
-RTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/bLvSHgCwIe34QWKCudiyxLtG
-UPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg==
------END CERTIFICATE-----
-
-Entrust.net Secure Server CA
-============================
------BEGIN CERTIFICATE-----
-MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMCVVMxFDASBgNV
-BAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5uZXQvQ1BTIGluY29ycC4gYnkg
-cmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRl
-ZDE6MDgGA1UEAxMxRW50cnVzdC5uZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhv
-cml0eTAeFw05OTA1MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIG
-A1UEChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBi
-eSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1p
-dGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0
-aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQ
-aO2f55M28Qpku0f1BBc/I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5
-gXpa0zf3wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OCAdcw
-ggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHboIHYpIHVMIHSMQsw
-CQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5l
-dC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF
-bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENl
-cnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu
-dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0MFqBDzIwMTkw
-NTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8BdiE1U9s/8KAGv7UISX8+1i0Bow
-HQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAaMAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EA
-BAwwChsEVjQuMAMCBJAwDQYJKoZIhvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyN
-Ewr75Ji174z4xRAN95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9
-n9cd2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI=
------END CERTIFICATE-----
-
-Entrust.net Premium 2048 Secure Server CA
-=========================================
------BEGIN CERTIFICATE-----
-MIIEXDCCA0SgAwIBAgIEOGO5ZjANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChMLRW50cnVzdC5u
-ZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxp
-bWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNV
-BAMTKkVudHJ1c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQx
-NzUwNTFaFw0xOTEyMjQxODIwNTFaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3
-d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTEl
-MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5u
-ZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
-MIIBCgKCAQEArU1LqRKGsuqjIAcVFmQqK0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOL
-Gp18EzoOH1u3Hs/lJBQesYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSr
-hRSGlVuXMlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVTXTzW
-nLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/HoZdenoVve8AjhUi
-VBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH4QIDAQABo3QwcjARBglghkgBhvhC
-AQEEBAMCAAcwHwYDVR0jBBgwFoAUVeSB0RGAvtiJuQijMfmhJAkWuXAwHQYDVR0OBBYEFFXkgdER
-gL7YibkIozH5oSQJFrlwMB0GCSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0B
-AQUFAAOCAQEAWUesIYSKF8mciVMeuoCFGsY8Tj6xnLZ8xpJdGGQC49MGCBFhfGPjK50xA3B20qMo
-oPS7mmNz7W3lKtvtFKkrxjYR0CvrB4ul2p5cGZ1WEvVUKcgF7bISKo30Axv/55IQh7A6tcOdBTcS
-o8f0FbnVpDkWm1M6I5HxqIKiaohowXkCIryqptau37AUX7iH0N18f3v/rxzP5tsHrV7bhZ3QKw0z
-2wTR5klAEyt2+z7pnIkPFc4YsIV4IU9rTw76NmfNB/L/CNDi3tm/Kq+4h4YhPATKt5Rof8886ZjX
-OP/swNlQ8C5LWK5Gb9Auw2DaclVyvUxFnmG6v4SBkgPR0ml8xQ==
------END CERTIFICATE-----
-
-Baltimore CyberTrust Root
-=========================
------BEGIN CERTIFICATE-----
-MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJRTESMBAGA1UE
-ChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3li
-ZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoXDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMC
-SUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFs
-dGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKME
-uyKrmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsB
-UnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/C
-G9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9
-XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjpr
-l3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoI
-VDaGezq1BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEB
-BQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT929hkTI7gQCvlYpNRh
-cL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3WgxjkzSswF07r51XgdIGn9w/xZchMB5
-hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsa
-Y71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H
-RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
------END CERTIFICATE-----
-
-Equifax Secure Global eBusiness CA
-==================================
------BEGIN CERTIFICATE-----
-MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT
-RXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBTZWN1cmUgR2xvYmFsIGVCdXNp
-bmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIwMDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMx
-HDAaBgNVBAoTE0VxdWlmYXggU2VjdXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEds
-b2JhbCBlQnVzaW5lc3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRV
-PEnCUdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc58O/gGzN
-qfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/o5brhTMhHD4ePmBudpxn
-hcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAHMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j
-BBgwFoAUvqigdHJQa0S3ySPY+6j/s1draGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hs
-MA0GCSqGSIb3DQEBBAUAA4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okEN
-I7SS+RkAZ70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv8qIY
-NMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV
------END CERTIFICATE-----
-
-Equifax Secure eBusiness CA 1
-=============================
------BEGIN CERTIFICATE-----
-MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT
-RXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENB
-LTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQwMDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UE
-ChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNz
-IENBLTEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ
-1MRoRvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBuWqDZQu4a
-IZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKwEnv+j6YDAgMBAAGjZjBk
-MBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEp4MlIR21kW
-Nl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRKeDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQF
-AAOBgQB1W6ibAxHm6VZMzfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5
-lSE/9dR+WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN/Bf+
-KpYrtWKmpj29f5JZzVoqgrI3eQ==
------END CERTIFICATE-----
-
-Equifax Secure eBusiness CA 2
-=============================
------BEGIN CERTIFICATE-----
-MIIDIDCCAomgAwIBAgIEN3DPtTANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJVUzEXMBUGA1UE
-ChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2VjdXJlIGVCdXNpbmVzcyBDQS0y
-MB4XDTk5MDYyMzEyMTQ0NVoXDTE5MDYyMzEyMTQ0NVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoT
-DkVxdWlmYXggU2VjdXJlMSYwJAYDVQQLEx1FcXVpZmF4IFNlY3VyZSBlQnVzaW5lc3MgQ0EtMjCB
-nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA5Dk5kx5SBhsoNviyoynF7Y6yEb3+6+e0dMKP/wXn
-2Z0GvxLIPw7y1tEkshHe0XMJitSxLJgJDR5QRrKDpkWNYmi7hRsgcDKqQM2mll/EcTc/BPO3QSQ5
-BxoeLmFYoBIL5aXfxavqN3HMHMg3OrmXUqesxWoklE6ce8/AatbfIb0CAwEAAaOCAQkwggEFMHAG
-A1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORXF1aWZheCBTZWN1cmUx
-JjAkBgNVBAsTHUVxdWlmYXggU2VjdXJlIGVCdXNpbmVzcyBDQS0yMQ0wCwYDVQQDEwRDUkwxMBoG
-A1UdEAQTMBGBDzIwMTkwNjIzMTIxNDQ1WjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUUJ4L6q9e
-uSBIplBqy/3YIHqngnYwHQYDVR0OBBYEFFCeC+qvXrkgSKZQasv92CB6p4J2MAwGA1UdEwQFMAMB
-Af8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GBAAyGgq3oThr1
-jokn4jVYPSm0B482UJW/bsGe68SQsoWou7dC4A8HOd/7npCy0cE+U58DRLB+S/Rv5Hwf5+Kx5Lia
-78O9zt4LMjTZ3ijtM2vE1Nc9ElirfQkty3D1E4qUoSek1nDFbZS1yX2doNLGCEnZZpum0/QL3MUm
-V+GRMOrN
------END CERTIFICATE-----
-
-AddTrust Low-Value Services Root
-================================
------BEGIN CERTIFICATE-----
-MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
-QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRU
-cnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMwMTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQsw
-CQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBO
-ZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEB
-AQUAA4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ulCDtbKRY6
-54eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6ntGO0/7Gcrjyvd7ZWxbWr
-oulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyldI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1
-Zmne3yzxbrww2ywkEtvrNTVokMsAsJchPXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJui
-GMx1I4S+6+JNM3GOGvDC+Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8w
-HQYDVR0OBBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8EBTAD
-AQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBlMQswCQYDVQQGEwJT
-RTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEw
-HwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxt
-ZBsfzQ3duQH6lmM0MkhHma6X7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0Ph
-iVYrqW9yTkkz43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY
-eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJlpz/+0WatC7xr
-mYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOAWiFeIc9TVPC6b4nbqKqVz4vj
-ccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk=
------END CERTIFICATE-----
-
-AddTrust External Root
-======================
------BEGIN CERTIFICATE-----
-MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
-QWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYD
-VQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEw
-NDgzOFowbzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRU
-cnVzdCBFeHRlcm5hbCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0Eg
-Um9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvtH7xsD821
-+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9uMq/NzgtHj6RQa1wVsfw
-Tz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzXmk6vBbOmcZSccbNQYArHE504B4YCqOmo
-aSYYkKtMsE8jqzpPhNjfzp/haW+710LXa0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy
-2xSoRcRdKn23tNbE7qzNE0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv7
-7+ldU9U0WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYDVR0P
-BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0Jvf6xCZU7wO94CTL
-VBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRk
-VHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENB
-IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZl
-j7DYd7usQWxHYINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
-6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvCNr4TDea9Y355
-e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEXc4g/VhsxOBi0cQ+azcgOno4u
-G+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5amnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
------END CERTIFICATE-----
-
-AddTrust Public Services Root
-=============================
------BEGIN CERTIFICATE-----
-MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
-QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSAwHgYDVQQDExdBZGRU
-cnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAxMDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJ
-BgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5l
-dHdvcmsxIDAeBgNVBAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEF
-AAOCAQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV6tsfSlbu
-nyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nXGCwwfQ56HmIexkvA/X1i
-d9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnPdzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSG
-Aa2Il+tmzV7R/9x98oTaunet3IAIx6eH1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAw
-HM+A+WD+eeSI8t0A65RF62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0G
-A1UdDgQWBBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
-/zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDELMAkGA1UEBhMCU0Ux
-FDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29yazEgMB4G
-A1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4
-JNojVhaTdt02KLmuG7jD8WS6IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL
-+YPoRNWyQSW/iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao
-GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh4SINhwBk/ox9
-Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQmXiLsks3/QppEIW1cxeMiHV9H
-EufOX1362KqxMy3ZdvJOOjMMK7MtkAY=
------END CERTIFICATE-----
-
-AddTrust Qualified Certificates Root
-====================================
------BEGIN CERTIFICATE-----
-MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
-QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSMwIQYDVQQDExpBZGRU
-cnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcx
-CzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQ
-IE5ldHdvcmsxIzAhBgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG
-9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwqxBb/4Oxx
-64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G87B4pfYOQnrjfxvM0PC3
-KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i2O+tCBGaKZnhqkRFmhJePp1tUvznoD1o
-L/BLcHwTOK28FSXx1s6rosAx1i+f4P8UWfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GR
-wVY18BTcZTYJbqukB8c10cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HU
-MIHRMB0GA1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/
-BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6FrpGkwZzELMAkGA1UE
-BhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29y
-azEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlmaWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQAD
-ggEBABmrder4i2VhlRO6aQTvhsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxG
-GuoYQ992zPlmhpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X
-dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3P6CxB9bpT9ze
-RXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9YiQBCYz95OdBEsIJuQRno3eDB
-iFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5noxqE=
------END CERTIFICATE-----
-
-Entrust Root Certification Authority
-====================================
------BEGIN CERTIFICATE-----
-MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMCVVMxFjAUBgNV
-BAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0Lm5ldC9DUFMgaXMgaW5jb3Jw
-b3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMWKGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsG
-A1UEAxMkRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0
-MloXDTI2MTEyNzIwNTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMu
-MTkwNwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSByZWZlcmVu
-Y2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNVBAMTJEVudHJ1c3QgUm9v
-dCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
-ALaVtkNC+sZtKm9I35RMOVcF7sN5EUFoNu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYsz
-A9u3g3s+IIRe7bJWKKf44LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOww
-Cj0Yzfv9KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGIrb68
-j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi94DkZfs0Nw4pgHBN
-rziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOBsDCBrTAOBgNVHQ8BAf8EBAMCAQYw
-DwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAigA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1
-MzQyWjAfBgNVHSMEGDAWgBRokORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DH
-hmak8fdLQ/uEvW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA
-A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9tO1KzKtvn1ISM
-Y/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6ZuaAGAT/3B+XxFNSRuzFVJ7yVTa
-v52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTS
-W3iDVuycNsMm4hH2Z0kdkquM++v/eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0
-tHuu2guQOHXvgR1m0vdXcDazv/wor3ElhVsT/h5/WrQ8
------END CERTIFICATE-----
-
-RSA Security 2048 v3
-====================
------BEGIN CERTIFICATE-----
-MIIDYTCCAkmgAwIBAgIQCgEBAQAAAnwAAAAKAAAAAjANBgkqhkiG9w0BAQUFADA6MRkwFwYDVQQK
-ExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0EgU2VjdXJpdHkgMjA0OCBWMzAeFw0wMTAy
-MjIyMDM5MjNaFw0yNjAyMjIyMDM5MjNaMDoxGTAXBgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAb
-BgNVBAsTFFJTQSBTZWN1cml0eSAyMDQ4IFYzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
-AQEAt49VcdKA3XtpeafwGFAyPGJn9gqVB93mG/Oe2dJBVGutn3y+Gc37RqtBaB4Y6lXIL5F4iSj7
-Jylg/9+PjDvJSZu1pJTOAeo+tWN7fyb9Gd3AIb2E0S1PRsNO3Ng3OTsor8udGuorryGlwSMiuLgb
-WhOHV4PR8CDn6E8jQrAApX2J6elhc5SYcSa8LWrg903w8bYqODGBDSnhAMFRD0xS+ARaqn1y07iH
-KrtjEAMqs6FPDVpeRrc9DvV07Jmf+T0kgYim3WBU6JU2PcYJk5qjEoAAVZkZR73QpXzDuvsf9/UP
-+Ky5tfQ3mBMY3oVbtwyCO4dvlTlYMNpuAWgXIszACwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/
-MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQHw1EwpKrpRa41JPr/JCwz0LGdjDAdBgNVHQ4E
-FgQUB8NRMKSq6UWuNST6/yQsM9CxnYwwDQYJKoZIhvcNAQEFBQADggEBAF8+hnZuuDU8TjYcHnmY
-v/3VEhF5Ug7uMYm83X/50cYVIeiKAVQNOvtUudZj1LGqlk2iQk3UUx+LEN5/Zb5gEydxiKRz44Rj
-0aRV4VCT5hsOedBnvEbIvz8XDZXmxpBp3ue0L96VfdASPz0+f00/FGj1EVDVwfSQpQgdMWD/YIwj
-VAqv/qFuxdF6Kmh4zx6CCiC0H63lhbJqaHVOrSU3lIW+vaHU6rcMSzyd6BIA8F+sDeGscGNz9395
-nzIlQnQFgCi/vcEkllgVsRch6YlL2weIZ/QVrXA+L02FO8K32/6YaCOJ4XQP3vTFhGMpG8zLB8kA
-pKnXwiJPZ9d37CAFYd4=
------END CERTIFICATE-----
-
-GeoTrust Global CA
-==================
------BEGIN CERTIFICATE-----
-MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVTMRYwFAYDVQQK
-Ew1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9iYWwgQ0EwHhcNMDIwNTIxMDQw
-MDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j
-LjEbMBkGA1UEAxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
-CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjo
-BbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDviS2Aelet
-8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU1XupGc1V3sjs0l44U+Vc
-T4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagU
-vTLrGAMoUgRx5aszPeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTAD
-AQH/MB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVk
-DBF9qn1luMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKInZ57Q
-zxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfStQWVYrmm3ok9Nns4
-d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcFPseKUgzbFbS9bZvlxrFUaKnjaZC2
-mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Unhw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6p
-XE0zX5IJL4hmXXeXxx12E6nV5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvm
-Mw==
------END CERTIFICATE-----
-
-GeoTrust Global CA 2
-====================
------BEGIN CERTIFICATE-----
-MIIDZjCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN
-R2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwHhcNMDQwMzA0MDUw
-MDAwWhcNMTkwMzA0MDUwMDAwWjBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j
-LjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
-ggEKAoIBAQDvPE1APRDfO1MA4Wf+lGAVPoWI8YkNkMgoI5kF6CsgncbzYEbYwbLVjDHZ3CB5JIG/
-NTL8Y2nbsSpr7iFY8gjpeMtvy/wWUsiRxP89c96xPqfCfWbB9X5SJBri1WeR0IIQ13hLTytCOb1k
-LUCgsBDTOEhGiKEMuzozKmKY+wCdE1l/bztyqu6mD4b5BWHqZ38MN5aL5mkWRxHCJ1kDs6ZgwiFA
-Vvqgx306E+PsV8ez1q6diYD3Aecs9pYrEw15LNnA5IZ7S4wMcoKK+xfNAGw6EzywhIdLFnopsk/b
-HdQL82Y3vdj2V7teJHq4PIu5+pIaGoSe2HSPqht/XvT+RSIhAgMBAAGjYzBhMA8GA1UdEwEB/wQF
-MAMBAf8wHQYDVR0OBBYEFHE4NvICMVNHK266ZUapEBVYIAUJMB8GA1UdIwQYMBaAFHE4NvICMVNH
-K266ZUapEBVYIAUJMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAQEAA/e1K6tdEPx7
-srJerJsOflN4WT5CBP51o62sgU7XAotexC3IUnbHLB/8gTKY0UvGkpMzNTEv/NgdRN3ggX+d6Yvh
-ZJFiCzkIjKx0nVnZellSlxG5FntvRdOW2TF9AjYPnDtuzywNA0ZF66D0f0hExghAzN4bcLUprbqL
-OzRldRtxIR0sFAqwlpW41uryZfspuk/qkZN0abby/+Ea0AzRdoXLiiW9l14sbxWZJue2Kf8i7MkC
-x1YAzUm5s2x7UwQa4qjJqhIFI8LO57sEAszAR6LkxCkvW0VXiVHuPOtSCP8HNR6fNWpHSlaY0VqF
-H4z1Ir+rzoPz4iIprn2DQKi6bA==
------END CERTIFICATE-----
-
-GeoTrust Universal CA
-=====================
------BEGIN CERTIFICATE-----
-MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN
-R2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVyc2FsIENBMB4XDTA0MDMwNDA1
-MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu
-Yy4xHjAcBgNVBAMTFUdlb1RydXN0IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
-ADCCAgoCggIBAKYVVaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9t
-JPi8cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTTQjOgNB0e
-RXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFhF7em6fgemdtzbvQKoiFs
-7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2vc7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d
-8Lsrlh/eezJS/R27tQahsiFepdaVaH/wmZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7V
-qnJNk22CDtucvc+081xdVHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3Cga
-Rr0BHdCXteGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZf9hB
-Z3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfReBi9Fi1jUIxaS5BZu
-KGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+nhutxx9z3SxPGWX9f5NAEC7S8O08
-ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0
-XG0D08DYj3rWMB8GA1UdIwQYMBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIB
-hjANBgkqhkiG9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc
-aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fXIwjhmF7DWgh2
-qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzynANXH/KttgCJwpQzgXQQpAvvL
-oJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0zuzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsK
-xr2EoyNB3tZ3b4XUhRxQ4K5RirqNPnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxF
-KyDuSN/n3QmOGKjaQI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2
-DFKWkoRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9ER/frslK
-xfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQtDF4JbAiXfKM9fJP/P6EU
-p8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/SfuvmbJxPgWp6ZKy7PtXny3YuxadIwVyQD8vI
-P/rmMuGNG2+k5o7Y+SlIis5z/iw=
------END CERTIFICATE-----
-
-GeoTrust Universal CA 2
-=======================
------BEGIN CERTIFICATE-----
-MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN
-R2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwHhcNMDQwMzA0
-MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3Qg
-SW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUA
-A4ICDwAwggIKAoICAQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0
-DE81WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUGFF+3Qs17
-j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdqXbboW0W63MOhBW9Wjo8Q
-JqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxLse4YuU6W3Nx2/zu+z18DwPw76L5GG//a
-QMJS9/7jOvdqdzXQ2o3rXhhqMcceujwbKNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2
-WP0+GfPtDCapkzj4T8FdIgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP
-20gaXT73y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRthAAn
-ZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgocQIgfksILAAX/8sgC
-SqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4Lt1ZrtmhN79UNdxzMk+MBB4zsslG
-8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2
-+/CfXGJx7Tz0RzgQKzAfBgNVHSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8E
-BAMCAYYwDQYJKoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z
-dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQL1EuxBRa3ugZ
-4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgrFg5fNuH8KrUwJM/gYwx7WBr+
-mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSoag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpq
-A1Ihn0CoZ1Dy81of398j9tx4TuaYT1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpg
-Y+RdM4kX2TGq2tbzGDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiP
-pm8m1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJVOCiNUW7d
-FGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH6aLcr34YEoP9VhdBLtUp
-gn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwXQMAJKOSLakhT2+zNVVXxxvjpoixMptEm
-X36vWkzaH6byHCx+rgIW0lbQL1dTR+iS
------END CERTIFICATE-----
-
-UTN-USER First-Network Applications
-===================================
------BEGIN CERTIFICATE-----
-MIIEZDCCA0ygAwIBAgIQRL4Mi1AAJLQR0zYwS8AzdzANBgkqhkiG9w0BAQUFADCBozELMAkGA1UE
-BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl
-IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xKzAp
-BgNVBAMTIlVUTi1VU0VSRmlyc3QtTmV0d29yayBBcHBsaWNhdGlvbnMwHhcNOTkwNzA5MTg0ODM5
-WhcNMTkwNzA5MTg1NzQ5WjCBozELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5T
-YWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
-dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xKzApBgNVBAMTIlVUTi1VU0VSRmlyc3QtTmV0d29yayBB
-cHBsaWNhdGlvbnMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCz+5Gh5DZVhawGNFug
-mliy+LUPBXeDrjKxdpJo7CNKyXY/45y2N3kDuatpjQclthln5LAbGHNhSuh+zdMvZOOmfAz6F4Cj
-DUeJT1FxL+78P/m4FoCHiZMlIJpDgmkkdihZNaEdwH+DBmQWICzTSaSFtMBhf1EI+GgVkYDLpdXu
-Ozr0hAReYFmnjDRy7rh4xdE7EkpvfmUnuaRVxblvQ6TFHSyZwFKkeEwVs0CYCGtDxgGwenv1axwi
-P8vv/6jQOkt2FZ7S0cYu49tXGzKiuG/ohqY/cKvlcJKrRB5AUPuco2LkbG6gyN7igEL66S/ozjIE
-j3yNtxyjNTwV3Z7DrpelAgMBAAGjgZEwgY4wCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8w
-HQYDVR0OBBYEFPqGydvguul49Uuo1hXf8NPhahQ8ME8GA1UdHwRIMEYwRKBCoECGPmh0dHA6Ly9j
-cmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LU5ldHdvcmtBcHBsaWNhdGlvbnMuY3JsMA0G
-CSqGSIb3DQEBBQUAA4IBAQCk8yXM0dSRgyLQzDKrm5ZONJFUICU0YV8qAhXhi6r/fWRRzwr/vH3Y
-IWp4yy9Rb/hCHTO967V7lMPDqaAt39EpHx3+jz+7qEUqf9FuVSTiuwL7MT++6LzsQCv4AdRWOOTK
-RIK1YSAhZ2X28AvnNPilwpyjXEAfhZOVBt5P1CeptqX8Fs1zMT+4ZSfP1FMa8Kxun08FDAOBp4Qp
-xFq9ZFdyrTvPNximmMatBrTcCKME1SmklpoSZ0qMYEWd8SOasACcaLWYUNPvji6SZbFIPiG+FTAq
-DbUMo2s/rn9X9R+WfN9v3YIwLGUbQErNaLly7HF27FSOH4UMAWr6pjisH8SE
------END CERTIFICATE-----
-
-America Online Root Certification Authority 1
-=============================================
------BEGIN CERTIFICATE-----
-MIIDpDCCAoygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT
-QW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBPbmxpbmUgUm9vdCBDZXJ0aWZp
-Y2F0aW9uIEF1dGhvcml0eSAxMB4XDTAyMDUyODA2MDAwMFoXDTM3MTExOTIwNDMwMFowYzELMAkG
-A1UEBhMCVVMxHDAaBgNVBAoTE0FtZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2Eg
-T25saW5lIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMTCCASIwDQYJKoZIhvcNAQEBBQAD
-ggEPADCCAQoCggEBAKgv6KRpBgNHw+kqmP8ZonCaxlCyfqXfaE0bfA+2l2h9LaaLl+lkhsmj76CG
-v2BlnEtUiMJIxUo5vxTjWVXlGbR0yLQFOVwWpeKVBeASrlmLojNoWBym1BW32J/X3HGrfpq/m44z
-DyL9Hy7nBzbvYjnF3cu6JRQj3gzGPTzOggjmZj7aUTsWOqMFf6Dch9Wc/HKpoH145LcxVR5lu9Rh
-sCFg7RAycsWSJR74kEoYeEfffjA3PlAb2xzTa5qGUwew76wGePiEmf4hjUyAtgyC9mZweRrTT6PP
-8c9GsEsPPt2IYriMqQkoO3rHl+Ee5fSfwMCuJKDIodkP1nsmgmkyPacCAwEAAaNjMGEwDwYDVR0T
-AQH/BAUwAwEB/zAdBgNVHQ4EFgQUAK3Zo/Z59m50qX8zPYEX10zPM94wHwYDVR0jBBgwFoAUAK3Z
-o/Z59m50qX8zPYEX10zPM94wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBBQUAA4IBAQB8itEf
-GDeC4Liwo+1WlchiYZwFos3CYiZhzRAW18y0ZTTQEYqtqKkFZu90821fnZmv9ov761KyBZiibyrF
-VL0lvV+uyIbqRizBs73B6UlwGBaXCBOMIOAbLjpHyx7kADCVW/RFo8AasAFOq73AI25jP4BKxQft
-3OJvx8Fi8eNy1gTIdGcL+oiroQHIb/AUr9KZzVGTfu0uOMe9zkZQPXLjeSWdm4grECDdpbgyn43g
-Kd8hdIaC2y+CMMbHNYaz+ZZfRtsMRf3zUMNvxsNIrUam4SdHCh0Om7bCd39j8uB9Gr784N/Xx6ds
-sPmuujz9dLQR6FgNgLzTqIA6me11zEZ7
------END CERTIFICATE-----
-
-America Online Root Certification Authority 2
-=============================================
------BEGIN CERTIFICATE-----
-MIIFpDCCA4ygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT
-QW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBPbmxpbmUgUm9vdCBDZXJ0aWZp
-Y2F0aW9uIEF1dGhvcml0eSAyMB4XDTAyMDUyODA2MDAwMFoXDTM3MDkyOTE0MDgwMFowYzELMAkG
-A1UEBhMCVVMxHDAaBgNVBAoTE0FtZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2Eg
-T25saW5lIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMjCCAiIwDQYJKoZIhvcNAQEBBQAD
-ggIPADCCAgoCggIBAMxBRR3pPU0Q9oyxQcngXssNt79Hc9PwVU3dxgz6sWYFas14tNwC206B89en
-fHG8dWOgXeMHDEjsJcQDIPT/DjsS/5uN4cbVG7RtIuOx238hZK+GvFciKtZHgVdEglZTvYYUAQv8
-f3SkWq7xuhG1m1hagLQ3eAkzfDJHA1zEpYNI9FdWboE2JxhP7JsowtS013wMPgwr38oE18aO6lhO
-qKSlGBxsRZijQdEt0sdtjRnxrXm3gT+9BoInLRBYBbV4Bbkv2wxrkJB+FFk4u5QkE+XRnRTf04JN
-RvCAOVIyD+OEsnpD8l7eXz8d3eOyG6ChKiMDbi4BFYdcpnV1x5dhvt6G3NRI270qv0pV2uh9UPu0
-gBe4lL8BPeraunzgWGcXuVjgiIZGZ2ydEEdYMtA1fHkqkKJaEBEjNa0vzORKW6fIJ/KD3l67Xnfn
-6KVuY8INXWHQjNJsWiEOyiijzirplcdIz5ZvHZIlyMbGwcEMBawmxNJ10uEqZ8A9W6Wa6897Gqid
-FEXlD6CaZd4vKL3Ob5Rmg0gp2OpljK+T2WSfVVcmv2/LNzGZo2C7HK2JNDJiuEMhBnIMoVxtRsX6
-Kc8w3onccVvdtjc+31D1uAclJuW8tf48ArO3+L5DwYcRlJ4jbBeKuIonDFRH8KmzwICMoCfrHRnj
-B453cMor9H124HhnAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFE1FwWg4u3Op
-aaEg5+31IqEjFNeeMB8GA1UdIwQYMBaAFE1FwWg4u3OpaaEg5+31IqEjFNeeMA4GA1UdDwEB/wQE
-AwIBhjANBgkqhkiG9w0BAQUFAAOCAgEAZ2sGuV9FOypLM7PmG2tZTiLMubekJcmnxPBUlgtk87FY
-T15R/LKXeydlwuXK5w0MJXti4/qftIe3RUavg6WXSIylvfEWK5t2LHo1YGwRgJfMqZJS5ivmae2p
-+DYtLHe/YUjRYwu5W1LtGLBDQiKmsXeu3mnFzcccobGlHBD7GL4acN3Bkku+KVqdPzW+5X1R+FXg
-JXUjhx5c3LqdsKyzadsXg8n33gy8CNyRnqjQ1xU3c6U1uPx+xURABsPr+CKAXEfOAuMRn0T//Zoy
-zH1kUQ7rVyZ2OuMeIjzCpjbdGe+n/BLzJsBZMYVMnNjP36TMzCmT/5RtdlwTCJfy7aULTd3oyWgO
-ZtMADjMSW7yV5TKQqLPGbIOtd+6Lfn6xqavT4fG2wLHqiMDn05DpKJKUe2h7lyoKZy2FAjgQ5ANh
-1NolNscIWC2hp1GvMApJ9aZphwctREZ2jirlmjvXGKL8nDgQzMY70rUXOm/9riW99XJZZLF0Kjhf
-GEzfz3EEWjbUvy+ZnOjZurGV5gJLIaFb1cFPj65pbVPbAZO1XB4Y3WRayhgoPmMEEf0cjQAPuDff
-Z4qdZqkCapH/E8ovXYO8h5Ns3CRRFgQlZvqz2cK6Kb6aSDiCmfS/O0oxGfm/jiEzFMpPVF/7zvuP
-cX/9XhmgD0uRuMRUvAawRY8mkaKO/qk=
------END CERTIFICATE-----
-
-Visa eCommerce Root
-===================
------BEGIN CERTIFICATE-----
-MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBrMQswCQYDVQQG
-EwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2Ug
-QXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2
-WhcNMjIwNjI0MDAxNjEyWjBrMQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMm
-VmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv
-bW1lcmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h2mCxlCfL
-F9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4ElpF7sDPwsRROEW+1QK8b
-RaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdVZqW1LS7YgFmypw23RuwhY/81q6UCzyr0
-TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI
-/k4+oKsGGelT84ATB+0tvz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzs
-GHxBvfaLdXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEG
-MB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUFAAOCAQEAX/FBfXxc
-CLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcRzCSs00Rsca4BIGsDoo8Ytyk6feUW
-YFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pz
-zkWKsKZJ/0x9nXGIxHYdkFsd7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBu
-YQa7FkKMcPcw++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt
-398znM/jra6O1I7mT1GvFpLgXPYHDw==
------END CERTIFICATE-----
-
-Certum Root CA
-==============
------BEGIN CERTIFICATE-----
-MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQK
-ExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBDQTAeFw0wMjA2MTExMDQ2Mzla
-Fw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8u
-by4xEjAQBgNVBAMTCUNlcnR1bSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6x
-wS7TT3zNJc4YPk/EjG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdL
-kKWoePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GIULdtlkIJ
-89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapuOb7kky/ZR6By6/qmW6/K
-Uz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUgAKpoC6EahQGcxEZjgoi2IrHu/qpGWX7P
-NSzVttpd90gzFFS269lvzs2I1qsb2pY7HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkq
-hkiG9w0BAQUFAAOCAQEAuI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+
-GXYkHAQaTOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTgxSvg
-GrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1qCjqTE5s7FCMTY5w/
-0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5xO/fIR/RpbxXyEV6DHpx8Uq79AtoS
-qFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs6GAqm4VKQPNriiTsBhYscw==
------END CERTIFICATE-----
-
-Comodo AAA Services root
-========================
------BEGIN CERTIFICATE-----
-MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS
-R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg
-TGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAw
-MFoXDTI4MTIzMTIzNTk1OVowezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hl
-c3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV
-BAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
-ggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQuaBtDFcCLNSS1UY8y2bmhG
-C1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe3M/vg4aijJRPn2jymJBGhCfHdr/jzDUs
-i14HZGWCwEiwqJH5YZ92IFCokcdmtet4YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszW
-Y19zjNoFmag4qMsXeDZRrOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjH
-Ypy+g8cmez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQUoBEK
-Iz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wewYDVR0f
-BHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNl
-cy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29tb2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2Vz
-LmNybDANBgkqhkiG9w0BAQUFAAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm
-7l3sAg9g1o1QGE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz
-Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2G9w84FoVxp7Z
-8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsil2D4kF501KKaU73yqWjgom7C
-12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
------END CERTIFICATE-----
-
-Comodo Secure Services root
-===========================
------BEGIN CERTIFICATE-----
-MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS
-R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg
-TGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAw
-MDAwMFoXDTI4MTIzMTIzNTk1OVowfjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFu
-Y2hlc3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAi
-BgNVBAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP
-ADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPMcm3ye5drswfxdySRXyWP
-9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3SHpR7LZQdqnXXs5jLrLxkU0C8j6ysNstc
-rbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rC
-oznl2yY4rYsK7hljxxwk3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3V
-p6ea5EQz6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNVHQ4E
-FgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w
-gYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2RvY2EuY29tL1NlY3VyZUNlcnRpZmlj
-YXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRwOi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlm
-aWNhdGVTZXJ2aWNlcy5jcmwwDQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm
-4J4oqF7Tt/Q05qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj
-Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtIgKvcnDe4IRRL
-DXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJaD61JlfutuC23bkpgHl9j6Pw
-pCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDlizeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1H
-RR3B7Hzs/Sk=
------END CERTIFICATE-----
-
-Comodo Trusted Services root
-============================
------BEGIN CERTIFICATE-----
-MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS
-R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg
-TGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEw
-MDAwMDBaFw0yODEyMzEyMzU5NTlaMH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1h
-bmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUw
-IwYDVQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0BAQEFAAOC
-AQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWWfnJSoBVC21ndZHoa0Lh7
-3TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMtTGo87IvDktJTdyR0nAducPy9C1t2ul/y
-/9c3S0pgePfw+spwtOpZqqPOSC+pw7ILfhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6
-juljatEPmsbS9Is6FARW1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsS
-ivnkBbA7kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0GA1Ud
-DgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
-/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21vZG9jYS5jb20vVHJ1c3RlZENlcnRp
-ZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRodHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENl
-cnRpZmljYXRlU2VydmljZXMuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8Ntw
-uleGFTQQuS9/HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32
-pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxISjBc/lDb+XbDA
-BHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+xqFx7D+gIIxmOom0jtTYsU0l
-R+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/AtyjcndBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O
-9y5Xt5hwXsjEeLBi
------END CERTIFICATE-----
-
-QuoVadis Root CA
-================
------BEGIN CERTIFICATE-----
-MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJCTTEZMBcGA1UE
-ChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
-eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAz
-MTkxODMzMzNaFw0yMTAzMTcxODMzMzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRp
-cyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQD
-EyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF
-AAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Ypli4kVEAkOPcahdxYTMuk
-J0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2DrOpm2RgbaIr1VxqYuvXtdj182d6UajtL
-F8HVj71lODqV0D1VNk7feVcxKh7YWWVJWCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeL
-YzcS19Dsw3sgQUSj7cugF+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWen
-AScOospUxbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCCAk4w
-PQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVvdmFkaXNvZmZzaG9y
-ZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREwggENMIIBCQYJKwYBBAG+WAABMIH7
-MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNlIG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmlj
-YXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJs
-ZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh
-Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYIKwYBBQUHAgEW
-Fmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3TKbkGGew5Oanwl4Rqy+/fMIGu
-BgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rqy+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkw
-FwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0
-aG9yaXR5MS4wLAYDVQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6
-tlCLMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSkfnIYj9lo
-fFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf87C9TqnN7Az10buYWnuul
-LsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1RcHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2x
-gI4JVrmcGmD+XcHXetwReNDWXcG31a0ymQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi
-5upZIof4l/UO/erMkqQWxFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi
-5nrQNiOKSnQ2+Q==
------END CERTIFICATE-----
-
-QuoVadis Root CA 2
-==================
------BEGIN CERTIFICATE-----
-MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT
-EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMjAeFw0wNjExMjQx
-ODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
-aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4IC
-DwAwggIKAoICAQCaGMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6
-XJxgFyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55JWpzmM+Yk
-lvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bBrrcCaoF6qUWD4gXmuVbB
-lDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp+ARz8un+XJiM9XOva7R+zdRcAitMOeGy
-lZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt
-66/3FsvbzSUr5R/7mp/iUcw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1Jdxn
-wQ5hYIizPtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og/zOh
-D7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UHoycR7hYQe7xFSkyy
-BNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuIyV77zGHcizN300QyNQliBJIWENie
-J0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1Ud
-DgQWBBQahGK8SEwzJQTU7tD2A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGU
-a6FJpEcwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT
-ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2fBluornFdLwUv
-Z+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzng/iN/Ae42l9NLmeyhP3ZRPx3
-UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2BlfF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodm
-VjB3pjd4M1IQWK4/YY7yarHvGH5KWWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK
-+JDSV6IZUaUtl0HaB0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrW
-IozchLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPRTUIZ3Ph1
-WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWDmbA4CD/pXvk1B+TJYm5X
-f6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0ZohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II
-4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8
-VCLAAVBpQ570su9t+Oza8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u
------END CERTIFICATE-----
-
-QuoVadis Root CA 3
-==================
------BEGIN CERTIFICATE-----
-MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT
-EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMzAeFw0wNjExMjQx
-OTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
-aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4IC
-DwAwggIKAoICAQDMV0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNgg
-DhoB4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUrH556VOij
-KTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd8lyyBTNvijbO0BNO/79K
-DDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9CabwvvWhDFlaJKjdhkf2mrk7AyxRllDdLkgbv
-BNDInIjbC3uBr7E9KsRlOni27tyAsdLTmZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwp
-p5ijJUMv7/FfJuGITfhebtfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8
-nT8KKdjcT5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDtWAEX
-MJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZc6tsgLjoC2SToJyM
-Gf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A4iLItLRkT9a6fUg+qGkM17uGcclz
-uD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYDVR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHT
-BgkrBgEEAb5YAAMwgcUwgZMGCCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmlj
-YXRlIGNvbnN0aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0
-aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVudC4wLQYIKwYB
-BQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2NwczALBgNVHQ8EBAMCAQYwHQYD
-VR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4GA1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4
-ywLQoUmkRzBFMQswCQYDVQQGEwJCTTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UE
-AxMSUXVvVmFkaXMgUm9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZV
-qyM07ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSemd1o417+s
-hvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd+LJ2w/w4E6oM3kJpK27z
-POuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2
-Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadNt54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp
-8kokUvd0/bpO5qgdAm6xDYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBC
-bjPsMZ57k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6szHXu
-g/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0jWy10QJLZYxkNc91p
-vGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeTmJlglFwjz1onl14LBQaTNx47aTbr
-qZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK4SVhM7JZG+Ju1zdXtg2pEto=
------END CERTIFICATE-----
-
-Security Communication Root CA
-==============================
------BEGIN CERTIFICATE-----
-MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP
-U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw
-HhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP
-U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw
-ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw
-8yl89f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJDKaVv0uM
-DPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9Ms+k2Y7CI9eNqPPYJayX
-5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/NQV3Is00qVUarH9oe4kA92819uZKAnDfd
-DJZkndwi92SL32HeFZRSFaB9UslLqCHJxrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2
-JChzAgMBAAGjPzA9MB0GA1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYw
-DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vGkl3g
-0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfrUj94nK9NrvjVT8+a
-mCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5Bw+SUEmK3TGXX8npN6o7WWWXlDLJ
-s58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJUJRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ
-6rBK+1YWc26sTfcioU+tHXotRSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAi
-FL39vmwLAw==
------END CERTIFICATE-----
-
-Sonera Class 1 Root CA
-======================
------BEGIN CERTIFICATE-----
-MIIDIDCCAgigAwIBAgIBJDANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEPMA0GA1UEChMG
-U29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MxIENBMB4XDTAxMDQwNjEwNDkxM1oXDTIxMDQw
-NjEwNDkxM1owOTELMAkGA1UEBhMCRkkxDzANBgNVBAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJh
-IENsYXNzMSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALWJHytPZwp5/8Ue+H88
-7dF+2rDNbS82rDTG29lkFwhjMDMiikzujrsPDUJVyZ0upe/3p4zDq7mXy47vPxVnqIJyY1MPQYx9
-EJUkoVqlBvqSV536pQHydekfvFYmUk54GWVYVQNYwBSujHxVX3BbdyMGNpfzJLWaRpXk3w0LBUXl
-0fIdgrvGE+D+qnr9aTCU89JFhfzyMlsy3uhsXR/LpCJ0sICOXZT3BgBLqdReLjVQCfOAl/QMF645
-2F/NM8EcyonCIvdFEu1eEpOdY6uCLrnrQkFEy0oaAIINnvmLVz5MxxftLItyM19yejhW1ebZrgUa
-HXVFsculJRwSVzb9IjcCAwEAAaMzMDEwDwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQIR+IMi/ZT
-iFIwCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQCLGrLJXWG04bkruVPRsoWdd44W7hE9
-28Jj2VuXZfsSZ9gqXLar5V7DtxYvyOirHYr9qxp81V9jz9yw3Xe5qObSIjiHBxTZ/75Wtf0HDjxV
-yhbMp6Z3N/vbXB9OWQaHowND9Rart4S9Tu+fMTfwRvFAttEMpWT4Y14h21VOTzF2nBBhjrZTOqMR
-vq9tfB69ri3iDGnHhVNoomG6xT60eVR4ngrHAr5i0RGCS2UvkVrCqIexVmiUefkl98HVrhq4uz2P
-qYo4Ffdz0Fpg0YCw8NzVUM1O7pJIae2yIx4wzMiUyLb1O4Z/P6Yun/Y+LLWSlj7fLJOK/4GMDw9Z
-IRlXvVWa
------END CERTIFICATE-----
-
-Sonera Class 2 Root CA
-======================
------BEGIN CERTIFICATE-----
-MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEPMA0GA1UEChMG
-U29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAxMDQwNjA3Mjk0MFoXDTIxMDQw
-NjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNVBAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJh
-IENsYXNzMiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3
-/Ei9vX+ALTU74W+oZ6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybT
-dXnt5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s3TmVToMG
-f+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2EjvOr7nQKV0ba5cTppCD8P
-tOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu8nYybieDwnPz3BjotJPqdURrBGAgcVeH
-nfO+oJAjPYok4doh28MCAwEAAaMzMDEwDwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITT
-XjwwCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt
-0jSv9zilzqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/3DEI
-cbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvDFNr450kkkdAdavph
-Oe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6Tk6ezAyNlNzZRZxe7EJQY670XcSx
-EtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLH
-llpwrN9M
------END CERTIFICATE-----
-
-Staat der Nederlanden Root CA
-=============================
------BEGIN CERTIFICATE-----
-MIIDujCCAqKgAwIBAgIEAJiWijANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJOTDEeMBwGA1UE
-ChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFhdCBkZXIgTmVkZXJsYW5kZW4g
-Um9vdCBDQTAeFw0wMjEyMTcwOTIzNDlaFw0xNTEyMTYwOTE1MzhaMFUxCzAJBgNVBAYTAk5MMR4w
-HAYDVQQKExVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xJjAkBgNVBAMTHVN0YWF0IGRlciBOZWRlcmxh
-bmRlbiBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmNK1URF6gaYUmHFt
-vsznExvWJw56s2oYHLZhWtVhCb/ekBPHZ+7d89rFDBKeNVU+LCeIQGv33N0iYfXCxw719tV2U02P
-jLwYdjeFnejKScfST5gTCaI+Ioicf9byEGW07l8Y1Rfj+MX94p2i71MOhXeiD+EwR+4A5zN9RGca
-C1Hoi6CeUJhoNFIfLm0B8mBF8jHrqTFoKbt6QZ7GGX+UtFE5A3+y3qcym7RHjm+0Sq7lr7HcsBth
-vJly3uSJt3omXdozSVtSnA71iq3DuD3oBmrC1SoLbHuEvVYFy4ZlkuxEK7COudxwC0barbxjiDn6
-22r+I/q85Ej0ZytqERAhSQIDAQABo4GRMIGOMAwGA1UdEwQFMAMBAf8wTwYDVR0gBEgwRjBEBgRV
-HSAAMDwwOgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cucGtpb3ZlcmhlaWQubmwvcG9saWNpZXMvcm9v
-dC1wb2xpY3kwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSofeu8Y6R0E3QA7Jbg0zTBLL9s+DAN
-BgkqhkiG9w0BAQUFAAOCAQEABYSHVXQ2YcG70dTGFagTtJ+k/rvuFbQvBgwp8qiSpGEN/KtcCFtR
-EytNwiphyPgJWPwtArI5fZlmgb9uXJVFIGzmeafR2Bwp/MIgJ1HI8XxdNGdphREwxgDS1/PTfLbw
-MVcoEoJz6TMvplW0C5GUR5z6u3pCMuiufi3IvKwUv9kP2Vv8wfl6leF9fpb8cbDCTMjfRTTJzg3y
-nGQI0DvDKcWy7ZAEwbEpkcUwb8GpcjPM/l0WFywRaed+/sWDCN+83CI6LiBpIzlWYGeQiy52OfsR
-iJf2fL1LuCAWZwWN4jvBcj+UlTfHXbme2JOhF4//DGYVwSR8MnwDHTuhWEUykw==
------END CERTIFICATE-----
-
-TDC Internet Root CA
-====================
------BEGIN CERTIFICATE-----
-MIIEKzCCAxOgAwIBAgIEOsylTDANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJESzEVMBMGA1UE
-ChMMVERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTAeFw0wMTA0MDUx
-NjMzMTdaFw0yMTA0MDUxNzAzMTdaMEMxCzAJBgNVBAYTAkRLMRUwEwYDVQQKEwxUREMgSW50ZXJu
-ZXQxHTAbBgNVBAsTFFREQyBJbnRlcm5ldCBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
-MIIBCgKCAQEAxLhAvJHVYx/XmaCLDEAedLdInUaMArLgJF/wGROnN4NrXceO+YQwzho7+vvOi20j
-xsNuZp+Jpd/gQlBn+h9sHvTQBda/ytZO5GhgbEaqHF1j4QeGDmUApy6mcca8uYGoOn0a0vnRrEvL
-znWv3Hv6gXPU/Lq9QYjUdLP5Xjg6PEOo0pVOd20TDJ2PeAG3WiAfAzc14izbSysseLlJ28TQx5yc
-5IogCSEWVmb/Bexb4/DPqyQkXsN/cHoSxNK1EKC2IeGNeGlVRGn1ypYcNIUXJXfi9i8nmHj9eQY6
-otZaQ8H/7AQ77hPv01ha/5Lr7K7a8jcDR0G2l8ktCkEiu7vmpwIDAQABo4IBJTCCASEwEQYJYIZI
-AYb4QgEBBAQDAgAHMGUGA1UdHwReMFwwWqBYoFakVDBSMQswCQYDVQQGEwJESzEVMBMGA1UEChMM
-VERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTENMAsGA1UEAxMEQ1JM
-MTArBgNVHRAEJDAigA8yMDAxMDQwNTE2MzMxN1qBDzIwMjEwNDA1MTcwMzE3WjALBgNVHQ8EBAMC
-AQYwHwYDVR0jBBgwFoAUbGQBx/2FbazI2p5QCIUItTxWqFAwHQYDVR0OBBYEFGxkAcf9hW2syNqe
-UAiFCLU8VqhQMAwGA1UdEwQFMAMBAf8wHQYJKoZIhvZ9B0EABBAwDhsIVjUuMDo0LjADAgSQMA0G
-CSqGSIb3DQEBBQUAA4IBAQBOQ8zR3R0QGwZ/t6T609lN+yOfI1Rb5osvBCiLtSdtiaHsmGnc540m
-gwV5dOy0uaOXwTUA/RXaOYE6lTGQ3pfphqiZdwzlWqCE/xIWrG64jcN7ksKsLtB9KOy282A4aW8+
-2ARVPp7MVdK6/rtHBNcK2RYKNCn1WBPVT8+PVkuzHu7TmHnaCB4Mb7j4Fifvwm899qNLPg7kbWzb
-O0ESm70NRyN/PErQr8Cv9u8btRXE64PECV90i9kR+8JWsTz4cMo0jUNAE4z9mQNUecYu6oah9jrU
-Cbz0vGbMPVjQV0kK7iXiQe4T+Zs4NNEA9X7nlB38aQNiuJkFBT1reBK9sG9l
------END CERTIFICATE-----
-
-TDC OCES Root CA
-================
------BEGIN CERTIFICATE-----
-MIIFGTCCBAGgAwIBAgIEPki9xDANBgkqhkiG9w0BAQUFADAxMQswCQYDVQQGEwJESzEMMAoGA1UE
-ChMDVERDMRQwEgYDVQQDEwtUREMgT0NFUyBDQTAeFw0wMzAyMTEwODM5MzBaFw0zNzAyMTEwOTA5
-MzBaMDExCzAJBgNVBAYTAkRLMQwwCgYDVQQKEwNUREMxFDASBgNVBAMTC1REQyBPQ0VTIENBMIIB
-IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArGL2YSCyz8DGhdfjeebM7fI5kqSXLmSjhFuH
-nEz9pPPEXyG9VhDr2y5h7JNp46PMvZnDBfwGuMo2HP6QjklMxFaaL1a8z3sM8W9Hpg1DTeLpHTk0
-zY0s2RKY+ePhwUp8hjjEqcRhiNJerxomTdXkoCJHhNlktxmW/OwZ5LKXJk5KTMuPJItUGBxIYXvV
-iGjaXbXqzRowwYCDdlCqT9HU3Tjw7xb04QxQBr/q+3pJoSgrHPb8FTKjdGqPqcNiKXEx5TukYBde
-dObaE+3pHx8b0bJoc8YQNHVGEBDjkAB2QMuLt0MJIf+rTpPGWOmlgtt3xDqZsXKVSQTwtyv6e1mO
-3QIDAQABo4ICNzCCAjMwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwgewGA1UdIASB
-5DCB4TCB3gYIKoFQgSkBAQEwgdEwLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuY2VydGlmaWthdC5k
-ay9yZXBvc2l0b3J5MIGdBggrBgEFBQcCAjCBkDAKFgNUREMwAwIBARqBgUNlcnRpZmlrYXRlciBm
-cmEgZGVubmUgQ0EgdWRzdGVkZXMgdW5kZXIgT0lEIDEuMi4yMDguMTY5LjEuMS4xLiBDZXJ0aWZp
-Y2F0ZXMgZnJvbSB0aGlzIENBIGFyZSBpc3N1ZWQgdW5kZXIgT0lEIDEuMi4yMDguMTY5LjEuMS4x
-LjARBglghkgBhvhCAQEEBAMCAAcwgYEGA1UdHwR6MHgwSKBGoESkQjBAMQswCQYDVQQGEwJESzEM
-MAoGA1UEChMDVERDMRQwEgYDVQQDEwtUREMgT0NFUyBDQTENMAsGA1UEAxMEQ1JMMTAsoCqgKIYm
-aHR0cDovL2NybC5vY2VzLmNlcnRpZmlrYXQuZGsvb2Nlcy5jcmwwKwYDVR0QBCQwIoAPMjAwMzAy
-MTEwODM5MzBagQ8yMDM3MDIxMTA5MDkzMFowHwYDVR0jBBgwFoAUYLWF7FZkfhIZJ2cdUBVLc647
-+RIwHQYDVR0OBBYEFGC1hexWZH4SGSdnHVAVS3OuO/kSMB0GCSqGSIb2fQdBAAQQMA4bCFY2LjA6
-NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEACromJkbTc6gJ82sLMJn9iuFXehHTuJTXCRBuo7E4
-A9G28kNBKWKnctj7fAXmMXAnVBhOinxO5dHKjHiIzxvTkIvmI/gLDjNDfZziChmPyQE+dF10yYsc
-A+UYyAFMP8uXBV2YcaaYb7Z8vTd/vuGTJW1v8AqtFxjhA7wHKcitJuj4YfD9IQl+mo6paH1IYnK9
-AOoBmbgGglGBTvH1tJFUuSN6AJqfXY3gPGS5GhKSKseCRHI53OI8xthV9RVOyAUO28bQYqbsFbS1
-AoLbrIyigfCbmTH1ICCoiGEKB5+U/NDXG8wuF/MEJ3Zn61SD/aSQfgY9BKNDLdr8C2LqL19iUw==
------END CERTIFICATE-----
-
-UTN DATACorp SGC Root CA
-========================
------BEGIN CERTIFICATE-----
-MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCBkzELMAkGA1UE
-BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl
-IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZ
-BgNVBAMTElVUTiAtIERBVEFDb3JwIFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBa
-MIGTMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4w
-HAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRy
-dXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjANBgkqhkiG9w0BAQEFAAOC
-AQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ys
-raP6LnD43m77VkIVni5c7yPeIbkFdicZD0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlo
-wHDyUwDAXlCCpVZvNvlK4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA
-9P4yPykqlXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulWbfXv
-33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQABo4GrMIGoMAsGA1Ud
-DwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRTMtGzz3/64PGgXYVOktKeRR20TzA9
-BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dD
-LmNybDAqBgNVHSUEIzAhBggrBgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3
-DQEBBQUAA4IBAQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft
-Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyjj98C5OBxOvG0
-I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVHKWss5nbZqSl9Mt3JNjy9rjXx
-EZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwP
-DPafepE39peC4N1xaf92P2BNPM/3mfnGV/TJVTl4uix5yaaIK/QI
------END CERTIFICATE-----
-
-UTN USERFirst Email Root CA
-===========================
------BEGIN CERTIFICATE-----
-MIIEojCCA4qgAwIBAgIQRL4Mi1AAJLQR0zYlJWfJiTANBgkqhkiG9w0BAQUFADCBrjELMAkGA1UE
-BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl
-IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xNjA0
-BgNVBAMTLVVUTi1VU0VSRmlyc3QtQ2xpZW50IEF1dGhlbnRpY2F0aW9uIGFuZCBFbWFpbDAeFw05
-OTA3MDkxNzI4NTBaFw0xOTA3MDkxNzM2NThaMIGuMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQx
-FzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsx
-ITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTE2MDQGA1UEAxMtVVROLVVTRVJGaXJz
-dC1DbGllbnQgQXV0aGVudGljYXRpb24gYW5kIEVtYWlsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
-MIIBCgKCAQEAsjmFpPJ9q0E7YkY3rs3BYHW8OWX5ShpHornMSMxqmNVNNRm5pELlzkniii8efNIx
-B8dOtINknS4p1aJkxIW9hVE1eaROaJB7HHqkkqgX8pgV8pPMyaQylbsMTzC9mKALi+VuG6JG+ni8
-om+rWV6lL8/K2m2qL+usobNqqrcuZzWLeeEeaYji5kbNoKXqvgvOdjp6Dpvq/NonWz1zHyLmSGHG
-TPNpsaguG7bUMSAsvIKKjqQOpdeJQ/wWWq8dcdcRWdq6hw2v+vPhwvCkxWeM1tZUOt4KpLoDd7Nl
-yP0e03RiqhjKaJMeoYV+9Udly/hNVyh00jT/MLbu9mIwFIws6wIDAQABo4G5MIG2MAsGA1UdDwQE
-AwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSJgmd9xJ0mcABLtFBIfN49rgRufTBYBgNV
-HR8EUTBPME2gS6BJhkdodHRwOi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLVVTRVJGaXJzdC1DbGll
-bnRBdXRoZW50aWNhdGlvbmFuZEVtYWlsLmNybDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUH
-AwQwDQYJKoZIhvcNAQEFBQADggEBALFtYV2mGn98q0rkMPxTbyUkxsrt4jFcKw7u7mFVbwQ+zzne
-xRtJlOTrIEy05p5QLnLZjfWqo7NK2lYcYJeA3IKirUq9iiv/Cwm0xtcgBEXkzYABurorbs6q15L+
-5K/r9CYdFip/bDCVNy8zEqx/3cfREYxRmLLQo5HQrfafnoOTHh1CuEava2bwm3/q4wMC5QJRwarV
-NZ1yQAOJujEdxRBoUp7fooXFXAimeOZTT7Hot9MUnpOmw2TjrH5xzbyf6QMbzPvprDHBr3wVdAKZ
-w7JHpsIyYdfHb0gkUSeh1YdV8nuPmD0Wnu51tvjQjvLzxq4oW6fw8zYX/MMF08oDSlQ=
------END CERTIFICATE-----
-
-UTN USERFirst Hardware Root CA
-==============================
------BEGIN CERTIFICATE-----
-MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCBlzELMAkGA1UE
-BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl
-IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAd
-BgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgx
-OTIyWjCBlzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0
-eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVz
-ZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwggEiMA0GCSqGSIb3
-DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlI
-wrthdBKWHTxqctU8EGc6Oe0rE81m65UJM6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFd
-tqdt++BxF2uiiPsA3/4aMXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8
-i4fDidNdoI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqIDsjf
-Pe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9KsyoUhbAgMBAAGjgbkw
-gbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFKFyXyYbKJhDlV0HN9WF
-lp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNF
-UkZpcnN0LUhhcmR3YXJlLmNybDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUF
-BwMGBggrBgEFBQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM
-//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28GpgoiskliCE7/yMgUsogW
-XecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gECJChicsZUN/KHAG8HQQZexB2
-lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kn
-iCrVWFCVH/A7HFe7fRQ5YiuayZSSKqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67
-nfhmqA==
------END CERTIFICATE-----
-
-UTN USERFirst Object Root CA
-============================
------BEGIN CERTIFICATE-----
-MIIEZjCCA06gAwIBAgIQRL4Mi1AAJLQR0zYt4LNfGzANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UE
-BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl
-IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHTAb
-BgNVBAMTFFVUTi1VU0VSRmlyc3QtT2JqZWN0MB4XDTk5MDcwOTE4MzEyMFoXDTE5MDcwOTE4NDAz
-NlowgZUxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJVVDEXMBUGA1UEBxMOU2FsdCBMYWtlIENpdHkx
-HjAcBgNVBAoTFVRoZSBVU0VSVFJVU1QgTmV0d29yazEhMB8GA1UECxMYaHR0cDovL3d3dy51c2Vy
-dHJ1c3QuY29tMR0wGwYDVQQDExRVVE4tVVNFUkZpcnN0LU9iamVjdDCCASIwDQYJKoZIhvcNAQEB
-BQADggEPADCCAQoCggEBAM6qgT+jo2F4qjEAVZURnicPHxzfOpuCaDDASmEd8S8O+r5596Uj71VR
-loTN2+O5bj4x2AogZ8f02b+U60cEPgLOKqJdhwQJ9jCdGIqXsqoc/EHSoTbL+z2RuufZcDX65OeQ
-w5ujm9M89RKZd7G3CeBo5hy485RjiGpq/gt2yb70IuRnuasaXnfBhQfdDWy/7gbHd2pBnqcP1/vu
-lBe3/IW+pKvEHDHd17bR5PDv3xaPslKT16HUiaEHLr/hARJCHhrh2JU022R5KP+6LhHC5ehbkkj7
-RwvCbNqtMoNB86XlQXD9ZZBt+vpRxPm9lisZBCzTbafc8H9vg2XiaquHhnUCAwEAAaOBrzCBrDAL
-BgNVHQ8EBAMCAcYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU2u1kdBScFDyr3ZmpvVsoTYs8
-ydgwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2NybC51c2VydHJ1c3QuY29tL1VUTi1VU0VSRmly
-c3QtT2JqZWN0LmNybDApBgNVHSUEIjAgBggrBgEFBQcDAwYIKwYBBQUHAwgGCisGAQQBgjcKAwQw
-DQYJKoZIhvcNAQEFBQADggEBAAgfUrE3RHjb/c652pWWmKpVZIC1WkDdIaXFwfNfLEzIR1pp6ujw
-NTX00CXzyKakh0q9G7FzCL3Uw8q2NbtZhncxzaeAFK4T7/yxSPlrJSUtUbYsbUXBmMiKVl0+7kNO
-PmsnjtA6S4ULX9Ptaqd1y9Fahy85dRNacrACgZ++8A+EVCBibGnU4U3GDZlDAQ0Slox4nb9QorFE
-qmrPF3rPbw/U+CRVX/A0FklmPlBGyWNxODFiuGK581OtbLUrohKqGU8J2l7nk8aOFAj+8DCAGKCG
-hU3IfdeLA/5u1fedFqySLKAj5ZyRUh+U3xeUc8OzwcFxBSAAeL0TUh2oPs0AH8g=
------END CERTIFICATE-----
-
-Camerfirma Chambers of Commerce Root
-====================================
------BEGIN CERTIFICATE-----
-MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEnMCUGA1UEChMe
-QUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1i
-ZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAx
-NjEzNDNaFw0zNzA5MzAxNjEzNDRaMH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZp
-cm1hIFNBIENJRiBBODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3Jn
-MSIwIAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0BAQEFAAOC
-AQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtbunXF/KGIJPov7coISjlU
-xFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0dBmpAPrMMhe5cG3nCYsS4No41XQEMIwRH
-NaqbYE6gZj3LJgqcQKH0XZi/caulAGgq7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jW
-DA+wWFjbw2Y3npuRVDM30pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFV
-d9oKDMyXroDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIGA1Ud
-EwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5jaGFtYmVyc2lnbi5v
-cmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p26EpW1eLTXYGduHRooowDgYDVR0P
-AQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hh
-bWJlcnNpZ24ub3JnMCcGA1UdEgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYD
-VR0gBFEwTzBNBgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz
-aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEBAAxBl8IahsAi
-fJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZdp0AJPaxJRUXcLo0waLIJuvvD
-L8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wN
-UPf6s+xCX6ndbcj0dc97wXImsQEcXCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/n
-ADydb47kMgkdTXg0eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1
-erfutGWaIZDgqtCYvDi1czyL+Nw=
------END CERTIFICATE-----
-
-Camerfirma Global Chambersign Root
-==================================
------BEGIN CERTIFICATE-----
-MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEnMCUGA1UEChMe
-QUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1i
-ZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYx
-NDE4WhcNMzcwOTMwMTYxNDE4WjB9MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJt
-YSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEg
-MB4GA1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUAA4IBDQAw
-ggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0Mi+ITaFgCPS3CU6gSS9J
-1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/sQJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8O
-by4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpVeAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl
-6DJWk0aJqCWKZQbua795B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c
-8lCrEqWhz0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0TAQH/
-BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1iZXJzaWduLm9yZy9j
-aGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4wTcbOX60Qq+UDpfqpFDAOBgNVHQ8B
-Af8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAHMCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBj
-aGFtYmVyc2lnbi5vcmcwKgYDVR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9y
-ZzBbBgNVHSAEVDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh
-bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0BAQUFAAOCAQEA
-PDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUMbKGKfKX0j//U2K0X1S0E0T9Y
-gOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXiryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJ
-PJ7oKXqJ1/6v/2j1pReQvayZzKWGVwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4
-IBHNfTIzSJRUTN3cecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREes
-t2d/AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A==
------END CERTIFICATE-----
-
-NetLock Qualified (Class QA) Root
-=================================
------BEGIN CERTIFICATE-----
-MIIG0TCCBbmgAwIBAgIBezANBgkqhkiG9w0BAQUFADCByTELMAkGA1UEBhMCSFUxETAPBgNVBAcT
-CEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4xGjAYBgNV
-BAsTEVRhbnVzaXR2YW55a2lhZG9rMUIwQAYDVQQDEzlOZXRMb2NrIE1pbm9zaXRldHQgS296amVn
-eXpvaSAoQ2xhc3MgUUEpIFRhbnVzaXR2YW55a2lhZG8xHjAcBgkqhkiG9w0BCQEWD2luZm9AbmV0
-bG9jay5odTAeFw0wMzAzMzAwMTQ3MTFaFw0yMjEyMTUwMTQ3MTFaMIHJMQswCQYDVQQGEwJIVTER
-MA8GA1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRvbnNhZ2kgS2Z0
-LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxQjBABgNVBAMTOU5ldExvY2sgTWlub3NpdGV0
-dCBLb3pqZWd5em9pIChDbGFzcyBRQSkgVGFudXNpdHZhbnlraWFkbzEeMBwGCSqGSIb3DQEJARYP
-aW5mb0BuZXRsb2NrLmh1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx1Ilstg91IRV
-CacbvWy5FPSKAtt2/GoqeKvld/Bu4IwjZ9ulZJm53QE+b+8tmjwi8F3JV6BVQX/yQ15YglMxZc4e
-8ia6AFQer7C8HORSjKAyr7c3sVNnaHRnUPYtLmTeriZ539+Zhqurf4XsoPuAzPS4DB6TRWO53Lhb
-m+1bOdRfYrCnjnxmOCyqsQhjF2d9zL2z8cM/z1A57dEZgxXbhxInlrfa6uWdvLrqOU+L73Sa58XQ
-0uqGURzk/mQIKAR5BevKxXEOC++r6uwSEaEYBTJp0QwsGj0lmT+1fMptsK6ZmfoIYOcZwvK9UdPM
-0wKswREMgM6r3JSda6M5UzrWhQIDAMV9o4ICwDCCArwwEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNV
-HQ8BAf8EBAMCAQYwggJ1BglghkgBhvhCAQ0EggJmFoICYkZJR1lFTEVNISBFemVuIHRhbnVzaXR2
-YW55IGEgTmV0TG9jayBLZnQuIE1pbm9zaXRldHQgU3pvbGdhbHRhdGFzaSBTemFiYWx5emF0YWJh
-biBsZWlydCBlbGphcmFzb2sgYWxhcGphbiBrZXN6dWx0LiBBIG1pbm9zaXRldHQgZWxla3Ryb25p
-a3VzIGFsYWlyYXMgam9naGF0YXMgZXJ2ZW55ZXN1bGVzZW5laywgdmFsYW1pbnQgZWxmb2dhZGFz
-YW5hayBmZWx0ZXRlbGUgYSBNaW5vc2l0ZXR0IFN6b2xnYWx0YXRhc2kgU3phYmFseXphdGJhbiwg
-YXogQWx0YWxhbm9zIFN6ZXJ6b2Rlc2kgRmVsdGV0ZWxla2JlbiBlbG9pcnQgZWxsZW5vcnplc2kg
-ZWxqYXJhcyBtZWd0ZXRlbGUuIEEgZG9rdW1lbnR1bW9rIG1lZ3RhbGFsaGF0b2sgYSBodHRwczov
-L3d3dy5uZXRsb2NrLmh1L2RvY3MvIGNpbWVuIHZhZ3kga2VyaGV0b2sgYXogaW5mb0BuZXRsb2Nr
-Lm5ldCBlLW1haWwgY2ltZW4uIFdBUk5JTkchIFRoZSBpc3N1YW5jZSBhbmQgdGhlIHVzZSBvZiB0
-aGlzIGNlcnRpZmljYXRlIGFyZSBzdWJqZWN0IHRvIHRoZSBOZXRMb2NrIFF1YWxpZmllZCBDUFMg
-YXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3Lm5ldGxvY2suaHUvZG9jcy8gb3IgYnkgZS1tYWlsIGF0
-IGluZm9AbmV0bG9jay5uZXQwHQYDVR0OBBYEFAlqYhaSsFq7VQ7LdTI6MuWyIckoMA0GCSqGSIb3
-DQEBBQUAA4IBAQCRalCc23iBmz+LQuM7/KbD7kPgz/PigDVJRXYC4uMvBcXxKufAQTPGtpvQMznN
-wNuhrWw3AkxYQTvyl5LGSKjN5Yo5iWH5Upfpvfb5lHTocQ68d4bDBsxafEp+NFAwLvt/MpqNPfMg
-W/hqyobzMUwsWYACff44yTB1HLdV47yfuqhthCgFdbOLDcCRVCHnpgu0mfVRQdzNo0ci2ccBgcTc
-R08m6h/t280NmPSjnLRzMkqWmf68f8glWPhY83ZmiVSkpj7EUFy6iRiCdUgh0k8T6GB+B3bbELVR
-5qq5aKrN9p2QdRLqOBrKROi3macqaJVmlaut74nLYKkGEsaUR+ko
------END CERTIFICATE-----
-
-NetLock Notary (Class A) Root
-=============================
------BEGIN CERTIFICATE-----
-MIIGfTCCBWWgAwIBAgICAQMwDQYJKoZIhvcNAQEEBQAwga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQI
-EwdIdW5nYXJ5MREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6
-dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9j
-ayBLb3pqZWd5em9pIChDbGFzcyBBKSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNDIzMTQ0N1oX
-DTE5MDIxOTIzMTQ0N1owga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQH
-EwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQuMRowGAYD
-VQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBLb3pqZWd5em9pIChDbGFz
-cyBBKSBUYW51c2l0dmFueWtpYWRvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvHSM
-D7tM9DceqQWC2ObhbHDqeLVu0ThEDaiDzl3S1tWBxdRL51uUcCbbO51qTGL3cfNk1mE7PetzozfZ
-z+qMkjvN9wfcZnSX9EUi3fRc4L9t875lM+QVOr/bmJBVOMTtplVjC7B4BPTjbsE/jvxReB+SnoPC
-/tmwqcm8WgD/qaiYdPv2LD4VOQ22BFWoDpggQrOxJa1+mm9dU7GrDPzr4PN6s6iz/0b2Y6LYOph7
-tqyF/7AlT3Rj5xMHpQqPBffAZG9+pyeAlt7ULoZgx2srXnN7F+eRP2QM2EsiNCubMvJIH5+hCoR6
-4sKtlz2O1cH5VqNQ6ca0+pii7pXmKgOM3wIDAQABo4ICnzCCApswDgYDVR0PAQH/BAQDAgAGMBIG
-A1UdEwEB/wQIMAYBAf8CAQQwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaC
-Ak1GSUdZRUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pv
-bGdhbHRhdGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQu
-IEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2Vn
-LWJpenRvc2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0
-ZXRlbGUgYXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFz
-IGxlaXJhc2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBh
-IGh0dHBzOi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVu
-b3J6ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1YW5jZSBh
-bmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sg
-Q1BTIGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFp
-bCBhdCBjcHNAbmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4IBAQBIJEb3ulZv+sgoA0BO5TE5
-ayZrU3/b39/zcT0mwBQOxmd7I6gMc90Bu8bKbjc5VdXHjFYgDigKDtIqpLBJUsY4B/6+CgmM0ZjP
-ytoUMaFP0jn8DxEsQ8Pdq5PHVT5HfBgaANzze9jyf1JsIPQLX2lS9O74silg6+NJMSEN1rUQQeJB
-CWziGppWS3cC9qCbmieH6FUpccKQn0V4GuEVZD3QDtigdp+uxdAu6tYPVuxkf1qbFFgBJ34TUMdr
-KuZoPL9coAob4Q566eKAw+np9v1sEZ7Q5SgnK1QyQhSCdeZK8CtmdWOMovsEPoMOmzbwGOQmIMOM
-8CgHrTwXZoi1/baI
------END CERTIFICATE-----
-
-NetLock Business (Class B) Root
-===============================
------BEGIN CERTIFICATE-----
-MIIFSzCCBLSgAwIBAgIBaTANBgkqhkiG9w0BAQQFADCBmTELMAkGA1UEBhMCSFUxETAPBgNVBAcT
-CEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4xGjAYBgNV
-BAsTEVRhbnVzaXR2YW55a2lhZG9rMTIwMAYDVQQDEylOZXRMb2NrIFV6bGV0aSAoQ2xhc3MgQikg
-VGFudXNpdHZhbnlraWFkbzAeFw05OTAyMjUxNDEwMjJaFw0xOTAyMjAxNDEwMjJaMIGZMQswCQYD
-VQQGEwJIVTERMA8GA1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRv
-bnNhZ2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxMjAwBgNVBAMTKU5ldExvY2sg
-VXpsZXRpIChDbGFzcyBCKSBUYW51c2l0dmFueWtpYWRvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
-iQKBgQCx6gTsIKAjwo84YM/HRrPVG/77uZmeBNwcf4xKgZjupNTKihe5In+DCnVMm8Bp2GQ5o+2S
-o/1bXHQawEfKOml2mrriRBf8TKPV/riXiK+IA4kfpPIEPsgHC+b5sy96YhQJRhTKZPWLgLViqNhr
-1nGTLbO/CVRY7QbrqHvcQ7GhaQIDAQABo4ICnzCCApswEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNV
-HQ8BAf8EBAMCAAYwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1GSUdZ
-RUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pvbGdhbHRh
-dGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQuIEEgaGl0
-ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2VnLWJpenRv
-c2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUg
-YXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJh
-c2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBhIGh0dHBz
-Oi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVub3J6ZXNA
-bmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1YW5jZSBhbmQgdGhl
-IHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sgQ1BTIGF2
-YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBj
-cHNAbmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4GBAATbrowXr/gOkDFOzT4JwG06sPgzTEdM
-43WIEJessDgVkcYplswhwG08pXTP2IKlOcNl40JwuyKQ433bNXbhoLXan3BukxowOR0w2y7jfLKR
-stE3Kfq51hdcR0/jHTjrn9V7lagonhVK0dHQKwCXoOKSNitjrFgBazMpUIaD8QFI
------END CERTIFICATE-----
-
-NetLock Express (Class C) Root
-==============================
------BEGIN CERTIFICATE-----
-MIIFTzCCBLigAwIBAgIBaDANBgkqhkiG9w0BAQQFADCBmzELMAkGA1UEBhMCSFUxETAPBgNVBAcT
-CEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4xGjAYBgNV
-BAsTEVRhbnVzaXR2YW55a2lhZG9rMTQwMgYDVQQDEytOZXRMb2NrIEV4cHJlc3N6IChDbGFzcyBD
-KSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNTE0MDgxMVoXDTE5MDIyMDE0MDgxMVowgZsxCzAJ
-BgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6
-dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE0MDIGA1UEAxMrTmV0TG9j
-ayBFeHByZXNzeiAoQ2xhc3MgQykgVGFudXNpdHZhbnlraWFkbzCBnzANBgkqhkiG9w0BAQEFAAOB
-jQAwgYkCgYEA6+ywbGGKIyWvYCDj2Z/8kwvbXY2wobNAOoLO/XXgeDIDhlqGlZHtU/qdQPzm6N3Z
-W3oDvV3zOwzDUXmbrVWg6dADEK8KuhRC2VImESLH0iDMgqSaqf64gXadarfSNnU+sYYJ9m5tfk63
-euyucYT2BDMIJTLrdKwWRMbkQJMdf60CAwEAAaOCAp8wggKbMBIGA1UdEwEB/wQIMAYBAf8CAQQw
-DgYDVR0PAQH/BAQDAgAGMBEGCWCGSAGG+EIBAQQEAwIABzCCAmAGCWCGSAGG+EIBDQSCAlEWggJN
-RklHWUVMRU0hIEV6ZW4gdGFudXNpdHZhbnkgYSBOZXRMb2NrIEtmdC4gQWx0YWxhbm9zIFN6b2xn
-YWx0YXRhc2kgRmVsdGV0ZWxlaWJlbiBsZWlydCBlbGphcmFzb2sgYWxhcGphbiBrZXN6dWx0LiBB
-IGhpdGVsZXNpdGVzIGZvbHlhbWF0YXQgYSBOZXRMb2NrIEtmdC4gdGVybWVrZmVsZWxvc3NlZy1i
-aXp0b3NpdGFzYSB2ZWRpLiBBIGRpZ2l0YWxpcyBhbGFpcmFzIGVsZm9nYWRhc2FuYWsgZmVsdGV0
-ZWxlIGF6IGVsb2lydCBlbGxlbm9yemVzaSBlbGphcmFzIG1lZ3RldGVsZS4gQXogZWxqYXJhcyBs
-ZWlyYXNhIG1lZ3RhbGFsaGF0byBhIE5ldExvY2sgS2Z0LiBJbnRlcm5ldCBob25sYXBqYW4gYSBo
-dHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIGNpbWVuIHZhZ3kga2VyaGV0byBheiBlbGxlbm9y
-emVzQG5ldGxvY2submV0IGUtbWFpbCBjaW1lbi4gSU1QT1JUQU5UISBUaGUgaXNzdWFuY2UgYW5k
-IHRoZSB1c2Ugb2YgdGhpcyBjZXJ0aWZpY2F0ZSBpcyBzdWJqZWN0IHRvIHRoZSBOZXRMb2NrIENQ
-UyBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cubmV0bG9jay5uZXQvZG9jcyBvciBieSBlLW1haWwg
-YXQgY3BzQG5ldGxvY2submV0LjANBgkqhkiG9w0BAQQFAAOBgQAQrX/XDDKACtiG8XmYta3UzbM2
-xJZIwVzNmtkFLp++UOv0JhQQLdRmF/iewSf98e3ke0ugbLWrmldwpu2gpO0u9f38vf5NNwgMvOOW
-gyL1SRt/Syu0VMGAfJlOHdCM7tCs5ZL6dVb+ZKATj7i4Fp1hBWeAyNDYpQcCNJgEjTME1A==
------END CERTIFICATE-----
-
-XRamp Global CA Root
-====================
------BEGIN CERTIFICATE-----
-MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UE
-BhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2Vj
-dXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB
-dXRob3JpdHkwHhcNMDQxMTAxMTcxNDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMx
-HjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkg
-U2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
-dHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS638eMpSe2OAtp87ZOqCwu
-IR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCPKZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMx
-foArtYzAQDsRhtDLooY2YKTVMIJt2W7QDxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FE
-zG+gSqmUsE3a56k0enI4qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqs
-AxcZZPRaJSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNViPvry
-xS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud
-EwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASsjVy16bYbMDYGA1UdHwQvMC0wK6Ap
-oCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMC
-AQEwDQYJKoZIhvcNAQEFBQADggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc
-/Kh4ZzXxHfARvbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt
-qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLaIR9NmXmd4c8n
-nxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSyi6mx5O+aGtA9aZnuqCij4Tyz
-8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQO+7ETPTsJ3xCwnR8gooJybQDJbw=
------END CERTIFICATE-----
-
-Go Daddy Class 2 CA
-===================
------BEGIN CERTIFICATE-----
-MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMY
-VGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRp
-ZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkG
-A1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g
-RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQAD
-ggENADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv
-2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+qN1j3hybX2C32
-qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiOr18SPaAIBQi2XKVlOARFmR6j
-YGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmY
-vLEHZ6IVDd2gWMZEewo+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0O
-BBYEFNLEsNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h/t2o
-atTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMu
-MTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwG
-A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wim
-PQoZ+YeAEW5p5JYXMP80kWNyOO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKt
-I3lpjbi2Tc7PTMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
-HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mERdEr/VxqHD3VI
-Ls9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5CufReYNnyicsbkqWletNw+vHX/b
-vZ8=
------END CERTIFICATE-----
-
-Starfield Class 2 CA
-====================
------BEGIN CERTIFICATE-----
-MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzElMCMGA1UEChMc
-U3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZpZWxkIENsYXNzIDIg
-Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBo
-MQswCQYDVQQGEwJVUzElMCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAG
-A1UECxMpU3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqG
-SIb3DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf8MOh2tTY
-bitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN+lq2cwQlZut3f+dZxkqZ
-JRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVm
-epsZGD3/cVE8MC5fvj13c7JdBmzDI1aaK4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSN
-F4Azbl5KXZnJHoe0nRrA1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HF
-MIHCMB0GA1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fRzt0f
-hvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNo
-bm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBDbGFzcyAyIENlcnRpZmljYXRpb24g
-QXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGs
-afPzWdqbAYcaT1epoXkJKtv3L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLM
-PUxA2IGvd56Deruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl
-xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynpVSJYACPq4xJD
-KVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEYWQPJIrSPnNVeKtelttQKbfi3
-QBFGmh95DmK/D5fs4C8fF5Q=
------END CERTIFICATE-----
-
-StartCom Certification Authority
-================================
------BEGIN CERTIFICATE-----
-MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMN
-U3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmlu
-ZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0
-NjM2WhcNMzYwOTE3MTk0NjM2WjB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRk
-LjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMg
-U3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
-ggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZkpMyONvg45iPwbm2xPN1y
-o4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rfOQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/
-Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/CJi/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/d
-eMotHweXMAEtcnn6RtYTKqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt
-2PZE4XNiHzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMMAv+Z
-6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w+2OqqGwaVLRcJXrJ
-osmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/
-untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVc
-UjyJthkqcwEKDwOzEmDyei+B26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT
-37uMdBNSSwIDAQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE
-FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9jZXJ0LnN0YXJ0
-Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3JsLnN0YXJ0Y29tLm9yZy9zZnNj
-YS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFMBgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUH
-AgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRw
-Oi8vY2VydC5zdGFydGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYg
-U3RhcnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlhYmlsaXR5
-LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2YgdGhlIFN0YXJ0Q29tIENl
-cnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFpbGFibGUgYXQgaHR0cDovL2NlcnQuc3Rh
-cnRjb20ub3JnL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilT
-dGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOC
-AgEAFmyZ9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8jhvh
-3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUWFjgKXlf2Ysd6AgXm
-vB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJzewT4F+irsfMuXGRuczE6Eri8sxHk
-fY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3
-fsNrarnDy0RLrHiQi+fHLB5LEUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZ
-EoalHmdkrQYuL6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq
-yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuCO3NJo2pXh5Tl
-1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6Vum0ABj6y6koQOdjQK/W/7HW/
-lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkyShNOsF/5oirpt9P/FlUQqmMGqz9IgcgA38coro
-g14=
------END CERTIFICATE-----
-
-Taiwan GRCA
-===========
------BEGIN CERTIFICATE-----
-MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/MQswCQYDVQQG
-EwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4X
-DTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1owPzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dv
-dmVybm1lbnQgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQAD
-ggIPADCCAgoCggIBAJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qN
-w8XRIePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1qgQdW8or5
-BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKyyhwOeYHWtXBiCAEuTk8O
-1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAtsF/tnyMKtsc2AtJfcdgEWFelq16TheEfO
-htX7MfP6Mb40qij7cEwdScevLJ1tZqa2jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wov
-J5pGfaENda1UhhXcSTvxls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7
-Q3hub/FCVGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHKYS1t
-B6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoHEgKXTiCQ8P8NHuJB
-O9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThNXo+EHWbNxWCWtFJaBYmOlXqYwZE8
-lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1UdDgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNV
-HRMEBTADAQH/MDkGBGcqBwAEMTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg2
-09yewDL7MTqKUWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ
-TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyfqzvS/3WXy6Tj
-Zwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaKZEk9GhiHkASfQlK3T8v+R0F2
-Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFEJPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlU
-D7gsL0u8qV1bYH+Mh6XgUmMqvtg7hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6Qz
-DxARvBMB1uUO07+1EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+Hbk
-Z6MmnD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WXudpVBrkk
-7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44VbnzssQwmSNOXfJIoRIM3BKQ
-CZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDeLMDDav7v3Aun+kbfYNucpllQdSNpc5Oy
-+fwC00fmcc4QAu4njIT/rEUNE1yDMuAlpYYsfPQS
------END CERTIFICATE-----
-
-Firmaprofesional Root CA
-========================
------BEGIN CERTIFICATE-----
-MIIEVzCCAz+gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBnTELMAkGA1UEBhMCRVMxIjAgBgNVBAcT
-GUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMTOUF1dG9yaWRhZCBkZSBDZXJ0aWZp
-Y2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODEmMCQGCSqGSIb3DQEJARYXY2FA
-ZmlybWFwcm9mZXNpb25hbC5jb20wHhcNMDExMDI0MjIwMDAwWhcNMTMxMDI0MjIwMDAwWjCBnTEL
-MAkGA1UEBhMCRVMxIjAgBgNVBAcTGUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMT
-OUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2
-ODEmMCQGCSqGSIb3DQEJARYXY2FAZmlybWFwcm9mZXNpb25hbC5jb20wggEiMA0GCSqGSIb3DQEB
-AQUAA4IBDwAwggEKAoIBAQDnIwNvbyOlXnjOlSztlB5uCp4Bx+ow0Syd3Tfom5h5VtP8c9/Qit5V
-j1H5WuretXDE7aTt/6MNbg9kUDGvASdYrv5sp0ovFy3Tc9UTHI9ZpTQsHVQERc1ouKDAA6XPhUJH
-lShbz++AbOCQl4oBPB3zhxAwJkh91/zpnZFx/0GaqUC1N5wpIE8fUuOgfRNtVLcK3ulqTgesrBlf
-3H5idPayBQC6haD9HThuy1q7hryUZzM1gywfI834yJFxzJeL764P3CkDG8A563DtwW4O2GcLiam8
-NeTvtjS0pbbELaW+0MOUJEjb35bTALVmGotmBQ/dPz/LP6pemkr4tErvlTcbAgMBAAGjgZ8wgZww
-KgYDVR0RBCMwIYYfaHR0cDovL3d3dy5maXJtYXByb2Zlc2lvbmFsLmNvbTASBgNVHRMBAf8ECDAG
-AQH/AgEBMCsGA1UdEAQkMCKADzIwMDExMDI0MjIwMDAwWoEPMjAxMzEwMjQyMjAwMDBaMA4GA1Ud
-DwEB/wQEAwIBBjAdBgNVHQ4EFgQUMwugZtHq2s7eYpMEKFK1FH84aLcwDQYJKoZIhvcNAQEFBQAD
-ggEBAEdz/o0nVPD11HecJ3lXV7cVVuzH2Fi3AQL0M+2TUIiefEaxvT8Ub/GzR0iLjJcG1+p+o1wq
-u00vR+L4OQbJnC4xGgN49Lw4xiKLMzHwFgQEffl25EvXwOaD7FnMP97/T2u3Z36mhoEyIwOdyPdf
-wUpgpZKpsaSgYMN4h7Mi8yrrW6ntBas3D7Hi05V2Y1Z0jFhyGzflZKG+TQyTmAyX9odtsz/ny4Cm
-7YjHX1BiAuiZdBbQ5rQ58SfLyEDW44YQqSMSkuBpQWOnryULwMWSyx6Yo1q6xTMPoJcB3X/ge9YG
-VM+h4k0460tQtcsm9MracEpqoeJ5quGnM/b9Sh/22WA=
------END CERTIFICATE-----
-
-Wells Fargo Root CA
-===================
------BEGIN CERTIFICATE-----
-MIID5TCCAs2gAwIBAgIEOeSXnjANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UEBhMCVVMxFDASBgNV
-BAoTC1dlbGxzIEZhcmdvMSwwKgYDVQQLEyNXZWxscyBGYXJnbyBDZXJ0aWZpY2F0aW9uIEF1dGhv
-cml0eTEvMC0GA1UEAxMmV2VsbHMgRmFyZ28gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcN
-MDAxMDExMTY0MTI4WhcNMjEwMTE0MTY0MTI4WjCBgjELMAkGA1UEBhMCVVMxFDASBgNVBAoTC1dl
-bGxzIEZhcmdvMSwwKgYDVQQLEyNXZWxscyBGYXJnbyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEv
-MC0GA1UEAxMmV2VsbHMgRmFyZ28gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG
-SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVqDM7Jvk0/82bfuUER84A4n135zHCLielTWi5MbqNQ1mX
-x3Oqfz1cQJ4F5aHiidlMuD+b+Qy0yGIZLEWukR5zcUHESxP9cMIlrCL1dQu3U+SlK93OvRw6esP3
-E48mVJwWa2uv+9iWsWCaSOAlIiR5NM4OJgALTqv9i86C1y8IcGjBqAr5dE8Hq6T54oN+J3N0Prj5
-OEL8pahbSCOz6+MlsoCultQKnMJ4msZoGK43YjdeUXWoWGPAUe5AeH6orxqg4bB4nVCMe+ez/I4j
-sNtlAHCEAQgAFG5Uhpq6zPk3EPbg3oQtnaSFN9OH4xXQwReQfhkhahKpdv0SAulPIV4XAgMBAAGj
-YTBfMA8GA1UdEwEB/wQFMAMBAf8wTAYDVR0gBEUwQzBBBgtghkgBhvt7hwcBCzAyMDAGCCsGAQUF
-BwIBFiRodHRwOi8vd3d3LndlbGxzZmFyZ28uY29tL2NlcnRwb2xpY3kwDQYJKoZIhvcNAQEFBQAD
-ggEBANIn3ZwKdyu7IvICtUpKkfnRLb7kuxpo7w6kAOnu5+/u9vnldKTC2FJYxHT7zmu1Oyl5GFrv
-m+0fazbuSCUlFLZWohDo7qd/0D+j0MNdJu4HzMPBJCGHHt8qElNvQRbn7a6U+oxy+hNH8Dx+rn0R
-OhPs7fpvcmR7nX1/Jv16+yWt6j4pf0zjAFcysLPp7VMX2YuyFA4w6OXVE8Zkr8QA1dhYJPz1j+zx
-x32l2w8n0cbyQIjmH/ZhqPRCyLk306m+LFZ4wnKbWV01QIroTmMatukgalHizqSQ33ZwmVxwQ023
-tqcZZE6St8WRPH9IFmV7Fv3L/PvZ1dZPIWU7Sn9Ho/s=
------END CERTIFICATE-----
-
-Swisscom Root CA 1
-==================
------BEGIN CERTIFICATE-----
-MIIF2TCCA8GgAwIBAgIQXAuFXAvnWUHfV8w/f52oNjANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQG
-EwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0YWwgQ2VydGlmaWNhdGUgU2Vy
-dmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3QgQ0EgMTAeFw0wNTA4MTgxMjA2MjBaFw0yNTA4
-MTgyMjA2MjBaMGQxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGln
-aXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAxMIIC
-IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0LmwqAzZuz8h+BvVM5OAFmUgdbI9m2BtRsiM
-MW8Xw/qabFbtPMWRV8PNq5ZJkCoZSx6jbVfd8StiKHVFXqrWW/oLJdihFvkcxC7mlSpnzNApbjyF
-NDhhSbEAn9Y6cV9Nbc5fuankiX9qUvrKm/LcqfmdmUc/TilftKaNXXsLmREDA/7n29uj/x2lzZAe
-AR81sH8A25Bvxn570e56eqeqDFdvpG3FEzuwpdntMhy0XmeLVNxzh+XTF3xmUHJd1BpYwdnP2IkC
-b6dJtDZd0KTeByy2dbcokdaXvij1mB7qWybJvbCXc9qukSbraMH5ORXWZ0sKbU/Lz7DkQnGMU3nn
-7uHbHaBuHYwadzVcFh4rUx80i9Fs/PJnB3r1re3WmquhsUvhzDdf/X/NTa64H5xD+SpYVUNFvJbN
-cA78yeNmuk6NO4HLFWR7uZToXTNShXEuT46iBhFRyePLoW4xCGQMwtI89Tbo19AOeCMgkckkKmUp
-WyL3Ic6DXqTz3kvTaI9GdVyDCW4pa8RwjPWd1yAv/0bSKzjCL3UcPX7ape8eYIVpQtPM+GP+HkM5
-haa2Y0EQs3MevNP6yn0WR+Kn1dCjigoIlmJWbjTb2QK5MHXjBNLnj8KwEUAKrNVxAmKLMb7dxiNY
-MUJDLXT5xp6mig/p/r+D5kNXJLrvRjSq1xIBOO0CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYw
-HQYDVR0hBBYwFDASBgdghXQBUwABBgdghXQBUwABMBIGA1UdEwEB/wQIMAYBAf8CAQcwHwYDVR0j
-BBgwFoAUAyUv3m+CATpcLNwroWm1Z9SM0/0wHQYDVR0OBBYEFAMlL95vggE6XCzcK6FptWfUjNP9
-MA0GCSqGSIb3DQEBBQUAA4ICAQA1EMvspgQNDQ/NwNurqPKIlwzfky9NfEBWMXrrpA9gzXrzvsMn
-jgM+pN0S734edAY8PzHyHHuRMSG08NBsl9Tpl7IkVh5WwzW9iAUPWxAaZOHHgjD5Mq2eUCzneAXQ
-MbFamIp1TpBcahQq4FJHgmDmHtqBsfsUC1rxn9KVuj7QG9YVHaO+htXbD8BJZLsuUBlL0iT43R4H
-VtA4oJVwIHaM190e3p9xxCPvgxNcoyQVTSlAPGrEqdi3pkSlDfTgnXceQHAm/NrZNuR55LU/vJtl
-vrsRls/bxig5OgjOR1tTWsWZ/l2p3e9M1MalrQLmjAcSHm8D0W+go/MpvRLHUKKwf4ipmXeascCl
-OS5cfGniLLDqN2qk4Vrh9VDlg++luyqI54zb/W1elxmofmZ1a3Hqv7HHb6D0jqTsNFFbjCYDcKF3
-1QESVwA12yPeDooomf2xEG9L/zgtYE4snOtnta1J7ksfrK/7DZBaZmBwXarNeNQk7shBoJMBkpxq
-nvy5JMWzFYJ+vq6VK+uxwNrjAWALXmmshFZhvnEX/h0TD/7Gh0Xp/jKgGg0TpJRVcaUWi7rKibCy
-x/yP2FS1k2Kdzs9Z+z0YzirLNRWCXf9UIltxUvu3yf5gmwBBZPCqKuy2QkPOiWaByIufOVQDJdMW
-NY6E0F/6MBr1mmz0DlP5OlvRHA==
------END CERTIFICATE-----
-
-DigiCert Assured ID Root CA
-===========================
------BEGIN CERTIFICATE-----
-MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQG
-EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw
-IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzEx
-MTEwMDAwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL
-ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0Ew
-ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7cJpSIqvTO
-9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYPmDI2dsze3Tyoou9q+yHy
-UmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW
-/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpy
-oeb6pNnVFzF1roV9Iq4/AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whf
-GHdPAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRF
-66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkq
-hkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRCdWKuh+vy1dneVrOfzM4UKLkNl2Bc
-EkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTffwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38Fn
-SbNd67IJKusm7Xi+fT8r87cmNW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i
-8b5QZ7dsvfPxH2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe
-+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==
------END CERTIFICATE-----
-
-DigiCert Global Root CA
-=======================
------BEGIN CERTIFICATE-----
-MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQG
-EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw
-HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAw
-MDAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
-dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkq
-hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsBCSDMAZOn
-TjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97nh6Vfe63SKMI2tavegw5
-BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt43C/dxC//AH2hdmoRBBYMql1GNXRor5H
-4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7PT19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y
-7vrTC0LUq7dBMtoM1O/4gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQAB
-o2MwYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbRTLtm
-8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEF
-BQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/EsrhMAtudXH/vTBH1jLuG2cenTnmCmr
-EbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIt
-tep3Sp+dWOIrWcBAI+0tKIJFPnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886
-UAb3LujEV0lsYSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
-CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
------END CERTIFICATE-----
-
-DigiCert High Assurance EV Root CA
-==================================
------BEGIN CERTIFICATE-----
-MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQG
-EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSsw
-KQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAw
-MFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
-MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFu
-Y2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm+9S75S0t
-Mqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMS
-OO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3
-MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQ
-NAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUe
-h10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB
-Af8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSY
-JhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQ
-V8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFp
-myPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkK
-mNEVX58Svnw2Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
-vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K
------END CERTIFICATE-----
-
-Certplus Class 2 Primary CA
-===========================
------BEGIN CERTIFICATE-----
-MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAwPTELMAkGA1UE
-BhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFzcyAyIFByaW1hcnkgQ0EwHhcN
-OTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2Vy
-dHBsdXMxGzAZBgNVBAMTEkNsYXNzIDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP
-ADCCAQoCggEBANxQltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR
-5aiRVhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyLkcAbmXuZ
-Vg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCdEgETjdyAYveVqUSISnFO
-YFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yasH7WLO7dDWWuwJKZtkIvEcupdM5i3y95e
-e++U8Rs+yskhwcWYAqqi9lt3m/V+llU0HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRME
-CDAGAQH/AgEKMAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJ
-YIZIAYb4QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMuY29t
-L0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/AN9WM2K191EBkOvD
-P9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8yfFC82x/xXp8HVGIutIKPidd3i1R
-TtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMRFcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+
-7UCmnYR0ObncHoUW2ikbhiMAybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW
-//1IMwrh3KWBkJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7
-l7+ijrRU
------END CERTIFICATE-----
-
-DST Root CA X3
-==============
------BEGIN CERTIFICATE-----
-MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/MSQwIgYDVQQK
-ExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMTDkRTVCBSb290IENBIFgzMB4X
-DTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVowPzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1
-cmUgVHJ1c3QgQ28uMRcwFQYDVQQDEw5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQAD
-ggEPADCCAQoCggEBAN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmT
-rE4Orz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEqOLl5CjH9
-UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9bxiqKqy69cK3FCxolkHRy
-xXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40d
-utolucbY38EVAjqr2m7xPi71XAicPNaDaeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0T
-AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQ
-MA0GCSqGSIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69ikug
-dB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXrAvHRAosZy5Q6XkjE
-GB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZzR8srzJmwN0jP41ZL9c8PDHIyh8bw
-RLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubS
-fZGL+T0yjWW06XyxV3bqxbYoOb8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
------END CERTIFICATE-----
-
-DST ACES CA X6
-==============
------BEGIN CERTIFICATE-----
-MIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBbMQswCQYDVQQG
-EwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QxETAPBgNVBAsTCERTVCBBQ0VT
-MRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0wMzExMjAyMTE5NThaFw0xNzExMjAyMTE5NTha
-MFsxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UE
-CxMIRFNUIEFDRVMxFzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOC
-AQ8AMIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPuktKe1jzI
-DZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7gLFViYsx+tC3dr5BPTCa
-pCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZHfAjIgrrep4c9oW24MFbCswKBXy314pow
-GCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4aahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPy
-MjwmR/onJALJfh1biEITajV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1Ud
-EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rkc3Qu
-Y29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjtodHRwOi8vd3d3LnRy
-dXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMtaW5kZXguaHRtbDAdBgNVHQ4EFgQU
-CXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZIhvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V2
-5FYrnJmQ6AgwbN99Pe7lv7UkQIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6t
-Fr8hlxCBPeP/h40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq
-nExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpRrscL9yuwNwXs
-vFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf29w4LTJxoeHtxMcfrHuBnQfO3
-oKfN5XozNmr6mis=
------END CERTIFICATE-----
-
-TURKTRUST Certificate Services Provider Root 1
-==============================================
------BEGIN CERTIFICATE-----
-MIID+zCCAuOgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBtzE/MD0GA1UEAww2VMOcUktUUlVTVCBF
-bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGDAJUUjEP
-MA0GA1UEBwwGQU5LQVJBMVYwVAYDVQQKDE0oYykgMjAwNSBUw5xSS1RSVVNUIEJpbGdpIMSwbGV0
-acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjAeFw0wNTA1MTMx
-MDI3MTdaFw0xNTAzMjIxMDI3MTdaMIG3MT8wPQYDVQQDDDZUw5xSS1RSVVNUIEVsZWt0cm9uaWsg
-U2VydGlmaWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLExCzAJBgNVBAYMAlRSMQ8wDQYDVQQHDAZB
-TktBUkExVjBUBgNVBAoMTShjKSAyMDA1IFTDnFJLVFJVU1QgQmlsZ2kgxLBsZXRpxZ9pbSB2ZSBC
-aWxpxZ9pbSBHw7x2ZW5sacSfaSBIaXptZXRsZXJpIEEuxZ4uMIIBIjANBgkqhkiG9w0BAQEFAAOC
-AQ8AMIIBCgKCAQEAylIF1mMD2Bxf3dJ7XfIMYGFbazt0K3gNfUW9InTojAPBxhEqPZW8qZSwu5GX
-yGl8hMW0kWxsE2qkVa2kheiVfrMArwDCBRj1cJ02i67L5BuBf5OI+2pVu32Fks66WJ/bMsW9Xe8i
-Si9BB35JYbOG7E6mQW6EvAPs9TscyB/C7qju6hJKjRTP8wrgUDn5CDX4EVmt5yLqS8oUBt5CurKZ
-8y1UiBAG6uEaPj1nH/vO+3yC6BFdSsG5FOpU2WabfIl9BJpiyelSPJ6c79L1JuTm5Rh8i27fbMx4
-W09ysstcP4wFjdFMjK2Sx+F4f2VsSQZQLJ4ywtdKxnWKWU51b0dewQIDAQABoxAwDjAMBgNVHRME
-BTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAV9VX/N5aAWSGk/KEVTCD21F/aAyT8z5Aa9CEKmu46
-sWrv7/hg0Uw2ZkUd82YCdAR7kjCo3gp2D++Vbr3JN+YaDayJSFvMgzbC9UZcWYJWtNX+I7TYVBxE
-q8Sn5RTOPEFhfEPmzcSBCYsk+1Ql1haolgxnB2+zUEfjHCQo3SqYpGH+2+oSN7wBGjSFvW5P55Fy
-B0SFHljKVETd96y5y4khctuPwGkplyqjrhgjlxxBKot8KsF8kOipKMDTkcatKIdAaLX/7KfS0zgY
-nNN9aV3wxqUeJBujR/xpB2jn5Jq07Q+hh4cCzofSSE7hvP/L8XKSRGQDJereW26fyfJOrN3H
------END CERTIFICATE-----
-
-TURKTRUST Certificate Services Provider Root 2
-==============================================
------BEGIN CERTIFICATE-----
-MIIEPDCCAySgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBF
-bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEP
-MA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUg
-QmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwHhcN
-MDUxMTA3MTAwNzU3WhcNMTUwOTE2MTAwNzU3WjCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBFbGVr
-dHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEPMA0G
-A1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmls
-acWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwggEiMA0G
-CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCpNn7DkUNMwxmYCMjHWHtPFoylzkkBH3MOrHUTpvqe
-LCDe2JAOCtFp0if7qnefJ1Il4std2NiDUBd9irWCPwSOtNXwSadktx4uXyCcUHVPr+G1QRT0mJKI
-x+XlZEdhR3n9wFHxwZnn3M5q+6+1ATDcRhzviuyV79z/rxAc653YsKpqhRgNF8k+v/Gb0AmJQv2g
-QrSdiVFVKc8bcLyEVK3BEx+Y9C52YItdP5qtygy/p1Zbj3e41Z55SZI/4PGXJHpsmxcPbe9TmJEr
-5A++WXkHeLuXlfSfadRYhwqp48y2WBmfJiGxxFmNskF1wK1pzpwACPI2/z7woQ8arBT9pmAPAgMB
-AAGjQzBBMB0GA1UdDgQWBBTZN7NOBf3Zz58SFq62iS/rJTqIHDAPBgNVHQ8BAf8EBQMDBwYAMA8G
-A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAHJglrfJ3NgpXiOFX7KzLXb7iNcX/ntt
-Rbj2hWyfIvwqECLsqrkw9qtY1jkQMZkpAL2JZkH7dN6RwRgLn7Vhy506vvWolKMiVW4XSf/SKfE4
-Jl3vpao6+XF75tpYHdN0wgH6PmlYX63LaL4ULptswLbcoCb6dxriJNoaN+BnrdFzgw2lGh1uEpJ+
-hGIAF728JRhX8tepb1mIvDS3LoV4nZbcFMMsilKbloxSZj2GFotHuFEJjOp9zYhys2AzsfAKRO8P
-9Qk3iCQOLGsgOqL6EfJANZxEaGM7rDNvY7wsu/LSy3Z9fYjYHcgFHW68lKlmjHdxx/qR+i9Rnuk5
-UrbnBEI=
------END CERTIFICATE-----
-
-SwissSign Platinum CA - G2
-==========================
------BEGIN CERTIFICATE-----
-MIIFwTCCA6mgAwIBAgIITrIAZwwDXU8wDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCQ0gxFTAT
-BgNVBAoTDFN3aXNzU2lnbiBBRzEjMCEGA1UEAxMaU3dpc3NTaWduIFBsYXRpbnVtIENBIC0gRzIw
-HhcNMDYxMDI1MDgzNjAwWhcNMzYxMDI1MDgzNjAwWjBJMQswCQYDVQQGEwJDSDEVMBMGA1UEChMM
-U3dpc3NTaWduIEFHMSMwIQYDVQQDExpTd2lzc1NpZ24gUGxhdGludW0gQ0EgLSBHMjCCAiIwDQYJ
-KoZIhvcNAQEBBQADggIPADCCAgoCggIBAMrfogLi2vj8Bxax3mCq3pZcZB/HL37PZ/pEQtZ2Y5Wu
-669yIIpFR4ZieIbWIDkm9K6j/SPnpZy1IiEZtzeTIsBQnIJ71NUERFzLtMKfkr4k2HtnIuJpX+UF
-eNSH2XFwMyVTtIc7KZAoNppVRDBopIOXfw0enHb/FZ1glwCNioUD7IC+6ixuEFGSzH7VozPY1kne
-WCqv9hbrS3uQMpe5up1Y8fhXSQQeol0GcN1x2/ndi5objM89o03Oy3z2u5yg+gnOI2Ky6Q0f4nIo
-j5+saCB9bzuohTEJfwvH6GXp43gOCWcwizSC+13gzJ2BbWLuCB4ELE6b7P6pT1/9aXjvCR+htL/6
-8++QHkwFix7qepF6w9fl+zC8bBsQWJj3Gl/QKTIDE0ZNYWqFTFJ0LwYfexHihJfGmfNtf9dng34T
-aNhxKFrYzt3oEBSa/m0jh26OWnA81Y0JAKeqvLAxN23IhBQeW71FYyBrS3SMvds6DsHPWhaPpZjy
-domyExI7C3d3rLvlPClKknLKYRorXkzig3R3+jVIeoVNjZpTxN94ypeRSCtFKwH3HBqi7Ri6Cr2D
-+m+8jVeTO9TUps4e8aCxzqv9KyiaTxvXw3LbpMS/XUz13XuWae5ogObnmLo2t/5u7Su9IPhlGdpV
-CX4l3P5hYnL5fhgC72O00Puv5TtjjGePAgMBAAGjgawwgakwDgYDVR0PAQH/BAQDAgEGMA8GA1Ud
-EwEB/wQFMAMBAf8wHQYDVR0OBBYEFFCvzAeHFUdvOMW0ZdHelarp35zMMB8GA1UdIwQYMBaAFFCv
-zAeHFUdvOMW0ZdHelarp35zMMEYGA1UdIAQ/MD0wOwYJYIV0AVkBAQEBMC4wLAYIKwYBBQUHAgEW
-IGh0dHA6Ly9yZXBvc2l0b3J5LnN3aXNzc2lnbi5jb20vMA0GCSqGSIb3DQEBBQUAA4ICAQAIhab1
-Fgz8RBrBY+D5VUYI/HAcQiiWjrfFwUF1TglxeeVtlspLpYhg0DB0uMoI3LQwnkAHFmtllXcBrqS3
-NQuB2nEVqXQXOHtYyvkv+8Bldo1bAbl93oI9ZLi+FHSjClTTLJUYFzX1UWs/j6KWYTl4a0vlpqD4
-U99REJNi54Av4tHgvI42Rncz7Lj7jposiU0xEQ8mngS7twSNC/K5/FqdOxa3L8iYq/6KUFkuozv8
-KV2LwUvJ4ooTHbG/u0IdUt1O2BReEMYxB+9xJ/cbOQncguqLs5WGXv312l0xpuAxtpTmREl0xRbl
-9x8DYSjFyMsSoEJL+WuICI20MhjzdZ/EfwBPBZWcoxcCw7NTm6ogOSkrZvqdr16zktK1puEa+S1B
-aYEUtLS17Yk9zvupnTVCRLEcFHOBzyoBNZox1S2PbYTfgE1X4z/FhHXaicYwu+uPyyIIoK6q8QNs
-OktNCaUOcsZWayFCTiMlFGiudgp8DAdwZPmaL/YFOSbGDI8Zf0NebvRbFS/bYV3mZy8/CJT5YLSY
-Mdp08YSTcU1f+2BY0fvEwW2JorsgH51xkcsymxM9Pn2SUjWskpSi0xjCfMfqr3YFFt1nJ8J+HAci
-IfNAChs0B0QTwoRqjt8ZWr9/6x3iGjjRXK9HkmuAtTClyY3YqzGBH9/CZjfTk6mFhnll0g==
------END CERTIFICATE-----
-
-SwissSign Gold CA - G2
-======================
------BEGIN CERTIFICATE-----
-MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkNIMRUw
-EwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2lnbiBHb2xkIENBIC0gRzIwHhcN
-MDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBFMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dp
-c3NTaWduIEFHMR8wHQYDVQQDExZTd2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0B
-AQEFAAOCAg8AMIICCgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUq
-t2/876LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+bbqBHH5C
-jCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c6bM8K8vzARO/Ws/BtQpg
-vd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqEemA8atufK+ze3gE/bk3lUIbLtK/tREDF
-ylqM2tIrfKjuvqblCqoOpd8FUrdVxyJdMmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvR
-AiTysybUa9oEVeXBCsdtMDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuend
-jIj3o02yMszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69yFGkO
-peUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPiaG59je883WX0XaxR
-7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxMgI93e2CaHt+28kgeDrpOVG2Y4OGi
-GqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw
-AwEB/zAdBgNVHQ4EFgQUWyV7lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64
-OfPAeGZe6Drn8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov
-L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe645R88a7A3hfm
-5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczOUYrHUDFu4Up+GC9pWbY9ZIEr
-44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOf
-Mke6UiI0HTJ6CVanfCU2qT1L2sCCbwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6m
-Gu6uLftIdxf+u+yvGPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxp
-mo/a77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCChdiDyyJk
-vC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid392qgQmwLOM7XdVAyksLf
-KzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEppLd6leNcG2mqeSz53OiATIgHQv2ieY2Br
-NU0LbbqhPcCT4H8js1WtciVORvnSFu+wZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6Lqj
-viOvrv1vA+ACOzB2+httQc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ
------END CERTIFICATE-----
-
-SwissSign Silver CA - G2
-========================
------BEGIN CERTIFICATE-----
-MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCQ0gxFTAT
-BgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMB4X
-DTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0NlowRzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3
-aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG
-9w0BAQEFAAOCAg8AMIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644
-N0MvFz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7brYT7QbNHm
-+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieFnbAVlDLaYQ1HTWBCrpJH
-6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH6ATK72oxh9TAtvmUcXtnZLi2kUpCe2Uu
-MGoM9ZDulebyzYLs2aFK7PayS+VFheZteJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5h
-qAaEuSh6XzjZG6k4sIN/c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5
-FZGkECwJMoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRHHTBs
-ROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTfjNFusB3hB48IHpmc
-celM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb65i/4z3GcRm25xBWNOHkDRUjvxF3X
-CO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
-BAUwAwEB/zAdBgNVHQ4EFgQUF6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRB
-tjpbO8tFnb0cwpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0
-cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBAHPGgeAn0i0P
-4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShpWJHckRE1qTodvBqlYJ7YH39F
-kWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L
-3XWgwF15kIwb4FDm3jH+mHtwX6WQ2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx
-/uNncqCxv1yL5PqZIseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFa
-DGi8aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2Xem1ZqSqP
-e97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQRdAtq/gsD/KNVV4n+Ssuu
-WxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJ
-DIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ub
-DgEj8Z+7fNzcbBGXJbLytGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u
------END CERTIFICATE-----
-
-GeoTrust Primary Certification Authority
-========================================
------BEGIN CERTIFICATE-----
-MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQG
-EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMoR2VvVHJ1c3QgUHJpbWFyeSBD
-ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgx
-CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQ
-cmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
-CgKCAQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9AWbK7hWN
-b6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjAZIVcFU2Ix7e64HXprQU9
-nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE07e9GceBrAqg1cmuXm2bgyxx5X9gaBGge
-RwLmnWDiNpcB3841kt++Z8dtd1k7j53WkBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGt
-tm/81w7a4DSwDRp35+MImO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
-AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJKoZI
-hvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ16CePbJC/kRYkRj5K
-Ts4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl4b7UVXGYNTq+k+qurUKykG/g/CFN
-NWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6KoKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHa
-Floxt/m0cYASSJlyc1pZU8FjUjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG
-1riR/aYNKxoUAT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk=
------END CERTIFICATE-----
-
-thawte Primary Root CA
-======================
------BEGIN CERTIFICATE-----
-MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCBqTELMAkGA1UE
-BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2
-aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv
-cml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3
-MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwg
-SW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMv
-KGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMT
-FnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCs
-oPD7gFnUnMekz52hWXMJEEUMDSxuaPFsW0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ
-1CRfBsDMRJSUjQJib+ta3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGc
-q/gcfomk6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6Sk/K
-aAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94JNqR32HuHUETVPm4p
-afs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD
-VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XPr87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUF
-AAOCAQEAeRHAS7ORtvzw6WfUDW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeE
-uzLlQRHAd9mzYJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX
-xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2/qxAeeWsEG89
-jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/LHbTY5xZ3Y+m4Q6gLkH3LpVH
-z7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7jVaMaA==
------END CERTIFICATE-----
-
-VeriSign Class 3 Public Primary Certification Authority - G5
-============================================================
------BEGIN CERTIFICATE-----
-MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE
-BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO
-ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk
-IHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRp
-ZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCB
-yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln
-biBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBh
-dXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmlt
-YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
-ggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKz
-j/i5Vbext0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhD
-Y2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/
-Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNHiDxpg8v+R70r
-fk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/
-BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2Uv
-Z2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
-aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG
-SIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzEp6B4Eq1iDkVwZMXnl2YtmAl+
-X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKE
-KQsTb47bDN0lAtukixlE0kF6BWlKWE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiC
-Km0oHw0LxOXnGiYZ4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vE
-ZV8NhnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
------END CERTIFICATE-----
-
-SecureTrust CA
-==============
------BEGIN CERTIFICATE-----
-MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBIMQswCQYDVQQG
-EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xFzAVBgNVBAMTDlNlY3VyZVRy
-dXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIzMTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAe
-BgNVBAoTF1NlY3VyZVRydXN0IENvcnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCC
-ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQX
-OZEzZum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO0gMdA+9t
-DWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIaowW8xQmxSPmjL8xk037uH
-GFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b
-01k/unK8RCSc43Oz969XL0Imnal0ugBS8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmH
-ursCAwEAAaOBnTCBmjATBgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/
-BAUwAwEB/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCegJYYj
-aHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ
-KoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt36Z3q059c4EVlew3KW+JwULKUBRSu
-SceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHf
-mbx8IVQr5Fiiu1cprp6poxkmD5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZ
-nMUFdAvnZyPSCPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR
-3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE=
------END CERTIFICATE-----
-
-Secure Global CA
-================
------BEGIN CERTIFICATE-----
-MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQG
-EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBH
-bG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkxMjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEg
-MB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwg
-Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jx
-YDiJiQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa/FHtaMbQ
-bqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJjnIFHovdRIWCQtBJwB1g
-8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnIHmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYV
-HDGA76oYa8J719rO+TMg1fW9ajMtgQT7sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi
-0XPnj3pDAgMBAAGjgZ0wgZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud
-EwEB/wQFMAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCswKaAn
-oCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsGAQQBgjcVAQQDAgEA
-MA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0LURYD7xh8yOOvaliTFGCRsoTciE6+
-OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXOH0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cn
-CDpOGR86p1hcF895P4vkp9MmI50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/5
-3CYNv6ZHdAbYiNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc
-f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW
------END CERTIFICATE-----
-
-COMODO Certification Authority
-==============================
------BEGIN CERTIFICATE-----
-MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCBgTELMAkGA1UE
-BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG
-A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNVBAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1
-dGhvcml0eTAeFw0wNjEyMDEwMDAwMDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEb
-MBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFD
-T01PRE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0aG9yaXR5
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3UcEbVASY06m/weaKXTuH
-+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI2GqGd0S7WWaXUF601CxwRM/aN5VCaTww
-xHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV
-4EajcNxo2f8ESIl33rXp+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA
-1KGzqSX+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5OnKVI
-rLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW/zAOBgNVHQ8BAf8E
-BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLmNvbW9k
-b2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOC
-AQEAPpiem/Yb6dc5t3iuHXIYSdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CP
-OGEIqB6BCsAvIC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/
-RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4zJVSk/BwJVmc
-IGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5ddBA6+C4OmF4O5MBKgxTMVBbkN
-+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IBZQ==
------END CERTIFICATE-----
-
-Network Solutions Certificate Authority
-=======================================
------BEGIN CERTIFICATE-----
-MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQG
-EwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydOZXR3b3Jr
-IFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMx
-MjM1OTU5WjBiMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu
-MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G
-CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwzc7MEL7xx
-jOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPPOCwGJgl6cvf6UDL4wpPT
-aaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rlmGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXT
-crA/vGp97Eh/jcOrqnErU2lBUzS1sLnFBgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc
-/Qzpf14Dl847ABSHJ3A4qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMB
-AAGjgZcwgZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIBBjAP
-BgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwubmV0c29sc3NsLmNv
-bS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3JpdHkuY3JsMA0GCSqGSIb3DQEBBQUA
-A4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc86fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q
-4LqILPxFzBiwmZVRDuwduIj/h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/
-GGUsyfJj4akH/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv
-wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHNpGxlaKFJdlxD
-ydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey
------END CERTIFICATE-----
-
-WellsSecure Public Root Certificate Authority
-=============================================
------BEGIN CERTIFICATE-----
-MIIEvTCCA6WgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoM
-F1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYw
-NAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcN
-MDcxMjEzMTcwNzU0WhcNMjIxMjE0MDAwNzU0WjCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dl
-bGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYD
-VQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G
-CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDub7S9eeKPCCGeOARBJe+rWxxTkqxtnt3CxC5FlAM1
-iGd0V+PfjLindo8796jE2yljDpFoNoqXjopxaAkH5OjUDk/41itMpBb570OYj7OeUt9tkTmPOL13
-i0Nj67eT/DBMHAGTthP796EfvyXhdDcsHqRePGj4S78NuR4uNuip5Kf4D8uCdXw1LSLWwr8L87T8
-bJVhHlfXBIEyg1J55oNjz7fLY4sR4r1e6/aN7ZVyKLSsEmLpSjPmgzKuBXWVvYSV2ypcm44uDLiB
-K0HmOFafSZtsdvqKXfcBeYF8wYNABf5x/Qw/zE5gCQ5lRxAvAcAFP4/4s0HvWkJ+We/SlwxlAgMB
-AAGjggE0MIIBMDAPBgNVHRMBAf8EBTADAQH/MDkGA1UdHwQyMDAwLqAsoCqGKGh0dHA6Ly9jcmwu
-cGtpLndlbGxzZmFyZ28uY29tL3dzcHJjYS5jcmwwDgYDVR0PAQH/BAQDAgHGMB0GA1UdDgQWBBQm
-lRkQ2eihl5H/3BnZtQQ+0nMKajCBsgYDVR0jBIGqMIGngBQmlRkQ2eihl5H/3BnZtQQ+0nMKaqGB
-i6SBiDCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRww
-GgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMg
-Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCAQEwDQYJKoZIhvcNAQEFBQADggEBALkVsUSRzCPI
-K0134/iaeycNzXK7mQDKfGYZUMbVmO2rvwNa5U3lHshPcZeG1eMd/ZDJPHV3V3p9+N701NX3leZ0
-bh08rnyd2wIDBSxxSyU+B+NemvVmFymIGjifz6pBA4SXa5M4esowRBskRDPQ5NHcKDj0E0M1NSlj
-qHyita04pO2t/caaH/+Xc/77szWnk4bGdpEA5qxRFsQnMlzbc9qlk1eOPm01JghZ1edE13YgY+es
-E2fDbbFwRnzVlhE9iW9dqKHrjQrawx0zbKPqZxmamX9LPYNRKh3KL4YMon4QLSvUFpULB6ouFJJJ
-tylv2G0xffX8oRAHh84vWdw+WNs=
------END CERTIFICATE-----
-
-COMODO ECC Certification Authority
-==================================
------BEGIN CERTIFICATE-----
-MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTELMAkGA1UEBhMC
-R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE
-ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBB
-dXRob3JpdHkwHhcNMDgwMzA2MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0Ix
-GzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR
-Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRo
-b3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSRFtSrYpn1PlILBs5BAH+X
-4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0JcfRK9ChQtP6IHG4/bC8vCVlbpVsLM5ni
-wz2J+Wos77LTBumjQjBAMB0GA1UdDgQWBBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8E
-BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VG
-FAkK+qDmfQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdvGDeA
-U/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=
------END CERTIFICATE-----
-
-IGC/A
-=====
------BEGIN CERTIFICATE-----
-MIIEAjCCAuqgAwIBAgIFORFFEJQwDQYJKoZIhvcNAQEFBQAwgYUxCzAJBgNVBAYTAkZSMQ8wDQYD
-VQQIEwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVE
-Q1NTSTEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZy
-MB4XDTAyMTIxMzE0MjkyM1oXDTIwMTAxNzE0MjkyMlowgYUxCzAJBgNVBAYTAkZSMQ8wDQYDVQQI
-EwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVEQ1NT
-STEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZyMIIB
-IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsh/R0GLFMzvABIaIs9z4iPf930Pfeo2aSVz2
-TqrMHLmh6yeJ8kbpO0px1R2OLc/mratjUMdUC24SyZA2xtgv2pGqaMVy/hcKshd+ebUyiHDKcMCW
-So7kVc0dJ5S/znIq7Fz5cyD+vfcuiWe4u0dzEvfRNWk68gq5rv9GQkaiv6GFGvm/5P9JhfejcIYy
-HF2fYPepraX/z9E0+X1bF8bc1g4oa8Ld8fUzaJ1O/Id8NhLWo4DoQw1VYZTqZDdH6nfK0LJYBcNd
-frGoRpAxVs5wKpayMLh35nnAvSk7/ZR3TL0gzUEl4C7HG7vupARB0l2tEmqKm0f7yd1GQOGdPDPQ
-tQIDAQABo3cwdTAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBRjAVBgNVHSAEDjAMMAoGCCqB
-egF5AQEBMB0GA1UdDgQWBBSjBS8YYFDCiQrdKyFP/45OqDAxNjAfBgNVHSMEGDAWgBSjBS8YYFDC
-iQrdKyFP/45OqDAxNjANBgkqhkiG9w0BAQUFAAOCAQEABdwm2Pp3FURo/C9mOnTgXeQp/wYHE4RK
-q89toB9RlPhJy3Q2FLwV3duJL92PoF189RLrn544pEfMs5bZvpwlqwN+Mw+VgQ39FuCIvjfwbF3Q
-MZsyK10XZZOYYLxuj7GoPB7ZHPOpJkL5ZB3C55L29B5aqhlSXa/oovdgoPaN8In1buAKBQGVyYsg
-Crpa/JosPL3Dt8ldeCUFP1YUmwza+zpI/pdpXsoQhvdOlgQITeywvl3cO45Pwf2aNjSaTFR+FwNI
-lQgRHAdvhQh+XU3Endv7rs6y0bO4g2wdsrN58dhwmX7wEwLOXt1R0982gaEbeC9xs/FZTEYYKKuF
-0mBWWg==
------END CERTIFICATE-----
-
-Security Communication EV RootCA1
-=================================
------BEGIN CERTIFICATE-----
-MIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJKUDElMCMGA1UEChMc
-U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEqMCgGA1UECxMhU2VjdXJpdHkgQ29tbXVuaWNh
-dGlvbiBFViBSb290Q0ExMB4XDTA3MDYwNjAyMTIzMloXDTM3MDYwNjAyMTIzMlowYDELMAkGA1UE
-BhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKjAoBgNVBAsTIVNl
-Y3VyaXR5IENvbW11bmljYXRpb24gRVYgUm9vdENBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
-AQoCggEBALx/7FebJOD+nLpCeamIivqA4PUHKUPqjgo0No0c+qe1OXj/l3X3L+SqawSERMqm4miO
-/VVQYg+kcQ7OBzgtQoVQrTyWb4vVog7P3kmJPdZkLjjlHmy1V4qe70gOzXppFodEtZDkBp2uoQSX
-WHnvIEqCa4wiv+wfD+mEce3xDuS4GBPMVjZd0ZoeUWs5bmB2iDQL87PRsJ3KYeJkHcFGB7hj3R4z
-ZbOOCVVSPbW9/wfrrWFVGCypaZhKqkDFMxRldAD5kd6vA0jFQFTcD4SQaCDFkpbcLuUCRarAX1T4
-bepJz11sS6/vmsJWXMY1VkJqMF/Cq/biPT+zyRGPMUzXn0kCAwEAAaNCMEAwHQYDVR0OBBYEFDVK
-9U2vP9eCOKyrcWUXdYydVZPmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqG
-SIb3DQEBBQUAA4IBAQCoh+ns+EBnXcPBZsdAS5f8hxOQWsTvoMpfi7ent/HWtWS3irO4G8za+6xm
-iEHO6Pzk2x6Ipu0nUBsCMCRGef4Eh3CXQHPRwMFXGZpppSeZq51ihPZRwSzJIxXYKLerJRO1RuGG
-Av8mjMSIkh1W/hln8lXkgKNrnKt34VFxDSDbEJrbvXZ5B3eZKK2aXtqxT0QsNY6llsf9g/BYxnnW
-mHyojf6GPgcWkuF75x3sM3Z+Qi5KhfmRiWiEA4Glm5q+4zfFVKtWOxgtQaQM+ELbmaDgcm+7XeEW
-T1MKZPlO9L9OVL14bIjqv5wTJMJwaaJ/D8g8rQjJsJhAoyrniIPtd490
------END CERTIFICATE-----
-
-OISTE WISeKey Global Root GA CA
-===============================
------BEGIN CERTIFICATE-----
-MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCBijELMAkGA1UE
-BhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHlyaWdodCAoYykgMjAwNTEiMCAG
-A1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBH
-bG9iYWwgUm9vdCBHQSBDQTAeFw0wNTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYD
-VQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIw
-IAYDVQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5
-IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy0+zAJs9
-Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxRVVuuk+g3/ytr6dTqvirdqFEr12bDYVxg
-Asj1znJ7O7jyTmUIms2kahnBAbtzptf2w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbD
-d50kc3vkDIzh2TbhmYsFmQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ
-/yxViJGg4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t94B3R
-LoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw
-AwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ
-KoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOxSPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vIm
-MMkQyh2I+3QZH4VFvbBsUfk2ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4
-+vg1YFkCExh8vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa
-hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZiFj4A4xylNoEY
-okxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ/L7fCg0=
------END CERTIFICATE-----
-
-S-TRUST Authentication and Encryption Root CA 2005 PN
-=====================================================
------BEGIN CERTIFICATE-----
-MIIEezCCA2OgAwIBAgIQNxkY5lNUfBq1uMtZWts1tzANBgkqhkiG9w0BAQUFADCBrjELMAkGA1UE
-BhMCREUxIDAeBgNVBAgTF0JhZGVuLVd1ZXJ0dGVtYmVyZyAoQlcpMRIwEAYDVQQHEwlTdHV0dGdh
-cnQxKTAnBgNVBAoTIERldXRzY2hlciBTcGFya2Fzc2VuIFZlcmxhZyBHbWJIMT4wPAYDVQQDEzVT
-LVRSVVNUIEF1dGhlbnRpY2F0aW9uIGFuZCBFbmNyeXB0aW9uIFJvb3QgQ0EgMjAwNTpQTjAeFw0w
-NTA2MjIwMDAwMDBaFw0zMDA2MjEyMzU5NTlaMIGuMQswCQYDVQQGEwJERTEgMB4GA1UECBMXQmFk
-ZW4tV3VlcnR0ZW1iZXJnIChCVykxEjAQBgNVBAcTCVN0dXR0Z2FydDEpMCcGA1UEChMgRGV1dHNj
-aGVyIFNwYXJrYXNzZW4gVmVybGFnIEdtYkgxPjA8BgNVBAMTNVMtVFJVU1QgQXV0aGVudGljYXRp
-b24gYW5kIEVuY3J5cHRpb24gUm9vdCBDQSAyMDA1OlBOMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
-MIIBCgKCAQEA2bVKwdMz6tNGs9HiTNL1toPQb9UY6ZOvJ44TzbUlNlA0EmQpoVXhOmCTnijJ4/Ob
-4QSwI7+Vio5bG0F/WsPoTUzVJBY+h0jUJ67m91MduwwA7z5hca2/OnpYH5Q9XIHV1W/fuJvS9eXL
-g3KSwlOyggLrra1fFi2SU3bxibYs9cEv4KdKb6AwajLrmnQDaHgTncovmwsdvs91DSaXm8f1Xgqf
-eN+zvOyauu9VjxuapgdjKRdZYgkqeQd3peDRF2npW932kKvimAoA0SVtnteFhy+S8dF2g08LOlk3
-KC8zpxdQ1iALCvQm+Z845y2kuJuJja2tyWp9iRe79n+Ag3rm7QIDAQABo4GSMIGPMBIGA1UdEwEB
-/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgEGMCkGA1UdEQQiMCCkHjAcMRowGAYDVQQDExFTVFJv
-bmxpbmUxLTIwNDgtNTAdBgNVHQ4EFgQUD8oeXHngovMpttKFswtKtWXsa1IwHwYDVR0jBBgwFoAU
-D8oeXHngovMpttKFswtKtWXsa1IwDQYJKoZIhvcNAQEFBQADggEBAK8B8O0ZPCjoTVy7pWMciDMD
-pwCHpB8gq9Yc4wYfl35UvbfRssnV2oDsF9eK9XvCAPbpEW+EoFolMeKJ+aQAPzFoLtU96G7m1R08
-P7K9n3frndOMusDXtk3sU5wPBG7qNWdX4wple5A64U8+wwCSersFiXOMy6ZNwPv2AtawB6MDwidA
-nwzkhYItr5pCHdDHjfhA7p0GVxzZotiAFP7hYy0yh9WUUpY6RsZxlj33mA6ykaqP2vROJAA5Veit
-F7nTNCtKqUDMFypVZUF0Qn71wK/Ik63yGFs9iQzbRzkk+OBM8h+wPQrKBU6JIRrjKpms/H+h8Q8b
-Hz2eBIPdltkdOpQ=
------END CERTIFICATE-----
-
-Microsec e-Szigno Root CA
-=========================
------BEGIN CERTIFICATE-----
-MIIHqDCCBpCgAwIBAgIRAMy4579OKRr9otxmpRwsDxEwDQYJKoZIhvcNAQEFBQAwcjELMAkGA1UE
-BhMCSFUxETAPBgNVBAcTCEJ1ZGFwZXN0MRYwFAYDVQQKEw1NaWNyb3NlYyBMdGQuMRQwEgYDVQQL
-EwtlLVN6aWdubyBDQTEiMCAGA1UEAxMZTWljcm9zZWMgZS1Temlnbm8gUm9vdCBDQTAeFw0wNTA0
-MDYxMjI4NDRaFw0xNzA0MDYxMjI4NDRaMHIxCzAJBgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVz
-dDEWMBQGA1UEChMNTWljcm9zZWMgTHRkLjEUMBIGA1UECxMLZS1Temlnbm8gQ0ExIjAgBgNVBAMT
-GU1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
-AQDtyADVgXvNOABHzNuEwSFpLHSQDCHZU4ftPkNEU6+r+ICbPHiN1I2uuO/TEdyB5s87lozWbxXG
-d36hL+BfkrYn13aaHUM86tnsL+4582pnS4uCzyL4ZVX+LMsvfUh6PXX5qqAnu3jCBspRwn5mS6/N
-oqdNAoI/gqyFxuEPkEeZlApxcpMqyabAvjxWTHOSJ/FrtfX9/DAFYJLG65Z+AZHCabEeHXtTRbjc
-QR/Ji3HWVBTji1R4P770Yjtb9aPs1ZJ04nQw7wHb4dSrmZsqa/i9phyGI0Jf7Enemotb9HI6QMVJ
-PqW+jqpx62z69Rrkav17fVVA71hu5tnVvCSrwe+3AgMBAAGjggQ3MIIEMzBnBggrBgEFBQcBAQRb
-MFkwKAYIKwYBBQUHMAGGHGh0dHBzOi8vcmNhLmUtc3ppZ25vLmh1L29jc3AwLQYIKwYBBQUHMAKG
-IWh0dHA6Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNydDAPBgNVHRMBAf8EBTADAQH/MIIBcwYD
-VR0gBIIBajCCAWYwggFiBgwrBgEEAYGoGAIBAQEwggFQMCgGCCsGAQUFBwIBFhxodHRwOi8vd3d3
-LmUtc3ppZ25vLmh1L1NaU1ovMIIBIgYIKwYBBQUHAgIwggEUHoIBEABBACAAdABhAG4A+gBzAO0A
-dAB2AOEAbgB5ACAA6QByAHQAZQBsAG0AZQB6AOkAcwDpAGgAZQB6ACAA6QBzACAAZQBsAGYAbwBn
-AGEAZADhAHMA4QBoAG8AegAgAGEAIABTAHoAbwBsAGcA4QBsAHQAYQB0APMAIABTAHoAbwBsAGcA
-4QBsAHQAYQB0AOEAcwBpACAAUwB6AGEAYgDhAGwAeQB6AGEAdABhACAAcwB6AGUAcgBpAG4AdAAg
-AGsAZQBsAGwAIABlAGwAagDhAHIAbgBpADoAIABoAHQAdABwADoALwAvAHcAdwB3AC4AZQAtAHMA
-egBpAGcAbgBvAC4AaAB1AC8AUwBaAFMAWgAvMIHIBgNVHR8EgcAwgb0wgbqggbeggbSGIWh0dHA6
-Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNybIaBjmxkYXA6Ly9sZGFwLmUtc3ppZ25vLmh1L0NO
-PU1pY3Jvc2VjJTIwZS1Temlnbm8lMjBSb290JTIwQ0EsT1U9ZS1Temlnbm8lMjBDQSxPPU1pY3Jv
-c2VjJTIwTHRkLixMPUJ1ZGFwZXN0LEM9SFU/Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdDtiaW5h
-cnkwDgYDVR0PAQH/BAQDAgEGMIGWBgNVHREEgY4wgYuBEGluZm9AZS1zemlnbm8uaHWkdzB1MSMw
-IQYDVQQDDBpNaWNyb3NlYyBlLVN6aWduw7MgUm9vdCBDQTEWMBQGA1UECwwNZS1TemlnbsOzIEhT
-WjEWMBQGA1UEChMNTWljcm9zZWMgS2Z0LjERMA8GA1UEBxMIQnVkYXBlc3QxCzAJBgNVBAYTAkhV
-MIGsBgNVHSMEgaQwgaGAFMegSXUWYYTbMUuE0vE3QJDvTtz3oXakdDByMQswCQYDVQQGEwJIVTER
-MA8GA1UEBxMIQnVkYXBlc3QxFjAUBgNVBAoTDU1pY3Jvc2VjIEx0ZC4xFDASBgNVBAsTC2UtU3pp
-Z25vIENBMSIwIAYDVQQDExlNaWNyb3NlYyBlLVN6aWdubyBSb290IENBghEAzLjnv04pGv2i3Gal
-HCwPETAdBgNVHQ4EFgQUx6BJdRZhhNsxS4TS8TdAkO9O3PcwDQYJKoZIhvcNAQEFBQADggEBANMT
-nGZjWS7KXHAM/IO8VbH0jgdsZifOwTsgqRy7RlRw7lrMoHfqaEQn6/Ip3Xep1fvj1KcExJW4C+FE
-aGAHQzAxQmHl7tnlJNUb3+FKG6qfx1/4ehHqE5MAyopYse7tDk2016g2JnzgOsHVV4Lxdbb9iV/a
-86g4nzUGCM4ilb7N1fy+W955a9x6qWVmvrElWl/tftOsRm1M9DKHtCAE4Gx4sHfRhUZLphK3dehK
-yVZs15KrnfVJONJPU+NVkBHbmJbGSfI+9J8b4PeI3CVimUTYc78/MPMMNz7UwiiAc7EBt51alhQB
-S6kRnSlqLtBdgcDPsiBDxwPgN05dCtxZICU=
------END CERTIFICATE-----
-
-Certigna
-========
------BEGIN CERTIFICATE-----
-MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNVBAYTAkZSMRIw
-EAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4XDTA3MDYyOTE1MTMwNVoXDTI3
-MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwI
-Q2VydGlnbmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7q
-XOEm7RFHYeGifBZ4QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyH
-GxnygQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbwzBfsV1/p
-ogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q130yGLMLLGq/jj8UEYkg
-DncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKf
-Irjxwo1p3Po6WAbfAgMBAAGjgbwwgbkwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQ
-tCRZvgHyUtVF9lo53BEwZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJ
-BgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzjAQ/J
-SP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG9w0BAQUFAAOCAQEA
-hQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8hbV6lUmPOEvjvKtpv6zf+EwLHyzs+
-ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFncfca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1klu
-PBS1xp81HlDQwY9qcEQCYsuuHWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY
-1gkIl2PlwS6wt0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw
-WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg==
------END CERTIFICATE-----
-
-AC Ra\xC3\xADz Certic\xC3\xA1mara S.A.
-======================================
------BEGIN CERTIFICATE-----
-MIIGZjCCBE6gAwIBAgIPB35Sk3vgFeNX8GmMy+wMMA0GCSqGSIb3DQEBBQUAMHsxCzAJBgNVBAYT
-AkNPMUcwRQYDVQQKDD5Tb2NpZWRhZCBDYW1lcmFsIGRlIENlcnRpZmljYWNpw7NuIERpZ2l0YWwg
-LSBDZXJ0aWPDoW1hcmEgUy5BLjEjMCEGA1UEAwwaQUMgUmHDrXogQ2VydGljw6FtYXJhIFMuQS4w
-HhcNMDYxMTI3MjA0NjI5WhcNMzAwNDAyMjE0MjAyWjB7MQswCQYDVQQGEwJDTzFHMEUGA1UECgw+
-U29jaWVkYWQgQ2FtZXJhbCBkZSBDZXJ0aWZpY2FjacOzbiBEaWdpdGFsIC0gQ2VydGljw6FtYXJh
-IFMuQS4xIzAhBgNVBAMMGkFDIFJhw616IENlcnRpY8OhbWFyYSBTLkEuMIICIjANBgkqhkiG9w0B
-AQEFAAOCAg8AMIICCgKCAgEAq2uJo1PMSCMI+8PPUZYILrgIem08kBeGqentLhM0R7LQcNzJPNCN
-yu5LF6vQhbCnIwTLqKL85XXbQMpiiY9QngE9JlsYhBzLfDe3fezTf3MZsGqy2IiKLUV0qPezuMDU
-2s0iiXRNWhU5cxh0T7XrmafBHoi0wpOQY5fzp6cSsgkiBzPZkc0OnB8OIMfuuzONj8LSWKdf/WU3
-4ojC2I+GdV75LaeHM/J4Ny+LvB2GNzmxlPLYvEqcgxhaBvzz1NS6jBUJJfD5to0EfhcSM2tXSExP
-2yYe68yQ54v5aHxwD6Mq0Do43zeX4lvegGHTgNiRg0JaTASJaBE8rF9ogEHMYELODVoqDA+bMMCm
-8Ibbq0nXl21Ii/kDwFJnmxL3wvIumGVC2daa49AZMQyth9VXAnow6IYm+48jilSH5L887uvDdUhf
-HjlvgWJsxS3EF1QZtzeNnDeRyPYL1epjb4OsOMLzP96a++EjYfDIJss2yKHzMI+ko6Kh3VOz3vCa
-Mh+DkXkwwakfU5tTohVTP92dsxA7SH2JD/ztA/X7JWR1DhcZDY8AFmd5ekD8LVkH2ZD6mq093ICK
-5lw1omdMEWux+IBkAC1vImHFrEsm5VoQgpukg3s0956JkSCXjrdCx2bD0Omk1vUgjcTDlaxECp1b
-czwmPS9KvqfJpxAe+59QafMCAwEAAaOB5jCB4zAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE
-AwIBBjAdBgNVHQ4EFgQU0QnQ6dfOeXRU+Tows/RtLAMDG2gwgaAGA1UdIASBmDCBlTCBkgYEVR0g
-ADCBiTArBggrBgEFBQcCARYfaHR0cDovL3d3dy5jZXJ0aWNhbWFyYS5jb20vZHBjLzBaBggrBgEF
-BQcCAjBOGkxMaW1pdGFjaW9uZXMgZGUgZ2FyYW507WFzIGRlIGVzdGUgY2VydGlmaWNhZG8gc2Ug
-cHVlZGVuIGVuY29udHJhciBlbiBsYSBEUEMuMA0GCSqGSIb3DQEBBQUAA4ICAQBclLW4RZFNjmEf
-AygPU3zmpFmps4p6xbD/CHwso3EcIRNnoZUSQDWDg4902zNc8El2CoFS3UnUmjIz75uny3XlesuX
-EpBcunvFm9+7OSPI/5jOCk0iAUgHforA1SBClETvv3eiiWdIG0ADBaGJ7M9i4z0ldma/Jre7Ir5v
-/zlXdLp6yQGVwZVR6Kss+LGGIOk/yzVb0hfpKv6DExdA7ohiZVvVO2Dpezy4ydV/NgIlqmjCMRW3
-MGXrfx1IebHPOeJCgBbT9ZMj/EyXyVo3bHwi2ErN0o42gzmRkBDI8ck1fj+404HGIGQatlDCIaR4
-3NAvO2STdPCWkPHv+wlaNECW8DYSwaN0jJN+Qd53i+yG2dIPPy3RzECiiWZIHiCznCNZc6lEc7wk
-eZBWN7PGKX6jD/EpOe9+XCgycDWs2rjIdWb8m0w5R44bb5tNAlQiM+9hup4phO9OSzNHdpdqy35f
-/RWmnkJDW2ZaiogN9xa5P1FlK2Zqi9E4UqLWRhH6/JocdJ6PlwsCT2TG9WjTSy3/pDceiz+/RL5h
-RqGEPQgnTIEgd4kI6mdAXmwIUV80WoyWaM3X94nCHNMyAK9Sy9NgWyo6R35rMDOhYil/SrnhLecU
-Iw4OGEfhefwVVdCx/CVxY3UzHCMrr1zZ7Ud3YA47Dx7SwNxkBYn8eNZcLCZDqQ==
------END CERTIFICATE-----
-
-TC TrustCenter Class 2 CA II
-============================
------BEGIN CERTIFICATE-----
-MIIEqjCCA5KgAwIBAgIOLmoAAQACH9dSISwRXDswDQYJKoZIhvcNAQEFBQAwdjELMAkGA1UEBhMC
-REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNVBAsTGVRDIFRydXN0Q2VudGVy
-IENsYXNzIDIgQ0ExJTAjBgNVBAMTHFRDIFRydXN0Q2VudGVyIENsYXNzIDIgQ0EgSUkwHhcNMDYw
-MTEyMTQzODQzWhcNMjUxMjMxMjI1OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1
-c3RDZW50ZXIgR21iSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQTElMCMGA1UE
-AxMcVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
-AQoCggEBAKuAh5uO8MN8h9foJIIRszzdQ2Lu+MNF2ujhoF/RKrLqk2jftMjWQ+nEdVl//OEd+DFw
-IxuInie5e/060smp6RQvkL4DUsFJzfb95AhmC1eKokKguNV/aVyQMrKXDcpK3EY+AlWJU+MaWss2
-xgdW94zPEfRMuzBwBJWl9jmM/XOBCH2JXjIeIqkiRUuwZi4wzJ9l/fzLganx4Duvo4bRierERXlQ
-Xa7pIXSSTYtZgo+U4+lK8edJsBTj9WLL1XK9H7nSn6DNqPoByNkN39r8R52zyFTfSUrxIan+GE7u
-SNQZu+995OKdy1u2bv/jzVrndIIFuoAlOMvkaZ6vQaoahPUCAwEAAaOCATQwggEwMA8GA1UdEwEB
-/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTjq1RMgKHbVkO3kUrL84J6E1wIqzCB
-7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRydXN0Y2VudGVyLmRlL2NybC92Mi90
-Y19jbGFzc18yX2NhX0lJLmNybIaBn2xkYXA6Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBU
-cnVzdENlbnRlciUyMENsYXNzJTIwMiUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21i
-SCxPVT1yb290Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u
-TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEAjNfffu4bgBCzg/XbEeprS6iSGNn3Bzn1LL4G
-dXpoUxUc6krtXvwjshOg0wn/9vYua0Fxec3ibf2uWWuFHbhOIprtZjluS5TmVfwLG4t3wVMTZonZ
-KNaL80VKY7f9ewthXbhtvsPcW3nS7Yblok2+XnR8au0WOB9/WIFaGusyiC2y8zl3gK9etmF1Kdsj
-TYjKUCjLhdLTEKJZbtOTVAB6okaVhgWcqRmY5TFyDADiZ9lA4CQze28suVyrZZ0srHbqNZn1l7kP
-JOzHdiEoZa5X6AeIdUpWoNIFOqTmjZKILPPy4cHGYdtBxceb9w4aUUXCYWvcZCcXjFq32nQozZfk
-vQ==
------END CERTIFICATE-----
-
-TC TrustCenter Class 3 CA II
-============================
------BEGIN CERTIFICATE-----
-MIIEqjCCA5KgAwIBAgIOSkcAAQAC5aBd1j8AUb8wDQYJKoZIhvcNAQEFBQAwdjELMAkGA1UEBhMC
-REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNVBAsTGVRDIFRydXN0Q2VudGVy
-IENsYXNzIDMgQ0ExJTAjBgNVBAMTHFRDIFRydXN0Q2VudGVyIENsYXNzIDMgQ0EgSUkwHhcNMDYw
-MTEyMTQ0MTU3WhcNMjUxMjMxMjI1OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1
-c3RDZW50ZXIgR21iSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQTElMCMGA1UE
-AxMcVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
-AQoCggEBALTgu1G7OVyLBMVMeRwjhjEQY0NVJz/GRcekPewJDRoeIMJWHt4bNwcwIi9v8Qbxq63W
-yKthoy9DxLCyLfzDlml7forkzMA5EpBCYMnMNWju2l+QVl/NHE1bWEnrDgFPZPosPIlY2C8u4rBo
-6SI7dYnWRBpl8huXJh0obazovVkdKyT21oQDZogkAHhg8fir/gKya/si+zXmFtGt9i4S5Po1auUZ
-uV3bOx4a+9P/FRQI2AlqukWdFHlgfa9Aigdzs5OW03Q0jTo3Kd5c7PXuLjHCINy+8U9/I1LZW+Jk
-2ZyqBwi1Rb3R0DHBq1SfqdLDYmAD8bs5SpJKPQq5ncWg/jcCAwEAAaOCATQwggEwMA8GA1UdEwEB
-/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTUovyfs8PYA9NXXAek0CSnwPIA1DCB
-7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRydXN0Y2VudGVyLmRlL2NybC92Mi90
-Y19jbGFzc18zX2NhX0lJLmNybIaBn2xkYXA6Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBU
-cnVzdENlbnRlciUyMENsYXNzJTIwMyUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21i
-SCxPVT1yb290Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u
-TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEANmDkcPcGIEPZIxpC8vijsrlNirTzwppVMXzE
-O2eatN9NDoqTSheLG43KieHPOh6sHfGcMrSOWXaiQYUlN6AT0PV8TtXqluJucsG7Kv5sbviRmEb8
-yRtXW+rIGjs/sFGYPAfaLFkB2otE6OF0/ado3VS6g0bsyEa1+K+XwDsJHI/OcpY9M1ZwvJbL2NV9
-IJqDnxrcOfHFcqMRA/07QlIp2+gB95tejNaNhk4Z+rwcvsUhpYeeeC422wlxo3I0+GzjBgnyXlal
-092Y+tTmBvTwtiBjS+opvaqCZh77gaqnN60TGOaSw4HBM7uIHqHn4rS9MWwOUT1v+5ZWgOI2F9Hc
-5A==
------END CERTIFICATE-----
-
-TC TrustCenter Universal CA I
-=============================
------BEGIN CERTIFICATE-----
-MIID3TCCAsWgAwIBAgIOHaIAAQAC7LdggHiNtgYwDQYJKoZIhvcNAQEFBQAweTELMAkGA1UEBhMC
-REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNVBAsTG1RDIFRydXN0Q2VudGVy
-IFVuaXZlcnNhbCBDQTEmMCQGA1UEAxMdVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBIEkwHhcN
-MDYwMzIyMTU1NDI4WhcNMjUxMjMxMjI1OTU5WjB5MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMg
-VHJ1c3RDZW50ZXIgR21iSDEkMCIGA1UECxMbVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBMSYw
-JAYDVQQDEx1UQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0EgSTCCASIwDQYJKoZIhvcNAQEBBQAD
-ggEPADCCAQoCggEBAKR3I5ZEr5D0MacQ9CaHnPM42Q9e3s9B6DGtxnSRJJZ4Hgmgm5qVSkr1YnwC
-qMqs+1oEdjneX/H5s7/zA1hV0qq34wQi0fiU2iIIAI3TfCZdzHd55yx4Oagmcw6iXSVphU9VDprv
-xrlE4Vc93x9UIuVvZaozhDrzznq+VZeujRIPFDPiUHDDSYcTvFHe15gSWu86gzOSBnWLknwSaHtw
-ag+1m7Z3W0hZneTvWq3zwZ7U10VOylY0Ibw+F1tvdwxIAUMpsN0/lm7mlaoMwCC2/T42J5zjXM9O
-gdwZu5GQfezmlwQek8wiSdeXhrYTCjxDI3d+8NzmzSQfO4ObNDqDNOMCAwEAAaNjMGEwHwYDVR0j
-BBgwFoAUkqR1LKSevoFE63n8isWVpesQdXMwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
-AYYwHQYDVR0OBBYEFJKkdSyknr6BROt5/IrFlaXrEHVzMA0GCSqGSIb3DQEBBQUAA4IBAQAo0uCG
-1eb4e/CX3CJrO5UUVg8RMKWaTzqwOuAGy2X17caXJ/4l8lfmXpWMPmRgFVp/Lw0BxbFg/UU1z/Cy
-vwbZ71q+s2IhtNerNXxTPqYn8aEt2hojnczd7Dwtnic0XQ/CNnm8yUpiLe1r2X1BQ3y2qsrtYbE3
-ghUJGooWMNjsydZHcnhLEEYUjl8Or+zHL6sQ17bxbuyGssLoDZJz3KL0Dzq/YSMQiZxIQG5wALPT
-ujdEWBF6AmqI8Dc08BnprNRlc/ZpjGSUOnmFKbAWKwyCPwacx/0QK54PLLae4xW/2TYcuiUaUj0a
-7CIMHOCkoj3w6DnPgcB77V0fb8XQC9eY
------END CERTIFICATE-----
-
-Deutsche Telekom Root CA 2
-==========================
------BEGIN CERTIFICATE-----
-MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMT
-RGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEG
-A1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENBIDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5
-MjM1OTAwWjBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0G
-A1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBS
-b290IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEUha88EOQ5
-bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhCQN/Po7qCWWqSG6wcmtoI
-KyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1MjwrrFDa1sPeg5TKqAyZMg4ISFZbavva4VhY
-AUlfckE8FQYBjl2tqriTtM2e66foai1SNNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aK
-Se5TBY8ZTNXeWHmb0mocQqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTV
-jlsB9WoHtxa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAPBgNV
-HRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAlGRZrTlk5ynr
-E/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756AbrsptJh6sTtU6zkXR34ajgv8HzFZMQSy
-zhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpaIzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8
-rZ7/gFnkm0W09juwzTkZmDLl6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4G
-dyd1Lx+4ivn+xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU
-Cm26OWMohpLzGITY+9HPBVZkVw==
------END CERTIFICATE-----
-
-ComSign CA
-==========
------BEGIN CERTIFICATE-----
-MIIDkzCCAnugAwIBAgIQFBOWgxRVjOp7Y+X8NId3RDANBgkqhkiG9w0BAQUFADA0MRMwEQYDVQQD
-EwpDb21TaWduIENBMRAwDgYDVQQKEwdDb21TaWduMQswCQYDVQQGEwJJTDAeFw0wNDAzMjQxMTMy
-MThaFw0yOTAzMTkxNTAyMThaMDQxEzARBgNVBAMTCkNvbVNpZ24gQ0ExEDAOBgNVBAoTB0NvbVNp
-Z24xCzAJBgNVBAYTAklMMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8ORUaSvTx49q
-ROR+WCf4C9DklBKK8Rs4OC8fMZwG1Cyn3gsqrhqg455qv588x26i+YtkbDqthVVRVKU4VbirgwTy
-P2Q298CNQ0NqZtH3FyrV7zb6MBBC11PN+fozc0yz6YQgitZBJzXkOPqUm7h65HkfM/sb2CEJKHxN
-GGleZIp6GZPKfuzzcuc3B1hZKKxC+cX/zT/npfo4sdAMx9lSGlPWgcxCejVb7Us6eva1jsz/D3zk
-YDaHL63woSV9/9JLEYhwVKZBqGdTUkJe5DSe5L6j7KpiXd3DTKaCQeQzC6zJMw9kglcq/QytNuEM
-rkvF7zuZ2SOzW120V+x0cAwqTwIDAQABo4GgMIGdMAwGA1UdEwQFMAMBAf8wPQYDVR0fBDYwNDAy
-oDCgLoYsaHR0cDovL2ZlZGlyLmNvbXNpZ24uY28uaWwvY3JsL0NvbVNpZ25DQS5jcmwwDgYDVR0P
-AQH/BAQDAgGGMB8GA1UdIwQYMBaAFEsBmz5WGmU2dst7l6qSBe4y5ygxMB0GA1UdDgQWBBRLAZs+
-VhplNnbLe5eqkgXuMucoMTANBgkqhkiG9w0BAQUFAAOCAQEA0Nmlfv4pYEWdfoPPbrxHbvUanlR2
-QnG0PFg/LUAlQvaBnPGJEMgOqnhPOAlXsDzACPw1jvFIUY0McXS6hMTXcpuEfDhOZAYnKuGntewI
-mbQKDdSFc8gS4TXt8QUxHXOZDOuWyt3T5oWq8Ir7dcHyCTxlZWTzTNity4hp8+SDtwy9F1qWF8pb
-/627HOkthIDYIb6FUtnUdLlphbpN7Sgy6/lhSuTENh4Z3G+EER+V9YMoGKgzkkMn3V0TBEVPh9VG
-zT2ouvDzuFYkRes3x+F2T3I5GN9+dHLHcy056mDmrRGiVod7w2ia/viMcKjfZTL0pECMocJEAw6U
-AGegcQCCSA==
------END CERTIFICATE-----
-
-ComSign Secured CA
-==================
------BEGIN CERTIFICATE-----
-MIIDqzCCApOgAwIBAgIRAMcoRwmzuGxFjB36JPU2TukwDQYJKoZIhvcNAQEFBQAwPDEbMBkGA1UE
-AxMSQ29tU2lnbiBTZWN1cmVkIENBMRAwDgYDVQQKEwdDb21TaWduMQswCQYDVQQGEwJJTDAeFw0w
-NDAzMjQxMTM3MjBaFw0yOTAzMTYxNTA0NTZaMDwxGzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBD
-QTEQMA4GA1UEChMHQ29tU2lnbjELMAkGA1UEBhMCSUwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
-ggEKAoIBAQDGtWhfHZQVw6QIVS3joFd67+l0Kru5fFdJGhFeTymHDEjWaueP1H5XJLkGieQcPOqs
-49ohgHMhCu95mGwfCP+hUH3ymBvJVG8+pSjsIQQPRbsHPaHA+iqYHU4Gk/v1iDurX8sWv+bznkqH
-7Rnqwp9D5PGBpX8QTz7RSmKtUxvLg/8HZaWSLWapW7ha9B20IZFKF3ueMv5WJDmyVIRD9YTC2LxB
-kMyd1mja6YJQqTtoz7VdApRgFrFD2UNd3V2Hbuq7s8lr9gOUCXDeFhF6K+h2j0kQmHe5Y1yLM5d1
-9guMsqtb3nQgJT/j8xH5h2iGNXHDHYwt6+UarA9z1YJZQIDTAgMBAAGjgacwgaQwDAYDVR0TBAUw
-AwEB/zBEBgNVHR8EPTA7MDmgN6A1hjNodHRwOi8vZmVkaXIuY29tc2lnbi5jby5pbC9jcmwvQ29t
-U2lnblNlY3VyZWRDQS5jcmwwDgYDVR0PAQH/BAQDAgGGMB8GA1UdIwQYMBaAFMFL7XC29z58ADsA
-j8c+DkWfHl3sMB0GA1UdDgQWBBTBS+1wtvc+fAA7AI/HPg5Fnx5d7DANBgkqhkiG9w0BAQUFAAOC
-AQEAFs/ukhNQq3sUnjO2QiBq1BW9Cav8cujvR3qQrFHBZE7piL1DRYHjZiM/EoZNGeQFsOY3wo3a
-BijJD4mkU6l1P7CW+6tMM1X5eCZGbxs2mPtCdsGCuY7e+0X5YxtiOzkGynd6qDwJz2w2PQ8KRUtp
-FhpFfTMDZflScZAmlaxMDPWLkz/MdXSFmLr/YnpNH4n+rr2UAJm/EaXc4HnFFgt9AmEd6oX5AhVP
-51qJThRv4zdLhfXBPGHg/QVBspJ/wx2g0K5SZGBrGMYmnNj1ZOQ2GmKfig8+/21OGVZOIJFsnzQz
-OjRXUDpvgV4GxvU+fE6OK85lBi5d0ipTdF7Tbieejw==
------END CERTIFICATE-----
-
-Cybertrust Global Root
-======================
------BEGIN CERTIFICATE-----
-MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYGA1UEChMPQ3li
-ZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBSb290MB4XDTA2MTIxNTA4
-MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQD
-ExZDeWJlcnRydXN0IEdsb2JhbCBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
-+Mi8vRRQZhP/8NN57CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW
-0ozSJ8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2yHLtgwEZL
-AfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iPt3sMpTjr3kfb1V05/Iin
-89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNzFtApD0mpSPCzqrdsxacwOUBdrsTiXSZT
-8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAYXSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAP
-BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2
-MDSgMqAwhi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3JsMB8G
-A1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUAA4IBAQBW7wojoFRO
-lZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMjWqd8BfP9IjsO0QbE2zZMcwSO5bAi
-5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUxXOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2
-hO0j9n0Hq0V+09+zv+mKts2oomcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+T
-X3EJIrduPuocA06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW
-WL1WMRJOEcgh4LMRkWXbtKaIOM5V
------END CERTIFICATE-----
-
-ePKI Root Certification Authority
-=================================
------BEGIN CERTIFICATE-----
-MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQG
-EwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0ZC4xKjAoBgNVBAsMIWVQS0kg
-Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMx
-MjdaMF4xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEq
-MCgGA1UECwwhZVBLSSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0B
-AQEFAAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAHSyZbCUNs
-IZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAhijHyl3SJCRImHJ7K2RKi
-lTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3XDZoTM1PRYfl61dd4s5oz9wCGzh1NlDiv
-qOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX
-12ruOzjjK9SXDrkb5wdJfzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0O
-WQqraffAsgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uUWH1+
-ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLSnT0IFaUQAS2zMnao
-lQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pHdmX2Os+PYhcZewoozRrSgx4hxyy/
-vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJipNiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXi
-Zo1jDiVN1Rmy5nk3pyKdVDECAwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/Qkqi
-MAwGA1UdEwQFMAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH
-ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGBuvl2ICO1J2B0
-1GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6YlPwZpVnPDimZI+ymBV3QGypzq
-KOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkPJXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdV
-xrsStZf0X4OFunHB2WyBEXYKCrC/gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEP
-NXubrjlpC2JgQCA2j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+r
-GNm65ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUBo2M3IUxE
-xJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS/jQ6fbjpKdx2qcgw+BRx
-gMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2zGp1iro2C6pSe3VkQw63d4k3jMdXH7Ojy
-sP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTEW9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmOD
-BCEIZ43ygknQW/2xzQ+DhNQ+IIX3Sj0rnP0qCglN6oH4EZw=
------END CERTIFICATE-----
-
-T\xc3\x9c\x42\xC4\xB0TAK UEKAE K\xC3\xB6k Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 - S\xC3\xBCr\xC3\xBCm 3
-=============================================================================================================================
------BEGIN CERTIFICATE-----
-MIIFFzCCA/+gAwIBAgIBETANBgkqhkiG9w0BAQUFADCCASsxCzAJBgNVBAYTAlRSMRgwFgYDVQQH
-DA9HZWJ6ZSAtIEtvY2FlbGkxRzBFBgNVBAoMPlTDvHJraXllIEJpbGltc2VsIHZlIFRla25vbG9q
-aWsgQXJhxZ90xLFybWEgS3VydW11IC0gVMOcQsSwVEFLMUgwRgYDVQQLDD9VbHVzYWwgRWxla3Ry
-b25payB2ZSBLcmlwdG9sb2ppIEFyYcWfdMSxcm1hIEVuc3RpdMO8c8O8IC0gVUVLQUUxIzAhBgNV
-BAsMGkthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppMUowSAYDVQQDDEFUw5xCxLBUQUsgVUVLQUUg
-S8O2ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSAtIFPDvHLDvG0gMzAeFw0wNzA4
-MjQxMTM3MDdaFw0xNzA4MjExMTM3MDdaMIIBKzELMAkGA1UEBhMCVFIxGDAWBgNVBAcMD0dlYnpl
-IC0gS29jYWVsaTFHMEUGA1UECgw+VMO8cmtpeWUgQmlsaW1zZWwgdmUgVGVrbm9sb2ppayBBcmHF
-n3TEsXJtYSBLdXJ1bXUgLSBUw5xCxLBUQUsxSDBGBgNVBAsMP1VsdXNhbCBFbGVrdHJvbmlrIHZl
-IEtyaXB0b2xvamkgQXJhxZ90xLFybWEgRW5zdGl0w7xzw7wgLSBVRUtBRTEjMCEGA1UECwwaS2Ft
-dSBTZXJ0aWZpa2FzeW9uIE1lcmtlemkxSjBIBgNVBAMMQVTDnELEsFRBSyBVRUtBRSBLw7ZrIFNl
-cnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIC0gU8O8csO8bSAzMIIBIjANBgkqhkiG9w0B
-AQEFAAOCAQ8AMIIBCgKCAQEAim1L/xCIOsP2fpTo6iBkcK4hgb46ezzb8R1Sf1n68yJMlaCQvEhO
-Eav7t7WNeoMojCZG2E6VQIdhn8WebYGHV2yKO7Rm6sxA/OOqbLLLAdsyv9Lrhc+hDVXDWzhXcLh1
-xnnRFDDtG1hba+818qEhTsXOfJlfbLm4IpNQp81McGq+agV/E5wrHur+R84EpW+sky58K5+eeROR
-6Oqeyjh1jmKwlZMq5d/pXpduIF9fhHpEORlAHLpVK/swsoHvhOPc7Jg4OQOFCKlUAwUp8MmPi+oL
-hmUZEdPpCSPeaJMDyTYcIW7OjGbxmTDY17PDHfiBLqi9ggtm/oLL4eAagsNAgQIDAQABo0IwQDAd
-BgNVHQ4EFgQUvYiHyY/2pAoLquvF/pEjnatKijIwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
-MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAB18+kmPNOm3JpIWmgV050vQbTlswyb2zrgxvMTfvCr4
-N5EY3ATIZJkrGG2AA1nJrvhY0D7twyOfaTyGOBye79oneNGEN3GKPEs5z35FBtYt2IpNeBLWrcLT
-y9LQQfMmNkqblWwM7uXRQydmwYj3erMgbOqwaSvHIOgMA8RBBZniP+Rr+KCGgceExh/VS4ESshYh
-LBOhgLJeDEoTniDYYkCrkOpkSi+sDQESeUWoL4cZaMjihccwsnX5OD+ywJO0a+IDRM5noN+J1q2M
-dqMTw5RhK2vZbMEHCiIHhWyFJEapvj+LeISCfiQMnf2BN+MlqO02TpUsyZyQ2uypQjyttgI=
------END CERTIFICATE-----
-
-Buypass Class 2 CA 1
-====================
------BEGIN CERTIFICATE-----
-MIIDUzCCAjugAwIBAgIBATANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU
-QnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3MgQ2xhc3MgMiBDQSAxMB4XDTA2
-MTAxMzEwMjUwOVoXDTE2MTAxMzEwMjUwOVowSzELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBh
-c3MgQVMtOTgzMTYzMzI3MR0wGwYDVQQDDBRCdXlwYXNzIENsYXNzIDIgQ0EgMTCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBAIs8B0XY9t/mx8q6jUPFR42wWsE425KEHK8T1A9vNkYgxC7M
-cXA0ojTTNy7Y3Tp3L8DrKehc0rWpkTSHIln+zNvnma+WwajHQN2lFYxuyHyXA8vmIPLXl18xoS83
-0r7uvqmtqEyeIWZDO6i88wmjONVZJMHCR3axiFyCO7srpgTXjAePzdVBHfCuuCkslFJgNJQ72uA4
-0Z0zPhX0kzLFANq1KWYOOngPIVJfAuWSeyXTkh4vFZ2B5J2O6O+JzhRMVB0cgRJNcKi+EAUXfh/R
-uFdV7c27UsKwHnjCTTZoy1YmwVLBvXb3WNVyfh9EdrsAiR0WnVE1703CVu9r4Iw7DekCAwEAAaNC
-MEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUP42aWYv8e3uco684sDntkHGA1sgwDgYDVR0P
-AQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQAVGn4TirnoB6NLJzKyQJHyIdFkhb5jatLPgcIV
-1Xp+DCmsNx4cfHZSldq1fyOhKXdlyTKdqC5Wq2B2zha0jX94wNWZUYN/Xtm+DKhQ7SLHrQVMdvvt
-7h5HZPb3J31cKA9FxVxiXqaakZG3Uxcu3K1gnZZkOb1naLKuBctN518fV4bVIJwo+28TOPX2EZL2
-fZleHwzoq0QkKXJAPTZSr4xYkHPB7GEseaHsh7U/2k3ZIQAw3pDaDtMaSKk+hQsUi4y8QZ5q9w5w
-wDX3OaJdZtB7WZ+oRxKaJyOkLY4ng5IgodcVf/EuGO70SH8vf/GhGLWhC5SgYiAynB321O+/TIho
------END CERTIFICATE-----
-
-Buypass Class 3 CA 1
-====================
------BEGIN CERTIFICATE-----
-MIIDUzCCAjugAwIBAgIBAjANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU
-QnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3MgQ2xhc3MgMyBDQSAxMB4XDTA1
-MDUwOTE0MTMwM1oXDTE1MDUwOTE0MTMwM1owSzELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBh
-c3MgQVMtOTgzMTYzMzI3MR0wGwYDVQQDDBRCdXlwYXNzIENsYXNzIDMgQ0EgMTCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBAKSO13TZKWTeXx+HgJHqTjnmGcZEC4DVC69TB4sSveZn8AKx
-ifZgisRbsELRwCGoy+Gb72RRtqfPFfV0gGgEkKBYouZ0plNTVUhjP5JW3SROjvi6K//zNIqeKNc0
-n6wv1g/xpC+9UrJJhW05NfBEMJNGJPO251P7vGGvqaMU+8IXF4Rs4HyI+MkcVyzwPX6UvCWThOia
-AJpFBUJXgPROztmuOfbIUxAMZTpHe2DC1vqRycZxbL2RhzyRhkmr8w+gbCZ2Xhysm3HljbybIR6c
-1jh+JIAVMYKWsUnTYjdbiAwKYjT+p0h+mbEwi5A3lRyoH6UsjfRVyNvdWQrCrXig9IsCAwEAAaNC
-MEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUOBTmyPCppAP0Tj4io1vy1uCtQHQwDgYDVR0P
-AQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQABZ6OMySU9E2NdFm/soT4JXJEVKirZgCFPBdy7
-pYmrEzMqnji3jG8CcmPHc3ceCQa6Oyh7pEfJYWsICCD8igWKH7y6xsL+z27sEzNxZy5p+qksP2bA
-EllNC1QCkoS72xLvg3BweMhT+t/Gxv/ciC8HwEmdMldg0/L2mSlf56oBzKwzqBwKu5HEA6BvtjT5
-htOzdlSY9EqBs1OdTUDs5XcTRa9bqh/YL0yCe/4qxFi7T/ye/QNlGioOw6UgFpRreaaiErS7GqQj
-el/wroQk5PMr+4okoyeYZdowdXb8GZHo2+ubPzK/QJcHJrrM85SFSnonk8+QQtS4Wxam58tAA915
------END CERTIFICATE-----
-
-EBG Elektronik Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1
-==========================================================================
------BEGIN CERTIFICATE-----
-MIIF5zCCA8+gAwIBAgIITK9zQhyOdAIwDQYJKoZIhvcNAQEFBQAwgYAxODA2BgNVBAMML0VCRyBF
-bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMTcwNQYDVQQKDC5FQkcg
-QmlsacWfaW0gVGVrbm9sb2ppbGVyaSB2ZSBIaXptZXRsZXJpIEEuxZ4uMQswCQYDVQQGEwJUUjAe
-Fw0wNjA4MTcwMDIxMDlaFw0xNjA4MTQwMDMxMDlaMIGAMTgwNgYDVQQDDC9FQkcgRWxla3Ryb25p
-ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTE3MDUGA1UECgwuRUJHIEJpbGnFn2lt
-IFRla25vbG9qaWxlcmkgdmUgSGl6bWV0bGVyaSBBLsWeLjELMAkGA1UEBhMCVFIwggIiMA0GCSqG
-SIb3DQEBAQUAA4ICDwAwggIKAoICAQDuoIRh0DpqZhAy2DE4f6en5f2h4fuXd7hxlugTlkaDT7by
-X3JWbhNgpQGR4lvFzVcfd2NR/y8927k/qqk153nQ9dAktiHq6yOU/im/+4mRDGSaBUorzAzu8T2b
-gmmkTPiab+ci2hC6X5L8GCcKqKpE+i4stPtGmggDg3KriORqcsnlZR9uKg+ds+g75AxuetpX/dfr
-eYteIAbTdgtsApWjluTLdlHRKJ2hGvxEok3MenaoDT2/F08iiFD9rrbskFBKW5+VQarKD7JK/oCZ
-TqNGFav4c0JqwmZ2sQomFd2TkuzbqV9UIlKRcF0T6kjsbgNs2d1s/OsNA/+mgxKb8amTD8UmTDGy
-Y5lhcucqZJnSuOl14nypqZoaqsNW2xCaPINStnuWt6yHd6i58mcLlEOzrz5z+kI2sSXFCjEmN1Zn
-uqMLfdb3ic1nobc6HmZP9qBVFCVMLDMNpkGMvQQxahByCp0OLna9XvNRiYuoP1Vzv9s6xiQFlpJI
-qkuNKgPlV5EQ9GooFW5Hd4RcUXSfGenmHmMWOeMRFeNYGkS9y8RsZteEBt8w9DeiQyJ50hBs37vm
-ExH8nYQKE3vwO9D8owrXieqWfo1IhR5kX9tUoqzVegJ5a9KK8GfaZXINFHDk6Y54jzJ0fFfy1tb0
-Nokb+Clsi7n2l9GkLqq+CxnCRelwXQIDAJ3Zo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB
-/wQEAwIBBjAdBgNVHQ4EFgQU587GT/wWZ5b6SqMHwQSny2re2kcwHwYDVR0jBBgwFoAU587GT/wW
-Z5b6SqMHwQSny2re2kcwDQYJKoZIhvcNAQEFBQADggIBAJuYml2+8ygjdsZs93/mQJ7ANtyVDR2t
-FcU22NU57/IeIl6zgrRdu0waypIN30ckHrMk2pGI6YNw3ZPX6bqz3xZaPt7gyPvT/Wwp+BVGoGgm
-zJNSroIBk5DKd8pNSe/iWtkqvTDOTLKBtjDOWU/aWR1qeqRFsIImgYZ29fUQALjuswnoT4cCB64k
-XPBfrAowzIpAoHMEwfuJJPaaHFy3PApnNgUIMbOv2AFoKuB4j3TeuFGkjGwgPaL7s9QJ/XvCgKqT
-bCmYIai7FvOpEl90tYeY8pUm3zTvilORiF0alKM/fCL414i6poyWqD1SNGKfAB5UVUJnxk1Gj7sU
-RT0KlhaOEKGXmdXTMIXM3rRyt7yKPBgpaP3ccQfuJDlq+u2lrDgv+R4QDgZxGhBM/nV+/x5XOULK
-1+EVoVZVWRvRo68R2E7DpSvvkL/A7IITW43WciyTTo9qKd+FPNMN4KIYEsxVL0e3p5sC/kH2iExt
-2qkBR4NkJ2IQgtYSe14DHzSpyZH+r11thie3I6p1GMog57AP14kOpmciY/SDQSsGS7tY1dHXt7kQ
-Y9iJSrSq3RZj9W6+YKH47ejWkE8axsWgKdOnIaj1Wjz3x0miIZpKlVIglnKaZsv30oZDfCK+lvm9
-AahH3eU7QPl1K5srRmSGjR70j/sHd9DqSaIcjVIUpgqT
------END CERTIFICATE-----
-
-certSIGN ROOT CA
-================
------BEGIN CERTIFICATE-----
-MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYTAlJPMREwDwYD
-VQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTAeFw0wNjA3MDQxNzIwMDRa
-Fw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UE
-CxMQY2VydFNJR04gUk9PVCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7I
-JUqOtdu0KBuqV5Do0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHH
-rfAQUySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5dRdY4zTW2
-ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQOA7+j0xbm0bqQfWwCHTD
-0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwvJoIQ4uNllAoEwF73XVv4EOLQunpL+943
-AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B
-Af8EBAMCAcYwHQYDVR0OBBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IB
-AQA+0hyJLjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecYMnQ8
-SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ44gx+FkagQnIl6Z0
-x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6IJd1hJyMctTEHBDa0GpC9oHRxUIlt
-vBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNwi/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7Nz
-TogVZ96edhBiIL5VaZVDADlN9u6wWk5JRFRYX0KD
------END CERTIFICATE-----
-
-CNNIC ROOT
-==========
------BEGIN CERTIFICATE-----
-MIIDVTCCAj2gAwIBAgIESTMAATANBgkqhkiG9w0BAQUFADAyMQswCQYDVQQGEwJDTjEOMAwGA1UE
-ChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwHhcNMDcwNDE2MDcwOTE0WhcNMjcwNDE2MDcw
-OTE0WjAyMQswCQYDVQQGEwJDTjEOMAwGA1UEChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1Qw
-ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDTNfc/c3et6FtzF8LRb+1VvG7q6KR5smzD
-o+/hn7E7SIX1mlwhIhAsxYLO2uOabjfhhyzcuQxauohV3/2q2x8x6gHx3zkBwRP9SFIhxFXf2tiz
-VHa6dLG3fdfA6PZZxU3Iva0fFNrfWEQlMhkqx35+jq44sDB7R3IJMfAw28Mbdim7aXZOV/kbZKKT
-VrdvmW7bCgScEeOAH8tjlBAKqeFkgjH5jCftppkA9nCTGPihNIaj3XrCGHn2emU1z5DrvTOTn1Or
-czvmmzQgLx3vqR1jGqCA2wMv+SYahtKNu6m+UjqHZ0gNv7Sg2Ca+I19zN38m5pIEo3/PIKe38zrK
-y5nLAgMBAAGjczBxMBEGCWCGSAGG+EIBAQQEAwIABzAfBgNVHSMEGDAWgBRl8jGtKvf33VKWCscC
-wQ7vptU7ETAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIB/jAdBgNVHQ4EFgQUZfIxrSr3991S
-lgrHAsEO76bVOxEwDQYJKoZIhvcNAQEFBQADggEBAEs17szkrr/Dbq2flTtLP1se31cpolnKOOK5
-Gv+e5m4y3R6u6jW39ZORTtpC4cMXYFDy0VwmuYK36m3knITnA3kXr5g9lNvHugDnuL8BV8F3RTIM
-O/G0HAiw/VGgod2aHRM2mm23xzy54cXZF/qD1T0VoDy7HgviyJA/qIYM/PmLXoXLT1tLYhFHxUV8
-BS9BsZ4QaRuZluBVeftOhpm4lNqGOGqTo+fLbuXf6iFViZx9fX+Y9QCJ7uOEwFyWtcVG6kbghVW2
-G8kS1sHNzYDzAgE8yGnLRUhj2JTQ7IUOO04RZfSCjKY9ri4ilAnIXOo8gV0WKgOXFlUJ24pBgp5m
-mxE=
------END CERTIFICATE-----
-
-ApplicationCA - Japanese Government
-===================================
------BEGIN CERTIFICATE-----
-MIIDoDCCAoigAwIBAgIBMTANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJKUDEcMBoGA1UEChMT
-SmFwYW5lc2UgR292ZXJubWVudDEWMBQGA1UECxMNQXBwbGljYXRpb25DQTAeFw0wNzEyMTIxNTAw
-MDBaFw0xNzEyMTIxNTAwMDBaMEMxCzAJBgNVBAYTAkpQMRwwGgYDVQQKExNKYXBhbmVzZSBHb3Zl
-cm5tZW50MRYwFAYDVQQLEw1BcHBsaWNhdGlvbkNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
-CgKCAQEAp23gdE6Hj6UG3mii24aZS2QNcfAKBZuOquHMLtJqO8F6tJdhjYq+xpqcBrSGUeQ3DnR4
-fl+Kf5Sk10cI/VBaVuRorChzoHvpfxiSQE8tnfWuREhzNgaeZCw7NCPbXCbkcXmP1G55IrmTwcrN
-wVbtiGrXoDkhBFcsovW8R0FPXjQilbUfKW1eSvNNcr5BViCH/OlQR9cwFO5cjFW6WY2H/CPek9AE
-jP3vbb3QesmlOmpyM8ZKDQUXKi17safY1vC+9D/qDihtQWEjdnjDuGWk81quzMKq2edY3rZ+nYVu
-nyoKb58DKTCXKB28t89UKU5RMfkntigm/qJj5kEW8DOYRwIDAQABo4GeMIGbMB0GA1UdDgQWBBRU
-WssmP3HMlEYNllPqa0jQk/5CdTAOBgNVHQ8BAf8EBAMCAQYwWQYDVR0RBFIwUKROMEwxCzAJBgNV
-BAYTAkpQMRgwFgYDVQQKDA/ml6XmnKzlm73mlL/lupwxIzAhBgNVBAsMGuOCouODl+ODquOCseOD
-vOOCt+ODp+ODs0NBMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADlqRHZ3ODrs
-o2dGD/mLBqj7apAxzn7s2tGJfHrrLgy9mTLnsCTWw//1sogJhyzjVOGjprIIC8CFqMjSnHH2HZ9g
-/DgzE+Ge3Atf2hZQKXsvcJEPmbo0NI2VdMV+eKlmXb3KIXdCEKxmJj3ekav9FfBv7WxfEPjzFvYD
-io+nEhEMy/0/ecGc/WLuo89UDNErXxc+4z6/wCs+CZv+iKZ+tJIX/COUgb1up8WMwusRRdv4QcmW
-dupwX3kSa+SjB1oF7ydJzyGfikwJcGapJsErEU4z0g781mzSDjJkaP+tBXhfAx2o45CsJOAPQKdL
-rosot4LKGAfmt1t06SAZf7IbiVQ=
------END CERTIFICATE-----
-
-GeoTrust Primary Certification Authority - G3
-=============================================
------BEGIN CERTIFICATE-----
-MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UE
-BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA4IEdlb1RydXN0
-IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFy
-eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIz
-NTk1OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAo
-YykgMjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMT
-LUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5j
-K/BGvESyiaHAKAxJcCGVn2TAppMSAmUmhsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdE
-c5IiaacDiGydY8hS2pgn5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3C
-IShwiP/WJmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exALDmKu
-dlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZChuOl1UcCAwEAAaNC
-MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMR5yo6hTgMdHNxr
-2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IBAQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9
-cr5HqQ6XErhK8WTTOd8lNNTBzU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbE
-Ap7aDHdlDkQNkv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD
-AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUHSJsMC8tJP33s
-t/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2Gspki4cErx5z481+oghLrGREt
------END CERTIFICATE-----
-
-thawte Primary Root CA - G2
-===========================
------BEGIN CERTIFICATE-----
-MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDELMAkGA1UEBhMC
-VVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMpIDIwMDcgdGhhd3RlLCBJbmMu
-IC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3Qg
-Q0EgLSBHMjAeFw0wNzExMDUwMDAwMDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEV
-MBMGA1UEChMMdGhhd3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBG
-b3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAt
-IEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/BebfowJPDQfGAFG6DAJS
-LSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6papu+7qzcMBniKI11KOasf2twu8x+qi5
-8/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU
-mtgAMADna3+FGO6Lts6KDPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUN
-G4k8VIZ3KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41oxXZ3K
-rr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg==
------END CERTIFICATE-----
-
-thawte Primary Root CA - G3
-===========================
------BEGIN CERTIFICATE-----
-MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCBrjELMAkGA1UE
-BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2
-aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv
-cml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0w
-ODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh
-d3RlLCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMTgwNgYD
-VQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIG
-A1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
-MIIBCgKCAQEAsr8nLPvb2FvdeHsbnndmgcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2At
-P0LMqmsywCPLLEHd5N/8YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC
-+BsUa0Lfb1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS99irY
-7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2SzhkGcuYMXDhpxwTW
-vGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUkOQIDAQABo0IwQDAPBgNVHRMBAf8E
-BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJ
-KoZIhvcNAQELBQADggEBABpA2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweK
-A3rD6z8KLFIWoCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu
-t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7cKUGRIjxpp7sC
-8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fMm7v/OeZWYdMKp8RcTGB7BXcm
-er/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZuMdRAGmI0Nj81Aa6sY6A=
------END CERTIFICATE-----
-
-GeoTrust Primary Certification Authority - G2
-=============================================
------BEGIN CERTIFICATE-----
-MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDELMAkGA1UEBhMC
-VVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA3IEdlb1RydXN0IElu
-Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBD
-ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1
-OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg
-MjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMTLUdl
-b1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjB2MBAGByqGSM49AgEG
-BSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcLSo17VDs6bl8VAsBQps8lL33KSLjHUGMc
-KiEIfJo22Av+0SbFWDEwKCXzXV2juLaltJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYD
-VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+
-EVXVMAoGCCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGTqQ7m
-ndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBuczrD6ogRLQy7rQkgu2
-npaqBA+K
------END CERTIFICATE-----
-
-VeriSign Universal Root Certification Authority
-===============================================
------BEGIN CERTIFICATE-----
-MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCBvTELMAkGA1UE
-BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO
-ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk
-IHVzZSBvbmx5MTgwNgYDVQQDEy9WZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9u
-IEF1dGhvcml0eTAeFw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJV
-UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
-cmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
-IG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0
-aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj
-1mCOkdeQmIN65lgZOIzF9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGP
-MiJhgsWHH26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+HLL72
-9fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN/BMReYTtXlT2NJ8I
-AfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPTrJ9VAMf2CGqUuV/c4DPxhGD5WycR
-tPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0G
-CCsGAQUFBwEMBGEwX6FdoFswWTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2O
-a8PPgGrUSBgsexkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud
-DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4sAPmLGd75JR3
-Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+seQxIcaBlVZaDrHC1LGmWazx
-Y8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTx
-P/jgdFcrGJ2BtMQo2pSXpXDrrB2+BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+P
-wGZsY6rp2aQW9IHRlRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4
-mJO37M2CYfE45k+XmCpajQ==
------END CERTIFICATE-----
-
-VeriSign Class 3 Public Primary Certification Authority - G4
-============================================================
------BEGIN CERTIFICATE-----
-MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjELMAkGA1UEBhMC
-VVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3
-b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVz
-ZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmlj
-YXRpb24gQXV0aG9yaXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjEL
-MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBU
-cnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRo
-b3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5
-IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8
-Utpkmw4tXNherJI9/gHmGUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGz
-rl0Bp3vefLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUwAwEB
-/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEw
-HzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24u
-Y29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMWkf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMD
-A2gAMGUCMGYhDBgmYFo4e1ZC4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIx
-AJw9SDkjOVgaFRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA==
------END CERTIFICATE-----
-
-NetLock Arany (Class Gold) Főtanúsítvány
-============================================
------BEGIN CERTIFICATE-----
-MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQGEwJIVTERMA8G
-A1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3MDUGA1UECwwuVGFuw7pzw610
-dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBB
-cmFueSAoQ2xhc3MgR29sZCkgRsWRdGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgx
-MjA2MTUwODIxWjCBpzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxO
-ZXRMb2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlmaWNhdGlv
-biBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNzIEdvbGQpIEbFkXRhbsO6
-c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCRec75LbRTDofTjl5Bu
-0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrTlF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw
-/HpYzY6b7cNGbIRwXdrzAZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAk
-H3B5r9s5VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRGILdw
-fzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2BJtr+UBdADTHLpl1
-neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAGAQH/AgEEMA4GA1UdDwEB/wQEAwIB
-BjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2MU9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwW
-qZw8UQCgwBEIBaeZ5m8BiFRhbvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTta
-YtOUZcTh5m2C+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC
-bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2FuLjbvrW5Kfna
-NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu
-dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E=
------END CERTIFICATE-----
-
-Staat der Nederlanden Root CA - G2
-==================================
------BEGIN CERTIFICATE-----
-MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE
-CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFhdCBkZXIgTmVkZXJsYW5kZW4g
-Um9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oXDTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMC
-TkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5l
-ZGVybGFuZGVuIFJvb3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ
-5291qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8SpuOUfiUtn
-vWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPUZ5uW6M7XxgpT0GtJlvOj
-CwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvEpMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiil
-e7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCR
-OME4HYYEhLoaJXhena/MUGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpI
-CT0ugpTNGmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy5V65
-48r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv6q012iDTiIJh8BIi
-trzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEKeN5KzlW/HdXZt1bv8Hb/C3m1r737
-qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMB
-AAGjgZcwgZQwDwYDVR0TAQH/BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcC
-ARYxaHR0cDovL3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV
-HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqGSIb3DQEBCwUA
-A4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLySCZa59sCrI2AGeYwRTlHSeYAz
-+51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwj
-f/ST7ZwaUb7dRUG/kSS0H4zpX897IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaN
-kqbG9AclVMwWVxJKgnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfk
-CpYL+63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxLvJxxcypF
-URmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkmbEgeqmiSBeGCc1qb3Adb
-CG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvkN1trSt8sV4pAWja63XVECDdCcAz+3F4h
-oKOKwJCcaNpQ5kUQR3i2TtJlycM33+FCY7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoV
-IPVVYpbtbZNQvOSqeK3Zywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm
-66+KAQ==
------END CERTIFICATE-----
-
-CA Disig
-========
------BEGIN CERTIFICATE-----
-MIIEDzCCAvegAwIBAgIBATANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJTSzETMBEGA1UEBxMK
-QnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwHhcNMDYw
-MzIyMDEzOTM0WhcNMTYwMzIyMDEzOTM0WjBKMQswCQYDVQQGEwJTSzETMBEGA1UEBxMKQnJhdGlz
-bGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwggEiMA0GCSqGSIb3
-DQEBAQUAA4IBDwAwggEKAoIBAQCS9jHBfYj9mQGp2HvycXXxMcbzdWb6UShGhJd4NLxs/LxFWYgm
-GErENx+hSkS943EE9UQX4j/8SFhvXJ56CbpRNyIjZkMhsDxkovhqFQ4/61HhVKndBpnXmjxUizkD
-Pw/Fzsbrg3ICqB9x8y34dQjbYkzo+s7552oftms1grrijxaSfQUMbEYDXcDtab86wYqg6I7ZuUUo
-hwjstMoVvoLdtUSLLa2GDGhibYVW8qwUYzrG0ZmsNHhWS8+2rT+MitcE5eN4TPWGqvWP+j1scaMt
-ymfraHtuM6kMgiioTGohQBUgDCZbg8KpFhXAJIJdKxatymP2dACw30PEEGBWZ2NFAgMBAAGjgf8w
-gfwwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUjbJJaJ1yCCW5wCf1UJNWSEZx+Y8wDgYDVR0P
-AQH/BAQDAgEGMDYGA1UdEQQvMC2BE2Nhb3BlcmF0b3JAZGlzaWcuc2uGFmh0dHA6Ly93d3cuZGlz
-aWcuc2svY2EwZgYDVR0fBF8wXTAtoCugKYYnaHR0cDovL3d3dy5kaXNpZy5zay9jYS9jcmwvY2Ff
-ZGlzaWcuY3JsMCygKqAohiZodHRwOi8vY2EuZGlzaWcuc2svY2EvY3JsL2NhX2Rpc2lnLmNybDAa
-BgNVHSAEEzARMA8GDSuBHpGT5goAAAABAQEwDQYJKoZIhvcNAQEFBQADggEBAF00dGFMrzvY/59t
-WDYcPQuBDRIrRhCA/ec8J9B6yKm2fnQwM6M6int0wHl5QpNt/7EpFIKrIYwvF/k/Ji/1WcbvgAa3
-mkkp7M5+cTxqEEHA9tOasnxakZzArFvITV734VP/Q3f8nktnbNfzg9Gg4H8l37iYC5oyOGwwoPP/
-CBUz91BKez6jPiCp3C9WgArtQVCwyfTssuMmRAAOb54GvCKWU3BlxFAKRmukLyeBEicTXxChds6K
-ezfqwzlhA5WYOudsiCUI/HloDYd9Yvi0X/vF2Ey9WLw/Q1vUHgFNPGO+I++MzVpQuGhU+QqZMxEA
-4Z7CRneC9VkGjCFMhwnN5ag=
------END CERTIFICATE-----
-
-Juur-SK
-=======
------BEGIN CERTIFICATE-----
-MIIE5jCCA86gAwIBAgIEO45L/DANBgkqhkiG9w0BAQUFADBdMRgwFgYJKoZIhvcNAQkBFglwa2lA
-c2suZWUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKExlBUyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMRAw
-DgYDVQQDEwdKdXVyLVNLMB4XDTAxMDgzMDE0MjMwMVoXDTE2MDgyNjE0MjMwMVowXTEYMBYGCSqG
-SIb3DQEJARYJcGtpQHNrLmVlMQswCQYDVQQGEwJFRTEiMCAGA1UEChMZQVMgU2VydGlmaXRzZWVy
-aW1pc2tlc2t1czEQMA4GA1UEAxMHSnV1ci1TSzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
-ggEBAIFxNj4zB9bjMI0TfncyRsvPGbJgMUaXhvSYRqTCZUXP00B841oiqBB4M8yIsdOBSvZiF3tf
-TQou0M+LI+5PAk676w7KvRhj6IAcjeEcjT3g/1tf6mTll+g/mX8MCgkzABpTpyHhOEvWgxutr2TC
-+Rx6jGZITWYfGAriPrsfB2WThbkasLnE+w0R9vXW+RvHLCu3GFH+4Hv2qEivbDtPL+/40UceJlfw
-UR0zlv/vWT3aTdEVNMfqPxZIe5EcgEMPPbgFPtGzlc3Yyg/CQ2fbt5PgIoIuvvVoKIO5wTtpeyDa
-Tpxt4brNj3pssAki14sL2xzVWiZbDcDq5WDQn/413z8CAwEAAaOCAawwggGoMA8GA1UdEwEB/wQF
-MAMBAf8wggEWBgNVHSAEggENMIIBCTCCAQUGCisGAQQBzh8BAQEwgfYwgdAGCCsGAQUFBwICMIHD
-HoHAAFMAZQBlACAAcwBlAHIAdABpAGYAaQBrAGEAYQB0ACAAbwBuACAAdgDkAGwAagBhAHMAdABh
-AHQAdQBkACAAQQBTAC0AaQBzACAAUwBlAHIAdABpAGYAaQB0AHMAZQBlAHIAaQBtAGkAcwBrAGUA
-cwBrAHUAcwAgAGEAbABhAG0ALQBTAEsAIABzAGUAcgB0AGkAZgBpAGsAYQBhAHQAaQBkAGUAIABr
-AGkAbgBuAGkAdABhAG0AaQBzAGUAawBzMCEGCCsGAQUFBwIBFhVodHRwOi8vd3d3LnNrLmVlL2Nw
-cy8wKwYDVR0fBCQwIjAgoB6gHIYaaHR0cDovL3d3dy5zay5lZS9qdXVyL2NybC8wHQYDVR0OBBYE
-FASqekej5ImvGs8KQKcYP2/v6X2+MB8GA1UdIwQYMBaAFASqekej5ImvGs8KQKcYP2/v6X2+MA4G
-A1UdDwEB/wQEAwIB5jANBgkqhkiG9w0BAQUFAAOCAQEAe8EYlFOiCfP+JmeaUOTDBS8rNXiRTHyo
-ERF5TElZrMj3hWVcRrs7EKACr81Ptcw2Kuxd/u+gkcm2k298gFTsxwhwDY77guwqYHhpNjbRxZyL
-abVAyJRld/JXIWY7zoVAtjNjGr95HvxcHdMdkxuLDF2FvZkwMhgJkVLpfKG6/2SSmuz+Ne6ML678
-IIbsSt4beDI3poHSna9aEhbKmVv8b20OxaAehsmR0FyYgl9jDIpaq9iVpszLita/ZEuOyoqysOkh
-Mp6qqIWYNIE5ITuoOlIyPfZrN4YGWhWY3PARZv40ILcD9EEQfTmEeZZyY7aWAuVrua0ZTbvGRNs2
-yyqcjg==
------END CERTIFICATE-----
-
-Hongkong Post Root CA 1
-=======================
------BEGIN CERTIFICATE-----
-MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoT
-DUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMB4XDTAzMDUx
-NTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25n
-IFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEF
-AAOCAQ8AMIIBCgKCAQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1
-ApzQjVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEnPzlTCeqr
-auh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjhZY4bXSNmO7ilMlHIhqqh
-qZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9nnV0ttgCXjqQesBCNnLsak3c78QA3xMY
-V18meMjWCnl3v/evt3a5pQuEF10Q6m/hq5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNV
-HRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7i
-h9legYsCmEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI37pio
-l7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clBoiMBdDhViw+5Lmei
-IAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJsEhTkYY2sEJCehFC78JZvRZ+K88ps
-T/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpOfMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilT
-c4afU9hDDl3WY4JxHYB0yvbiAmvZWg==
------END CERTIFICATE-----
-
-SecureSign RootCA11
-===================
------BEGIN CERTIFICATE-----
-MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDErMCkGA1UEChMi
-SmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoGA1UEAxMTU2VjdXJlU2lnbiBS
-b290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSsw
-KQYDVQQKEyJKYXBhbiBDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1
-cmVTaWduIFJvb3RDQTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvL
-TJszi1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8h9uuywGO
-wvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOVMdrAG/LuYpmGYz+/3ZMq
-g6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rP
-O7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitA
-bpSACW22s293bzUIUPsCh8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZX
-t94wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAKCh
-OBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xmKbabfSVSSUOrTC4r
-bnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQX5Ucv+2rIrVls4W6ng+4reV6G4pQ
-Oh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWrQbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01
-y8hSyn+B/tlr0/cR7SXf+Of5pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061
-lgeLKBObjBmNQSdJQO7e5iNEOdyhIta6A/I=
------END CERTIFICATE-----
-
-ACEDICOM Root
-=============
------BEGIN CERTIFICATE-----
-MIIFtTCCA52gAwIBAgIIYY3HhjsBggUwDQYJKoZIhvcNAQEFBQAwRDEWMBQGA1UEAwwNQUNFRElD
-T00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00xCzAJBgNVBAYTAkVTMB4XDTA4
-MDQxODE2MjQyMloXDTI4MDQxMzE2MjQyMlowRDEWMBQGA1UEAwwNQUNFRElDT00gUm9vdDEMMAoG
-A1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00xCzAJBgNVBAYTAkVTMIICIjANBgkqhkiG9w0BAQEF
-AAOCAg8AMIICCgKCAgEA/5KV4WgGdrQsyFhIyv2AVClVYyT/kGWbEHV7w2rbYgIB8hiGtXxaOLHk
-WLn709gtn70yN78sFW2+tfQh0hOR2QetAQXW8713zl9CgQr5auODAKgrLlUTY4HKRxx7XBZXehuD
-YAQ6PmXDzQHe3qTWDLqO3tkE7hdWIpuPY/1NFgu3e3eM+SW10W2ZEi5PGrjm6gSSrj0RuVFCPYew
-MYWveVqc/udOXpJPQ/yrOq2lEiZmueIM15jO1FillUAKt0SdE3QrwqXrIhWYENiLxQSfHY9g5QYb
-m8+5eaA9oiM/Qj9r+hwDezCNzmzAv+YbX79nuIQZ1RXve8uQNjFiybwCq0Zfm/4aaJQ0PZCOrfbk
-HQl/Sog4P75n/TSW9R28MHTLOO7VbKvU/PQAtwBbhTIWdjPp2KOZnQUAqhbm84F9b32qhm2tFXTT
-xKJxqvQUfecyuB+81fFOvW8XAjnXDpVCOscAPukmYxHqC9FK/xidstd7LzrZlvvoHpKuE1XI2Sf2
-3EgbsCTBheN3nZqk8wwRHQ3ItBTutYJXCb8gWH8vIiPYcMt5bMlL8qkqyPyHK9caUPgn6C9D4zq9
-2Fdx/c6mUlv53U3t5fZvie27k5x2IXXwkkwp9y+cAS7+UEaeZAwUswdbxcJzbPEHXEUkFDWug/Fq
-TYl6+rPYLWbwNof1K1MCAwEAAaOBqjCBpzAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKaz
-4SsrSbbXc6GqlPUB53NlTKxQMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUprPhKytJttdzoaqU
-9QHnc2VMrFAwRAYDVR0gBD0wOzA5BgRVHSAAMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly9hY2VkaWNv
-bS5lZGljb21ncm91cC5jb20vZG9jMA0GCSqGSIb3DQEBBQUAA4ICAQDOLAtSUWImfQwng4/F9tqg
-aHtPkl7qpHMyEVNEskTLnewPeUKzEKbHDZ3Ltvo/Onzqv4hTGzz3gvoFNTPhNahXwOf9jU8/kzJP
-eGYDdwdY6ZXIfj7QeQCM8htRM5u8lOk6e25SLTKeI6RF+7YuE7CLGLHdztUdp0J/Vb77W7tH1Pwk
-zQSulgUV1qzOMPPKC8W64iLgpq0i5ALudBF/TP94HTXa5gI06xgSYXcGCRZj6hitoocf8seACQl1
-ThCojz2GuHURwCRiipZ7SkXp7FnFvmuD5uHorLUwHv4FB4D54SMNUI8FmP8sX+g7tq3PgbUhh8oI
-KiMnMCArz+2UW6yyetLHKKGKC5tNSixthT8Jcjxn4tncB7rrZXtaAWPWkFtPF2Y9fwsZo5NjEFIq
-nxQWWOLcpfShFosOkYuByptZ+thrkQdlVV9SH686+5DdaaVbnG0OLLb6zqylfDJKZ0DcMDQj3dcE
-I2bw/FWAp/tmGYI1Z2JwOV5vx+qQQEQIHriy1tvuWacNGHk0vFQYXlPKNFHtRQrmjseCNj6nOGOp
-MCwXEGCSn1WHElkQwg9naRHMTh5+Spqtr0CodaxWkHS4oJyleW/c6RrIaQXpuvoDs3zk4E7Czp3o
-tkYNbn5XOmeUwssfnHdKZ05phkOTOPu220+DkdRgfks+KzgHVZhepA==
------END CERTIFICATE-----
-
-Verisign Class 1 Public Primary Certification Authority
-=======================================================
------BEGIN CERTIFICATE-----
-MIICPDCCAaUCED9pHoGc8JpK83P/uUii5N0wDQYJKoZIhvcNAQEFBQAwXzELMAkGA1UEBhMCVVMx
-FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAxIFB1YmxpYyBQcmltYXJ5
-IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVow
-XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAx
-IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA
-A4GNADCBiQKBgQDlGb9to1ZhLZlIcfZn3rmN67eehoAKkQ76OCWvRoiC5XOooJskXQ0fzGVuDLDQ
-VoQYh5oGmxChc9+0WDlrbsH2FdWoqD+qEgaNMax/sDTXjzRniAnNFBHiTkVWaR94AoDa3EeRKbs2
-yWNcxeDXLYd7obcysHswuiovMaruo2fa2wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFgVKTk8d6Pa
-XCUDfGD67gmZPCcQcMgMCeazh88K4hiWNWLMv5sneYlfycQJ9M61Hd8qveXbhpxoJeUwfLaJFf5n
-0a3hUKw8fGJLj7qE1xIVGx/KXQ/BUpQqEZnae88MNhPVNdwQGVnqlMEAv3WP2fr9dgTbYruQagPZ
-RjXZ+Hxb
------END CERTIFICATE-----
-
-Verisign Class 3 Public Primary Certification Authority
-=======================================================
------BEGIN CERTIFICATE-----
-MIICPDCCAaUCEDyRMcsf9tAbDpq40ES/Er4wDQYJKoZIhvcNAQEFBQAwXzELMAkGA1UEBhMCVVMx
-FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmltYXJ5
-IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVow
-XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAz
-IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA
-A4GNADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhEBarsAx94
-f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/isI19wKTakyYbnsZogy1Ol
-hec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBABByUqkFFBky
-CEHwxWsKzH4PIRnN5GfcX6kb5sroc50i2JhucwNhkcV8sEVAbkSdjbCxlnRhLQ2pRdKkkirWmnWX
-bj9T/UWZYB2oK0z5XqcJ2HUw19JlYD1n1khVdWk/kfVIC0dpImmClr7JyDiGSnoscxlIaU5rfGW/
-D/xwzoiQ
------END CERTIFICATE-----
-
-Microsec e-Szigno Root CA 2009
-==============================
------BEGIN CERTIFICATE-----
-MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYDVQQGEwJIVTER
-MA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jv
-c2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o
-dTAeFw0wOTA2MTYxMTMwMThaFw0yOTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UE
-BwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUt
-U3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTCCASIw
-DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvPkd6mJviZpWNwrZuuyjNA
-fW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tccbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG
-0IMZfcChEhyVbUr02MelTTMuhTlAdX4UfIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKA
-pxn1ntxVUwOXewdI/5n7N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm
-1HxdrtbCxkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1+rUC
-AwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTLD8bf
-QkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAbBgNVHREE
-FDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqGSIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0o
-lZMEyL/azXm4Q5DwpL7v8u8hmLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfX
-I/OMn74dseGkddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775
-tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c2Pm2G2JwCz02
-yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5tHMN1Rq41Bab2XD0h7lbwyYIi
-LXpUq3DDfSJlgnCW
------END CERTIFICATE-----
-
-E-Guven Kok Elektronik Sertifika Hizmet Saglayicisi
-===================================================
------BEGIN CERTIFICATE-----
-MIIDtjCCAp6gAwIBAgIQRJmNPMADJ72cdpW56tustTANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQG
-EwJUUjEoMCYGA1UEChMfRWxla3Ryb25payBCaWxnaSBHdXZlbmxpZ2kgQS5TLjE8MDoGA1UEAxMz
-ZS1HdXZlbiBLb2sgRWxla3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhZ2xheWljaXNpMB4XDTA3
-MDEwNDExMzI0OFoXDTE3MDEwNDExMzI0OFowdTELMAkGA1UEBhMCVFIxKDAmBgNVBAoTH0VsZWt0
-cm9uaWsgQmlsZ2kgR3V2ZW5saWdpIEEuUy4xPDA6BgNVBAMTM2UtR3V2ZW4gS29rIEVsZWt0cm9u
-aWsgU2VydGlmaWthIEhpem1ldCBTYWdsYXlpY2lzaTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
-AQoCggEBAMMSIJ6wXgBljU5Gu4Bc6SwGl9XzcslwuedLZYDBS75+PNdUMZTe1RK6UxYC6lhj71vY
-8+0qGqpxSKPcEC1fX+tcS5yWCEIlKBHMilpiAVDV6wlTL/jDj/6z/P2douNffb7tC+Bg62nsM+3Y
-jfsSSYMAyYuXjDtzKjKzEve5TfL0TW3H5tYmNwjy2f1rXKPlSFxYvEK+A1qBuhw1DADT9SN+cTAI
-JjjcJRFHLfO6IxClv7wC90Nex/6wN1CZew+TzuZDLMN+DfIcQ2Zgy2ExR4ejT669VmxMvLz4Bcpk
-9Ok0oSy1c+HCPujIyTQlCFzz7abHlJ+tiEMl1+E5YP6sOVkCAwEAAaNCMEAwDgYDVR0PAQH/BAQD
-AgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJ/uRLOU1fqRTy7ZVZoEVtstxNulMA0GCSqG
-SIb3DQEBBQUAA4IBAQB/X7lTW2M9dTLn+sR0GstG30ZpHFLPqk/CaOv/gKlR6D1id4k9CnU58W5d
-F4dvaAXBlGzZXd/aslnLpRCKysw5zZ/rTt5S/wzw9JKp8mxTq5vSR6AfdPebmvEvFZ96ZDAYBzwq
-D2fK/A+JYZ1lpTzlvBNbCNvj/+27BrtqBrF6T2XGgv0enIu1De5Iu7i9qgi0+6N8y5/NkHZchpZ4
-Vwpm+Vganf2XKWDeEaaQHBkc7gGWIjQ0LpH5t8Qn0Xvmv/uARFoW5evg1Ao4vOSR49XrXMGs3xtq
-fJ7lddK2l4fbzIcrQzqECK+rPNv3PGYxhrCdU3nt+CPeQuMtgvEP5fqX
------END CERTIFICATE-----
-
-GlobalSign Root CA - R3
-=======================
------BEGIN CERTIFICATE-----
-MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4GA1UECxMXR2xv
-YmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh
-bFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT
-aWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln
-bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWt
-iHL8RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsTgHeMCOFJ
-0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmmKPZpO/bLyCiR5Z2KYVc3
-rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zdQQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjl
-OCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZXriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2
-xmmFghcCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE
-FI/wS3+oLkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZURUm7
-lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMpjjM5RcOO5LlXbKr8
-EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK6fBdRoyV3XpYKBovHd7NADdBj+1E
-bddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQXmcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18
-YIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7r
-kpeDMdmztcpHWD9f
------END CERTIFICATE-----
-
-TC TrustCenter Universal CA III
-===============================
------BEGIN CERTIFICATE-----
-MIID4TCCAsmgAwIBAgIOYyUAAQACFI0zFQLkbPQwDQYJKoZIhvcNAQEFBQAwezELMAkGA1UEBhMC
-REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNVBAsTG1RDIFRydXN0Q2VudGVy
-IFVuaXZlcnNhbCBDQTEoMCYGA1UEAxMfVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBIElJSTAe
-Fw0wOTA5MDkwODE1MjdaFw0yOTEyMzEyMzU5NTlaMHsxCzAJBgNVBAYTAkRFMRwwGgYDVQQKExNU
-QyBUcnVzdENlbnRlciBHbWJIMSQwIgYDVQQLExtUQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0Ex
-KDAmBgNVBAMTH1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQSBJSUkwggEiMA0GCSqGSIb3DQEB
-AQUAA4IBDwAwggEKAoIBAQDC2pxisLlxErALyBpXsq6DFJmzNEubkKLF5+cvAqBNLaT6hdqbJYUt
-QCggbergvbFIgyIpRJ9Og+41URNzdNW88jBmlFPAQDYvDIRlzg9uwliT6CwLOunBjvvya8o84pxO
-juT5fdMnnxvVZ3iHLX8LR7PH6MlIfK8vzArZQe+f/prhsq75U7Xl6UafYOPfjdN/+5Z+s7Vy+Eut
-CHnNaYlAJ/Uqwa1D7KRTyGG299J5KmcYdkhtWyUB0SbFt1dpIxVbYYqt8Bst2a9c8SaQaanVDED1
-M4BDj5yjdipFtK+/fz6HP3bFzSreIMUWWMv5G/UPyw0RUmS40nZid4PxWJ//AgMBAAGjYzBhMB8G
-A1UdIwQYMBaAFFbn4VslQ4Dg9ozhcbyO5YAvxEjiMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
-BAQDAgEGMB0GA1UdDgQWBBRW5+FbJUOA4PaM4XG8juWAL8RI4jANBgkqhkiG9w0BAQUFAAOCAQEA
-g8ev6n9NCjw5sWi+e22JLumzCecYV42FmhfzdkJQEw/HkG8zrcVJYCtsSVgZ1OK+t7+rSbyUyKu+
-KGwWaODIl0YgoGhnYIg5IFHYaAERzqf2EQf27OysGh+yZm5WZ2B6dF7AbZc2rrUNXWZzwCUyRdhK
-BgePxLcHsU0GDeGl6/R1yrqc0L2z0zIkTO5+4nYES0lT2PLpVDP85XEfPRRclkvxOvIAu2y0+pZV
-CIgJwcyRGSmwIC3/yzikQOEXvnlhgP8HA4ZMTnsGnxGGjYnuJ8Tb4rwZjgvDwxPHLQNjO9Po5KIq
-woIIlBZU8O8fJ5AluA0OKBtHd0e9HKgl8ZS0Zg==
------END CERTIFICATE-----
-
-Autoridad de Certificacion Firmaprofesional CIF A62634068
-=========================================================
------BEGIN CERTIFICATE-----
-MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UEBhMCRVMxQjBA
-BgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2
-MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEyMzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIw
-QAYDVQQDDDlBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBB
-NjI2MzQwNjgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDD
-Utd9thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQMcas9UX4P
-B99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefGL9ItWY16Ck6WaVICqjaY
-7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15iNA9wBj4gGFrO93IbJWyTdBSTo3OxDqqH
-ECNZXyAFGUftaI6SEspd/NYrspI8IM/hX68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyI
-plD9amML9ZMWGxmPsu2bm8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctX
-MbScyJCyZ/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirjaEbsX
-LZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/TKI8xWVvTyQKmtFLK
-bpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF6NkBiDkal4ZkQdU7hwxu+g/GvUgU
-vzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVhOSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1Ud
-EwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNH
-DhpkLzCBpgYDVR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp
-cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBvACAAZABlACAA
-bABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBlAGwAbwBuAGEAIAAwADgAMAAx
-ADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx
-51tkljYyGOylMnfX40S2wBEqgLk9am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qk
-R71kMrv2JYSiJ0L1ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaP
-T481PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS3a/DTg4f
-Jl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5kSeTy36LssUzAKh3ntLFl
-osS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF3dvd6qJ2gHN99ZwExEWN57kci57q13XR
-crHedUTnQn3iV2t93Jm8PYMo6oCTjcVMZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoR
-saS8I8nkvof/uZS2+F0gStRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTD
-KCOM/iczQ0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQBjLMi
-6Et8Vcad+qMUu2WFbm5PEn4KPJ2V
------END CERTIFICATE-----
-
-Izenpe.com
-==========
------BEGIN CERTIFICATE-----
-MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4MQswCQYDVQQG
-EwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wHhcNMDcxMjEz
-MTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMu
-QS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ
-03rKDx6sp4boFmVqscIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAK
-ClaOxdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6HLmYRY2xU
-+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFXuaOKmMPsOzTFlUFpfnXC
-PCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQDyCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxT
-OTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbK
-F7jJeodWLBoBHmy+E60QrLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK
-0GqfvEyNBjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8Lhij+
-0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIBQFqNeb+Lz0vPqhbB
-leStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+HMh3/1uaD7euBUbl8agW7EekFwID
-AQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2luZm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+
-SVpFTlBFIFMuQS4gLSBDSUYgQTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBG
-NjIgUzgxQzBBBgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx
-MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O
-BBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUAA4ICAQB4pgwWSp9MiDrAyw6l
-Fn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWblaQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbga
-kEyrkgPH7UIBzg/YsfqikuFgba56awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8q
-hT/AQKM6WfxZSzwoJNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Cs
-g1lwLDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCTVyvehQP5
-aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGkLhObNA5me0mrZJfQRsN5
-nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJbUjWumDqtujWTI6cfSN01RpiyEGjkpTHC
-ClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZo
-Q0iy2+tzJOeRf1SktoA+naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1Z
-WrOZyGlsQyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw==
------END CERTIFICATE-----
-
-Chambers of Commerce Root - 2008
-================================
------BEGIN CERTIFICATE-----
-MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYDVQQGEwJFVTFD
-MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv
-bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu
-QS4xKTAnBgNVBAMTIENoYW1iZXJzIG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEy
-Mjk1MFoXDTM4MDczMTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNl
-ZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQF
-EwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJl
-cnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
-AQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW928sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKA
-XuFixrYp4YFs8r/lfTJqVKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorj
-h40G072QDuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR5gN/
-ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfLZEFHcpOrUMPrCXZk
-NNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05aSd+pZgvMPMZ4fKecHePOjlO+Bd5g
-D2vlGts/4+EhySnB8esHnFIbAURRPHsl18TlUlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331
-lubKgdaX8ZSD6e2wsWsSaR6s+12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ
-0wlf2eOKNcx5Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj
-ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAxhduub+84Mxh2
-EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNVHQ4EFgQU+SSsD7K1+HnA+mCI
-G8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1+HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJ
-BgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNh
-bWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENh
-bWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDiC
-CQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUH
-AgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAJASryI1
-wqM58C7e6bXpeHxIvj99RZJe6dqxGfwWPJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH
-3qLPaYRgM+gQDROpI9CF5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbU
-RWpGqOt1glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaHFoI6
-M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2pSB7+R5KBWIBpih1
-YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MDxvbxrN8y8NmBGuScvfaAFPDRLLmF
-9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QGtjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcK
-zBIKinmwPQN/aUv0NCB9szTqjktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvG
-nrDQWzilm1DefhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg
-OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZd0jQ
------END CERTIFICATE-----
-
-Global Chambersign Root - 2008
-==============================
------BEGIN CERTIFICATE-----
-MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYDVQQGEwJFVTFD
-MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv
-bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu
-QS4xJzAlBgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMx
-NDBaFw0zODA3MzExMjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUg
-Y3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJ
-QTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD
-aGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDf
-VtPkOpt2RbQT2//BthmLN0EYlVJH6xedKYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXf
-XjaOcNFccUMd2drvXNL7G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0
-ZJJ0YPP2zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4ddPB
-/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyGHoiMvvKRhI9lNNgA
-TH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2Id3UwD2ln58fQ1DJu7xsepeY7s2M
-H/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3VyJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfe
-Ox2YItaswTXbo6Al/3K1dh3ebeksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSF
-HTynyQbehP9r6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh
-wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsogzCtLkykPAgMB
-AAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQWBBS5CcqcHtvTbDprru1U8VuT
-BjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDprru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UE
-BhMCRVUxQzBBBgNVBAcTOk1hZHJpZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJm
-aXJtYS5jb20vYWRkcmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJm
-aXJtYSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiCCQDJzdPp
-1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0
-dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAICIf3DekijZBZRG
-/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZUohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6
-ReAJ3spED8IXDneRRXozX1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/s
-dZ7LoR/xfxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVza2Mg
-9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yydYhz2rXzdpjEetrHH
-foUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMdSqlapskD7+3056huirRXhOukP9Du
-qqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9OAP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETr
-P3iZ8ntxPjzxmKfFGBI/5rsoM0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVq
-c5iJWzouE4gev8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z
-09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B
------END CERTIFICATE-----
-
-Go Daddy Root Certificate Authority - G2
-========================================
------BEGIN CERTIFICATE-----
-MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT
-B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHkuY29tLCBJbmMu
-MTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5
-MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
-b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8G
-A1UEAxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKDE6bFIEMBO4Tx5oVJnyfq
-9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD
-+qK+ihVqf94Lw7YZFAXK6sOoBJQ7RnwyDfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutd
-fMh8+7ArU6SSYmlRJQVhGkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMl
-NAJWJwGRtDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEAAaNC
-MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9
-BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmXWWcDYfF+OwYxdS2hII5PZYe096ac
-vNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r
-5N9ss4UXnT3ZJE95kTXWXwTrgIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYV
-N8Gb5DKj7Tjo2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO
-LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI4uJEvlz36hz1
------END CERTIFICATE-----
-
-Starfield Root Certificate Authority - G2
-=========================================
------BEGIN CERTIFICATE-----
-MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT
-B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s
-b2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVsZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0
-eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAw
-DgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQg
-VGVjaG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZpY2F0ZSBB
-dXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3twQP89o/8ArFv
-W59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMgnLRJdzIpVv257IzdIvpy3Cdhl+72WoTs
-bhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNk
-N3mSwOxGXn/hbVNMYq/NHwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7Nf
-ZTD4p7dNdloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0HZbU
-JtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
-AQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0GCSqGSIb3DQEBCwUAA4IBAQARWfol
-TwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjUsHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx
-4mcujJUDJi5DnUox9g61DLu34jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUw
-F5okxBDgBPfg8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K
-pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1mMpYjn0q7pBZ
-c2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
------END CERTIFICATE-----
-
-Starfield Services Root Certificate Authority - G2
-==================================================
------BEGIN CERTIFICATE-----
-MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgT
-B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s
-b2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRl
-IEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNV
-BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxT
-dGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2VydmljZXMg
-Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
-AQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20pOsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2
-h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm28xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4Pa
-hHQUw2eeBGg6345AWh1KTs9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLP
-LJGmpufehRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk6mFB
-rMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAwDwYDVR0TAQH/BAUw
-AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMA0GCSqG
-SIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMIbw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPP
-E95Dz+I0swSdHynVv/heyNXBve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTy
-xQGjhdByPq1zqwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd
-iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn0q23KXB56jza
-YyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCNsSi6
------END CERTIFICATE-----
-
-AffirmTrust Commercial
-======================
------BEGIN CERTIFICATE-----
-MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxFDAS
-BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMB4XDTEw
-MDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly
-bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEF
-AAOCAQ8AMIIBCgKCAQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6Eqdb
-DuKPHx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yrba0F8PrV
-C8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPALMeIrJmqbTFeurCA+ukV6
-BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1yHp52UKqK39c/s4mT6NmgTWvRLpUHhww
-MmWd5jyTXlBOeuM61G7MGvv50jeuJCqrVwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNV
-HQ4EFgQUnZPGU4teyq8/nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
-AQYwDQYJKoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYGXUPG
-hi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNjvbz4YYCanrHOQnDi
-qX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivtZ8SOyUOyXGsViQK8YvxO8rUzqrJv
-0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9gN53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0kh
-sUlHRUe072o0EclNmsxZt9YCnlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8=
------END CERTIFICATE-----
-
-AffirmTrust Networking
-======================
------BEGIN CERTIFICATE-----
-MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UEBhMCVVMxFDAS
-BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMB4XDTEw
-MDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly
-bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEF
-AAOCAQ8AMIIBCgKCAQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SE
-Hi3yYJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbuakCNrmreI
-dIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRLQESxG9fhwoXA3hA/Pe24
-/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gb
-h+0t+nvujArjqWaJGctB+d1ENmHP4ndGyH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNV
-HQ4EFgQUBx/S55zawm6iQLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
-AQYwDQYJKoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfOtDIu
-UFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzuQY0x2+c06lkh1QF6
-12S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZLgo/bNjR9eUJtGxUAArgFU2HdW23
-WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4uolu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9
-/ZFvgrG+CJPbFEfxojfHRZ48x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s=
------END CERTIFICATE-----
-
-AffirmTrust Premium
-===================
------BEGIN CERTIFICATE-----
-MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UEBhMCVVMxFDAS
-BgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMB4XDTEwMDEy
-OTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRy
-dXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
-MIICCgKCAgEAxBLfqV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtn
-BKAQJG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ+jjeRFcV
-5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrSs8PhaJyJ+HoAVt70VZVs
-+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmd
-GPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d770O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5R
-p9EixAqnOEhss/n/fauGV+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NI
-S+LI+H+SqHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S5u04
-6uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4IaC1nEWTJ3s7xgaVY5
-/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TXOwF0lkLgAOIua+rF7nKsu7/+6qqo
-+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYEFJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB
-/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByv
-MiPIs0laUZx2KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg
-Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B8OWycvpEgjNC
-6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQMKSOyARiqcTtNd56l+0OOF6S
-L5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK
-+4w1IX2COPKpVJEZNZOUbWo6xbLQu4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmV
-BtWVyuEklut89pMFu+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFg
-IxpHYoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8GKa1qF60
-g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaORtGdFNrHF+QFlozEJLUb
-zxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6eKeC2uAloGRwYQw==
------END CERTIFICATE-----
-
-AffirmTrust Premium ECC
-=======================
------BEGIN CERTIFICATE-----
-MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMCVVMxFDASBgNV
-BAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQcmVtaXVtIEVDQzAeFw0xMDAx
-MjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1U
-cnVzdDEgMB4GA1UEAwwXQWZmaXJtVHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQA
-IgNiAAQNMF4bFZ0D0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQ
-N8O9ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0GA1UdDgQW
-BBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAK
-BggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/VsaobgxCd05DhT1wV/GzTjxi+zygk8N53X
-57hG8f2h4nECMEJZh0PUUd+60wkyWs6Iflc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKM
-eQ==
------END CERTIFICATE-----
-
-Certum Trusted Network CA
-=========================
------BEGIN CERTIFICATE-----
-MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBMMSIwIAYDVQQK
-ExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlv
-biBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBUcnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIy
-MTIwNzM3WhcNMjkxMjMxMTIwNzM3WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBU
-ZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5
-MSIwIAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC
-AQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rHUV+rpDKmYYe2bg+G0jAC
-l/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LMTXPb865Px1bVWqeWifrzq2jUI4ZZJ88J
-J7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVUBBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4
-fOQtf/WsX+sWn7Et0brMkUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0
-cvW0QM8xAcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNVHRMB
-Af8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNVHQ8BAf8EBAMCAQYw
-DQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15ysHhE49wcrwn9I0j6vSrEuVUEtRCj
-jSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfLI9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1
-mS1FhIrlQgnXdAIv94nYmem8J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5aj
-Zt3hrvJBW8qYVoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI
-03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw=
------END CERTIFICATE-----
-
-Certinomis - Autorité Racine
-=============================
------BEGIN CERTIFICATE-----
-MIIFnDCCA4SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJGUjETMBEGA1UEChMK
-Q2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxJjAkBgNVBAMMHUNlcnRpbm9taXMg
-LSBBdXRvcml0w6kgUmFjaW5lMB4XDTA4MDkxNzA4Mjg1OVoXDTI4MDkxNzA4Mjg1OVowYzELMAkG
-A1UEBhMCRlIxEzARBgNVBAoTCkNlcnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMSYw
-JAYDVQQDDB1DZXJ0aW5vbWlzIC0gQXV0b3JpdMOpIFJhY2luZTCCAiIwDQYJKoZIhvcNAQEBBQAD
-ggIPADCCAgoCggIBAJ2Fn4bT46/HsmtuM+Cet0I0VZ35gb5j2CN2DpdUzZlMGvE5x4jYF1AMnmHa
-wE5V3udauHpOd4cN5bjr+p5eex7Ezyh0x5P1FMYiKAT5kcOrJ3NqDi5N8y4oH3DfVS9O7cdxbwly
-Lu3VMpfQ8Vh30WC8Tl7bmoT2R2FFK/ZQpn9qcSdIhDWerP5pqZ56XjUl+rSnSTV3lqc2W+HN3yNw
-2F1MpQiD8aYkOBOo7C+ooWfHpi2GR+6K/OybDnT0K0kCe5B1jPyZOQE51kqJ5Z52qz6WKDgmi92N
-jMD2AR5vpTESOH2VwnHu7XSu5DaiQ3XV8QCb4uTXzEIDS3h65X27uK4uIJPT5GHfceF2Z5c/tt9q
-c1pkIuVC28+BA5PY9OMQ4HL2AHCs8MF6DwV/zzRpRbWT5BnbUhYjBYkOjUjkJW+zeL9i9Qf6lSTC
-lrLooyPCXQP8w9PlfMl1I9f09bze5N/NgL+RiH2nE7Q5uiy6vdFrzPOlKO1Enn1So2+WLhl+HPNb
-xxaOu2B9d2ZHVIIAEWBsMsGoOBvrbpgT1u449fCfDu/+MYHB0iSVL1N6aaLwD4ZFjliCK0wi1F6g
-530mJ0jfJUaNSih8hp75mxpZuWW/Bd22Ql095gBIgl4g9xGC3srYn+Y3RyYe63j3YcNBZFgCQfna
-4NH4+ej9Uji29YnfAgMBAAGjWzBZMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G
-A1UdDgQWBBQNjLZh2kS40RR9w759XkjwzspqsDAXBgNVHSAEEDAOMAwGCiqBegFWAgIAAQEwDQYJ
-KoZIhvcNAQEFBQADggIBACQ+YAZ+He86PtvqrxyaLAEL9MW12Ukx9F1BjYkMTv9sov3/4gbIOZ/x
-WqndIlgVqIrTseYyCYIDbNc/CMf4uboAbbnW/FIyXaR/pDGUu7ZMOH8oMDX/nyNTt7buFHAAQCva
-R6s0fl6nVjBhK4tDrP22iCj1a7Y+YEq6QpA0Z43q619FVDsXrIvkxmUP7tCMXWY5zjKn2BCXwH40
-nJ+U8/aGH88bc62UeYdocMMzpXDn2NU4lG9jeeu/Cg4I58UvD0KgKxRA/yHgBcUn4YQRE7rWhh1B
-CxMjidPJC+iKunqjo3M3NYB9Ergzd0A4wPpeMNLytqOx1qKVl4GbUu1pTP+A5FPbVFsDbVRfsbjv
-JL1vnxHDx2TCDyhihWZeGnuyt++uNckZM6i4J9szVb9o4XVIRFb7zdNIu0eJOqxp9YDG5ERQL1TE
-qkPFMTFYvZbF6nVsmnWxTfj3l/+WFvKXTej28xH5On2KOG4Ey+HTRRWqpdEdnV1j6CTmNhTih60b
-WfVEm/vXd3wfAXBioSAaosUaKPQhA+4u2cGA6rnZgtZbdsLLO7XSAPCjDuGtbkD326C00EauFddE
-wk01+dIL8hf2rGbVJLJP0RyZwG71fet0BLj5TXcJ17TPBzAJ8bgAVtkXFhYKK4bfjwEZGuW7gmP/
-vgt2Fl43N+bYdJeimUV5
------END CERTIFICATE-----
-
-Root CA Generalitat Valenciana
-==============================
------BEGIN CERTIFICATE-----
-MIIGizCCBXOgAwIBAgIEO0XlaDANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJFUzEfMB0GA1UE
-ChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290
-IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwHhcNMDEwNzA2MTYyMjQ3WhcNMjEwNzAxMTUyMjQ3
-WjBoMQswCQYDVQQGEwJFUzEfMB0GA1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UE
-CxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwggEiMA0G
-CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGKqtXETcvIorKA3Qdyu0togu8M1JAJke+WmmmO3I2
-F0zo37i7L3bhQEZ0ZQKQUgi0/6iMweDHiVYQOTPvaLRfX9ptI6GJXiKjSgbwJ/BXufjpTjJ3Cj9B
-ZPPrZe52/lSqfR0grvPXdMIKX/UIKFIIzFVd0g/bmoGlu6GzwZTNVOAydTGRGmKy3nXiz0+J2ZGQ
-D0EbtFpKd71ng+CT516nDOeB0/RSrFOyA8dEJvt55cs0YFAQexvba9dHq198aMpunUEDEO5rmXte
-JajCq+TA81yc477OMUxkHl6AovWDfgzWyoxVjr7gvkkHD6MkQXpYHYTqWBLI4bft75PelAgxAgMB
-AAGjggM7MIIDNzAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLnBraS5n
-dmEuZXMwEgYDVR0TAQH/BAgwBgEB/wIBAjCCAjQGA1UdIASCAiswggInMIICIwYKKwYBBAG/VQIB
-ADCCAhMwggHoBggrBgEFBQcCAjCCAdoeggHWAEEAdQB0AG8AcgBpAGQAYQBkACAAZABlACAAQwBl
-AHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAFIAYQDtAHoAIABkAGUAIABsAGEAIABHAGUAbgBlAHIA
-YQBsAGkAdABhAHQAIABWAGEAbABlAG4AYwBpAGEAbgBhAC4ADQAKAEwAYQAgAEQAZQBjAGwAYQBy
-AGEAYwBpAPMAbgAgAGQAZQAgAFAAcgDhAGMAdABpAGMAYQBzACAAZABlACAAQwBlAHIAdABpAGYA
-aQBjAGEAYwBpAPMAbgAgAHEAdQBlACAAcgBpAGcAZQAgAGUAbAAgAGYAdQBuAGMAaQBvAG4AYQBt
-AGkAZQBuAHQAbwAgAGQAZQAgAGwAYQAgAHAAcgBlAHMAZQBuAHQAZQAgAEEAdQB0AG8AcgBpAGQA
-YQBkACAAZABlACAAQwBlAHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAHMAZQAgAGUAbgBjAHUAZQBu
-AHQAcgBhACAAZQBuACAAbABhACAAZABpAHIAZQBjAGMAaQDzAG4AIAB3AGUAYgAgAGgAdAB0AHAA
-OgAvAC8AdwB3AHcALgBwAGsAaQAuAGcAdgBhAC4AZQBzAC8AYwBwAHMwJQYIKwYBBQUHAgEWGWh0
-dHA6Ly93d3cucGtpLmd2YS5lcy9jcHMwHQYDVR0OBBYEFHs100DSHHgZZu90ECjcPk+yeAT8MIGV
-BgNVHSMEgY0wgYqAFHs100DSHHgZZu90ECjcPk+yeAT8oWykajBoMQswCQYDVQQGEwJFUzEfMB0G
-A1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScwJQYDVQQDEx5S
-b290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmGCBDtF5WgwDQYJKoZIhvcNAQEFBQADggEBACRh
-TvW1yEICKrNcda3FbcrnlD+laJWIwVTAEGmiEi8YPyVQqHxK6sYJ2fR1xkDar1CdPaUWu20xxsdz
-Ckj+IHLtb8zog2EWRpABlUt9jppSCS/2bxzkoXHPjCpaF3ODR00PNvsETUlR4hTJZGH71BTg9J63
-NI8KJr2XXPR5OkowGcytT6CYirQxlyric21+eLj4iIlPsSKRZEv1UN4D2+XFducTZnV+ZfsBn5OH
-iJ35Rld8TWCvmHMTI6QgkYH60GFmuH3Rr9ZvHmw96RH9qfmCIoaZM3Fa6hlXPZHNqcCjbgcTpsnt
-+GijnsNacgmHKNHEc8RzGF9QdRYxn7fofMM=
------END CERTIFICATE-----
-
-A-Trust-nQual-03
-================
------BEGIN CERTIFICATE-----
-MIIDzzCCAregAwIBAgIDAWweMA0GCSqGSIb3DQEBBQUAMIGNMQswCQYDVQQGEwJBVDFIMEYGA1UE
-Cgw/QS1UcnVzdCBHZXMuIGYuIFNpY2hlcmhlaXRzc3lzdGVtZSBpbSBlbGVrdHIuIERhdGVudmVy
-a2VociBHbWJIMRkwFwYDVQQLDBBBLVRydXN0LW5RdWFsLTAzMRkwFwYDVQQDDBBBLVRydXN0LW5R
-dWFsLTAzMB4XDTA1MDgxNzIyMDAwMFoXDTE1MDgxNzIyMDAwMFowgY0xCzAJBgNVBAYTAkFUMUgw
-RgYDVQQKDD9BLVRydXN0IEdlcy4gZi4gU2ljaGVyaGVpdHNzeXN0ZW1lIGltIGVsZWt0ci4gRGF0
-ZW52ZXJrZWhyIEdtYkgxGTAXBgNVBAsMEEEtVHJ1c3QtblF1YWwtMDMxGTAXBgNVBAMMEEEtVHJ1
-c3QtblF1YWwtMDMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtPWFuA/OQO8BBC4SA
-zewqo51ru27CQoT3URThoKgtUaNR8t4j8DRE/5TrzAUjlUC5B3ilJfYKvUWG6Nm9wASOhURh73+n
-yfrBJcyFLGM/BWBzSQXgYHiVEEvc+RFZznF/QJuKqiTfC0Li21a8StKlDJu3Qz7dg9MmEALP6iPE
-SU7l0+m0iKsMrmKS1GWH2WrX9IWf5DMiJaXlyDO6w8dB3F/GaswADm0yqLaHNgBid5seHzTLkDx4
-iHQF63n1k3Flyp3HaxgtPVxO59X4PzF9j4fsCiIvI+n+u33J4PTs63zEsMMtYrWacdaxaujs2e3V
-cuy+VwHOBVWf3tFgiBCzAgMBAAGjNjA0MA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0OBAoECERqlWdV
-eRFPMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAVdRU0VlIXLOThaq/Yy/kgM40
-ozRiPvbY7meIMQQDbwvUB/tOdQ/TLtPAF8fGKOwGDREkDg6lXb+MshOWcdzUzg4NCmgybLlBMRmr
-sQd7TZjTXLDR8KdCoLXEjq/+8T/0709GAHbrAvv5ndJAlseIOrifEXnzgGWovR/TeIGgUUw3tKZd
-JXDRZslo+S4RFGjxVJgIrCaSD96JntT6s3kr0qN51OyLrIdTaEJMUVF0HhsnLuP1Hyl0Te2v9+GS
-mYHovjrHF1D2t8b8m7CKa9aIA5GPBnc6hQLdmNVDeD/GMBWsm2vLV7eJUYs66MmEDNuxUCAKGkq6
-ahq97BvIxYSazQ==
------END CERTIFICATE-----
-
-TWCA Root Certification Authority
-=================================
------BEGIN CERTIFICATE-----
-MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJ
-VEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlmaWNh
-dGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMzWhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQG
-EwJUVzESMBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NB
-IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
-AoIBAQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFEAcK0HMMx
-QhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HHK3XLfJ+utdGdIzdjp9xC
-oi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeXRfwZVzsrb+RH9JlF/h3x+JejiB03HFyP
-4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/zrX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1r
-y+UPizgN7gr8/g+YnzAx3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIB
-BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkqhkiG
-9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeCMErJk/9q56YAf4lC
-mtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdlsXebQ79NqZp4VKIV66IIArB6nCWlW
-QtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62Dlhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVY
-T0bf+215WfKEIlKuD8z7fDvnaspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocny
-Yh0igzyXxfkZYiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw==
------END CERTIFICATE-----
-
-Security Communication RootCA2
-==============================
------BEGIN CERTIFICATE-----
-MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc
-U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMeU2VjdXJpdHkgQ29tbXVuaWNh
-dGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoXDTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMC
-SlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3Vy
-aXR5IENvbW11bmljYXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
-ANAVOVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGrzbl+dp++
-+T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVMVAX3NuRFg3sUZdbcDE3R
-3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQhNBqyjoGADdH5H5XTz+L62e4iKrFvlNV
-spHEfbmwhRkGeC7bYRr6hfVKkaHnFtWOojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1K
-EOtOghY6rCcMU/Gt1SSwawNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8
-QIH4D5csOPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB
-CwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpFcoJxDjrSzG+ntKEj
-u/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXcokgfGT+Ok+vx+hfuzU7jBBJV1uXk
-3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6q
-tnRGEmyR7jTV7JqR50S+kDFy1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29
-mvVXIwAHIRc/SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03
------END CERTIFICATE-----
-
-EC-ACC
-======
------BEGIN CERTIFICATE-----
-MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB8zELMAkGA1UE
-BhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2VydGlmaWNhY2lvIChOSUYgUS0w
-ODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYD
-VQQLEyxWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UE
-CxMsSmVyYXJxdWlhIEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMT
-BkVDLUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQGEwJFUzE7
-MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8gKE5JRiBRLTA4MDExNzYt
-SSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBDZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZl
-Z2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQubmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJh
-cnF1aWEgRW50aXRhdHMgZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUND
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R85iK
-w5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm4CgPukLjbo73FCeT
-ae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaVHMf5NLWUhdWZXqBIoH7nF2W4onW4
-HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNdQlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0a
-E9jD2z3Il3rucO2n5nzbcc8tlGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw
-0JDnJwIDAQABo4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E
-BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4opvpXY0wfwYD
-VR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBodHRwczovL3d3dy5jYXRjZXJ0
-Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5l
-dC92ZXJhcnJlbCAwDQYJKoZIhvcNAQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJ
-lF7W2u++AVtd0x7Y/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNa
-Al6kSBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhyRp/7SNVe
-l+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOSAgu+TGbrIP65y7WZf+a2
-E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xlnJ2lYJU6Un/10asIbvPuW/mIPX64b24D
-5EI=
------END CERTIFICATE-----
-
-Actalis Authentication Root CA
-==============================
------BEGIN CERTIFICATE-----
-MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UEBhMCSVQxDjAM
-BgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UE
-AwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDky
-MjExMjIwMlowazELMAkGA1UEBhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlz
-IFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290
-IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNvUTufClrJ
-wkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX4ay8IMKx4INRimlNAJZa
-by/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9KK3giq0itFZljoZUj5NDKd45RnijMCO6
-zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1f
-YVEiVRvjRuPjPdA1YprbrxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2
-oxgkg4YQ51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2Fbe8l
-EfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxeKF+w6D9Fz8+vm2/7
-hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4Fv6MGn8i1zeQf1xcGDXqVdFUNaBr8
-EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbnfpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5
-jF66CyCU3nuDuP/jVo23Eek7jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLY
-iDrIn3hm7YnzezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt
-ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQALe3KHwGCmSUyI
-WOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70jsNjLiNmsGe+b7bAEzlgqqI0
-JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDzWochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKx
-K3JCaKygvU5a2hi/a5iB0P2avl4VSM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+
-Xlff1ANATIGk0k9jpwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC
-4yyXX04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+OkfcvHlXHo
-2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7RK4X9p2jIugErsWx0Hbhz
-lefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btUZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXem
-OR/qnuOf0GZvBeyqdn6/axag67XH/JJULysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9
-vwGYT7JZVEc+NHt4bVaTLnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg==
------END CERTIFICATE-----
-
-Trustis FPS Root CA
-===================
------BEGIN CERTIFICATE-----
-MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQG
-EwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQLExNUcnVzdGlzIEZQUyBSb290
-IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTExMzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNV
-BAoTD1RydXN0aXMgTGltaXRlZDEcMBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJ
-KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQ
-RUN+AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihHiTHcDnlk
-H5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjjvSkCqPoc4Vu5g6hBSLwa
-cY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zt
-o3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlBOrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEA
-AaNTMFEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAd
-BgNVHQ4EFgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01GX2c
-GE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmWzaD+vkAMXBJV+JOC
-yinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP41BIy+Q7DsdwyhEQsb8tGD+pmQQ9P
-8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZEf1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHV
-l/9D7S3B2l0pKoU/rGXuhg8FjZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYl
-iB6XzCGcKQENZetX2fNXlrtIzYE=
------END CERTIFICATE-----
-
-StartCom Certification Authority
-================================
------BEGIN CERTIFICATE-----
-MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMN
-U3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmlu
-ZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0
-NjM3WhcNMzYwOTE3MTk0NjM2WjB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRk
-LjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMg
-U3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
-ggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZkpMyONvg45iPwbm2xPN1y
-o4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rfOQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/
-Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/CJi/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/d
-eMotHweXMAEtcnn6RtYTKqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt
-2PZE4XNiHzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMMAv+Z
-6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w+2OqqGwaVLRcJXrJ
-osmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/
-untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVc
-UjyJthkqcwEKDwOzEmDyei+B26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT
-37uMdBNSSwIDAQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD
-VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFulF2mHMMo0aEPQ
-Qa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCCATgwLgYIKwYBBQUHAgEWImh0
-dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cu
-c3RhcnRzc2wuY29tL2ludGVybWVkaWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENv
-bW1lcmNpYWwgKFN0YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0
-aGUgc2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0aWZpY2F0
-aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93d3cuc3RhcnRzc2wuY29t
-L3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBG
-cmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5
-fPGFf59Jb2vKXfuM/gTFwWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWm
-N3PH/UvSTa0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst0OcN
-Org+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNcpRJvkrKTlMeIFw6T
-tn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKlCcWw0bdT82AUuoVpaiF8H3VhFyAX
-e2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVFP0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA
-2MFrLH9ZXF2RsXAiV+uKa0hK1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBs
-HvUwyKMQ5bLmKhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE
-JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ8dCAWZvLMdib
-D4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnmfyWl8kgAwKQB2j8=
------END CERTIFICATE-----
-
-StartCom Certification Authority G2
-===================================
------BEGIN CERTIFICATE-----
-MIIFYzCCA0ugAwIBAgIBOzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJJTDEWMBQGA1UEChMN
-U3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
-RzIwHhcNMTAwMTAxMDEwMDAxWhcNMzkxMjMxMjM1OTAxWjBTMQswCQYDVQQGEwJJTDEWMBQGA1UE
-ChMNU3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3Jp
-dHkgRzIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2iTZbB7cgNr2Cu+EWIAOVeq8O
-o1XJJZlKxdBWQYeQTSFgpBSHO839sj60ZwNq7eEPS8CRhXBF4EKe3ikj1AENoBB5uNsDvfOpL9HG
-4A/LnooUCri99lZi8cVytjIl2bLzvWXFDSxu1ZJvGIsAQRSCb0AgJnooD/Uefyf3lLE3PbfHkffi
-Aez9lInhzG7TNtYKGXmu1zSCZf98Qru23QumNK9LYP5/Q0kGi4xDuFby2X8hQxfqp0iVAXV16iul
-Q5XqFYSdCI0mblWbq9zSOdIxHWDirMxWRST1HFSr7obdljKF+ExP6JV2tgXdNiNnvP8V4so75qbs
-O+wmETRIjfaAKxojAuuKHDp2KntWFhxyKrOq42ClAJ8Em+JvHhRYW6Vsi1g8w7pOOlz34ZYrPu8H
-vKTlXcxNnw3h3Kq74W4a7I/htkxNeXJdFzULHdfBR9qWJODQcqhaX2YtENwvKhOuJv4KHBnM0D4L
-nMgJLvlblnpHnOl68wVQdJVznjAJ85eCXuaPOQgeWeU1FEIT/wCc976qUM/iUUjXuG+v+E5+M5iS
-FGI6dWPPe/regjupuznixL0sAA7IF6wT700ljtizkC+p2il9Ha90OrInwMEePnWjFqmveiJdnxMa
-z6eg6+OGCtP95paV1yPIN93EfKo2rJgaErHgTuixO/XWb/Ew1wIDAQABo0IwQDAPBgNVHRMBAf8E
-BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUS8W0QGutHLOlHGVuRjaJhwUMDrYwDQYJ
-KoZIhvcNAQELBQADggIBAHNXPyzVlTJ+N9uWkusZXn5T50HsEbZH77Xe7XRcxfGOSeD8bpkTzZ+K
-2s06Ctg6Wgk/XzTQLwPSZh0avZyQN8gMjgdalEVGKua+etqhqaRpEpKwfTbURIfXUfEpY9Z1zRbk
-J4kd+MIySP3bmdCPX1R0zKxnNBFi2QwKN4fRoxdIjtIXHfbX/dtl6/2o1PXWT6RbdejF0mCy2wl+
-JYt7ulKSnj7oxXehPOBKc2thz4bcQ///If4jXSRK9dNtD2IEBVeC2m6kMyV5Sy5UGYvMLD0w6dEG
-/+gyRr61M3Z3qAFdlsHB1b6uJcDJHgoJIIihDsnzb02CVAAgp9KP5DlUFy6NHrgbuxu9mk47EDTc
-nIhT76IxW1hPkWLIwpqazRVdOKnWvvgTtZ8SafJQYqz7Fzf07rh1Z2AQ+4NQ+US1dZxAF7L+/Xld
-blhYXzD8AK6vM8EOTmy6p6ahfzLbOOCxchcKK5HsamMm7YnUeMx0HgX4a/6ManY5Ka5lIxKVCCIc
-l85bBu4M4ru8H0ST9tg4RQUh7eStqxK2A6RCLi3ECToDZ2mEmuFZkIoohdVddLHRDiBYmxOlsGOm
-7XtH/UVVMKTumtTm4ofvmMkyghEpIrwACjFeLQ/Ajulrso8uBtjRkcfGEvRM/TAXw8HaOFvjqerm
-obp573PYtlNXLfbQ4ddI
------END CERTIFICATE-----
-
-Buypass Class 2 Root CA
-=======================
------BEGIN CERTIFICATE-----
-MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU
-QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMiBSb290IENBMB4X
-DTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1owTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1
-eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIw
-DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1
-g1Lr6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPVL4O2fuPn
-9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC911K2GScuVr1QGbNgGE41b
-/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHxMlAQTn/0hpPshNOOvEu/XAFOBz3cFIqU
-CqTqc/sLUegTBxj6DvEr0VQVfTzh97QZQmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeff
-awrbD02TTqigzXsu8lkBarcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgI
-zRFo1clrUs3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLiFRhn
-Bkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRSP/TizPJhk9H9Z2vX
-Uq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN9SG9dKpN6nIDSdvHXx1iY8f93ZHs
-M+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxPAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD
-VR0OBBYEFMmAd+BikoL1RpzzuvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF
-AAOCAgEAU18h9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s
-A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3tOluwlN5E40EI
-osHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo+fsicdl9sz1Gv7SEr5AcD48S
-aq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYd
-DnkM/crqJIByw5c/8nerQyIKx+u2DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWD
-LfJ6v9r9jv6ly0UsH8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0
-oyLQI+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK75t98biGC
-wWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h3PFaTWwyI0PurKju7koS
-CTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPzY11aWOIv4x3kqdbQCtCev9eBCfHJxyYN
-rJgWVqA=
------END CERTIFICATE-----
-
-Buypass Class 3 Root CA
-=======================
------BEGIN CERTIFICATE-----
-MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU
-QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMyBSb290IENBMB4X
-DTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFowTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1
-eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIw
-DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRH
-sJ8YZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3EN3coTRiR
-5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9tznDDgFHmV0ST9tD+leh
-7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX0DJq1l1sDPGzbjniazEuOQAnFN44wOwZ
-ZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH
-2xc519woe2v1n/MuwU8XKhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV
-/afmiSTYzIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvSO1UQ
-RwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D34xFMFbG02SrZvPA
-Xpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgPK9Dx2hzLabjKSWJtyNBjYt1gD1iq
-j6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD
-VR0OBBYEFEe4zf/lb+74suwvTg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF
-AAOCAgEAACAjQTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV
-cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXSIGrs/CIBKM+G
-uIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2HJLw5QY33KbmkJs4j1xrG0aG
-Q0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsaO5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8
-ZORK15FTAaggiG6cX0S5y2CBNOxv033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2
-KSb12tjE8nVhz36udmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz
-6MkEkbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg413OEMXbug
-UZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvDu79leNKGef9JOxqDDPDe
-eOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq4/g7u9xN12TyUb7mqqta6THuBrxzvxNi
-Cp/HuZc=
------END CERTIFICATE-----
-
-T-TeleSec GlobalRoot Class 3
-============================
------BEGIN CERTIFICATE-----
-MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM
-IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU
-cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgx
-MDAxMTAyOTU2WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz
-dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD
-ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0GCSqGSIb3
-DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN8ELg63iIVl6bmlQdTQyK
-9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/RLyTPWGrTs0NvvAgJ1gORH8EGoel15YU
-NpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZF
-iP0Zf3WHHx+xGwpzJFu5ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W
-0eDrXltMEnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGjQjBA
-MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1A/d2O2GCahKqGFPr
-AyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOyWL6ukK2YJ5f+AbGwUgC4TeQbIXQb
-fsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzT
-ucpH9sry9uetuUg/vBa3wW306gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7h
-P0HHRwA11fXT91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml
-e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4pTpPDpFQUWw==
------END CERTIFICATE-----
-
-Vivox Root CA
-=============
------BEGIN CERTIFICATE-----
-MIID5jCCA0+gAwIBAgIJAImvD34gft3eMA0GCSqGSIb3DQEBBAUAMIGpMRQwEgYD
-VQQKEwtWaXZveCwgSW5jLjEfMB0GA1UECxMWQ2VydGlmaWNhdGUgRGVwYXJ0bWVu
-dDEeMBwGCSqGSIb3DQEJARYPY2VydHNAdml2b3guY29tMRMwEQYDVQQHEwpGcmFt
-aW5naGFtMRYwFAYDVQQIEw1NYXNzYWNodXNldHRzMQswCQYDVQQGEwJVUzEWMBQG
-A1UEAxMNVml2b3ggUm9vdCBDQTAeFw0wNjEyMDExNjUzNDZaFw0xNjExMjgxNjUz
-NDZaMIGpMRQwEgYDVQQKEwtWaXZveCwgSW5jLjEfMB0GA1UECxMWQ2VydGlmaWNh
-dGUgRGVwYXJ0bWVudDEeMBwGCSqGSIb3DQEJARYPY2VydHNAdml2b3guY29tMRMw
-EQYDVQQHEwpGcmFtaW5naGFtMRYwFAYDVQQIEw1NYXNzYWNodXNldHRzMQswCQYD
-VQQGEwJVUzEWMBQGA1UEAxMNVml2b3ggUm9vdCBDQTCBnzANBgkqhkiG9w0BAQEF
-AAOBjQAwgYkCgYEAt6uRnN9SsAnM4LfLUB31ZUmRPxv+RrwSjDhQPbpmVGjQeeom
-5zU74pJ3WGtS6Iq6QYKah0NdqjQ1dEEd8943Bbfy0uqdfQbOmedjDKcGzAwvgKai
-2gJnKFi8pxbV4LYrFbtwMHzhQOHL5Ue5MICbCoX0fkTg+tmQ/cKu489jiRkCAwEA
-AaOCARIwggEOMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFAbenfLtlQ0ZUmc/tW0Q
-bWn3UgukMIHeBgNVHSMEgdYwgdOAFAbenfLtlQ0ZUmc/tW0QbWn3UgukoYGvpIGs
-MIGpMRQwEgYDVQQKEwtWaXZveCwgSW5jLjEfMB0GA1UECxMWQ2VydGlmaWNhdGUg
-RGVwYXJ0bWVudDEeMBwGCSqGSIb3DQEJARYPY2VydHNAdml2b3guY29tMRMwEQYD
-VQQHEwpGcmFtaW5naGFtMRYwFAYDVQQIEw1NYXNzYWNodXNldHRzMQswCQYDVQQG
-EwJVUzEWMBQGA1UEAxMNVml2b3ggUm9vdCBDQYIJAImvD34gft3eMA0GCSqGSIb3
-DQEBBAUAA4GBAFZMWOh7lT7fOMakbcV4sh1ePd5bm04QdUn/rKTfERuiBc1UC1Qq
-PAgtvJvl39wIB581WE7+QZZDUQc4hUlFQetbXSnXIkZ1kLH2wPuKgkunKjXviuzk
-ZGgJSPbsCb2+Ika9Cd4V6bNzucZp523TcSNNNmimyFR1iuEryLSEpI1v
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEUDCCA7mgAwIBAgIJAN4ppNGwj6yIMA0GCSqGSIb3DQEBBAUAMIHMMQswCQYD
-VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5j
-aXNjbzEZMBcGA1UEChMQTGluZGVuIExhYiwgSW5jLjEpMCcGA1UECxMgTGluZGVu
-IExhYiBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxKTAnBgNVBAMTIExpbmRlbiBMYWIg
-Q2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYJKoZIhvcNAQkBFhBjYUBsaW5kZW5s
-YWIuY29tMB4XDTA1MDQyMTAyNDAzMVoXDTI1MDQxNjAyNDAzMVowgcwxCzAJBgNV
-BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNp
-c2NvMRkwFwYDVQQKExBMaW5kZW4gTGFiLCBJbmMuMSkwJwYDVQQLEyBMaW5kZW4g
-TGFiIENlcnRpZmljYXRlIEF1dGhvcml0eTEpMCcGA1UEAxMgTGluZGVuIExhYiBD
-ZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgkqhkiG9w0BCQEWEGNhQGxpbmRlbmxh
-Yi5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKXh1MThucdTbMg9bYBO
-rAm8yWns32YojB0PRfbq8rUjepEhTm3/13s0u399Uc202v4ejcGhkIDWJZd2NZMF
-oKrhmRfxGHSKPCuFaXC3jh0lRECj7k8FoPkcmaPjSyodrDFDUUuv+C06oYJoI+rk
-8REyal9NwgHvqCzOrZtiTXAdAgMBAAGjggE2MIIBMjAdBgNVHQ4EFgQUO1zK2e1f
-1wO1fHAjq6DTJobKDrcwggEBBgNVHSMEgfkwgfaAFDtcytntX9cDtXxwI6ug0yaG
-yg63oYHSpIHPMIHMMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEW
-MBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEZMBcGA1UEChMQTGluZGVuIExhYiwgSW5j
-LjEpMCcGA1UECxMgTGluZGVuIExhYiBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxKTAn
-BgNVBAMTIExpbmRlbiBMYWIgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYJKoZI
-hvcNAQkBFhBjYUBsaW5kZW5sYWIuY29tggkA3imk0bCPrIgwDAYDVR0TBAUwAwEB
-/zANBgkqhkiG9w0BAQQFAAOBgQA/ZkgfvwHYqk1UIAKZS3kMCxz0HvYuEQtviwnu
-xA39CIJ65Zozs28Eg1aV9/Y+Of7TnWhW+U3J3/wD/GghaAGiKK6vMn9gJBIdBX/9
-e6ef37VGyiOEFFjnUIbuk0RWty0orN76q/lI/xjCi15XSA/VSq2j4vmnwfZcPTDu
-glmQ1A==
------END CERTIFICATE-----
diff --git a/indra/newview/cursors_mac/UI_CURSOR_PIPETTE.tif b/indra/newview/cursors_mac/UI_CURSOR_PIPETTE.tif
new file mode 100644
index 0000000000..b4780967f9
--- /dev/null
+++ b/indra/newview/cursors_mac/UI_CURSOR_PIPETTE.tif
Binary files differ
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index f67bb22f5b..901294d6b4 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -1580,6 +1580,8 @@ void LLAgent::setAutoPilotTargetGlobal(const LLVector3d &target_global)
LLViewerObject *obj;
LLWorld::getInstance()->resolveStepHeightGlobal(NULL, target_global, traceEndPt, targetOnGround, groundNorm, &obj);
+ // Note: this might malfunction for sitting agent, since pelvis stays same, but agent's position becomes lower
+ // But for autopilot to work we assume that agent is standing and ready to go.
F64 target_height = llmax((F64)gAgentAvatarp->getPelvisToFoot(), target_global.mdV[VZ] - targetOnGround.mdV[VZ]);
// clamp z value of target to minimum height above ground
@@ -3943,8 +3945,7 @@ void LLAgent::teleportRequest(
bool look_at_from_camera)
{
LLViewerRegion* regionp = getRegion();
- bool is_local = (region_handle == regionp->getHandle());
- if(regionp && teleportCore(is_local))
+ if (regionp && teleportCore(region_handle == regionp->getHandle()))
{
LL_INFOS("") << "TeleportLocationRequest: '" << region_handle << "':"
<< pos_local << LL_ENDL;
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 0fb811a386..c0f88ef704 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -1919,7 +1919,7 @@ bool LLAppearanceMgr::getCanReplaceCOF(const LLUUID& outfit_cat_id)
}
// Check whether it's the base outfit.
- if (outfit_cat_id.isNull() || outfit_cat_id == getBaseOutfitUUID())
+ if (outfit_cat_id.isNull())
{
return false;
}
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 07724e8ab7..f705084bdb 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -43,6 +43,7 @@
#include "llagentui.h"
#include "llagentwearables.h"
#include "llfloaterimcontainer.h"
+#include "llimprocessing.h"
#include "llwindow.h"
#include "llviewerstats.h"
#include "llviewerstatsrecorder.h"
@@ -353,6 +354,8 @@ BOOL gCrashOnStartup = FALSE;
BOOL gLLErrorActivated = FALSE;
BOOL gLogoutInProgress = FALSE;
+BOOL gSimulateMemLeak = FALSE;
+
////////////////////////////////////////////////////////////
// Internal globals... that should be removed.
static std::string gArgs;
@@ -546,27 +549,6 @@ bool create_text_segment_icon_from_url_match(LLUrlMatch* match,LLTextBase* base)
return true;
}
-void request_initial_instant_messages()
-{
- static BOOL requested = FALSE;
- if (!requested
- && gMessageSystem
- && LLMuteList::getInstance()->isLoaded()
- && isAgentAvatarValid())
- {
- // Auto-accepted inventory items may require the avatar object
- // to build a correct name. Likewise, inventory offers from
- // muted avatars require the mute list to properly mute.
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_RetrieveInstantMessages);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- gAgent.sendReliableMessage();
- requested = TRUE;
- }
-}
-
// Use these strictly for things that are constructed at startup,
// or for things that are performance critical. JC
static void settings_to_globals()
@@ -581,6 +563,7 @@ static void settings_to_globals()
LLSurface::setTextureSize(gSavedSettings.getU32("RegionTextureSize"));
LLRender::sGLCoreProfile = gSavedSettings.getBOOL("RenderGLCoreProfile");
+ LLRender::sNsightDebugSupport = gSavedSettings.getBOOL("RenderNsightDebugSupport");
LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO");
LLImageGL::sGlobalUseAnisotropic = gSavedSettings.getBOOL("RenderAnisotropic");
LLImageGL::sCompressTextures = gSavedSettings.getBOOL("RenderCompressTextures");
@@ -797,7 +780,6 @@ bool LLAppViewer::init()
initMaxHeapSize() ;
LLCoros::instance().setStackSize(gSavedSettings.getS32("CoroutineStackSize"));
- LLPrivateMemoryPoolManager::initClass((BOOL)gSavedSettings.getBOOL("MemoryPrivatePoolEnabled"), (U32)gSavedSettings.getU32("MemoryPrivatePoolSize")*1024*1024) ;
// write Google Breakpad minidump files to a per-run dump directory to avoid multiple viewer issues.
std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "");
mDumpPath = logdir;
@@ -977,10 +959,11 @@ bool LLAppViewer::init()
if (!initCache())
{
+ LL_WARNS("InitInfo") << "Failed to init cache" << LL_ENDL;
std::ostringstream msg;
msg << LLTrans::getString("MBUnableToAccessFile");
OSMessageBox(msg.str(),LLStringUtil::null,OSMB_OK);
- return 1;
+ return 0;
}
LL_INFOS("InitInfo") << "Cache initialization is done." << LL_ENDL ;
@@ -1322,13 +1305,49 @@ LLTrace::BlockTimerStatHandle FTM_FRAME("Frame");
bool LLAppViewer::frame()
{
+ bool ret = false;
+
+ if (gSimulateMemLeak)
+ {
+ try
+ {
+ ret = doFrame();
+ }
+ catch (const LLContinueError&)
+ {
+ LOG_UNHANDLED_EXCEPTION("");
+ }
+ catch (std::bad_alloc)
+ {
+ LLMemory::logMemoryInfo(TRUE);
+ LLFloaterMemLeak* mem_leak_instance = LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking");
+ if (mem_leak_instance)
+ {
+ mem_leak_instance->stop();
+ }
+ LL_WARNS() << "Bad memory allocation in LLAppViewer::frame()!" << LL_ENDL;
+ }
+ }
+ else
+ {
+ try
+ {
+ ret = doFrame();
+ }
+ catch (const LLContinueError&)
+ {
+ LOG_UNHANDLED_EXCEPTION("");
+ }
+ }
+
+ return ret;
+}
+
+bool LLAppViewer::doFrame()
+{
LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));
LLSD newFrame;
- //LLPrivateMemoryPoolTester::getInstance()->run(false) ;
- //LLPrivateMemoryPoolTester::getInstance()->run(true) ;
- //LLPrivateMemoryPoolTester::destroy() ;
-
LL_RECORD_BLOCK_TIME(FTM_FRAME);
LLTrace::BlockTimer::processTimes();
LLTrace::get_frame_recording().nextPeriod();
@@ -1342,7 +1361,6 @@ bool LLAppViewer::frame()
//check memory availability information
checkMemory() ;
- try
{
pingMainloopTimeout("Main:MiscNativeWindowEvents");
@@ -1366,11 +1384,14 @@ bool LLAppViewer::frame()
}
//memory leaking simulation
- LLFloaterMemLeak* mem_leak_instance =
- LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking");
- if(mem_leak_instance)
+ if (gSimulateMemLeak)
{
- mem_leak_instance->idle() ;
+ LLFloaterMemLeak* mem_leak_instance =
+ LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking");
+ if (mem_leak_instance)
+ {
+ mem_leak_instance->idle();
+ }
}
// canonical per-frame event
@@ -1383,7 +1404,8 @@ bool LLAppViewer::frame()
// Scan keyboard for movement keys. Command keys and typing
// are handled by windows callbacks. Don't do this until we're
// done initializing. JC
- if ((gHeadlessClient || gViewerWindow->getWindow()->getVisible())
+ if (gViewerWindow
+ && (gHeadlessClient || gViewerWindow->getWindow()->getVisible())
&& gViewerWindow->getActive()
&& !gViewerWindow->getWindow()->getMinimized()
&& LLStartUp::getStartupState() == STATE_STARTED
@@ -1414,7 +1436,7 @@ bool LLAppViewer::frame()
// Render scene.
// *TODO: Should we run display() even during gHeadlessClient? DK 2011-02-18
- if (!LLApp::isExiting() && !gHeadlessClient)
+ if (!LLApp::isExiting() && !gHeadlessClient && gViewerWindow)
{
pingMainloopTimeout("Main:Display");
gGLActive = TRUE;
@@ -1546,60 +1568,13 @@ bool LLAppViewer::frame()
pingMainloopTimeout("Main:End");
}
}
- catch (const LLContinueError&)
- {
- LOG_UNHANDLED_EXCEPTION("");
- }
- catch(std::bad_alloc)
- {
- LLMemory::logMemoryInfo(TRUE) ;
-
- //stop memory leaking simulation
- LLFloaterMemLeak* mem_leak_instance =
- LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking");
- if(mem_leak_instance)
- {
- mem_leak_instance->stop() ;
- LL_WARNS() << "Bad memory allocation in LLAppViewer::frame()!" << LL_ENDL ;
- }
- else
- {
- //output possible call stacks to log file.
- LLError::LLCallStacks::print() ;
-
- LL_ERRS() << "Bad memory allocation in LLAppViewer::frame()!" << LL_ENDL ;
- }
- }
- catch (...)
- {
- CRASH_ON_UNHANDLED_EXCEPTION("");
- }
if (LLApp::isExiting())
{
// Save snapshot for next time, if we made it through initialization
if (STATE_STARTED == LLStartUp::getStartupState())
{
- try
- {
- saveFinalSnapshot();
- }
- catch(std::bad_alloc)
- {
- LL_WARNS() << "Bad memory allocation when saveFinalSnapshot() is called!" << LL_ENDL ;
-
- //stop memory leaking simulation
- LLFloaterMemLeak* mem_leak_instance =
- LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking");
- if(mem_leak_instance)
- {
- mem_leak_instance->stop() ;
- }
- }
- catch (...)
- {
- CRASH_ON_UNHANDLED_EXCEPTION("saveFinalSnapshot()");
- }
+ saveFinalSnapshot();
}
delete gServicePump;
@@ -1656,7 +1631,10 @@ bool LLAppViewer::cleanup()
LLEventPumps::instance().reset();
//dump scene loading monitor results
- LLSceneMonitor::instance().dumpToFile(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "scene_monitor_results.csv"));
+ if (LLSceneMonitor::instanceExists())
+ {
+ LLSceneMonitor::instance().dumpToFile(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "scene_monitor_results.csv"));
+ }
// There used to be an 'if (LLFastTimerView::sAnalyzePerformance)' block
// here, completely redundant with the one that occurs later in this same
@@ -1698,7 +1676,10 @@ bool LLAppViewer::cleanup()
// Give any remaining SLPlugin instances a chance to exit cleanly.
LLPluginProcessParent::shutdown();
- LLVoiceClient::getInstance()->terminate();
+ if (LLVoiceClient::instanceExists())
+ {
+ LLVoiceClient::getInstance()->terminate();
+ }
disconnectViewer();
@@ -1754,7 +1735,10 @@ bool LLAppViewer::cleanup()
// Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be deleted.
- LLWorldMap::getInstance()->reset(); // release any images
+ if (LLWorldMap::instanceExists())
+ {
+ LLWorldMap::getInstance()->reset(); // release any images
+ }
LLCalc::cleanUp();
@@ -1927,10 +1911,16 @@ bool LLAppViewer::cleanup()
LLURLHistory::saveFile("url_history.xml");
// save mute list. gMuteList used to also be deleted here too.
- LLMuteList::getInstance()->cache(gAgent.getID());
+ if (gAgent.isInitialized() && LLMuteList::instanceExists())
+ {
+ LLMuteList::getInstance()->cache(gAgent.getID());
+ }
//save call log list
- LLConversationLog::instance().cache();
+ if (LLConversationLog::instanceExists())
+ {
+ LLConversationLog::instance().cache();
+ }
if (mPurgeOnExit)
{
@@ -2080,9 +2070,6 @@ bool LLAppViewer::cleanup()
LLMainLoopRepeater::instance().stop();
- //release all private memory pools.
- LLPrivateMemoryPoolManager::destroyClass() ;
-
ll_close_fail_log();
LLError::LLCallStacks::cleanup();
@@ -3238,7 +3225,7 @@ LLSD LLAppViewer::getViewerInfo() const
return info;
}
-std::string LLAppViewer::getViewerInfoString() const
+std::string LLAppViewer::getViewerInfoString(bool default_string) const
{
std::ostringstream support;
@@ -3248,7 +3235,7 @@ std::string LLAppViewer::getViewerInfoString() const
LLStringUtil::format_map_t args;
// allow the "Release Notes" URL label to be localized
- args["ReleaseNotes"] = LLTrans::getString("ReleaseNotes");
+ args["ReleaseNotes"] = LLTrans::getString("ReleaseNotes", default_string);
for (LLSD::map_const_iterator ii(info.beginMap()), iend(info.endMap());
ii != iend; ++ii)
@@ -3258,7 +3245,7 @@ std::string LLAppViewer::getViewerInfoString() const
// Scalar value
if (ii->second.isUndefined())
{
- args[ii->first] = LLTrans::getString("none_text");
+ args[ii->first] = LLTrans::getString("none_text", default_string);
}
else
{
@@ -3277,101 +3264,37 @@ std::string LLAppViewer::getViewerInfoString() const
}
// Now build the various pieces
- support << LLTrans::getString("AboutHeader", args);
+ support << LLTrans::getString("AboutHeader", args, default_string);
if (info.has("BUILD_CONFIG"))
{
- support << "\n" << LLTrans::getString("BuildConfig", args);
+ support << "\n" << LLTrans::getString("BuildConfig", args, default_string);
}
if (info.has("REGION"))
{
- support << "\n\n" << LLTrans::getString("AboutPosition", args);
+ support << "\n\n" << LLTrans::getString("AboutPosition", args, default_string);
}
- support << "\n\n" << LLTrans::getString("AboutSystem", args);
+ support << "\n\n" << LLTrans::getString("AboutSystem", args, default_string);
support << "\n";
if (info.has("GRAPHICS_DRIVER_VERSION"))
{
- support << "\n" << LLTrans::getString("AboutDriver", args);
+ support << "\n" << LLTrans::getString("AboutDriver", args, default_string);
}
- support << "\n" << LLTrans::getString("AboutOGL", args);
- support << "\n\n" << LLTrans::getString("AboutSettings", args);
- support << "\n\n" << LLTrans::getString("AboutLibs", args);
+ support << "\n" << LLTrans::getString("AboutOGL", args, default_string);
+ support << "\n\n" << LLTrans::getString("AboutSettings", args, default_string);
+ support << "\n\n" << LLTrans::getString("AboutLibs", args, default_string);
if (info.has("COMPILER"))
{
- support << "\n" << LLTrans::getString("AboutCompiler", args);
+ support << "\n" << LLTrans::getString("AboutCompiler", args, default_string);
}
if (info.has("PACKETS_IN"))
{
- support << '\n' << LLTrans::getString("AboutTraffic", args);
+ support << '\n' << LLTrans::getString("AboutTraffic", args, default_string);
}
// SLT timestamp
LLSD substitution;
substitution["datetime"] = (S32)time(NULL);//(S32)time_corrected();
- support << "\n" << LLTrans::getString("AboutTime", substitution);
-
- return support.str();
-}
-
-std::string LLAppViewer::getShortViewerInfoString() const
-{
- std::ostringstream support;
- LLSD info(getViewerInfo());
-
- support << LLTrans::getString("APP_NAME") << " " << info["VIEWER_VERSION_STR"].asString();
- support << " (" << info["CHANNEL"].asString() << ")";
- if (info.has("BUILD_CONFIG"))
- {
- support << "\n" << "Build Configuration " << info["BUILD_CONFIG"].asString();
- }
- if (info.has("REGION"))
- {
- support << "\n\n" << "You are at " << ll_vector3_from_sd(info["POSITION_LOCAL"]) << " in " << info["REGION"].asString();
- support << " located at " << info["HOSTNAME"].asString() << " (" << info["HOSTIP"].asString() << ")";
- support << "\n" << "SLURL: " << info["SLURL"].asString();
- support << "\n" << "(Global coordinates " << ll_vector3_from_sd(info["POSITION"]) << ")";
- support << "\n" << info["SERVER_VERSION"].asString();
- }
-
- support << "\n\n" << "CPU: " << info["CPU"].asString();
- support << "\n" << "Memory: " << info["MEMORY_MB"].asString() << " MB";
- support << "\n" << "OS: " << info["OS_VERSION"].asString();
- support << "\n" << "Graphics Card: " << info["GRAPHICS_CARD"].asString() << " (" << info["GRAPHICS_CARD_VENDOR"].asString() << ")";
-
- if (info.has("GRAPHICS_DRIVER_VERSION"))
- {
- support << "\n" << "Windows Graphics Driver Version: " << info["GRAPHICS_DRIVER_VERSION"].asString();
- }
-
- support << "\n" << "OpenGL Version: " << info["OPENGL_VERSION"].asString();
-
- support << "\n\n" << "Window size:" << info["WINDOW_WIDTH"].asString() << "x" << info["WINDOW_HEIGHT"].asString();
- support << "\n" << "Language: " << LLUI::getLanguage();
- support << "\n" << "Font Size Adjustment: " << info["FONT_SIZE_ADJUSTMENT"].asString() << "pt";
- support << "\n" << "UI Scaling: " << info["UI_SCALE"].asString();
- support << "\n" << "Draw distance: " << info["DRAW_DISTANCE"].asString();
- support << "\n" << "Bandwidth: " << info["NET_BANDWITH"].asString() << "kbit/s";
- support << "\n" << "LOD factor: " << info["LOD_FACTOR"].asString();
- support << "\n" << "Render quality: " << info["RENDER_QUALITY"].asString() << " / 7";
- support << "\n" << "ALM: " << info["GPU_SHADERS"].asString();
- support << "\n" << "Texture memory: " << info["TEXTURE_MEMORY"].asString() << "MB";
- support << "\n" << "VFS (cache) creation time: " << info["VFS_TIME"].asString();
-
- support << "\n\n" << "J2C Decoder: " << info["J2C_VERSION"].asString();
- support << "\n" << "Audio Driver: " << info["AUDIO_DRIVER_VERSION"].asString();
- support << "\n" << "LLCEFLib/CEF: " << info["LLCEFLIB_VERSION"].asString();
- support << "\n" << "LibVLC: " << info["LIBVLC_VERSION"].asString();
- support << "\n" << "Voice Server: " << info["VOICE_VERSION"].asString();
-
- if (info.has("PACKETS_IN"))
- {
- support << "\n" << "Packets Lost: " << info["PACKETS_LOST"].asInteger() << "/" << info["PACKETS_IN"].asInteger();
- F32 packets_pct = info["PACKETS_PCT"].asReal();
- support << " (" << ll_round(packets_pct, 0.001f) << "%)";
- }
-
- LLSD substitution;
- substitution["datetime"] = (S32)time(NULL);
- support << "\n" << LLTrans::getString("AboutTime", substitution);
+ support << "\n" << LLTrans::getString("AboutTime", substitution, default_string);
return support.str();
}
@@ -4690,7 +4613,7 @@ void LLAppViewer::idle()
// Must wait until both have avatar object and mute list, so poll
// here.
- request_initial_instant_messages();
+ LLIMProcessing::requestOfflineMessages();
///////////////////////////////////
//
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 6eb45d2495..e607b4a994 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -99,8 +99,7 @@ public:
void setServerReleaseNotesURL(const std::string& url) { mServerReleaseNotesURL = url; }
LLSD getViewerInfo() const;
- std::string getViewerInfoString() const;
- std::string getShortViewerInfoString() const;
+ std::string getViewerInfoString(bool default_string = false) const;
// Report true if under the control of a debugger. A null-op default.
virtual bool beingDebugged() { return false; }
@@ -222,6 +221,8 @@ protected:
private:
+ bool doFrame();
+
void initMaxHeapSize();
bool initThreads(); // Initialize viewer threads, return false on failure.
bool initConfiguration(); // Initialize settings from the command line/config file.
@@ -396,4 +397,6 @@ extern LLUUID gBlackSquareID;
extern BOOL gRandomizeFramerate;
extern BOOL gPeriodicSlowFrame;
+extern BOOL gSimulateMemLeak;
+
#endif // LL_LLAPPVIEWER_H
diff --git a/indra/newview/llavatarrenderinfoaccountant.cpp b/indra/newview/llavatarrenderinfoaccountant.cpp
index 7413dbed20..7c7f55f68c 100644
--- a/indra/newview/llavatarrenderinfoaccountant.cpp
+++ b/indra/newview/llavatarrenderinfoaccountant.cpp
@@ -286,6 +286,9 @@ void LLAvatarRenderInfoAccountant::sendRenderInfoToRegion(LLViewerRegion * regio
&& regionp->getRenderInfoReportTimer().hasExpired() // Time to make request)
)
{
+ // make sure we won't re-report, coro will update timer with correct time later
+ regionp->getRenderInfoReportTimer().resetWithExpiry(SECS_BETWEEN_REGION_REPORTS);
+
std::string coroname =
LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro",
boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro, url, regionp->getHandle()));
@@ -306,6 +309,9 @@ void LLAvatarRenderInfoAccountant::getRenderInfoFromRegion(LLViewerRegion * regi
<< " from " << url
<< LL_ENDL;
+ // make sure we won't re-request, coro will update timer with correct time later
+ regionp->getRenderInfoRequestTimer().resetWithExpiry(SECS_BETWEEN_REGION_REQUEST);
+
// First send a request to get the latest data
std::string coroname =
LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro",
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index a9e8e77a0b..97a71a8802 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -53,6 +53,7 @@
#include "llstylemap.h"
#include "llslurl.h"
#include "lllayoutstack.h"
+#include "llnotifications.h"
#include "llnotificationsutil.h"
#include "lltoastnotifypanel.h"
#include "lltooltip.h"
@@ -1315,44 +1316,52 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
// notify processing
if (chat.mNotifId.notNull())
{
- bool create_toast = true;
- for (LLToastNotifyPanel::instance_iter ti(LLToastNotifyPanel::beginInstances())
- , tend(LLToastNotifyPanel::endInstances()); ti != tend; ++ti)
- {
- LLToastNotifyPanel& panel = *ti;
- LLIMToastNotifyPanel * imtoastp = dynamic_cast<LLIMToastNotifyPanel *>(&panel);
- const std::string& notification_name = panel.getNotificationName();
- if (notification_name == "OfferFriendship" && panel.isControlPanelEnabled() && imtoastp)
- {
- create_toast = false;
- break;
- }
- }
-
- if (create_toast)
- {
LLNotificationPtr notification = LLNotificationsUtil::find(chat.mNotifId);
if (notification != NULL)
{
- LLIMToastNotifyPanel* notify_box = new LLIMToastNotifyPanel(
- notification, chat.mSessionID, LLRect::null, !use_plain_text_chat_history, mEditor);
-
- //Prepare the rect for the view
- LLRect target_rect = mEditor->getDocumentView()->getRect();
- // squeeze down the widget by subtracting padding off left and right
- target_rect.mLeft += mLeftWidgetPad + mEditor->getHPad();
- target_rect.mRight -= mRightWidgetPad;
- notify_box->reshape(target_rect.getWidth(), notify_box->getRect().getHeight());
- notify_box->setOrigin(target_rect.mLeft, notify_box->getRect().mBottom);
+ bool create_toast = true;
+ if (notification->getName() == "OfferFriendship")
+ {
+ // We don't want multiple friendship offers to appear, this code checks if there are previous offers
+ // by iterating though all panels.
+ // Note: it might be better to simply add a "pending offer" flag somewhere
+ for (LLToastNotifyPanel::instance_iter ti(LLToastNotifyPanel::beginInstances())
+ , tend(LLToastNotifyPanel::endInstances()); ti != tend; ++ti)
+ {
+ LLToastNotifyPanel& panel = *ti;
+ LLIMToastNotifyPanel * imtoastp = dynamic_cast<LLIMToastNotifyPanel *>(&panel);
+ const std::string& notification_name = panel.getNotificationName();
+ if (notification_name == "OfferFriendship"
+ && panel.isControlPanelEnabled()
+ && imtoastp)
+ {
+ create_toast = false;
+ break;
+ }
+ }
+ }
- LLInlineViewSegment::Params params;
- params.view = notify_box;
- params.left_pad = mLeftWidgetPad;
- params.right_pad = mRightWidgetPad;
- mEditor->appendWidget(params, "\n", false);
+ if (create_toast)
+ {
+ LLIMToastNotifyPanel* notify_box = new LLIMToastNotifyPanel(
+ notification, chat.mSessionID, LLRect::null, !use_plain_text_chat_history, mEditor);
+
+ //Prepare the rect for the view
+ LLRect target_rect = mEditor->getDocumentView()->getRect();
+ // squeeze down the widget by subtracting padding off left and right
+ target_rect.mLeft += mLeftWidgetPad + mEditor->getHPad();
+ target_rect.mRight -= mRightWidgetPad;
+ notify_box->reshape(target_rect.getWidth(), notify_box->getRect().getHeight());
+ notify_box->setOrigin(target_rect.mLeft, notify_box->getRect().mBottom);
+
+ LLInlineViewSegment::Params params;
+ params.view = notify_box;
+ params.left_pad = mLeftWidgetPad;
+ params.right_pad = mRightWidgetPad;
+ mEditor->appendWidget(params, "\n", false);
+ }
}
}
- }
// usual messages showing
else
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index f956023358..6ca8f1ae9c 100644
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -50,6 +50,7 @@
#include "llviewerobjectlist.h"
#include "llviewerwindow.h"
#include "llvocache.h"
+#include "lldrawpoolavatar.h"
const F32 MIN_INTERPOLATE_DISTANCE_SQUARED = 0.001f * 0.001f;
const F32 MAX_INTERPOLATE_DISTANCE_SQUARED = 10.f * 10.f;
@@ -143,6 +144,28 @@ void LLDrawable::init(bool new_entry)
initVisible(sCurVisible - 2);//invisible for the current frame and the last frame.
}
+void LLDrawable::unload()
+{
+ LLVOVolume *pVVol = getVOVolume();
+ pVVol->setNoLOD();
+
+ for (S32 i = 0; i < getNumFaces(); i++)
+ {
+ LLFace* facep = getFace(i);
+ if (facep->isState(LLFace::RIGGED))
+ {
+ LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*)facep->getPool();
+ if (pool) {
+ pool->removeRiggedFace(facep);
+ }
+ facep->setVertexBuffer(NULL);
+ }
+ facep->clearState(LLFace::RIGGED);
+ }
+
+ pVVol->markForUpdate(TRUE);
+}
+
// static
void LLDrawable::initClass()
{
@@ -595,7 +618,7 @@ F32 LLDrawable::updateXform(BOOL undamped)
BOOL damped = !undamped;
// Position
- LLVector3 old_pos(mXform.getPosition());
+ const LLVector3 old_pos(mXform.getPosition());
LLVector3 target_pos;
if (mXform.isRoot())
{
@@ -609,7 +632,7 @@ F32 LLDrawable::updateXform(BOOL undamped)
}
// Rotation
- LLQuaternion old_rot(mXform.getRotation());
+ const LLQuaternion old_rot(mXform.getRotation());
LLQuaternion target_rot = mVObjp->getRotation();
//scaling
LLVector3 target_scale = mVObjp->getScale();
@@ -644,6 +667,9 @@ F32 LLDrawable::updateXform(BOOL undamped)
{
// snap to final position (only if no target omega is applied)
dist_squared = 0.0f;
+ //set target scale here, because of dist_squared = 0.0f remove object from move list
+ mCurrentScale = target_scale;
+
if (getVOVolume() && !isRoot())
{ //child prim snapping to some position, needs a rebuild
gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE);
@@ -660,11 +686,16 @@ F32 LLDrawable::updateXform(BOOL undamped)
//dist_squared += dist_vec_squared(old_scale, target_scale);
}
- LLVector3 vec = mCurrentScale-target_scale;
+ const LLVector3 vec = mCurrentScale-target_scale;
+
+ //It's a very important on each cycle on Drawable::update form(), when object remained in move
+ //, list update the CurrentScale member, because if do not do that, it remained in this list forever
+ //or when the delta time between two frames a become a sufficiently large (due to interpolation)
+ //for overcome the MIN_INTERPOLATE_DISTANCE_SQUARED.
+ mCurrentScale = target_scale;
if (vec*vec > MIN_INTERPOLATE_DISTANCE_SQUARED)
{ //scale change requires immediate rebuild
- mCurrentScale = target_scale;
gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE);
}
else if (!isRoot() &&
@@ -979,9 +1010,7 @@ void LLDrawable::updateSpatialExtents()
if (mVObjp)
{
const LLVector4a* exts = getSpatialExtents();
- LLVector4a extents[2];
- extents[0] = exts[0];
- extents[1] = exts[1];
+ LLVector4a extents[2] = { exts[0], exts[1] };
mVObjp->updateSpatialExtents(extents[0], extents[1]);
setSpatialExtents(extents[0], extents[1]);
diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h
index a3461d4c01..14d782d6f2 100644
--- a/indra/newview/lldrawable.h
+++ b/indra/newview/lldrawable.h
@@ -84,6 +84,7 @@ public:
void markDead(); // Mark this drawable as dead
BOOL isDead() const { return isState(DEAD); }
BOOL isNew() const { return !isState(BUILT); }
+ BOOL isUnload() const { return isState(FOR_UNLOAD); }
BOOL isLight() const;
@@ -141,6 +142,7 @@ public:
void mergeFaces(LLDrawable* src);
void init(bool new_entry);
+ void unload();
void destroy();
void update();
@@ -282,6 +284,7 @@ public:
PARTITION_MOVE = 0x10000000,
ANIMATED_CHILD = 0x20000000,
ACTIVE_CHILD = 0x40000000,
+ FOR_UNLOAD = 0x80000000, //should be unload from memory
} EDrawableFlags;
public:
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index f74164aea6..075375082d 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -49,6 +49,7 @@
#include "llviewercamera.h"
#include "lldrawpoolwlsky.h"
#include "llglslshader.h"
+#include "llglcommonfunc.h"
S32 LLDrawPool::sNumDrawPools = 0;
@@ -504,7 +505,9 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba
{
params.mGroup->rebuildMesh();
}
-
+
+ LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
+
params.mVertexBuffer->setBuffer(mask);
params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index 60056ac21d..b0d48abb14 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -47,6 +47,7 @@
#include "llviewerregion.h"
#include "lldrawpoolwater.h"
#include "llspatialpartition.h"
+#include "llglcommonfunc.h"
BOOL LLDrawPoolAlpha::sShowDebugAlpha = FALSE;
@@ -324,6 +325,9 @@ void LLDrawPoolAlpha::render(S32 pass)
pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
pushBatches(LLRenderPass::PASS_ALPHA_INVISIBLE, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
+ gGL.diffuseColor4f(0, 0, 1, 1);
+ pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
+
if(shaders)
{
gHighlightProgram.unbind();
@@ -583,11 +587,14 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
{
LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_PUSH);
- gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);
- params.mVertexBuffer->setBuffer(mask & ~(params.mFullbright ? (LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2) : 0));
-
- params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
- gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
+
+ LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
+
+ gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);
+ params.mVertexBuffer->setBuffer(mask & ~(params.mFullbright ? (LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2) : 0));
+
+ params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
+ gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
}
// If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow). Interleaving these state-changing calls could be expensive, but glow must be drawn Z-sorted with alpha.
@@ -597,7 +604,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
{
// install glow-accumulating blend mode
gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, // don't touch color
- LLRender::BF_ONE, LLRender::BF_ONE); // add to alpha (glow)
+ LLRender::BF_ONE, LLRender::BF_ONE); // add to alpha (glow)
emissive_shader->bind();
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 8128790eb6..ef69990170 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -1574,6 +1574,11 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(
LLPointer<LLVertexBuffer> buffer = face->getVertexBuffer();
LLDrawable* drawable = face->getDrawable();
+ if (drawable->getVOVolume() && drawable->getVOVolume()->isNoLOD())
+ {
+ return;
+ }
+
U32 data_mask = face->getRiggedVertexBufferDataMask();
if (!vol_face.mWeightsScrubbed)
@@ -1621,7 +1626,9 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(
return;
}
- if (sShaderLevel <= 0 && face->mLastSkinTime < avatar->getLastSkinTime())
+ if (!buffer.isNull() &&
+ sShaderLevel <= 0 &&
+ face->mLastSkinTime < avatar->getLastSkinTime())
{
//perform software vertex skinning for this face
LLStrider<LLVector3> position;
@@ -1914,7 +1921,7 @@ void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar)
LLVOVolume* vobj = drawable->getVOVolume();
- if (!vobj)
+ if (!vobj || vobj->isNoLOD())
{
continue;
}
diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp
index f92320490a..63e96a93b5 100644
--- a/indra/newview/lldrawpoolmaterials.cpp
+++ b/indra/newview/lldrawpoolmaterials.cpp
@@ -30,6 +30,7 @@
#include "lldrawpoolmaterials.h"
#include "llviewershadermgr.h"
#include "pipeline.h"
+#include "llglcommonfunc.h"
S32 diffuse_channel = -1;
@@ -211,6 +212,9 @@ void LLDrawPoolMaterials::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture,
{
params.mGroup->rebuildMesh();
}
+
+ LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
+
params.mVertexBuffer->setBuffer(mask);
params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 50a4925c37..06f64b7597 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -53,6 +53,7 @@
#include "llviewershadermgr.h"
#include "llviewertexture.h"
#include "llvoavatar.h"
+#include "llsculptidsize.h"
#if LL_LINUX
// Work-around spurious used before init warning on Vector4a
@@ -1217,6 +1218,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
{
LL_RECORD_BLOCK_TIME(FTM_FACE_GET_GEOM);
llassert(verify());
+
+ if (volume.getNumVolumeFaces() <= f) {
+ LL_WARNS() << "Attempt get volume face out of range! Total Faces: " << volume.getNumVolumeFaces() << " Attempt get access to: " << f << LL_ENDL;
+ return FALSE;
+ }
+
const LLVolumeFace &vf = volume.getVolumeFace(f);
S32 num_vertices = (S32)vf.mNumVertices;
S32 num_indices = (S32) vf.mNumIndices;
@@ -2650,12 +2657,27 @@ LLViewerTexture* LLFace::getTexture(U32 ch) const
void LLFace::setVertexBuffer(LLVertexBuffer* buffer)
{
+ if (buffer)
+ {
+ LLSculptIDSize::instance().inc(mDrawablep, buffer->getSize() + buffer->getIndicesSize());
+ }
+
+ if (mVertexBuffer)
+ {
+ LLSculptIDSize::instance().dec(mDrawablep);
+ }
+
mVertexBuffer = buffer;
llassert(verify());
}
void LLFace::clearVertexBuffer()
{
+ if (mVertexBuffer)
+ {
+ LLSculptIDSize::instance().dec(mDrawablep);
+ }
+
mVertexBuffer = NULL;
}
diff --git a/indra/newview/llfacebookconnect.cpp b/indra/newview/llfacebookconnect.cpp
index 1de4102dba..43b01fa2f1 100644
--- a/indra/newview/llfacebookconnect.cpp
+++ b/indra/newview/llfacebookconnect.cpp
@@ -503,13 +503,10 @@ LLFacebookConnect::LLFacebookConnect()
void LLFacebookConnect::openFacebookWeb(std::string url)
{
- // Open the URL in an internal browser window without navigation UI
LLFloaterWebContent::Params p;
p.url(url);
p.show_chrome(true);
- p.allow_address_entry(false);
p.allow_back_forward_navigation(false);
- p.trusted_content(true);
p.clean_browser(true);
LLFloater *floater = LLFloaterReg::showInstance("fbc_web", p);
//the internal web browser has a bug that prevents it from gaining focus unless a mouse event occurs first (it seems).
diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp
index 9219dd0279..f68e63cb96 100644
--- a/indra/newview/llfasttimerview.cpp
+++ b/indra/newview/llfasttimerview.cpp
@@ -435,18 +435,22 @@ void LLFastTimerView::onClose(bool app_quitting)
void saveChart(const std::string& label, const char* suffix, LLImageRaw* scratch)
{
- //read result back into raw image
- glReadPixels(0, 0, 1024, 512, GL_RGB, GL_UNSIGNED_BYTE, scratch->getData());
+ // disable use of glReadPixels which messes up nVidia nSight graphics debugging
+ if (!LLRender::sNsightDebugSupport)
+ {
+ //read result back into raw image
+ glReadPixels(0, 0, 1024, 512, GL_RGB, GL_UNSIGNED_BYTE, scratch->getData());
- //write results to disk
- LLPointer<LLImagePNG> result = new LLImagePNG();
- result->encode(scratch, 0.f);
+ //write results to disk
+ LLPointer<LLImagePNG> result = new LLImagePNG();
+ result->encode(scratch, 0.f);
- std::string ext = result->getExtension();
- std::string filename = llformat("%s_%s.%s", label.c_str(), suffix, ext.c_str());
+ std::string ext = result->getExtension();
+ std::string filename = llformat("%s_%s.%s", label.c_str(), suffix, ext.c_str());
- std::string out_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, filename);
- result->save(out_file);
+ std::string out_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, filename);
+ result->save(out_file);
+ }
}
//static
@@ -904,8 +908,7 @@ void LLFastTimerView::doAnalysisDefault(std::string baseline, std::string target
base[label]["Samples"].asInteger());
}
- // This currently crashes, possibly due to a race condition in shutdown:
- // exportCharts(baseline, target);
+ exportCharts(baseline, target);
os.flush();
os.close();
diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
index 125a823e58..0f22b6200f 100644
--- a/indra/newview/llfilepicker.cpp
+++ b/indra/newview/llfilepicker.cpp
@@ -283,7 +283,7 @@ BOOL LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking)
return success;
}
-BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter)
+BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter, bool blocking)
{
if( mLocked )
{
@@ -310,9 +310,13 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter)
setupFilter(filter);
reset();
-
- // Modal, so pause agent
- send_agent_pause();
+
+ if (blocking)
+ {
+ // Modal, so pause agent
+ send_agent_pause();
+ }
+
// NOTA BENE: hitting the file dialog triggers a window focus event, destroying the selection manager!!
success = GetOpenFileName(&mOFN); // pauses until ok or cancel.
if( success )
@@ -345,14 +349,18 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter)
}
}
}
- send_agent_resume();
+
+ if (blocking)
+ {
+ send_agent_resume();
+ }
// Account for the fact that the app has been stalled.
LLFrameTimer::updateFrameTime();
return success;
}
-BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename)
+BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename, bool blocking)
{
if( mLocked )
{
@@ -540,8 +548,12 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename)
reset();
- // Modal, so pause agent
- send_agent_pause();
+ if (blocking)
+ {
+ // Modal, so pause agent
+ send_agent_pause();
+ }
+
{
// NOTA BENE: hitting the file dialog triggers a window focus event, destroying the selection manager!!
try
@@ -559,7 +571,11 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename)
}
gKeyboard->resetKeys();
}
- send_agent_resume();
+
+ if (blocking)
+ {
+ send_agent_resume();
+ }
// Account for the fact that the app has been stalled.
LLFrameTimer::updateFrameTime();
@@ -809,7 +825,7 @@ BOOL LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking)
mPickOptions |= F_NAV_SUPPORT;
}
- if (blocking)
+ if (blocking) // always true for linux/mac
{
// Modal, so pause agent
send_agent_pause();
@@ -834,7 +850,7 @@ BOOL LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking)
return success;
}
-BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter)
+BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter, bool blocking)
{
if( mLocked )
return FALSE;
@@ -852,13 +868,20 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter)
mPickOptions |= F_FILE;
mPickOptions |= F_MULTIPLE;
- // Modal, so pause agent
- send_agent_pause();
-
+
+ if (blocking) // always true for linux/mac
+ {
+ // Modal, so pause agent
+ send_agent_pause();
+ }
+
success = doNavChooseDialog(filter);
-
- send_agent_resume();
-
+
+ if (blocking)
+ {
+ send_agent_resume();
+ }
+
if (success)
{
if (!getFileCount())
@@ -872,7 +895,7 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter)
return success;
}
-BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename)
+BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename, bool blocking)
{
if( mLocked )
@@ -889,8 +912,11 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename)
mPickOptions &= ~F_MULTIPLE;
- // Modal, so pause agent
- send_agent_pause();
+ if (blocking)
+ {
+ // Modal, so pause agent
+ send_agent_pause();
+ }
success = doNavSaveDialog(filter, filename);
@@ -900,7 +926,10 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename)
success = false;
}
- send_agent_resume();
+ if (blocking)
+ {
+ send_agent_resume();
+ }
// Account for the fact that the app has been stalled.
LLFrameTimer::updateFrameTime();
@@ -1354,7 +1383,7 @@ BOOL LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking )
return rtn;
}
-BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter )
+BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter, bool blocking)
{
BOOL rtn = FALSE;
@@ -1438,7 +1467,7 @@ BOOL LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking )
return TRUE;
}
-BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter )
+BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter, bool blocking)
{
// if local file browsing is turned off, return without opening dialog
// (Even though this is a stub, I think we still should not return anything at all)
@@ -1467,7 +1496,7 @@ BOOL LLFilePicker::getOpenFile( ELoadFilter filter )
return FALSE;
}
-BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter )
+BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter, bool blocking)
{
reset();
return FALSE;
diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h
index b6e67375cd..2fc496a144 100644
--- a/indra/newview/llfilepicker.h
+++ b/indra/newview/llfilepicker.h
@@ -113,9 +113,9 @@ public:
};
// open the dialog. This is a modal operation
- BOOL getSaveFile( ESaveFilter filter = FFSAVE_ALL, const std::string& filename = LLStringUtil::null );
+ BOOL getSaveFile( ESaveFilter filter = FFSAVE_ALL, const std::string& filename = LLStringUtil::null, bool blocking = true);
BOOL getOpenFile( ELoadFilter filter = FFLOAD_ALL, bool blocking = true );
- BOOL getMultipleOpenFiles( ELoadFilter filter = FFLOAD_ALL );
+ BOOL getMultipleOpenFiles( ELoadFilter filter = FFLOAD_ALL, bool blocking = true );
// Get the filename(s) found. getFirstFile() sets the pointer to
// the start of the structure and allows the start of iteration.
@@ -198,6 +198,4 @@ public:
~LLFilePicker();
};
-const std::string upload_pick(void* data);
-
#endif
diff --git a/indra/newview/llfilteredwearablelist.cpp b/indra/newview/llfilteredwearablelist.cpp
index e67a6a2b77..2bfaa1e5bc 100644
--- a/indra/newview/llfilteredwearablelist.cpp
+++ b/indra/newview/llfilteredwearablelist.cpp
@@ -32,6 +32,7 @@
#include "llinventoryitemslist.h"
#include "llinventorymodel.h"
#include "llviewerinventory.h"
+#include "lltrans.h"
LLFilteredWearableListManager::LLFilteredWearableListManager(LLInventoryItemsList* list, LLInventoryCollectFunctor* collector)
@@ -118,6 +119,11 @@ void LLFilteredWearableListManager::populateList()
// Probably will also need to get items from Library (waiting for reply in EXT-6724).
+ if (item_array.empty() && gInventory.isCategoryComplete(gInventory.getRootFolderID()))
+ {
+ mWearableList->setNoItemsCommentText(LLTrans::getString("NoneFound"));
+ }
+
mWearableList->refreshList(item_array);
}
diff --git a/indra/newview/llflickrconnect.cpp b/indra/newview/llflickrconnect.cpp
index c0ca5b8cf8..d7d161f239 100644
--- a/indra/newview/llflickrconnect.cpp
+++ b/indra/newview/llflickrconnect.cpp
@@ -397,13 +397,10 @@ LLFlickrConnect::LLFlickrConnect()
void LLFlickrConnect::openFlickrWeb(std::string url)
{
- // Open the URL in an internal browser window without navigation UI
LLFloaterWebContent::Params p;
p.url(url);
p.show_chrome(true);
- p.allow_address_entry(false);
p.allow_back_forward_navigation(false);
- p.trusted_content(true);
p.clean_browser(true);
LLFloater *floater = LLFloaterReg::showInstance("flickr_web", p);
//the internal web browser has a bug that prevents it from gaining focus unless a mouse event occurs first (it seems).
diff --git a/indra/newview/llfloaterauction.cpp b/indra/newview/llfloaterauction.cpp
deleted file mode 100644
index 56619e818a..0000000000
--- a/indra/newview/llfloaterauction.cpp
+++ /dev/null
@@ -1,552 +0,0 @@
-/**
- * @file llfloaterauction.cpp
- * @author James Cook, Ian Wilkes
- * @brief Implementation of the auction floater.
- *
- * $LicenseInfo:firstyear=2004&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, 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 "llfloaterauction.h"
-
-#include "llgl.h"
-#include "llimagej2c.h"
-#include "llimagetga.h"
-#include "llparcel.h"
-#include "llvfile.h"
-#include "llvfs.h"
-#include "llwindow.h"
-#include "message.h"
-
-#include "llagent.h"
-#include "llassetstorage.h"
-#include "llcombobox.h"
-#include "llestateinfomodel.h"
-#include "llmimetypes.h"
-#include "llnotifications.h"
-#include "llnotificationsutil.h"
-#include "llsavedsettingsglue.h"
-#include "llviewertexturelist.h"
-#include "llviewerparcelmgr.h"
-#include "llviewerregion.h"
-#include "lluictrlfactory.h"
-#include "llviewerwindow.h"
-#include "llviewerdisplay.h"
-#include "llviewercontrol.h"
-#include "llui.h"
-#include "llrender.h"
-#include "llsdutil.h"
-#include "llsdutil_math.h"
-#include "lltrans.h"
-#include "llcorehttputil.h"
-
-///----------------------------------------------------------------------------
-/// Local function declarations, constants, enums, and typedefs
-///----------------------------------------------------------------------------
-
-void auction_j2c_upload_done(const LLUUID& asset_id,
- void* user_data, S32 status, LLExtStat ext_status);
-void auction_tga_upload_done(const LLUUID& asset_id,
- void* user_data, S32 status, LLExtStat ext_status);
-
-///----------------------------------------------------------------------------
-/// Class llfloaterauction
-///----------------------------------------------------------------------------
-
-// Default constructor
-LLFloaterAuction::LLFloaterAuction(const LLSD& key)
- : LLFloater(key),
- mParcelID(-1)
-{
- mCommitCallbackRegistrar.add("ClickSnapshot", boost::bind(&LLFloaterAuction::onClickSnapshot, this));
- mCommitCallbackRegistrar.add("ClickSellToAnyone", boost::bind(&LLFloaterAuction::onClickSellToAnyone, this));
- mCommitCallbackRegistrar.add("ClickStartAuction", boost::bind(&LLFloaterAuction::onClickStartAuction, this));
- mCommitCallbackRegistrar.add("ClickResetParcel", boost::bind(&LLFloaterAuction::onClickResetParcel, this));
-}
-
-// Destroys the object
-LLFloaterAuction::~LLFloaterAuction()
-{
-}
-
-BOOL LLFloaterAuction::postBuild()
-{
- return TRUE;
-}
-
-void LLFloaterAuction::onOpen(const LLSD& key)
-{
- initialize();
-}
-
-void LLFloaterAuction::initialize()
-{
- mParcelUpdateCapUrl.clear();
-
- mParcelp = LLViewerParcelMgr::getInstance()->getParcelSelection();
- LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
- LLParcel* parcelp = mParcelp->getParcel();
- if(parcelp && region && !parcelp->getForSale())
- {
- mParcelHost = region->getHost();
- mParcelID = parcelp->getLocalID();
- mParcelUpdateCapUrl = region->getCapability("ParcelPropertiesUpdate");
-
- getChild<LLUICtrl>("parcel_text")->setValue(parcelp->getName());
- getChildView("snapshot_btn")->setEnabled(TRUE);
- getChildView("reset_parcel_btn")->setEnabled(TRUE);
- getChildView("start_auction_btn")->setEnabled(TRUE);
-
- U32 estate_id = LLEstateInfoModel::instance().getID();
- // Only enable "Sell to Anyone" on Teen grid or if we don't know the ID yet
- getChildView("sell_to_anyone_btn")->setEnabled(estate_id == ESTATE_TEEN || estate_id == 0);
- }
- else
- {
- mParcelHost.invalidate();
- if(parcelp && parcelp->getForSale())
- {
- getChild<LLUICtrl>("parcel_text")->setValue(getString("already for sale"));
- }
- else
- {
- getChild<LLUICtrl>("parcel_text")->setValue(LLStringUtil::null);
- }
- mParcelID = -1;
- getChildView("snapshot_btn")->setEnabled(false);
- getChildView("reset_parcel_btn")->setEnabled(false);
- getChildView("sell_to_anyone_btn")->setEnabled(false);
- getChildView("start_auction_btn")->setEnabled(false);
- }
-
- mImageID.setNull();
- mImage = NULL;
-}
-
-void LLFloaterAuction::draw()
-{
- LLFloater::draw();
-
- if(!isMinimized() && mImage.notNull())
- {
- LLView* snapshot_icon = findChildView("snapshot_icon");
- if (snapshot_icon)
- {
- LLRect rect = snapshot_icon->getRect();
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gl_rect_2d(rect, LLColor4(0.f, 0.f, 0.f, 1.f));
- rect.stretch(-1);
- }
- {
- LLGLSUIDefault gls_ui;
- gGL.color3f(1.f, 1.f, 1.f);
- gl_draw_scaled_image(rect.mLeft,
- rect.mBottom,
- rect.getWidth(),
- rect.getHeight(),
- mImage);
- }
- }
- }
-}
-
-
-// static
-void LLFloaterAuction::onClickSnapshot(void* data)
-{
- LLFloaterAuction* self = (LLFloaterAuction*)(data);
-
- LLPointer<LLImageRaw> raw = new LLImageRaw;
-
- gForceRenderLandFence = self->getChild<LLUICtrl>("fence_check")->getValue().asBoolean();
- BOOL success = gViewerWindow->rawSnapshot(raw,
- gViewerWindow->getWindowWidthScaled(),
- gViewerWindow->getWindowHeightScaled(),
- TRUE, FALSE,
- FALSE, FALSE);
- gForceRenderLandFence = FALSE;
-
- if (success)
- {
- self->mTransactionID.generate();
- self->mImageID = self->mTransactionID.makeAssetID(gAgent.getSecureSessionID());
-
- if(!gSavedSettings.getBOOL("QuietSnapshotsToDisk"))
- {
- gViewerWindow->playSnapshotAnimAndSound();
- }
- LL_INFOS() << "Writing TGA..." << LL_ENDL;
-
- LLPointer<LLImageTGA> tga = new LLImageTGA;
- tga->encode(raw);
- LLVFile::writeFile(tga->getData(), tga->getDataSize(), gVFS, self->mImageID, LLAssetType::AT_IMAGE_TGA);
-
- raw->biasedScaleToPowerOfTwo(LLViewerTexture::MAX_IMAGE_SIZE_DEFAULT);
-
- LL_INFOS() << "Writing J2C..." << LL_ENDL;
-
- LLPointer<LLImageJ2C> j2c = new LLImageJ2C;
- j2c->encode(raw, 0.0f);
- LLVFile::writeFile(j2c->getData(), j2c->getDataSize(), gVFS, self->mImageID, LLAssetType::AT_TEXTURE);
-
- self->mImage = LLViewerTextureManager::getLocalTexture((LLImageRaw*)raw, FALSE);
- gGL.getTexUnit(0)->bind(self->mImage);
- self->mImage->setAddressMode(LLTexUnit::TAM_CLAMP);
- }
- else
- {
- LL_WARNS() << "Unable to take snapshot" << LL_ENDL;
- }
-}
-
-// static
-void LLFloaterAuction::onClickStartAuction(void* data)
-{
- LLFloaterAuction* self = (LLFloaterAuction*)(data);
-
- if(self->mImageID.notNull())
- {
- LLSD parcel_name = self->getChild<LLUICtrl>("parcel_text")->getValue();
-
- // create the asset
- std::string* name = new std::string(parcel_name.asString());
- gAssetStorage->storeAssetData(self->mTransactionID, LLAssetType::AT_IMAGE_TGA,
- &auction_tga_upload_done,
- (void*)name,
- FALSE);
- self->getWindow()->incBusyCount();
-
- std::string* j2c_name = new std::string(parcel_name.asString());
- gAssetStorage->storeAssetData(self->mTransactionID, LLAssetType::AT_TEXTURE,
- &auction_j2c_upload_done,
- (void*)j2c_name,
- FALSE);
- self->getWindow()->incBusyCount();
-
- LLNotificationsUtil::add("UploadingAuctionSnapshot");
-
- }
- LLMessageSystem* msg = gMessageSystem;
-
- msg->newMessage("ViewerStartAuction");
-
- msg->nextBlock("AgentData");
- msg->addUUID("AgentID", gAgent.getID());
- msg->addUUID("SessionID", gAgent.getSessionID());
- msg->nextBlock("ParcelData");
- msg->addS32("LocalID", self->mParcelID);
- msg->addUUID("SnapshotID", self->mImageID);
- msg->sendReliable(self->mParcelHost);
-
- // clean up floater, and get out
- self->cleanupAndClose();
-}
-
-
-void LLFloaterAuction::cleanupAndClose()
-{
- mImageID.setNull();
- mImage = NULL;
- mParcelID = -1;
- mParcelHost.invalidate();
- closeFloater();
-}
-
-
-
-// static glue
-void LLFloaterAuction::onClickResetParcel(void* data)
-{
- LLFloaterAuction* self = (LLFloaterAuction*)(data);
- if (self)
- {
- self->doResetParcel();
- }
-}
-
-
-// Reset all the values for the parcel in preparation for a sale
-void LLFloaterAuction::doResetParcel()
-{
- LLParcel* parcelp = mParcelp->getParcel();
- LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
-
- if (parcelp
- && region
- && !mParcelUpdateCapUrl.empty())
- {
- LLSD body;
- std::string empty;
-
- // request new properties update from simulator
- U32 message_flags = 0x01;
- body["flags"] = ll_sd_from_U32(message_flags);
-
- // Set all the default parcel properties for auction
- body["local_id"] = parcelp->getLocalID();
-
- U32 parcel_flags = PF_ALLOW_LANDMARK |
- PF_ALLOW_FLY |
- PF_CREATE_GROUP_OBJECTS |
- PF_ALLOW_ALL_OBJECT_ENTRY |
- PF_ALLOW_GROUP_OBJECT_ENTRY |
- PF_ALLOW_GROUP_SCRIPTS |
- PF_RESTRICT_PUSHOBJECT |
- PF_SOUND_LOCAL |
- PF_ALLOW_VOICE_CHAT |
- PF_USE_ESTATE_VOICE_CHAN;
-
- body["parcel_flags"] = ll_sd_from_U32(parcel_flags);
-
- // Build a parcel name like "Ahern (128,128) PG 4032m"
- std::ostringstream parcel_name;
- LLVector3 center_point( parcelp->getCenterpoint() );
- center_point.snap(0); // Get rid of fractions
- parcel_name << region->getName()
- << " ("
- << (S32) center_point.mV[VX]
- << ","
- << (S32) center_point.mV[VY]
- << ") "
- << region->getSimAccessString()
- << " "
- << parcelp->getArea()
- << "m";
-
- std::string new_name(parcel_name.str().c_str());
- body["name"] = new_name;
- getChild<LLUICtrl>("parcel_text")->setValue(new_name); // Set name in dialog as well, since it won't get updated otherwise
-
- body["sale_price"] = (S32) 0;
- body["description"] = empty;
- body["music_url"] = empty;
- body["media_url"] = empty;
- body["media_desc"] = empty;
- body["media_type"] = LLMIMETypes::getDefaultMimeType();
- body["media_width"] = (S32) 0;
- body["media_height"] = (S32) 0;
- body["auto_scale"] = (S32) 0;
- body["media_loop"] = (S32) 0;
- body["obscure_media"] = (S32) 0; // OBSOLETE - no longer used
- body["obscure_music"] = (S32) 0; // OBSOLETE - no longer used
- body["media_id"] = LLUUID::null;
- body["group_id"] = MAINTENANCE_GROUP_ID; // Use maintenance group
- body["pass_price"] = (S32) 10; // Defaults to $10
- body["pass_hours"] = 0.0f;
- body["category"] = (U8) LLParcel::C_NONE;
- body["auth_buyer_id"] = LLUUID::null;
- body["snapshot_id"] = LLUUID::null;
- body["user_location"] = ll_sd_from_vector3( LLVector3::zero );
- body["user_look_at"] = ll_sd_from_vector3( LLVector3::zero );
- body["landing_type"] = (U8) LLParcel::L_DIRECT;
-
- LL_INFOS() << "Sending parcel update to reset for auction via capability to: "
- << mParcelUpdateCapUrl << LL_ENDL;
-
- LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(mParcelUpdateCapUrl, body,
- "Parcel reset for auction",
- "Parcel not set for auction.");
-
- // Send a message to clear the object return time
- LLMessageSystem *msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_ParcelSetOtherCleanTime);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->nextBlockFast(_PREHASH_ParcelData);
- msg->addS32Fast(_PREHASH_LocalID, parcelp->getLocalID());
- msg->addS32Fast(_PREHASH_OtherCleanTime, 5); // 5 minute object auto-return
-
- msg->sendReliable(region->getHost());
-
- // Clear the access lists
- clearParcelAccessList(parcelp, region, AL_ACCESS);
- clearParcelAccessList(parcelp, region, AL_BAN);
- clearParcelAccessList(parcelp, region, AL_ALLOW_EXPERIENCE);
- clearParcelAccessList(parcelp, region, AL_BLOCK_EXPERIENCE);
- }
-}
-
-
-
-void LLFloaterAuction::clearParcelAccessList(LLParcel* parcel, LLViewerRegion* region, U32 list)
-{
- if (!region || !parcel) return;
-
- LLUUID transactionUUID;
- transactionUUID.generate();
-
- LLMessageSystem* msg = gMessageSystem;
-
- msg->newMessageFast(_PREHASH_ParcelAccessListUpdate);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
- msg->nextBlockFast(_PREHASH_Data);
- msg->addU32Fast(_PREHASH_Flags, list);
- msg->addS32(_PREHASH_LocalID, parcel->getLocalID() );
- msg->addUUIDFast(_PREHASH_TransactionID, transactionUUID);
- msg->addS32Fast(_PREHASH_SequenceID, 1); // sequence_id
- msg->addS32Fast(_PREHASH_Sections, 0); // num_sections
-
- // pack an empty block since there will be no data
- msg->nextBlockFast(_PREHASH_List);
- msg->addUUIDFast(_PREHASH_ID, LLUUID::null );
- msg->addS32Fast(_PREHASH_Time, 0 );
- msg->addU32Fast(_PREHASH_Flags, 0 );
-
- msg->sendReliable( region->getHost() );
-}
-
-
-
-// static - 'Sell to Anyone' clicked, throw up a confirmation dialog
-void LLFloaterAuction::onClickSellToAnyone(void* data)
-{
- LLFloaterAuction* self = (LLFloaterAuction*)(data);
- if (self)
- {
- LLParcel* parcelp = self->mParcelp->getParcel();
-
- // Do a confirmation
- S32 sale_price = parcelp->getArea(); // Selling for L$1 per meter
- S32 area = parcelp->getArea();
-
- LLSD args;
- args["LAND_SIZE"] = llformat("%d", area);
- args["SALE_PRICE"] = llformat("%d", sale_price);
- args["NAME"] = LLTrans::getString("Anyone");
-
- LLNotification::Params params("ConfirmLandSaleChange"); // Re-use existing dialog
- params.substitutions(args)
- .functor.function(boost::bind(&LLFloaterAuction::onSellToAnyoneConfirmed, self, _1, _2));
-
- params.name("ConfirmLandSaleToAnyoneChange");
-
- // ask away
- LLNotifications::instance().add(params);
- }
-}
-
-
-// Sell confirmation clicked
-bool LLFloaterAuction::onSellToAnyoneConfirmed(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if (option == 0)
- {
- doSellToAnyone();
- }
-
- return false;
-}
-
-
-
-// Reset all the values for the parcel in preparation for a sale
-void LLFloaterAuction::doSellToAnyone()
-{
- LLParcel* parcelp = mParcelp->getParcel();
- LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
-
- if (parcelp
- && region
- && !mParcelUpdateCapUrl.empty())
- {
- LLSD body;
- std::string empty;
-
- // request new properties update from simulator
- U32 message_flags = 0x01;
- body["flags"] = ll_sd_from_U32(message_flags);
-
- // Set all the default parcel properties for auction
- body["local_id"] = parcelp->getLocalID();
-
- // Set 'for sale' flag
- U32 parcel_flags = parcelp->getParcelFlags() | PF_FOR_SALE;
- // Ensure objects not included
- parcel_flags &= ~PF_FOR_SALE_OBJECTS;
- body["parcel_flags"] = ll_sd_from_U32(parcel_flags);
-
- body["sale_price"] = parcelp->getArea(); // Sell for L$1 per square meter
- body["auth_buyer_id"] = LLUUID::null; // To anyone
-
- LL_INFOS() << "Sending parcel update to sell to anyone for L$1 via capability to: "
- << mParcelUpdateCapUrl << LL_ENDL;
-
- LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(mParcelUpdateCapUrl, body,
- "Parcel set as sell to everyone.",
- "Parcel sell to everyone failed.");
-
- // clean up floater, and get out
- cleanupAndClose();
- }
-}
-
-
-///----------------------------------------------------------------------------
-/// Local function definitions
-///----------------------------------------------------------------------------
-
-void auction_tga_upload_done(const LLUUID& asset_id, void* user_data, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed)
-{
- std::string* name = (std::string*)(user_data);
- LL_INFOS() << "Upload of asset '" << *name << "' " << asset_id
- << " returned " << status << LL_ENDL;
- delete name;
-
- gViewerWindow->getWindow()->decBusyCount();
-
- if (0 == status)
- {
- LLNotificationsUtil::add("UploadWebSnapshotDone");
- }
- else
- {
- LLSD args;
- args["REASON"] = std::string(LLAssetStorage::getErrorString(status));
- LLNotificationsUtil::add("UploadAuctionSnapshotFail", args);
- }
-}
-
-void auction_j2c_upload_done(const LLUUID& asset_id, void* user_data, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed)
-{
- std::string* name = (std::string*)(user_data);
- LL_INFOS() << "Upload of asset '" << *name << "' " << asset_id
- << " returned " << status << LL_ENDL;
- delete name;
-
- gViewerWindow->getWindow()->decBusyCount();
-
- if (0 == status)
- {
- LLNotificationsUtil::add("UploadSnapshotDone");
- }
- else
- {
- LLSD args;
- args["REASON"] = std::string(LLAssetStorage::getErrorString(status));
- LLNotificationsUtil::add("UploadAuctionSnapshotFail", args);
- }
-}
diff --git a/indra/newview/llfloaterauction.h b/indra/newview/llfloaterauction.h
deleted file mode 100644
index c83a11ba8b..0000000000
--- a/indra/newview/llfloaterauction.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- * @file llfloaterauction.h
- * @author James Cook, Ian Wilkes
- * @brief llfloaterauction class header file
- *
- * $LicenseInfo:firstyear=2004&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, 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_LLFLOATERAUCTION_H
-#define LL_LLFLOATERAUCTION_H
-
-#include "llfloater.h"
-#include "lluuid.h"
-#include "llpointer.h"
-#include "llviewertexture.h"
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLFloaterAuction
-//
-// Class which holds the functionality to start auctions.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLParcelSelection;
-class LLParcel;
-class LLViewerRegion;
-
-class LLFloaterAuction : public LLFloater
-{
- friend class LLFloaterReg;
-public:
- // LLFloater interface
- /*virtual*/ void onOpen(const LLSD& key);
- /*virtual*/ void draw();
-
-private:
-
- LLFloaterAuction(const LLSD& key);
- ~LLFloaterAuction();
-
- void initialize();
-
- static void onClickSnapshot(void* data);
- static void onClickResetParcel(void* data);
- static void onClickSellToAnyone(void* data); // Sell to anyone clicked
- bool onSellToAnyoneConfirmed(const LLSD& notification, const LLSD& response); // Sell confirmation clicked
- static void onClickStartAuction(void* data);
-
- /*virtual*/ BOOL postBuild();
-
- void doResetParcel();
- void doSellToAnyone();
- void clearParcelAccessList( LLParcel* parcel, LLViewerRegion* region, U32 list);
- void cleanupAndClose();
-
-private:
-
- LLTransactionID mTransactionID;
- LLAssetID mImageID;
- LLPointer<LLViewerTexture> mImage;
- LLSafeHandle<LLParcelSelection> mParcelp;
- S32 mParcelID;
- LLHost mParcelHost;
-
- std::string mParcelUpdateCapUrl; // "ParcelPropertiesUpdate" capability
-};
-
-
-#endif // LL_LLFLOATERAUCTION_H
diff --git a/indra/newview/llfloaterautoreplacesettings.cpp b/indra/newview/llfloaterautoreplacesettings.cpp
index 5830f2f711..ec05ba924c 100644
--- a/indra/newview/llfloaterautoreplacesettings.cpp
+++ b/indra/newview/llfloaterautoreplacesettings.cpp
@@ -54,6 +54,7 @@
#include "llhost.h"
#include "llassetstorage.h"
#include "roles_constants.h"
+#include "llviewermenufile.h" // LLFilePickerReplyThread
#include "llviewertexteditor.h"
#include <boost/tokenizer.hpp>
@@ -349,62 +350,58 @@ void LLFloaterAutoReplaceSettings::onDeleteEntry()
// called when the Import List button is pressed
void LLFloaterAutoReplaceSettings::onImportList()
{
- LLFilePicker& picker = LLFilePicker::instance();
- if( picker.getOpenFile( LLFilePicker::FFLOAD_XML) )
+ (new LLFilePickerReplyThread(boost::bind(&LLFloaterAutoReplaceSettings::loadListFromFile, this, _1), LLFilePicker::FFLOAD_XML, false))->getFile();
+}
+
+void LLFloaterAutoReplaceSettings::loadListFromFile(const std::vector<std::string>& filenames)
+{
+ llifstream file;
+ file.open(filenames[0].c_str());
+ LLSD newList;
+ if (file.is_open())
{
- llifstream file;
- file.open(picker.getFirstFile().c_str());
- LLSD newList;
- if (file.is_open())
- {
- LLSDSerialize::fromXMLDocument(newList, file);
- }
- file.close();
+ LLSDSerialize::fromXMLDocument(newList, file);
+ }
+ file.close();
- switch ( mSettings.addList(newList) )
- {
- case LLAutoReplaceSettings::AddListOk:
- mSelectedListName = LLAutoReplaceSettings::getListName(newList);
+ switch ( mSettings.addList(newList) )
+ {
+ case LLAutoReplaceSettings::AddListOk:
+ mSelectedListName = LLAutoReplaceSettings::getListName(newList);
- updateListNames();
- updateListNamesControls();
- updateReplacementsList();
- break;
+ updateListNames();
+ updateListNamesControls();
+ updateReplacementsList();
+ break;
- case LLAutoReplaceSettings::AddListDuplicateName:
- {
- std::string newName = LLAutoReplaceSettings::getListName(newList);
- LL_WARNS("AutoReplace")<<"name '"<<newName<<"' is in use; prompting for new name"<<LL_ENDL;
- LLSD newPayload;
- newPayload["list"] = newList;
- LLSD args;
- args["DUPNAME"] = newName;
+ case LLAutoReplaceSettings::AddListDuplicateName:
+ {
+ std::string newName = LLAutoReplaceSettings::getListName(newList);
+ LL_WARNS("AutoReplace")<<"name '"<<newName<<"' is in use; prompting for new name"<<LL_ENDL;
+ LLSD newPayload;
+ newPayload["list"] = newList;
+ LLSD args;
+ args["DUPNAME"] = newName;
- LLNotificationsUtil::add("RenameAutoReplaceList", args, newPayload,
+ LLNotificationsUtil::add("RenameAutoReplaceList", args, newPayload,
boost::bind(&LLFloaterAutoReplaceSettings::callbackListNameConflict, this, _1, _2));
- }
- break;
+ }
+ break;
- case LLAutoReplaceSettings::AddListInvalidList:
- LLNotificationsUtil::add("InvalidAutoReplaceList");
- LL_WARNS("AutoReplace") << "imported list was invalid" << LL_ENDL;
+ case LLAutoReplaceSettings::AddListInvalidList:
+ LLNotificationsUtil::add("InvalidAutoReplaceList");
+ LL_WARNS("AutoReplace") << "imported list was invalid" << LL_ENDL;
- mSelectedListName.clear();
- updateListNames();
- updateListNamesControls();
- updateReplacementsList();
- break;
+ mSelectedListName.clear();
+ updateListNames();
+ updateListNamesControls();
+ updateReplacementsList();
+ break;
- default:
- LL_ERRS("AutoReplace") << "invalid AddListResult" << LL_ENDL;
+ default:
+ LL_ERRS("AutoReplace") << "invalid AddListResult" << LL_ENDL;
- }
-
- }
- else
- {
- LL_DEBUGS("AutoReplace") << "file selection failed for import list" << LL_ENDL;
- }
+ }
}
void LLFloaterAutoReplaceSettings::onNewList()
@@ -539,16 +536,17 @@ void LLFloaterAutoReplaceSettings::onDeleteList()
void LLFloaterAutoReplaceSettings::onExportList()
{
std::string listName=mListNames->getFirstSelected()->getColumn(0)->getValue().asString();
- const LLSD* list = mSettings.exportList(listName);
std::string listFileName = listName + ".xml";
- LLFilePicker& picker = LLFilePicker::instance();
- if( picker.getSaveFile( LLFilePicker::FFSAVE_XML, listFileName) )
- {
- llofstream file;
- file.open(picker.getFirstFile().c_str());
- LLSDSerialize::toPrettyXML(*list, file);
- file.close();
- }
+ (new LLFilePickerReplyThread(boost::bind(&LLFloaterAutoReplaceSettings::saveListToFile, this, _1, listName), LLFilePicker::FFSAVE_XML, listFileName))->getFile();
+}
+
+void LLFloaterAutoReplaceSettings::saveListToFile(const std::vector<std::string>& filenames, std::string listName)
+{
+ llofstream file;
+ const LLSD* list = mSettings.exportList(listName);
+ file.open(filenames[0].c_str());
+ LLSDSerialize::toPrettyXML(*list, file);
+ file.close();
}
void LLFloaterAutoReplaceSettings::onAddEntry()
diff --git a/indra/newview/llfloaterautoreplacesettings.h b/indra/newview/llfloaterautoreplacesettings.h
index 629aea3e3c..2109aa7026 100644
--- a/indra/newview/llfloaterautoreplacesettings.h
+++ b/indra/newview/llfloaterautoreplacesettings.h
@@ -112,6 +112,9 @@ private:
bool selectedListIsLast();
void cleanUp();
+
+ void loadListFromFile(const std::vector<std::string>& filenames);
+ void saveListToFile(const std::vector<std::string>& filenames, std::string listName);
};
#endif // LLFLOATERAUTOREPLACESETTINGS_H
diff --git a/indra/newview/llfloateravatartextures.cpp b/indra/newview/llfloateravatartextures.cpp
index 78807a8e99..8e654a53c4 100644
--- a/indra/newview/llfloateravatartextures.cpp
+++ b/indra/newview/llfloateravatartextures.cpp
@@ -78,7 +78,7 @@ static void update_texture_ctrl(LLVOAvatar* avatarp,
{
LLUUID id = IMG_DEFAULT_AVATAR;
const LLAvatarAppearanceDictionary::TextureEntry* tex_entry = LLAvatarAppearanceDictionary::getInstance()->getTexture(te);
- if (tex_entry->mIsLocalTexture)
+ if (tex_entry && tex_entry->mIsLocalTexture)
{
if (avatarp->isSelf())
{
@@ -96,7 +96,7 @@ static void update_texture_ctrl(LLVOAvatar* avatarp,
}
else
{
- id = avatarp->getTE(te)->getID();
+ id = tex_entry ? avatarp->getTE(te)->getID() : IMG_DEFAULT_AVATAR;
}
//id = avatarp->getTE(te)->getID();
if (id == IMG_DEFAULT_AVATAR)
diff --git a/indra/newview/llfloaterhoverheight.cpp b/indra/newview/llfloaterhoverheight.cpp
index 003a22fa04..42c5e40761 100644
--- a/indra/newview/llfloaterhoverheight.cpp
+++ b/indra/newview/llfloaterhoverheight.cpp
@@ -39,7 +39,7 @@ LLFloaterHoverHeight::LLFloaterHoverHeight(const LLSD& key) : LLFloater(key)
{
}
-void LLFloaterHoverHeight::syncFromPreferenceSetting(void *user_data)
+void LLFloaterHoverHeight::syncFromPreferenceSetting(void *user_data, bool update_offset)
{
F32 value = gSavedPerAccountSettings.getF32("AvatarHoverOffsetZ");
@@ -47,7 +47,7 @@ void LLFloaterHoverHeight::syncFromPreferenceSetting(void *user_data)
LLSliderCtrl* sldrCtrl = self->getChild<LLSliderCtrl>("HoverHeightSlider");
sldrCtrl->setValue(value,FALSE);
- if (isAgentAvatarValid())
+ if (isAgentAvatarValid() && update_offset)
{
LLVector3 offset(0.0, 0.0, llclamp(value,MIN_HOVER_Z,MAX_HOVER_Z));
LL_INFOS("Avatar") << "setting hover from preference setting " << offset[2] << LL_ENDL;
@@ -70,7 +70,7 @@ BOOL LLFloaterHoverHeight::postBuild()
// Update slider on future pref changes.
if (gSavedPerAccountSettings.getControl("AvatarHoverOffsetZ"))
{
- gSavedPerAccountSettings.getControl("AvatarHoverOffsetZ")->getCommitSignal()->connect(boost::bind(&syncFromPreferenceSetting, this));
+ gSavedPerAccountSettings.getControl("AvatarHoverOffsetZ")->getCommitSignal()->connect(boost::bind(&syncFromPreferenceSetting, this, false));
}
else
{
@@ -114,10 +114,6 @@ void LLFloaterHoverHeight::onFinalCommit()
LLSliderCtrl* sldrCtrl = getChild<LLSliderCtrl>("HoverHeightSlider");
F32 value = sldrCtrl->getValueF32();
gSavedPerAccountSettings.setF32("AvatarHoverOffsetZ",value);
-
- LLVector3 offset(0.0, 0.0, llclamp(value,MIN_HOVER_Z,MAX_HOVER_Z));
- LL_INFOS("Avatar") << "setting hover from slider final commit " << offset[2] << LL_ENDL;
- gAgentAvatarp->setHoverOffset(offset, true); // will send update this time.
}
void LLFloaterHoverHeight::onRegionChanged()
diff --git a/indra/newview/llfloaterhoverheight.h b/indra/newview/llfloaterhoverheight.h
index ee065bc184..a643fa2516 100644
--- a/indra/newview/llfloaterhoverheight.h
+++ b/indra/newview/llfloaterhoverheight.h
@@ -39,7 +39,7 @@ public:
void onFinalCommit();
- static void syncFromPreferenceSetting(void *user_data);
+ static void syncFromPreferenceSetting(void *user_data, bool update_offset = true);
void onRegionChanged();
void onSimulatorFeaturesReceived(const LLUUID &region_id);
diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp
index a9e4d752ac..0c2bb25e07 100644
--- a/indra/newview/llfloaterimagepreview.cpp
+++ b/indra/newview/llfloaterimagepreview.cpp
@@ -793,7 +793,7 @@ void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance)
if (imagep)
{
- mVolume->sculpt(imagep->getWidth(), imagep->getHeight(), imagep->getComponents(), imagep->getData(), 0);
+ mVolume->sculpt(imagep->getWidth(), imagep->getHeight(), imagep->getComponents(), imagep->getData(), 0, false);
}
const LLVolumeFace &vf = mVolume->getVolumeFace(0);
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 333765f99f..3cfa1133df 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -2276,6 +2276,7 @@ BOOL LLFloaterIMContainer::isFrontmost()
// This is intentional so it doesn't confuse the user. onClickCloseBtn() closes the whole floater.
void LLFloaterIMContainer::onClickCloseBtn(bool app_quitting/* = false*/)
{
+ gSavedPerAccountSettings.setS32("ConversationsListPaneWidth", mConversationsPane->getRect().getWidth());
LLMultiFloater::closeFloater(app_quitting);
}
diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index 6623ce0f80..a4ab1af9a8 100644
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -82,8 +82,7 @@ LLFloaterIMSession::LLFloaterIMSession(const LLUUID& session_id)
mPositioned(false),
mSessionInitialized(false),
mMeTypingTimer(),
- mOtherTypingTimer(),
- mImInfo()
+ mOtherTypingTimer()
{
mIsNearbyChat = false;
@@ -125,7 +124,7 @@ void LLFloaterIMSession::refresh()
if (mOtherTyping && mOtherTypingTimer.getElapsedTimeF32() > OTHER_TYPING_TIMEOUT)
{
LL_DEBUGS("TypingMsgs") << "Received: is typing cleared due to timeout" << LL_ENDL;
- removeTypingIndicator(mImInfo);
+ removeTypingIndicator(mImFromId);
mOtherTyping = false;
}
@@ -1006,19 +1005,19 @@ void LLFloaterIMSession::setTyping(bool typing)
}
}
-void LLFloaterIMSession::processIMTyping(const LLIMInfo* im_info, BOOL typing)
+void LLFloaterIMSession::processIMTyping(const LLUUID& from_id, BOOL typing)
{
LL_DEBUGS("TypingMsgs") << "typing=" << typing << LL_ENDL;
if ( typing )
{
// other user started typing
- addTypingIndicator(im_info);
+ addTypingIndicator(from_id);
mOtherTypingTimer.reset();
}
else
{
// other user stopped typing
- removeTypingIndicator(im_info);
+ removeTypingIndicator(from_id);
}
}
@@ -1218,7 +1217,7 @@ BOOL LLFloaterIMSession::inviteToSession(const uuid_vec_t& ids)
return is_region_exist;
}
-void LLFloaterIMSession::addTypingIndicator(const LLIMInfo* im_info)
+void LLFloaterIMSession::addTypingIndicator(const LLUUID& from_id)
{
/* Operation of "<name> is typing" state machine:
Not Typing state:
@@ -1248,35 +1247,35 @@ Note: OTHER_TYPING_TIMEOUT must be > ME_TYPING_TIMEOUT for proper operation of t
*/
// We may have lost a "stop-typing" packet, don't add it twice
- if (im_info && !mOtherTyping)
+ if (from_id.notNull() && !mOtherTyping)
{
mOtherTyping = true;
mOtherTypingTimer.reset();
// Save im_info so that removeTypingIndicator can be properly called because a timeout has occurred
- mImInfo = im_info;
+ mImFromId = from_id;
// Update speaker
LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
if ( speaker_mgr )
{
- speaker_mgr->setSpeakerTyping(im_info->mFromID, TRUE);
+ speaker_mgr->setSpeakerTyping(from_id, TRUE);
}
}
}
-void LLFloaterIMSession::removeTypingIndicator(const LLIMInfo* im_info)
+void LLFloaterIMSession::removeTypingIndicator(const LLUUID& from_id)
{
if (mOtherTyping)
{
mOtherTyping = false;
- if (im_info)
+ if (from_id.notNull())
{
// Update speaker
LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
if (speaker_mgr)
{
- speaker_mgr->setSpeakerTyping(im_info->mFromID, FALSE);
+ speaker_mgr->setSpeakerTyping(from_id, FALSE);
}
}
}
diff --git a/indra/newview/llfloaterimsession.h b/indra/newview/llfloaterimsession.h
index 0f7164a585..28464fc14b 100644
--- a/indra/newview/llfloaterimsession.h
+++ b/indra/newview/llfloaterimsession.h
@@ -122,7 +122,7 @@ public:
const LLVoiceChannel::EState& old_state,
const LLVoiceChannel::EState& new_state);
- void processIMTyping(const LLIMInfo* im_info, BOOL typing);
+ void processIMTyping(const LLUUID& from_id, BOOL typing);
void processAgentListUpdates(const LLSD& body);
void processSessionUpdate(const LLSD& session_update);
@@ -165,10 +165,10 @@ private:
void boundVoiceChannel();
// Add the "User is typing..." indicator.
- void addTypingIndicator(const LLIMInfo* im_info);
+ void addTypingIndicator(const LLUUID& from_id);
// Remove the "User is typing..." indicator.
- void removeTypingIndicator(const LLIMInfo* im_info = NULL);
+ void removeTypingIndicator(const LLUUID& from_id = LLUUID::null);
static void closeHiddenIMToasts();
@@ -199,7 +199,7 @@ private:
// connection to voice channel state change signal
boost::signals2::connection mVoiceChannelStateChangeConnection;
- const LLIMInfo* mImInfo;
+ LLUUID mImFromId;
};
#endif // LL_FLOATERIMSESSION_H
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index 88b3fb7b96..596b04c31c 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -45,7 +45,6 @@
#include "llcombobox.h"
#include "llfloaterreg.h"
#include "llfloateravatarpicker.h"
-#include "llfloaterauction.h"
#include "llfloatergroups.h"
#include "llfloaterscriptlimits.h"
#include "llavataractions.h"
@@ -79,6 +78,7 @@
#include "llpanelexperiencelisteditor.h"
#include "llpanelexperiencepicker.h"
#include "llexperiencecache.h"
+#include "llweb.h"
#include "llgroupactions.h"
@@ -542,7 +542,6 @@ void LLPanelLandGeneral::refresh()
mBtnDeedToGroup->setEnabled(FALSE);
mBtnSetGroup->setEnabled(FALSE);
- mBtnStartAuction->setEnabled(FALSE);
mCheckDeedToGroup ->set(FALSE);
mCheckDeedToGroup ->setEnabled(FALSE);
@@ -640,7 +639,6 @@ void LLPanelLandGeneral::refresh()
mTextClaimDate->setEnabled(FALSE);
mTextGroup->setText(getString("none_text"));
mTextGroup->setEnabled(FALSE);
- mBtnStartAuction->setEnabled(FALSE);
}
else
{
@@ -692,11 +690,6 @@ void LLPanelLandGeneral::refresh()
LLStringUtil::format (claim_date_str, substitution);
mTextClaimDate->setText(claim_date_str);
mTextClaimDate->setEnabled(is_leased);
-
- BOOL enable_auction = (gAgent.getGodLevel() >= GOD_LIAISON)
- && (owner_id == GOVERNOR_LINDEN_ID)
- && (parcel->getAuctionID() == 0);
- mBtnStartAuction->setEnabled(enable_auction);
}
// Display options
@@ -1024,20 +1017,8 @@ void LLPanelLandGeneral::onClickBuyPass(void* data)
// static
void LLPanelLandGeneral::onClickStartAuction(void* data)
{
- LLPanelLandGeneral* panelp = (LLPanelLandGeneral*)data;
- LLParcel* parcelp = panelp->mParcel->getParcel();
- if(parcelp)
- {
- if(parcelp->getForSale())
- {
- LLNotificationsUtil::add("CannotStartAuctionAlreadyForSale");
- }
- else
- {
- //LLFloaterAuction::showInstance();
- LLFloaterReg::showInstance("auction");
- }
- }
+ std::string auction_url = "https://places.[GRID]/auctions/";
+ LLWeb::loadURLExternal(LLWeb::expandURLSubstitutions(auction_url, LLSD()));
}
// static
diff --git a/indra/newview/llfloatermemleak.cpp b/indra/newview/llfloatermemleak.cpp
index 9edfe1e354..c43526acaf 100644
--- a/indra/newview/llfloatermemleak.cpp
+++ b/indra/newview/llfloatermemleak.cpp
@@ -42,6 +42,8 @@ U32 LLFloaterMemLeak::sTotalLeaked = 0 ;
S32 LLFloaterMemLeak::sStatus = LLFloaterMemLeak::STOP ;
BOOL LLFloaterMemLeak::sbAllocationFailed = FALSE ;
+extern BOOL gSimulateMemLeak;
+
LLFloaterMemLeak::LLFloaterMemLeak(const LLSD& key)
: LLFloater(key)
{
@@ -104,6 +106,7 @@ void LLFloaterMemLeak::release()
sStatus = STOP ;
sTotalLeaked = 0 ;
sbAllocationFailed = FALSE ;
+ gSimulateMemLeak = FALSE;
}
void LLFloaterMemLeak::stop()
@@ -140,8 +143,7 @@ void LLFloaterMemLeak::idle()
}
if(!p)
{
- sStatus = STOP ;
- sbAllocationFailed = TRUE ;
+ stop();
}
}
@@ -181,6 +183,7 @@ void LLFloaterMemLeak::onChangeMaxMemLeaking()
void LLFloaterMemLeak::onClickStart()
{
sStatus = START ;
+ gSimulateMemLeak = TRUE;
}
void LLFloaterMemLeak::onClickStop()
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index da84a6b8f8..7a2ab37a0d 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -218,9 +218,17 @@ LLMeshFilePicker::LLMeshFilePicker(LLModelPreview* mp, S32 lod)
mLOD = lod;
}
-void LLMeshFilePicker::notify(const std::string& filename)
+void LLMeshFilePicker::notify(const std::vector<std::string>& filenames)
{
- mMP->loadModel(mFile, mLOD);
+ if (filenames.size() > 0)
+ {
+ mMP->loadModel(filenames[0], mLOD);
+ }
+ else
+ {
+ //closes floater
+ mMP->loadModel(std::string(), mLOD);
+ }
}
void FindModel(LLModelLoader::scene& scene, const std::string& name_to_match, LLModel*& baseModelOut, LLMatrix4& matOut)
diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h
index 0b2b7db2b6..53b03c6069 100644
--- a/indra/newview/llfloatermodelpreview.h
+++ b/indra/newview/llfloatermodelpreview.h
@@ -219,7 +219,7 @@ class LLMeshFilePicker : public LLFilePickerThread
{
public:
LLMeshFilePicker(LLModelPreview* mp, S32 lod);
- virtual void notify(const std::string& filename);
+ virtual void notify(const std::vector<std::string>& filenames);
private:
LLModelPreview* mMP;
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 5de7ca5289..9d723bdd9d 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1249,6 +1249,8 @@ void LLFloaterPreference::refreshEnabledState()
// Cannot have floater active until caps have been received
getChild<LLButton>("default_creation_permissions")->setEnabled(LLStartUp::getStartupState() < STATE_STARTED ? false : true);
+
+ getChildView("block_list")->setEnabled(LLLoginInstance::getInstance()->authSuccess());
}
void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
@@ -1383,8 +1385,6 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
// now turn off any features that are unavailable
disableUnavailableSettings();
-
- getChildView("block_list")->setEnabled(LLLoginInstance::getInstance()->authSuccess());
}
// static
@@ -2563,18 +2563,6 @@ BOOL LLPanelPreferenceGraphics::postBuild()
LLFloaterReg::showInstance("prefs_graphics_advanced");
LLFloaterReg::hideInstance("prefs_graphics_advanced");
-// Don't do this on Mac as their braindead GL versioning
-// sets this when 8x and 16x are indeed available
-//
-#if !LL_DARWIN
- if (gGLManager.mIsIntel || gGLManager.mGLVersion < 3.f)
- { //remove FSAA settings above "4x"
- LLComboBox* combo = getChild<LLComboBox>("fsaa");
- combo->remove("8x");
- combo->remove("16x");
- }
-#endif
-
resetDirtyChilds();
setPresetText();
@@ -2749,6 +2737,23 @@ LLFloaterPreferenceProxy::LLFloaterPreferenceProxy(const LLSD& key)
mCommitCallbackRegistrar.add("Proxy.Change", boost::bind(&LLFloaterPreferenceProxy::onChangeSocksSettings, this));
}
+BOOL LLFloaterPreferenceGraphicsAdvanced::postBuild()
+{
+ // Don't do this on Mac as their braindead GL versioning
+ // sets this when 8x and 16x are indeed available
+ //
+#if !LL_DARWIN
+ if (gGLManager.mIsIntel || gGLManager.mGLVersion < 3.f)
+ { //remove FSAA settings above "4x"
+ LLComboBox* combo = getChild<LLComboBox>("fsaa");
+ combo->remove("8x");
+ combo->remove("16x");
+ }
+#endif
+
+ return TRUE;
+}
+
void LLFloaterPreferenceGraphicsAdvanced::onOpen(const LLSD& key)
{
refresh();
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 444ad5a928..0cd7bac20f 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -276,6 +276,7 @@ class LLFloaterPreferenceGraphicsAdvanced : public LLFloater
public:
LLFloaterPreferenceGraphicsAdvanced(const LLSD& key);
~LLFloaterPreferenceGraphicsAdvanced();
+ /*virtual*/ BOOL postBuild();
void onOpen(const LLSD& key);
void onClickCloseBtn(bool app_quitting);
void disableUnavailableSettings();
diff --git a/indra/newview/llfloaterproperties.cpp b/indra/newview/llfloaterproperties.cpp
index 1310a60638..fbb7432f71 100644
--- a/indra/newview/llfloaterproperties.cpp
+++ b/indra/newview/llfloaterproperties.cpp
@@ -490,7 +490,6 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item)
if (is_obj_modify && can_agent_sell
&& gAgent.allowOperation(PERM_TRANSFER, perm, GP_OBJECT_MANIPULATE))
{
- getChildView("SaleLabel")->setEnabled(is_complete);
getChildView("CheckPurchase")->setEnabled(is_complete);
getChildView("NextOwnerLabel")->setEnabled(TRUE);
@@ -498,13 +497,11 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item)
getChildView("CheckNextOwnerCopy")->setEnabled((base_mask & PERM_COPY) && !cannot_restrict_permissions);
getChildView("CheckNextOwnerTransfer")->setEnabled((next_owner_mask & PERM_COPY) && !cannot_restrict_permissions);
- getChildView("TextPrice")->setEnabled(is_complete && is_for_sale);
combo_sale_type->setEnabled(is_complete && is_for_sale);
edit_cost->setEnabled(is_complete && is_for_sale);
}
else
{
- getChildView("SaleLabel")->setEnabled(FALSE);
getChildView("CheckPurchase")->setEnabled(FALSE);
getChildView("NextOwnerLabel")->setEnabled(FALSE);
@@ -512,7 +509,6 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item)
getChildView("CheckNextOwnerCopy")->setEnabled(FALSE);
getChildView("CheckNextOwnerTransfer")->setEnabled(FALSE);
- getChildView("TextPrice")->setEnabled(FALSE);
combo_sale_type->setEnabled(FALSE);
edit_cost->setEnabled(FALSE);
}
diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index c0f5e63623..d94bf3f651 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -164,6 +164,7 @@ LLFloaterReporter::LLFloaterReporter(const LLSD& key)
mResourceDatap(new LLResourceData()),
mAvatarNameCacheConnection()
{
+ gIdleCallbacks.addFunction(onIdle, this);
}
// virtual
@@ -213,10 +214,30 @@ BOOL LLFloaterReporter::postBuild()
std::string reporter = LLSLURL("agent", gAgent.getID(), "inspect").getSLURLString();
getChild<LLUICtrl>("reporter_field")->setValue(reporter);
+ // request categories
+ if (gAgent.getRegion()
+ && gAgent.getRegion()->capabilitiesReceived())
+ {
+ std::string cap_url = gAgent.getRegionCapability("AbuseCategories");
+
+ if (!cap_url.empty())
+ {
+ std::string lang = gSavedSettings.getString("Language");
+ if (lang != "default" && !lang.empty())
+ {
+ cap_url += "?lc=";
+ cap_url += lang;
+ }
+ LLCoros::instance().launch("LLFloaterReporter::requestAbuseCategoriesCoro",
+ boost::bind(LLFloaterReporter::requestAbuseCategoriesCoro, cap_url, this->getHandle()));
+ }
+ }
+
center();
return TRUE;
}
+
// virtual
LLFloaterReporter::~LLFloaterReporter()
{
@@ -224,6 +245,7 @@ LLFloaterReporter::~LLFloaterReporter()
{
mAvatarNameCacheConnection.disconnect();
}
+ gIdleCallbacks.deleteFunction(onIdle, this);
// child views automatically deleted
mObjectID = LLUUID::null;
@@ -241,10 +263,18 @@ LLFloaterReporter::~LLFloaterReporter()
delete mResourceDatap;
}
-// virtual
-void LLFloaterReporter::draw()
+void LLFloaterReporter::onIdle(void* user_data)
{
- LLFloater::draw();
+ LLFloaterReporter* floater_reporter = (LLFloaterReporter*)user_data;
+ if (floater_reporter)
+ {
+ static LLCachedControl<F32> screenshot_delay(gSavedSettings, "AbuseReportScreenshotDelay");
+ if (floater_reporter->mSnapshotTimer.getStarted() && floater_reporter->mSnapshotTimer.getElapsedTimeF32() > screenshot_delay)
+ {
+ floater_reporter->mSnapshotTimer.stop();
+ floater_reporter->takeNewSnapshot();
+ }
+ }
}
void LLFloaterReporter::enableControls(BOOL enable)
@@ -392,6 +422,65 @@ void LLFloaterReporter::onAvatarNameCache(const LLUUID& avatar_id, const LLAvata
}
}
+void LLFloaterReporter::requestAbuseCategoriesCoro(std::string url, LLHandle<LLFloater> handle)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("requestAbuseCategoriesCoro", 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 || !result.has("categories")) // success = httpResults["success"].asBoolean();
+ {
+ LL_WARNS() << "Error requesting Abuse Categories from capability: " << url << LL_ENDL;
+ return;
+ }
+
+ if (handle.isDead())
+ {
+ // nothing to do
+ return;
+ }
+
+ LLFloater* floater = handle.get();
+ LLComboBox* combo = floater->getChild<LLComboBox>("category_combo");
+ if (!combo)
+ {
+ LL_WARNS() << "categories category_combo not found!" << LL_ENDL;
+ return;
+ }
+
+ //get selection (in case capability took a while)
+ S32 selection = combo->getCurrentIndex();
+
+ // Combobox should have a "Select category" element;
+ // This is a bit of workaround since there is no proper and simple way to save array of
+ // localizable strings in xml along with data (value). For now combobox is initialized along
+ // with placeholders, and first element is "Select category" which we want to keep, so remove
+ // everything but first element.
+ // Todo: once sim with capability fully releases, just remove this string and all unnecessary
+ // items from combobox since they will be obsolete (or depending on situation remake this to
+ // something better, for example move "Select category" to separate string)
+ while (combo->remove(1));
+
+ LLSD contents = result["categories"];
+
+ LLSD::array_iterator i = contents.beginArray();
+ LLSD::array_iterator iEnd = contents.endArray();
+ for (; i != iEnd; ++i)
+ {
+ const LLSD &message_data(*i);
+ std::string label = message_data["description_localized"];
+ combo->add(label, message_data["category"]);
+ }
+
+ //restore selection
+ combo->selectNthItem(selection);
+}
// static
void LLFloaterReporter::onClickSend(void *userdata)
@@ -877,8 +966,7 @@ void LLFloaterReporter::onOpen(const LLSD& key)
{
childSetEnabled("send_btn", false);
//Time delay to avoid UI artifacts. MAINT-7067
- doAfterInterval(boost::bind(&LLFloaterReporter::takeNewSnapshot,this), gSavedSettings.getF32("AbuseReportScreenshotDelay"));
-
+ mSnapshotTimer.start();
}
void LLFloaterReporter::onLoadScreenshotDialog(const LLSD& notification, const LLSD& response)
@@ -950,6 +1038,7 @@ void LLFloaterReporter::setPosBox(const LLVector3d &pos)
void LLFloaterReporter::onClose(bool app_quitting)
{
+ mSnapshotTimer.stop();
gSavedPerAccountSettings.setBOOL("PreviousScreenshotForReport", app_quitting);
}
diff --git a/indra/newview/llfloaterreporter.h b/indra/newview/llfloaterreporter.h
index decc01be98..c678df7155 100644
--- a/indra/newview/llfloaterreporter.h
+++ b/indra/newview/llfloaterreporter.h
@@ -83,7 +83,8 @@ public:
/*virtual*/ BOOL postBuild();
/*virtual*/ void onOpen(const LLSD& key);
/*virtual*/ void onClose(bool app_quitting);
- virtual void draw();
+
+ static void onIdle(void* user_data);
void setReportType(EReportType type) { mReportType = type; }
@@ -128,6 +129,7 @@ private:
void setFromAvatarID(const LLUUID& avatar_id);
void onAvatarNameCache(const LLUUID& avatar_id, const LLAvatarName& av_name);
+ static void requestAbuseCategoriesCoro(std::string url, LLHandle<LLFloater> handle);
static void finishedARPost(const LLSD &);
private:
@@ -149,6 +151,7 @@ private:
LLPointer<LLImageRaw> mImageRaw;
LLPointer<LLImageRaw> mPrevImageRaw;
+ LLFrameTimer mSnapshotTimer;
};
#endif
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index 2d0002dcd8..156b2ba7b1 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -54,7 +54,7 @@ LLSnapshotFloaterView* gSnapshotFloaterView = NULL;
const F32 AUTO_SNAPSHOT_TIME_DELAY = 1.f;
-const S32 MAX_POSTCARD_DATASIZE = 1024 * 1024; // one megabyte
+const S32 MAX_POSTCARD_DATASIZE = 1572864; // 1.5 megabyte, similar to simulator limit
const S32 MAX_TEXTURE_SIZE = 512 ; //max upload texture size 512 * 512
static LLDefaultChildRegistry::Register<LLSnapshotFloaterView> r("snapshot_floater_view");
@@ -1100,6 +1100,7 @@ void LLFloaterSnapshot::onOpen(const LLSD& key)
if(preview)
{
LL_DEBUGS() << "opened, updating snapshot" << LL_ENDL;
+ preview->setAllowFullScreenPreview(TRUE);
preview->updateSnapshot(TRUE);
}
focusFirstItem(FALSE);
@@ -1129,6 +1130,7 @@ void LLFloaterSnapshotBase::onClose(bool app_quitting)
LLSnapshotLivePreview* previewp = getPreviewView();
if (previewp)
{
+ previewp->setAllowFullScreenPreview(FALSE);
previewp->setVisible(FALSE);
previewp->setEnabled(FALSE);
}
@@ -1232,6 +1234,11 @@ S32 LLFloaterSnapshot::notify(const LLSD& info)
return 0;
}
+BOOL LLFloaterSnapshot::isWaitingState()
+{
+ return (impl->getStatus() == ImplBase::STATUS_WORKING);
+}
+
BOOL LLFloaterSnapshotBase::ImplBase::updatePreviewList(bool initialized)
{
LLFloaterFacebook* floater_facebook = LLFloaterReg::findTypedInstance<LLFloaterFacebook>("facebook");
diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h
index 1f303ea4d6..698273ac90 100644
--- a/indra/newview/llfloatersnapshot.h
+++ b/indra/newview/llfloatersnapshot.h
@@ -159,6 +159,8 @@ public:
BOOL saveLocal();
static void setAgentEmail(const std::string& email);
+ BOOL isWaitingState();
+
class Impl;
friend class Impl;
};
diff --git a/indra/newview/llfloaterspellchecksettings.cpp b/indra/newview/llfloaterspellchecksettings.cpp
index 5124dae147..b87044ef5a 100644
--- a/indra/newview/llfloaterspellchecksettings.cpp
+++ b/indra/newview/llfloaterspellchecksettings.cpp
@@ -30,12 +30,13 @@
#include "llfilepicker.h"
#include "llfloaterreg.h"
#include "llfloaterspellchecksettings.h"
+#include "llnotificationsutil.h"
#include "llscrolllistctrl.h"
#include "llsdserialize.h"
#include "llspellcheck.h"
#include "lltrans.h"
#include "llviewercontrol.h"
-#include "llnotificationsutil.h"
+#include "llviewermenufile.h" // LLFilePickerReplyThread
#include <boost/algorithm/string.hpp>
@@ -258,13 +259,12 @@ BOOL LLFloaterSpellCheckerImport::postBuild(void)
void LLFloaterSpellCheckerImport::onBtnBrowse()
{
- LLFilePicker& file_picker = LLFilePicker::instance();
- if (!file_picker.getOpenFile(LLFilePicker::FFLOAD_DICTIONARY))
- {
- return;
- }
+ (new LLFilePickerReplyThread(boost::bind(&LLFloaterSpellCheckerImport::importSelectedDictionary, this, _1), LLFilePicker::FFLOAD_DICTIONARY, false))->getFile();
+}
- std::string filepath = file_picker.getFirstFile();
+void LLFloaterSpellCheckerImport::importSelectedDictionary(const std::vector<std::string>& filenames)
+{
+ std::string filepath = filenames[0];
const std::string extension = gDirUtilp->getExtension(filepath);
if ("xcu" == extension)
@@ -277,7 +277,7 @@ void LLFloaterSpellCheckerImport::onBtnBrowse()
}
getChild<LLUICtrl>("dictionary_path")->setValue(filepath);
-
+
mDictionaryDir = gDirUtilp->getDirName(filepath);
mDictionaryBasename = gDirUtilp->getBaseFileName(filepath, true);
getChild<LLUICtrl>("dictionary_name")->setValue(mDictionaryBasename);
diff --git a/indra/newview/llfloaterspellchecksettings.h b/indra/newview/llfloaterspellchecksettings.h
index de59d83f24..f9bbefafb7 100644
--- a/indra/newview/llfloaterspellchecksettings.h
+++ b/indra/newview/llfloaterspellchecksettings.h
@@ -58,6 +58,7 @@ protected:
void onBtnBrowse();
void onBtnCancel();
void onBtnOK();
+ void importSelectedDictionary(const std::vector<std::string>& filenames);
std::string parseXcuFile(const std::string& file_path) const;
std::string mDictionaryDir;
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index c9d664c7c4..7fc60ddaac 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -253,7 +253,6 @@ BOOL LLFloaterTools::postBuild()
mCheckStretchTexture = getChild<LLCheckBoxCtrl>("checkbox stretch textures");
getChild<LLUICtrl>("checkbox stretch textures")->setValue((BOOL)gSavedSettings.getBOOL("ScaleStretchTextures"));
mComboGridMode = getChild<LLComboBox>("combobox grid mode");
- mCheckStretchUniformLabel = getChild<LLTextBox>("checkbox uniform label");
//
// Create Buttons
@@ -1214,7 +1213,7 @@ void LLFloaterTools::getMediaState()
&&first_object->permModify()
))
{
- getChildView("Add_Media")->setEnabled(FALSE);
+ getChildView("add_media")->setEnabled(FALSE);
media_info->clear();
clearMediaSettings();
return;
@@ -1225,7 +1224,7 @@ void LLFloaterTools::getMediaState()
if(!has_media_capability)
{
- getChildView("Add_Media")->setEnabled(FALSE);
+ getChildView("add_media")->setEnabled(FALSE);
LL_WARNS("LLFloaterTools: media") << "Media not enabled (no capability) in this region!" << LL_ENDL;
clearMediaSettings();
return;
@@ -1320,7 +1319,7 @@ void LLFloaterTools::getMediaState()
// update UI depending on whether "object" (prim or face) has media
// and whether or not you are allowed to edit it.
- getChildView("Add_Media")->setEnabled(editable);
+ getChildView("add_media")->setEnabled(editable);
// IF all the faces have media (or all dont have media)
if ( LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo )
{
@@ -1342,10 +1341,7 @@ void LLFloaterTools::getMediaState()
media_title = multi_media_info_str;
}
- getChildView("media_tex")->setEnabled(bool_has_media && editable);
- getChildView("edit_media")->setEnabled(bool_has_media && LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo && editable );
getChildView("delete_media")->setEnabled(bool_has_media && editable );
- getChildView("add_media")->setEnabled(editable);
// TODO: display a list of all media on the face - use 'identical' flag
}
else // not all face has media but at least one does.
@@ -1367,10 +1363,7 @@ void LLFloaterTools::getMediaState()
}
}
- getChildView("media_tex")->setEnabled(TRUE);
- getChildView("edit_media")->setEnabled(LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo);
getChildView("delete_media")->setEnabled(TRUE);
- getChildView("add_media")->setEnabled(editable);
}
navigateToTitleMedia(media_title);
diff --git a/indra/newview/llfloatertopobjects.cpp b/indra/newview/llfloatertopobjects.cpp
index e20360066e..3e6fc3dc0d 100644
--- a/indra/newview/llfloatertopobjects.cpp
+++ b/indra/newview/llfloatertopobjects.cpp
@@ -236,7 +236,7 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
&& have_extended_data)
{
columns[column_num]["column"] = "memory";
- columns[column_num]["value"] = llformat("%0.0f", (script_memory / 1000.f));
+ columns[column_num]["value"] = llformat("%0.0f", (script_memory / 1024.f));
columns[column_num++]["font"] = "SANSSERIF";
columns[column_num]["column"] = "URLs";
diff --git a/indra/newview/llfloaterwebcontent.cpp b/indra/newview/llfloaterwebcontent.cpp
index dece3fc1ea..3b17368445 100644
--- a/indra/newview/llfloaterwebcontent.cpp
+++ b/indra/newview/llfloaterwebcontent.cpp
@@ -105,6 +105,7 @@ BOOL LLFloaterWebContent::postBuild()
// these buttons are always enabled
mBtnReload->setEnabled( true );
+ mBtnReload->setVisible( false );
getChildView("popexternal")->setEnabled( true );
// cache image for secure browsing
@@ -399,6 +400,9 @@ void LLFloaterWebContent::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent
}
else if(event == MEDIA_EVENT_NAME_CHANGED )
{
+ // flags are sent with this event
+ mBtnBack->setEnabled(self->getHistoryBackAvailable());
+ mBtnForward->setEnabled(self->getHistoryForwardAvailable());
std::string page_title = self->getMediaName();
// simulate browser behavior - title is empty, use the current URL
if (mShowPageTitle)
diff --git a/indra/newview/llfloaterwebprofile.cpp b/indra/newview/llfloaterwebprofile.cpp
index a46f1d8af2..891bb90c0e 100644
--- a/indra/newview/llfloaterwebprofile.cpp
+++ b/indra/newview/llfloaterwebprofile.cpp
@@ -38,8 +38,10 @@ LLFloaterWebProfile::LLFloaterWebProfile(const Params& key) :
void LLFloaterWebProfile::onOpen(const LLSD& key)
{
Params p(key);
- p.show_chrome(false).
- window_class("profile");
+ p.show_chrome(true);
+ p.window_class("profile");
+ p.allow_address_entry(false);
+ p.trusted_content(true);
LLFloaterWebContent::onOpen(p);
applyPreferredRect();
}
diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp
index 83f268818e..3c3b004d2c 100644
--- a/indra/newview/llfloaterworldmap.cpp
+++ b/indra/newview/llfloaterworldmap.cpp
@@ -549,10 +549,10 @@ void LLFloaterWorldMap::trackAvatar( const LLUUID& avatar_id, const std::string&
getChild<LLUICtrl>("teleport_coordinate_z")->setValue(LLSD(200.f));
}
// Don't re-request info if we already have it or we won't have it in time to teleport
- if (mTrackedStatus != LLTracker::TRACKING_AVATAR || name != mTrackedAvatarName)
+ if (mTrackedStatus != LLTracker::TRACKING_AVATAR || avatar_id != mTrackedAvatarID)
{
mTrackedStatus = LLTracker::TRACKING_AVATAR;
- mTrackedAvatarName = name;
+ mTrackedAvatarID = avatar_id;
LLTracker::trackAvatar(avatar_id, name);
}
}
diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h
index c5801c8819..fce945df6c 100644
--- a/indra/newview/llfloaterworldmap.h
+++ b/indra/newview/llfloaterworldmap.h
@@ -190,7 +190,7 @@ private:
LLVector3d mTrackedLocation;
LLTracker::ETrackingStatus mTrackedStatus;
std::string mTrackedSimName;
- std::string mTrackedAvatarName;
+ LLUUID mTrackedAvatarID;
LLSLURL mSLURL;
LLCtrlListInterface * mListFriendCombo;
diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp
index 63270e13fe..4b0b10dd5a 100644
--- a/indra/newview/llglsandbox.cpp
+++ b/indra/newview/llglsandbox.cpp
@@ -920,7 +920,7 @@ public:
// unbind
if (texUnit)
{
- texUnit->unbind(LLTexUnit::TT_TEXTURE);
+ texUnit->unbind(LLTexUnit::TT_TEXTURE);
}
// ensure that we delete these textures regardless of how we exit
LLImageGL::deleteTextures(source.size(), &source[0]);
@@ -1060,7 +1060,7 @@ F32 gpu_benchmark()
delete [] pixels;
//make a dummy triangle to draw with
- LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, GL_STATIC_DRAW_ARB);
+ LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, GL_STREAM_DRAW_ARB);
if (!buff->allocateBuffer(3, 0, true))
{
diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp
new file mode 100644
index 0000000000..491671c46f
--- /dev/null
+++ b/indra/newview/llimprocessing.cpp
@@ -0,0 +1,1589 @@
+/**
+* @file LLIMProcessing.cpp
+* @brief Container for Instant Messaging
+*
+* $LicenseInfo:firstyear=2001&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 "llviewerprecompiledheaders.h"
+
+#include "llimprocessing.h"
+
+#include "llagent.h"
+#include "llavatarnamecache.h"
+#include "llfirstuse.h"
+#include "llfloaterreg.h"
+#include "llfloaterimnearbychat.h"
+#include "llimview.h"
+#include "llinventoryobserver.h"
+#include "llinventorymodel.h"
+#include "llmutelist.h"
+#include "llnotifications.h"
+#include "llnotificationsutil.h"
+#include "llnotificationmanager.h"
+#include "llpanelgroup.h"
+#include "llregionhandle.h"
+#include "llsdserialize.h"
+#include "llslurl.h"
+#include "llstring.h"
+#include "lltoastnotifypanel.h"
+#include "lltrans.h"
+#include "llviewergenericmessage.h"
+#include "llviewerobjectlist.h"
+#include "llviewermessage.h"
+#include "llviewerwindow.h"
+#include "llviewerregion.h"
+#include "llvoavatarself.h"
+
+#include <boost/regex.hpp>
+#include "boost/lexical_cast.hpp"
+#if LL_MSVC
+// disable boost::lexical_cast warning
+#pragma warning (disable:4702)
+#endif
+
+// Strip out "Resident" for display, but only if the message came from a user
+// (rather than a script)
+static std::string clean_name_from_im(const std::string& name, EInstantMessage type)
+{
+ switch (type)
+ {
+ case IM_NOTHING_SPECIAL:
+ case IM_MESSAGEBOX:
+ case IM_GROUP_INVITATION:
+ case IM_INVENTORY_OFFERED:
+ case IM_INVENTORY_ACCEPTED:
+ case IM_INVENTORY_DECLINED:
+ case IM_GROUP_VOTE:
+ case IM_GROUP_MESSAGE_DEPRECATED:
+ //IM_TASK_INVENTORY_OFFERED
+ //IM_TASK_INVENTORY_ACCEPTED
+ //IM_TASK_INVENTORY_DECLINED
+ case IM_NEW_USER_DEFAULT:
+ case IM_SESSION_INVITE:
+ case IM_SESSION_P2P_INVITE:
+ case IM_SESSION_GROUP_START:
+ case IM_SESSION_CONFERENCE_START:
+ case IM_SESSION_SEND:
+ case IM_SESSION_LEAVE:
+ //IM_FROM_TASK
+ case IM_DO_NOT_DISTURB_AUTO_RESPONSE:
+ case IM_CONSOLE_AND_CHAT_HISTORY:
+ case IM_LURE_USER:
+ case IM_LURE_ACCEPTED:
+ case IM_LURE_DECLINED:
+ case IM_GODLIKE_LURE_USER:
+ case IM_TELEPORT_REQUEST:
+ case IM_GROUP_ELECTION_DEPRECATED:
+ //IM_GOTO_URL
+ //IM_FROM_TASK_AS_ALERT
+ case IM_GROUP_NOTICE:
+ case IM_GROUP_NOTICE_INVENTORY_ACCEPTED:
+ case IM_GROUP_NOTICE_INVENTORY_DECLINED:
+ case IM_GROUP_INVITATION_ACCEPT:
+ case IM_GROUP_INVITATION_DECLINE:
+ case IM_GROUP_NOTICE_REQUESTED:
+ case IM_FRIENDSHIP_OFFERED:
+ case IM_FRIENDSHIP_ACCEPTED:
+ case IM_FRIENDSHIP_DECLINED_DEPRECATED:
+ //IM_TYPING_START
+ //IM_TYPING_STOP
+ return LLCacheName::cleanFullName(name);
+ default:
+ return name;
+ }
+}
+
+static std::string clean_name_from_task_im(const std::string& msg,
+ BOOL from_group)
+{
+ boost::smatch match;
+ static const boost::regex returned_exp(
+ "(.*been returned to your inventory lost and found folder by )(.+)( (from|near).*)");
+ if (boost::regex_match(msg, match, returned_exp))
+ {
+ // match objects are 1-based for groups
+ std::string final = match[1].str();
+ std::string name = match[2].str();
+ // Don't try to clean up group names
+ if (!from_group)
+ {
+ final += LLCacheName::buildUsername(name);
+ }
+ final += match[3].str();
+ return final;
+ }
+ return msg;
+}
+
+const std::string NOT_ONLINE_MSG("User not online - message will be stored and delivered later.");
+const std::string NOT_ONLINE_INVENTORY("User not online - inventory has been saved.");
+void translate_if_needed(std::string& message)
+{
+ if (message == NOT_ONLINE_MSG)
+ {
+ message = LLTrans::getString("not_online_msg");
+ }
+ else if (message == NOT_ONLINE_INVENTORY)
+ {
+ message = LLTrans::getString("not_online_inventory");
+ }
+}
+
+class LLPostponedIMSystemTipNotification : public LLPostponedNotification
+{
+protected:
+ /* virtual */
+ void modifyNotificationParams()
+ {
+ LLSD payload = mParams.payload;
+ payload["SESSION_NAME"] = mName;
+ mParams.payload = payload;
+ }
+};
+
+class LLPostponedOfferNotification : public LLPostponedNotification
+{
+protected:
+ /* virtual */
+ void modifyNotificationParams()
+ {
+ LLSD substitutions = mParams.substitutions;
+ substitutions["NAME"] = mName;
+ mParams.substitutions = substitutions;
+ }
+};
+
+void inventory_offer_handler(LLOfferInfo* info)
+{
+ // If muted, don't even go through the messaging stuff. Just curtail the offer here.
+ // Passing in a null UUID handles the case of where you have muted one of your own objects by_name.
+ // The solution for STORM-1297 seems to handle the cases where the object is owned by someone else.
+ if (LLMuteList::getInstance()->isMuted(info->mFromID, info->mFromName) ||
+ LLMuteList::getInstance()->isMuted(LLUUID::null, info->mFromName))
+ {
+ info->forceResponse(IOR_MUTE);
+ return;
+ }
+
+ bool bAutoAccept(false);
+ // Avoid the Accept/Discard dialog if the user so desires. JC
+ if (gSavedSettings.getBOOL("AutoAcceptNewInventory")
+ && (info->mType == LLAssetType::AT_NOTECARD
+ || info->mType == LLAssetType::AT_LANDMARK
+ || info->mType == LLAssetType::AT_TEXTURE))
+ {
+ // For certain types, just accept the items into the inventory,
+ // and possibly open them on receipt depending upon "ShowNewInventory".
+ bAutoAccept = true;
+ }
+
+ // Strip any SLURL from the message display. (DEV-2754)
+ std::string msg = info->mDesc;
+ int indx = msg.find(" ( http://slurl.com/secondlife/");
+ if (indx == std::string::npos)
+ {
+ // try to find new slurl host
+ indx = msg.find(" ( http://maps.secondlife.com/secondlife/");
+ }
+ if (indx >= 0)
+ {
+ LLStringUtil::truncate(msg, indx);
+ }
+
+ LLSD args;
+ args["[OBJECTNAME]"] = msg;
+
+ LLSD payload;
+
+ // must protect against a NULL return from lookupHumanReadable()
+ std::string typestr = ll_safe_string(LLAssetType::lookupHumanReadable(info->mType));
+ if (!typestr.empty())
+ {
+ // human readable matches string name from strings.xml
+ // lets get asset type localized name
+ args["OBJECTTYPE"] = LLTrans::getString(typestr);
+ }
+ else
+ {
+ LL_WARNS("Messaging") << "LLAssetType::lookupHumanReadable() returned NULL - probably bad asset type: " << info->mType << LL_ENDL;
+ args["OBJECTTYPE"] = "";
+
+ // This seems safest, rather than propagating bogosity
+ LL_WARNS("Messaging") << "Forcing an inventory-decline for probably-bad asset type." << LL_ENDL;
+ info->forceResponse(IOR_DECLINE);
+ return;
+ }
+
+ // If mObjectID is null then generate the object_id based on msg to prevent
+ // multiple creation of chiclets for same object.
+ LLUUID object_id = info->mObjectID;
+ if (object_id.isNull())
+ object_id.generate(msg);
+
+ payload["from_id"] = info->mFromID;
+ // Needed by LLScriptFloaterManager to bind original notification with
+ // faked for toast one.
+ payload["object_id"] = object_id;
+ // Flag indicating that this notification is faked for toast.
+ payload["give_inventory_notification"] = FALSE;
+ args["OBJECTFROMNAME"] = info->mFromName;
+ args["NAME"] = info->mFromName;
+ if (info->mFromGroup)
+ {
+ args["NAME_SLURL"] = LLSLURL("group", info->mFromID, "about").getSLURLString();
+ }
+ else
+ {
+ args["NAME_SLURL"] = LLSLURL("agent", info->mFromID, "about").getSLURLString();
+ }
+ std::string verb = "select?name=" + LLURI::escape(msg);
+ args["ITEM_SLURL"] = LLSLURL("inventory", info->mObjectID, verb.c_str()).getSLURLString();
+
+ LLNotification::Params p;
+
+ // Object -> Agent Inventory Offer
+ if (info->mFromObject && !bAutoAccept)
+ {
+ // Inventory Slurls don't currently work for non agent transfers, so only display the object name.
+ args["ITEM_SLURL"] = msg;
+ // Note: sets inventory_task_offer_callback as the callback
+ p.substitutions(args).payload(payload).functor.responder(LLNotificationResponderPtr(info));
+ info->mPersist = true;
+
+ // Offers from your own objects need a special notification template.
+ p.name = info->mFromID == gAgentID ? "OwnObjectGiveItem" : "ObjectGiveItem";
+
+ // Pop up inv offer chiclet and let the user accept (keep), or reject (and silently delete) the inventory.
+ LLPostponedNotification::add<LLPostponedOfferNotification>(p, info->mFromID, info->mFromGroup == TRUE);
+ }
+ else // Agent -> Agent Inventory Offer
+ {
+ p.responder = info;
+ // Note: sets inventory_offer_callback as the callback
+ // *TODO fix memory leak
+ // inventory_offer_callback() is not invoked if user received notification and
+ // closes viewer(without responding the notification)
+ p.substitutions(args).payload(payload).functor.responder(LLNotificationResponderPtr(info));
+ info->mPersist = true;
+ p.name = "UserGiveItem";
+ p.offer_from_agent = true;
+
+ // Prefetch the item into your local inventory.
+ LLInventoryFetchItemsObserver* fetch_item = new LLInventoryFetchItemsObserver(info->mObjectID);
+ fetch_item->startFetch();
+ if (fetch_item->isFinished())
+ {
+ fetch_item->done();
+ }
+ else
+ {
+ gInventory.addObserver(fetch_item);
+ }
+
+ // In viewer 2 we're now auto receiving inventory offers and messaging as such (not sending reject messages).
+ info->send_auto_receive_response();
+
+ if (gAgent.isDoNotDisturb())
+ {
+ send_do_not_disturb_message(gMessageSystem, info->mFromID);
+ }
+
+ if (!bAutoAccept) // if we auto accept, do not pester the user
+ {
+ // Inform user that there is a script floater via toast system
+ payload["give_inventory_notification"] = TRUE;
+ p.payload = payload;
+ LLPostponedNotification::add<LLPostponedOfferNotification>(p, info->mFromID, false);
+ }
+ }
+
+ LLFirstUse::newInventory();
+}
+
+// Callback for name resolution of a god/estate message
+static void god_message_name_cb(const LLAvatarName& av_name, LLChat chat, std::string message)
+{
+ LLSD args;
+ args["NAME"] = av_name.getCompleteName();
+ args["MESSAGE"] = message;
+ LLNotificationsUtil::add("GodMessage", args);
+
+ // Treat like a system message and put in chat history.
+ chat.mSourceType = CHAT_SOURCE_SYSTEM;
+ chat.mText = message;
+
+ LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+ if (nearby_chat)
+ {
+ nearby_chat->addMessage(chat);
+ }
+}
+
+static bool parse_lure_bucket(const std::string& bucket,
+ U64& region_handle,
+ LLVector3& pos,
+ LLVector3& look_at,
+ U8& region_access)
+{
+ // tokenize the bucket
+ typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+ boost::char_separator<char> sep("|", "", boost::keep_empty_tokens);
+ tokenizer tokens(bucket, sep);
+ tokenizer::iterator iter = tokens.begin();
+
+ S32 gx, gy, rx, ry, rz, lx, ly, lz;
+ try
+ {
+ gx = boost::lexical_cast<S32>((*(iter)).c_str());
+ gy = boost::lexical_cast<S32>((*(++iter)).c_str());
+ rx = boost::lexical_cast<S32>((*(++iter)).c_str());
+ ry = boost::lexical_cast<S32>((*(++iter)).c_str());
+ rz = boost::lexical_cast<S32>((*(++iter)).c_str());
+ lx = boost::lexical_cast<S32>((*(++iter)).c_str());
+ ly = boost::lexical_cast<S32>((*(++iter)).c_str());
+ lz = boost::lexical_cast<S32>((*(++iter)).c_str());
+ }
+ catch (boost::bad_lexical_cast&)
+ {
+ LL_WARNS("parse_lure_bucket")
+ << "Couldn't parse lure bucket."
+ << LL_ENDL;
+ return false;
+ }
+ // Grab region access
+ region_access = SIM_ACCESS_MIN;
+ if (++iter != tokens.end())
+ {
+ std::string access_str((*iter).c_str());
+ LLStringUtil::trim(access_str);
+ if (access_str == "A")
+ {
+ region_access = SIM_ACCESS_ADULT;
+ }
+ else if (access_str == "M")
+ {
+ region_access = SIM_ACCESS_MATURE;
+ }
+ else if (access_str == "PG")
+ {
+ region_access = SIM_ACCESS_PG;
+ }
+ }
+
+ pos.setVec((F32)rx, (F32)ry, (F32)rz);
+ look_at.setVec((F32)lx, (F32)ly, (F32)lz);
+
+ region_handle = to_region_handle(gx, gy);
+ return true;
+}
+
+static void notification_display_name_callback(const LLUUID& id,
+ const LLAvatarName& av_name,
+ const std::string& name,
+ LLSD& substitutions,
+ const LLSD& payload)
+{
+ substitutions["NAME"] = av_name.getDisplayName();
+ LLNotificationsUtil::add(name, substitutions, payload);
+}
+
+void LLIMProcessing::processNewMessage(LLUUID from_id,
+ BOOL from_group,
+ LLUUID to_id,
+ U8 offline,
+ EInstantMessage dialog, // U8
+ LLUUID session_id,
+ U32 timestamp,
+ std::string agentName,
+ std::string message,
+ U32 parent_estate_id,
+ LLUUID region_id,
+ LLVector3 position,
+ U8 *binary_bucket,
+ S32 binary_bucket_size,
+ LLHost &sender,
+ LLUUID aux_id)
+{
+ LLChat chat;
+ std::string buffer;
+ std::string name = agentName;
+
+ // make sure that we don't have an empty or all-whitespace name
+ LLStringUtil::trim(name);
+ if (name.empty())
+ {
+ name = LLTrans::getString("Unnamed");
+ }
+
+ // Preserve the unaltered name for use in group notice mute checking.
+ std::string original_name = name;
+
+ // IDEVO convert new-style "Resident" names for display
+ name = clean_name_from_im(name, dialog);
+
+ BOOL is_do_not_disturb = gAgent.isDoNotDisturb();
+ BOOL is_muted = LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat)
+ // object IMs contain sender object id in session_id (STORM-1209)
+ || (dialog == IM_FROM_TASK && LLMuteList::getInstance()->isMuted(session_id));
+ BOOL is_owned_by_me = FALSE;
+ BOOL is_friend = (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL) ? false : true;
+ BOOL accept_im_from_only_friend = gSavedSettings.getBOOL("VoiceCallsFriendsOnly");
+ BOOL is_linden = chat.mSourceType != CHAT_SOURCE_OBJECT &&
+ LLMuteList::getInstance()->isLinden(name);
+
+ chat.mMuted = is_muted;
+ chat.mFromID = from_id;
+ chat.mFromName = name;
+ chat.mSourceType = (from_id.isNull() || (name == std::string(SYSTEM_FROM))) ? CHAT_SOURCE_SYSTEM : CHAT_SOURCE_AGENT;
+
+ if (chat.mSourceType == CHAT_SOURCE_SYSTEM)
+ { // Translate server message if required (MAINT-6109)
+ translate_if_needed(message);
+ }
+
+ LLViewerObject *source = gObjectList.findObject(session_id); //Session ID is probably the wrong thing.
+ if (source)
+ {
+ is_owned_by_me = source->permYouOwner();
+ }
+
+ std::string separator_string(": ");
+
+ LLSD args;
+ LLSD payload;
+ LLNotification::Params params;
+
+ switch (dialog)
+ {
+ case IM_CONSOLE_AND_CHAT_HISTORY:
+ args["MESSAGE"] = message;
+ payload["from_id"] = from_id;
+
+ params.name = "IMSystemMessageTip";
+ params.substitutions = args;
+ params.payload = payload;
+ LLPostponedNotification::add<LLPostponedIMSystemTipNotification>(params, from_id, false);
+ break;
+
+ case IM_NOTHING_SPECIAL: // p2p IM
+ // Don't show dialog, just do IM
+ if (!gAgent.isGodlike()
+ && gAgent.getRegion()->isPrelude()
+ && to_id.isNull())
+ {
+ // do nothing -- don't distract newbies in
+ // Prelude with global IMs
+ }
+ else if (offline == IM_ONLINE
+ && is_do_not_disturb
+ && from_id.notNull() //not a system message
+ && to_id.notNull()) //not global message
+ {
+
+ // now store incoming IM in chat history
+
+ buffer = message;
+
+ LL_DEBUGS("Messaging") << "session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
+
+ // add to IM panel, but do not bother the user
+ gIMMgr->addMessage(
+ session_id,
+ from_id,
+ name,
+ buffer,
+ IM_OFFLINE == offline,
+ LLStringUtil::null,
+ dialog,
+ parent_estate_id,
+ region_id,
+ position,
+ true);
+
+ if (!gIMMgr->isDNDMessageSend(session_id))
+ {
+ // return a standard "do not disturb" message, but only do it to online IM
+ // (i.e. not other auto responses and not store-and-forward IM)
+ send_do_not_disturb_message(gMessageSystem, from_id, session_id);
+ gIMMgr->setDNDMessageSent(session_id, true);
+ }
+
+ }
+ else if (from_id.isNull())
+ {
+ LLSD args;
+ args["MESSAGE"] = message;
+ LLNotificationsUtil::add("SystemMessage", args);
+ }
+ else if (to_id.isNull())
+ {
+ // Message to everyone from GOD, look up the fullname since
+ // server always slams name to legacy names
+ LLAvatarNameCache::get(from_id, boost::bind(god_message_name_cb, _2, chat, message));
+ }
+ else
+ {
+ // standard message, not from system
+ std::string saved;
+ if (offline == IM_OFFLINE)
+ {
+ LLStringUtil::format_map_t args;
+ args["[LONG_TIMESTAMP]"] = formatted_time(timestamp);
+ saved = LLTrans::getString("Saved_message", args);
+ }
+ buffer = saved + message;
+
+ LL_DEBUGS("Messaging") << "session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
+
+ bool mute_im = is_muted;
+ if (accept_im_from_only_friend && !is_friend && !is_linden)
+ {
+ if (!gIMMgr->isNonFriendSessionNotified(session_id))
+ {
+ std::string message = LLTrans::getString("IM_unblock_only_groups_friends");
+ gIMMgr->addMessage(session_id, from_id, name, message, IM_OFFLINE == offline);
+ gIMMgr->addNotifiedNonFriendSessionID(session_id);
+ }
+
+ mute_im = true;
+ }
+ if (!mute_im)
+ {
+ gIMMgr->addMessage(
+ session_id,
+ from_id,
+ name,
+ buffer,
+ IM_OFFLINE == offline,
+ LLStringUtil::null,
+ dialog,
+ parent_estate_id,
+ region_id,
+ position,
+ true);
+ }
+ else
+ {
+ /*
+ EXT-5099
+ */
+ }
+ }
+ break;
+
+ case IM_TYPING_START:
+ {
+ gIMMgr->processIMTypingStart(from_id, dialog);
+ }
+ break;
+
+ case IM_TYPING_STOP:
+ {
+ gIMMgr->processIMTypingStop(from_id, dialog);
+ }
+ break;
+
+ case IM_MESSAGEBOX:
+ {
+ // This is a block, modeless dialog.
+ args["MESSAGE"] = message;
+ LLNotificationsUtil::add("SystemMessageTip", args);
+ }
+ break;
+ case IM_GROUP_NOTICE:
+ case IM_GROUP_NOTICE_REQUESTED:
+ {
+ LL_INFOS("Messaging") << "Received IM_GROUP_NOTICE message." << LL_ENDL;
+
+ LLUUID agent_id;
+ U8 has_inventory;
+ U8 asset_type = 0;
+ LLUUID group_id;
+ std::string item_name;
+
+ if (aux_id.notNull())
+ {
+ // aux_id contains group id, binary bucket contains name and asset type
+ group_id = aux_id;
+ has_inventory = binary_bucket_size > 1 ? TRUE : FALSE;
+ from_group = TRUE; // inaccurate value correction
+ if (has_inventory)
+ {
+ 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();
+
+ asset_type = (LLAssetType::EType)(atoi((*(iter++)).c_str()));
+ iter++; // wearable type if applicable, otherwise asset type
+ item_name = std::string((*(iter++)).c_str());
+ // Note There is more elements in 'tokens' ...
+
+
+ for (int i = 0; i < 6; i++)
+ {
+ LL_WARNS() << *(iter++) << LL_ENDL;
+ iter++;
+ }
+ }
+ }
+ else
+ {
+ // All info is in binary bucket, read it for more information.
+ struct notice_bucket_header_t
+ {
+ U8 has_inventory;
+ U8 asset_type;
+ LLUUID group_id;
+ };
+ struct notice_bucket_full_t
+ {
+ struct notice_bucket_header_t header;
+ U8 item_name[DB_INV_ITEM_NAME_BUF_SIZE];
+ }*notice_bin_bucket;
+
+ // Make sure the binary bucket is big enough to hold the header
+ // and a null terminated item name.
+ if ((binary_bucket_size < (S32)((sizeof(notice_bucket_header_t) + sizeof(U8))))
+ || (binary_bucket[binary_bucket_size - 1] != '\0'))
+ {
+ LL_WARNS("Messaging") << "Malformed group notice binary bucket" << LL_ENDL;
+ break;
+ }
+
+ notice_bin_bucket = (struct notice_bucket_full_t*) &binary_bucket[0];
+ has_inventory = notice_bin_bucket->header.has_inventory;
+ asset_type = notice_bin_bucket->header.asset_type;
+ group_id = notice_bin_bucket->header.group_id;
+ item_name = ll_safe_string((const char*)notice_bin_bucket->item_name);
+ }
+
+ if (group_id != from_id)
+ {
+ agent_id = from_id;
+ }
+ else
+ {
+ S32 index = original_name.find(" Resident");
+ if (index != std::string::npos)
+ {
+ original_name = original_name.substr(0, index);
+ }
+
+ // The group notice packet does not have an AgentID. Obtain one from the name cache.
+ // If last name is "Resident" strip it out so the cache name lookup works.
+ std::string legacy_name = gCacheName->buildLegacyName(original_name);
+ agent_id = LLAvatarNameCache::findIdByName(legacy_name);
+
+ if (agent_id.isNull())
+ {
+ LL_WARNS("Messaging") << "buildLegacyName returned null while processing " << original_name << LL_ENDL;
+ }
+ }
+
+ if (agent_id.notNull() && LLMuteList::getInstance()->isMuted(agent_id))
+ {
+ break;
+ }
+
+ // If there is inventory, give the user the inventory offer.
+ LLOfferInfo* info = NULL;
+
+ if (has_inventory)
+ {
+ info = new LLOfferInfo();
+
+ info->mIM = IM_GROUP_NOTICE;
+ info->mFromID = from_id;
+ info->mFromGroup = from_group;
+ info->mTransactionID = session_id;
+ info->mType = (LLAssetType::EType) asset_type;
+ info->mFolderID = gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(info->mType));
+ std::string from_name;
+
+ from_name += "A group member named ";
+ from_name += name;
+
+ info->mFromName = from_name;
+ info->mDesc = item_name;
+ info->mHost = sender;
+ }
+
+ std::string str(message);
+
+ // Tokenize the string.
+ // TODO: Support escaped tokens ("||" -> "|")
+ typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+ boost::char_separator<char> sep("|", "", boost::keep_empty_tokens);
+ tokenizer tokens(str, sep);
+ tokenizer::iterator iter = tokens.begin();
+
+ std::string subj(*iter++);
+ std::string mes(*iter++);
+
+ // Send the notification down the new path.
+ // For requested notices, we don't want to send the popups.
+ if (dialog != IM_GROUP_NOTICE_REQUESTED)
+ {
+ payload["subject"] = subj;
+ payload["message"] = mes;
+ payload["sender_name"] = name;
+ payload["sender_id"] = agent_id;
+ payload["group_id"] = group_id;
+ payload["inventory_name"] = item_name;
+ payload["received_time"] = LLDate::now();
+ if (info && info->asLLSD())
+ {
+ payload["inventory_offer"] = info->asLLSD();
+ }
+
+ LLSD args;
+ args["SUBJECT"] = subj;
+ args["MESSAGE"] = mes;
+ LLDate notice_date = LLDate(timestamp).notNull() ? LLDate(timestamp) : LLDate::now();
+ LLNotifications::instance().add(LLNotification::Params("GroupNotice").substitutions(args).payload(payload).time_stamp(notice_date));
+ }
+
+ // Also send down the old path for now.
+ if (IM_GROUP_NOTICE_REQUESTED == dialog)
+ {
+
+ LLPanelGroup::showNotice(subj, mes, group_id, has_inventory, item_name, info);
+ }
+ else
+ {
+ delete info;
+ }
+ }
+ break;
+ case IM_GROUP_INVITATION:
+ {
+ if (!is_muted)
+ {
+ // group is not blocked, but we still need to check agent that sent the invitation
+ // and we have no agent's id
+ // Note: server sends username "first.last".
+ is_muted |= LLMuteList::getInstance()->isMuted(name);
+ }
+ if (is_do_not_disturb || is_muted)
+ {
+ send_do_not_disturb_message(gMessageSystem, from_id);
+ }
+
+ if (!is_muted)
+ {
+ LL_INFOS("Messaging") << "Received IM_GROUP_INVITATION message." << LL_ENDL;
+ // Read the binary bucket for more information.
+ struct invite_bucket_t
+ {
+ S32 membership_fee;
+ LLUUID role_id;
+ }*invite_bucket;
+
+ // Make sure the binary bucket is the correct size.
+ if (binary_bucket_size != sizeof(invite_bucket_t))
+ {
+ LL_WARNS("Messaging") << "Malformed group invite binary bucket" << LL_ENDL;
+ break;
+ }
+
+ invite_bucket = (struct invite_bucket_t*) &binary_bucket[0];
+ S32 membership_fee = ntohl(invite_bucket->membership_fee);
+
+ LLSD payload;
+ payload["transaction_id"] = session_id;
+ payload["group_id"] = from_id;
+ payload["name"] = name;
+ payload["message"] = message;
+ payload["fee"] = membership_fee;
+
+ LLSD args;
+ args["MESSAGE"] = message;
+ // we shouldn't pass callback functor since it is registered in LLFunctorRegistration
+ LLNotificationsUtil::add("JoinGroup", args, payload);
+ }
+ }
+ break;
+
+ case IM_INVENTORY_OFFERED:
+ case IM_TASK_INVENTORY_OFFERED:
+ // Someone has offered us some inventory.
+ {
+ LLOfferInfo* info = new LLOfferInfo;
+ if (IM_INVENTORY_OFFERED == dialog)
+ {
+ struct offer_agent_bucket_t
+ {
+ S8 asset_type;
+ LLUUID object_id;
+ }*bucketp;
+
+ if (sizeof(offer_agent_bucket_t) != binary_bucket_size)
+ {
+ LL_WARNS("Messaging") << "Malformed inventory offer from agent" << LL_ENDL;
+ delete info;
+ break;
+ }
+ bucketp = (struct offer_agent_bucket_t*) &binary_bucket[0];
+ info->mType = (LLAssetType::EType) bucketp->asset_type;
+ info->mObjectID = bucketp->object_id;
+ info->mFromObject = FALSE;
+ }
+ else // IM_TASK_INVENTORY_OFFERED
+ {
+ 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->mIM = dialog;
+ info->mFromID = from_id;
+ info->mFromGroup = from_group;
+ info->mTransactionID = session_id;
+ info->mFolderID = gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(info->mType));
+
+ info->mFromName = name;
+ info->mDesc = message;
+ info->mHost = sender;
+ //if (((is_do_not_disturb && !is_owned_by_me) || is_muted))
+ if (is_muted)
+ {
+ // Prefetch the offered item so that it can be discarded by the appropriate observer. (EXT-4331)
+ LLInventoryFetchItemsObserver* fetch_item = new LLInventoryFetchItemsObserver(info->mObjectID);
+ fetch_item->startFetch();
+ delete fetch_item;
+
+ // Same as closing window
+ info->forceResponse(IOR_DECLINE);
+ }
+ // old logic: busy mode must not affect interaction with objects (STORM-565)
+ // new logic: inventory offers from in-world objects should be auto-declined (CHUI-519)
+ else if (is_do_not_disturb && dialog == IM_TASK_INVENTORY_OFFERED)
+ {
+ // Until throttling is implemented, do not disturb mode should reject inventory instead of silently
+ // accepting it. SEE SL-39554
+ info->forceResponse(IOR_DECLINE);
+ }
+ else
+ {
+ inventory_offer_handler(info);
+ }
+ }
+ break;
+
+ case IM_INVENTORY_ACCEPTED:
+ {
+ args["NAME"] = LLSLURL("agent", from_id, "completename").getSLURLString();;
+ args["ORIGINAL_NAME"] = original_name;
+ LLSD payload;
+ payload["from_id"] = from_id;
+ // Passing the "SESSION_NAME" to use it for IM notification logging
+ // in LLTipHandler::processNotification(). See STORM-941.
+ payload["SESSION_NAME"] = name;
+ LLNotificationsUtil::add("InventoryAccepted", args, payload);
+ break;
+ }
+ case IM_INVENTORY_DECLINED:
+ {
+ args["NAME"] = LLSLURL("agent", from_id, "completename").getSLURLString();;
+ LLSD payload;
+ payload["from_id"] = from_id;
+ LLNotificationsUtil::add("InventoryDeclined", args, payload);
+ break;
+ }
+ // TODO: _DEPRECATED suffix as part of vote removal - DEV-24856
+ case IM_GROUP_VOTE:
+ {
+ LL_WARNS("Messaging") << "Received IM: IM_GROUP_VOTE_DEPRECATED" << LL_ENDL;
+ }
+ break;
+
+ case IM_GROUP_ELECTION_DEPRECATED:
+ {
+ LL_WARNS("Messaging") << "Received IM: IM_GROUP_ELECTION_DEPRECATED" << LL_ENDL;
+ }
+ break;
+
+ case IM_FROM_TASK:
+ {
+
+ if (is_do_not_disturb && !is_owned_by_me)
+ {
+ return;
+ }
+
+ // Build a link to open the object IM info window.
+ std::string location = ll_safe_string((char*)binary_bucket, binary_bucket_size - 1);
+
+ if (session_id.notNull())
+ {
+ chat.mFromID = session_id;
+ }
+ else
+ {
+ // This message originated on a region without the updated code for task id and slurl information.
+ // We just need a unique ID for this object that isn't the owner ID.
+ // If it is the owner ID it will overwrite the style that contains the link to that owner's profile.
+ // This isn't ideal - it will make 1 style for all objects owned by the the same person/group.
+ // This works because the only thing we can really do in this case is show the owner name and link to their profile.
+ chat.mFromID = from_id ^ gAgent.getSessionID();
+ }
+
+ chat.mSourceType = CHAT_SOURCE_OBJECT;
+
+ // To conclude that the source type of message is CHAT_SOURCE_SYSTEM it's not
+ // enough to check only from name (i.e. fromName = "Second Life"). For example
+ // source type of messages from objects called "Second Life" should not be CHAT_SOURCE_SYSTEM.
+ bool chat_from_system = (SYSTEM_FROM == name) && region_id.isNull() && position.isNull();
+ if (chat_from_system)
+ {
+ // System's UUID is NULL (fixes EXT-4766)
+ chat.mFromID = LLUUID::null;
+ chat.mSourceType = CHAT_SOURCE_SYSTEM;
+ }
+
+ // IDEVO Some messages have embedded resident names
+ message = clean_name_from_task_im(message, from_group);
+
+ LLSD query_string;
+ query_string["owner"] = from_id;
+ query_string["slurl"] = location;
+ query_string["name"] = name;
+ if (from_group)
+ {
+ query_string["groupowned"] = "true";
+ }
+
+ chat.mURL = LLSLURL("objectim", session_id, "").getSLURLString();
+ chat.mText = message;
+
+ // Note: lie to Nearby Chat, pretending that this is NOT an IM, because
+ // IMs from obejcts don't open IM sessions.
+ LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+ if (!chat_from_system && nearby_chat)
+ {
+ chat.mOwnerID = from_id;
+ LLSD args;
+ args["slurl"] = location;
+
+ // Look for IRC-style emotes here so object name formatting is correct
+ std::string prefix = message.substr(0, 4);
+ if (prefix == "/me " || prefix == "/me'")
+ {
+ chat.mChatStyle = CHAT_STYLE_IRC;
+ }
+
+ LLNotificationsUI::LLNotificationManager::instance().onChat(chat, args);
+ }
+
+
+ //Object IMs send with from name: 'Second Life' need to be displayed also in notification toasts (EXT-1590)
+ if (!chat_from_system) break;
+
+ LLSD substitutions;
+ substitutions["NAME"] = name;
+ substitutions["MSG"] = message;
+
+ LLSD payload;
+ payload["object_id"] = session_id;
+ payload["owner_id"] = from_id;
+ payload["from_id"] = from_id;
+ payload["slurl"] = location;
+ payload["name"] = name;
+
+ if (from_group)
+ {
+ payload["group_owned"] = "true";
+ }
+
+ LLNotificationsUtil::add("ServerObjectMessage", substitutions, payload);
+ }
+ break;
+
+ case IM_SESSION_SEND: // ad-hoc or group IMs
+
+ // Only show messages if we have a session open (which
+ // should happen after you get an "invitation"
+ if (!gIMMgr->hasSession(session_id))
+ {
+ return;
+ }
+
+ else if (offline == IM_ONLINE && is_do_not_disturb)
+ {
+
+ // return a standard "do not disturb" message, but only do it to online IM
+ // (i.e. not other auto responses and not store-and-forward IM)
+ if (!gIMMgr->hasSession(session_id))
+ {
+ // if there is not a panel for this conversation (i.e. it is a new IM conversation
+ // initiated by the other party) then...
+ send_do_not_disturb_message(gMessageSystem, from_id, session_id);
+ }
+
+ // now store incoming IM in chat history
+
+ buffer = message;
+
+ LL_DEBUGS("Messaging") << "message in dnd; session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
+
+ // add to IM panel, but do not bother the user
+ gIMMgr->addMessage(
+ session_id,
+ from_id,
+ name,
+ buffer,
+ IM_OFFLINE == offline,
+ ll_safe_string((char*)binary_bucket),
+ IM_SESSION_INVITE,
+ parent_estate_id,
+ region_id,
+ position,
+ true);
+ }
+ else
+ {
+ // standard message, not from system
+ std::string saved;
+ if (offline == IM_OFFLINE)
+ {
+ saved = llformat("(Saved %s) ", formatted_time(timestamp).c_str());
+ }
+
+ buffer = saved + message;
+
+ LL_DEBUGS("Messaging") << "standard message session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
+
+ gIMMgr->addMessage(
+ session_id,
+ from_id,
+ name,
+ buffer,
+ IM_OFFLINE == offline,
+ ll_safe_string((char*)binary_bucket),
+ IM_SESSION_INVITE,
+ parent_estate_id,
+ region_id,
+ position,
+ true);
+ }
+ break;
+
+ case IM_FROM_TASK_AS_ALERT:
+ if (is_do_not_disturb && !is_owned_by_me)
+ {
+ return;
+ }
+ {
+ // Construct a viewer alert for this message.
+ args["NAME"] = name;
+ args["MESSAGE"] = message;
+ LLNotificationsUtil::add("ObjectMessage", args);
+ }
+ break;
+ case IM_DO_NOT_DISTURB_AUTO_RESPONSE:
+ if (is_muted)
+ {
+ LL_DEBUGS("Messaging") << "Ignoring do-not-disturb response from " << from_id << LL_ENDL;
+ return;
+ }
+ else
+ {
+ gIMMgr->addMessage(session_id, from_id, name, message);
+ }
+ break;
+
+ case IM_LURE_USER:
+ case IM_TELEPORT_REQUEST:
+ {
+ if (is_muted)
+ {
+ return;
+ }
+ else if (gSavedSettings.getBOOL("VoiceCallsFriendsOnly") && (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL))
+ {
+ return;
+ }
+ else
+ {
+ if (is_do_not_disturb)
+ {
+ send_do_not_disturb_message(gMessageSystem, from_id);
+ }
+
+ LLVector3 pos, look_at;
+ U64 region_handle(0);
+ U8 region_access(SIM_ACCESS_MIN);
+ std::string region_info = ll_safe_string((char*)binary_bucket, binary_bucket_size);
+ std::string region_access_str = LLStringUtil::null;
+ std::string region_access_icn = LLStringUtil::null;
+ std::string region_access_lc = LLStringUtil::null;
+
+ bool canUserAccessDstRegion = true;
+ bool doesUserRequireMaturityIncrease = false;
+
+ // Do not parse the (empty) lure bucket for TELEPORT_REQUEST
+ if (IM_TELEPORT_REQUEST != dialog && parse_lure_bucket(region_info, region_handle, pos, look_at, region_access))
+ {
+ region_access_str = LLViewerRegion::accessToString(region_access);
+ region_access_icn = LLViewerRegion::getAccessIcon(region_access);
+ region_access_lc = region_access_str;
+ LLStringUtil::toLower(region_access_lc);
+
+ if (!gAgent.isGodlike())
+ {
+ switch (region_access)
+ {
+ case SIM_ACCESS_MIN:
+ case SIM_ACCESS_PG:
+ break;
+ case SIM_ACCESS_MATURE:
+ if (gAgent.isTeen())
+ {
+ canUserAccessDstRegion = false;
+ }
+ else if (gAgent.prefersPG())
+ {
+ doesUserRequireMaturityIncrease = true;
+ }
+ break;
+ case SIM_ACCESS_ADULT:
+ if (!gAgent.isAdult())
+ {
+ canUserAccessDstRegion = false;
+ }
+ else if (!gAgent.prefersAdult())
+ {
+ doesUserRequireMaturityIncrease = true;
+ }
+ break;
+ default:
+ llassert(0);
+ break;
+ }
+ }
+ }
+
+ LLSD args;
+ // *TODO: Translate -> [FIRST] [LAST] (maybe)
+ args["NAME_SLURL"] = LLSLURL("agent", from_id, "about").getSLURLString();
+ args["MESSAGE"] = message;
+ args["MATURITY_STR"] = region_access_str;
+ args["MATURITY_ICON"] = region_access_icn;
+ args["REGION_CONTENT_MATURITY"] = region_access_lc;
+ LLSD payload;
+ payload["from_id"] = from_id;
+ payload["lure_id"] = session_id;
+ payload["godlike"] = FALSE;
+ payload["region_maturity"] = region_access;
+
+ if (!canUserAccessDstRegion)
+ {
+ LLNotification::Params params("TeleportOffered_MaturityBlocked");
+ params.substitutions = args;
+ params.payload = payload;
+ LLPostponedNotification::add<LLPostponedOfferNotification>(params, from_id, false);
+ send_simple_im(from_id, LLTrans::getString("TeleportMaturityExceeded"), IM_NOTHING_SPECIAL, session_id);
+ send_simple_im(from_id, LLStringUtil::null, IM_LURE_DECLINED, session_id);
+ }
+ else if (doesUserRequireMaturityIncrease)
+ {
+ LLNotification::Params params("TeleportOffered_MaturityExceeded");
+ params.substitutions = args;
+ params.payload = payload;
+ LLPostponedNotification::add<LLPostponedOfferNotification>(params, from_id, false);
+ }
+ else
+ {
+ LLNotification::Params params;
+ if (IM_LURE_USER == dialog)
+ {
+ params.name = "TeleportOffered";
+ params.functor.name = "TeleportOffered";
+ }
+ else if (IM_TELEPORT_REQUEST == dialog)
+ {
+ params.name = "TeleportRequest";
+ params.functor.name = "TeleportRequest";
+ }
+
+ params.substitutions = args;
+ params.payload = payload;
+ LLPostponedNotification::add<LLPostponedOfferNotification>(params, from_id, false);
+ }
+ }
+ }
+ break;
+
+ case IM_GODLIKE_LURE_USER:
+ {
+ LLVector3 pos, look_at;
+ U64 region_handle(0);
+ U8 region_access(SIM_ACCESS_MIN);
+ std::string region_info = ll_safe_string((char*)binary_bucket, binary_bucket_size);
+ std::string region_access_str = LLStringUtil::null;
+ std::string region_access_icn = LLStringUtil::null;
+ std::string region_access_lc = LLStringUtil::null;
+
+ bool canUserAccessDstRegion = true;
+ bool doesUserRequireMaturityIncrease = false;
+
+ if (parse_lure_bucket(region_info, region_handle, pos, look_at, region_access))
+ {
+ region_access_str = LLViewerRegion::accessToString(region_access);
+ region_access_icn = LLViewerRegion::getAccessIcon(region_access);
+ region_access_lc = region_access_str;
+ LLStringUtil::toLower(region_access_lc);
+
+ if (!gAgent.isGodlike())
+ {
+ switch (region_access)
+ {
+ case SIM_ACCESS_MIN:
+ case SIM_ACCESS_PG:
+ break;
+ case SIM_ACCESS_MATURE:
+ if (gAgent.isTeen())
+ {
+ canUserAccessDstRegion = false;
+ }
+ else if (gAgent.prefersPG())
+ {
+ doesUserRequireMaturityIncrease = true;
+ }
+ break;
+ case SIM_ACCESS_ADULT:
+ if (!gAgent.isAdult())
+ {
+ canUserAccessDstRegion = false;
+ }
+ else if (!gAgent.prefersAdult())
+ {
+ doesUserRequireMaturityIncrease = true;
+ }
+ break;
+ default:
+ llassert(0);
+ break;
+ }
+ }
+ }
+
+ LLSD args;
+ // *TODO: Translate -> [FIRST] [LAST] (maybe)
+ args["NAME_SLURL"] = LLSLURL("agent", from_id, "about").getSLURLString();
+ args["MESSAGE"] = message;
+ args["MATURITY_STR"] = region_access_str;
+ args["MATURITY_ICON"] = region_access_icn;
+ args["REGION_CONTENT_MATURITY"] = region_access_lc;
+ LLSD payload;
+ payload["from_id"] = from_id;
+ payload["lure_id"] = session_id;
+ payload["godlike"] = TRUE;
+ payload["region_maturity"] = region_access;
+
+ if (!canUserAccessDstRegion)
+ {
+ LLNotification::Params params("TeleportOffered_MaturityBlocked");
+ params.substitutions = args;
+ params.payload = payload;
+ LLPostponedNotification::add<LLPostponedOfferNotification>(params, from_id, false);
+ send_simple_im(from_id, LLTrans::getString("TeleportMaturityExceeded"), IM_NOTHING_SPECIAL, session_id);
+ send_simple_im(from_id, LLStringUtil::null, IM_LURE_DECLINED, session_id);
+ }
+ else if (doesUserRequireMaturityIncrease)
+ {
+ LLNotification::Params params("TeleportOffered_MaturityExceeded");
+ params.substitutions = args;
+ params.payload = payload;
+ LLPostponedNotification::add<LLPostponedOfferNotification>(params, from_id, false);
+ }
+ else
+ {
+ // do not show a message box, because you're about to be
+ // teleported.
+ LLNotifications::instance().forceResponse(LLNotification::Params("TeleportOffered").payload(payload), 0);
+ }
+ }
+ break;
+
+ case IM_GOTO_URL:
+ {
+ LLSD args;
+ // n.b. this is for URLs sent by the system, not for
+ // URLs sent by scripts (i.e. llLoadURL)
+ if (binary_bucket_size <= 0)
+ {
+ LL_WARNS("Messaging") << "bad binary_bucket_size: "
+ << binary_bucket_size
+ << " - aborting function." << LL_ENDL;
+ return;
+ }
+
+ std::string url;
+
+ url.assign((char*)binary_bucket, binary_bucket_size - 1);
+ args["MESSAGE"] = message;
+ args["URL"] = url;
+ LLSD payload;
+ payload["url"] = url;
+ LLNotificationsUtil::add("GotoURL", args, payload);
+ }
+ break;
+
+ case IM_FRIENDSHIP_OFFERED:
+ {
+ LLSD payload;
+ payload["from_id"] = from_id;
+ payload["session_id"] = session_id;;
+ payload["online"] = (offline == IM_ONLINE);
+ payload["sender"] = sender.getIPandPort();
+
+ bool add_notification = true;
+ for (LLToastNotifyPanel::instance_iter ti(LLToastNotifyPanel::beginInstances())
+ , tend(LLToastNotifyPanel::endInstances()); ti != tend; ++ti)
+ {
+ LLToastNotifyPanel& panel = *ti;
+ const std::string& notification_name = panel.getNotificationName();
+ if (notification_name == "OfferFriendship" && panel.isControlPanelEnabled())
+ {
+ add_notification = false;
+ break;
+ }
+ }
+
+ if (is_muted && add_notification)
+ {
+ LLNotifications::instance().forceResponse(LLNotification::Params("OfferFriendship").payload(payload), 1);
+ }
+ else
+ {
+ if (is_do_not_disturb)
+ {
+ send_do_not_disturb_message(gMessageSystem, from_id);
+ }
+ args["NAME_SLURL"] = LLSLURL("agent", from_id, "about").getSLURLString();
+
+ if (add_notification)
+ {
+ if (message.empty())
+ {
+ //support for frienship offers from clients before July 2008
+ LLNotificationsUtil::add("OfferFriendshipNoMessage", args, payload);
+ }
+ else
+ {
+ args["[MESSAGE]"] = message;
+ LLNotification::Params params("OfferFriendship");
+ params.substitutions = args;
+ params.payload = payload;
+ LLPostponedNotification::add<LLPostponedOfferNotification>(params, from_id, false);
+ }
+ }
+ }
+ }
+ break;
+
+ case IM_FRIENDSHIP_ACCEPTED:
+ {
+ // In the case of an offline IM, the formFriendship() may be extraneous
+ // as the database should already include the relationship. But it
+ // doesn't hurt for dupes.
+ LLAvatarTracker::formFriendship(from_id);
+
+ std::vector<std::string> strings;
+ strings.push_back(from_id.asString());
+ send_generic_message("requestonlinenotification", strings);
+
+ args["NAME"] = name;
+ LLSD payload;
+ payload["from_id"] = from_id;
+ LLAvatarNameCache::get(from_id, boost::bind(&notification_display_name_callback, _1, _2, "FriendshipAccepted", args, payload));
+ }
+ break;
+
+ case IM_FRIENDSHIP_DECLINED_DEPRECATED:
+ default:
+ LL_WARNS("Messaging") << "Instant message calling for unknown dialog "
+ << (S32)dialog << LL_ENDL;
+ break;
+ }
+
+ LLWindow* viewer_window = gViewerWindow->getWindow();
+ if (viewer_window && viewer_window->getMinimized())
+ {
+ viewer_window->flashIcon(5.f);
+ }
+}
+
+void LLIMProcessing::requestOfflineMessages()
+{
+ static BOOL requested = FALSE;
+ if (!requested
+ && gMessageSystem
+ && LLMuteList::getInstance()->isLoaded()
+ && isAgentAvatarValid()
+ && gAgent.getRegion()
+ && gAgent.getRegion()->capabilitiesReceived())
+ {
+ std::string cap_url = gAgent.getRegionCapability("ReadOfflineMsgs");
+
+ // Auto-accepted inventory items may require the avatar object
+ // to build a correct name. Likewise, inventory offers from
+ // muted avatars require the mute list to properly mute.
+ if (cap_url.empty())
+ {
+ requestOfflineMessagesLegacy();
+ }
+ else
+ {
+ LLCoros::instance().launch("LLIMProcessing::requestOfflineMessagesCoro",
+ boost::bind(&LLIMProcessing::requestOfflineMessagesCoro, cap_url));
+ }
+ requested = TRUE;
+ }
+}
+
+void LLIMProcessing::requestOfflineMessagesCoro(std::string url)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("requestOfflineMessagesCoro", 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) // success = httpResults["success"].asBoolean();
+ {
+ LL_WARNS("Messaging") << "Error requesting offline messages via capability " << url << ", Status: " << status.toString() << "\nFalling back to legacy method." << LL_ENDL;
+
+ requestOfflineMessagesLegacy();
+ return;
+ }
+
+ LLSD contents = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_CONTENT];
+
+ if (!contents.size())
+ {
+ LL_WARNS("Messaging") << "No contents received for offline messages via capability " << url << LL_ENDL;
+ return;
+ }
+
+ // Todo: once dirtsim-369 releases, remove one of the map/array options
+ LLSD messages;
+ if (contents.isArray())
+ {
+ messages = *contents.beginArray();
+ }
+ else if (contents.has("messages"))
+ {
+ messages = contents["messages"];
+ }
+ else
+ {
+ LL_WARNS("Messaging") << "Invalid offline message content received via capability " << url << LL_ENDL;
+ return;
+ }
+
+ if (!messages.isArray())
+ {
+ LL_WARNS("Messaging") << "Invalid offline message content received via capability " << url << LL_ENDL;
+ return;
+ }
+
+ if (messages.emptyArray())
+ {
+ // Nothing to process
+ return;
+ }
+
+ LL_INFOS("Messaging") << "Processing offline messages." << LL_ENDL;
+
+ std::vector<U8> data;
+ S32 binary_bucket_size = 0;
+ LLHost sender = gAgent.getRegion()->getHost();
+
+ LLSD::array_iterator i = messages.beginArray();
+ LLSD::array_iterator iEnd = messages.endArray();
+ for (; i != iEnd; ++i)
+ {
+ const LLSD &message_data(*i);
+
+ LLVector3 position(message_data["local_x"].asReal(), message_data["local_y"].asReal(), message_data["local_z"].asReal());
+ data = message_data["binary_bucket"].asBinary();
+ binary_bucket_size = data.size(); // message_data["count"] always 0
+ U32 parent_estate_id = message_data.has("parent_estate_id") ? message_data["parent_estate_id"].asInteger() : 1; // 1 - IMMainland
+
+ // Todo: once dirtsim-369 releases, remove one of the int/str options
+ BOOL from_group;
+ if (message_data["from_group"].isInteger())
+ {
+ from_group = message_data["from_group"].asInteger();
+ }
+ else
+ {
+ from_group = message_data["from_group"].asString() == "Y";
+ }
+
+ LLIMProcessing::processNewMessage(message_data["from_agent_id"].asUUID(),
+ from_group,
+ message_data["to_agent_id"].asUUID(),
+ IM_OFFLINE,
+ (EInstantMessage)message_data["dialog"].asInteger(),
+ LLUUID::null, // session id, fix this for friendship offers to work
+ message_data["timestamp"].asInteger(),
+ message_data["from_agent_name"].asString(),
+ message_data["message"].asString(),
+ parent_estate_id,
+ message_data["region_id"].asUUID(),
+ position,
+ &data[0],
+ binary_bucket_size,
+ sender,
+ message_data["asset_id"].asUUID()); // not necessarily an asset
+ }
+}
+
+void LLIMProcessing::requestOfflineMessagesLegacy()
+{
+ LL_INFOS("Messaging") << "Requesting offline messages (Legacy)." << LL_ENDL;
+
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_RetrieveInstantMessages);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ gAgent.sendReliableMessage();
+}
+
diff --git a/indra/newview/llimprocessing.h b/indra/newview/llimprocessing.h
new file mode 100644
index 0000000000..4d20b963a4
--- /dev/null
+++ b/indra/newview/llimprocessing.h
@@ -0,0 +1,63 @@
+/**
+* @file LLIMMgr.h
+* @brief Container for Instant Messaging
+*
+* $LicenseInfo:firstyear=2001&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2010, 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_LLIMPROCESSING_H
+#define LL_LLIMPROCESSING_H
+
+#include "llinstantmessage.h"
+
+class LLIMProcessing
+{
+public:
+ // Pre-process message for IM manager
+ static void processNewMessage(LLUUID from_id,
+ BOOL from_group,
+ LLUUID to_id,
+ U8 offline,
+ EInstantMessage dialog, // U8
+ LLUUID session_id,
+ U32 timestamp,
+ std::string agentName,
+ std::string message,
+ U32 parent_estate_id,
+ LLUUID region_id,
+ LLVector3 position,
+ U8 *binary_bucket,
+ S32 binary_bucket_size,
+ LLHost &sender,
+ LLUUID aux_id = LLUUID::null);
+
+ // Either receives list of offline messages from 'ReadOfflineMsgs' capability
+ // or uses legacy method
+ static void requestOfflineMessages();
+
+private:
+ static void requestOfflineMessagesCoro(std::string url);
+ static void requestOfflineMessagesLegacy();
+};
+
+
+#endif // LL_LLLLIMPROCESSING_H
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index d62b6300cb..0f5d514660 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -3432,23 +3432,23 @@ void LLIMMgr::noteMutedUsers(const LLUUID& session_id,
}
}
-void LLIMMgr::processIMTypingStart(const LLIMInfo* im_info)
+void LLIMMgr::processIMTypingStart(const LLUUID& from_id, const EInstantMessage im_type)
{
- processIMTypingCore(im_info, TRUE);
+ processIMTypingCore(from_id, im_type, TRUE);
}
-void LLIMMgr::processIMTypingStop(const LLIMInfo* im_info)
+void LLIMMgr::processIMTypingStop(const LLUUID& from_id, const EInstantMessage im_type)
{
- processIMTypingCore(im_info, FALSE);
+ processIMTypingCore(from_id, im_type, FALSE);
}
-void LLIMMgr::processIMTypingCore(const LLIMInfo* im_info, BOOL typing)
+void LLIMMgr::processIMTypingCore(const LLUUID& from_id, const EInstantMessage im_type, BOOL typing)
{
- LLUUID session_id = computeSessionID(im_info->mIMType, im_info->mFromID);
+ LLUUID session_id = computeSessionID(im_type, from_id);
LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(session_id);
if ( im_floater )
{
- im_floater->processIMTyping(im_info, typing);
+ im_floater->processIMTyping(from_id, typing);
}
}
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index e3851a56e0..81d3ffa1a6 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -391,8 +391,8 @@ public:
const std::string& session_handle = LLStringUtil::null,
const std::string& session_uri = LLStringUtil::null);
- void processIMTypingStart(const LLIMInfo* im_info);
- void processIMTypingStop(const LLIMInfo* im_info);
+ void processIMTypingStart(const LLUUID& from_id, const EInstantMessage im_type);
+ void processIMTypingStop(const LLUUID& from_id, const EInstantMessage im_type);
// automatically start a call once the session has initialized
void autoStartCallOnStartup(const LLUUID& session_id);
@@ -471,7 +471,7 @@ private:
void noteOfflineUsers(const LLUUID& session_id, const std::vector<LLUUID>& ids);
void noteMutedUsers(const LLUUID& session_id, const std::vector<LLUUID>& ids);
- void processIMTypingCore(const LLIMInfo* im_info, BOOL typing);
+ void processIMTypingCore(const LLUUID& from_id, const EInstantMessage im_type, BOOL typing);
static void onInviteNameLookup(LLSD payload, const LLUUID& id, const LLAvatarName& name);
diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp
index 1e15dc832c..88e7ad1b71 100644
--- a/indra/newview/llinspectavatar.cpp
+++ b/indra/newview/llinspectavatar.cpp
@@ -215,7 +215,9 @@ void LLInspectAvatar::onOpen(const LLSD& data)
}
// Generate link to avatar profile.
- getChild<LLUICtrl>("avatar_profile_link")->setTextArg("[LINK]", LLSLURL("agent", mAvatarID, "about").getSLURLString());
+ LLTextBase* avatar_profile_link = getChild<LLTextBase>("avatar_profile_link");
+ avatar_profile_link->setTextArg("[LINK]", LLSLURL("agent", mAvatarID, "about").getSLURLString());
+ avatar_profile_link->setIsFriendCallback(LLAvatarActions::isFriend);
// can't call from constructor as widgets are not built yet
requestUpdate();
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 3acfaeb049..90a000c196 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -779,6 +779,14 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
if (obj)
{
+
+ items.push_back(std::string("Copy Separator"));
+ items.push_back(std::string("Copy"));
+ if (!isItemCopyable())
+ {
+ disabled_items.push_back(std::string("Copy"));
+ }
+
if (obj->getIsLinkType())
{
items.push_back(std::string("Find Original"));
@@ -821,13 +829,6 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
disabled_items.push_back(std::string("Copy Asset UUID"));
}
}
- items.push_back(std::string("Copy Separator"));
-
- items.push_back(std::string("Copy"));
- if (!isItemCopyable())
- {
- disabled_items.push_back(std::string("Copy"));
- }
items.push_back(std::string("Cut"));
if (!isItemMovable() || !isItemRemovable())
@@ -2104,12 +2105,6 @@ BOOL LLItemBridge::isItemCopyable() const
return FALSE;
}
- // You can never copy a link.
- if (item->getIsLinkType())
- {
- return FALSE;
- }
-
return item->getPermissions().allowCopyBy(gAgent.getID()) || gSavedSettings.getBOOL("InventoryLinking");
}
return FALSE;
@@ -3812,6 +3807,11 @@ void LLFolderBridge::perform_pasteFromClipboard()
break;
}
}
+ else if (item->getIsLinkType())
+ {
+ link_inventory_object(parent_id, item_id,
+ LLPointer<LLInventoryCallback>(NULL));
+ }
else
{
copy_inventory_item(
@@ -6588,11 +6588,9 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
getClipboardEntries(true, items, disabled_items, flags);
items.push_back(std::string("Wearable And Object Separator"));
-
items.push_back(std::string("Wearable Edit"));
- bool modifiable = !gAgentWearables.isWearableModifiable(item->getUUID());
- if (((flags & FIRST_SELECTED_ITEM) == 0) || modifiable)
+ if (((flags & FIRST_SELECTED_ITEM) == 0) || (item && !gAgentWearables.isWearableModifiable(item->getUUID())))
{
disabled_items.push_back(std::string("Wearable Edit"));
}
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index 9193613e9f..f64c39c3ad 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -153,7 +153,7 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const
// we're showing all folders, overriding filter
if (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS)
{
- return true;
+ return !gInventory.isCategoryHidden(folder_id);
}
// when applying a filter, matching folders get their contents downloaded first
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index e056ccebee..030c967019 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -398,57 +398,66 @@ void copy_inventory_category(LLInventoryModel* model,
LLViewerInventoryCategory* cat,
const LLUUID& parent_id,
const LLUUID& root_copy_id,
- bool move_no_copy_items )
+ bool move_no_copy_items )
{
// Create the initial folder
- LLUUID new_cat_uuid = gInventory.createNewCategory(parent_id, LLFolderType::FT_NONE, cat->getName());
+ inventory_func_type func = boost::bind(&copy_inventory_category_content, _1, model, cat, root_copy_id, move_no_copy_items);
+ gInventory.createNewCategory(parent_id, LLFolderType::FT_NONE, cat->getName(), func);
+}
+
+void copy_inventory_category_content(const LLUUID& new_cat_uuid, LLInventoryModel* model, LLViewerInventoryCategory* cat, const LLUUID& root_copy_id, bool move_no_copy_items)
+{
model->notifyObservers();
-
+
// We need to exclude the initial root of the copy to avoid recursively copying the copy, etc...
LLUUID root_id = (root_copy_id.isNull() ? new_cat_uuid : root_copy_id);
// Get the content of the folder
LLInventoryModel::cat_array_t* cat_array;
LLInventoryModel::item_array_t* item_array;
- gInventory.getDirectDescendentsOf(cat->getUUID(),cat_array,item_array);
-
- // If root_copy_id is null, tell the marketplace model we'll be waiting for new items to be copied over for this folder
- if (root_copy_id.isNull())
- {
- LLMarketplaceData::instance().setValidationWaiting(root_id,count_descendants_items(cat->getUUID()));
- }
+ gInventory.getDirectDescendentsOf(cat->getUUID(), cat_array, item_array);
+
+ // If root_copy_id is null, tell the marketplace model we'll be waiting for new items to be copied over for this folder
+ if (root_copy_id.isNull())
+ {
+ LLMarketplaceData::instance().setValidationWaiting(root_id, count_descendants_items(cat->getUUID()));
+ }
// Copy all the items
LLInventoryModel::item_array_t item_array_copy = *item_array;
for (LLInventoryModel::item_array_t::iterator iter = item_array_copy.begin(); iter != item_array_copy.end(); iter++)
{
LLInventoryItem* item = *iter;
- LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(update_folder_cb, new_cat_uuid));
+ LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(update_folder_cb, new_cat_uuid));
- if (!item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID()))
- {
- // If the item is nocopy, we do nothing or, optionally, move it
- if (move_no_copy_items)
- {
- // Reparent the item
- LLViewerInventoryItem * viewer_inv_item = (LLViewerInventoryItem *) item;
- gInventory.changeItemParent(viewer_inv_item, new_cat_uuid, true);
- }
- // Decrement the count in root_id since that one item won't be copied over
- LLMarketplaceData::instance().decrementValidationWaiting(root_id);
- }
- else
- {
- copy_inventory_item(
- gAgent.getID(),
- item->getPermissions().getOwner(),
- item->getUUID(),
- new_cat_uuid,
- std::string(),
- cb);
- }
+ if (item->getIsLinkType())
+ {
+ link_inventory_object(new_cat_uuid, item->getLinkedUUID(), cb);
+ }
+ else if (!item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID()))
+ {
+ // If the item is nocopy, we do nothing or, optionally, move it
+ if (move_no_copy_items)
+ {
+ // Reparent the item
+ LLViewerInventoryItem * viewer_inv_item = (LLViewerInventoryItem *)item;
+ gInventory.changeItemParent(viewer_inv_item, new_cat_uuid, true);
+ }
+ // Decrement the count in root_id since that one item won't be copied over
+ LLMarketplaceData::instance().decrementValidationWaiting(root_id);
+ }
+ else
+ {
+ copy_inventory_item(
+ gAgent.getID(),
+ item->getPermissions().getOwner(),
+ item->getUUID(),
+ new_cat_uuid,
+ std::string(),
+ cb);
+ }
}
-
+
// Copy all the folders
LLInventoryModel::cat_array_t cat_array_copy = *cat_array;
for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++)
diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h
index d454d7e00b..fd106bc2d8 100644
--- a/indra/newview/llinventoryfunctions.h
+++ b/indra/newview/llinventoryfunctions.h
@@ -72,6 +72,8 @@ void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::s
void copy_inventory_category(LLInventoryModel* model, LLViewerInventoryCategory* cat, const LLUUID& parent_id, const LLUUID& root_copy_id = LLUUID::null, bool move_no_copy_items = false);
+void copy_inventory_category_content(const LLUUID& new_cat_uuid, LLInventoryModel* model, LLViewerInventoryCategory* cat, const LLUUID& root_copy_id, bool move_no_copy_items);
+
// Generates a string containing the path to the item specified by item_id.
void append_path(const LLUUID& id, std::string& path);
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 6a1ec9f991..76bf87cfe5 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -342,6 +342,27 @@ LLViewerInventoryCategory* LLInventoryModel::getCategory(const LLUUID& id) const
return category;
}
+bool LLInventoryModel::isCategoryHidden(const LLUUID& id) const
+{
+ bool res = false;
+ const LLViewerInventoryCategory* category = getCategory(id);
+ if (category)
+ {
+ LLFolderType::EType cat_type = category->getPreferredType();
+ switch (cat_type)
+ {
+ case LLFolderType::FT_INBOX:
+ case LLFolderType::FT_OUTBOX:
+ case LLFolderType::FT_MARKETPLACE_LISTINGS:
+ res = true;
+ break;
+ default:
+ break;
+ }
+ }
+ return res;
+}
+
S32 LLInventoryModel::getItemCount() const
{
return mItemMap.size();
@@ -904,7 +925,20 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item, U32 mask)
new_item = old_item;
LLUUID old_parent_id = old_item->getParentUUID();
LLUUID new_parent_id = item->getParentUUID();
-
+ bool update_parent_on_server = false;
+
+ if (new_parent_id.isNull())
+ {
+ // item with null parent will end in random location and then in Lost&Found,
+ // either move to default folder as if it is new item or don't move at all
+ LL_WARNS(LOG_INV) << "Update attempts to reparent item " << item->getUUID()
+ << " to null folder. Moving to Lost&Found. Old item name: " << old_item->getName()
+ << ". New name: " << item->getName()
+ << "." << LL_ENDL;
+ new_parent_id = findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
+ update_parent_on_server = true;
+ }
+
if(old_parent_id != new_parent_id)
{
// need to update the parent-child tree
@@ -917,6 +951,11 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item, U32 mask)
item_array = get_ptr_in_map(mParentChildItemTree, new_parent_id);
if(item_array)
{
+ if (update_parent_on_server)
+ {
+ LLInventoryModel::LLCategoryUpdate update(new_parent_id, 1);
+ gInventory.accountForUpdate(update);
+ }
item_array->push_back(old_item);
}
mask |= LLInventoryObserver::STRUCTURE;
@@ -926,6 +965,12 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item, U32 mask)
mask |= LLInventoryObserver::LABEL;
}
old_item->copyViewerItem(item);
+ if (update_parent_on_server)
+ {
+ // Parent id at server is null, so update server even if item already is in the same folder
+ old_item->setParent(new_parent_id);
+ new_item->updateParentOnServer(FALSE);
+ }
mask |= LLInventoryObserver::INTERNAL;
}
else
@@ -2799,7 +2844,6 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account, U32
item_array_t items;
update_map_t update;
S32 count = msg->getNumberOfBlocksFast(_PREHASH_InventoryData);
- LLUUID folder_id;
// Does this loop ever execute more than once?
for(S32 i = 0; i < count; ++i)
{
@@ -2826,10 +2870,6 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account, U32
{
++update[titem->getParentUUID()];
}
- if (folder_id.isNull())
- {
- folder_id = titem->getParentUUID();
- }
}
if(account)
{
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index 01e0ed7e9b..576c5e9e20 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -316,7 +316,9 @@ public:
// Copy content of all folders of type "type" into folder "id" and delete/purge the empty folders
// Note : This method has been designed for FT_OUTBOX (aka Merchant Outbox) but can be used for other categories
void consolidateForType(const LLUUID& id, LLFolderType::EType type);
-
+
+ bool isCategoryHidden(const LLUUID& id) const;
+
private:
mutable LLPointer<LLViewerInventoryItem> mLastItem; // cache recent lookups
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 93269db380..702675ad49 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -1313,6 +1313,8 @@ void LLInventoryPanel::fileUploadLocation(const LLSD& userdata)
void LLInventoryPanel::purgeSelectedItems()
{
+ if (!mFolderRoot.get()) return;
+
const std::set<LLFolderViewItem*> inventory_selected = mFolderRoot.get()->getSelectionList();
if (inventory_selected.empty()) return;
LLSD args;
@@ -1333,6 +1335,8 @@ void LLInventoryPanel::purgeSelectedItems()
void LLInventoryPanel::callbackPurgeSelectedItems(const LLSD& notification, const LLSD& response)
{
+ if (!mFolderRoot.get()) return;
+
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if (option == 0)
{
@@ -1445,14 +1449,16 @@ LLInventoryPanel* LLInventoryPanel::getActiveInventoryPanel(BOOL auto_open)
//static
void LLInventoryPanel::openInventoryPanelAndSetSelection(BOOL auto_open, const LLUUID& obj_id, BOOL main_panel, BOOL take_keyboard_focus, BOOL reset_filter)
{
- LLInventoryPanel *active_panel;
+ LLSidepanelInventory* sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
+ sidepanel_inventory->showInventoryPanel();
+
bool in_inbox = (gInventory.isObjectDescendentOf(obj_id, gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX)));
if (main_panel && !in_inbox)
{
- LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory")->selectAllItemsPanel();
+ sidepanel_inventory->selectAllItemsPanel();
}
- active_panel = LLInventoryPanel::getActiveInventoryPanel(auto_open);
+ LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(auto_open);
if (active_panel)
{
@@ -1465,7 +1471,7 @@ void LLInventoryPanel::openInventoryPanelAndSetSelection(BOOL auto_open, const L
if (in_inbox)
{
- LLSidepanelInventory * sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
+
LLInventoryPanel * inventory_panel = NULL;
sidepanel_inventory->openInbox();
inventory_panel = sidepanel_inventory->getInboxPanel();
diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp
index a55938f334..760325b652 100644
--- a/indra/newview/lllocalbitmaps.cpp
+++ b/indra/newview/lllocalbitmaps.cpp
@@ -358,8 +358,9 @@ void LLLocalBitmap::replaceIDs(LLUUID old_id, LLUUID new_id)
updateUserPrims(old_id, new_id, LLRender::DIFFUSE_MAP);
updateUserPrims(old_id, new_id, LLRender::NORMAL_MAP);
updateUserPrims(old_id, new_id, LLRender::SPECULAR_MAP);
-
- updateUserSculpts(old_id, new_id); // isn't there supposed to be an IMG_DEFAULT_SCULPT or something?
+
+ updateUserVolumes(old_id, new_id, LLRender::LIGHT_TEX);
+ updateUserVolumes(old_id, new_id, LLRender::SCULPT_TEX); // isn't there supposed to be an IMG_DEFAULT_SCULPT or something?
// default safeguard image for layers
if( new_id == IMG_DEFAULT )
@@ -502,26 +503,39 @@ void LLLocalBitmap::updateUserPrims(LLUUID old_id, LLUUID new_id, U32 channel)
}
}
}
-
}
-void LLLocalBitmap::updateUserSculpts(LLUUID old_id, LLUUID new_id)
+void LLLocalBitmap::updateUserVolumes(LLUUID old_id, LLUUID new_id, U32 channel)
{
LLViewerFetchedTexture* old_texture = gTextureList.findImage(old_id, TEX_LIST_STANDARD);
- for(U32 volume_iter = 0; volume_iter < old_texture->getNumVolumes(); volume_iter++)
+ for (U32 volume_iter = 0; volume_iter < old_texture->getNumVolumes(channel); volume_iter++)
{
- LLVOVolume* volume_to_object = (*old_texture->getVolumeList())[volume_iter];
- LLViewerObject* object = (LLViewerObject*)volume_to_object;
-
- if(object)
+ LLVOVolume* volobjp = (*old_texture->getVolumeList(channel))[volume_iter];
+ switch (channel)
{
- if (object->isSculpted() && object->getVolume() &&
- object->getVolume()->getParams().getSculptID() == old_id)
+ case LLRender::LIGHT_TEX:
+ {
+ if (volobjp->getLightTextureID() == old_id)
+ {
+ volobjp->setLightTextureID(new_id);
+ }
+ break;
+ }
+ case LLRender::SCULPT_TEX:
{
- LLSculptParams* old_params = (LLSculptParams*)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
- LLSculptParams new_params(*old_params);
- new_params.setSculptTexture(new_id, (*old_params).getSculptType());
- object->setParameterEntry(LLNetworkData::PARAMS_SCULPT, new_params, TRUE);
+ LLViewerObject* object = (LLViewerObject*)volobjp;
+
+ if (object)
+ {
+ if (object->isSculpted() && object->getVolume() &&
+ object->getVolume()->getParams().getSculptID() == old_id)
+ {
+ LLSculptParams* old_params = (LLSculptParams*)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ LLSculptParams new_params(*old_params);
+ new_params.setSculptTexture(new_id, (*old_params).getSculptType());
+ object->setParameterEntry(LLNetworkData::PARAMS_SCULPT, new_params, TRUE);
+ }
+ }
}
}
}
diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h
index 59467922b4..ee4161fb45 100644
--- a/indra/newview/lllocalbitmaps.h
+++ b/indra/newview/lllocalbitmaps.h
@@ -64,7 +64,7 @@ class LLLocalBitmap
void replaceIDs(LLUUID old_id, LLUUID new_id);
std::vector<LLViewerObject*> prepUpdateObjects(LLUUID old_id, U32 channel);
void updateUserPrims(LLUUID old_id, LLUUID new_id, U32 channel);
- void updateUserSculpts(LLUUID old_id, LLUUID new_id);
+ void updateUserVolumes(LLUUID old_id, LLUUID new_id, U32 channel);
void updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableType::EType type);
LLAvatarAppearanceDefines::ETextureIndex getTexIndex(LLWearableType::EType type, LLAvatarAppearanceDefines::EBakedTextureIndex baked_texind);
diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp
index 8d361d3161..bc93fa2c20 100644
--- a/indra/newview/lllogininstance.cpp
+++ b/indra/newview/lllogininstance.cpp
@@ -269,6 +269,10 @@ bool LLLoginInstance::handleLoginEvent(const LLSD& event)
void LLLoginInstance::handleLoginFailure(const LLSD& event)
{
+ // TODO: we are handling failure in two separate places -
+ // here and in STATE_LOGIN_PROCESS_RESPONSE processing
+ // consider uniting them.
+
// Login has failed.
// Figure out why and respond...
LLSD response = event["data"];
@@ -339,6 +343,8 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)
else if( reason_response == "key"
|| reason_response == "presence"
|| reason_response == "connect"
+ || !message_response.empty() // will be handled in STATE_LOGIN_PROCESS_RESPONSE
+ || !response["message_id"].asString().empty()
)
{
// these are events that have already been communicated elsewhere
diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp
index 7bd5e4cba2..f158aae3d2 100644
--- a/indra/newview/llmaniprotate.cpp
+++ b/indra/newview/llmaniprotate.cpp
@@ -283,6 +283,7 @@ void LLManipRotate::render()
LLGLEnable cull_face(GL_CULL_FACE);
LLGLEnable clip_plane0(GL_CLIP_PLANE0);
LLGLDepthTest gls_depth(GL_FALSE);
+ LLGLDisable gls_stencil(GL_STENCIL_TEST);
// First pass: centers. Second pass: sides.
for( S32 i=0; i<2; i++ )
diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp
index 8b2ac4f303..9a8222d941 100644
--- a/indra/newview/llmanipscale.cpp
+++ b/indra/newview/llmanipscale.cpp
@@ -754,6 +754,7 @@ void LLManipScale::renderBoxHandle( F32 x, F32 y, F32 z )
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
LLGLDepthTest gls_depth(GL_FALSE);
+ LLGLDisable gls_stencil(GL_STENCIL_TEST);
gGL.pushMatrix();
{
diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp
index 785022792b..92a09357c8 100644
--- a/indra/newview/llmaniptranslate.cpp
+++ b/indra/newview/llmaniptranslate.cpp
@@ -1060,6 +1060,7 @@ void LLManipTranslate::render()
renderGuidelines();
}
{
+ LLGLDisable gls_stencil(GL_STENCIL_TEST);
renderTranslationHandles();
renderSnapGuides();
}
@@ -1638,8 +1639,8 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
- U32 types[] = { LLRenderPass::PASS_SIMPLE, LLRenderPass::PASS_ALPHA, LLRenderPass::PASS_FULLBRIGHT, LLRenderPass::PASS_SHINY };
- U32 num_types = LL_ARRAY_SIZE(types);
+ static const U32 types[] = { LLRenderPass::PASS_SIMPLE, LLRenderPass::PASS_ALPHA, LLRenderPass::PASS_FULLBRIGHT, LLRenderPass::PASS_SHINY };
+ static const U32 num_types = LL_ARRAY_SIZE(types);
GLuint stencil_mask = 0xFFFFFFFF;
//stencil in volumes
diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp
index d9fc489b4e..52b9fb40ae 100644
--- a/indra/newview/llmaterialmgr.cpp
+++ b/indra/newview/llmaterialmgr.cpp
@@ -350,6 +350,25 @@ void LLMaterialMgr::remove(const LLUUID& object_id, const U8 te)
put(object_id, te, LLMaterial::null);
}
+void LLMaterialMgr::setLocalMaterial(const LLUUID& region_id, LLMaterialPtr material_ptr)
+{
+ LLUUID uuid;
+ uuid.generate();
+ LLMaterialID material_id(uuid);
+ while (mMaterials.end() != mMaterials.find(material_id))
+ { //probability that this loop will executed is very, very low (one in a billion chance)
+ uuid.generate();
+ material_id.set(uuid.mData);
+ }
+
+ LL_DEBUGS("Materials") << "region " << region_id << "new local material id " << material_id << LL_ENDL;
+ mMaterials.insert(std::pair<LLMaterialID, LLMaterialPtr>(material_id, material_ptr));
+
+ setMaterialCallbacks(material_id, material_ptr);
+
+ mGetPending.erase(pending_material_t(region_id, material_id));
+}
+
const LLMaterialPtr LLMaterialMgr::setMaterial(const LLUUID& region_id, const LLMaterialID& material_id, const LLSD& material_data)
{
LL_DEBUGS("Materials") << "region " << region_id << " material id " << material_id << LL_ENDL;
@@ -362,17 +381,26 @@ const LLMaterialPtr LLMaterialMgr::setMaterial(const LLUUID& region_id, const LL
itMaterial = ret.first;
}
+ setMaterialCallbacks(material_id, itMaterial->second);
+
+ mGetPending.erase(pending_material_t(region_id, material_id));
+
+ return itMaterial->second;
+}
+
+void LLMaterialMgr::setMaterialCallbacks(const LLMaterialID& material_id, const LLMaterialPtr material_ptr)
+{
TEMaterialPair te_mat_pair;
te_mat_pair.materialID = material_id;
U32 i = 0;
- while (i < LLTEContents::MAX_TES)
+ while (i < LLTEContents::MAX_TES && !mGetTECallbacks.empty())
{
te_mat_pair.te = i++;
get_callback_te_map_t::iterator itCallbackTE = mGetTECallbacks.find(te_mat_pair);
if (itCallbackTE != mGetTECallbacks.end())
{
- (*itCallbackTE->second)(material_id, itMaterial->second, te_mat_pair.te);
+ (*itCallbackTE->second)(material_id, material_ptr, te_mat_pair.te);
delete itCallbackTE->second;
mGetTECallbacks.erase(itCallbackTE);
}
@@ -381,15 +409,11 @@ const LLMaterialPtr LLMaterialMgr::setMaterial(const LLUUID& region_id, const LL
get_callback_map_t::iterator itCallback = mGetCallbacks.find(material_id);
if (itCallback != mGetCallbacks.end())
{
- (*itCallback->second)(material_id, itMaterial->second);
+ (*itCallback->second)(material_id, material_ptr);
delete itCallback->second;
mGetCallbacks.erase(itCallback);
}
-
- mGetPending.erase(pending_material_t(region_id, material_id));
-
- return itMaterial->second;
}
void LLMaterialMgr::onGetResponse(bool success, const LLSD& content, const LLUUID& region_id)
diff --git a/indra/newview/llmaterialmgr.h b/indra/newview/llmaterialmgr.h
index 60b58d17de..843dc66fbc 100644
--- a/indra/newview/llmaterialmgr.h
+++ b/indra/newview/llmaterialmgr.h
@@ -56,6 +56,9 @@ public:
boost::signals2::connection getAll(const LLUUID& region_id, getall_callback_t::slot_type cb);
void put(const LLUUID& object_id, const U8 te, const LLMaterial& material);
void remove(const LLUUID& object_id, const U8 te);
+
+ //explicitly add new material to material manager
+ void setLocalMaterial(const LLUUID& region_id, LLMaterialPtr material_ptr);
private:
void clearGetQueues(const LLUUID& region_id);
@@ -63,7 +66,8 @@ private:
bool isGetAllPending(const LLUUID& region_id) const;
void markGetPending(const LLUUID& region_id, const LLMaterialID& material_id);
const LLMaterialPtr setMaterial(const LLUUID& region_id, const LLMaterialID& material_id, const LLSD& material_data);
-
+ void setMaterialCallbacks(const LLMaterialID& material_id, const LLMaterialPtr material_ptr);
+
static void onIdle(void*);
static void CapsRecvForRegion(const LLUUID& regionId, LLUUID regionTest, std::string pumpname);
diff --git a/indra/newview/llmediadataclient.cpp b/indra/newview/llmediadataclient.cpp
index bd8f464acd..bc45eb6d3a 100644
--- a/indra/newview/llmediadataclient.cpp
+++ b/indra/newview/llmediadataclient.cpp
@@ -27,6 +27,7 @@
#include "llviewerprecompiledheaders.h"
#include "llmediadataclient.h"
+#include "llviewercontrol.h"
#if LL_MSVC
// disable boost::lexical_cast warning
@@ -718,6 +719,13 @@ bool LLObjectMediaDataClient::compareRequestScores(const Request::ptr_t &o1, con
void LLObjectMediaDataClient::enqueue(Request::ptr_t request)
{
+ static LLCachedControl<bool> audio_streaming_enabled(gSavedSettings, "AudioStreamingMedia", true);
+ if (!audio_streaming_enabled)
+ {
+ LL_DEBUGS("LLMediaDataClient") << "not queueing request when Media is disabled " << *request << LL_ENDL;
+ return;
+ }
+
if(request->isDead())
{
LL_DEBUGS("LLMediaDataClient") << "not queueing dead request " << *request << LL_ENDL;
@@ -978,6 +986,13 @@ const char *LLObjectMediaNavigateClient::getCapabilityName() const
void LLObjectMediaNavigateClient::enqueue(Request::ptr_t request)
{
+ static LLCachedControl<bool> audio_streaming_enabled(gSavedSettings, "AudioStreamingMedia", true);
+ if (!audio_streaming_enabled)
+ {
+ LL_DEBUGS("LLMediaDataClient") << "not queueing request when Media is disabled " << *request << LL_ENDL;
+ return;
+ }
+
if(request->isDead())
{
LL_DEBUGS("LLMediaDataClient") << "not queuing dead request " << *request << LL_ENDL;
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index fdaa28b22b..2c1980922a 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -353,6 +353,9 @@ const U32 LARGE_MESH_FETCH_THRESHOLD = 1U << 21; // Size at which requests goes
const long SMALL_MESH_XFER_TIMEOUT = 120L; // Seconds to complete xfer, small mesh downloads
const long LARGE_MESH_XFER_TIMEOUT = 600L; // Seconds to complete xfer, large downloads
+const U32 DOWNLOAD_RETRY_LIMIT = 8;
+const F32 DOWNLOAD_RETRY_DELAY = 0.5f; // seconds
+
// Would normally like to retry on uploads as some
// retryable failures would be recoverable. Unfortunately,
// the mesh service is using 500 (retryable) rather than
@@ -516,6 +519,24 @@ void get_vertex_buffer_from_mesh(LLCDMeshData& mesh, LLModel::PhysicsMesh& res,
}
}
+void RequestStats::updateTime()
+{
+ U32 modifier = 1 << mRetries; // before ++
+ mRetries++;
+ mTimer.reset();
+ mTimer.setTimerExpirySec(DOWNLOAD_RETRY_DELAY * (F32)modifier); // up to 32s, 64 total wait
+}
+
+bool RequestStats::canRetry() const
+{
+ return mRetries < DOWNLOAD_RETRY_LIMIT;
+}
+
+bool RequestStats::isDelayed() const
+{
+ return mTimer.getStarted() && !mTimer.hasExpired();
+}
+
LLViewerFetchedTexture* LLMeshUploadThread::FindViewerTexture(const LLImportMaterial& material)
{
LLPointer< LLViewerFetchedTexture > * ppTex = static_cast< LLPointer< LLViewerFetchedTexture > * >(material.mOpaqueData);
@@ -836,6 +857,12 @@ LLMeshRepoThread::~LLMeshRepoThread()
mHttpRequestSet.clear();
mHttpHeaders.reset();
+ while (!mDecompositionQ.empty())
+ {
+ delete mDecompositionQ.front();
+ mDecompositionQ.pop_front();
+ }
+
delete mHttpRequest;
mHttpRequest = NULL;
delete mMutex;
@@ -884,141 +911,225 @@ void LLMeshRepoThread::run()
sRequestWaterLevel = mHttpRequestSet.size(); // Stats data update
// NOTE: order of queue processing intentionally favors LOD requests over header requests
+ // Todo: we are processing mLODReqQ, mHeaderReqQ, mSkinRequests, mDecompositionRequests and mPhysicsShapeRequests
+ // in relatively similar manners, remake code to simplify/unify the process,
+ // like processRequests(&requestQ, fetchFunction); which does same thing for each element
- while (!mLODReqQ.empty() && mHttpRequestSet.size() < sRequestHighWater)
- {
- if (! mMutex)
- {
- break;
- }
- mMutex->lock();
- LODRequest req = mLODReqQ.front();
- mLODReqQ.pop();
- LLMeshRepository::sLODProcessing--;
- mMutex->unlock();
-
- if (!fetchMeshLOD(req.mMeshParams, req.mLOD)) // failed, resubmit
- {
- mMutex->lock();
- mLODReqQ.push(req);
- ++LLMeshRepository::sLODProcessing;
- mMutex->unlock();
- }
- }
-
- while (!mHeaderReqQ.empty() && mHttpRequestSet.size() < sRequestHighWater)
- {
- if (! mMutex)
- {
- break;
- }
- mMutex->lock();
- HeaderRequest req = mHeaderReqQ.front();
- mHeaderReqQ.pop();
- mMutex->unlock();
- if (!fetchMeshHeader(req.mMeshParams))//failed, resubmit
- {
- mMutex->lock();
- mHeaderReqQ.push(req) ;
- mMutex->unlock();
- }
- }
-
- // For the final three request lists, similar goal to above but
- // slightly different queue structures. Stay off the mutex when
- // performing long-duration actions.
-
- if (mHttpRequestSet.size() < sRequestHighWater
- && (! mSkinRequests.empty()
- || ! mDecompositionRequests.empty()
- || ! mPhysicsShapeRequests.empty()))
- {
- // Something to do probably, lock and double-check. We don't want
- // to hold the lock long here. That will stall main thread activities
- // so we bounce it.
-
- mMutex->lock();
- if (! mSkinRequests.empty() && mHttpRequestSet.size() < sRequestHighWater)
- {
- std::set<LLUUID> incomplete;
- std::set<LLUUID>::iterator iter(mSkinRequests.begin());
- while (iter != mSkinRequests.end() && mHttpRequestSet.size() < sRequestHighWater)
- {
- LLUUID mesh_id = *iter;
- mSkinRequests.erase(iter);
- mMutex->unlock();
-
- if (! fetchMeshSkinInfo(mesh_id))
- {
- incomplete.insert(mesh_id);
- }
+ if (!mLODReqQ.empty() && mHttpRequestSet.size() < sRequestHighWater)
+ {
+ std::list<LODRequest> incomplete;
+ while (!mLODReqQ.empty() && mHttpRequestSet.size() < sRequestHighWater)
+ {
+ if (!mMutex)
+ {
+ break;
+ }
+
+ mMutex->lock();
+ LODRequest req = mLODReqQ.front();
+ mLODReqQ.pop();
+ LLMeshRepository::sLODProcessing--;
+ mMutex->unlock();
+ if (req.isDelayed())
+ {
+ // failed to load before, wait a bit
+ incomplete.push_front(req);
+ }
+ else if (!fetchMeshLOD(req.mMeshParams, req.mLOD, req.canRetry()))
+ {
+ if (req.canRetry())
+ {
+ // failed, resubmit
+ req.updateTime();
+ incomplete.push_front(req);
+ }
+ else
+ {
+ // too many fails
+ mUnavailableQ.push(req);
+ LL_WARNS() << "Failed to load " << req.mMeshParams << " , skip" << LL_ENDL;
+ }
+ }
+ }
- mMutex->lock();
- iter = mSkinRequests.begin();
- }
+ if (!incomplete.empty())
+ {
+ LLMutexLock locker(mMutex);
+ for (std::list<LODRequest>::iterator iter = incomplete.begin(); iter != incomplete.end(); iter++)
+ {
+ mLODReqQ.push(*iter);
+ ++LLMeshRepository::sLODProcessing;
+ }
+ }
+ }
- if (! incomplete.empty())
- {
- mSkinRequests.insert(incomplete.begin(), incomplete.end());
- }
- }
+ if (!mHeaderReqQ.empty() && mHttpRequestSet.size() < sRequestHighWater)
+ {
+ std::list<HeaderRequest> incomplete;
+ while (!mHeaderReqQ.empty() && mHttpRequestSet.size() < sRequestHighWater)
+ {
+ if (!mMutex)
+ {
+ break;
+ }
+
+ mMutex->lock();
+ HeaderRequest req = mHeaderReqQ.front();
+ mHeaderReqQ.pop();
+ mMutex->unlock();
+ if (req.isDelayed())
+ {
+ // failed to load before, wait a bit
+ incomplete.push_front(req);
+ }
+ else if (!fetchMeshHeader(req.mMeshParams, req.canRetry()))
+ {
+ if (req.canRetry())
+ {
+ //failed, resubmit
+ req.updateTime();
+ incomplete.push_front(req);
+ }
+ else
+ {
+ LL_DEBUGS() << "mHeaderReqQ failed: " << req.mMeshParams << LL_ENDL;
+ }
+ }
+ }
- // holding lock, try next list
- // *TODO: For UI/debug-oriented lists, we might drop the fine-
- // grained locking as there's a lowered expectation of smoothness
- // in these cases.
- if (! mDecompositionRequests.empty() && mHttpRequestSet.size() < sRequestHighWater)
- {
- std::set<LLUUID> incomplete;
- std::set<LLUUID>::iterator iter(mDecompositionRequests.begin());
- while (iter != mDecompositionRequests.end() && mHttpRequestSet.size() < sRequestHighWater)
- {
- LLUUID mesh_id = *iter;
- mDecompositionRequests.erase(iter);
- mMutex->unlock();
-
- if (! fetchMeshDecomposition(mesh_id))
- {
- incomplete.insert(mesh_id);
- }
+ if (!incomplete.empty())
+ {
+ LLMutexLock locker(mMutex);
+ for (std::list<HeaderRequest>::iterator iter = incomplete.begin(); iter != incomplete.end(); iter++)
+ {
+ mHeaderReqQ.push(*iter);
+ }
+ }
+ }
- mMutex->lock();
- iter = mDecompositionRequests.begin();
- }
+ // For the final three request lists, similar goal to above but
+ // slightly different queue structures. Stay off the mutex when
+ // performing long-duration actions.
- if (! incomplete.empty())
- {
- mDecompositionRequests.insert(incomplete.begin(), incomplete.end());
- }
- }
+ if (mHttpRequestSet.size() < sRequestHighWater
+ && (!mSkinRequests.empty()
+ || !mDecompositionRequests.empty()
+ || !mPhysicsShapeRequests.empty()))
+ {
+ // Something to do probably, lock and double-check. We don't want
+ // to hold the lock long here. That will stall main thread activities
+ // so we bounce it.
- // holding lock, final list
- if (! mPhysicsShapeRequests.empty() && mHttpRequestSet.size() < sRequestHighWater)
- {
- std::set<LLUUID> incomplete;
- std::set<LLUUID>::iterator iter(mPhysicsShapeRequests.begin());
- while (iter != mPhysicsShapeRequests.end() && mHttpRequestSet.size() < sRequestHighWater)
- {
- LLUUID mesh_id = *iter;
- mPhysicsShapeRequests.erase(iter);
- mMutex->unlock();
-
- if (! fetchMeshPhysicsShape(mesh_id))
- {
- incomplete.insert(mesh_id);
- }
+ if (!mSkinRequests.empty())
+ {
+ std::set<UUIDBasedRequest> incomplete;
+ while (!mSkinRequests.empty() && mHttpRequestSet.size() < sRequestHighWater)
+ {
+ mMutex->lock();
+ std::set<UUIDBasedRequest>::iterator iter = mSkinRequests.begin();
+ UUIDBasedRequest req = *iter;
+ mSkinRequests.erase(iter);
+ mMutex->unlock();
+ if (req.isDelayed())
+ {
+ incomplete.insert(req);
+ }
+ else if (!fetchMeshSkinInfo(req.mId))
+ {
+ if (req.canRetry())
+ {
+ req.updateTime();
+ incomplete.insert(req);
+ }
+ else
+ {
+ LL_DEBUGS() << "mSkinRequests failed: " << req.mId << LL_ENDL;
+ }
+ }
+ }
+
+ if (!incomplete.empty())
+ {
+ LLMutexLock locker(mMutex);
+ mSkinRequests.insert(incomplete.begin(), incomplete.end());
+ }
+ }
- mMutex->lock();
- iter = mPhysicsShapeRequests.begin();
- }
+ // holding lock, try next list
+ // *TODO: For UI/debug-oriented lists, we might drop the fine-
+ // grained locking as there's a lowered expectation of smoothness
+ // in these cases.
+ if (!mDecompositionRequests.empty())
+ {
+ std::set<UUIDBasedRequest> incomplete;
+ while (!mDecompositionRequests.empty() && mHttpRequestSet.size() < sRequestHighWater)
+ {
+ mMutex->lock();
+ std::set<UUIDBasedRequest>::iterator iter = mDecompositionRequests.begin();
+ UUIDBasedRequest req = *iter;
+ mDecompositionRequests.erase(iter);
+ mMutex->unlock();
+ if (req.isDelayed())
+ {
+ incomplete.insert(req);
+ }
+ else if (!fetchMeshDecomposition(req.mId))
+ {
+ if (req.canRetry())
+ {
+ req.updateTime();
+ incomplete.insert(req);
+ }
+ else
+ {
+ LL_DEBUGS() << "mDecompositionRequests failed: " << req.mId << LL_ENDL;
+ }
+ }
+ }
+
+ if (!incomplete.empty())
+ {
+ LLMutexLock locker(mMutex);
+ mDecompositionRequests.insert(incomplete.begin(), incomplete.end());
+ }
+ }
- if (! incomplete.empty())
- {
- mPhysicsShapeRequests.insert(incomplete.begin(), incomplete.end());
- }
- }
- mMutex->unlock();
- }
+ // holding lock, final list
+ if (!mPhysicsShapeRequests.empty())
+ {
+ std::set<UUIDBasedRequest> incomplete;
+ while (!mPhysicsShapeRequests.empty() && mHttpRequestSet.size() < sRequestHighWater)
+ {
+ mMutex->lock();
+ std::set<UUIDBasedRequest>::iterator iter = mPhysicsShapeRequests.begin();
+ UUIDBasedRequest req = *iter;
+ mPhysicsShapeRequests.erase(iter);
+ mMutex->unlock();
+ if (req.isDelayed())
+ {
+ incomplete.insert(req);
+ }
+ else if (!fetchMeshPhysicsShape(req.mId))
+ {
+ if (req.canRetry())
+ {
+ req.updateTime();
+ incomplete.insert(req);
+ }
+ else
+ {
+ LL_DEBUGS() << "mPhysicsShapeRequests failed: " << req.mId << LL_ENDL;
+ }
+ }
+ }
+
+ if (!incomplete.empty())
+ {
+ LLMutexLock locker(mMutex);
+ mPhysicsShapeRequests.insert(incomplete.begin(), incomplete.end());
+ }
+ }
+ }
// For dev purposes only. A dynamic change could make this false
// and that shouldn't assert.
@@ -1040,19 +1151,19 @@ void LLMeshRepoThread::run()
// Mutex: LLMeshRepoThread::mMutex must be held on entry
void LLMeshRepoThread::loadMeshSkinInfo(const LLUUID& mesh_id)
{
- mSkinRequests.insert(mesh_id);
+ mSkinRequests.insert(UUIDBasedRequest(mesh_id));
}
// Mutex: LLMeshRepoThread::mMutex must be held on entry
void LLMeshRepoThread::loadMeshDecomposition(const LLUUID& mesh_id)
{
- mDecompositionRequests.insert(mesh_id);
+ mDecompositionRequests.insert(UUIDBasedRequest(mesh_id));
}
// Mutex: LLMeshRepoThread::mMutex must be held on entry
void LLMeshRepoThread::loadMeshPhysicsShape(const LLUUID& mesh_id)
{
- mPhysicsShapeRequests.insert(mesh_id);
+ mPhysicsShapeRequests.insert(UUIDBasedRequest(mesh_id));
}
void LLMeshRepoThread::lockAndLoadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
@@ -1112,19 +1223,27 @@ void LLMeshRepoThread::constructUrl(LLUUID mesh_id, std::string * url)
if (gAgent.getRegion())
{
- LLMutexLock lock(mMutex);
- res_url = mGetMeshCapability;
- }
+ {
+ LLMutexLock lock(mMutex);
+ res_url = mGetMeshCapability;
+ }
- if (! res_url.empty())
- {
- res_url += "/?mesh_id=";
- res_url += mesh_id.asString().c_str();
+ if (!res_url.empty())
+ {
+ res_url += "/?mesh_id=";
+ res_url += mesh_id.asString().c_str();
+ }
+ else
+ {
+ LL_WARNS_ONCE(LOG_MESH) << "Current region does not have ViewerAsset capability! Cannot load meshes. Region id: "
+ << gAgent.getRegion()->getRegionID() << LL_ENDL;
+ LL_DEBUGS_ONCE(LOG_MESH) << "Cannot load mesh " << mesh_id << " due to missing capability." << LL_ENDL;
+ }
}
else
{
- LL_WARNS_ONCE(LOG_MESH) << "Current region does not have ViewerAsset capability! Cannot load "
- << mesh_id << ".mesh" << LL_ENDL;
+ LL_WARNS_ONCE(LOG_MESH) << "Current region is not loaded so there is no capability to load from! Cannot load meshes." << LL_ENDL;
+ LL_DEBUGS_ONCE(LOG_MESH) << "Cannot load mesh " << mesh_id << " due to missing capability." << LL_ENDL;
}
*url = res_url;
@@ -1220,16 +1339,16 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
//check VFS for mesh skin info
LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH);
if (file.getSize() >= offset+size)
- {
- LLMeshRepository::sCacheBytesRead += size;
- ++LLMeshRepository::sCacheReads;
- file.seek(offset);
+ {
U8* buffer = new(std::nothrow) U8[size];
if (!buffer)
{
- LL_WARNS(LOG_MESH) << "Failed to allocate memory for skin info" << LL_ENDL;
+ LL_WARNS_ONCE(LOG_MESH) << "Failed to allocate memory for skin info, size: " << size << LL_ENDL;
return false;
}
+ LLMeshRepository::sCacheBytesRead += size;
+ ++LLMeshRepository::sCacheReads;
+ file.seek(offset);
file.read(buffer, size);
//make sure buffer isn't all 0's by checking the first 1KB (reserved block but not written)
@@ -1317,16 +1436,16 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH);
if (file.getSize() >= offset+size)
{
- LLMeshRepository::sCacheBytesRead += size;
- ++LLMeshRepository::sCacheReads;
-
- file.seek(offset);
U8* buffer = new(std::nothrow) U8[size];
if (!buffer)
{
- LL_WARNS(LOG_MESH) << "Failed to allocate memory for mesh decomposition" << LL_ENDL;
+ LL_WARNS_ONCE(LOG_MESH) << "Failed to allocate memory for mesh decomposition, size: " << size << LL_ENDL;
return false;
}
+ LLMeshRepository::sCacheBytesRead += size;
+ ++LLMeshRepository::sCacheReads;
+
+ file.seek(offset);
file.read(buffer, size);
//make sure buffer isn't all 0's by checking the first 1KB (reserved block but not written)
@@ -1420,7 +1539,7 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
U8* buffer = new(std::nothrow) U8[size];
if (!buffer)
{
- LL_WARNS(LOG_MESH) << "Failed to allocate memory for physics shape" << LL_ENDL;
+ LL_WARNS_ONCE(LOG_MESH) << "Failed to allocate memory for physics shape, size: " << size << LL_ENDL;
return false;
}
file.read(buffer, size);
@@ -1510,7 +1629,7 @@ void LLMeshRepoThread::decActiveHeaderRequests()
}
//return false if failed to get header
-bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params)
+bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, bool can_retry)
{
++LLMeshRepository::sMeshRequestCount;
@@ -1557,7 +1676,7 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params)
<< LL_ENDL;
retval = false;
}
- else
+ else if (can_retry)
{
handler->mHttpHandle = handle;
mHttpRequestSet.insert(handler);
@@ -1568,7 +1687,7 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params)
}
//return false if failed to get mesh lod.
-bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
+bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, bool can_retry)
{
if (!mHeaderMutex)
{
@@ -1598,15 +1717,17 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH);
if (file.getSize() >= offset+size)
{
- LLMeshRepository::sCacheBytesRead += size;
- ++LLMeshRepository::sCacheReads;
- file.seek(offset);
U8* buffer = new(std::nothrow) U8[size];
if (!buffer)
{
- LL_WARNS(LOG_MESH) << "Can't allocate memory for mesh LOD" << LL_ENDL;
+ LL_WARNS_ONCE(LOG_MESH) << "Can't allocate memory for mesh " << mesh_id << " LOD " << lod << ", size: " << size << LL_ENDL;
+ // todo: for now it will result in indefinite constant retries, should result in timeout
+ // or in retry-count and disabling mesh. (but usually viewer is beyond saving at this point)
return false;
}
+ LLMeshRepository::sCacheBytesRead += size;
+ ++LLMeshRepository::sCacheReads;
+ file.seek(offset);
file.read(buffer, size);
//make sure buffer isn't all 0's by checking the first 1KB (reserved block but not written)
@@ -1618,7 +1739,7 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
if (!zero)
{ //attempt to parse
- if (lodReceived(mesh_params, lod, buffer, size))
+ if (lodReceived(mesh_params, lod, buffer, size) == MESH_OK)
{
delete[] buffer;
return true;
@@ -1644,12 +1765,16 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
<< LL_ENDL;
retval = false;
}
- else
+ else if (can_retry)
{
handler->mHttpHandle = handle;
mHttpRequestSet.insert(handler);
// *NOTE: Allowing a re-request, not marking as unavailable. Is that correct?
}
+ else
+ {
+ mUnavailableQ.push(LODRequest(mesh_params, lod));
+ }
}
else
{
@@ -1734,11 +1859,11 @@ bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* dat
return true;
}
-bool LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_params, S32 lod, U8* data, S32 data_size)
+EMeshProcessingResult LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_params, S32 lod, U8* data, S32 data_size)
{
if (data == NULL || data_size == 0)
{
- return false;
+ return MESH_NO_DATA;
}
LLPointer<LLVolume> volume = new LLVolume(mesh_params, LLVolumeLODGroup::getVolumeScaleFromDetail(lod));
@@ -1751,7 +1876,7 @@ bool LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_params, S32 lod, U
catch (std::bad_alloc)
{
// out of memory, we won't be able to process this mesh
- return false;
+ return MESH_OUT_OF_MEMORY;
}
if (volume->unpackVolumeFaces(stream, data_size))
@@ -1763,11 +1888,11 @@ bool LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_params, S32 lod, U
LLMutexLock lock(mMutex);
mLoadedQ.push(mesh);
}
- return true;
+ return MESH_OK;
}
}
- return false;
+ return MESH_UNKNOWN;
}
bool LLMeshRepoThread::skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 data_size)
@@ -1941,6 +2066,9 @@ LLMeshUploadThread::~LLMeshUploadThread()
{
delete mHttpRequest;
mHttpRequest = NULL;
+ delete mMutex;
+ mMutex = NULL;
+
}
LLMeshUploadThread::DecompRequest::DecompRequest(LLModel* mdl, LLModel* base_model, LLMeshUploadThread* thread)
@@ -2952,6 +3080,11 @@ void LLMeshHandlerBase::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRespo
body->read(body_offset, (char *) data, data_size - body_offset);
LLMeshRepository::sBytesReceived += data_size;
}
+ else
+ {
+ LL_WARNS(LOG_MESH) << "Failed to allocate " << data_size - body_offset << " memory for mesh response" << LL_ENDL;
+ processFailure(LLCore::HttpStatus(LLCore::HttpStatus::LLCORE, LLCore::HE_BAD_ALLOC));
+ }
}
processData(body, body_offset, data, data_size - body_offset);
@@ -3127,27 +3260,43 @@ void LLMeshLODHandler::processData(LLCore::BufferArray * /* body */, S32 /* body
U8 * data, S32 data_size)
{
if ((!MESH_LOD_PROCESS_FAILED)
- && ((data != NULL) == (data_size > 0)) // if we have data but no size or have size but no data, something is wrong
- && gMeshRepo.mThread->lodReceived(mMeshParams, mLOD, data, data_size))
+ && ((data != NULL) == (data_size > 0))) // if we have data but no size or have size but no data, something is wrong
{
- // good fetch from sim, write to VFS for caching
- LLVFile file(gVFS, mMeshParams.getSculptID(), LLAssetType::AT_MESH, LLVFile::WRITE);
+ EMeshProcessingResult result = gMeshRepo.mThread->lodReceived(mMeshParams, mLOD, data, data_size);
+ if (result == MESH_OK)
+ {
+ // good fetch from sim, write to VFS for caching
+ LLVFile file(gVFS, mMeshParams.getSculptID(), LLAssetType::AT_MESH, LLVFile::WRITE);
- S32 offset = mOffset;
- S32 size = mRequestedBytes;
+ S32 offset = mOffset;
+ S32 size = mRequestedBytes;
- if (file.getSize() >= offset+size)
+ if (file.getSize() >= offset+size)
+ {
+ file.seek(offset);
+ file.write(data, size);
+ LLMeshRepository::sCacheBytesWritten += size;
+ ++LLMeshRepository::sCacheWrites;
+ }
+ }
+ else
{
- file.seek(offset);
- file.write(data, size);
- LLMeshRepository::sCacheBytesWritten += size;
- ++LLMeshRepository::sCacheWrites;
+ LL_WARNS(LOG_MESH) << "Error during mesh LOD processing. ID: " << mMeshParams.getSculptID()
+ << ", Reason: " << result
+ << " LOD: " << mLOD
+ << " Data size: " << data_size
+ << " Not retrying."
+ << LL_ENDL;
+ LLMutexLock lock(gMeshRepo.mThread->mMutex);
+ gMeshRepo.mThread->mUnavailableQ.push(LLMeshRepoThread::LODRequest(mMeshParams, mLOD));
}
}
else
{
LL_WARNS(LOG_MESH) << "Error during mesh LOD processing. ID: " << mMeshParams.getSculptID()
<< ", Unknown reason. Not retrying."
+ << " LOD: " << mLOD
+ << " Data size: " << data_size
<< LL_ENDL;
LLMutexLock lock(gMeshRepo.mThread->mMutex);
gMeshRepo.mThread->mUnavailableQ.push(LLMeshRepoThread::LODRequest(mMeshParams, mLOD));
@@ -3300,6 +3449,7 @@ void LLMeshPhysicsShapeHandler::processData(LLCore::BufferArray * /* body */, S3
LLMeshRepository::LLMeshRepository()
: mMeshMutex(NULL),
+ mDecompThread(NULL),
mMeshThreadCount(0),
mThread(NULL)
{
@@ -3329,6 +3479,8 @@ void LLMeshRepository::init()
void LLMeshRepository::shutdown()
{
LL_INFOS(LOG_MESH) << "Shutting down mesh repository." << LL_ENDL;
+ llassert(mThread != NULL);
+ llassert(mThread->mSignal != NULL);
metrics_teleport_started_signal.disconnect();
@@ -3986,7 +4138,7 @@ void LLMeshRepository::uploadModel(std::vector<LLModelInstance>& data, LLVector3
S32 LLMeshRepository::getMeshSize(const LLUUID& mesh_id, S32 lod)
{
- if (mThread && mesh_id.notNull())
+ if (mThread && mesh_id.notNull() && LLPrimitive::NO_LOD != lod)
{
LLMutexLock lock(mThread->mHeaderMutex);
LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id);
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 23af837f6f..22215c784a 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -51,6 +51,15 @@ class LLCondition;
class LLVFS;
class LLMeshRepository;
+typedef enum e_mesh_processing_result_enum
+{
+ MESH_OK = 0,
+ MESH_NO_DATA = 1,
+ MESH_OUT_OF_MEMORY,
+ MESH_HTTP_REQUEST_FAILED,
+ MESH_UNKNOWN
+} EMeshProcessingResult;
+
class LLMeshUploadData
{
public:
@@ -168,6 +177,21 @@ public:
};
+class RequestStats
+{
+public:
+ RequestStats() : mRetries(0) {};
+
+ void updateTime();
+ bool canRetry() const;
+ bool isDelayed() const;
+ U32 getRetries() { return mRetries; }
+
+private:
+ U32 mRetries;
+ LLFrameTimer mTimer;
+};
+
class LLMeshRepoThread : public LLThread
{
public:
@@ -188,14 +212,14 @@ public:
mesh_header_map mMeshHeader;
std::map<LLUUID, U32> mMeshHeaderSize;
-
- class HeaderRequest
+
+ class HeaderRequest : public RequestStats
{
public:
const LLVolumeParams mMeshParams;
HeaderRequest(const LLVolumeParams& mesh_params)
- : mMeshParams(mesh_params)
+ : RequestStats(), mMeshParams(mesh_params)
{
}
@@ -205,7 +229,7 @@ public:
}
};
- class LODRequest
+ class LODRequest : public RequestStats
{
public:
LLVolumeParams mMeshParams;
@@ -213,7 +237,7 @@ public:
F32 mScore;
LODRequest(const LLVolumeParams& mesh_params, S32 lod)
- : mMeshParams(mesh_params), mLOD(lod), mScore(0.f)
+ : RequestStats(), mMeshParams(mesh_params), mLOD(lod), mScore(0.f)
{
}
};
@@ -225,7 +249,22 @@ public:
return lhs.mScore > rhs.mScore; // greatest = first
}
};
-
+
+ class UUIDBasedRequest : public RequestStats
+ {
+ public:
+ LLUUID mId;
+
+ UUIDBasedRequest(const LLUUID& id)
+ : RequestStats(), mId(id)
+ {
+ }
+
+ bool operator<(const UUIDBasedRequest& rhs) const
+ {
+ return mId < rhs.mId;
+ }
+ };
class LoadedMesh
{
@@ -242,16 +281,16 @@ public:
};
//set of requested skin info
- std::set<LLUUID> mSkinRequests;
+ std::set<UUIDBasedRequest> mSkinRequests;
// list of completed skin info requests
std::list<LLMeshSkinInfo> mSkinInfoQ;
//set of requested decompositions
- std::set<LLUUID> mDecompositionRequests;
+ std::set<UUIDBasedRequest> mDecompositionRequests;
//set of requested physics shapes
- std::set<LLUUID> mPhysicsShapeRequests;
+ std::set<UUIDBasedRequest> mPhysicsShapeRequests;
// list of completed Decomposition info requests
std::list<LLModel::Decomposition*> mDecompositionQ;
@@ -295,10 +334,10 @@ public:
void lockAndLoadMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
void loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
- bool fetchMeshHeader(const LLVolumeParams& mesh_params);
- bool fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
+ bool fetchMeshHeader(const LLVolumeParams& mesh_params, bool can_retry = true);
+ bool fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, bool can_retry = true);
bool headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size);
- bool lodReceived(const LLVolumeParams& mesh_params, S32 lod, U8* data, S32 data_size);
+ EMeshProcessingResult lodReceived(const LLVolumeParams& mesh_params, S32 lod, U8* data, S32 data_size);
bool skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
bool decompositionReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
bool physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp
index 4999318973..301487b994 100644
--- a/indra/newview/llmoveview.cpp
+++ b/indra/newview/llmoveview.cpp
@@ -400,12 +400,12 @@ void LLFloaterMove::initMovementMode()
{
initMovementMode = MM_FLY;
}
- setMovementMode(initMovementMode);
+
+ mCurrentMode = initMovementMode;
+ bool hide_mode_buttons = (MM_FLY == mCurrentMode) || (isAgentAvatarValid() && gAgentAvatarp->isSitting());
- if (isAgentAvatarValid())
- {
- showModeButtons(!gAgentAvatarp->isSitting());
- }
+ updateButtonsWithMovementMode(mCurrentMode);
+ showModeButtons(!hide_mode_buttons);
}
void LLFloaterMove::setModeTooltip(const EMovementMode mode)
@@ -716,9 +716,9 @@ void LLPanelStandStopFlying::updatePosition()
left_tb_width = toolbar_left->getRect().getWidth();
}
- if (!mStateManagementButtons.get())
+ if (!mStateManagementButtons.get()) // Obsolete?!!
{
- LLPanel* panel_ssf_container = getRootView()->getChild<LLPanel>("state_management_buttons_container");
+ LLPanel* panel_ssf_container = gToolBarView->getChild<LLPanel>("state_management_buttons_container");
if (panel_ssf_container)
{
mStateManagementButtons = panel_ssf_container->getHandle();
diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp
index 84a2cd8be1..cfe2e6bf6a 100644
--- a/indra/newview/llnavigationbar.cpp
+++ b/indra/newview/llnavigationbar.cpp
@@ -443,6 +443,7 @@ void LLNavigationBar::onLocationSelection()
{
gAgent.teleportViaLandmark( LLUUID(value["AssetUUID"].asString()));
+ mSaveToLocationHistory = true;
return;
}
else
@@ -453,6 +454,7 @@ void LLNavigationBar::onLocationSelection()
if (!landmark_items.empty())
{
gAgent.teleportViaLandmark( landmark_items[0]->getAssetUUID());
+ mSaveToLocationHistory = true;
return;
}
}
diff --git a/indra/newview/llnotificationlistitem.cpp b/indra/newview/llnotificationlistitem.cpp
index cbcf9cac9c..f2de8e54a0 100644
--- a/indra/newview/llnotificationlistitem.cpp
+++ b/indra/newview/llnotificationlistitem.cpp
@@ -288,9 +288,7 @@ BOOL LLGroupInviteNotificationListItem::postBuild()
//invitation with any non-default group role, doesn't have newline characters at the end unlike simple invitations
std::string invitation_desc = mNoticeTextExp->getValue().asString();
- boost::regex pattern = boost::regex("\n\n$", boost::regex::perl|boost::regex::icase);
- boost::match_results<std::string::const_iterator> matches;
- if(!boost::regex_search(invitation_desc, matches, pattern))
+ if (invitation_desc.substr(invitation_desc.size() - 2) != "\n\n")
{
invitation_desc += "\n\n";
mNoticeTextExp->setValue(invitation_desc);
diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index c38d3ab140..dc3b153da2 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -1267,6 +1267,13 @@ LLUUID LLOutfitGallery::getDefaultPhoto()
void LLOutfitGallery::onTexturePickerCommit(LLTextureCtrl::ETexturePickOp op, LLUUID id)
{
+ LLUUID selected_outfit_id = getSelectedOutfitUUID();
+
+ if (selected_outfit_id.isNull())
+ {
+ return;
+ }
+
LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
if (floaterp && op == LLTextureCtrl::TEXTURE_SELECT)
@@ -1316,8 +1323,8 @@ void LLOutfitGallery::onTexturePickerCommit(LLTextureCtrl::ETexturePickOp op, LL
return;
}
- checkRemovePhoto(getSelectedOutfitUUID());
- linkPhotoToOutfit(image_item_id, getSelectedOutfitUUID());
+ checkRemovePhoto(selected_outfit_id);
+ linkPhotoToOutfit(image_item_id, selected_outfit_id);
}
}
diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp
index e2157f985e..892fa385d7 100644
--- a/indra/newview/lloutfitslist.cpp
+++ b/indra/newview/lloutfitslist.cpp
@@ -1050,15 +1050,15 @@ bool LLOutfitContextMenu::onEnable(LLSD::String param)
bool LLOutfitContextMenu::onVisible(LLSD::String param)
{
LLUUID outfit_cat_id = mUUIDs.back();
- bool is_worn = LLAppearanceMgr::instance().getBaseOutfitUUID() == outfit_cat_id;
if ("edit" == param)
{
+ bool is_worn = LLAppearanceMgr::instance().getBaseOutfitUUID() == outfit_cat_id;
return is_worn;
}
else if ("wear_replace" == param)
{
- return !is_worn;
+ return true;
}
else if ("delete" == param)
{
diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp
index a46fb3dfeb..3a8378f8df 100644
--- a/indra/newview/llpaneleditwearable.cpp
+++ b/indra/newview/llpaneleditwearable.cpp
@@ -1624,7 +1624,7 @@ void LLPanelEditWearable::initPreviousAlphaTextures()
initPreviousAlphaTextureEntry(TEX_UPPER_ALPHA);
initPreviousAlphaTextureEntry(TEX_HEAD_ALPHA);
initPreviousAlphaTextureEntry(TEX_EYES_ALPHA);
- initPreviousAlphaTextureEntry(TEX_LOWER_ALPHA);
+ initPreviousAlphaTextureEntry(TEX_HAIR_ALPHA);
}
void LLPanelEditWearable::initPreviousAlphaTextureEntry(LLAvatarAppearanceDefines::ETextureIndex te)
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 7e75dca908..01ce4470f0 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -1165,16 +1165,6 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
getChild<LLUICtrl>("combobox texgen")->setTentative(!identical);
getChildView("tex gen")->setEnabled(editable);
- if (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR)
- {
- // EXP-1507 (change label based on the mapping mode)
- getChild<LLUICtrl>("rpt")->setValue(getString("string repeats per meter"));
- }
- else
- if (selected_texgen == LLTextureEntry::TEX_GEN_DEFAULT)
- {
- getChild<LLUICtrl>("rpt")->setValue(getString("string repeats per face"));
- }
}
{
@@ -1390,8 +1380,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
mColorSwatch->setValid(FALSE);
}
getChildView("color trans")->setEnabled(FALSE);
- getChildView("rpt")->setEnabled(FALSE);
- getChildView("tex offset")->setEnabled(FALSE);
+ getChildView("rptctrl")->setEnabled(FALSE);
getChildView("tex gen")->setEnabled(FALSE);
getChildView("label shininess")->setEnabled(FALSE);
getChildView("label bumpiness")->setEnabled(FALSE);
diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp
index 342b57ba4a..e41211ddbd 100644
--- a/indra/newview/llpanelgroup.cpp
+++ b/indra/newview/llpanelgroup.cpp
@@ -159,9 +159,6 @@ BOOL LLPanelGroup::postBuild()
button = getChild<LLButton>("btn_chat");
button->setClickedCallback(onBtnGroupChatClicked, this);
- button = getChild<LLButton>("btn_cancel");
- button->setVisible(false); button->setEnabled(true);
-
button = getChild<LLButton>("btn_refresh");
button->setClickedCallback(onBtnRefresh, this);
@@ -170,8 +167,6 @@ BOOL LLPanelGroup::postBuild()
childSetCommitCallback("back",boost::bind(&LLPanelGroup::onBackBtnClick,this),NULL);
childSetCommitCallback("btn_create",boost::bind(&LLPanelGroup::onBtnCreate,this),NULL);
-
- childSetCommitCallback("btn_cancel",boost::bind(&LLPanelGroup::onBtnCancel,this),NULL);
LLPanelGroupTab* panel_general = findChild<LLPanelGroupTab>("group_general_tab_panel");
LLPanelGroupTab* panel_roles = findChild<LLPanelGroupTab>("group_roles_tab_panel");
@@ -299,11 +294,6 @@ void LLPanelGroup::onBtnJoin()
LLGroupActions::join(mID);
}
-void LLPanelGroup::onBtnCancel()
-{
- onBackBtnClick();
-}
-
void LLPanelGroup::changed(LLGroupChange gc)
{
for(std::vector<LLPanelGroupTab* >::iterator it = mTabs.begin();it!=mTabs.end();++it)
diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h
index 05be4b5aee..0b40c8b5d3 100644
--- a/indra/newview/llpanelgroup.h
+++ b/indra/newview/llpanelgroup.h
@@ -95,7 +95,6 @@ protected:
void onBtnCreate();
void onBackBtnClick();
void onBtnJoin();
- void onBtnCancel();
static void onBtnApply(void*);
static void onBtnRefresh(void*);
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index d17f5494a0..f85a2ffbc1 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -194,6 +194,7 @@ void LLPanelGroupGeneral::setupCtrls(LLPanel* panel_group)
if (mInsignia)
{
mInsignia->setCommitCallback(onCommitAny, this);
+ mInsignia->setAllowLocalTexture(FALSE);
}
mFounderName = getChild<LLTextBox>("founder_name");
diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp
index 48b659a81e..178b5db6c2 100644
--- a/indra/newview/llpanelgroupnotices.cpp
+++ b/indra/newview/llpanelgroupnotices.cpp
@@ -575,6 +575,7 @@ void LLPanelGroupNotices::processNotices(LLMessageSystem* msg)
mNoticesList->setNeedsSort(save_sort);
mNoticesList->updateSort();
+ mNoticesList->selectFirstItem();
}
void LLPanelGroupNotices::onSelectNotice(LLUICtrl* ctrl, void* data)
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index 66a0a1d4ad..087e0a0759 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -465,12 +465,12 @@ BOOL LLPanelGroupSubTab::postBuild()
{
// Hook up the search widgets.
bool recurse = true;
- mSearchEditor = getChild<LLFilterEditor>("filter_input", recurse);
- if (!mSearchEditor)
- return FALSE;
-
- mSearchEditor->setCommitCallback(boost::bind(&LLPanelGroupSubTab::setSearchFilter, this, _2));
+ mSearchEditor = findChild<LLFilterEditor>("filter_input", recurse);
+ if (mSearchEditor) // SubTab doesn't implement this, only some of derived classes
+ {
+ mSearchEditor->setCommitCallback(boost::bind(&LLPanelGroupSubTab::setSearchFilter, this, _2));
+ }
return LLPanelGroupTab::postBuild();
}
@@ -815,14 +815,18 @@ BOOL LLPanelGroupMembersSubTab::postBuildSubTab(LLView* root)
// Look recursively from the parent to find all our widgets.
bool recurse = true;
- mHeader = parent->getChild<LLPanel>("members_header", recurse);
- mFooter = parent->getChild<LLPanel>("members_footer", recurse);
+ mHeader = parent->findChild<LLPanel>("members_header", recurse);
+ mFooter = parent->findChild<LLPanel>("members_footer", recurse);
mMembersList = parent->getChild<LLNameListCtrl>("member_list", recurse);
mAssignedRolesList = parent->getChild<LLScrollListCtrl>("member_assigned_roles", recurse);
mAllowedActionsList = parent->getChild<LLScrollListCtrl>("member_allowed_actions", recurse);
+ mActionDescription = parent->getChild<LLTextEditor>("member_action_description", recurse);
- if (!mMembersList || !mAssignedRolesList || !mAllowedActionsList) return FALSE;
+ if (!mMembersList || !mAssignedRolesList || !mAllowedActionsList || !mActionDescription) return FALSE;
+
+ mAllowedActionsList->setCommitOnSelectionChange(TRUE);
+ mAllowedActionsList->setCommitCallback(boost::bind(&LLPanelGroupMembersSubTab::updateActionDescription, this));
// We want to be notified whenever a member is selected.
mMembersList->setCommitOnSelectionChange(TRUE);
@@ -889,6 +893,7 @@ void LLPanelGroupMembersSubTab::handleMemberSelect()
mAssignedRolesList->deleteAllItems();
mAllowedActionsList->deleteAllItems();
+ mActionDescription->clear();
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
if (!gdatap)
@@ -1386,6 +1391,7 @@ void LLPanelGroupMembersSubTab::activate()
update(GC_MEMBER_DATA);
}
}
+ mActionDescription->clear();
}
void LLPanelGroupMembersSubTab::deactivate()
@@ -1894,6 +1900,23 @@ bool LLPanelGroupMembersSubTab::handleBanCallback(const LLSD& notification, cons
return false;
}
+void LLPanelGroupMembersSubTab::updateActionDescription()
+{
+ mActionDescription->setText(std::string());
+ LLScrollListItem* action_item = mAllowedActionsList->getFirstSelected();
+ if (!action_item || !mAllowedActionsList->getCanSelect())
+ {
+ return;
+ }
+
+ LLRoleAction* rap = (LLRoleAction*)action_item->getUserdata();
+ if (rap)
+ {
+ std::string desc = rap->mLongDescription.empty() ? rap->mDescription : rap->mLongDescription;
+ mActionDescription->setText(desc);
+ }
+}
+
void LLPanelGroupMembersSubTab::handleBanMember()
{
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
@@ -1957,13 +1980,14 @@ BOOL LLPanelGroupRolesSubTab::postBuildSubTab(LLView* root)
// Look recursively from the parent to find all our widgets.
bool recurse = true;
- mHeader = parent->getChild<LLPanel>("roles_header", recurse);
- mFooter = parent->getChild<LLPanel>("roles_footer", recurse);
+ mHeader = parent->findChild<LLPanel>("roles_header", recurse);
+ mFooter = parent->findChild<LLPanel>("roles_footer", recurse);
mRolesList = parent->getChild<LLScrollListCtrl>("role_list", recurse);
mAssignedMembersList = parent->getChild<LLNameListCtrl>("role_assigned_members", recurse);
mAllowedActionsList = parent->getChild<LLScrollListCtrl>("role_allowed_actions", recurse);
+ mActionDescription = parent->getChild<LLTextEditor>("role_action_description", recurse);
mRoleName = parent->getChild<LLLineEditor>("role_name", recurse);
mRoleTitle = parent->getChild<LLLineEditor>("role_title", recurse);
@@ -1971,7 +1995,7 @@ BOOL LLPanelGroupRolesSubTab::postBuildSubTab(LLView* root)
mMemberVisibleCheck = parent->getChild<LLCheckBoxCtrl>("role_visible_in_list", recurse);
- if (!mRolesList || !mAssignedMembersList || !mAllowedActionsList
+ if (!mRolesList || !mAssignedMembersList || !mAllowedActionsList || !mActionDescription
|| !mRoleName || !mRoleTitle || !mRoleDescription || !mMemberVisibleCheck)
{
LL_WARNS() << "ARG! element not found." << LL_ENDL;
@@ -2004,6 +2028,7 @@ BOOL LLPanelGroupRolesSubTab::postBuildSubTab(LLView* root)
mMemberVisibleCheck->setCommitCallback(onMemberVisibilityChange, this);
mAllowedActionsList->setCommitOnSelectionChange(TRUE);
+ mAllowedActionsList->setCommitCallback(boost::bind(&LLPanelGroupRolesSubTab::updateActionDescription, this));
mRoleName->setCommitOnFocusLost(TRUE);
mRoleName->setKeystrokeCallback(onPropertiesKey, this);
@@ -2023,6 +2048,7 @@ void LLPanelGroupRolesSubTab::activate()
{
LLPanelGroupSubTab::activate();
+ mActionDescription->clear();
mRolesList->deselectAllItems();
mAssignedMembersList->deleteAllItems();
mAllowedActionsList->deleteAllItems();
@@ -2707,6 +2733,23 @@ void LLPanelGroupRolesSubTab::saveRoleChanges(bool select_saved_role)
}
}
+void LLPanelGroupRolesSubTab::updateActionDescription()
+{
+ mActionDescription->setText(std::string());
+ LLScrollListItem* action_item = mAllowedActionsList->getFirstSelected();
+ if (!action_item || !mAllowedActionsList->getCanSelect())
+ {
+ return;
+ }
+
+ LLRoleAction* rap = (LLRoleAction*)action_item->getUserdata();
+ if (rap)
+ {
+ std::string desc = rap->mLongDescription.empty() ? rap->mDescription : rap->mLongDescription;
+ mActionDescription->setText(desc);
+ }
+}
+
void LLPanelGroupRolesSubTab::setGroupID(const LLUUID& id)
{
if(mRolesList) mRolesList->deleteAllItems();
@@ -2746,8 +2789,8 @@ BOOL LLPanelGroupActionsSubTab::postBuildSubTab(LLView* root)
// Look recursively from the parent to find all our widgets.
bool recurse = true;
- mHeader = parent->getChild<LLPanel>("actions_header", recurse);
- mFooter = parent->getChild<LLPanel>("actions_footer", recurse);
+ mHeader = parent->findChild<LLPanel>("actions_header", recurse);
+ mFooter = parent->findChild<LLPanel>("actions_footer", recurse);
mActionDescription = parent->getChild<LLTextEditor>("action_description", recurse);
@@ -2953,10 +2996,10 @@ BOOL LLPanelGroupBanListSubTab::postBuildSubTab(LLView* root)
// Look recursively from the parent to find all our widgets.
bool recurse = true;
-
- mHeader = parent->getChild<LLPanel>("banlist_header", recurse);
- mFooter = parent->getChild<LLPanel>("banlist_footer", recurse);
-
+
+ mHeader = parent->findChild<LLPanel>("banlist_header", recurse);
+ mFooter = parent->findChild<LLPanel>("banlist_footer", recurse);
+
mBanList = parent->getChild<LLNameListCtrl>("ban_list", recurse);
mCreateBanButton = parent->getChild<LLButton>("ban_create", recurse);
diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h
index 1d1d69e0ae..aafbd242cb 100644
--- a/indra/newview/llpanelgrouproles.h
+++ b/indra/newview/llpanelgrouproles.h
@@ -132,7 +132,7 @@ protected:
BOOL is_owner_role);
protected:
- LLPanel* mHeader;
+ LLPanel* mHeader; // Might not be present in xui of derived class (NULL)
LLPanel* mFooter;
LLFilterEditor* mSearchEditor;
@@ -182,6 +182,7 @@ public:
bool handleBanCallback(const LLSD& notification, const LLSD& response);
void confirmBanMembers();
+ void updateActionDescription();
void applyMemberChanges();
bool addOwnerCB(const LLSD& notification, const LLSD& response);
@@ -222,6 +223,8 @@ protected:
BOOL mPendingMemberUpdate;
BOOL mHasMatch;
+ LLTextEditor* mActionDescription;
+
member_role_changes_map_t mMemberRoleChangeData;
U32 mNumOwnerAdditions;
@@ -269,6 +272,8 @@ public:
static void onDeleteRole(void*);
void handleDeleteRole();
+ void updateActionDescription();
+
void saveRoleChanges(bool select_saved_role);
virtual void setGroupID(const LLUUID& id);
@@ -282,6 +287,7 @@ protected:
LLScrollListCtrl* mRolesList;
LLNameListCtrl* mAssignedMembersList;
LLScrollListCtrl* mAllowedActionsList;
+ LLTextEditor* mActionDescription;
LLLineEditor* mRoleName;
LLLineEditor* mRoleTitle;
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index c876c1c149..ef5ce155b1 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -271,9 +271,6 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
LLTextBox* forgot_password_text = getChild<LLTextBox>("forgot_password_text");
forgot_password_text->setClickedCallback(onClickForgotPassword, NULL);
- LLTextBox* need_help_text = getChild<LLTextBox>("login_help");
- need_help_text->setClickedCallback(onClickHelp, NULL);
-
// get the web browser control
LLMediaCtrl* web_browser = getChild<LLMediaCtrl>("login_html");
web_browser->addObserver(this);
@@ -284,6 +281,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
username_combo->setTextChangedCallback(boost::bind(&LLPanelLogin::addFavoritesToStartLocation, this));
// STEAM-14: When user presses Enter with this field in focus, initiate login
username_combo->setCommitCallback(boost::bind(&LLPanelLogin::onClickConnect, this));
+ username_combo->setKeystrokeOnEsc(TRUE);
}
void LLPanelLogin::addFavoritesToStartLocation()
@@ -923,16 +921,6 @@ void LLPanelLogin::onClickForgotPassword(void*)
}
}
-//static
-void LLPanelLogin::onClickHelp(void*)
-{
- if (sInstance)
- {
- LLViewerHelp* vhelp = LLViewerHelp::getInstance();
- vhelp->showTopic(vhelp->preLoginTopic());
- }
-}
-
// static
void LLPanelLogin::onPassKey(LLLineEditor* caller, void* user_data)
{
diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h
index 82ef048493..852195b304 100644
--- a/indra/newview/llpanellogin.h
+++ b/indra/newview/llpanellogin.h
@@ -99,7 +99,6 @@ private:
static void onClickNewAccount(void*);
static void onClickVersion(void*);
static void onClickForgotPassword(void*);
- static void onClickHelp(void*);
static void onPassKey(LLLineEditor* caller, void* user_data);
static void updateServerCombo();
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.cpp b/indra/newview/llpanelmarketplaceinboxinventory.cpp
index 2d2ba30e9b..cea7054d6a 100644
--- a/indra/newview/llpanelmarketplaceinboxinventory.cpp
+++ b/indra/newview/llpanelmarketplaceinboxinventory.cpp
@@ -139,6 +139,7 @@ void LLInboxFolderViewFolder::draw()
if (!hasBadgeHolderParent())
{
addBadgeToParentHolder();
+ setDrawBadgeAtTop(true);
}
setBadgeVisibility(mFresh);
@@ -158,6 +159,12 @@ BOOL LLInboxFolderViewFolder::handleDoubleClick( S32 x, S32 y, MASK mask )
return LLFolderViewFolder::handleDoubleClick(x, y, mask);
}
+void LLInboxFolderViewFolder::selectItem()
+{
+ deFreshify();
+ LLFolderViewFolder::selectItem();
+}
+
void LLInboxFolderViewFolder::computeFreshness()
{
const U32 last_expansion_utc = gSavedPerAccountSettings.getU32("LastInventoryInboxActivity");
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.h b/indra/newview/llpanelmarketplaceinboxinventory.h
index d398cdafed..0b27818c95 100644
--- a/indra/newview/llpanelmarketplaceinboxinventory.h
+++ b/indra/newview/llpanelmarketplaceinboxinventory.h
@@ -71,6 +71,7 @@ public:
BOOL handleMouseDown(S32 x, S32 y, MASK mask);
BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
+ void selectItem();
void computeFreshness();
void deFreshify();
diff --git a/indra/newview/llpanelnearbymedia.cpp b/indra/newview/llpanelnearbymedia.cpp
index 737ae2e32d..d8ef5b39ad 100644
--- a/indra/newview/llpanelnearbymedia.cpp
+++ b/indra/newview/llpanelnearbymedia.cpp
@@ -526,6 +526,7 @@ void LLPanelNearByMedia::removeListItem(const LLUUID &id)
if (NULL == mMediaList) return;
mMediaList->deleteSingleItem(mMediaList->getItemIndex(id));
+ mMediaList->updateLayout();
}
void LLPanelNearByMedia::refreshParcelItems()
@@ -1047,7 +1048,7 @@ void LLPanelNearByMedia::updateControls()
else {
showBasicControls(!impl->isMediaDisabled(),
! impl->isParcelMedia(), // include_zoom
- LLViewerMediaFocus::getInstance()->isZoomed(),
+ LLViewerMediaFocus::getInstance()->isZoomedOnMedia(impl->getMediaTextureID()),
impl->getVolume() == 0.0,
impl->getVolume());
}
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index 0bf4d48421..25cfb598e7 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -342,9 +342,9 @@ void LLPanelObject::getState( )
}
// can move or rotate only linked group with move permissions, or sub-object with move and modify perms
- BOOL enable_move = objectp->permMove() && !objectp->isPermanentEnforced() && ((root_objectp == NULL) || !root_objectp->isPermanentEnforced()) && !objectp->isAttachment() && (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts"));
+ BOOL enable_move = objectp->permMove() && !objectp->isPermanentEnforced() && ((root_objectp == NULL) || !root_objectp->isPermanentEnforced()) && (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts"));
BOOL enable_scale = objectp->permMove() && !objectp->isPermanentEnforced() && ((root_objectp == NULL) || !root_objectp->isPermanentEnforced()) && objectp->permModify();
- BOOL enable_rotate = objectp->permMove() && !objectp->isPermanentEnforced() && ((root_objectp == NULL) || !root_objectp->isPermanentEnforced()) && ( (objectp->permModify() && !objectp->isAttachment()) || !gSavedSettings.getBOOL("EditLinkedParts"));
+ BOOL enable_rotate = objectp->permMove() && !objectp->isPermanentEnforced() && ((root_objectp == NULL) || !root_objectp->isPermanentEnforced()) && (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts"));
S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
BOOL single_volume = (LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ))
@@ -448,20 +448,6 @@ void LLPanelObject::getState( )
S32 roots_selected = LLSelectMgr::getInstance()->getSelection()->getRootObjectCount();
BOOL editable = root_objectp->permModify();
- // Select Single Message
- getChildView("select_single")->setVisible( FALSE);
- getChildView("edit_object")->setVisible( FALSE);
- if (!editable || single_volume || selected_count <= 1)
- {
- getChildView("edit_object")->setVisible( TRUE);
- getChildView("edit_object")->setEnabled(TRUE);
- }
- else
- {
- getChildView("select_single")->setVisible( TRUE);
- getChildView("select_single")->setEnabled(TRUE);
- }
-
BOOL is_flexible = volobjp && volobjp->isFlexible();
BOOL is_permanent = root_objectp->flagObjectPermanent();
BOOL is_permanent_enforced = root_objectp->isPermanentEnforced();
@@ -1587,9 +1573,14 @@ void LLPanelObject::sendRotation(BOOL btn_down)
{
rotation = rotation * ~mRootObject->getRotationRegion();
}
+
+ // To include avatars into movements and rotation
+ // If false, all children are selected anyway - move avatar
+ // If true, not all children are selected - save positions
+ bool individual_selection = gSavedSettings.getBOOL("EditLinkedParts");
std::vector<LLVector3>& child_positions = mObject->mUnselectedChildrenPositions ;
std::vector<LLQuaternion> child_rotations;
- if (mObject->isRootEdit())
+ if (mObject->isRootEdit() && individual_selection)
{
mObject->saveUnselectedChildrenRotation(child_rotations) ;
mObject->saveUnselectedChildrenPosition(child_positions) ;
@@ -1599,8 +1590,8 @@ void LLPanelObject::sendRotation(BOOL btn_down)
LLManip::rebuild(mObject) ;
// for individually selected roots, we need to counterrotate all the children
- if (mObject->isRootEdit())
- {
+ if (mObject->isRootEdit() && individual_selection)
+ {
mObject->resetChildrenRotationAndPosition(child_rotations, child_positions) ;
}
@@ -1888,10 +1879,6 @@ void LLPanelObject::clearCtrls()
mLabelTaper ->setEnabled( FALSE );
mLabelRadiusOffset->setEnabled( FALSE );
mLabelRevolutions->setEnabled( FALSE );
-
- getChildView("select_single")->setVisible( FALSE);
- getChildView("edit_object")->setVisible( TRUE);
- getChildView("edit_object")->setEnabled(FALSE);
getChildView("scale_hole")->setEnabled(FALSE);
getChildView("scale_taper")->setEnabled(FALSE);
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index b5ee68ba25..cd1875e995 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -101,9 +101,7 @@ public:
static LLTaskInvFVBridge* createObjectBridge(LLPanelObjectInventory* panel,
LLInventoryObject* object);
void showProperties();
- void buyItem();
S32 getPrice();
- static bool commitBuyItem(const LLSD& notification, const LLSD& response);
// LLFolderViewModelItemInventory functionality
virtual const std::string& getName() const;
@@ -200,75 +198,6 @@ void LLTaskInvFVBridge::showProperties()
show_task_item_profile(mUUID, mPanel->getTaskUUID());
}
-struct LLBuyInvItemData
-{
- LLUUID mTaskID;
- LLUUID mItemID;
- LLAssetType::EType mType;
-
- LLBuyInvItemData(const LLUUID& task,
- const LLUUID& item,
- LLAssetType::EType type) :
- mTaskID(task), mItemID(item), mType(type)
- {}
-};
-
-void LLTaskInvFVBridge::buyItem()
-{
- LL_INFOS() << "LLTaskInvFVBridge::buyItem()" << LL_ENDL;
- LLInventoryItem* item = findItem();
- if(!item || !item->getSaleInfo().isForSale()) return;
- LLBuyInvItemData* inv = new LLBuyInvItemData(mPanel->getTaskUUID(),
- mUUID,
- item->getType());
-
- const LLSaleInfo& sale_info = item->getSaleInfo();
- const LLPermissions& perm = item->getPermissions();
- const std::string owner_name; // no owner name currently... FIXME?
-
- LLViewerObject* obj;
- if( ( obj = gObjectList.findObject( mPanel->getTaskUUID() ) ) && obj->isAttachment() )
- {
- LLNotificationsUtil::add("Cannot_Purchase_an_Attachment");
- LL_INFOS() << "Attempt to purchase an attachment" << LL_ENDL;
- delete inv;
- }
- else
- {
- LLSD args;
- args["PRICE"] = llformat("%d",sale_info.getSalePrice());
- args["OWNER"] = owner_name;
- if (sale_info.getSaleType() != LLSaleInfo::FS_CONTENTS)
- {
- U32 next_owner_mask = perm.getMaskNextOwner();
- args["MODIFYPERM"] = LLTrans::getString((next_owner_mask & PERM_MODIFY) ? "PermYes" : "PermNo");
- args["COPYPERM"] = LLTrans::getString((next_owner_mask & PERM_COPY) ? "PermYes" : "PermNo");
- args["RESELLPERM"] = LLTrans::getString((next_owner_mask & PERM_TRANSFER) ? "PermYes" : "PermNo");
- }
-
- std::string alertdesc;
- switch(sale_info.getSaleType())
- {
- case LLSaleInfo::FS_ORIGINAL:
- alertdesc = owner_name.empty() ? "BuyOriginalNoOwner" : "BuyOriginal";
- break;
- case LLSaleInfo::FS_CONTENTS:
- alertdesc = owner_name.empty() ? "BuyContentsNoOwner" : "BuyContents";
- break;
- case LLSaleInfo::FS_COPY:
- default:
- alertdesc = owner_name.empty() ? "BuyCopyNoOwner" : "BuyCopy";
- break;
- }
-
- LLSD payload;
- payload["task_id"] = inv->mTaskID;
- payload["item_id"] = inv->mItemID;
- payload["type"] = inv->mType;
- LLNotificationsUtil::add(alertdesc, args, payload, LLTaskInvFVBridge::commitBuyItem);
- }
-}
-
S32 LLTaskInvFVBridge::getPrice()
{
LLInventoryItem* item = findItem();
@@ -282,31 +211,6 @@ S32 LLTaskInvFVBridge::getPrice()
}
}
-// static
-bool LLTaskInvFVBridge::commitBuyItem(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if(0 == option)
- {
- LLViewerObject* object = gObjectList.findObject(notification["payload"]["task_id"].asUUID());
- if(!object || !object->getRegion()) return false;
-
-
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_BuyObjectInventory);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->nextBlockFast(_PREHASH_Data);
- msg->addUUIDFast(_PREHASH_ObjectID, notification["payload"]["task_id"].asUUID());
- msg->addUUIDFast(_PREHASH_ItemID, notification["payload"]["item_id"].asUUID());
- msg->addUUIDFast(_PREHASH_FolderID,
- gInventory.findCategoryUUIDForType((LLFolderType::EType)notification["payload"]["type"].asInteger()));
- msg->sendReliable(object->getRegion()->getHost());
- }
- return false;
-}
-
const std::string& LLTaskInvFVBridge::getName() const
{
return mName;
@@ -615,29 +519,7 @@ BOOL LLTaskInvFVBridge::dragOrDrop(MASK mask, BOOL drop,
// virtual
void LLTaskInvFVBridge::performAction(LLInventoryModel* model, std::string action)
{
- if (action == "task_buy")
- {
- // Check the price of the item.
- S32 price = getPrice();
- if (-1 == price)
- {
- LL_WARNS() << "label_buy_task_bridged_item: Invalid price" << LL_ENDL;
- }
- else
- {
- if (price > 0 && price > gStatusBar->getBalance())
- {
- LLStringUtil::format_map_t args;
- args["AMOUNT"] = llformat("%d", price);
- LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString("this_costs", args), price );
- }
- else
- {
- buyItem();
- }
- }
- }
- else if (action == "task_open")
+ if (action == "task_open")
{
openItem();
}
@@ -659,43 +541,15 @@ void LLTaskInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
return;
}
- if(!gAgent.allowOperation(PERM_OWNER, item->getPermissions(),
- GP_OBJECT_MANIPULATE)
- && item->getSaleInfo().isForSale())
- {
- items.push_back(std::string("Task Buy"));
-
- std::string label= LLTrans::getString("Buy");
- // Check the price of the item.
- S32 price = getPrice();
- if (-1 == price)
- {
- LL_WARNS() << "label_buy_task_bridged_item: Invalid price" << LL_ENDL;
- }
- else
- {
- std::ostringstream info;
- info << LLTrans::getString("BuyforL$") << price;
- label.assign(info.str());
- }
-
- const LLView::child_list_t *list = menu.getChildList();
- LLView::child_list_t::const_iterator itor;
- for (itor = list->begin(); itor != list->end(); ++itor)
- {
- std::string name = (*itor)->getName();
- LLMenuItemCallGL* menu_itemp = dynamic_cast<LLMenuItemCallGL*>(*itor);
- if (name == "Task Buy" && menu_itemp)
- {
- menu_itemp->setLabel(label);
- }
- }
- }
- else if (canOpenItem())
+ if (canOpenItem())
{
items.push_back(std::string("Task Open"));
}
items.push_back(std::string("Task Properties"));
+ if ((flags & FIRST_SELECTED_ITEM) == 0)
+ {
+ disabled_items.push_back(std::string("Task Properties"));
+ }
if(isItemRenameable())
{
items.push_back(std::string("Task Rename"));
@@ -974,42 +828,15 @@ void LLTaskSoundBridge::performAction(LLInventoryModel* model, std::string actio
void LLTaskSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
LLInventoryItem* item = findItem();
- if(!item) return;
std::vector<std::string> items;
std::vector<std::string> disabled_items;
-
- if(item->getPermissions().getOwner() != gAgent.getID()
- && item->getSaleInfo().isForSale())
+ if (!item)
{
- items.push_back(std::string("Task Buy"));
-
- std::string label= LLTrans::getString("Buy");
- // Check the price of the item.
- S32 price = getPrice();
- if (-1 == price)
- {
- LL_WARNS() << "label_buy_task_bridged_item: Invalid price" << LL_ENDL;
- }
- else
- {
- std::ostringstream info;
- info << LLTrans::getString("BuyforL$") << price;
- label.assign(info.str());
- }
-
- const LLView::child_list_t *list = menu.getChildList();
- LLView::child_list_t::const_iterator itor;
- for (itor = list->begin(); itor != list->end(); ++itor)
- {
- std::string name = (*itor)->getName();
- LLMenuItemCallGL* menu_itemp = dynamic_cast<LLMenuItemCallGL*>(*itor);
- if (name == "Task Buy" && menu_itemp)
- {
- menu_itemp->setLabel(label);
- }
- }
+ hide_context_entries(menu, items, disabled_items);
+ return;
}
- else if (canOpenItem())
+
+ if (canOpenItem())
{
if (!isItemCopyable())
{
@@ -1017,6 +844,10 @@ void LLTaskSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
}
items.push_back(std::string("Task Properties"));
+ if ((flags & FIRST_SELECTED_ITEM) == 0)
+ {
+ disabled_items.push_back(std::string("Task Properties"));
+ }
if(isItemRenameable())
{
items.push_back(std::string("Task Rename"));
@@ -1344,50 +1175,25 @@ void LLTaskMeshBridge::performAction(LLInventoryModel* model, std::string action
void LLTaskMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
LLInventoryItem* item = findItem();
- if(!item) return;
std::vector<std::string> items;
std::vector<std::string> disabled_items;
-
- if(item->getPermissions().getOwner() != gAgent.getID()
- && item->getSaleInfo().isForSale())
+ if(!item)
{
- items.push_back(std::string("Task Buy"));
-
- std::string label= LLTrans::getString("Buy");
- // Check the price of the item.
- S32 price = getPrice();
- if (-1 == price)
- {
- LL_WARNS() << "label_buy_task_bridged_item: Invalid price" << LL_ENDL;
- }
- else
- {
- std::ostringstream info;
- info << LLTrans::getString("BuyforL$") << price;
- label.assign(info.str());
- }
-
- const LLView::child_list_t *list = menu.getChildList();
- LLView::child_list_t::const_iterator itor;
- for (itor = list->begin(); itor != list->end(); ++itor)
- {
- std::string name = (*itor)->getName();
- LLMenuItemCallGL* menu_itemp = dynamic_cast<LLMenuItemCallGL*>(*itor);
- if (name == "Task Buy" && menu_itemp)
- {
- menu_itemp->setLabel(label);
- }
- }
+ hide_context_entries(menu, items, disabled_items);
+ return;
}
- else
+
+ items.push_back(std::string("Task Open"));
+ if (!isItemCopyable())
{
- items.push_back(std::string("Task Open"));
- if (!isItemCopyable())
- {
- disabled_items.push_back(std::string("Task Open"));
- }
+ disabled_items.push_back(std::string("Task Open"));
}
+
items.push_back(std::string("Task Properties"));
+ if ((flags & FIRST_SELECTED_ITEM) == 0)
+ {
+ disabled_items.push_back(std::string("Task Properties"));
+ }
if(isItemRenameable())
{
items.push_back(std::string("Task Rename"));
diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index 5973b08183..c5bae9c52e 100644
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -531,11 +531,6 @@ BOOL LLPanelOutfitEdit::postBuild()
mPlusBtn = getChild<LLButton>("plus_btn");
mPlusBtn->setClickedCallback(boost::bind(&LLPanelOutfitEdit::onPlusBtnClicked, this));
-
- mEditWearableBtn = getChild<LLButton>("edit_wearable_btn");
- mEditWearableBtn->setEnabled(FALSE);
- mEditWearableBtn->setVisible(FALSE);
- mEditWearableBtn->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onEditWearableClicked, this));
childSetAction(REVERT_BTN, boost::bind(&LLAppearanceMgr::wearBaseOutfit, LLAppearanceMgr::getInstance()));
diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h
index 30870daf40..2cc8b65001 100644
--- a/indra/newview/llpaneloutfitedit.h
+++ b/indra/newview/llpaneloutfitedit.h
@@ -214,7 +214,6 @@ private:
LLFilterEditor* mSearchFilter;
LLSaveFolderState* mSavedFolderState;
std::string mSearchString;
- LLButton* mEditWearableBtn;
LLButton* mFolderViewBtn;
LLButton* mListViewBtn;
LLButton* mPlusBtn;
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index eb2a297a35..30fef9f5f0 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -586,7 +586,6 @@ BOOL LLPanelPeople::postBuild()
getChild<LLFilterEditor>("friends_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
getChild<LLFilterEditor>("groups_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
getChild<LLFilterEditor>("recent_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
- getChild<LLFilterEditor>("fbc_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
if(gMaxAgentGroups <= BASE_MAX_AGENT_GROUPS)
{
diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp
index 29ca172f60..a7c53a7050 100644
--- a/indra/newview/llpanelpermissions.cpp
+++ b/indra/newview/llpanelpermissions.cpp
@@ -171,6 +171,8 @@ BOOL LLPanelPermissions::postBuild()
childSetCommitCallback("search_check",LLPanelPermissions::onCommitIncludeInSearch,this);
mLabelGroupName = getChild<LLNameBox>("Group Name Proxy");
+ mLabelOwnerName = getChild<LLTextBox>("Owner Name");
+ mLabelCreatorName = getChild<LLTextBox>("Creator Name");
return TRUE;
}
@@ -178,6 +180,14 @@ BOOL LLPanelPermissions::postBuild()
LLPanelPermissions::~LLPanelPermissions()
{
+ if (mOwnerCacheConnection.connected())
+ {
+ mOwnerCacheConnection.disconnect();
+ }
+ if (mCreatorCacheConnection.connected())
+ {
+ mCreatorCacheConnection.disconnect();
+ }
// base class will take care of everything
}
@@ -192,14 +202,14 @@ void LLPanelPermissions::disableAll()
getChildView("Creator:")->setEnabled(FALSE);
getChild<LLUICtrl>("Creator Icon")->setVisible(FALSE);
- getChild<LLUICtrl>("Creator Name")->setValue(LLStringUtil::null);
- getChildView("Creator Name")->setEnabled(FALSE);
+ mLabelCreatorName->setValue(LLStringUtil::null);
+ mLabelCreatorName->setEnabled(FALSE);
getChildView("Owner:")->setEnabled(FALSE);
getChild<LLUICtrl>("Owner Icon")->setVisible(FALSE);
getChild<LLUICtrl>("Owner Group Icon")->setVisible(FALSE);
- getChild<LLUICtrl>("Owner Name")->setValue(LLStringUtil::null);
- getChildView("Owner Name")->setEnabled(FALSE);
+ mLabelOwnerName->setValue(LLStringUtil::null);
+ mLabelOwnerName->setEnabled(FALSE);
getChildView("Group:")->setEnabled(FALSE);
getChild<LLUICtrl>("Group Name Proxy")->setValue(LLStringUtil::null);
@@ -214,8 +224,6 @@ void LLPanelPermissions::disableAll()
getChildView("Description:")->setEnabled(FALSE);
getChild<LLUICtrl>("Object Description")->setValue(LLStringUtil::null);
getChildView("Object Description")->setEnabled(FALSE);
-
- getChildView("Permissions:")->setEnabled(FALSE);
getChild<LLUICtrl>("checkbox share with group")->setValue(FALSE);
getChildView("checkbox share with group")->setEnabled(FALSE);
@@ -369,8 +377,6 @@ void LLPanelPermissions::refresh()
getChildView("pathfinding_attributes_value")->setEnabled(TRUE);
getChild<LLUICtrl>("pathfinding_attributes_value")->setValue(LLTrans::getString(pfAttrName));
-
- getChildView("Permissions:")->setEnabled(TRUE);
// Update creator text field
getChildView("Creator:")->setEnabled(TRUE);
@@ -383,22 +389,29 @@ void LLPanelPermissions::refresh()
style_params.color = link_color;
style_params.readonly_color = link_color;
style_params.is_link = true; // link will be added later
- const LLFontGL* fontp = getChild<LLTextBox>("Creator Name")->getFont();
+ const LLFontGL* fontp = mLabelCreatorName->getFont();
style_params.font.name = LLFontGL::nameFromFont(fontp);
style_params.font.size = LLFontGL::sizeFromFont(fontp);
style_params.font.style = "UNDERLINE";
LLAvatarName av_name;
+ style_params.link_href = creator_app_link;
if (LLAvatarNameCache::get(mCreatorID, &av_name))
{
- // If name isn't present, this will 'request' it and trigger refresh() again
- LLTextBox* text_box = getChild<LLTextBox>("Creator Name");
- style_params.link_href = creator_app_link;
- text_box->setText(av_name.getCompleteName(), style_params);
+ updateCreatorName(mCreatorID, av_name, style_params);
+ }
+ else
+ {
+ if (mCreatorCacheConnection.connected())
+ {
+ mCreatorCacheConnection.disconnect();
+ }
+ mLabelCreatorName->setText(LLTrans::getString("None"));
+ mCreatorCacheConnection = LLAvatarNameCache::get(mCreatorID, boost::bind(&LLPanelPermissions::updateCreatorName, this, _1, _2, style_params));
}
getChild<LLAvatarIconCtrl>("Creator Icon")->setValue(mCreatorID);
getChild<LLAvatarIconCtrl>("Creator Icon")->setVisible(TRUE);
- getChildView("Creator Name")->setEnabled(TRUE);
+ mLabelCreatorName->setEnabled(TRUE);
// Update owner text field
getChildView("Owner:")->setEnabled(TRUE);
@@ -413,9 +426,8 @@ void LLPanelPermissions::refresh()
LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(mOwnerID);
if (group_data && group_data->isGroupPropertiesDataComplete())
{
- LLTextBox* text_box = getChild<LLTextBox>("Owner Name");
style_params.link_href = owner_app_link;
- text_box->setText(group_data->mName, style_params);
+ mLabelOwnerName->setText(group_data->mName, style_params);
getChild<LLGroupIconCtrl>("Owner Group Icon")->setIconId(group_data->mInsigniaID);
getChild<LLGroupIconCtrl>("Owner Group Icon")->setVisible(TRUE);
getChild<LLUICtrl>("Owner Icon")->setVisible(FALSE);
@@ -444,18 +456,27 @@ void LLPanelPermissions::refresh()
}
owner_id = mLastOwnerID;
}
+
+ style_params.link_href = owner_app_link;
if (LLAvatarNameCache::get(owner_id, &av_name))
{
- // If name isn't present, this will 'request' it and trigger refresh() again
- LLTextBox* text_box = getChild<LLTextBox>("Owner Name");
- style_params.link_href = owner_app_link;
- text_box->setText(av_name.getCompleteName(), style_params);
+ updateOwnerName(owner_id, av_name, style_params);
+ }
+ else
+ {
+ if (mOwnerCacheConnection.connected())
+ {
+ mOwnerCacheConnection.disconnect();
+ }
+ mLabelOwnerName->setText(LLTrans::getString("None"));
+ mOwnerCacheConnection = LLAvatarNameCache::get(owner_id, boost::bind(&LLPanelPermissions::updateOwnerName, this, _1, _2, style_params));
}
+
getChild<LLAvatarIconCtrl>("Owner Icon")->setValue(owner_id);
getChild<LLAvatarIconCtrl>("Owner Icon")->setVisible(TRUE);
getChild<LLUICtrl>("Owner Group Icon")->setVisible(FALSE);
}
- getChildView("Owner Name")->setEnabled(TRUE);
+ mLabelOwnerName->setEnabled(TRUE);
// update group text field
getChildView("Group:")->setEnabled(TRUE);
@@ -785,7 +806,7 @@ void LLPanelPermissions::refresh()
else
{
getChild<LLUICtrl>("checkbox share with group")->setValue(TRUE);
- getChild<LLUICtrl>("checkbox share with group")->setTentative( TRUE);
+ getChild<LLUICtrl>("checkbox share with group")->setTentative(!has_change_perm_ability);
getChildView("button deed")->setEnabled(gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED) && (group_mask_on & PERM_MOVE) && (owner_mask_on & PERM_TRANSFER) && !group_owned && can_transfer);
}
}
@@ -944,6 +965,23 @@ void LLPanelPermissions::refresh()
getChildView("clickaction")->setEnabled(is_perm_modify && is_nonpermanent_enforced && all_volume);
}
+void LLPanelPermissions::updateOwnerName(const LLUUID& owner_id, const LLAvatarName& owner_name, const LLStyle::Params& style_params)
+{
+ if (mOwnerCacheConnection.connected())
+ {
+ mOwnerCacheConnection.disconnect();
+ }
+ mLabelOwnerName->setText(owner_name.getCompleteName(), style_params);
+}
+
+void LLPanelPermissions::updateCreatorName(const LLUUID& creator_id, const LLAvatarName& creator_name, const LLStyle::Params& style_params)
+{
+ if (mCreatorCacheConnection.connected())
+ {
+ mCreatorCacheConnection.disconnect();
+ }
+ mLabelCreatorName->setText(creator_name.getCompleteName(), style_params);
+}
// static
void LLPanelPermissions::onClickClaim(void*)
diff --git a/indra/newview/llpanelpermissions.h b/indra/newview/llpanelpermissions.h
index 2d15954baa..e657f8f8b7 100644
--- a/indra/newview/llpanelpermissions.h
+++ b/indra/newview/llpanelpermissions.h
@@ -28,6 +28,7 @@
#define LL_LLPANELPERMISSIONS_H
#include "llpanel.h"
+#include "llstyle.h"
#include "lluuid.h"
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -36,6 +37,8 @@
// Panel for permissions of an object.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLAvatarName;
+class LLTextBox;
class LLNameBox;
class LLViewerInventoryItem;
@@ -46,7 +49,8 @@ public:
virtual ~LLPanelPermissions();
/*virtual*/ BOOL postBuild();
-
+ void updateOwnerName(const LLUUID& owner_id, const LLAvatarName& owner_name, const LLStyle::Params& style_params);
+ void updateCreatorName(const LLUUID& creator_id, const LLAvatarName& creator_name, const LLStyle::Params& style_params);
void refresh(); // refresh all labels as needed
protected:
@@ -85,10 +89,14 @@ protected:
private:
LLNameBox* mLabelGroupName; // group name
-
+ LLTextBox* mLabelOwnerName;
+ LLTextBox* mLabelCreatorName;
LLUUID mCreatorID;
LLUUID mOwnerID;
LLUUID mLastOwnerID;
+
+ boost::signals2::connection mOwnerCacheConnection;
+ boost::signals2::connection mCreatorCacheConnection;
};
diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index b1895bfc9b..1c4384ff08 100644
--- a/indra/newview/llpanelvolume.cpp
+++ b/indra/newview/llpanelvolume.cpp
@@ -282,7 +282,6 @@ void LLPanelVolume::getState( )
if (is_light && editable && single_volume)
{
- getChildView("label color")->setEnabled(true);
//mLabelColor ->setEnabled( TRUE );
LLColorSwatchCtrl* LightColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
if(LightColorSwatch)
@@ -325,7 +324,6 @@ void LLPanelVolume::getState( )
getChild<LLSpinCtrl>("Light Radius", true)->clear();
getChild<LLSpinCtrl>("Light Falloff", true)->clear();
- getChildView("label color")->setEnabled(false);
LLColorSwatchCtrl* LightColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
if(LightColorSwatch)
{
@@ -526,7 +524,6 @@ void LLPanelVolume::refresh()
BOOL visible = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 0 ? TRUE : FALSE;
- getChildView("label texture")->setVisible( visible);
getChildView("Light FOV")->setVisible( visible);
getChildView("Light Focus")->setVisible( visible);
getChildView("Light Ambiance")->setVisible( visible);
@@ -567,9 +564,7 @@ void LLPanelVolume::clearCtrls()
getChildView("select_single")->setVisible(true);
getChildView("edit_object")->setEnabled(false);
getChildView("edit_object")->setVisible(false);
- getChildView("Light Checkbox Ctrl")->setEnabled(false);
- getChildView("label color")->setEnabled(false);
- getChildView("label color")->setEnabled(false);
+ getChildView("Light Checkbox Ctrl")->setEnabled(false);;
LLColorSwatchCtrl* LightColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
if(LightColorSwatch)
{
diff --git a/indra/newview/llpanelvolumepulldown.cpp b/indra/newview/llpanelvolumepulldown.cpp
index 6595da235c..6792137350 100644
--- a/indra/newview/llpanelvolumepulldown.cpp
+++ b/indra/newview/llpanelvolumepulldown.cpp
@@ -35,6 +35,7 @@
// Linden libs
#include "llbutton.h"
+#include "llcheckboxctrl.h"
#include "lltabcontainer.h"
#include "llfloaterreg.h"
#include "llfloaterpreference.h"
@@ -52,17 +53,15 @@ LLPanelVolumePulldown::LLPanelVolumePulldown()
{
mHoverTimer.stop();
- mCommitCallbackRegistrar.add("Vol.setControlFalse", boost::bind(&LLPanelVolumePulldown::setControlFalse, this, _2));
+ mCommitCallbackRegistrar.add("Vol.setControlFalse", boost::bind(&LLPanelVolumePulldown::setControlFalse, this, _2));
+ mCommitCallbackRegistrar.add("Vol.SetSounds", boost::bind(&LLPanelVolumePulldown::onClickSetSounds, this));
+ mCommitCallbackRegistrar.add("Vol.updateMediaAutoPlayCheckbox", boost::bind(&LLPanelVolumePulldown::updateMediaAutoPlayCheckbox, this, _1));
mCommitCallbackRegistrar.add("Vol.GoAudioPrefs", boost::bind(&LLPanelVolumePulldown::onAdvancedButtonClick, this, _2));
buildFromFile( "panel_volume_pulldown.xml");
}
BOOL LLPanelVolumePulldown::postBuild()
{
- // set the initial volume-slider's position to reflect reality
- LLSliderCtrl* volslider = getChild<LLSliderCtrl>( "mastervolume" );
- volslider->setValue(gSavedSettings.getF32("AudioLevelMaster"));
-
return LLPanel::postBuild();
}
@@ -130,6 +129,28 @@ void LLPanelVolumePulldown::setControlFalse(const LLSD& user_data)
control->set(LLSD(FALSE));
}
+void LLPanelVolumePulldown::updateMediaAutoPlayCheckbox(LLUICtrl* ctrl)
+{
+ std::string name = ctrl->getName();
+
+ // Disable "Allow Media to auto play" only when both
+ // "Streaming Music" and "Media" are unchecked. STORM-513.
+ if ((name == "enable_music") || (name == "enable_media"))
+ {
+ bool music_enabled = getChild<LLCheckBoxCtrl>("enable_music")->get();
+ bool media_enabled = getChild<LLCheckBoxCtrl>("enable_media")->get();
+
+ getChild<LLCheckBoxCtrl>("media_auto_play_btn")->setEnabled(music_enabled || media_enabled);
+ }
+}
+
+void LLPanelVolumePulldown::onClickSetSounds()
+{
+ // Disable Enable gesture sounds checkbox if the master sound is disabled
+ // or if sound effects are disabled.
+ getChild<LLCheckBoxCtrl>("gesture_audio_play_btn")->setEnabled(!gSavedSettings.getBOOL("MuteSounds"));
+}
+
//virtual
void LLPanelVolumePulldown::draw()
{
diff --git a/indra/newview/llpanelvolumepulldown.h b/indra/newview/llpanelvolumepulldown.h
index b843fab756..4f23112f50 100644
--- a/indra/newview/llpanelvolumepulldown.h
+++ b/indra/newview/llpanelvolumepulldown.h
@@ -47,6 +47,10 @@ class LLPanelVolumePulldown : public LLPanel
private:
void setControlFalse(const LLSD& user_data);
+ void onClickSetSounds();
+ // Disables "Allow Media to auto play" check box only when both
+ // "Streaming Music" and "Media" are unchecked. Otherwise enables it.
+ void updateMediaAutoPlayCheckbox(LLUICtrl* ctrl);
void onAdvancedButtonClick(const LLSD& user_data);
LLFrameTimer mHoverTimer;
diff --git a/indra/newview/llpanelwearing.cpp b/indra/newview/llpanelwearing.cpp
index 3099a6e039..89cb495db9 100644
--- a/indra/newview/llpanelwearing.cpp
+++ b/indra/newview/llpanelwearing.cpp
@@ -65,7 +65,7 @@ public:
LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
registrar.add("Gear.Edit", boost::bind(&edit_outfit));
- registrar.add("Gear.TakeOff", boost::bind(&LLWearingGearMenu::onTakeOff, this));
+ registrar.add("Gear.TakeOff", boost::bind(&LLPanelWearing::onRemoveItem, mPanelWearing));
registrar.add("Gear.Copy", boost::bind(&LLPanelWearing::copyToClipboard, mPanelWearing));
enable_registrar.add("Gear.OnEnable", boost::bind(&LLPanelWearing::isActionEnabled, mPanelWearing, _2));
@@ -79,13 +79,6 @@ public:
private:
- void onTakeOff()
- {
- uuid_vec_t selected_uuids;
- mPanelWearing->getSelectedItemsUUIDs(selected_uuids);
- LLAppearanceMgr::instance().removeItemsFromAvatar(selected_uuids);
- }
-
LLToggleableMenu* mMenu;
LLPanelWearing* mPanelWearing;
};
@@ -343,7 +336,18 @@ bool LLPanelWearing::isActionEnabled(const LLSD& userdata)
if (command_name == "take_off")
{
- return hasItemSelected() && canTakeOffSelected();
+ if (mWearablesTab->isExpanded())
+ {
+ return hasItemSelected() && canTakeOffSelected();
+ }
+ else
+ {
+ LLScrollListItem* item = mTempItemsList->getFirstSelected();
+ if (item && item->getUUID().notNull())
+ {
+ return true;
+ }
+ }
}
return false;
@@ -524,7 +528,7 @@ void LLPanelWearing::onEditAttachment()
void LLPanelWearing::onRemoveAttachment()
{
LLScrollListItem* item = mTempItemsList->getFirstSelected();
- if (item)
+ if (item && item->getUUID().notNull())
{
LLSelectMgr::getInstance()->deselectAll();
LLSelectMgr::getInstance()->selectObjectAndFamily(mAttachmentsMap[item->getUUID()]);
@@ -532,6 +536,21 @@ void LLPanelWearing::onRemoveAttachment()
}
}
+void LLPanelWearing::onRemoveItem()
+{
+ if (mWearablesTab->isExpanded())
+ {
+ uuid_vec_t selected_uuids;
+ getSelectedItemsUUIDs(selected_uuids);
+ LLAppearanceMgr::instance().removeItemsFromAvatar(selected_uuids);
+ }
+ else
+ {
+ onRemoveAttachment();
+ }
+}
+
+
void LLPanelWearing::copyToClipboard()
{
std::string text;
diff --git a/indra/newview/llpanelwearing.h b/indra/newview/llpanelwearing.h
index c5cb79092a..715404a457 100644
--- a/indra/newview/llpanelwearing.h
+++ b/indra/newview/llpanelwearing.h
@@ -80,6 +80,7 @@ public:
void onAccordionTabStateChanged();
void setAttachmentDetails(LLSD content);
void requestAttachmentDetails();
+ void onRemoveItem();
void onEditAttachment();
void onRemoveAttachment();
diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp
index 08d734ddac..f48ce680fd 100644
--- a/indra/newview/llphysicsmotion.cpp
+++ b/indra/newview/llphysicsmotion.cpp
@@ -44,7 +44,9 @@ typedef std::map<std::string, std::string> controller_map_t;
typedef std::map<std::string, F32> default_controller_map_t;
#define MIN_REQUIRED_PIXEL_AREA_AVATAR_PHYSICS_MOTION 0.f
-#define TIME_ITERATION_STEP 0.05f
+// we use TIME_ITERATION_STEP_MAX in division operation, make sure this is a simple
+// value and devision result won't end with repeated/recurring tail like 1.333(3)
+#define TIME_ITERATION_STEP_MAX 0.05f // minimal step size will end up as 0.025
inline F64 llsgn(const F64 a)
{
@@ -480,7 +482,7 @@ BOOL LLPhysicsMotion::onUpdate(F32 time)
if (!mParamDriver)
return FALSE;
- if (!mLastTime)
+ if (!mLastTime || mLastTime >= time)
{
mLastTime = time;
return FALSE;
@@ -561,14 +563,10 @@ BOOL LLPhysicsMotion::onUpdate(F32 time)
// bounce at right (relatively) position.
// Note: this doesn't look to be optimal, since it provides only "roughly same" behavior, but
// irregularity at higher fps looks to be insignificant so it works good enough for low fps.
- for (F32 time_iteration = 0; time_iteration <= time_delta; time_iteration += TIME_ITERATION_STEP)
+ U32 steps = (U32)(time_delta / TIME_ITERATION_STEP_MAX) + 1;
+ F32 time_iteration_step = time_delta / (F32)steps; //minimal step size ends up as 0.025
+ for (U32 i = 0; i < steps; i++)
{
- F32 time_iteration_step = TIME_ITERATION_STEP;
- if (time_iteration + TIME_ITERATION_STEP > time_delta)
- {
- time_iteration_step = time_delta-time_iteration;
- }
-
// mPositon_local should be in normalized 0,1 range already. Just making sure...
const F32 position_current_local = llclamp(mPosition_local,
0.0f,
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 6ecc4c7fb9..d4eecaffce 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -61,6 +61,7 @@
#include "llselectmgr.h"
#include "llviewerinventory.h"
#include "llviewermenu.h"
+#include "llviewermenufile.h" // LLFilePickerReplyThread
#include "llviewerobject.h"
#include "llviewerobjectlist.h"
#include "llviewerregion.h"
@@ -1202,17 +1203,12 @@ BOOL LLScriptEdCore::handleKeyHere(KEY key, MASK mask)
void LLScriptEdCore::onBtnLoadFromFile( void* data )
{
- LLScriptEdCore* self = (LLScriptEdCore*) data;
-
- // TODO Maybe add a dialogue warning here if the current file has unsaved changes.
- LLFilePicker& file_picker = LLFilePicker::instance();
- if( !file_picker.getOpenFile( LLFilePicker::FFLOAD_SCRIPT ) )
- {
- //File picking cancelled by user, so nothing to do.
- return;
- }
+ (new LLFilePickerReplyThread(boost::bind(&LLScriptEdCore::loadScriptFromFile, _1, data), LLFilePicker::FFLOAD_SCRIPT, false))->getFile();
+}
- std::string filename = file_picker.getFirstFile();
+void LLScriptEdCore::loadScriptFromFile(const std::vector<std::string>& filenames, void* data)
+{
+ std::string filename = filenames[0];
llifstream fin(filename.c_str());
@@ -1220,8 +1216,8 @@ void LLScriptEdCore::onBtnLoadFromFile( void* data )
std::string text;
std::string linetotal;
while (!fin.eof())
- {
- getline(fin,line);
+ {
+ getline(fin, line);
text += line;
if (!fin.eof())
{
@@ -1231,7 +1227,8 @@ void LLScriptEdCore::onBtnLoadFromFile( void* data )
fin.close();
// Only replace the script if there is something to replace with.
- if (text.length() > 0)
+ LLScriptEdCore* self = (LLScriptEdCore*)data;
+ if (self && (text.length() > 0))
{
self->mEditor->selectAll();
LLWString script(utf8str_to_wstring(text));
@@ -1247,16 +1244,21 @@ void LLScriptEdCore::onBtnSaveToFile( void* userdata )
if( self->mSaveCallback )
{
- LLFilePicker& file_picker = LLFilePicker::instance();
- if( file_picker.getSaveFile( LLFilePicker::FFSAVE_SCRIPT, self->mScriptName ) )
- {
- std::string filename = file_picker.getFirstFile();
- std::string scriptText=self->mEditor->getText();
- llofstream fout(filename.c_str());
- fout<<(scriptText);
- fout.close();
- self->mSaveCallback( self->mUserdata, FALSE );
- }
+ (new LLFilePickerReplyThread(boost::bind(&LLScriptEdCore::saveScriptToFile, _1, userdata), LLFilePicker::FFSAVE_SCRIPT, self->mScriptName))->getFile();
+ }
+}
+
+void LLScriptEdCore::saveScriptToFile(const std::vector<std::string>& filenames, void* data)
+{
+ LLScriptEdCore* self = (LLScriptEdCore*)data;
+ if (self)
+ {
+ std::string filename = filenames[0];
+ std::string scriptText = self->mEditor->getText();
+ llofstream fout(filename.c_str());
+ fout << (scriptText);
+ fout.close();
+ self->mSaveCallback(self->mUserdata, FALSE);
}
}
@@ -2041,7 +2043,15 @@ void LLLiveLSLEditor::loadScriptText(LLVFS *vfs, const LLUUID &uuid, LLAssetType
mScriptEd->setScriptText(LLStringExplicit(&buffer[0]), TRUE);
mScriptEd->makeEditorPristine();
- mScriptEd->setScriptName(getItem()->getName());
+
+ std::string script_name = DEFAULT_SCRIPT_NAME;
+ const LLInventoryItem* inv_item = getItem();
+
+ if(inv_item)
+ {
+ script_name = inv_item->getName();
+ }
+ mScriptEd->setScriptName(script_name);
}
diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h
index a185d85889..69cf9d9158 100644
--- a/indra/newview/llpreviewscript.h
+++ b/indra/newview/llpreviewscript.h
@@ -109,7 +109,10 @@ public:
static void onBtnInsertSample(void*);
static void onBtnInsertFunction(LLUICtrl*, void*);
static void onBtnLoadFromFile(void*);
- static void onBtnSaveToFile(void*);
+ static void onBtnSaveToFile(void*);
+
+ static void loadScriptFromFile(const std::vector<std::string>& filenames, void* data);
+ static void saveScriptToFile(const std::vector<std::string>& filenames, void* data);
static bool enableSaveToFileMenu(void* userdata);
static bool enableLoadFromFileMenu(void* userdata);
diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp
index 12bcd89cb0..9d8be4b2fe 100644
--- a/indra/newview/llpreviewtexture.cpp
+++ b/indra/newview/llpreviewtexture.cpp
@@ -46,6 +46,7 @@
#include "lltextureview.h"
#include "llui.h"
#include "llviewerinventory.h"
+#include "llviewermenufile.h" // LLFilePickerReplyThread
#include "llviewertexture.h"
#include "llviewertexturelist.h"
#include "lluictrlfactory.h"
@@ -293,27 +294,27 @@ void LLPreviewTexture::saveAs()
if( mLoadingFullImage )
return;
- LLFilePicker& file_picker = LLFilePicker::instance();
- const LLInventoryItem* item = getItem() ;
- if( !file_picker.getSaveFile( LLFilePicker::FFSAVE_TGAPNG, item ? LLDir::getScrubbedFileName(item->getName()) : LLStringUtil::null) )
- {
- // User canceled or we failed to acquire save file.
- return;
- }
- if(mPreviewToSave)
+ std::string filename = getItem() ? LLDir::getScrubbedFileName(getItem()->getName()) : LLStringUtil::null;
+ (new LLFilePickerReplyThread(boost::bind(&LLPreviewTexture::saveTextureToFile, this, _1), LLFilePicker::FFSAVE_TGAPNG, filename))->getFile();
+}
+
+void LLPreviewTexture::saveTextureToFile(const std::vector<std::string>& filenames)
+{
+ const LLInventoryItem* item = getItem();
+ if (item && mPreviewToSave)
{
mPreviewToSave = FALSE;
LLFloaterReg::showTypedInstance<LLPreviewTexture>("preview_texture", item->getUUID());
}
// remember the user-approved/edited file name.
- mSaveFileName = file_picker.getFirstFile();
+ mSaveFileName = filenames[0];
mLoadingFullImage = TRUE;
getWindow()->incBusyCount();
- mImage->forceToSaveRawImage(0) ;//re-fetch the raw image if the old one is removed.
- mImage->setLoadedCallback( LLPreviewTexture::onFileLoadedForSave,
- 0, TRUE, FALSE, new LLUUID( mItemUUID ), &mCallbackTextureList );
+ mImage->forceToSaveRawImage(0);//re-fetch the raw image if the old one is removed.
+ mImage->setLoadedCallback(LLPreviewTexture::onFileLoadedForSave,
+ 0, TRUE, FALSE, new LLUUID(mItemUUID), &mCallbackTextureList);
}
// virtual
diff --git a/indra/newview/llpreviewtexture.h b/indra/newview/llpreviewtexture.h
index c156c48d0c..ad77d9e118 100644
--- a/indra/newview/llpreviewtexture.h
+++ b/indra/newview/llpreviewtexture.h
@@ -61,6 +61,8 @@ public:
BOOL final,
void* userdata );
void openToSave();
+
+ void saveTextureToFile(const std::vector<std::string>& filenames);
static void onSaveAsBtn(void* data);
diff --git a/indra/newview/llsculptidsize.cpp b/indra/newview/llsculptidsize.cpp
new file mode 100644
index 0000000000..9edd78bff0
--- /dev/null
+++ b/indra/newview/llsculptidsize.cpp
@@ -0,0 +1,154 @@
+/**
+* @file llsculptidsize.cpp
+* @brief LLSculptIDSize class implementation
+*
+* $LicenseInfo:firstyear=2002&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2010, 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 "llsculptidsize.h"
+#include "llvovolume.h"
+#include "lldrawable.h"
+#include "llvoavatar.h"
+//boost
+#include "boost/make_shared.hpp"
+
+//...........
+
+extern LLControlGroup gSavedSettings;
+
+//...........
+
+typedef std::pair<LLSculptIDSize::container_BY_SCULPT_ID_view::iterator, LLSculptIDSize::container_BY_SCULPT_ID_view::iterator> pair_iter_iter_BY_SCULPT_ID_t;
+
+//...........
+
+void _nothing_to_do_func(int) { /*nothing todo here because of the size it's a shared member*/ }
+
+void LLSculptIDSize::inc(const LLDrawable *pdrawable, int sz)
+{
+ llassert(sz >= 0);
+
+ if (!pdrawable) return;
+ LLVOVolume* vvol = pdrawable->getVOVolume();
+ if (!vvol) return;
+ if (!vvol->isAttachment()) return;
+ if (!vvol->getAvatar()) return;
+ if (vvol->getAvatar()->isSelf()) return;
+ LLVolume *vol = vvol->getVolume();
+ if (!vol) return;
+
+ const LLUUID &sculptId = vol->getParams().getSculptID();
+ if (sculptId.isNull()) return;
+
+ unsigned int total_size = 0;
+
+ pair_iter_iter_BY_SCULPT_ID_t itLU = mSizeInfo.get<tag_BY_SCULPT_ID>().equal_range(sculptId);
+ if (itLU.first == itLU.second)
+ { //register
+ llassert(mSizeInfo.get<tag_BY_DRAWABLE>().end() == mSizeInfo.get<tag_BY_DRAWABLE>().find(pdrawable));
+ mSizeInfo.get<tag_BY_DRAWABLE>().insert(Info(pdrawable, sz, boost::make_shared<SizeSum>(sz), sculptId));
+ total_size = sz;
+ }
+ else
+ { //update + register
+ Info &nfo = const_cast<Info &>(*itLU.first);
+ //calc new size
+ total_size = nfo.getSizeSum() + sz;
+ nfo.mSharedSizeSum->mSizeSum = total_size;
+ nfo.mSize = sz;
+ //update size for all LLDrwable in range of sculptId
+ for (pair_iter_iter_BY_SCULPT_ID_t::first_type it = itLU.first; it != itLU.second; ++it)
+ {
+ mSizeInfo.get<tag_BY_SIZE>().modify_key(mSizeInfo.project<tag_BY_SIZE>(it), boost::bind(&_nothing_to_do_func, _1));
+ }
+
+ //trying insert the LLDrawable
+ mSizeInfo.get<tag_BY_DRAWABLE>().insert(Info(pdrawable, sz, nfo.mSharedSizeSum, sculptId));
+ }
+
+ static LLCachedControl<U32> render_auto_mute_byte_limit(gSavedSettings, "RenderAutoMuteByteLimit", 0U);
+
+ if (0 != render_auto_mute_byte_limit && total_size > render_auto_mute_byte_limit)
+ {
+ pair_iter_iter_BY_SCULPT_ID_t it_eqr = mSizeInfo.get<tag_BY_SCULPT_ID>().equal_range(sculptId);
+ for (; it_eqr.first != it_eqr.second; ++it_eqr.first)
+ {
+ const Info &i = *it_eqr.first;
+ LLVOVolume *pVVol = i.mDrawable->getVOVolume();
+ if (pVVol
+ && !pVVol->isDead()
+ && pVVol->isAttachment()
+ && !pVVol->getAvatar()->isSelf()
+ && LLVOVolume::NO_LOD != pVVol->getLOD()
+ )
+ {
+ addToUnloaded(sculptId);
+ //immediately
+ const_cast<LLDrawable*>(i.mDrawable)->unload();
+ }
+ }
+ }
+}
+
+void LLSculptIDSize::dec(const LLDrawable *pdrawable)
+{
+ container_BY_DRAWABLE_view::iterator it = mSizeInfo.get<tag_BY_DRAWABLE>().find(pdrawable);
+ if (mSizeInfo.get<tag_BY_DRAWABLE>().end() == it) return;
+
+ unsigned int size = it->getSizeSum() - it->getSize();
+
+ if (0 == size)
+ {
+ mSizeInfo.get<tag_BY_SCULPT_ID>().erase(it->getSculptId());
+ }
+ else
+ {
+ Info &nfo = const_cast<Info &>(*it);
+ nfo.mSize = 0;
+ pair_iter_iter_BY_SCULPT_ID_t itLU = mSizeInfo.get<tag_BY_SCULPT_ID>().equal_range(it->getSculptId());
+ it->mSharedSizeSum->mSizeSum = size;
+ for (pair_iter_iter_BY_SCULPT_ID_t::first_type it = itLU.first; it != itLU.second; ++it)
+ {
+ mSizeInfo.get<tag_BY_SIZE>().modify_key(mSizeInfo.project<tag_BY_SIZE>(it), boost::bind(&_nothing_to_do_func, _1));
+ }
+ }
+}
+
+void LLSculptIDSize::rem(const LLUUID &sculptId)
+{
+ mSizeInfo.get<tag_BY_SCULPT_ID>().erase(sculptId);
+}
+
+void LLSculptIDSize::resetSizeSum(const LLUUID &sculptId)
+{
+ const pair_iter_iter_BY_SCULPT_ID_t itLU = mSizeInfo.get<tag_BY_SCULPT_ID>().equal_range(sculptId);
+
+ if (itLU.first != itLU.second) {
+ itLU.first->mSharedSizeSum->mSizeSum = 0;
+ }
+
+ for (pair_iter_iter_BY_SCULPT_ID_t::first_type it = itLU.first, itE = itLU.second; it != itE; ++it)
+ {
+ mSizeInfo.get<tag_BY_SIZE>().modify_key(mSizeInfo.project<tag_BY_SIZE>(it), boost::bind(&_nothing_to_do_func, _1));
+ }
+}
diff --git a/indra/newview/llsculptidsize.h b/indra/newview/llsculptidsize.h
new file mode 100644
index 0000000000..87ee417b86
--- /dev/null
+++ b/indra/newview/llsculptidsize.h
@@ -0,0 +1,134 @@
+/**
+* @file llsculptidsize.h
+* @brief LLSculptIDSize class definition
+*
+* $LicenseInfo:firstyear=2009&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2010, 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_LLSCULPTIDSIZE_H
+#define LL_LLSCULPTIDSIZE_H
+
+#include "lluuid.h"
+
+//std
+#include <set>
+//boost
+#include "boost/multi_index_container.hpp"
+#include "boost/multi_index/ordered_index.hpp"
+#include "boost/multi_index/mem_fun.hpp"
+
+class LLDrawable;
+
+
+class LLSculptIDSize
+{
+public:
+ struct SizeSum
+ {
+ SizeSum(int size)
+ : mSizeSum(size)
+ {}
+ unsigned int mSizeSum;
+ };
+
+ struct Info
+ {
+ typedef boost::shared_ptr<SizeSum> PtrSizeSum;
+
+ Info(const LLDrawable *drawable, int size, PtrSizeSum sizeInfo, LLUUID sculptId)
+ : mDrawable(drawable)
+ , mSize(size)
+ , mSharedSizeSum(sizeInfo)
+ , mSculptId(sculptId)
+ {}
+
+ const LLDrawable *mDrawable;
+ unsigned int mSize;
+ PtrSizeSum mSharedSizeSum;
+ LLUUID mSculptId;
+
+ inline const LLDrawable* getPtrLLDrawable() const { return mDrawable; }
+ inline unsigned int getSize() const { return mSize; }
+ inline unsigned int getSizeSum() const { return mSharedSizeSum->mSizeSum; }
+ inline LLUUID getSculptId() const { return mSculptId; }
+ PtrSizeSum getSizeInfo() { return mSharedSizeSum; }
+ };
+
+public:
+ //tags
+ struct tag_BY_DRAWABLE {};
+ struct tag_BY_SCULPT_ID {};
+ struct tag_BY_SIZE {};
+
+ //container
+ typedef boost::multi_index_container <
+ Info,
+ boost::multi_index::indexed_by <
+ boost::multi_index::ordered_unique< boost::multi_index::tag<tag_BY_DRAWABLE>
+ , boost::multi_index::const_mem_fun<Info, const LLDrawable*, &Info::getPtrLLDrawable>
+ >
+ , boost::multi_index::ordered_non_unique<boost::multi_index::tag<tag_BY_SCULPT_ID>
+ , boost::multi_index::const_mem_fun<Info, LLUUID, &Info::getSculptId>
+ >
+ , boost::multi_index::ordered_non_unique < boost::multi_index::tag<tag_BY_SIZE>
+ , boost::multi_index::const_mem_fun < Info, unsigned int, &Info::getSizeSum >
+ >
+ >
+ > container;
+
+ //views
+ typedef container::index<tag_BY_DRAWABLE>::type container_BY_DRAWABLE_view;
+ typedef container::index<tag_BY_SCULPT_ID>::type container_BY_SCULPT_ID_view;
+ typedef container::index<tag_BY_SIZE>::type container_BY_SIZE_view;
+
+private:
+ LLSculptIDSize()
+ {}
+
+public:
+ static LLSculptIDSize & instance()
+ {
+ static LLSculptIDSize inst;
+ return inst;
+ }
+
+public:
+ void inc(const LLDrawable *pdrawable, int sz);
+ void dec(const LLDrawable *pdrawable);
+ void rem(const LLUUID &sculptId);
+
+ inline void addToUnloaded(const LLUUID &sculptId) { mMarkAsUnloaded.insert(sculptId); }
+ inline void remFromUnloaded(const LLUUID &sculptId) { mMarkAsUnloaded.erase(sculptId); }
+ inline bool isUnloaded(const LLUUID &sculptId) const { return mMarkAsUnloaded.end() != mMarkAsUnloaded.find(sculptId); }
+ inline void clearUnloaded() { mMarkAsUnloaded.clear(); }
+
+ void resetSizeSum(const LLUUID &sculptId);
+
+ inline const container & getSizeInfo() const { return mSizeInfo; }
+
+private:
+ container mSizeInfo;
+ typedef std::set<LLUUID> std_LLUUID;
+ std_LLUUID mMarkAsUnloaded;
+};
+
+#endif
diff --git a/indra/newview/llsechandler_basic.cpp b/indra/newview/llsechandler_basic.cpp
index 814cfde75d..9ab9e4a1a2 100644
--- a/indra/newview/llsechandler_basic.cpp
+++ b/indra/newview/llsechandler_basic.cpp
@@ -1275,7 +1275,7 @@ void LLSecAPIBasicHandler::init()
// grab the application ca-bundle.crt file that contains the well-known certs shipped
// with the product
- std::string ca_file_path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "ca-bundle.crt");
+ std::string ca_file_path = gDirUtilp->getCAFile();
LL_INFOS("SECAPI") << "Loading application certificate store from " << ca_file_path << LL_ENDL;
LLPointer<LLBasicCertificateStore> app_ca_store = new LLBasicCertificateStore(ca_file_path);
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index c44aca6fa5..ddae109030 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -6271,92 +6271,107 @@ void pushWireframe(LLDrawable* drawable)
void LLSelectNode::renderOneWireframe(const LLColor4& color)
{
- //Need to because crash on ATI 3800 (and similar cards) MAINT-5018
- LLGLDisable multisample(LLPipeline::RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
+ //Need to because crash on ATI 3800 (and similar cards) MAINT-5018
+ LLGLDisable multisample(LLPipeline::RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
- LLViewerObject* objectp = getObject();
- if (!objectp)
- {
- return;
- }
+ LLViewerObject* objectp = getObject();
+ if (!objectp)
+ {
+ return;
+ }
- LLDrawable* drawable = objectp->mDrawable;
- if(!drawable)
- {
- return;
- }
+ LLDrawable* drawable = objectp->mDrawable;
+ if (!drawable)
+ {
+ return;
+ }
- LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+ LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
- if (shader)
- {
- gDebugProgram.bind();
- }
+ if (shader)
+ {
+ gDebugProgram.bind();
+ }
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
-
- BOOL is_hud_object = objectp->isHUDAttachment();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
- if (drawable->isActive())
- {
- gGL.loadMatrix(gGLModelView);
- gGL.multMatrix((F32*) objectp->getRenderMatrix().mMatrix);
- }
- else if (!is_hud_object)
- {
- gGL.loadIdentity();
- gGL.multMatrix(gGLModelView);
- LLVector3 trans = objectp->getRegion()->getOriginAgent();
- gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);
- }
-
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-
- if (LLSelectMgr::sRenderHiddenSelections) // && gFloaterTools && gFloaterTools->getVisible())
- {
- gGL.blendFunc(LLRender::BF_SOURCE_COLOR, LLRender::BF_ONE);
- LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GEQUAL);
- if (shader)
- {
- gGL.diffuseColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f);
- pushWireframe(drawable);
- }
- else
- {
- LLGLEnable fog(GL_FOG);
- glFogi(GL_FOG_MODE, GL_LINEAR);
- float d = (LLViewerCamera::getInstance()->getPointOfInterest()-LLViewerCamera::getInstance()->getOrigin()).magVec();
- LLColor4 fogCol = color * (F32)llclamp((LLSelectMgr::getInstance()->getSelectionCenterGlobal()-gAgentCamera.getCameraPositionGlobal()).magVec()/(LLSelectMgr::getInstance()->getBBoxOfSelection().getExtentLocal().magVec()*4), 0.0, 1.0);
- glFogf(GL_FOG_START, d);
- glFogf(GL_FOG_END, d*(1 + (LLViewerCamera::getInstance()->getView() / LLViewerCamera::getInstance()->getDefaultFOV())));
- glFogfv(GL_FOG_COLOR, fogCol.mV);
+ BOOL is_hud_object = objectp->isHUDAttachment();
- gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
- {
- gGL.diffuseColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f);
- pushWireframe(drawable);
- }
- }
- }
+ if (drawable->isActive())
+ {
+ gGL.loadMatrix(gGLModelView);
+ gGL.multMatrix((F32*)objectp->getRenderMatrix().mMatrix);
+ }
+ else if (!is_hud_object)
+ {
+ gGL.loadIdentity();
+ gGL.multMatrix(gGLModelView);
+ LLVector3 trans = objectp->getRegion()->getOriginAgent();
+ gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);
+ }
- gGL.flush();
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- gGL.diffuseColor4f(color.mV[VRED]*2, color.mV[VGREEN]*2, color.mV[VBLUE]*2, LLSelectMgr::sHighlightAlpha*2);
-
- LLGLEnable offset(GL_POLYGON_OFFSET_LINE);
- glPolygonOffset(3.f, 3.f);
- glLineWidth(3.f);
- pushWireframe(drawable);
- glLineWidth(1.f);
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- gGL.popMatrix();
+ if (LLSelectMgr::sRenderHiddenSelections) // && gFloaterTools && gFloaterTools->getVisible())
+ {
+ gGL.blendFunc(LLRender::BF_SOURCE_COLOR, LLRender::BF_ONE);
+ LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GEQUAL);
+ if (shader)
+ {
+ gGL.diffuseColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f);
+ pushWireframe(drawable);
+ }
+ else
+ {
+ LLGLEnable fog(GL_FOG);
+ glFogi(GL_FOG_MODE, GL_LINEAR);
+ float d = (LLViewerCamera::getInstance()->getPointOfInterest() - LLViewerCamera::getInstance()->getOrigin()).magVec();
+ LLColor4 fogCol = color * (F32)llclamp((LLSelectMgr::getInstance()->getSelectionCenterGlobal() - gAgentCamera.getCameraPositionGlobal()).magVec() / (LLSelectMgr::getInstance()->getBBoxOfSelection().getExtentLocal().magVec() * 4), 0.0, 1.0);
+ glFogf(GL_FOG_START, d);
+ glFogf(GL_FOG_END, d*(1 + (LLViewerCamera::getInstance()->getView() / LLViewerCamera::getInstance()->getDefaultFOV())));
+ glFogfv(GL_FOG_COLOR, fogCol.mV);
+
+ gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
+ {
+ gGL.diffuseColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f);
+ pushWireframe(drawable);
+ }
+ }
+ }
- if (shader)
- {
- shader->bind();
- }
+ gGL.flush();
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
+
+ gGL.diffuseColor4f(color.mV[VRED] * 2, color.mV[VGREEN] * 2, color.mV[VBLUE] * 2, LLSelectMgr::sHighlightAlpha * 2);
+
+ {
+ bool wireframe_selection = gFloaterTools && gFloaterTools->getVisible();
+
+ LLGLDisable depth(wireframe_selection ? 0 : GL_BLEND);
+ LLGLEnable stencil(wireframe_selection ? 0 : GL_STENCIL_TEST);
+
+ if (!wireframe_selection)
+ { //modify wireframe into outline selection mode
+ glStencilFunc(GL_NOTEQUAL, 2, 0xffff);
+ glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+ }
+
+ LLGLEnable offset(GL_POLYGON_OFFSET_LINE);
+ glPolygonOffset(3.f, 3.f);
+ glLineWidth(5.f);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ pushWireframe(drawable);
+ }
+
+ glLineWidth(1.f);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ gGL.popMatrix();
+
+ if (shader)
+ {
+ shader->bind();
+ }
}
//-----------------------------------------------------------------------------
diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp
index d6bf2164a0..4ebcffa554 100644
--- a/indra/newview/llsidepanelappearance.cpp
+++ b/indra/newview/llsidepanelappearance.cpp
@@ -102,10 +102,6 @@ BOOL LLSidepanelAppearance::postBuild()
childSetAction("edit_outfit_btn", boost::bind(&LLSidepanelAppearance::showOutfitEditPanel, this));
- mNewOutfitBtn = getChild<LLButton>("newlook_btn");
- mNewOutfitBtn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onNewOutfitButtonClicked, this));
- mNewOutfitBtn->setEnabled(false);
-
mFilterEditor = getChild<LLFilterEditor>("Filter");
if (mFilterEditor)
{
@@ -285,14 +281,6 @@ void LLSidepanelAppearance::onEditAppearanceButtonClicked()
}
}
-void LLSidepanelAppearance::onNewOutfitButtonClicked()
-{
- if (!mOutfitEdit->getVisible())
- {
- mPanelOutfitsInventory->onSave();
- }
-}
-
void LLSidepanelAppearance::showOutfitsInventoryPanel()
{
toggleWearableEditPanel(FALSE);
@@ -347,7 +335,6 @@ void LLSidepanelAppearance::toggleMyOutfitsPanel(BOOL visible)
// *TODO: Move these controls to panel_outfits_inventory.xml
// so that we don't need to toggle them explicitly.
mFilterEditor->setVisible(visible);
- mNewOutfitBtn->setVisible(visible);
mCurrOutfitPanel->setVisible(visible);
if (visible)
@@ -473,8 +460,6 @@ void LLSidepanelAppearance::editWearable(LLViewerWearable *wearable, LLView *dat
// fetched. Alternatively, we could stuff this logic into llagentwearables::makeNewOutfitLinks.
void LLSidepanelAppearance::fetchInventory()
{
-
- mNewOutfitBtn->setEnabled(false);
uuid_vec_t ids;
LLUUID item_id;
for(S32 type = (S32)LLWearableType::WT_SHAPE; type < (S32)LLWearableType::WT_COUNT; ++type)
@@ -525,7 +510,6 @@ void LLSidepanelAppearance::fetchInventory()
void LLSidepanelAppearance::inventoryFetched()
{
- mNewOutfitBtn->setEnabled(true);
}
void LLSidepanelAppearance::setWearablesLoading(bool val)
diff --git a/indra/newview/llsidepanelappearance.h b/indra/newview/llsidepanelappearance.h
index 440fce07bb..7817fd317c 100644
--- a/indra/newview/llsidepanelappearance.h
+++ b/indra/newview/llsidepanelappearance.h
@@ -55,7 +55,6 @@ public:
void fetchInventory();
void inventoryFetched();
- void onNewOutfitButtonClicked();
void showOutfitsInventoryPanel();
void showOutfitEditPanel();
@@ -84,7 +83,6 @@ private:
LLButton* mOpenOutfitBtn;
LLButton* mEditAppearanceBtn;
- LLButton* mNewOutfitBtn;
LLPanel* mCurrOutfitPanel;
LLTextBox* mCurrentLookName;
diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp
index e25cac8c17..689734e36a 100644
--- a/indra/newview/llsidepanelinventory.cpp
+++ b/indra/newview/llsidepanelinventory.cpp
@@ -177,9 +177,6 @@ BOOL LLSidepanelInventory::postBuild()
mTeleportBtn = mInventoryPanel->getChild<LLButton>("teleport_btn");
mTeleportBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onTeleportButtonClicked, this));
- mOverflowBtn = mInventoryPanel->getChild<LLButton>("overflow_btn");
- mOverflowBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onOverflowButtonClicked, this));
-
mPanelMainInventory = mInventoryPanel->getChild<LLPanelMainInventory>("panel_main_inventory");
mPanelMainInventory->setSelectCallback(boost::bind(&LLSidepanelInventory::onSelectionChange, this, _1, _2));
LLTabContainer* tabs = mPanelMainInventory->getChild<LLTabContainer>("inventory filter tabs");
@@ -515,10 +512,6 @@ void LLSidepanelInventory::onTeleportButtonClicked()
performActionOnSelection("teleport");
}
-void LLSidepanelInventory::onOverflowButtonClicked()
-{
-}
-
void LLSidepanelInventory::onBackButtonClicked()
{
showInventoryPanel();
diff --git a/indra/newview/llsidepanelinventory.h b/indra/newview/llsidepanelinventory.h
index 3b8cdb98ab..a3cd20a2c6 100644
--- a/indra/newview/llsidepanelinventory.h
+++ b/indra/newview/llsidepanelinventory.h
@@ -114,7 +114,6 @@ protected:
void onWearButtonClicked();
void onPlayButtonClicked();
void onTeleportButtonClicked();
- void onOverflowButtonClicked();
void onBackButtonClicked();
private:
@@ -123,7 +122,6 @@ private:
LLButton* mWearBtn;
LLButton* mPlayBtn;
LLButton* mTeleportBtn;
- LLButton* mOverflowBtn;
LLButton* mShopBtn;
bool mInboxEnabled;
diff --git a/indra/newview/llsidepanelinventorysubpanel.cpp b/indra/newview/llsidepanelinventorysubpanel.cpp
index 2918bb388a..3b73b6b7dd 100644
--- a/indra/newview/llsidepanelinventorysubpanel.cpp
+++ b/indra/newview/llsidepanelinventorysubpanel.cpp
@@ -50,8 +50,7 @@ LLSidepanelInventorySubpanel::LLSidepanelInventorySubpanel(const LLPanel::Params
: LLPanel(p),
mIsDirty(TRUE),
mIsEditing(FALSE),
- mCancelBtn(NULL),
- mSaveBtn(NULL)
+ mCancelBtn(NULL)
{
}
@@ -63,11 +62,12 @@ LLSidepanelInventorySubpanel::~LLSidepanelInventorySubpanel()
// virtual
BOOL LLSidepanelInventorySubpanel::postBuild()
{
- mSaveBtn = getChild<LLButton>("save_btn");
- mSaveBtn->setClickedCallback(boost::bind(&LLSidepanelInventorySubpanel::onSaveButtonClicked, this));
- mCancelBtn = getChild<LLButton>("cancel_btn");
- mCancelBtn->setClickedCallback(boost::bind(&LLSidepanelInventorySubpanel::onCancelButtonClicked, this));
+ mCancelBtn = findChild<LLButton>("cancel_btn");
+ if (mCancelBtn)
+ {
+ mCancelBtn->setClickedCallback(boost::bind(&LLSidepanelInventorySubpanel::onCancelButtonClicked, this));
+ }
return TRUE;
}
@@ -118,8 +118,10 @@ void LLSidepanelInventorySubpanel::dirty()
void LLSidepanelInventorySubpanel::updateVerbs()
{
- mSaveBtn->setVisible(mIsEditing);
- mCancelBtn->setVisible(mIsEditing);
+ if (mCancelBtn)
+ {
+ mCancelBtn->setVisible(mIsEditing);
+ }
}
void LLSidepanelInventorySubpanel::onEditButtonClicked()
@@ -129,14 +131,6 @@ void LLSidepanelInventorySubpanel::onEditButtonClicked()
updateVerbs();
}
-void LLSidepanelInventorySubpanel::onSaveButtonClicked()
-{
- save();
- setIsEditing(FALSE);
- refresh();
- updateVerbs();
-}
-
void LLSidepanelInventorySubpanel::onCancelButtonClicked()
{
setIsEditing(FALSE);
diff --git a/indra/newview/llsidepanelinventorysubpanel.h b/indra/newview/llsidepanelinventorysubpanel.h
index b5cf3aaf17..0d18943cbf 100644
--- a/indra/newview/llsidepanelinventorysubpanel.h
+++ b/indra/newview/llsidepanelinventorysubpanel.h
@@ -62,9 +62,7 @@ protected:
//
protected:
void onEditButtonClicked();
- void onSaveButtonClicked();
void onCancelButtonClicked();
- LLButton* mSaveBtn;
LLButton* mCancelBtn;
private:
diff --git a/indra/newview/llsidepaneliteminfo.cpp b/indra/newview/llsidepaneliteminfo.cpp
index 43e7e57814..a486a29aa2 100644
--- a/indra/newview/llsidepaneliteminfo.cpp
+++ b/indra/newview/llsidepaneliteminfo.cpp
@@ -441,7 +441,6 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item)
const std::string perm_and_sale_items[]={
"perms_inv",
- "OwnerLabel",
"perm_modify",
"CheckOwnerModify",
"CheckOwnerCopy",
@@ -455,10 +454,8 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item)
"CheckNextOwnerCopy",
"CheckNextOwnerTransfer",
"CheckPurchase",
- "SaleLabel",
"ComboBoxSaleType",
- "Edit Cost",
- "TextPrice"
+ "Edit Cost"
};
const std::string debug_items[]={
@@ -495,14 +492,6 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item)
///////////////////////
// OWNER PERMISSIONS //
///////////////////////
- if(can_agent_manipulate)
- {
- getChild<LLUICtrl>("OwnerLabel")->setValue(getString("you_can"));
- }
- else
- {
- getChild<LLUICtrl>("OwnerLabel")->setValue(getString("owner_can"));
- }
U32 base_mask = perm.getMaskBase();
U32 owner_mask = perm.getMaskOwner();
@@ -510,7 +499,6 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item)
U32 everyone_mask = perm.getMaskEveryone();
U32 next_owner_mask = perm.getMaskNextOwner();
- getChildView("OwnerLabel")->setEnabled(TRUE);
getChildView("CheckOwnerModify")->setEnabled(FALSE);
getChild<LLUICtrl>("CheckOwnerModify")->setValue(LLSD((BOOL)(owner_mask & PERM_MODIFY)));
getChildView("CheckOwnerCopy")->setEnabled(FALSE);
@@ -645,7 +633,6 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item)
if (is_obj_modify && can_agent_sell
&& gAgent.allowOperation(PERM_TRANSFER, perm, GP_OBJECT_MANIPULATE))
{
- getChildView("SaleLabel")->setEnabled(is_complete);
getChildView("CheckPurchase")->setEnabled(is_complete);
getChildView("NextOwnerLabel")->setEnabled(TRUE);
@@ -653,13 +640,11 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item)
getChildView("CheckNextOwnerCopy")->setEnabled((base_mask & PERM_COPY) && !cannot_restrict_permissions);
getChildView("CheckNextOwnerTransfer")->setEnabled((next_owner_mask & PERM_COPY) && !cannot_restrict_permissions);
- getChildView("TextPrice")->setEnabled(is_complete && is_for_sale);
combo_sale_type->setEnabled(is_complete && is_for_sale);
edit_cost->setEnabled(is_complete && is_for_sale);
}
else
{
- getChildView("SaleLabel")->setEnabled(FALSE);
getChildView("CheckPurchase")->setEnabled(FALSE);
getChildView("NextOwnerLabel")->setEnabled(FALSE);
@@ -667,7 +652,6 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item)
getChildView("CheckNextOwnerCopy")->setEnabled(FALSE);
getChildView("CheckNextOwnerTransfer")->setEnabled(FALSE);
- getChildView("TextPrice")->setEnabled(FALSE);
combo_sale_type->setEnabled(FALSE);
edit_cost->setEnabled(FALSE);
}
diff --git a/indra/newview/llsidepaneltaskinfo.cpp b/indra/newview/llsidepaneltaskinfo.cpp
index 403ca7bcbf..f73722521a 100644
--- a/indra/newview/llsidepaneltaskinfo.cpp
+++ b/indra/newview/llsidepaneltaskinfo.cpp
@@ -124,30 +124,24 @@ BOOL LLSidepanelTaskInfo::postBuild()
childSetCommitCallback("search_check", &LLSidepanelTaskInfo::onCommitIncludeInSearch,this);
mDAPermModify = getChild<LLUICtrl>("perm_modify");
- mDACreator = getChildView("Creator:");
mDACreatorName = getChild<LLUICtrl>("Creator Name");
mDAOwner = getChildView("Owner:");
mDAOwnerName = getChild<LLUICtrl>("Owner Name");
- mDAGroup = getChildView("Group:");
- mDAGroupName = getChild<LLUICtrl>("Group Name");
mDAButtonSetGroup = getChildView("button set group");
mDAObjectName = getChild<LLUICtrl>("Object Name");
mDAName = getChildView("Name:");
mDADescription = getChildView("Description:");
mDAObjectDescription = getChild<LLUICtrl>("Object Description");
- mDAPermissions = getChildView("Permissions:");
mDACheckboxShareWithGroup = getChild<LLUICtrl>("checkbox share with group");
mDAButtonDeed = getChildView("button deed");
mDACheckboxAllowEveryoneMove = getChild<LLUICtrl>("checkbox allow everyone move");
mDACheckboxAllowEveryoneCopy = getChild<LLUICtrl>("checkbox allow everyone copy");
- mDANextOwnerCan = getChildView("Next owner can:");
mDACheckboxNextOwnerCanModify = getChild<LLUICtrl>("checkbox next owner can modify");
mDACheckboxNextOwnerCanCopy = getChild<LLUICtrl>("checkbox next owner can copy");
mDACheckboxNextOwnerCanTransfer = getChild<LLUICtrl>("checkbox next owner can transfer");
mDACheckboxForSale = getChild<LLUICtrl>("checkbox for sale");
mDASearchCheck = getChild<LLUICtrl>("search_check");
mDAComboSaleType = getChild<LLComboBox>("sale type");
- mDACost = getChild<LLUICtrl>("Cost");
mDAEditCost = getChild<LLUICtrl>("Edit Cost");
mDALabelClickAction = getChildView("label click action");
mDAComboClickAction = getChild<LLComboBox>("clickaction");
@@ -183,7 +177,6 @@ void LLSidepanelTaskInfo::disableAll()
mDAPermModify->setEnabled(FALSE);
mDAPermModify->setValue(LLStringUtil::null);
- mDACreator->setEnabled(FALSE);
mDACreatorName->setValue(LLStringUtil::null);
mDACreatorName->setEnabled(FALSE);
@@ -191,21 +184,14 @@ void LLSidepanelTaskInfo::disableAll()
mDAOwnerName->setValue(LLStringUtil::null);
mDAOwnerName->setEnabled(FALSE);
- mDAGroup->setEnabled(FALSE);
- mDAGroupName->setValue(LLStringUtil::null);
- mDAGroupName->setEnabled(FALSE);
mDAButtonSetGroup->setEnabled(FALSE);
mDAObjectName->setValue(LLStringUtil::null);
mDAObjectName->setEnabled(FALSE);
mDAName->setEnabled(FALSE);
- mDAGroupName->setValue(LLStringUtil::null);
- mDAGroupName->setEnabled(FALSE);
mDADescription->setEnabled(FALSE);
mDAObjectDescription->setValue(LLStringUtil::null);
mDAObjectDescription->setEnabled(FALSE);
-
- mDAPermissions->setEnabled(FALSE);
mDACheckboxShareWithGroup->setValue(FALSE);
mDACheckboxShareWithGroup->setEnabled(FALSE);
@@ -217,7 +203,6 @@ void LLSidepanelTaskInfo::disableAll()
mDACheckboxAllowEveryoneCopy->setEnabled(FALSE);
//Next owner can:
- mDANextOwnerCan->setEnabled(FALSE);
mDACheckboxNextOwnerCanModify->setValue(FALSE);
mDACheckboxNextOwnerCanModify->setEnabled(FALSE);
mDACheckboxNextOwnerCanCopy->setValue(FALSE);
@@ -235,9 +220,7 @@ void LLSidepanelTaskInfo::disableAll()
mDAComboSaleType->setValue(LLSaleInfo::FS_COPY);
mDAComboSaleType->setEnabled(FALSE);
-
- mDACost->setEnabled(FALSE);
- mDACost->setValue(getString("Cost Default"));
+
mDAEditCost->setValue(LLStringUtil::null);
mDAEditCost->setEnabled(FALSE);
@@ -365,8 +348,6 @@ void LLSidepanelTaskInfo::refresh()
mDAPathfindingAttributes->setEnabled(TRUE);
mDAPathfindingAttributes->setValue(LLTrans::getString(pfAttrName));
-
- getChildView("Permissions:")->setEnabled(TRUE);
// Update creator text field
getChildView("Creator:")->setEnabled(TRUE);
@@ -698,7 +679,6 @@ void LLSidepanelTaskInfo::refresh()
getChild<LLUICtrl>("checkbox for sale")->setTentative( is_for_sale_mixed);
getChildView("sale type")->setEnabled(num_for_sale && can_transfer && !is_sale_price_mixed);
- getChildView("Next owner can:")->setEnabled(TRUE);
getChildView("checkbox next owner can modify")->setEnabled(base_mask_on & PERM_MODIFY);
getChildView("checkbox next owner can copy")->setEnabled(base_mask_on & PERM_COPY);
getChildView("checkbox next owner can transfer")->setEnabled(next_owner_mask_on & PERM_COPY);
@@ -708,7 +688,6 @@ void LLSidepanelTaskInfo::refresh()
getChildView("checkbox for sale")->setEnabled(FALSE);
getChildView("sale type")->setEnabled(FALSE);
- getChildView("Next owner can:")->setEnabled(FALSE);
getChildView("checkbox next owner can modify")->setEnabled(FALSE);
getChildView("checkbox next owner can copy")->setEnabled(FALSE);
getChildView("checkbox next owner can transfer")->setEnabled(FALSE);
diff --git a/indra/newview/llsidepaneltaskinfo.h b/indra/newview/llsidepaneltaskinfo.h
index a1479ef0e7..cbfb07874b 100644
--- a/indra/newview/llsidepaneltaskinfo.h
+++ b/indra/newview/llsidepaneltaskinfo.h
@@ -125,30 +125,24 @@ private:
private:
// Pointers cached here to speed up the "disableAll" function which gets called on idle
LLUICtrl* mDAPermModify;
- LLView* mDACreator;
LLUICtrl* mDACreatorName;
LLView* mDAOwner;
LLUICtrl* mDAOwnerName;
- LLView* mDAGroup;
- LLUICtrl* mDAGroupName;
LLView* mDAButtonSetGroup;
LLUICtrl* mDAObjectName;
LLView* mDAName;
LLView* mDADescription;
LLUICtrl* mDAObjectDescription;
- LLView* mDAPermissions;
LLUICtrl* mDACheckboxShareWithGroup;
LLView* mDAButtonDeed;
LLUICtrl* mDACheckboxAllowEveryoneMove;
LLUICtrl* mDACheckboxAllowEveryoneCopy;
- LLView* mDANextOwnerCan;
LLUICtrl* mDACheckboxNextOwnerCanModify;
LLUICtrl* mDACheckboxNextOwnerCanCopy;
LLUICtrl* mDACheckboxNextOwnerCanTransfer;
LLUICtrl* mDACheckboxForSale;
LLUICtrl* mDASearchCheck;
LLComboBox* mDAComboSaleType;
- LLUICtrl* mDACost;
LLUICtrl* mDAEditCost;
LLView* mDALabelClickAction;
LLComboBox* mDAComboClickAction;
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index d2a87ee2af..9791f4a921 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -3941,6 +3941,7 @@ LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector4a& start, co
LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,
LLViewerTexture* texture, LLVertexBuffer* buffer,
+ bool selected,
BOOL fullbright, U8 bump, BOOL particle, F32 part_size)
: LLTrace::MemTrackableNonVirtual<LLDrawInfo, 16>("LLDrawInfo"),
mVertexBuffer(buffer),
@@ -3968,7 +3969,8 @@ LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,
mHasGlow(FALSE),
mEnvIntensity(0.0f),
mAlphaMaskCutoff(0.5f),
- mDiffuseAlphaMode(0)
+ mDiffuseAlphaMode(0),
+ mSelected(selected)
{
mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset);
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index 7633e46200..6104b92d43 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -75,6 +75,7 @@ public:
LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,
LLViewerTexture* image, LLVertexBuffer* buffer,
+ bool selected,
BOOL fullbright = FALSE, U8 bump = 0, BOOL particle = FALSE, F32 part_size = 0);
@@ -117,6 +118,7 @@ public:
F32 mEnvIntensity;
F32 mAlphaMaskCutoff;
U8 mDiffuseAlphaMode;
+ bool mSelected;
struct CompareTexture
@@ -646,7 +648,7 @@ class LLVolumeGeometryManager: public LLGeometryManager
virtual void rebuildGeom(LLSpatialGroup* group);
virtual void rebuildMesh(LLSpatialGroup* group);
virtual void getGeometry(LLSpatialGroup* group);
- void genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE, BOOL no_materials = FALSE);
+ U32 genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE, BOOL no_materials = FALSE);
void registerFace(LLSpatialGroup* group, LLFace* facep, U32 type);
private:
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 8c5cad5af0..7a4c41779a 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -313,6 +313,13 @@ void set_flags_and_update_appearance()
// true when all initialization done.
bool idle_startup()
{
+ if (gViewerWindow == NULL)
+ {
+ // We expect window to be initialized
+ LL_WARNS_ONCE() << "gViewerWindow is not initialized" << LL_ENDL;
+ return false; // No world yet
+ }
+
const F32 PRECACHING_DELAY = gSavedSettings.getF32("PrecachingDelay");
static LLTimer timeout;
@@ -744,7 +751,6 @@ bool idle_startup()
if (gLoginMenuBarView == NULL)
{
LL_DEBUGS("AppInit") << "initializing menu bar" << LL_ENDL;
- initialize_edit_menu();
initialize_spellcheck_menu();
init_menus();
}
@@ -1151,7 +1157,7 @@ bool idle_startup()
}
}
- else
+ else if (!message.empty())
{
// This wasn't a certificate error, so throw up the normal
// notificatioin message.
diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp
index 72c5c961aa..43c0fbd53a 100644
--- a/indra/newview/llstatusbar.cpp
+++ b/indra/newview/llstatusbar.cpp
@@ -108,7 +108,6 @@ LLStatusBar::LLStatusBar(const LLRect& rect)
mTextTime(NULL),
mSGBandwidth(NULL),
mSGPacketLoss(NULL),
- mBtnStats(NULL),
mBtnVolume(NULL),
mBoxBalance(NULL),
mBalance(0),
@@ -168,8 +167,6 @@ BOOL LLStatusBar::postBuild()
mBoxBalance = getChild<LLTextBox>("balance");
mBoxBalance->setClickedCallback( &LLStatusBar::onClickBalance, this );
-
- mBtnStats = getChildView("stat_btn");
mIconPresets = getChild<LLIconCtrl>( "presets_icon" );
mIconPresets->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterPresets, this));
@@ -242,8 +239,6 @@ BOOL LLStatusBar::postBuild()
mPanelNearByMedia->setFollows(FOLLOWS_TOP|FOLLOWS_RIGHT);
mPanelNearByMedia->setVisible(FALSE);
- mScriptOut = getChildView("scriptout");
-
return TRUE;
}
@@ -297,7 +292,6 @@ void LLStatusBar::refresh()
mSGBandwidth->setVisible(net_stats_visible);
mSGPacketLoss->setVisible(net_stats_visible);
- mBtnStats->setEnabled(net_stats_visible);
// update the master volume button state
bool mute_audio = LLAppViewer::instance()->getMasterSystemAudioMute();
diff --git a/indra/newview/llstatusbar.h b/indra/newview/llstatusbar.h
index 277f039f20..a3326e752a 100644
--- a/indra/newview/llstatusbar.h
+++ b/indra/newview/llstatusbar.h
@@ -105,12 +105,10 @@ private:
LLStatGraph *mSGBandwidth;
LLStatGraph *mSGPacketLoss;
- LLView *mBtnStats;
LLIconCtrl *mIconPresets;
LLButton *mBtnVolume;
LLTextBox *mBoxBalance;
LLButton *mMediaToggle;
- LLView *mScriptOut;
LLFrameTimer mClockUpdateTimer;
S32 mBalance;
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index dadf2f9701..2a0d961952 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -117,7 +117,7 @@ public:
~LLTextureCacheWorker()
{
llassert_always(!haveWork());
- FREE_MEM(LLImageBase::getPrivatePool(), mReadData);
+ ll_aligned_free_16(mReadData);
}
// override this interface
@@ -237,7 +237,7 @@ bool LLTextureCacheLocalFileWorker::doRead()
// << " Bytes: " << mDataSize << " Offset: " << mOffset
// << " / " << mDataSize << LL_ENDL;
mDataSize = 0; // failed
- FREE_MEM(LLImageBase::getPrivatePool(), mReadData);
+ ll_aligned_free_16(mReadData);
mReadData = NULL;
}
return true;
@@ -252,7 +252,7 @@ bool LLTextureCacheLocalFileWorker::doRead()
{
mDataSize = local_size;
}
- mReadData = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), mDataSize);
+ mReadData = (U8*)ll_aligned_malloc_16(mDataSize);
S32 bytes_read = LLAPRFile::readEx(mFileName, mReadData, mOffset, mDataSize, mCache->getLocalAPRFilePool());
@@ -262,7 +262,7 @@ bool LLTextureCacheLocalFileWorker::doRead()
// << " Bytes: " << mDataSize << " Offset: " << mOffset
// << " / " << mDataSize << LL_ENDL;
mDataSize = 0;
- FREE_MEM(LLImageBase::getPrivatePool(), mReadData);
+ ll_aligned_free_16(mReadData);
mReadData = NULL;
}
else
@@ -386,7 +386,7 @@ bool LLTextureCacheRemoteWorker::doRead()
mDataSize = local_size;
}
// Allocate read buffer
- mReadData = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), mDataSize);
+ mReadData = (U8*)ll_aligned_malloc_16(mDataSize);
if (mReadData)
{
@@ -402,7 +402,7 @@ bool LLTextureCacheRemoteWorker::doRead()
<< " Bytes: " << mDataSize << " Offset: " << mOffset
<< " / " << mDataSize << LL_ENDL;
mDataSize = 0;
- FREE_MEM(LLImageBase::getPrivatePool(), mReadData);
+ ll_aligned_free_16(mReadData);
mReadData = NULL;
}
else
@@ -451,7 +451,7 @@ bool LLTextureCacheRemoteWorker::doRead()
S32 size = TEXTURE_CACHE_ENTRY_SIZE - mOffset;
size = llmin(size, mDataSize);
// Allocate the read buffer
- mReadData = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), size);
+ mReadData = (U8*)ll_aligned_malloc_16(size);
if (mReadData)
{
S32 bytes_read = LLAPRFile::readEx(mCache->mHeaderDataFileName,
@@ -461,7 +461,7 @@ bool LLTextureCacheRemoteWorker::doRead()
LL_WARNS() << "LLTextureCacheWorker: " << mID
<< " incorrect number of bytes read from header: " << bytes_read
<< " / " << size << LL_ENDL;
- FREE_MEM(LLImageBase::getPrivatePool(), mReadData);
+ ll_aligned_free_16(mReadData);
mReadData = NULL;
mDataSize = -1; // failed
done = true;
@@ -500,7 +500,7 @@ bool LLTextureCacheRemoteWorker::doRead()
S32 data_offset, file_size, file_offset;
// Reserve the whole data buffer first
- U8* data = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), mDataSize);
+ U8* data = (U8*)ll_aligned_malloc_16(mDataSize);
if (data)
{
// Set the data file pointers taking the read offset into account. 2 cases:
@@ -514,7 +514,7 @@ bool LLTextureCacheRemoteWorker::doRead()
// Copy the raw data we've been holding from the header cache into the new sized buffer
llassert_always(mReadData);
memcpy(data, mReadData, data_offset);
- FREE_MEM(LLImageBase::getPrivatePool(), mReadData);
+ ll_aligned_free_16(mReadData);
mReadData = NULL;
}
else
@@ -540,7 +540,7 @@ bool LLTextureCacheRemoteWorker::doRead()
LL_WARNS() << "LLTextureCacheWorker: " << mID
<< " incorrect number of bytes read from body: " << bytes_read
<< " / " << file_size << LL_ENDL;
- FREE_MEM(LLImageBase::getPrivatePool(), mReadData);
+ ll_aligned_free_16(mReadData);
mReadData = NULL;
mDataSize = -1; // failed
done = true;
@@ -550,7 +550,7 @@ bool LLTextureCacheRemoteWorker::doRead()
{
LL_WARNS() << "LLTextureCacheWorker: " << mID
<< " failed to allocate memory for reading: " << mDataSize << LL_ENDL;
- FREE_MEM(LLImageBase::getPrivatePool(), mReadData);
+ ll_aligned_free_16(mReadData);
mReadData = NULL;
mDataSize = -1; // failed
done = true;
@@ -673,11 +673,11 @@ bool LLTextureCacheRemoteWorker::doWrite()
{
// We need to write a full record in the header cache so, if the amount of data is smaller
// than a record, we need to transfer the data to a buffer padded with 0 and write that
- U8* padBuffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), TEXTURE_CACHE_ENTRY_SIZE);
+ U8* padBuffer = (U8*)ll_aligned_malloc_16(TEXTURE_CACHE_ENTRY_SIZE);
memset(padBuffer, 0, TEXTURE_CACHE_ENTRY_SIZE); // Init with zeros
memcpy(padBuffer, mWriteData, mDataSize); // Copy the write buffer
bytes_written = LLAPRFile::writeEx(mCache->mHeaderDataFileName, padBuffer, offset, size, mCache->getLocalAPRFilePool());
- FREE_MEM(LLImageBase::getPrivatePool(), padBuffer);
+ ll_aligned_free_16(padBuffer);
}
else
{
@@ -783,7 +783,7 @@ void LLTextureCacheWorker::finishWork(S32 param, bool completed)
}
else
{
- FREE_MEM(LLImageBase::getPrivatePool(), mReadData);
+ ll_aligned_free_16(mReadData);
mReadData = NULL;
}
}
@@ -845,7 +845,7 @@ LLTextureCache::~LLTextureCache()
writeUpdatedEntries() ;
delete mFastCachep;
delete mFastCachePoolp;
- FREE_MEM(LLImageBase::getPrivatePool(), mFastCachePadBuffer);
+ ll_aligned_free_16(mFastCachePadBuffer);
}
//////////////////////////////////////////////////////////////////////////////
@@ -1983,10 +1983,10 @@ LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& d
}
discardlevel = head[3];
- data = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), image_size);
+ data = (U8*)ll_aligned_malloc_16(image_size);
if(mFastCachep->read(data, image_size) != image_size)
{
- FREE_MEM(LLImageBase::getPrivatePool(), data);
+ ll_aligned_free_16(data);
closeFastCache();
return NULL;
}
@@ -2078,7 +2078,7 @@ void LLTextureCache::openFastCache(bool first_time)
{
if(!mFastCachePadBuffer)
{
- mFastCachePadBuffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), TEXTURE_FAST_CACHE_ENTRY_SIZE);
+ mFastCachePadBuffer = (U8*)ll_aligned_malloc_16(TEXTURE_FAST_CACHE_ENTRY_SIZE);
}
mFastCachePoolp = new LLVolatileAPRPool();
if (LLAPRFile::isExist(mFastCacheFileName, mFastCachePoolp))
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index c7adaa908f..a5a2eec246 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -990,6 +990,7 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p)
mOnSelectCallback(NULL),
mBorderColor( p.border_color() ),
mAllowNoTexture( FALSE ),
+ mAllowLocalTexture( TRUE ),
mImmediateFilterPermMask( PERM_NONE ),
mNonImmediateFilterPermMask( PERM_NONE ),
mCanApplyImmediately( FALSE ),
@@ -1198,6 +1199,12 @@ void LLTextureCtrl::showPicker(BOOL take_focus)
floaterp->openFloater();
}
+ LLFloaterTexturePicker* picker_floater = dynamic_cast<LLFloaterTexturePicker*>(floaterp);
+ if (picker_floater)
+ {
+ picker_floater->setLocalTextureEnabled(mAllowLocalTexture);
+ }
+
if (take_focus)
{
floaterp->setFocus(TRUE);
diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h
index 840feddfaf..6bcf9c3a75 100644
--- a/indra/newview/lltexturectrl.h
+++ b/indra/newview/lltexturectrl.h
@@ -142,6 +142,9 @@ public:
void setAllowNoTexture( BOOL b ) { mAllowNoTexture = b; }
bool getAllowNoTexture() const { return mAllowNoTexture; }
+ void setAllowLocalTexture(BOOL b) { mAllowLocalTexture = b; }
+ BOOL getAllowLocalTexture() const { return mAllowLocalTexture; }
+
const LLUUID& getImageItemID() { return mImageItemID; }
virtual void setImageAssetName(const std::string& name);
@@ -222,6 +225,7 @@ private:
LLTextBox* mCaption;
std::string mLabel;
BOOL mAllowNoTexture; // If true, the user can select "none" as an option
+ BOOL mAllowLocalTexture;
PermissionMask mImmediateFilterPermMask;
PermissionMask mDnDFilterPermMask;
PermissionMask mNonImmediateFilterPermMask;
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index 1f7796e6d0..1f69939c46 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -1761,7 +1761,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
mRequestedOffset += src_offset;
}
- U8 * buffer = (U8 *)ALLOCATE_MEM(LLImageBase::getPrivatePool(), total_size);
+ U8 * buffer = (U8 *)ll_aligned_malloc_16(total_size);
if (!buffer)
{
// abort. If we have no space for packet, we have not enough space to decode image
@@ -2266,7 +2266,7 @@ bool LLTextureFetchWorker::processSimulatorPackets()
if (buffer_size > cur_size)
{
/// We have new data
- U8* buffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), buffer_size);
+ U8* buffer = (U8*)ll_aligned_malloc_16(buffer_size);
S32 offset = 0;
if (cur_size > 0 && mFirstPacket > 0)
{
@@ -3082,7 +3082,7 @@ void LLTextureFetch::commonUpdate()
//virtual
S32 LLTextureFetch::update(F32 max_time_ms)
{
- static LLCachedControl<F32> band_width(gSavedSettings,"ThrottleBandwidthKBPS", 500.0);
+ static LLCachedControl<F32> band_width(gSavedSettings,"ThrottleBandwidthKBPS", 3000.0);
{
mNetworkQueueMutex.lock(); // +Mfnq
@@ -5059,7 +5059,7 @@ void LLTextureFetchDebugger::callbackHTTP(FetchEntry & fetch, LLCore::HttpRespon
//LL_INFOS(LOG_TXT) << "Fetch Debugger : got results for " << fetch.mID << ", data_size = " << data_size << ", received = " << fetch.mCurlReceivedSize << ", requested = " << fetch.mRequestedSize << ", partial = " << partial << LL_ENDL;
if ((fetch.mCurlReceivedSize >= fetch.mRequestedSize) || !partial || (fetch.mRequestedSize == 600))
{
- U8* d_buffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), data_size);
+ U8* d_buffer = (U8*)ll_aligned_malloc_16(data_size);
if (ba)
{
ba->read(0, d_buffer, data_size);
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index 6da13da58c..d7b95db94f 100644
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -173,9 +173,9 @@ void LLTextureBar::draw()
{
color = LLColor4::green4;
}
- else if (mImagep->getBoostLevel() > LLGLTexture::BOOST_NONE)
+ else if (mImagep->getBoostLevel() > LLGLTexture::BOOST_ALM)
{
- color = LLColor4::magenta;
+ color = LLColor4::magenta; // except none and alm
}
else if (mImagep->getDecodePriority() <= 0.0f)
{
diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp
index edde7c8076..b9b05966bc 100644
--- a/indra/newview/lltoast.cpp
+++ b/indra/newview/lltoast.cpp
@@ -34,6 +34,7 @@
#include "llviewercontrol.h"
using namespace LLNotificationsUI;
+std::list<LLToast*> LLToast::sModalToastsList;
//--------------------------------------------------------------------------
LLToastLifeTimer::LLToastLifeTimer(LLToast* toast, F32 period)
@@ -143,6 +144,11 @@ LLToast::LLToast(const LLToast::Params& p)
{
mOnDeleteToastSignal.connect(p.on_delete_toast());
}
+
+ if (isModal())
+ {
+ sModalToastsList.push_front(this);
+ }
}
void LLToast::reshape(S32 width, S32 height, BOOL called_from_parent)
@@ -187,6 +193,15 @@ LLToast::~LLToast()
{
mOnToastDestroyedSignal(this);
}
+
+ if (isModal())
+ {
+ std::list<LLToast*>::iterator iter = std::find(sModalToastsList.begin(), sModalToastsList.end(), this);
+ if (iter != sModalToastsList.end())
+ {
+ sModalToastsList.erase(iter);
+ }
+ }
}
//--------------------------------------------------------------------------
diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h
index cd92189012..69074b1670 100644
--- a/indra/newview/lltoast.h
+++ b/indra/newview/lltoast.h
@@ -108,6 +108,8 @@ public:
static void updateClass();
static void cleanupToasts();
+ static BOOL isAlertToastShown() { return sModalToastsList.size() > 0; }
+
LLToast(const LLToast::Params& p);
virtual ~LLToast();
BOOL postBuild();
@@ -245,6 +247,8 @@ private:
commit_signal_t mToastMouseEnterSignal;
commit_signal_t mToastMouseLeaveSignal;
+
+ static std::list<LLToast*> sModalToastsList;
};
}
diff --git a/indra/newview/lltoastimpanel.cpp b/indra/newview/lltoastimpanel.cpp
index 39adfb3431..c4c4b13a2f 100644
--- a/indra/newview/lltoastimpanel.cpp
+++ b/indra/newview/lltoastimpanel.cpp
@@ -65,14 +65,9 @@ LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) : LLToastPanel(p.notif
LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(p.session_id);
mIsGroupMsg = (im_session && im_session->mSessionType == LLIMModel::LLIMSession::GROUP_SESSION);
- if(mIsGroupMsg)
- {
- mAvatarName->setValue(im_session->mName);
- LLAvatarName avatar_name;
- LLAvatarNameCache::get(p.avatar_id, &avatar_name);
- p.message = "[From " + avatar_name.getDisplayName() + "]\n" + p.message;
- }
-
+ std::string title = mIsGroupMsg ? im_session->mName : p.from;
+ mAvatarName->setValue(title);
+
//Handle IRC styled /me messages.
std::string prefix = p.message.substr(0, 4);
if (prefix == "/me " || prefix == "/me'")
@@ -88,14 +83,16 @@ LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) : LLToastPanel(p.notif
}
else
{
+ if (mIsGroupMsg)
+ {
+ LLAvatarName avatar_name;
+ LLAvatarNameCache::get(p.avatar_id, &avatar_name);
+ p.message = "[From " + avatar_name.getDisplayName() + "]\n" + p.message;
+ }
style_params.font.style = "NORMAL";
mMessage->setText(p.message, style_params);
}
- if(!mIsGroupMsg)
- {
- mAvatarName->setValue(p.from);
- }
mTime->setValue(p.time);
mSessionID = p.session_id;
mAvatarID = p.avatar_id;
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index bd68d8c999..9fb53dc9ab 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -1278,7 +1278,6 @@ void LLToolDragAndDrop::dropObject(LLViewerObject* raycast_target,
if (gInventory.isObjectDescendentOf(item->getUUID(), trash_id))
{
is_in_trash = true;
- remove_from_inventory = TRUE;
}
LLUUID source_id = from_task_inventory ? mSourceID : LLUUID::null;
@@ -1806,7 +1805,6 @@ EAcceptance LLToolDragAndDrop::dad3dRezObjectOnLand(
if(gInventory.isObjectDescendentOf(item->getUUID(), trash_id))
{
accept = ACCEPT_YES_SINGLE;
- remove_inventory = TRUE;
}
if(drop)
diff --git a/indra/newview/lltoolfocus.cpp b/indra/newview/lltoolfocus.cpp
index caa055e5e0..596951fdfb 100644
--- a/indra/newview/lltoolfocus.cpp
+++ b/indra/newview/lltoolfocus.cpp
@@ -222,8 +222,10 @@ void LLToolCamera::pickCallback(const LLPickInfo& pick_info)
gAgentCamera.setFocusGlobal(pick_info);
}
+ BOOL zoom_tool = gCameraBtnZoom && (LLToolMgr::getInstance()->getBaseTool() == LLToolCamera::getInstance());
if (!(pick_info.mKeyMask & MASK_ALT) &&
!LLFloaterCamera::inFreeCameraMode() &&
+ !zoom_tool &&
gAgentCamera.cameraThirdPerson() &&
gViewerWindow->getLeftMouseDown() &&
!gSavedSettings.getBOOL("FreezeTime") &&
diff --git a/indra/newview/lltoolselect.cpp b/indra/newview/lltoolselect.cpp
index 1fcc9a0711..c22eb48eef 100644
--- a/indra/newview/lltoolselect.cpp
+++ b/indra/newview/lltoolselect.cpp
@@ -52,6 +52,7 @@
//extern BOOL gAllowSelectAvatar;
const F32 SELECTION_ROTATION_TRESHOLD = 0.1f;
+const F32 SELECTION_SITTING_ROTATION_TRESHOLD = 3.2f; //radian
LLToolSelect::LLToolSelect( LLToolComposite* composite )
: LLTool( std::string("Select"), composite ),
@@ -194,7 +195,13 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi
{
LLQuaternion target_rot;
target_rot.shortestArc(LLVector3::x_axis, selection_dir);
- gAgent.startAutoPilotGlobal(gAgent.getPositionGlobal(), "", &target_rot, NULL, NULL, 1.f, SELECTION_ROTATION_TRESHOLD);
+ gAgent.startAutoPilotGlobal(gAgent.getPositionGlobal(),
+ "",
+ &target_rot,
+ NULL,
+ NULL,
+ MAX_FAR_CLIP /*stop_distance, don't care since we are looking, not moving*/,
+ gAgentAvatarp->isSitting() ? SELECTION_SITTING_ROTATION_TRESHOLD : SELECTION_ROTATION_TRESHOLD);
}
}
diff --git a/indra/newview/lltwitterconnect.cpp b/indra/newview/lltwitterconnect.cpp
index 9b7c13b57d..5d598aaebe 100644
--- a/indra/newview/lltwitterconnect.cpp
+++ b/indra/newview/lltwitterconnect.cpp
@@ -380,13 +380,10 @@ LLTwitterConnect::LLTwitterConnect()
void LLTwitterConnect::openTwitterWeb(std::string url)
{
- // Open the URL in an internal browser window without navigation UI
LLFloaterWebContent::Params p;
p.url(url);
p.show_chrome(true);
- p.allow_address_entry(false);
p.allow_back_forward_navigation(false);
- p.trusted_content(true);
p.clean_browser(true);
LLFloater *floater = LLFloaterReg::showInstance("twitter_web", p);
//the internal web browser has a bug that prevents it from gaining focus unless a mouse event occurs first (it seems).
diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp
index 4f68c9a98e..4e13eceb55 100644
--- a/indra/newview/llviewerassetupload.cpp
+++ b/indra/newview/llviewerassetupload.cpp
@@ -39,6 +39,7 @@
#include "lleconomy.h"
#include "llagent.h"
#include "llfloaterreg.h"
+#include "llfloatersnapshot.h"
#include "llstatusbar.h"
#include "llinventorypanel.h"
#include "llsdutil.h"
@@ -765,14 +766,7 @@ void LLViewerAssetUpload::AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCorouti
// Show the preview panel for textures and sounds to let
// user know that the image (or snapshot) arrived intact.
LLInventoryPanel* panel = LLInventoryPanel::getActiveInventoryPanel(FALSE);
- if (panel)
- {
- panel->setSelection(serverInventoryItem, TAKE_FOCUS_NO);
- }
- else
- {
- LLInventoryPanel::openInventoryPanelAndSetSelection(TRUE, serverInventoryItem, TRUE, TAKE_FOCUS_NO, TRUE);
- }
+ LLInventoryPanel::openInventoryPanelAndSetSelection(TRUE, serverInventoryItem, TRUE, TAKE_FOCUS_NO, (panel == NULL));
// restore keyboard focus
gFocusMgr.setKeyboardFocus(focus);
@@ -863,11 +857,19 @@ void LLViewerAssetUpload::HandleUploadError(LLCore::HttpStatus status, LLSD &res
}
// Let the Snapshot floater know we have failed uploading.
- LLFloater* floater_snapshot = LLFloaterReg::findInstance("snapshot");
- if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE && floater_snapshot && floater_snapshot->isShown())
+ LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::findInstance();
+ if (floater_snapshot && floater_snapshot->isWaitingState())
{
- floater_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", false).with("msg", "inventory")));
+ if (uploadInfo->getAssetType() == LLAssetType::AT_IMAGE_JPEG)
+ {
+ floater_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", false).with("msg", "postcard")));
+ }
+ if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE)
+ {
+ floater_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", false).with("msg", "inventory")));
+ }
}
+
LLFloater* floater_outfit_snapshot = LLFloaterReg::findInstance("outfit_snapshot");
if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE && floater_outfit_snapshot && floater_outfit_snapshot->isShown())
{
diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp
index 57a0195d23..778e275727 100644
--- a/indra/newview/llviewercamera.cpp
+++ b/indra/newview/llviewercamera.cpp
@@ -113,6 +113,7 @@ LLViewerCamera::LLViewerCamera() : LLCamera()
{
calcProjection(getFar());
mCameraFOVDefault = DEFAULT_FIELD_OF_VIEW;
+ mPrevCameraFOVDefault = DEFAULT_FIELD_OF_VIEW;
mCosHalfCameraFOV = cosf(mCameraFOVDefault * 0.5f);
mPixelMeterRatio = 0.f;
mScreenPixelArea = 0;
@@ -882,6 +883,15 @@ void LLViewerCamera::setDefaultFOV(F32 vertical_fov_rads)
mCosHalfCameraFOV = cosf(mCameraFOVDefault * 0.5f);
}
+BOOL LLViewerCamera::isDefaultFOVChanged()
+{
+ if(mPrevCameraFOVDefault != mCameraFOVDefault)
+ {
+ mPrevCameraFOVDefault = mCameraFOVDefault;
+ return !gSavedSettings.getBOOL("IgnoreFOVZoomForLODs");
+ }
+ return FALSE;
+}
// static
void LLViewerCamera::updateCameraAngle( void* user_data, const LLSD& value)
diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h
index f8c973690a..5901de289f 100644
--- a/indra/newview/llviewercamera.h
+++ b/indra/newview/llviewercamera.h
@@ -115,6 +115,8 @@ public:
void setDefaultFOV(F32 fov) ;
F32 getDefaultFOV() { return mCameraFOVDefault; }
+ BOOL isDefaultFOVChanged();
+
BOOL cameraUnderWater() const;
BOOL areVertsVisible(LLViewerObject* volumep, BOOL all_verts);
@@ -138,6 +140,7 @@ protected:
mutable LLMatrix4 mProjectionMatrix; // Cache of perspective matrix
mutable LLMatrix4 mModelviewMatrix;
F32 mCameraFOVDefault;
+ F32 mPrevCameraFOVDefault;
F32 mCosHalfCameraFOV;
LLVector3 mLastPointOfInterest;
F32 mPixelMeterRatio; // Divide by distance from camera to get pixels per meter at that distance.
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index d9d66ef254..88984d518a 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -126,6 +126,16 @@ static bool handleDebugAvatarJointsChanged(const LLSD& newvalue)
return true;
}
+static bool handleAvatarHoverOffsetChanged(const LLSD& newvalue)
+{
+ if (isAgentAvatarValid())
+ {
+ gAgentAvatarp->setHoverIfRegionEnabled();
+ }
+ return true;
+}
+
+
static bool handleSetShaderChanged(const LLSD& newvalue)
{
// changing shader level may invalidate existing cached bump maps, as the shader type determines the format of the bump map it expects - clear and repopulate the bump cache
@@ -582,6 +592,7 @@ bool toggle_show_object_render_cost(const LLSD& newvalue)
return true;
}
+void handleRenderAutoMuteByteLimitChanged(const LLSD& new_value);
////////////////////////////////////////////////////////////////////////////
void settings_setup_listeners()
@@ -734,7 +745,9 @@ void settings_setup_listeners()
gSavedSettings.getControl("SpellCheck")->getSignal()->connect(boost::bind(&handleSpellCheckChanged));
gSavedSettings.getControl("SpellCheckDictionary")->getSignal()->connect(boost::bind(&handleSpellCheckChanged));
gSavedSettings.getControl("LoginLocation")->getSignal()->connect(boost::bind(&handleLoginLocationChanged));
- gSavedSettings.getControl("DebugAvatarJoints")->getCommitSignal()->connect(boost::bind(&handleDebugAvatarJointsChanged, _2));
+ gSavedSettings.getControl("DebugAvatarJoints")->getCommitSignal()->connect(boost::bind(&handleDebugAvatarJointsChanged, _2));
+ gSavedSettings.getControl("RenderAutoMuteByteLimit")->getSignal()->connect(boost::bind(&handleRenderAutoMuteByteLimitChanged, _2));
+ gSavedPerAccountSettings.getControl("AvatarHoverOffsetZ")->getCommitSignal()->connect(boost::bind(&handleAvatarHoverOffsetChanged, _2));
}
#if TEST_CACHED_CONTROL
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 96ef160c72..86a9e7e2ad 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -1005,7 +1005,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
gPipeline.mDeferredScreen.getHeight(), 0, 0,
gPipeline.mDeferredScreen.getWidth(),
gPipeline.mDeferredScreen.getHeight(),
- GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+ GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
}
}
else
@@ -1017,7 +1017,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
gPipeline.mScreen.getHeight(), 0, 0,
gPipeline.mScreen.getWidth(),
gPipeline.mScreen.getHeight(),
- GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+ GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
}
}
}
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 0ebacddd9b..55317bdaf5 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -34,7 +34,6 @@
#include "llcompilequeue.h"
#include "llfasttimerview.h"
#include "llfloaterabout.h"
-#include "llfloaterauction.h"
#include "llfloaterautoreplacesettings.h"
#include "llfloateravatar.h"
#include "llfloateravatarpicker.h"
@@ -194,7 +193,6 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("about_land", "floater_about_land.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLand>);
LLFloaterReg::add("appearance", "floater_my_appearance.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
LLFloaterReg::add("associate_listing", "floater_associate_listing.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAssociateListing>);
- LLFloaterReg::add("auction", "floater_auction.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAuction>);
LLFloaterReg::add("avatar", "floater_avatar.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatar>);
LLFloaterReg::add("avatar_picker", "floater_avatar_picker.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatarPicker>);
LLFloaterReg::add("avatar_render_settings", "floater_avatar_render_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatarRenderSettings>);
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 422c1a2328..4334cbfda3 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -55,6 +55,7 @@
#include "llversioninfo.h"
#include "llviewermediafocus.h"
#include "llviewercontrol.h"
+#include "llviewermenufile.h" // LLFilePickerThread
#include "llviewernetwork.h"
#include "llviewerparcelmedia.h"
#include "llviewerparcelmgr.h"
@@ -82,6 +83,43 @@
/*static*/ const char* LLViewerMedia::SHOW_MEDIA_OUTSIDE_PARCEL_SETTING = "MediaShowOutsideParcel";
+class LLMediaFilePicker : public LLFilePickerThread // deletes itself when done
+{
+public:
+ LLMediaFilePicker(LLPluginClassMedia* plugin, LLFilePicker::ELoadFilter filter, bool get_multiple)
+ : LLFilePickerThread(filter, get_multiple),
+ mPlugin(plugin->getSharedPrt())
+ {
+ }
+
+ LLMediaFilePicker(LLPluginClassMedia* plugin, LLFilePicker::ESaveFilter filter, const std::string &proposed_name)
+ : LLFilePickerThread(filter, proposed_name),
+ mPlugin(plugin->getSharedPrt())
+ {
+ }
+
+ virtual void notify(const std::vector<std::string>& filenames)
+ {
+ mPlugin->sendPickFileResponse(mResponses);
+ mPlugin = NULL;
+ }
+
+private:
+ boost::shared_ptr<LLPluginClassMedia> mPlugin;
+};
+
+void init_threaded_picker_load_dialog(LLPluginClassMedia* plugin, LLFilePicker::ELoadFilter filter, bool get_multiple)
+{
+ (new LLMediaFilePicker(plugin, filter, get_multiple))->getFile(); // will delete itself
+}
+
+void init_threaded_picker_save_dialog(LLPluginClassMedia* plugin, LLFilePicker::ESaveFilter filter, std::string &proposed_name)
+{
+ (new LLMediaFilePicker(plugin, filter, proposed_name))->getFile(); // will delete itself
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
// Move this to its own file.
LLViewerMediaEventEmitter::~LLViewerMediaEventEmitter()
@@ -1647,8 +1685,7 @@ void LLViewerMediaImpl::destroyMediaSource()
if(mMediaSource)
{
mMediaSource->setDeleteOK(true) ;
- delete mMediaSource;
- mMediaSource = NULL;
+ mMediaSource = NULL; // shared pointer
}
}
@@ -1829,7 +1866,7 @@ bool LLViewerMediaImpl::initializePlugin(const std::string& media_type)
// the correct way to deal with certs it to load ours from ca-bundle.crt and append them to the ones
// Qt/WebKit loads from your system location.
- std::string ca_path = gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "ca-bundle.crt" );
+ std::string ca_path = gDirUtilp->getCAFile();
media_source->addCertificateFilePath( ca_path );
media_source->proxy_setup(gSavedSettings.getBOOL("BrowserProxyEnabled"), gSavedSettings.getString("BrowserProxyAddress"), gSavedSettings.getS32("BrowserProxyPort"));
@@ -1840,7 +1877,7 @@ bool LLViewerMediaImpl::initializePlugin(const std::string& media_type)
media_source->clear_cache();
}
- mMediaSource = media_source;
+ mMediaSource.reset(media_source);
mMediaSource->setDeleteOK(false) ;
updateVolume();
@@ -3274,37 +3311,9 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla
case LLViewerMediaObserver::MEDIA_EVENT_PICK_FILE_REQUEST:
{
- LLFilePicker& picker = LLFilePicker::instance();
- std::vector<std::string> responses;
-
- bool pick_multiple_files = plugin->getIsMultipleFilePick();
- if (pick_multiple_files == false)
- {
- picker.getOpenFile(LLFilePicker::FFLOAD_ALL);
-
- std::string filename = picker.getFirstFile();
- responses.push_back(filename);
- }
- else
- {
- if (picker.getMultipleOpenFiles())
- {
- std::string filename = picker.getFirstFile();
-
- responses.push_back(filename);
-
- while (!filename.empty())
- {
- filename = picker.getNextFile();
+ LL_DEBUGS("Media") << "Media event - file pick requested." << LL_ENDL;
- if (!filename.empty())
- {
- responses.push_back(filename);
- }
- }
- }
- }
- plugin->sendPickFileResponse(responses);
+ init_threaded_picker_load_dialog(plugin, LLFilePicker::FFLOAD_ALL, plugin->getIsMultipleFilePick());
}
break;
diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h
index 6e18c4fecb..c52960dfcf 100644
--- a/indra/newview/llviewermedia.h
+++ b/indra/newview/llviewermedia.h
@@ -202,7 +202,7 @@ public:
bool initializeMedia(const std::string& mime_type);
bool initializePlugin(const std::string& media_type);
void loadURI();
- LLPluginClassMedia* getMediaPlugin() { return mMediaSource; }
+ LLPluginClassMedia* getMediaPlugin() { return mMediaSource.get(); }
void setSize(int width, int height);
void showNotification(LLNotificationPtr notify);
@@ -417,7 +417,7 @@ private:
private:
// a single media url with some data and an impl.
- LLPluginClassMedia* mMediaSource;
+ boost::shared_ptr<LLPluginClassMedia> mMediaSource;
F64 mZoomFactor;
LLUUID mTextureId;
bool mMovieImageHasMips;
diff --git a/indra/newview/llviewermediafocus.cpp b/indra/newview/llviewermediafocus.cpp
index 7b4df3d3da..59165c1d71 100644
--- a/indra/newview/llviewermediafocus.cpp
+++ b/indra/newview/llviewermediafocus.cpp
@@ -82,7 +82,7 @@ void LLViewerMediaFocus::setFocusFace(LLPointer<LLViewerObject> objectp, S32 fac
if (media_impl.notNull() && objectp.notNull())
{
bool face_auto_zoom = false;
-
+ mPrevFocusedImplID = LLUUID::null;
mFocusedImplID = media_impl->getMediaTextureID();
mFocusedObjectID = objectp->getID();
mFocusedObjectFace = face;
@@ -403,6 +403,7 @@ void LLViewerMediaFocus::update()
else
{
// Someone else has focus -- back off.
+ mPrevFocusedImplID = mFocusedImplID;
clearFocus();
}
}
@@ -602,6 +603,15 @@ bool LLViewerMediaFocus::isZoomed() const
return (mMediaControls.get() && mMediaControls.get()->getZoomLevel() != LLPanelPrimMediaControls::ZOOM_NONE);
}
+bool LLViewerMediaFocus::isZoomedOnMedia(LLUUID media_id)
+{
+ if (isZoomed())
+ {
+ return (mFocusedImplID == media_id) || (mPrevFocusedImplID == media_id);
+ }
+ return false;
+}
+
LLUUID LLViewerMediaFocus::getControlsMediaID()
{
if(getFocusedMediaImpl())
diff --git a/indra/newview/llviewermediafocus.h b/indra/newview/llviewermediafocus.h
index 368c671f84..763a6c1688 100644
--- a/indra/newview/llviewermediafocus.h
+++ b/indra/newview/llviewermediafocus.h
@@ -83,6 +83,7 @@ public:
void focusZoomOnMedia(LLUUID media_id);
// Are we zoomed in?
bool isZoomed() const;
+ bool isZoomedOnMedia(LLUUID media_id);
void unZoom();
// Return the ID of the media instance the controls are currently attached to (either focus or hover).
@@ -104,6 +105,7 @@ private:
LLUUID mFocusedObjectID;
S32 mFocusedObjectFace;
LLUUID mFocusedImplID;
+ LLUUID mPrevFocusedImplID;
LLVector3 mFocusedObjectNormal;
LLUUID mHoverObjectID;
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 5bbf5650ad..0eebf2051c 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -7976,6 +7976,23 @@ void handle_web_browser_test(const LLSD& param)
LLWeb::loadURLInternal(url);
}
+bool callback_clear_cache_immediately(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if ( option == 0 ) // YES
+ {
+ //clear cache
+ LLAppViewer::instance()->purgeCacheImmediate();
+ }
+
+ return false;
+}
+
+void handle_cache_clear_immediately()
+{
+ LLNotificationsUtil::add("ConfirmClearCache", LLSD(), LLSD(), callback_clear_cache_immediately);
+}
+
void handle_web_content_test(const LLSD& param)
{
std::string url = param.asString();
@@ -8001,7 +8018,7 @@ void handle_report_bug(const LLSD& param)
LLUIString url(param.asString());
LLStringUtil::format_map_t replace;
- replace["[ENVIRONMENT]"] = LLURI::escape(LLAppViewer::instance()->getShortViewerInfoString());
+ replace["[ENVIRONMENT]"] = LLURI::escape(LLAppViewer::instance()->getViewerInfoString(true));
LLSLURL location_url;
LLAgentUI::buildSLURL(location_url);
replace["[LOCATION]"] = LLURI::escape(location_url.getSLURLString());
@@ -9026,6 +9043,8 @@ void initialize_menus()
//Develop (Texture Fetch Debug Console)
view_listener_t::addMenu(new LLDevelopTextureFetchDebugger(), "Develop.SetTexFetchDebugger");
+ //Develop (clear cache immediately)
+ commit.add("Develop.ClearCache", boost::bind(&handle_cache_clear_immediately) );
// Admin >Object
view_listener_t::addMenu(new LLAdminForceTakeCopy(), "Admin.ForceTakeCopy");
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index 90355b7166..dc05d98228 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -46,6 +46,7 @@
#include "llimagetga.h"
#include "llinventorymodel.h" // gInventory
#include "llresourcedata.h"
+#include "lltoast.h"
#include "llfloaterperms.h"
#include "llstatusbar.h"
#include "llviewercontrol.h" // gSavedSettings
@@ -134,18 +135,35 @@ void LLFilePickerThread::getFile()
//virtual
void LLFilePickerThread::run()
{
- LLFilePicker picker;
#if LL_WINDOWS
- if (picker.getOpenFile(mFilter, false))
+ bool blocking = false;
+#else
+ bool blocking = true; // modal
+#endif
+
+ LLFilePicker picker;
+
+ if (mIsSaveDialog)
{
- mFile = picker.getFirstFile();
+ if (picker.getSaveFile(mSaveFilter, mProposedName, blocking))
+ {
+ mResponses.push_back(picker.getFirstFile());
+ }
}
-#else
- if (picker.getOpenFile(mFilter, true))
+ else
{
- mFile = picker.getFirstFile();
+ bool result = mIsGetMultiple ? picker.getMultipleOpenFiles(mLoadFilter, blocking) : picker.getOpenFile(mLoadFilter, blocking);
+ if (result)
+ {
+ std::string filename = picker.getFirstFile(); // consider copying mFiles directly
+ do
+ {
+ mResponses.push_back(filename);
+ filename = picker.getNextFile();
+ }
+ while (mIsGetMultiple && !filename.empty());
+ }
}
-#endif
{
LLMutexLock lock(sMutex);
@@ -178,13 +196,47 @@ void LLFilePickerThread::clearDead()
while (!sDeadQ.empty())
{
LLFilePickerThread* thread = sDeadQ.front();
- thread->notify(thread->mFile);
+ thread->notify(thread->mResponses);
delete thread;
sDeadQ.pop();
}
}
}
+LLFilePickerReplyThread::LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ELoadFilter filter, bool get_multiple)
+ : LLFilePickerThread(filter, get_multiple),
+ mLoadFilter(filter),
+ mSaveFilter(LLFilePicker::FFSAVE_ALL),
+ mFilePickedSignal(NULL)
+{
+ mFilePickedSignal = new file_picked_signal_t();
+ mFilePickedSignal->connect(cb);
+}
+
+LLFilePickerReplyThread::LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ESaveFilter filter, const std::string &proposed_name)
+ : LLFilePickerThread(filter, proposed_name),
+ mLoadFilter(LLFilePicker::FFLOAD_ALL),
+ mSaveFilter(filter),
+ mFilePickedSignal(NULL)
+{
+ mFilePickedSignal = new file_picked_signal_t();
+ mFilePickedSignal->connect(cb);
+}
+
+LLFilePickerReplyThread::~LLFilePickerReplyThread()
+{
+ delete mFilePickedSignal;
+}
+
+void LLFilePickerReplyThread::notify(const std::vector<std::string>& filenames)
+{
+ if (filenames.empty()) return;
+
+ if (mFilePickedSignal)
+ {
+ (*mFilePickedSignal)(filenames, mLoadFilter, mSaveFilter);
+ }
+}
//============================================================================
@@ -231,54 +283,21 @@ std::string build_extensions_string(LLFilePicker::ELoadFilter filter)
}
}
-/**
- char* upload_pick(void* data)
- If applicable, brings up a file chooser in which the user selects a file
- to upload for a particular task. If the file is valid for the given action,
- returns the string to the full path filename, else returns NULL.
- Data is the load filter for the type of file as defined in LLFilePicker.
-**/
-const std::string upload_pick(void* data)
+const bool check_file_extension(const std::string& filename, LLFilePicker::ELoadFilter type)
{
- if( gAgentCamera.cameraMouselook() )
- {
- gAgentCamera.changeCameraToDefault();
- // This doesn't seem necessary. JC
- // display();
- }
-
- LLFilePicker::ELoadFilter type;
- if(data)
- {
- type = (LLFilePicker::ELoadFilter)((intptr_t)data);
- }
- else
- {
- type = LLFilePicker::FFLOAD_ALL;
- }
-
- LLFilePicker& picker = LLFilePicker::instance();
- if (!picker.getOpenFile(type))
- {
- LL_INFOS() << "Couldn't import objects from file" << LL_ENDL;
- return std::string();
- }
-
-
- const std::string& filename = picker.getFirstFile();
std::string ext = gDirUtilp->getExtension(filename);
//strincmp doesn't like NULL pointers
if (ext.empty())
{
std::string short_name = gDirUtilp->getBaseFileName(filename);
-
+
// No extension
LLSD args;
args["FILE"] = short_name;
LLNotificationsUtil::add("NoFileExtension", args);
- return std::string();
+ return false;
}
else
{
@@ -290,7 +309,7 @@ const std::string upload_pick(void* data)
std::string valid_extensions = build_extensions_string(type);
BOOL ext_valid = FALSE;
-
+
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
boost::char_separator<char> sep(" ");
tokenizer tokens(valid_extensions, sep);
@@ -299,9 +318,9 @@ const std::string upload_pick(void* data)
//now loop over all valid file extensions
//and compare them to the extension of the file
//to be uploaded
- for( token_iter = tokens.begin();
- token_iter != tokens.end() && ext_valid != TRUE;
- ++token_iter)
+ for (token_iter = tokens.begin();
+ token_iter != tokens.end() && ext_valid != TRUE;
+ ++token_iter)
{
const std::string& cur_token = *token_iter;
@@ -321,42 +340,103 @@ const std::string upload_pick(void* data)
args["EXTENSION"] = ext;
args["VALIDS"] = valid_extensions;
LLNotificationsUtil::add("InvalidFileExtension", args);
- return std::string();
+ return false;
}
}//end else (non-null extension)
+ return true;
+}
- //valid file extension
+const void upload_single_file(const std::vector<std::string>& filenames, LLFilePicker::ELoadFilter type)
+{
+ std::string filename = filenames[0];
+ if (!check_file_extension(filename, type)) return;
- //now we check to see
- //if the file is actually a valid image/sound/etc.
- if (type == LLFilePicker::FFLOAD_WAV)
+ if (!filename.empty())
{
- // pre-qualify wavs to make sure the format is acceptable
- std::string error_msg;
- if (check_for_invalid_wav_formats(filename,error_msg))
+ if (type == LLFilePicker::FFLOAD_WAV)
{
- LL_INFOS() << error_msg << ": " << filename << LL_ENDL;
- LLSD args;
- args["FILE"] = filename;
- LLNotificationsUtil::add( error_msg, args );
- return std::string();
+ // pre-qualify wavs to make sure the format is acceptable
+ std::string error_msg;
+ if (check_for_invalid_wav_formats(filename, error_msg))
+ {
+ LL_INFOS() << error_msg << ": " << filename << LL_ENDL;
+ LLSD args;
+ args["FILE"] = filename;
+ LLNotificationsUtil::add(error_msg, args);
+ return;
+ }
+ else
+ {
+ LLFloaterReg::showInstance("upload_sound", LLSD(filename));
+ }
+ }
+ if (type == LLFilePicker::FFLOAD_IMAGE)
+ {
+ LLFloaterReg::showInstance("upload_image", LLSD(filename));
}
- }//end if a wave/sound file
+ if (type == LLFilePicker::FFLOAD_ANIM)
+ {
+ if (filename.rfind(".anim") != std::string::npos)
+ {
+ LLFloaterReg::showInstance("upload_anim_anim", LLSD(filename));
+ }
+ else
+ {
+ LLFloaterReg::showInstance("upload_anim_bvh", LLSD(filename));
+ }
+ }
+ }
+ return;
+}
-
- return filename;
+
+const void upload_bulk(const std::vector<std::string>& filenames, LLFilePicker::ELoadFilter type)
+{
+ // TODO:
+ // Check user balance for entire cost
+ // Charge user entire cost
+ // Loop, uploading
+ // If an upload fails, refund the user for that one
+ //
+ // Also fix single upload to charge first, then refund
+
+ S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload();
+ for (std::vector<std::string>::const_iterator in_iter = filenames.begin(); in_iter != filenames.end(); ++in_iter)
+ {
+ std::string filename = (*in_iter);
+ if (!check_file_extension(filename, type)) continue;
+
+ std::string name = gDirUtilp->getBaseFileName(filename, true);
+ std::string asset_name = name;
+ LLStringUtil::replaceNonstandardASCII(asset_name, '?');
+ LLStringUtil::replaceChar(asset_name, '|', '?');
+ LLStringUtil::stripNonprintable(asset_name);
+ LLStringUtil::trim(asset_name);
+
+ LLResourceUploadInfo::ptr_t uploadInfo(new LLNewFileResourceUploadInfo(
+ filename,
+ asset_name,
+ asset_name, 0,
+ LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
+ LLFloaterPerms::getNextOwnerPerms("Uploads"),
+ LLFloaterPerms::getGroupPerms("Uploads"),
+ LLFloaterPerms::getEveryonePerms("Uploads"),
+ expected_upload_cost));
+
+ upload_new_resource(uploadInfo, NULL, NULL);
+ }
}
class LLFileUploadImage : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
- std::string filename = upload_pick((void *)LLFilePicker::FFLOAD_IMAGE);
- if (!filename.empty())
+ if (gAgentCamera.cameraMouselook())
{
- LLFloaterReg::showInstance("upload_image", LLSD(filename));
+ gAgentCamera.changeCameraToDefault();
}
- return TRUE;
+ (new LLFilePickerReplyThread(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_IMAGE, false))->getFile();
+ return true;
}
};
@@ -378,11 +458,11 @@ class LLFileUploadSound : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
- std::string filename = upload_pick((void*)LLFilePicker::FFLOAD_WAV);
- if (!filename.empty())
+ if (gAgentCamera.cameraMouselook())
{
- LLFloaterReg::showInstance("upload_sound", LLSD(filename));
+ gAgentCamera.changeCameraToDefault();
}
+ (new LLFilePickerReplyThread(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_WAV, false))->getFile();
return true;
}
};
@@ -391,18 +471,11 @@ class LLFileUploadAnim : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
- const std::string filename = upload_pick((void*)LLFilePicker::FFLOAD_ANIM);
- if (!filename.empty())
+ if (gAgentCamera.cameraMouselook())
{
- if (filename.rfind(".anim") != std::string::npos)
- {
- LLFloaterReg::showInstance("upload_anim_anim", LLSD(filename));
- }
- else
- {
- LLFloaterReg::showInstance("upload_anim_bvh", LLSD(filename));
- }
+ gAgentCamera.changeCameraToDefault();
}
+ (new LLFilePickerReplyThread(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_ANIM, false))->getFile();
return true;
}
};
@@ -411,55 +484,11 @@ class LLFileUploadBulk : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
- if( gAgentCamera.cameraMouselook() )
+ if (gAgentCamera.cameraMouselook())
{
gAgentCamera.changeCameraToDefault();
}
-
- // TODO:
- // Check extensions for uploadability, cost
- // Check user balance for entire cost
- // Charge user entire cost
- // Loop, uploading
- // If an upload fails, refund the user for that one
- //
- // Also fix single upload to charge first, then refund
-
- LLFilePicker& picker = LLFilePicker::instance();
- if (picker.getMultipleOpenFiles())
- {
- std::string filename = picker.getFirstFile();
- S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload();
-
- while (!filename.empty())
- {
- std::string name = gDirUtilp->getBaseFileName(filename, true);
-
- std::string asset_name = name;
- LLStringUtil::replaceNonstandardASCII( asset_name, '?' );
- LLStringUtil::replaceChar(asset_name, '|', '?');
- LLStringUtil::stripNonprintable(asset_name);
- LLStringUtil::trim(asset_name);
-
- LLResourceUploadInfo::ptr_t uploadInfo(new LLNewFileResourceUploadInfo(
- filename,
- asset_name,
- asset_name, 0,
- LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
- LLFloaterPerms::getNextOwnerPerms("Uploads"),
- LLFloaterPerms::getGroupPerms("Uploads"),
- LLFloaterPerms::getEveryonePerms("Uploads"),
- expected_upload_cost));
-
- upload_new_resource(uploadInfo, NULL, NULL);
-
- filename = picker.getNextFile();
- }
- }
- else
- {
- LL_INFOS() << "Couldn't import objects from file" << LL_ENDL;
- }
+ (new LLFilePickerReplyThread(boost::bind(&upload_bulk, _1, _2), LLFilePicker::FFLOAD_ALL, true))->getFile();
return true;
}
};
@@ -482,7 +511,7 @@ class LLFileEnableCloseWindow : public view_listener_t
bool frontmost_fl_exists = (NULL != gFloaterView->getFrontmostClosableFloater());
bool frontmost_snapshot_fl_exists = (NULL != gSnapshotFloaterView->getFrontmostClosableFloater());
- return frontmost_fl_exists || frontmost_snapshot_fl_exists;
+ return !LLNotificationsUI::LLToast::isAlertToastShown() && (frontmost_fl_exists || frontmost_snapshot_fl_exists);
}
};
@@ -519,7 +548,7 @@ class LLFileEnableCloseAllWindows : public view_listener_t
bool is_floaters_snapshot_opened = (floater_snapshot && floater_snapshot->isInVisibleChain())
|| (floater_outfit_snapshot && floater_outfit_snapshot->isInVisibleChain());
bool open_children = gFloaterView->allChildrenClosed() && !is_floaters_snapshot_opened;
- return !open_children;
+ return !open_children && !LLNotificationsUI::LLToast::isAlertToastShown();
}
};
diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h
index 6941b4dc0e..15bbdd1e2d 100644
--- a/indra/newview/llviewermenufile.h
+++ b/indra/newview/llviewermenufile.h
@@ -81,21 +81,48 @@ public:
static void cleanupClass();
static void clearDead();
- std::string mFile;
+ std::vector<std::string> mResponses;
+ std::string mProposedName;
- LLFilePicker::ELoadFilter mFilter;
+ LLFilePicker::ELoadFilter mLoadFilter;
+ LLFilePicker::ESaveFilter mSaveFilter;
+ bool mIsSaveDialog;
+ bool mIsGetMultiple;
- LLFilePickerThread(LLFilePicker::ELoadFilter filter)
- : LLThread("file picker"), mFilter(filter)
+ LLFilePickerThread(LLFilePicker::ELoadFilter filter, bool get_multiple = false)
+ : LLThread("file picker"), mLoadFilter(filter), mIsSaveDialog(false), mIsGetMultiple(get_multiple)
{
+ }
+ LLFilePickerThread(LLFilePicker::ESaveFilter filter, const std::string &proposed_name)
+ : LLThread("file picker"), mSaveFilter(filter), mIsSaveDialog(true), mProposedName(proposed_name)
+ {
}
void getFile();
virtual void run();
- virtual void notify(const std::string& filename) = 0;
+ virtual void notify(const std::vector<std::string>& filenames) = 0;
+};
+
+
+class LLFilePickerReplyThread : public LLFilePickerThread
+{
+public:
+
+ typedef boost::signals2::signal<void(const std::vector<std::string>& filenames, LLFilePicker::ELoadFilter load_filter, LLFilePicker::ESaveFilter save_filter)> file_picked_signal_t;
+
+ LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ELoadFilter filter, bool get_multiple);
+ LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ESaveFilter filter, const std::string &proposed_name);
+ ~LLFilePickerReplyThread();
+
+ virtual void notify(const std::vector<std::string>& filenames);
+
+private:
+ LLFilePicker::ELoadFilter mLoadFilter;
+ LLFilePicker::ESaveFilter mSaveFilter;
+ file_picked_signal_t* mFilePickedSignal;
};
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index e9085f9327..0f326efe09 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -26,7 +26,6 @@
#include "llviewerprecompiledheaders.h"
#include "llviewermessage.h"
-#include "boost/lexical_cast.hpp"
// Linden libraries
#include "llanimationstates.h"
@@ -66,7 +65,7 @@
#include "llfloatersnapshot.h"
#include "llhudeffecttrail.h"
#include "llhudmanager.h"
-#include "llimview.h"
+#include "llimprocessing.h"
#include "llinventoryfunctions.h"
#include "llinventoryobserver.h"
#include "llinventorypanel.h"
@@ -116,7 +115,6 @@
#include "llfloaterregionrestarting.h"
#include <boost/algorithm/string/split.hpp> //
-#include <boost/regex.hpp>
#include <boost/foreach.hpp>
#include "llnotificationmanager.h" //
@@ -124,11 +122,6 @@
#include "llexperiencecache.h"
-#if LL_MSVC
-// disable boost::lexical_cast warning
-#pragma warning (disable:4702)
-#endif
-
extern void on_new_message(const LLSD& msg);
//
@@ -1883,18 +1876,6 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
return false;
}
-class LLPostponedOfferNotification: public LLPostponedNotification
-{
-protected:
- /* virtual */
- void modifyNotificationParams()
- {
- LLSD substitutions = mParams.substitutions;
- substitutions["NAME"] = mName;
- mParams.substitutions = substitutions;
- }
-};
-
void LLOfferInfo::initRespondFunctionMap()
{
if(mRespondFunctions.empty())
@@ -1905,153 +1886,6 @@ void LLOfferInfo::initRespondFunctionMap()
}
}
-void inventory_offer_handler(LLOfferInfo* info)
-{
- // If muted, don't even go through the messaging stuff. Just curtail the offer here.
- // Passing in a null UUID handles the case of where you have muted one of your own objects by_name.
- // The solution for STORM-1297 seems to handle the cases where the object is owned by someone else.
- if (LLMuteList::getInstance()->isMuted(info->mFromID, info->mFromName) ||
- LLMuteList::getInstance()->isMuted(LLUUID::null, info->mFromName))
- {
- info->forceResponse(IOR_MUTE);
- return;
- }
-
- bool bAutoAccept(false);
- // Avoid the Accept/Discard dialog if the user so desires. JC
- if (gSavedSettings.getBOOL("AutoAcceptNewInventory")
- && (info->mType == LLAssetType::AT_NOTECARD
- || info->mType == LLAssetType::AT_LANDMARK
- || info->mType == LLAssetType::AT_TEXTURE))
- {
- // For certain types, just accept the items into the inventory,
- // and possibly open them on receipt depending upon "ShowNewInventory".
- bAutoAccept = true;
- }
-
- // Strip any SLURL from the message display. (DEV-2754)
- std::string msg = info->mDesc;
- int indx = msg.find(" ( http://slurl.com/secondlife/");
- if(indx == std::string::npos)
- {
- // try to find new slurl host
- indx = msg.find(" ( http://maps.secondlife.com/secondlife/");
- }
- if(indx >= 0)
- {
- LLStringUtil::truncate(msg, indx);
- }
-
- LLSD args;
- args["[OBJECTNAME]"] = msg;
-
- LLSD payload;
-
- // must protect against a NULL return from lookupHumanReadable()
- std::string typestr = ll_safe_string(LLAssetType::lookupHumanReadable(info->mType));
- if (!typestr.empty())
- {
- // human readable matches string name from strings.xml
- // lets get asset type localized name
- args["OBJECTTYPE"] = LLTrans::getString(typestr);
- }
- else
- {
- LL_WARNS("Messaging") << "LLAssetType::lookupHumanReadable() returned NULL - probably bad asset type: " << info->mType << LL_ENDL;
- args["OBJECTTYPE"] = "";
-
- // This seems safest, rather than propagating bogosity
- LL_WARNS("Messaging") << "Forcing an inventory-decline for probably-bad asset type." << LL_ENDL;
- info->forceResponse(IOR_DECLINE);
- return;
- }
-
- // If mObjectID is null then generate the object_id based on msg to prevent
- // multiple creation of chiclets for same object.
- LLUUID object_id = info->mObjectID;
- if (object_id.isNull())
- object_id.generate(msg);
-
- payload["from_id"] = info->mFromID;
- // Needed by LLScriptFloaterManager to bind original notification with
- // faked for toast one.
- payload["object_id"] = object_id;
- // Flag indicating that this notification is faked for toast.
- payload["give_inventory_notification"] = FALSE;
- args["OBJECTFROMNAME"] = info->mFromName;
- args["NAME"] = info->mFromName;
- if (info->mFromGroup)
- {
- args["NAME_SLURL"] = LLSLURL("group", info->mFromID, "about").getSLURLString();
- }
- else
- {
- args["NAME_SLURL"] = LLSLURL("agent", info->mFromID, "about").getSLURLString();
- }
- std::string verb = "select?name=" + LLURI::escape(msg);
- args["ITEM_SLURL"] = LLSLURL("inventory", info->mObjectID, verb.c_str()).getSLURLString();
-
- LLNotification::Params p;
-
- // Object -> Agent Inventory Offer
- if (info->mFromObject && !bAutoAccept)
- {
- // Inventory Slurls don't currently work for non agent transfers, so only display the object name.
- args["ITEM_SLURL"] = msg;
- // Note: sets inventory_task_offer_callback as the callback
- p.substitutions(args).payload(payload).functor.responder(LLNotificationResponderPtr(info));
- info->mPersist = true;
-
- // Offers from your own objects need a special notification template.
- p.name = info->mFromID == gAgentID ? "OwnObjectGiveItem" : "ObjectGiveItem";
-
- // Pop up inv offer chiclet and let the user accept (keep), or reject (and silently delete) the inventory.
- LLPostponedNotification::add<LLPostponedOfferNotification>(p, info->mFromID, info->mFromGroup == TRUE);
- }
- else // Agent -> Agent Inventory Offer
- {
- p.responder = info;
- // Note: sets inventory_offer_callback as the callback
- // *TODO fix memory leak
- // inventory_offer_callback() is not invoked if user received notification and
- // closes viewer(without responding the notification)
- p.substitutions(args).payload(payload).functor.responder(LLNotificationResponderPtr(info));
- info->mPersist = true;
- p.name = "UserGiveItem";
- p.offer_from_agent = true;
-
- // Prefetch the item into your local inventory.
- LLInventoryFetchItemsObserver* fetch_item = new LLInventoryFetchItemsObserver(info->mObjectID);
- fetch_item->startFetch();
- if(fetch_item->isFinished())
- {
- fetch_item->done();
- }
- else
- {
- gInventory.addObserver(fetch_item);
- }
-
- // In viewer 2 we're now auto receiving inventory offers and messaging as such (not sending reject messages).
- info->send_auto_receive_response();
-
- if (gAgent.isDoNotDisturb())
- {
- send_do_not_disturb_message(gMessageSystem, info->mFromID);
- }
-
- if( !bAutoAccept ) // if we auto accept, do not pester the user
- {
- // Inform user that there is a script floater via toast system
- payload["give_inventory_notification"] = TRUE;
- p.payload = payload;
- LLPostponedNotification::add<LLPostponedOfferNotification>(p, info->mFromID, false);
- }
- }
-
- LLFirstUse::newInventory();
-}
-
bool lure_callback(const LLSD& notification, const LLSD& response)
{
S32 option = 0;
@@ -2175,1212 +2009,57 @@ protected:
}
};
-static bool parse_lure_bucket(const std::string& bucket,
- U64& region_handle,
- LLVector3& pos,
- LLVector3& look_at,
- U8& region_access)
-{
- // tokenize the bucket
- typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
- boost::char_separator<char> sep("|", "", boost::keep_empty_tokens);
- tokenizer tokens(bucket, sep);
- tokenizer::iterator iter = tokens.begin();
-
- S32 gx,gy,rx,ry,rz,lx,ly,lz;
- try
- {
- gx = boost::lexical_cast<S32>((*(iter)).c_str());
- gy = boost::lexical_cast<S32>((*(++iter)).c_str());
- rx = boost::lexical_cast<S32>((*(++iter)).c_str());
- ry = boost::lexical_cast<S32>((*(++iter)).c_str());
- rz = boost::lexical_cast<S32>((*(++iter)).c_str());
- lx = boost::lexical_cast<S32>((*(++iter)).c_str());
- ly = boost::lexical_cast<S32>((*(++iter)).c_str());
- lz = boost::lexical_cast<S32>((*(++iter)).c_str());
- }
- catch( boost::bad_lexical_cast& )
- {
- LL_WARNS("parse_lure_bucket")
- << "Couldn't parse lure bucket."
- << LL_ENDL;
- return false;
- }
- // Grab region access
- region_access = SIM_ACCESS_MIN;
- if (++iter != tokens.end())
- {
- std::string access_str((*iter).c_str());
- LLStringUtil::trim(access_str);
- if ( access_str == "A" )
- {
- region_access = SIM_ACCESS_ADULT;
- }
- else if ( access_str == "M" )
- {
- region_access = SIM_ACCESS_MATURE;
- }
- else if ( access_str == "PG" )
- {
- region_access = SIM_ACCESS_PG;
- }
- }
-
- pos.setVec((F32)rx, (F32)ry, (F32)rz);
- look_at.setVec((F32)lx, (F32)ly, (F32)lz);
-
- region_handle = to_region_handle(gx, gy);
- return true;
-}
-
-// Strip out "Resident" for display, but only if the message came from a user
-// (rather than a script)
-static std::string clean_name_from_im(const std::string& name, EInstantMessage type)
-{
- switch(type)
- {
- case IM_NOTHING_SPECIAL:
- case IM_MESSAGEBOX:
- case IM_GROUP_INVITATION:
- case IM_INVENTORY_OFFERED:
- case IM_INVENTORY_ACCEPTED:
- case IM_INVENTORY_DECLINED:
- case IM_GROUP_VOTE:
- case IM_GROUP_MESSAGE_DEPRECATED:
- //IM_TASK_INVENTORY_OFFERED
- //IM_TASK_INVENTORY_ACCEPTED
- //IM_TASK_INVENTORY_DECLINED
- case IM_NEW_USER_DEFAULT:
- case IM_SESSION_INVITE:
- case IM_SESSION_P2P_INVITE:
- case IM_SESSION_GROUP_START:
- case IM_SESSION_CONFERENCE_START:
- case IM_SESSION_SEND:
- case IM_SESSION_LEAVE:
- //IM_FROM_TASK
- case IM_DO_NOT_DISTURB_AUTO_RESPONSE:
- case IM_CONSOLE_AND_CHAT_HISTORY:
- case IM_LURE_USER:
- case IM_LURE_ACCEPTED:
- case IM_LURE_DECLINED:
- case IM_GODLIKE_LURE_USER:
- case IM_TELEPORT_REQUEST:
- case IM_GROUP_ELECTION_DEPRECATED:
- //IM_GOTO_URL
- //IM_FROM_TASK_AS_ALERT
- case IM_GROUP_NOTICE:
- case IM_GROUP_NOTICE_INVENTORY_ACCEPTED:
- case IM_GROUP_NOTICE_INVENTORY_DECLINED:
- case IM_GROUP_INVITATION_ACCEPT:
- case IM_GROUP_INVITATION_DECLINE:
- case IM_GROUP_NOTICE_REQUESTED:
- case IM_FRIENDSHIP_OFFERED:
- case IM_FRIENDSHIP_ACCEPTED:
- case IM_FRIENDSHIP_DECLINED_DEPRECATED:
- //IM_TYPING_START
- //IM_TYPING_STOP
- return LLCacheName::cleanFullName(name);
- default:
- return name;
- }
-}
-
-static std::string clean_name_from_task_im(const std::string& msg,
- BOOL from_group)
-{
- boost::smatch match;
- static const boost::regex returned_exp(
- "(.*been returned to your inventory lost and found folder by )(.+)( (from|near).*)");
- if (boost::regex_match(msg, match, returned_exp))
- {
- // match objects are 1-based for groups
- std::string final = match[1].str();
- std::string name = match[2].str();
- // Don't try to clean up group names
- if (!from_group)
- {
- final += LLCacheName::buildUsername(name);
- }
- final += match[3].str();
- return final;
- }
- return msg;
-}
-
-static void notification_display_name_callback(const LLUUID& id,
- const LLAvatarName& av_name,
- const std::string& name,
- LLSD& substitutions,
- const LLSD& payload)
-{
- substitutions["NAME"] = av_name.getDisplayName();
- LLNotificationsUtil::add(name, substitutions, payload);
-}
-
-class LLPostponedIMSystemTipNotification: public LLPostponedNotification
-{
-protected:
- /* virtual */
- void modifyNotificationParams()
- {
- LLSD payload = mParams.payload;
- payload["SESSION_NAME"] = mName;
- mParams.payload = payload;
- }
-
-};
-
-// Callback for name resolution of a god/estate message
-static void god_message_name_cb(const LLAvatarName& av_name, LLChat chat, std::string message)
-{
- LLSD args;
- args["NAME"] = av_name.getCompleteName();
- args["MESSAGE"] = message;
- LLNotificationsUtil::add("GodMessage", args);
-
- // Treat like a system message and put in chat history.
- chat.mSourceType = CHAT_SOURCE_SYSTEM;
- chat.mText = message;
-
- LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
- if (nearby_chat)
- {
- nearby_chat->addMessage(chat);
- }
-}
-
-const std::string NOT_ONLINE_MSG("User not online - message will be stored and delivered later.");
-const std::string NOT_ONLINE_INVENTORY("User not online - inventory has been saved.");
-void translate_if_needed(std::string& message)
-{
- if (message == NOT_ONLINE_MSG)
- {
- message = LLTrans::getString("not_online_msg");
- }
- else if (message == NOT_ONLINE_INVENTORY)
- {
- message = LLTrans::getString("not_online_inventory");
- }
-}
-
void process_improved_im(LLMessageSystem *msg, void **user_data)
{
- LLUUID from_id;
- BOOL from_group;
- LLUUID to_id;
- U8 offline;
- U8 d = 0;
- LLUUID session_id;
- U32 timestamp;
- std::string name;
- std::string message;
- U32 parent_estate_id = 0;
- LLUUID region_id;
- LLVector3 position;
- U8 binary_bucket[MTUBYTES];
- S32 binary_bucket_size;
- LLChat chat;
- std::string buffer;
-
- // *TODO: Translate - need to fix the full name to first/last (maybe)
- msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, from_id);
- msg->getBOOLFast(_PREHASH_MessageBlock, _PREHASH_FromGroup, from_group);
- msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_ToAgentID, to_id);
- msg->getU8Fast( _PREHASH_MessageBlock, _PREHASH_Offline, offline);
- msg->getU8Fast( _PREHASH_MessageBlock, _PREHASH_Dialog, d);
- msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_ID, session_id);
- msg->getU32Fast( _PREHASH_MessageBlock, _PREHASH_Timestamp, timestamp);
- //msg->getData("MessageBlock", "Count", &count);
- msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_FromAgentName, name);
- msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_Message, message);
- msg->getU32Fast(_PREHASH_MessageBlock, _PREHASH_ParentEstateID, parent_estate_id);
- msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_RegionID, region_id);
- msg->getVector3Fast(_PREHASH_MessageBlock, _PREHASH_Position, position);
- msg->getBinaryDataFast( _PREHASH_MessageBlock, _PREHASH_BinaryBucket, binary_bucket, 0, 0, MTUBYTES);
- binary_bucket_size = msg->getSizeFast(_PREHASH_MessageBlock, _PREHASH_BinaryBucket);
- EInstantMessage dialog = (EInstantMessage)d;
-
- // make sure that we don't have an empty or all-whitespace name
- LLStringUtil::trim(name);
- if (name.empty())
- {
- name = LLTrans::getString("Unnamed");
- }
-
- // Preserve the unaltered name for use in group notice mute checking.
- std::string original_name = name;
-
- // IDEVO convert new-style "Resident" names for display
- name = clean_name_from_im(name, dialog);
-
- BOOL is_do_not_disturb = gAgent.isDoNotDisturb();
- BOOL is_muted = LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat)
- // object IMs contain sender object id in session_id (STORM-1209)
- || (dialog == IM_FROM_TASK && LLMuteList::getInstance()->isMuted(session_id));
- BOOL is_owned_by_me = FALSE;
- BOOL is_friend = (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL) ? false : true;
- BOOL accept_im_from_only_friend = gSavedSettings.getBOOL("VoiceCallsFriendsOnly");
- BOOL is_linden = chat.mSourceType != CHAT_SOURCE_OBJECT &&
- LLMuteList::getInstance()->isLinden(name);
-
- chat.mMuted = is_muted;
- chat.mFromID = from_id;
- chat.mFromName = name;
- chat.mSourceType = (from_id.isNull() || (name == std::string(SYSTEM_FROM))) ? CHAT_SOURCE_SYSTEM : CHAT_SOURCE_AGENT;
-
- if (chat.mSourceType == CHAT_SOURCE_SYSTEM)
- { // Translate server message if required (MAINT-6109)
- translate_if_needed(message);
- }
-
- LLViewerObject *source = gObjectList.findObject(session_id); //Session ID is probably the wrong thing.
- if (source)
- {
- is_owned_by_me = source->permYouOwner();
- }
-
- std::string separator_string(": ");
-
- LLSD args;
- LLSD payload;
- LLNotification::Params params;
-
- switch(dialog)
- {
- case IM_CONSOLE_AND_CHAT_HISTORY:
- args["MESSAGE"] = message;
- payload["from_id"] = from_id;
-
- params.name = "IMSystemMessageTip";
- params.substitutions = args;
- params.payload = payload;
- LLPostponedNotification::add<LLPostponedIMSystemTipNotification>(params, from_id, false);
- break;
-
- case IM_NOTHING_SPECIAL: // p2p IM
- // Don't show dialog, just do IM
- if (!gAgent.isGodlike()
- && gAgent.getRegion()->isPrelude()
- && to_id.isNull() )
- {
- // do nothing -- don't distract newbies in
- // Prelude with global IMs
- }
- else if (offline == IM_ONLINE
- && is_do_not_disturb
- && from_id.notNull() //not a system message
- && to_id.notNull()) //not global message
- {
-
- // now store incoming IM in chat history
-
- buffer = message;
-
- LL_DEBUGS("Messaging") << "session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
-
- // add to IM panel, but do not bother the user
- gIMMgr->addMessage(
- session_id,
- from_id,
- name,
- buffer,
- IM_OFFLINE == offline,
- LLStringUtil::null,
- dialog,
- parent_estate_id,
- region_id,
- position,
- true);
-
- if (!gIMMgr->isDNDMessageSend(session_id))
- {
- // return a standard "do not disturb" message, but only do it to online IM
- // (i.e. not other auto responses and not store-and-forward IM)
- send_do_not_disturb_message(msg, from_id, session_id);
- gIMMgr->setDNDMessageSent(session_id, true);
- }
-
- }
- else if (from_id.isNull())
- {
- LLSD args;
- args["MESSAGE"] = message;
- LLNotificationsUtil::add("SystemMessage", args);
- }
- else if (to_id.isNull())
- {
- // Message to everyone from GOD, look up the fullname since
- // server always slams name to legacy names
- LLAvatarNameCache::get(from_id, boost::bind(god_message_name_cb, _2, chat, message));
- }
- else
- {
- // standard message, not from system
- std::string saved;
- if(offline == IM_OFFLINE)
- {
- LLStringUtil::format_map_t args;
- args["[LONG_TIMESTAMP]"] = formatted_time(timestamp);
- saved = LLTrans::getString("Saved_message", args);
- }
- buffer = saved + message;
-
- LL_DEBUGS("Messaging") << "session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
-
- bool mute_im = is_muted;
- if(accept_im_from_only_friend && !is_friend && !is_linden)
- {
- if (!gIMMgr->isNonFriendSessionNotified(session_id))
- {
- std::string message = LLTrans::getString("IM_unblock_only_groups_friends");
- gIMMgr->addMessage(session_id, from_id, name, message, IM_OFFLINE == offline);
- gIMMgr->addNotifiedNonFriendSessionID(session_id);
- }
-
- mute_im = true;
- }
- if (!mute_im)
- {
- gIMMgr->addMessage(
- session_id,
- from_id,
- name,
- buffer,
- IM_OFFLINE == offline,
- LLStringUtil::null,
- dialog,
- parent_estate_id,
- region_id,
- position,
- true);
- }
- else
- {
- /*
- EXT-5099
- currently there is no way to store in history only...
- using LLNotificationsUtil::add will add message to Nearby Chat
-
- // muted user, so don't start an IM session, just record line in chat
- // history. Pretend the chat is from a local agent,
- // so it will go into the history but not be shown on screen.
-
- LLSD args;
- args["MESSAGE"] = buffer;
- LLNotificationsUtil::add("SystemMessageTip", args);
- */
- }
- }
- break;
-
- case IM_TYPING_START:
- {
- LLPointer<LLIMInfo> im_info = new LLIMInfo(gMessageSystem);
- gIMMgr->processIMTypingStart(im_info);
- }
- break;
-
- case IM_TYPING_STOP:
- {
- LLPointer<LLIMInfo> im_info = new LLIMInfo(gMessageSystem);
- gIMMgr->processIMTypingStop(im_info);
- }
- break;
-
- case IM_MESSAGEBOX:
- {
- // This is a block, modeless dialog.
- //*TODO: Translate
- args["MESSAGE"] = message;
- LLNotificationsUtil::add("SystemMessageTip", args);
- }
- break;
- case IM_GROUP_NOTICE:
- case IM_GROUP_NOTICE_REQUESTED:
- {
- LL_INFOS("Messaging") << "Received IM_GROUP_NOTICE message." << LL_ENDL;
- // Read the binary bucket for more information.
- struct notice_bucket_header_t
- {
- U8 has_inventory;
- U8 asset_type;
- LLUUID group_id;
- };
- struct notice_bucket_full_t
- {
- struct notice_bucket_header_t header;
- U8 item_name[DB_INV_ITEM_NAME_BUF_SIZE];
- }* notice_bin_bucket;
-
- // Make sure the binary bucket is big enough to hold the header
- // and a null terminated item name.
- if ( (binary_bucket_size < (S32)((sizeof(notice_bucket_header_t) + sizeof(U8))))
- || (binary_bucket[binary_bucket_size - 1] != '\0') )
- {
- LL_WARNS("Messaging") << "Malformed group notice binary bucket" << LL_ENDL;
- break;
- }
-
- // The group notice packet does not have an AgentID. Obtain one from the name cache.
- // If last name is "Resident" strip it out so the cache name lookup works.
- std::string::size_type index = original_name.find(" Resident");
- if (index != std::string::npos)
- {
- original_name = original_name.substr(0, index);
- }
-
- std::string legacy_name = gCacheName->buildLegacyName(original_name);
- LLUUID agent_id = LLAvatarNameCache::findIdByName(legacy_name);
-
- if (agent_id.isNull())
- {
- LL_WARNS("Messaging") << "buildLegacyName returned null while processing " << original_name << LL_ENDL;
- }
- else if (LLMuteList::getInstance()->isMuted(agent_id))
- {
- break;
- }
-
- notice_bin_bucket = (struct notice_bucket_full_t*) &binary_bucket[0];
- U8 has_inventory = notice_bin_bucket->header.has_inventory;
- U8 asset_type = notice_bin_bucket->header.asset_type;
- LLUUID group_id = notice_bin_bucket->header.group_id;
- std::string item_name = ll_safe_string((const char*) notice_bin_bucket->item_name);
-
- // If there is inventory, give the user the inventory offer.
- LLOfferInfo* info = NULL;
-
- if (has_inventory)
- {
- info = new LLOfferInfo();
-
- info->mIM = IM_GROUP_NOTICE;
- info->mFromID = from_id;
- info->mFromGroup = from_group;
- info->mTransactionID = session_id;
- info->mType = (LLAssetType::EType) asset_type;
- info->mFolderID = gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(info->mType));
- std::string from_name;
-
- from_name += "A group member named ";
- from_name += name;
-
- info->mFromName = from_name;
- info->mDesc = item_name;
- info->mHost = msg->getSender();
- }
-
- std::string str(message);
-
- // Tokenize the string.
- // TODO: Support escaped tokens ("||" -> "|")
- typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
- boost::char_separator<char> sep("|","",boost::keep_empty_tokens);
- tokenizer tokens(str, sep);
- tokenizer::iterator iter = tokens.begin();
-
- std::string subj(*iter++);
- std::string mes(*iter++);
-
- // Send the notification down the new path.
- // For requested notices, we don't want to send the popups.
- if (dialog != IM_GROUP_NOTICE_REQUESTED)
- {
- payload["subject"] = subj;
- payload["message"] = mes;
- payload["sender_name"] = name;
- payload["sender_id"] = agent_id;
- payload["group_id"] = group_id;
- payload["inventory_name"] = item_name;
- payload["received_time"] = LLDate::now();
- if(info && info->asLLSD())
- {
- payload["inventory_offer"] = info->asLLSD();
- }
-
- LLSD args;
- args["SUBJECT"] = subj;
- args["MESSAGE"] = mes;
- LLDate notice_date = LLDate(timestamp).notNull() ? LLDate(timestamp) : LLDate::now();
- LLNotifications::instance().add(LLNotification::Params("GroupNotice").substitutions(args).payload(payload).time_stamp(notice_date));
- }
-
- // Also send down the old path for now.
- if (IM_GROUP_NOTICE_REQUESTED == dialog)
- {
-
- LLPanelGroup::showNotice(subj,mes,group_id,has_inventory,item_name,info);
- }
- else
- {
- delete info;
- }
- }
- break;
- case IM_GROUP_INVITATION:
- {
- if (!is_muted)
- {
- // group is not blocked, but we still need to check agent that sent the invitation
- // and we have no agent's id
- // Note: server sends username "first.last".
- is_muted |= LLMuteList::getInstance()->isMuted(name);
- }
- if (is_do_not_disturb || is_muted)
- {
- send_do_not_disturb_message(msg, from_id);
- }
-
- if (!is_muted)
- {
- LL_INFOS("Messaging") << "Received IM_GROUP_INVITATION message." << LL_ENDL;
- // Read the binary bucket for more information.
- struct invite_bucket_t
- {
- S32 membership_fee;
- LLUUID role_id;
- }* invite_bucket;
-
- // Make sure the binary bucket is the correct size.
- if (binary_bucket_size != sizeof(invite_bucket_t))
- {
- LL_WARNS("Messaging") << "Malformed group invite binary bucket" << LL_ENDL;
- break;
- }
-
- invite_bucket = (struct invite_bucket_t*) &binary_bucket[0];
- S32 membership_fee = ntohl(invite_bucket->membership_fee);
-
- LLSD payload;
- payload["transaction_id"] = session_id;
- payload["group_id"] = from_id;
- payload["name"] = name;
- payload["message"] = message;
- payload["fee"] = membership_fee;
-
- LLSD args;
- args["MESSAGE"] = message;
- // we shouldn't pass callback functor since it is registered in LLFunctorRegistration
- LLNotificationsUtil::add("JoinGroup", args, payload);
- }
- }
- break;
-
- case IM_INVENTORY_OFFERED:
- case IM_TASK_INVENTORY_OFFERED:
- // Someone has offered us some inventory.
- {
- LLOfferInfo* info = new LLOfferInfo;
- if (IM_INVENTORY_OFFERED == dialog)
- {
- struct offer_agent_bucket_t
- {
- S8 asset_type;
- LLUUID object_id;
- }* bucketp;
-
- if (sizeof(offer_agent_bucket_t) != binary_bucket_size)
- {
- LL_WARNS("Messaging") << "Malformed inventory offer from agent" << LL_ENDL;
- delete info;
- break;
- }
- bucketp = (struct offer_agent_bucket_t*) &binary_bucket[0];
- info->mType = (LLAssetType::EType) bucketp->asset_type;
- info->mObjectID = bucketp->object_id;
- info->mFromObject = FALSE;
- }
- else // IM_TASK_INVENTORY_OFFERED
- {
- 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->mIM = dialog;
- info->mFromID = from_id;
- info->mFromGroup = from_group;
- info->mTransactionID = session_id;
- info->mFolderID = gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(info->mType));
-
- info->mFromName = name;
- info->mDesc = message;
- info->mHost = msg->getSender();
- //if (((is_do_not_disturb && !is_owned_by_me) || is_muted))
- if (is_muted)
- {
- // Prefetch the offered item so that it can be discarded by the appropriate observer. (EXT-4331)
- LLInventoryFetchItemsObserver* fetch_item = new LLInventoryFetchItemsObserver(info->mObjectID);
- fetch_item->startFetch();
- delete fetch_item;
-
- // Same as closing window
- info->forceResponse(IOR_DECLINE);
- }
- // old logic: busy mode must not affect interaction with objects (STORM-565)
- // new logic: inventory offers from in-world objects should be auto-declined (CHUI-519)
- else if (is_do_not_disturb && dialog == IM_TASK_INVENTORY_OFFERED)
- {
- // Until throttling is implemented, do not disturb mode should reject inventory instead of silently
- // accepting it. SEE SL-39554
- info->forceResponse(IOR_DECLINE);
- }
- else
- {
- inventory_offer_handler(info);
- }
- }
- break;
-
- case IM_INVENTORY_ACCEPTED:
- {
- args["NAME"] = LLSLURL("agent", from_id, "completename").getSLURLString();;
- args["ORIGINAL_NAME"] = original_name;
- LLSD payload;
- payload["from_id"] = from_id;
- // Passing the "SESSION_NAME" to use it for IM notification logging
- // in LLTipHandler::processNotification(). See STORM-941.
- payload["SESSION_NAME"] = name;
- LLNotificationsUtil::add("InventoryAccepted", args, payload);
- break;
- }
- case IM_INVENTORY_DECLINED:
- {
- args["NAME"] = LLSLURL("agent", from_id, "completename").getSLURLString();;
- LLSD payload;
- payload["from_id"] = from_id;
- LLNotificationsUtil::add("InventoryDeclined", args, payload);
- break;
- }
- // TODO: _DEPRECATED suffix as part of vote removal - DEV-24856
- case IM_GROUP_VOTE:
- {
- LL_WARNS("Messaging") << "Received IM: IM_GROUP_VOTE_DEPRECATED" << LL_ENDL;
- }
- break;
-
- case IM_GROUP_ELECTION_DEPRECATED:
- {
- LL_WARNS("Messaging") << "Received IM: IM_GROUP_ELECTION_DEPRECATED" << LL_ENDL;
- }
- break;
-
- case IM_FROM_TASK:
- {
-
- if (is_do_not_disturb && !is_owned_by_me)
- {
- return;
- }
-
- // Build a link to open the object IM info window.
- std::string location = ll_safe_string((char*)binary_bucket, binary_bucket_size-1);
-
- if (session_id.notNull())
- {
- chat.mFromID = session_id;
- }
- else
- {
- // This message originated on a region without the updated code for task id and slurl information.
- // We just need a unique ID for this object that isn't the owner ID.
- // If it is the owner ID it will overwrite the style that contains the link to that owner's profile.
- // This isn't ideal - it will make 1 style for all objects owned by the the same person/group.
- // This works because the only thing we can really do in this case is show the owner name and link to their profile.
- chat.mFromID = from_id ^ gAgent.getSessionID();
- }
-
- chat.mSourceType = CHAT_SOURCE_OBJECT;
-
- // To conclude that the source type of message is CHAT_SOURCE_SYSTEM it's not
- // enough to check only from name (i.e. fromName = "Second Life"). For example
- // source type of messages from objects called "Second Life" should not be CHAT_SOURCE_SYSTEM.
- bool chat_from_system = (SYSTEM_FROM == name) && region_id.isNull() && position.isNull();
- if(chat_from_system)
- {
- // System's UUID is NULL (fixes EXT-4766)
- chat.mFromID = LLUUID::null;
- chat.mSourceType = CHAT_SOURCE_SYSTEM;
- }
-
- // IDEVO Some messages have embedded resident names
- message = clean_name_from_task_im(message, from_group);
-
- LLSD query_string;
- query_string["owner"] = from_id;
- query_string["slurl"] = location;
- query_string["name"] = name;
- if (from_group)
- {
- query_string["groupowned"] = "true";
- }
-
- chat.mURL = LLSLURL("objectim", session_id, "").getSLURLString();
- chat.mText = message;
-
- // Note: lie to Nearby Chat, pretending that this is NOT an IM, because
- // IMs from obejcts don't open IM sessions.
- LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
- if(!chat_from_system && nearby_chat)
- {
- chat.mOwnerID = from_id;
- LLSD args;
- args["slurl"] = location;
-
- // Look for IRC-style emotes here so object name formatting is correct
- std::string prefix = message.substr(0, 4);
- if (prefix == "/me " || prefix == "/me'")
- {
- chat.mChatStyle = CHAT_STYLE_IRC;
- }
-
- LLNotificationsUI::LLNotificationManager::instance().onChat(chat, args);
- }
-
-
- //Object IMs send with from name: 'Second Life' need to be displayed also in notification toasts (EXT-1590)
- if (!chat_from_system) break;
-
- LLSD substitutions;
- substitutions["NAME"] = name;
- substitutions["MSG"] = message;
-
- LLSD payload;
- payload["object_id"] = session_id;
- payload["owner_id"] = from_id;
- payload["from_id"] = from_id;
- payload["slurl"] = location;
- payload["name"] = name;
-
- if (from_group)
- {
- payload["group_owned"] = "true";
- }
-
- LLNotificationsUtil::add("ServerObjectMessage", substitutions, payload);
- }
- break;
-
- case IM_SESSION_SEND: // ad-hoc or group IMs
-
- // Only show messages if we have a session open (which
- // should happen after you get an "invitation"
- if ( !gIMMgr->hasSession(session_id) )
- {
- return;
- }
-
- else if (offline == IM_ONLINE && is_do_not_disturb)
- {
-
- // return a standard "do not disturb" message, but only do it to online IM
- // (i.e. not other auto responses and not store-and-forward IM)
- if (!gIMMgr->hasSession(session_id))
- {
- // if there is not a panel for this conversation (i.e. it is a new IM conversation
- // initiated by the other party) then...
- send_do_not_disturb_message(msg, from_id, session_id);
- }
-
- // now store incoming IM in chat history
-
- buffer = message;
-
- LL_DEBUGS("Messaging") << "message in dnd; session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
-
- // add to IM panel, but do not bother the user
- gIMMgr->addMessage(
- session_id,
- from_id,
- name,
- buffer,
- IM_OFFLINE == offline,
- ll_safe_string((char*)binary_bucket),
- IM_SESSION_INVITE,
- parent_estate_id,
- region_id,
- position,
- true);
- }
- else
- {
- // standard message, not from system
- std::string saved;
- if(offline == IM_OFFLINE)
- {
- saved = llformat("(Saved %s) ", formatted_time(timestamp).c_str());
- }
-
- buffer = saved + message;
-
- LL_DEBUGS("Messaging") << "standard message session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
-
- gIMMgr->addMessage(
- session_id,
- from_id,
- name,
- buffer,
- IM_OFFLINE == offline,
- ll_safe_string((char*)binary_bucket),
- IM_SESSION_INVITE,
- parent_estate_id,
- region_id,
- position,
- true);
- }
- break;
-
- case IM_FROM_TASK_AS_ALERT:
- if (is_do_not_disturb && !is_owned_by_me)
- {
- return;
- }
- {
- // Construct a viewer alert for this message.
- args["NAME"] = name;
- args["MESSAGE"] = message;
- LLNotificationsUtil::add("ObjectMessage", args);
- }
- break;
- case IM_DO_NOT_DISTURB_AUTO_RESPONSE:
- if (is_muted)
- {
- LL_DEBUGS("Messaging") << "Ignoring do-not-disturb response from " << from_id << LL_ENDL;
- return;
- }
- else
- {
- gIMMgr->addMessage(session_id, from_id, name, message);
- }
- break;
-
- case IM_LURE_USER:
- case IM_TELEPORT_REQUEST:
- {
- if (is_muted)
- {
- return;
- }
- else if (gSavedSettings.getBOOL("VoiceCallsFriendsOnly") && (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL))
- {
- return;
- }
- else
- {
- if (is_do_not_disturb)
- {
- send_do_not_disturb_message(msg, from_id);
- }
-
- LLVector3 pos, look_at;
- U64 region_handle(0);
- U8 region_access(SIM_ACCESS_MIN);
- std::string region_info = ll_safe_string((char*)binary_bucket, binary_bucket_size);
- std::string region_access_str = LLStringUtil::null;
- std::string region_access_icn = LLStringUtil::null;
- std::string region_access_lc = LLStringUtil::null;
-
- bool canUserAccessDstRegion = true;
- bool doesUserRequireMaturityIncrease = false;
-
- // Do not parse the (empty) lure bucket for TELEPORT_REQUEST
- if (IM_TELEPORT_REQUEST != dialog && parse_lure_bucket(region_info, region_handle, pos, look_at, region_access))
- {
- region_access_str = LLViewerRegion::accessToString(region_access);
- region_access_icn = LLViewerRegion::getAccessIcon(region_access);
- region_access_lc = region_access_str;
- LLStringUtil::toLower(region_access_lc);
-
- if (!gAgent.isGodlike())
- {
- switch (region_access)
- {
- case SIM_ACCESS_MIN :
- case SIM_ACCESS_PG :
- break;
- case SIM_ACCESS_MATURE :
- if (gAgent.isTeen())
- {
- canUserAccessDstRegion = false;
- }
- else if (gAgent.prefersPG())
- {
- doesUserRequireMaturityIncrease = true;
- }
- break;
- case SIM_ACCESS_ADULT :
- if (!gAgent.isAdult())
- {
- canUserAccessDstRegion = false;
- }
- else if (!gAgent.prefersAdult())
- {
- doesUserRequireMaturityIncrease = true;
- }
- break;
- default :
- llassert(0);
- break;
- }
- }
- }
-
- LLSD args;
- // *TODO: Translate -> [FIRST] [LAST] (maybe)
- args["NAME_SLURL"] = LLSLURL("agent", from_id, "about").getSLURLString();
- args["MESSAGE"] = message;
- args["MATURITY_STR"] = region_access_str;
- args["MATURITY_ICON"] = region_access_icn;
- args["REGION_CONTENT_MATURITY"] = region_access_lc;
- LLSD payload;
- payload["from_id"] = from_id;
- payload["lure_id"] = session_id;
- payload["godlike"] = FALSE;
- payload["region_maturity"] = region_access;
-
- if (!canUserAccessDstRegion)
- {
- LLNotification::Params params("TeleportOffered_MaturityBlocked");
- params.substitutions = args;
- params.payload = payload;
- LLPostponedNotification::add<LLPostponedOfferNotification>( params, from_id, false);
- send_simple_im(from_id, LLTrans::getString("TeleportMaturityExceeded"), IM_NOTHING_SPECIAL, session_id);
- send_simple_im(from_id, LLStringUtil::null, IM_LURE_DECLINED, session_id);
- }
- else if (doesUserRequireMaturityIncrease)
- {
- LLNotification::Params params("TeleportOffered_MaturityExceeded");
- params.substitutions = args;
- params.payload = payload;
- LLPostponedNotification::add<LLPostponedOfferNotification>( params, from_id, false);
- }
- else
- {
- LLNotification::Params params;
- if (IM_LURE_USER == dialog)
- {
- params.name = "TeleportOffered";
- params.functor.name = "TeleportOffered";
- }
- else if (IM_TELEPORT_REQUEST == dialog)
- {
- params.name = "TeleportRequest";
- params.functor.name = "TeleportRequest";
- }
-
- params.substitutions = args;
- params.payload = payload;
- LLPostponedNotification::add<LLPostponedOfferNotification>( params, from_id, false);
- }
- }
- }
- break;
-
- case IM_GODLIKE_LURE_USER:
- {
- LLVector3 pos, look_at;
- U64 region_handle(0);
- U8 region_access(SIM_ACCESS_MIN);
- std::string region_info = ll_safe_string((char*)binary_bucket, binary_bucket_size);
- std::string region_access_str = LLStringUtil::null;
- std::string region_access_icn = LLStringUtil::null;
- std::string region_access_lc = LLStringUtil::null;
-
- bool canUserAccessDstRegion = true;
- bool doesUserRequireMaturityIncrease = false;
-
- if (parse_lure_bucket(region_info, region_handle, pos, look_at, region_access))
- {
- region_access_str = LLViewerRegion::accessToString(region_access);
- region_access_icn = LLViewerRegion::getAccessIcon(region_access);
- region_access_lc = region_access_str;
- LLStringUtil::toLower(region_access_lc);
-
- if (!gAgent.isGodlike())
- {
- switch (region_access)
- {
- case SIM_ACCESS_MIN :
- case SIM_ACCESS_PG :
- break;
- case SIM_ACCESS_MATURE :
- if (gAgent.isTeen())
- {
- canUserAccessDstRegion = false;
- }
- else if (gAgent.prefersPG())
- {
- doesUserRequireMaturityIncrease = true;
- }
- break;
- case SIM_ACCESS_ADULT :
- if (!gAgent.isAdult())
- {
- canUserAccessDstRegion = false;
- }
- else if (!gAgent.prefersAdult())
- {
- doesUserRequireMaturityIncrease = true;
- }
- break;
- default :
- llassert(0);
- break;
- }
- }
- }
-
- LLSD args;
- // *TODO: Translate -> [FIRST] [LAST] (maybe)
- args["NAME_SLURL"] = LLSLURL("agent", from_id, "about").getSLURLString();
- args["MESSAGE"] = message;
- args["MATURITY_STR"] = region_access_str;
- args["MATURITY_ICON"] = region_access_icn;
- args["REGION_CONTENT_MATURITY"] = region_access_lc;
- LLSD payload;
- payload["from_id"] = from_id;
- payload["lure_id"] = session_id;
- payload["godlike"] = TRUE;
- payload["region_maturity"] = region_access;
-
- if (!canUserAccessDstRegion)
- {
- LLNotification::Params params("TeleportOffered_MaturityBlocked");
- params.substitutions = args;
- params.payload = payload;
- LLPostponedNotification::add<LLPostponedOfferNotification>( params, from_id, false);
- send_simple_im(from_id, LLTrans::getString("TeleportMaturityExceeded"), IM_NOTHING_SPECIAL, session_id);
- send_simple_im(from_id, LLStringUtil::null, IM_LURE_DECLINED, session_id);
- }
- else if (doesUserRequireMaturityIncrease)
- {
- LLNotification::Params params("TeleportOffered_MaturityExceeded");
- params.substitutions = args;
- params.payload = payload;
- LLPostponedNotification::add<LLPostponedOfferNotification>( params, from_id, false);
- }
- else
- {
- // do not show a message box, because you're about to be
- // teleported.
- LLNotifications::instance().forceResponse(LLNotification::Params("TeleportOffered").payload(payload), 0);
- }
- }
- break;
-
- case IM_GOTO_URL:
- {
- LLSD args;
- // n.b. this is for URLs sent by the system, not for
- // URLs sent by scripts (i.e. llLoadURL)
- if (binary_bucket_size <= 0)
- {
- LL_WARNS("Messaging") << "bad binary_bucket_size: "
- << binary_bucket_size
- << " - aborting function." << LL_ENDL;
- return;
- }
-
- std::string url;
-
- url.assign((char*)binary_bucket, binary_bucket_size-1);
- args["MESSAGE"] = message;
- args["URL"] = url;
- LLSD payload;
- payload["url"] = url;
- LLNotificationsUtil::add("GotoURL", args, payload );
- }
- break;
-
- case IM_FRIENDSHIP_OFFERED:
- {
- LLSD payload;
- payload["from_id"] = from_id;
- payload["session_id"] = session_id;;
- payload["online"] = (offline == IM_ONLINE);
- payload["sender"] = msg->getSender().getIPandPort();
-
- bool add_notification = true;
- for (LLToastNotifyPanel::instance_iter ti(LLToastNotifyPanel::beginInstances())
- , tend(LLToastNotifyPanel::endInstances()); ti != tend; ++ti)
- {
- LLToastNotifyPanel& panel = *ti;
- const std::string& notification_name = panel.getNotificationName();
- if (notification_name == "OfferFriendship" && panel.isControlPanelEnabled())
- {
- add_notification = false;
- break;
- }
- }
-
- if (is_muted && add_notification)
- {
- LLNotifications::instance().forceResponse(LLNotification::Params("OfferFriendship").payload(payload), 1);
- }
- else
- {
- if (is_do_not_disturb)
- {
- send_do_not_disturb_message(msg, from_id);
- }
- args["NAME_SLURL"] = LLSLURL("agent", from_id, "about").getSLURLString();
-
- if (add_notification)
- {
- if(message.empty())
- {
- //support for frienship offers from clients before July 2008
- LLNotificationsUtil::add("OfferFriendshipNoMessage", args, payload);
- }
- else
- {
- args["[MESSAGE]"] = message;
- LLNotification::Params params("OfferFriendship");
- params.substitutions = args;
- params.payload = payload;
- LLPostponedNotification::add<LLPostponedOfferNotification>( params, from_id, false);
- }
- }
- }
- }
- break;
-
- case IM_FRIENDSHIP_ACCEPTED:
- {
- // In the case of an offline IM, the formFriendship() may be extraneous
- // as the database should already include the relationship. But it
- // doesn't hurt for dupes.
- LLAvatarTracker::formFriendship(from_id);
-
- std::vector<std::string> strings;
- strings.push_back(from_id.asString());
- send_generic_message("requestonlinenotification", strings);
-
- args["NAME"] = name;
- LLSD payload;
- payload["from_id"] = from_id;
- LLAvatarNameCache::get(from_id, boost::bind(&notification_display_name_callback,_1,_2,"FriendshipAccepted",args,payload));
- }
- break;
-
- case IM_FRIENDSHIP_DECLINED_DEPRECATED:
- default:
- LL_WARNS("Messaging") << "Instant message calling for unknown dialog "
- << (S32)dialog << LL_ENDL;
- break;
- }
-
- LLWindow* viewer_window = gViewerWindow->getWindow();
- if (viewer_window && viewer_window->getMinimized())
- {
- viewer_window->flashIcon(5.f);
- }
+ LLUUID from_id;
+ BOOL from_group;
+ LLUUID to_id;
+ U8 offline;
+ U8 d = 0;
+ LLUUID session_id;
+ U32 timestamp;
+ std::string agentName;
+ std::string message;
+ U32 parent_estate_id = 0;
+ LLUUID region_id;
+ LLVector3 position;
+ U8 binary_bucket[MTUBYTES];
+ S32 binary_bucket_size;
+
+ // *TODO: Translate - need to fix the full name to first/last (maybe)
+ msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, from_id);
+ msg->getBOOLFast(_PREHASH_MessageBlock, _PREHASH_FromGroup, from_group);
+ msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_ToAgentID, to_id);
+ msg->getU8Fast(_PREHASH_MessageBlock, _PREHASH_Offline, offline);
+ msg->getU8Fast(_PREHASH_MessageBlock, _PREHASH_Dialog, d);
+ msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_ID, session_id);
+ msg->getU32Fast(_PREHASH_MessageBlock, _PREHASH_Timestamp, timestamp);
+ //msg->getData("MessageBlock", "Count", &count);
+ msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_FromAgentName, agentName);
+ msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_Message, message);
+ msg->getU32Fast(_PREHASH_MessageBlock, _PREHASH_ParentEstateID, parent_estate_id);
+ msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_RegionID, region_id);
+ msg->getVector3Fast(_PREHASH_MessageBlock, _PREHASH_Position, position);
+ msg->getBinaryDataFast(_PREHASH_MessageBlock, _PREHASH_BinaryBucket, binary_bucket, 0, 0, MTUBYTES);
+ binary_bucket_size = msg->getSizeFast(_PREHASH_MessageBlock, _PREHASH_BinaryBucket);
+ EInstantMessage dialog = (EInstantMessage)d;
+ LLHost sender = msg->getSender();
+
+ LLIMProcessing::processNewMessage(from_id,
+ from_group,
+ to_id,
+ offline,
+ dialog,
+ session_id,
+ timestamp,
+ agentName,
+ message,
+ parent_estate_id,
+ region_id,
+ position,
+ binary_bucket,
+ binary_bucket_size,
+ sender);
}
void send_do_not_disturb_message (LLMessageSystem* msg, const LLUUID& from_id, const LLUUID& session_id)
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 5d49c888cf..955cc79283 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -134,6 +134,7 @@ std::map<std::string, U32> LLViewerObject::sObjectDataMap;
// JC 3/18/2003
const F32 PHYSICS_TIMESTEP = 1.f / 45.f;
+const U32 MAX_INV_FILE_READ_FAILS = 25;
static LLTrace::BlockTimerStatHandle FTM_CREATE_OBJECT("Create Object");
@@ -3063,6 +3064,7 @@ BOOL LLViewerObject::loadTaskInvFile(const std::string& filename)
llifstream ifs(filename_and_local_path.c_str());
if(ifs.good())
{
+ U32 fail_count = 0;
char buffer[MAX_STRING]; /* Flawfinder: ignore */
// *NOTE: This buffer size is hard coded into scanf() below.
char keyword[MAX_STRING]; /* Flawfinder: ignore */
@@ -3077,8 +3079,14 @@ BOOL LLViewerObject::loadTaskInvFile(const std::string& filename)
while(ifs.good())
{
ifs.getline(buffer, MAX_STRING);
- sscanf(buffer, " %254s", keyword); /* Flawfinder: ignore */
- if(0 == strcmp("inv_item", keyword))
+ if (sscanf(buffer, " %254s", keyword) == EOF) /* Flawfinder: ignore */
+ {
+ // Blank file?
+ LL_WARNS() << "Issue reading from file '"
+ << filename << "'" << LL_ENDL;
+ break;
+ }
+ else if(0 == strcmp("inv_item", keyword))
{
LLPointer<LLInventoryObject> inv = new LLViewerInventoryItem;
inv->importLegacyStream(ifs);
@@ -3091,9 +3099,17 @@ BOOL LLViewerObject::loadTaskInvFile(const std::string& filename)
inv->rename("Contents");
mInventory->push_front(inv);
}
+ else if (fail_count >= MAX_INV_FILE_READ_FAILS)
+ {
+ LL_WARNS() << "Encountered too many unknowns while reading from file: '"
+ << filename << "'" << LL_ENDL;
+ break;
+ }
else
{
- LL_WARNS() << "Unknown token in inventory file '"
+ // Is there really a point to continue processing? We already failing to display full inventory
+ fail_count++;
+ LL_WARNS_ONCE() << "Unknown token while reading from inventory file. Token: '"
<< keyword << "'" << LL_ENDL;
}
}
@@ -4376,10 +4392,10 @@ void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry)
if (getTE(te)->getMaterialParams().notNull())
{
const LLUUID& norm_id = getTE(te)->getMaterialParams()->getNormalID();
- mTENormalMaps[te] = LLViewerTextureManager::getFetchedTexture(norm_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ mTENormalMaps[te] = LLViewerTextureManager::getFetchedTexture(norm_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM, LLViewerTexture::LOD_TEXTURE);
const LLUUID& spec_id = getTE(te)->getMaterialParams()->getSpecularID();
- mTESpecularMaps[te] = LLViewerTextureManager::getFetchedTexture(spec_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ mTESpecularMaps[te] = LLViewerTextureManager::getFetchedTexture(spec_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM, LLViewerTexture::LOD_TEXTURE);
}
}
@@ -4502,14 +4518,14 @@ S32 LLViewerObject::setTETexture(const U8 te, const LLUUID& uuid)
S32 LLViewerObject::setTENormalMap(const U8 te, const LLUUID& uuid)
{
LLViewerFetchedTexture *image = (uuid == LLUUID::null) ? NULL : LLViewerTextureManager::getFetchedTexture(
- uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost());
+ uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost());
return setTENormalMapCore(te, image);
}
S32 LLViewerObject::setTESpecularMap(const U8 te, const LLUUID& uuid)
{
LLViewerFetchedTexture *image = (uuid == LLUUID::null) ? NULL : LLViewerTextureManager::getFetchedTexture(
- uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost());
+ uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost());
return setTESpecularMapCore(te, image);
}
@@ -5894,6 +5910,14 @@ void LLViewerObject::markForUpdate(BOOL priority)
}
}
+void LLViewerObject::markForUnload(BOOL priority)
+{
+ if (mDrawable.notNull())
+ {
+ gPipeline.markRebuild(mDrawable, LLDrawable::FOR_UNLOAD, priority);
+ }
+}
+
bool LLViewerObject::isPermanentEnforced() const
{
return flagObjectPermanent() && (mRegionp != gAgent.getRegion()) && !gAgent.isGodlike();
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 21c95d5533..d61832c2ad 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -412,6 +412,7 @@ public:
void clearIcon();
void markForUpdate(BOOL priority);
+ void markForUnload(BOOL priority);
void updateVolume(const LLVolumeParams& volume_params);
virtual void updateSpatialExtents(LLVector4a& min, LLVector4a& max);
virtual F32 getBinRadius();
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index dc54346d59..23a51b99f6 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -1046,9 +1046,11 @@ void LLViewerObjectList::fetchObjectCostsCoro(std::string url)
mPendingObjectCost.begin(), mPendingObjectCost.end(),
std::inserter(diff, diff.begin()));
+ mStaleObjectCost.clear();
+
if (diff.empty())
{
- LL_INFOS() << "No outstanding object IDs to request." << LL_ENDL;
+ LL_INFOS() << "No outstanding object IDs to request. Pending count: " << mPendingObjectCost.size() << LL_ENDL;
return;
}
@@ -1057,7 +1059,6 @@ void LLViewerObjectList::fetchObjectCostsCoro(std::string url)
for (uuid_set_t::iterator it = diff.begin(); it != diff.end(); ++it)
{
idList.append(*it);
- mStaleObjectCost.erase(*it);
}
mPendingObjectCost.insert(diff.begin(), diff.end());
@@ -1094,9 +1095,7 @@ void LLViewerObjectList::fetchObjectCostsCoro(std::string url)
{
LLUUID objectId = it->asUUID();
- // If the object was added to the StaleObjectCost set after it had been
- // added to mPendingObjectCost it would still be in the StaleObjectCost
- // set when we got the response back.
+ // Object could have been added to the mStaleObjectCost after request started
mStaleObjectCost.erase(objectId);
mPendingObjectCost.erase(objectId);
diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp
index 023f1b92ba..5f0e21db71 100644
--- a/indra/newview/llvieweroctree.cpp
+++ b/indra/newview/llvieweroctree.cpp
@@ -465,7 +465,7 @@ LLViewerOctreeGroup::LLViewerOctreeGroup(OctreeNode* node)
{
LLVector4a tmp;
tmp.splat(0.f);
- mExtents[0] = mExtents[1] = mObjectBounds[0] = mObjectBounds[0] = mObjectBounds[1] =
+ mExtents[0] = mExtents[1] = mObjectBounds[0] = mObjectBounds[1] =
mObjectExtents[0] = mObjectExtents[1] = tmp;
mBounds[0] = node->getCenter();
diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp
index 25cf082751..e5265f1dcd 100644
--- a/indra/newview/llviewerpartsim.cpp
+++ b/indra/newview/llviewerpartsim.cpp
@@ -662,9 +662,6 @@ void LLViewerPartSim::updateSimulation()
{
static LLFrameTimer update_timer;
- //reset VBO cursor
- LLVOPartGroup::sVBSlotCursor = 0;
-
const F32 dt = llmin(update_timer.getElapsedTimeAndResetF32(), 0.1f);
if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES)))
diff --git a/indra/newview/llviewerpartsource.cpp b/indra/newview/llviewerpartsource.cpp
index 814060f4f2..998ae52fe0 100644
--- a/indra/newview/llviewerpartsource.cpp
+++ b/indra/newview/llviewerpartsource.cpp
@@ -40,6 +40,25 @@
#include "llworld.h"
#include "pipeline.h"
+
+static LLVOAvatar* find_avatar(const LLUUID& id)
+{
+ LLViewerObject *obj = gObjectList.findObject(id);
+ while (obj && obj->isAttachment())
+ {
+ obj = (LLViewerObject *)obj->getParent();
+ }
+
+ if (obj && obj->isAvatar())
+ {
+ return (LLVOAvatar*)obj;
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
LLViewerPartSource::LLViewerPartSource(const U32 type) :
mType(type),
mOwnerUUID(LLUUID::null),
@@ -113,6 +132,15 @@ void LLViewerPartSourceScript::update(const F32 dt)
if( mIsSuspended )
return;
+ if (mOwnerAvatarp.isNull() && mOwnerUUID != LLUUID::null)
+ {
+ mOwnerAvatarp = find_avatar(mOwnerUUID);
+ }
+ if (mOwnerAvatarp.notNull() && LLVOAvatar::AV_DO_NOT_RENDER == mOwnerAvatarp->getVisualMuteSettings())
+ {
+ return;
+ }
+
F32 old_update_time = mLastUpdateTime;
mLastUpdateTime += dt;
diff --git a/indra/newview/llviewerpartsource.h b/indra/newview/llviewerpartsource.h
index 12e926173b..504229e81f 100644
--- a/indra/newview/llviewerpartsource.h
+++ b/indra/newview/llviewerpartsource.h
@@ -42,6 +42,7 @@
class LLViewerTexture;
class LLViewerObject;
class LLViewerPart;
+class LLVOAvatar;
class LLViewerPartSource : public LLRefCount
{
@@ -85,6 +86,7 @@ protected:
F32 mLastUpdateTime;
F32 mLastPartTime;
LLUUID mOwnerUUID;
+ LLPointer<LLVOAvatar> mOwnerAvatarp;
LLPointer<LLViewerTexture> mImagep;
// Particle information
U32 mPartFlags; // Flags for the particle
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 5b61eab5f7..feaafad2e1 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -290,6 +290,13 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
continue;
}
+ if (!result.isMap() || result.has("error"))
+ {
+ LL_WARNS("AppInit", "Capabilities") << "Malformed response" << LL_ENDL;
+ // setup for retry.
+ continue;
+ }
+
LLSD httpResults = result["http_result"];
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
if (!status)
@@ -1870,7 +1877,7 @@ void LLViewerRegion::updateNetStats()
mLastPacketsLost = mPacketsLost;
mPacketsIn = cdp->getPacketsIn();
- mBitsIn = 8 * cdp->getBytesIn();
+ mBitsIn = cdp->getBytesIn();
mPacketsOut = cdp->getPacketsOut();
mPacketsLost = cdp->getPacketsLost();
mPingDelay = cdp->getPingDelay();
@@ -2809,6 +2816,7 @@ void LLViewerRegion::unpackRegionHandshake()
void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
{
+ capabilityNames.append("AbuseCategories");
capabilityNames.append("AgentPreferences");
capabilityNames.append("AgentState");
capabilityNames.append("AttachmentResources");
@@ -2868,6 +2876,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("ParcelVoiceInfoRequest");
capabilityNames.append("ProductInfoRequest");
capabilityNames.append("ProvisionVoiceAccountRequest");
+ //capabilityNames.append("ReadOfflineMsgs");
capabilityNames.append("RemoteParcelRequest");
capabilityNames.append("RenderMaterials");
capabilityNames.append("RequestTextureDownload");
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 3e0cec0f09..ff7647a7e4 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -2811,6 +2811,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gSkinnedObjectSimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
gSkinnedObjectSimpleWaterProgram.mFeatures.hasObjectSkinning = true;
gSkinnedObjectSimpleWaterProgram.mFeatures.disableTextureIndex = true;
+ gSkinnedObjectSimpleWaterProgram.mFeatures.hasAlphaMask = true;
gSkinnedObjectSimpleWaterProgram.mShaderFiles.clear();
gSkinnedObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
gSkinnedObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index e5a1bed48c..39ffbfc989 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -651,14 +651,16 @@ void LLViewerTexture::init(bool firstinit)
mAdditionalDecodePriority = 0.f;
mParcelMedia = NULL;
- mNumVolumes = 0;
+ memset(&mNumVolumes, 0, sizeof(U32)* LLRender::NUM_VOLUME_TEXTURE_CHANNELS);
mFaceList[LLRender::DIFFUSE_MAP].clear();
mFaceList[LLRender::NORMAL_MAP].clear();
mFaceList[LLRender::SPECULAR_MAP].clear();
mNumFaces[LLRender::DIFFUSE_MAP] =
mNumFaces[LLRender::NORMAL_MAP] =
mNumFaces[LLRender::SPECULAR_MAP] = 0;
- mVolumeList.clear();
+
+ mVolumeList[LLRender::LIGHT_TEX].clear();
+ mVolumeList[LLRender::SCULPT_TEX].clear();
}
//virtual
@@ -674,7 +676,8 @@ void LLViewerTexture::cleanup()
mFaceList[LLRender::DIFFUSE_MAP].clear();
mFaceList[LLRender::NORMAL_MAP].clear();
mFaceList[LLRender::SPECULAR_MAP].clear();
- mVolumeList.clear();
+ mVolumeList[LLRender::LIGHT_TEX].clear();
+ mVolumeList[LLRender::SCULPT_TEX].clear();
}
void LLViewerTexture::notifyAboutCreatingTexture()
@@ -715,6 +718,7 @@ void LLViewerTexture::setBoostLevel(S32 level)
{
mBoostLevel = level;
if(mBoostLevel != LLViewerTexture::BOOST_NONE &&
+ mBoostLevel != LLViewerTexture::BOOST_ALM &&
mBoostLevel != LLViewerTexture::BOOST_SELECTED &&
mBoostLevel != LLViewerTexture::BOOST_ICON)
{
@@ -891,40 +895,40 @@ S32 LLViewerTexture::getNumFaces(U32 ch) const
//virtual
-void LLViewerTexture::addVolume(LLVOVolume* volumep)
+void LLViewerTexture::addVolume(U32 ch, LLVOVolume* volumep)
{
- if( mNumVolumes >= mVolumeList.size())
+ if (mNumVolumes[ch] >= mVolumeList[ch].size())
{
- mVolumeList.resize(2 * mNumVolumes + 1);
+ mVolumeList[ch].resize(2 * mNumVolumes[ch] + 1);
}
- mVolumeList[mNumVolumes] = volumep;
- volumep->setIndexInTex(mNumVolumes);
- mNumVolumes++;
+ mVolumeList[ch][mNumVolumes[ch]] = volumep;
+ volumep->setIndexInTex(ch, mNumVolumes[ch]);
+ mNumVolumes[ch]++;
mLastVolumeListUpdateTimer.reset();
}
//virtual
-void LLViewerTexture::removeVolume(LLVOVolume* volumep)
+void LLViewerTexture::removeVolume(U32 ch, LLVOVolume* volumep)
{
- if(mNumVolumes > 1)
+ if (mNumVolumes[ch] > 1)
{
- S32 index = volumep->getIndexInTex();
- llassert(index < mVolumeList.size());
- llassert(index < mNumVolumes);
- mVolumeList[index] = mVolumeList[--mNumVolumes];
- mVolumeList[index]->setIndexInTex(index);
+ S32 index = volumep->getIndexInTex(ch);
+ llassert(index < mVolumeList[ch].size());
+ llassert(index < mNumVolumes[ch]);
+ mVolumeList[ch][index] = mVolumeList[ch][--mNumVolumes[ch]];
+ mVolumeList[ch][index]->setIndexInTex(ch, index);
}
else
{
- mVolumeList.clear();
- mNumVolumes = 0;
+ mVolumeList[ch].clear();
+ mNumVolumes[ch] = 0;
}
mLastVolumeListUpdateTimer.reset();
}
-S32 LLViewerTexture::getNumVolumes() const
+S32 LLViewerTexture::getNumVolumes(U32 ch) const
{
- return mNumVolumes;
+ return mNumVolumes[ch];
}
void LLViewerTexture::reorganizeFaceList()
@@ -955,9 +959,13 @@ void LLViewerTexture::reorganizeVolumeList()
static const F32 MAX_WAIT_TIME = 20.f; // seconds
static const U32 MAX_EXTRA_BUFFER_SIZE = 4;
- if(mNumVolumes + MAX_EXTRA_BUFFER_SIZE > mVolumeList.size())
+
+ for (U32 i = 0; i < LLRender::NUM_VOLUME_TEXTURE_CHANNELS; ++i)
{
- return;
+ if (mNumVolumes[i] + MAX_EXTRA_BUFFER_SIZE > mVolumeList[i].size())
+ {
+ return;
+ }
}
if(mLastVolumeListUpdateTimer.getElapsedTimeF32() < MAX_WAIT_TIME)
@@ -966,7 +974,10 @@ void LLViewerTexture::reorganizeVolumeList()
}
mLastVolumeListUpdateTimer.reset();
- mVolumeList.erase(mVolumeList.begin() + mNumVolumes, mVolumeList.end());
+ for (U32 i = 0; i < LLRender::NUM_VOLUME_TEXTURE_CHANNELS; ++i)
+ {
+ mVolumeList[i].erase(mVolumeList[i].begin() + mNumVolumes[i], mVolumeList[i].end());
+ }
}
//virtual
@@ -1547,6 +1558,10 @@ void LLViewerFetchedTexture::processTextureStats()
{
mDesiredDiscardLevel = 0;
}
+ else if (!LLPipeline::sRenderDeferred && mBoostLevel == LLGLTexture::BOOST_ALM)
+ {
+ mDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1;
+ }
else if (mDontDiscard && mBoostLevel == LLGLTexture::BOOST_ICON)
{
if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT)
@@ -1814,8 +1829,9 @@ void LLViewerFetchedTexture::updateVirtualSize()
{
if(drawable->isRecentlyVisible())
{
- if (getBoostLevel() == LLViewerTexture::BOOST_NONE &&
- drawable->getVObj() && drawable->getVObj()->isSelected())
+ if ((getBoostLevel() == LLViewerTexture::BOOST_NONE || getBoostLevel() == LLViewerTexture::BOOST_ALM)
+ && drawable->getVObj()
+ && drawable->getVObj()->isSelected())
{
setBoostLevel(LLViewerTexture::BOOST_SELECTED);
}
@@ -1832,6 +1848,7 @@ void LLViewerFetchedTexture::updateVirtualSize()
if (getBoostLevel() == LLViewerTexture::BOOST_SELECTED &&
gFrameTimeSeconds - mSelectedTime > SELECTION_RESET_TIME)
{
+ // Could have been BOOST_ALM, but if user was working with this texture, better keep it as NONE
setBoostLevel(LLViewerTexture::BOOST_NONE);
}
@@ -2105,7 +2122,7 @@ bool LLViewerFetchedTexture::updateFetch()
// Load the texture progressively: we try not to rush to the desired discard too fast.
// If the camera is not moving, we do not tweak the discard level notch by notch but go to the desired discard with larger boosted steps
// This mitigates the "textures stay blurry" problem when loading while not killing the texture memory while moving around
- S32 delta_level = (mBoostLevel > LLGLTexture::BOOST_NONE) ? 2 : 1;
+ S32 delta_level = (mBoostLevel > LLGLTexture::BOOST_ALM) ? 2 : 1;
if (current_discard < 0)
{
desired_discard = llmax(desired_discard, getMaxDiscardLevel() - delta_level);
@@ -3117,6 +3134,10 @@ void LLViewerLODTexture::processTextureStats()
if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT)
mDesiredDiscardLevel = 1; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048
}
+ else if (!LLPipeline::sRenderDeferred && mBoostLevel == LLGLTexture::BOOST_ALM)
+ {
+ mDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1;
+ }
else if (mBoostLevel < LLGLTexture::BOOST_HIGH && mMaxVirtualSize <= 10.f)
{
// If the image has not been significantly visible in a while, we don't want it
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index c9dea17f63..5d89f9f029 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -156,10 +156,10 @@ public:
S32 getNumFaces(U32 ch) const;
const ll_face_list_t* getFaceList(U32 channel) const {llassert(channel < LLRender::NUM_TEXTURE_CHANNELS); return &mFaceList[channel];}
- virtual void addVolume(LLVOVolume* volumep);
- virtual void removeVolume(LLVOVolume* volumep);
- S32 getNumVolumes() const;
- const ll_volume_list_t* getVolumeList() const { return &mVolumeList; }
+ virtual void addVolume(U32 channel, LLVOVolume* volumep);
+ virtual void removeVolume(U32 channel, LLVOVolume* volumep);
+ S32 getNumVolumes(U32 channel) const;
+ const ll_volume_list_t* getVolumeList(U32 channel) const { return &mVolumeList[channel]; }
virtual void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) ;
@@ -201,8 +201,8 @@ protected:
U32 mNumFaces[LLRender::NUM_TEXTURE_CHANNELS];
LLFrameTimer mLastFaceListUpdateTimer ;
- ll_volume_list_t mVolumeList;
- U32 mNumVolumes;
+ ll_volume_list_t mVolumeList[LLRender::NUM_VOLUME_TEXTURE_CHANNELS];
+ U32 mNumVolumes[LLRender::NUM_VOLUME_TEXTURE_CHANNELS];
LLFrameTimer mLastVolumeListUpdateTimer;
//do not use LLPointer here.
diff --git a/indra/newview/llviewertextureanim.cpp b/indra/newview/llviewertextureanim.cpp
index 9af92d7377..9603811066 100644
--- a/indra/newview/llviewertextureanim.cpp
+++ b/indra/newview/llviewertextureanim.cpp
@@ -146,6 +146,8 @@ S32 LLViewerTextureAnim::animateTextures(F32 &off_s, F32 &off_t,
if (!(mMode & SMOOTH))
{
frame_counter = (F32)llfloor(frame_counter + 0.01f);
+ // account for 0.01, we shouldn't step over full length
+ frame_counter = llmin(full_length - 1.f, frame_counter);
}
if (mMode & PING_PONG)
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index 45ea169fb8..4308405c64 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -509,6 +509,12 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,
LLPointer<LLViewerFetchedTexture> imagep = findImage(image_id, get_element_type(boost_priority));
if (!imagep.isNull())
{
+ if (boost_priority != LLViewerTexture::BOOST_ALM && imagep->getBoostLevel() == LLViewerTexture::BOOST_ALM)
+ {
+ // Workaround: we need BOOST_ALM texture for something, 'rise' to NONE
+ imagep->setDecodePriority(LLViewerTexture::BOOST_NONE);
+ }
+
LLViewerFetchedTexture *texture = imagep.get();
if (request_from_host.isOk() &&
!texture->getTargetHost().isOk())
diff --git a/indra/newview/llviewerthrottle.cpp b/indra/newview/llviewerthrottle.cpp
index 22de7e150b..2729253d18 100644
--- a/indra/newview/llviewerthrottle.cpp
+++ b/indra/newview/llviewerthrottle.cpp
@@ -46,7 +46,7 @@ const F32 MAX_FRACTIONAL = 1.5f;
const F32 MIN_FRACTIONAL = 0.2f;
const F32 MIN_BANDWIDTH = 50.f;
-const F32 MAX_BANDWIDTH = 3000.f;
+const F32 MAX_BANDWIDTH = 6000.f;
const F32 STEP_FRACTIONAL = 0.1f;
const LLUnit<F32, LLUnits::Percent> TIGHTEN_THROTTLE_THRESHOLD(3.0f); // packet loss % per s
const LLUnit<F32, LLUnits::Percent> EASE_THROTTLE_THRESHOLD(0.5f); // packet loss % per s
diff --git a/indra/newview/llviewerwearable.cpp b/indra/newview/llviewerwearable.cpp
index ae9ce37a28..2d7a0f920f 100644
--- a/indra/newview/llviewerwearable.cpp
+++ b/indra/newview/llviewerwearable.cpp
@@ -301,7 +301,7 @@ void LLViewerWearable::setTexturesToDefaults()
LLUUID LLViewerWearable::getDefaultTextureImageID(ETextureIndex index) const
{
const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(index);
- const std::string &default_image_name = texture_dict->mDefaultImageName;
+ const std::string &default_image_name = texture_dict ? texture_dict->mDefaultImageName : "";
if (default_image_name == "")
{
return IMG_DEFAULT_AVATAR;
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 74deaffe16..f394d6913f 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -261,10 +261,8 @@ static const F32 MIN_UI_SCALE = 0.75f;
static const F32 MAX_UI_SCALE = 7.0f;
static const F32 MIN_DISPLAY_SCALE = 0.75f;
-std::string LLViewerWindow::sSnapshotBaseName;
-std::string LLViewerWindow::sSnapshotDir;
-
-std::string LLViewerWindow::sMovieBaseName;
+static LLCachedControl<std::string> sSnapshotBaseName(LLCachedControl<std::string>(gSavedPerAccountSettings, "SnapshotBaseName", "Snapshot"));
+static LLCachedControl<std::string> sSnapshotDir(LLCachedControl<std::string>(gSavedPerAccountSettings, "SnapshotBaseDir", ""));
LLTrace::SampleStatHandle<> LLViewerWindow::sMouseVelocityStat("Mouse Velocity");
@@ -393,14 +391,12 @@ public:
}
}
-#if LL_WINDOWS
if (gSavedSettings.getBOOL("DebugShowMemory"))
{
addText(xpos, ypos,
STRINGIZE("Memory: " << (LLMemory::getCurrentRSS() / 1024) << " (KB)"));
ypos += y_inc;
}
-#endif
if (gDisplayCameraPos)
{
@@ -614,7 +610,7 @@ public:
if (last_frame_recording.getSampleCount(LLPipeline::sStatBatchSize) > 0)
{
- addText(xpos, ypos, llformat("Batch min/max/mean: %d/%d/%d", last_frame_recording.getMin(LLPipeline::sStatBatchSize), last_frame_recording.getMax(LLPipeline::sStatBatchSize), last_frame_recording.getMean(LLPipeline::sStatBatchSize)));
+ addText(xpos, ypos, llformat("Batch min/max/mean: %d/%d/%d", (U32)last_frame_recording.getMin(LLPipeline::sStatBatchSize), (U32)last_frame_recording.getMax(LLPipeline::sStatBatchSize), (U32)last_frame_recording.getMean(LLPipeline::sStatBatchSize)));
}
ypos += y_inc;
@@ -731,7 +727,8 @@ public:
addText(xpos, ypos, "View Matrix");
ypos += y_inc;
}
- if (gSavedSettings.getBOOL("DebugShowColor"))
+ // disable use of glReadPixels which messes up nVidia nSight graphics debugging
+ if (gSavedSettings.getBOOL("DebugShowColor") && !LLRender::sNsightDebugSupport)
{
U8 color[4];
LLCoordGL coord = gViewerWindow->getCurrentMouse();
@@ -740,16 +737,6 @@ public:
ypos += y_inc;
}
- if (gSavedSettings.getBOOL("DebugShowPrivateMem"))
- {
- LLPrivateMemoryPoolManager::getInstance()->updateStatistics() ;
- addText(xpos, ypos, llformat("Total Reserved(KB): %d", LLPrivateMemoryPoolManager::getInstance()->mTotalReservedSize / 1024));
- ypos += y_inc;
-
- addText(xpos, ypos, llformat("Total Allocated(KB): %d", LLPrivateMemoryPoolManager::getInstance()->mTotalAllocatedSize / 1024));
- ypos += y_inc;
- }
-
// only display these messages if we are actually rendering beacons at this moment
if (LLPipeline::getRenderBeacons() && LLFloaterReg::instanceVisible("beacons"))
{
@@ -1703,11 +1690,6 @@ LLViewerWindow::LLViewerWindow(const Params& p)
LL_INFOS() << "NOTE: ALL NOTIFICATIONS THAT OCCUR WILL GET ADDED TO IGNORE LIST FOR LATER RUNS." << LL_ENDL;
}
- // Default to application directory.
- LLViewerWindow::sSnapshotBaseName = "Snapshot";
- LLViewerWindow::sMovieBaseName = "SLmovie";
- resetSnapshotLoc();
-
/*
LLWindowCallbacks* callbacks,
@@ -1886,6 +1868,11 @@ void LLViewerWindow::showSystemUIScaleFactorChanged()
LLNotificationsUtil::add("SystemUIScaleFactorChanged", LLSD(), LLSD(), onSystemUIScaleFactorChanged);
}
+std::string LLViewerWindow::getLastSnapshotDir()
+{
+ return sSnapshotDir;
+}
+
//static
bool LLViewerWindow::onSystemUIScaleFactorChanged(const LLSD& notification, const LLSD& response)
{
@@ -1955,6 +1942,10 @@ void LLViewerWindow::initBase()
// Create global views
+ // Login screen and main_view.xml need edit menus for preferences and browser
+ LL_DEBUGS("AppInit") << "initializing edit menu" << LL_ENDL;
+ initialize_edit_menu();
+
// Create the floater view at the start so that other views can add children to it.
// (But wait to add it as a child of the root view so that it will be in front of the
// other views.)
@@ -2165,6 +2156,15 @@ void LLViewerWindow::shutdownViews()
RecordToChatConsole::getInstance()->stopRecorder();
LL_INFOS() << "Warning logger is cleaned." << LL_ENDL ;
+ gFocusMgr.unlockFocus();
+ gFocusMgr.setMouseCapture(NULL);
+ gFocusMgr.setKeyboardFocus(NULL);
+ gFocusMgr.setTopCtrl(NULL);
+ if (mWindow)
+ {
+ mWindow->allowLanguageTextInput(NULL, FALSE);
+ }
+
delete mDebugText;
mDebugText = NULL;
@@ -2197,7 +2197,11 @@ void LLViewerWindow::shutdownViews()
view_listener_t::cleanup();
LL_INFOS() << "view listeners destroyed." << LL_ENDL ;
-
+
+ // Clean up pointers that are going to be invalid. (todo: check sMenuContainer)
+ mProgressView = NULL;
+ mPopupView = NULL;
+
// Delete all child views.
delete mRootView;
mRootView = NULL;
@@ -4406,20 +4410,21 @@ BOOL LLViewerWindow::saveImageNumbered(LLImageFormatted *image, BOOL force_picke
// Copy the directory + file name
std::string filepath = picker.getFirstFile();
- LLViewerWindow::sSnapshotBaseName = gDirUtilp->getBaseFileName(filepath, true);
- LLViewerWindow::sSnapshotDir = gDirUtilp->getDirName(filepath);
+ gSavedPerAccountSettings.setString("SnapshotBaseName", gDirUtilp->getBaseFileName(filepath, true));
+ gSavedPerAccountSettings.setString("SnapshotBaseDir", gDirUtilp->getDirName(filepath));
}
- if(LLViewerWindow::sSnapshotDir.empty())
+ std::string snapshot_dir = sSnapshotDir;
+ if(snapshot_dir.empty())
{
return FALSE;
}
// Check if there is enough free space to save snapshot
#ifdef LL_WINDOWS
- boost::filesystem::space_info b_space = boost::filesystem::space(utf8str_to_utf16str(sSnapshotDir));
+ boost::filesystem::space_info b_space = boost::filesystem::space(utf8str_to_utf16str(snapshot_dir));
#else
- boost::filesystem::space_info b_space = boost::filesystem::space(sSnapshotDir);
+ boost::filesystem::space_info b_space = boost::filesystem::space(snapshot_dir);
#endif
if (b_space.free < image->getDataSize())
{
@@ -4457,7 +4462,7 @@ BOOL LLViewerWindow::saveImageNumbered(LLImageFormatted *image, BOOL force_picke
void LLViewerWindow::resetSnapshotLoc()
{
- sSnapshotDir.clear();
+ gSavedPerAccountSettings.setString("SnapshotBaseDir", std::string());
}
// static
@@ -4511,6 +4516,17 @@ void LLViewerWindow::playSnapshotAnimAndSound()
send_sound_trigger(LLUUID(gSavedSettings.getString("UISndSnapshot")), 1.0f);
}
+BOOL LLViewerWindow::isSnapshotLocSet() const
+{
+ std::string snapshot_dir = sSnapshotDir;
+ return !snapshot_dir.empty();
+}
+
+void LLViewerWindow::resetSnapshotLoc() const
+{
+ gSavedPerAccountSettings.setString("SnapshotBaseDir", std::string());
+}
+
BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type)
{
return rawSnapshot(raw, preview_width, preview_height, FALSE, FALSE, show_ui, do_rebuild, type);
@@ -4727,36 +4743,39 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
{
LLAppViewer::instance()->pingMainloopTimeout("LLViewerWindow::rawSnapshot");
}
-
- if (type == LLSnapshotModel::SNAPSHOT_TYPE_COLOR)
+ // disable use of glReadPixels when doing nVidia nSight graphics debugging
+ if (!LLRender::sNsightDebugSupport)
{
- glReadPixels(
+ if (type == LLSnapshotModel::SNAPSHOT_TYPE_COLOR)
+ {
+ glReadPixels(
subimage_x_offset, out_y + subimage_y_offset,
read_width, 1,
GL_RGB, GL_UNSIGNED_BYTE,
raw->getData() + output_buffer_offset
);
- }
- else // LLSnapshotModel::SNAPSHOT_TYPE_DEPTH
- {
- LLPointer<LLImageRaw> depth_line_buffer = new LLImageRaw(read_width, 1, sizeof(GL_FLOAT)); // need to store floating point values
- glReadPixels(
- subimage_x_offset, out_y + subimage_y_offset,
- read_width, 1,
- GL_DEPTH_COMPONENT, GL_FLOAT,
- depth_line_buffer->getData()// current output pixel is beginning of buffer...
- );
-
- for (S32 i = 0; i < (S32)read_width; i++)
+ }
+ else // LLSnapshotModel::SNAPSHOT_TYPE_DEPTH
{
- F32 depth_float = *(F32*)(depth_line_buffer->getData() + (i * sizeof(F32)));
-
- F32 linear_depth_float = 1.f / (depth_conversion_factor_1 - (depth_float * depth_conversion_factor_2));
- U8 depth_byte = F32_to_U8(linear_depth_float, LLViewerCamera::getInstance()->getNear(), LLViewerCamera::getInstance()->getFar());
- // write converted scanline out to result image
- for (S32 j = 0; j < raw->getComponents(); j++)
+ LLPointer<LLImageRaw> depth_line_buffer = new LLImageRaw(read_width, 1, sizeof(GL_FLOAT)); // need to store floating point values
+ glReadPixels(
+ subimage_x_offset, out_y + subimage_y_offset,
+ read_width, 1,
+ GL_DEPTH_COMPONENT, GL_FLOAT,
+ depth_line_buffer->getData()// current output pixel is beginning of buffer...
+ );
+
+ for (S32 i = 0; i < (S32)read_width; i++)
{
- *(raw->getData() + output_buffer_offset + (i * raw->getComponents()) + j) = depth_byte;
+ F32 depth_float = *(F32*)(depth_line_buffer->getData() + (i * sizeof(F32)));
+
+ F32 linear_depth_float = 1.f / (depth_conversion_factor_1 - (depth_float * depth_conversion_factor_2));
+ U8 depth_byte = F32_to_U8(linear_depth_float, LLViewerCamera::getInstance()->getNear(), LLViewerCamera::getInstance()->getFar());
+ // write converted scanline out to result image
+ for (S32 j = 0; j < raw->getComponents(); j++)
+ {
+ *(raw->getData() + output_buffer_offset + (i * raw->getComponents()) + j) = depth_byte;
+ }
}
}
}
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index 38178fa910..c01921641c 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -350,8 +350,8 @@ public:
BOOL rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, BOOL keep_window_aspect = TRUE, BOOL is_texture = FALSE,
BOOL show_ui = TRUE, BOOL do_rebuild = FALSE, LLSnapshotModel::ESnapshotLayerType type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR, S32 max_size = MAX_SNAPSHOT_IMAGE_SIZE);
BOOL thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type);
- BOOL isSnapshotLocSet() const { return ! sSnapshotDir.empty(); }
- void resetSnapshotLoc() const { sSnapshotDir.clear(); }
+ BOOL isSnapshotLocSet() const;
+ void resetSnapshotLoc() const;
BOOL saveImageNumbered(LLImageFormatted *image, BOOL force_picker, BOOL& insufficient_memory);
// Reset the directory where snapshots are saved.
@@ -419,7 +419,7 @@ public:
bool getSystemUIScaleFactorChanged() { return mSystemUIScaleFactorChanged; }
static void showSystemUIScaleFactorChanged();
- static std::string getLastSnapshotDir() { return sSnapshotDir; }
+ static std::string getLastSnapshotDir();
private:
bool shouldShowToolTipFor(LLMouseHandler *mh);
@@ -504,11 +504,6 @@ private:
boost::scoped_ptr<LLWindowListener> mWindowListener;
boost::scoped_ptr<LLViewerWindowListener> mViewerWindowListener;
- static std::string sSnapshotBaseName;
- static std::string sSnapshotDir;
-
- static std::string sMovieBaseName;
-
// Object temporarily hovered over while dragging
LLPointer<LLViewerObject> mDragHoveredObject;
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index eae8f2cc56..b221dc7c35 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -1007,7 +1007,7 @@ void LLVOAvatar::dumpBakedStatus()
const ETextureIndex index = baked_dict->mTextureIndex;
if (!inst->isTextureDefined(index))
{
- LL_CONT << " " << LLAvatarAppearanceDictionary::getInstance()->getTexture(index)->mName;
+ LL_CONT << " " << (LLAvatarAppearanceDictionary::getInstance()->getTexture(index) ? LLAvatarAppearanceDictionary::getInstance()->getTexture(index)->mName : "");
}
}
LL_CONT << " ) " << inst->getUnbakedPixelAreaRank();
@@ -4715,7 +4715,7 @@ void LLVOAvatar::collectLocalTextureUUIDs(std::set<LLUUID>& ids) const
if (imagep)
{
const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)texture_index);
- if (texture_dict->mIsLocalTexture)
+ if (texture_dict && texture_dict->mIsLocalTexture)
{
ids.insert(imagep->getID());
}
@@ -4872,8 +4872,8 @@ void LLVOAvatar::updateTextures()
if (imagep)
{
const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)texture_index);
- const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
- if (texture_dict->mIsLocalTexture)
+ const EBakedTextureIndex baked_index = texture_dict ? texture_dict->mBakedTextureIndex : EBakedTextureIndex::BAKED_NUM_INDICES;
+ if (texture_dict && texture_dict->mIsLocalTexture)
{
addLocalTextureStats((ETextureIndex)texture_index, imagep, texel_area_ratio, render_avatar, mBakedTextureDatas[baked_index].mIsUsed);
}
@@ -5304,6 +5304,10 @@ LLUUID LLVOAvatar::remapMotionID(const LLUUID& id)
if (use_new_walk_run)
result = ANIM_AGENT_FEMALE_RUN_NEW;
}
+ else if (id == ANIM_AGENT_SIT)
+ {
+ result = ANIM_AGENT_SIT_FEMALE;
+ }
}
else
{
@@ -5318,6 +5322,11 @@ LLUUID LLVOAvatar::remapMotionID(const LLUUID& id)
if (use_new_walk_run)
result = ANIM_AGENT_RUN_NEW;
}
+ // keeps in sync with setSex() related code (viewer controls sit's sex)
+ else if (id == ANIM_AGENT_SIT_FEMALE)
+ {
+ result = ANIM_AGENT_SIT;
+ }
}
@@ -6089,7 +6098,26 @@ void LLVOAvatar::initAttachmentPoints(bool ignore_hud_joints)
//-----------------------------------------------------------------------------
void LLVOAvatar::updateVisualParams()
{
- setSex( (getVisualParamWeight( "male" ) > 0.5f) ? SEX_MALE : SEX_FEMALE );
+ ESex avatar_sex = (getVisualParamWeight("male") > 0.5f) ? SEX_MALE : SEX_FEMALE;
+ if (getSex() != avatar_sex)
+ {
+ if (mIsSitting && findMotion(avatar_sex == SEX_MALE ? ANIM_AGENT_SIT_FEMALE : ANIM_AGENT_SIT) != NULL)
+ {
+ // In some cases of gender change server changes sit motion with motion message,
+ // but in case of some avatars (legacy?) there is no update from server side,
+ // likely because server doesn't know about difference between motions
+ // (female and male sit ids are same server side, so it is likely unaware that it
+ // need to send update)
+ // Make sure motion is up to date
+ stopMotion(ANIM_AGENT_SIT);
+ setSex(avatar_sex);
+ startMotion(ANIM_AGENT_SIT);
+ }
+ else
+ {
+ setSex(avatar_sex);
+ }
+ }
LLCharacter::updateVisualParams();
@@ -7366,7 +7394,7 @@ void LLVOAvatar::updateMeshTextures()
// set texture and color of hair manually if we are not using a baked image.
// This can happen while loading hair for yourself, or for clients that did not
// bake a hair texture. Still needed for yourself after 1.22 is depricated.
- if (!is_layer_baked[BAKED_HAIR] || isEditingAppearance())
+ if (!is_layer_baked[BAKED_HAIR])
{
const LLColor4 color = mTexHairColor ? mTexHairColor->getColor() : LLColor4(1,1,1,1);
LLViewerTexture* hair_img = getImage( TEX_HAIR, 0 );
@@ -8511,6 +8539,8 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara
apr_file_printf( file, "<linden_genepool version=\"1.0\">\n" );
apr_file_printf( file, "\n\t<archetype name=\"???\">\n" );
+ bool agent_is_godlike = gAgent.isGodlikeWithoutAdminMenuFakery();
+
if (group_by_wearables)
{
for (S32 type = LLWearableType::WT_SHAPE; type < LLWearableType::WT_COUNT; type++)
@@ -8536,8 +8566,11 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara
LLViewerTexture* te_image = getImage((ETextureIndex)te, 0);
if( te_image )
{
- std::string uuid_str;
- te_image->getID().toString( uuid_str );
+ std::string uuid_str = LLUUID().asString();
+ if (agent_is_godlike)
+ {
+ te_image->getID().toString(uuid_str);
+ }
apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", te, uuid_str.c_str());
}
}
@@ -8559,8 +8592,11 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara
LLViewerTexture* te_image = getImage((ETextureIndex)te, 0);
if( te_image )
{
- std::string uuid_str;
- te_image->getID().toString( uuid_str );
+ std::string uuid_str = LLUUID().asString();
+ if (agent_is_godlike)
+ {
+ te_image->getID().toString(uuid_str);
+ }
apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", te, uuid_str.c_str());
}
}
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index 10af524ee7..b2954f4de2 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -2606,6 +2606,8 @@ void LLVOAvatarSelf::requestLayerSetUpdate(ETextureIndex index )
if( mUpperBodyLayerSet )
mUpperBodyLayerSet->requestUpdate(); */
const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(index);
+ if (!texture_dict)
+ return;
if (!texture_dict->mIsLocalTexture || !texture_dict->mIsUsedByBakedTexture)
return;
const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
@@ -2622,7 +2624,7 @@ LLViewerTexLayerSet* LLVOAvatarSelf::getLayerSet(ETextureIndex index) const
case TEX_HEAD_BODYPAINT:
return mHeadLayerSet; */
const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(index);
- if (texture_dict->mIsUsedByBakedTexture)
+ if (texture_dict && texture_dict->mIsUsedByBakedTexture)
{
const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
return getLayerSet(baked_index);
@@ -2758,7 +2760,7 @@ void LLVOAvatarSelf::sendHoverHeight() const
// class responder if nothing else gets added.
// (comment from removed Responder)
LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, update,
- "Hover hight sent to sim", "Hover hight not sent to sim");
+ "Hover height sent to sim", "Hover height not sent to sim");
mLastHoverOffsetSent = hover_offset;
}
}
diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp
index de63a3963c..b5c90a8f60 100644
--- a/indra/newview/llvograss.cpp
+++ b/indra/newview/llvograss.cpp
@@ -741,7 +741,7 @@ void LLGrassPartition::getGeometry(LLSpatialGroup* group)
U32 count = facep->getIndicesCount();
LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(),
//facep->getTexture(),
- buffer, fullbright);
+ buffer, object->isSelected(), fullbright);
const LLVector4a* exts = group->getObjectExtents();
info->mExtents[0] = exts[0];
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 6e5a5e3084..da4b6a5008 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -643,7 +643,13 @@ void LLVivoxVoiceClient::voiceControlCoro()
{
mIsCoroutineActive = true;
LLCoros::set_consuming(true);
-
+
+ while (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE)
+ {
+ LL_INFOS("Voice") << "Suspending voiceControlCoro() due to teleport. Tuning: " << mTuningMode << ". Relog: " << mRelogRequested << LL_ENDL;
+ llcoro::suspendUntilTimeout(1.0);
+ }
+
do
{
@@ -665,7 +671,7 @@ void LLVivoxVoiceClient::voiceControlCoro()
// and then reconstruct the voice connecion from scratch.
if (mRelogRequested)
{
- while (isGatewayRunning())
+ while (isGatewayRunning() || gAgent.getTeleportState() != LLAgent::TELEPORT_NONE)
{
llcoro::suspendUntilTimeout(1.0);
}
@@ -1302,7 +1308,7 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession)
mAudioSession = nextSession;
mAudioSessionChanged = true;
- if (!mAudioSession->mReconnect)
+ if (!mAudioSession || !mAudioSession->mReconnect)
{
mNextAudioSession.reset();
}
@@ -1310,16 +1316,19 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession)
// The old session may now need to be deleted.
reapSession(oldSession);
- if (!mAudioSession->mHandle.empty())
+ if (mAudioSession)
{
- // Connect to a session by session handle
+ if (!mAudioSession->mHandle.empty())
+ {
+ // Connect to a session by session handle
- sessionMediaConnectSendMessage(mAudioSession);
- }
- else
- {
- // Connect to a session by URI
- sessionCreateSendMessage(mAudioSession, true, false);
+ sessionMediaConnectSendMessage(mAudioSession);
+ }
+ else
+ {
+ // Connect to a session by URI
+ sessionCreateSendMessage(mAudioSession, true, false);
+ }
}
notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_JOINING);
@@ -1384,6 +1393,11 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession)
LL_INFOS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
if (result.has("session"))
{
+ if (!mAudioSession)
+ {
+ LL_WARNS("Voice") << "Message for session handle \"" << result["handle"] << "\" while session is not initialized." << LL_ENDL;
+ continue;
+ }
if (result.has("handle") && result["handle"] != mAudioSession->mHandle)
{
LL_WARNS("Voice") << "Message for session handle \"" << result["handle"] << "\" while waiting for \"" << mAudioSession->mHandle << "\"." << LL_ENDL;
@@ -1722,6 +1736,11 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session)
{
if (result.has("handle"))
{
+ if (!mAudioSession)
+ {
+ LL_WARNS("Voice") << "Message for session handle \"" << result["handle"] << "\" while session is not initiated." << LL_ENDL;
+ continue;
+ }
if (result["handle"] != mAudioSession->mHandle)
{
LL_WARNS("Voice") << "Message for session handle \"" << result["handle"] << "\" while waiting for \"" << mAudioSession->mHandle << "\"." << LL_ENDL;
@@ -3978,13 +3997,13 @@ void LLVivoxVoiceClient::sessionNotificationEvent(std::string &sessionHandle, st
{
// Other end started typing
// TODO: The proper way to add a typing notification seems to be LLIMMgr::processIMTypingStart().
- // It requires an LLIMInfo for the message, which we don't have here.
+ // It requires some info for the message, which we don't have here.
}
else if (!stricmp(notificationType.c_str(), "NotTyping"))
{
// Other end stopped typing
// TODO: The proper way to remove a typing notification seems to be LLIMMgr::processIMTypingStop().
- // It requires an LLIMInfo for the message, which we don't have here.
+ // It requires some info for the message, which we don't have here.
}
else
{
diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp
index f7b21338f8..b31afca61d 100644
--- a/indra/newview/llvopartgroup.cpp
+++ b/indra/newview/llvopartgroup.cpp
@@ -47,11 +47,17 @@
extern U64MicrosecondsImplicit gFrameTime;
LLPointer<LLVertexBuffer> LLVOPartGroup::sVB = NULL;
-S32 LLVOPartGroup::sVBSlotCursor = 0;
+S32 LLVOPartGroup::sVBSlotFree[];
+S32* LLVOPartGroup::sVBSlotCursor = NULL;
void LLVOPartGroup::initClass()
{
+ for (S32 i = 0; i < LL_MAX_PARTICLE_COUNT; ++i)
+ {
+ sVBSlotFree[i] = i;
+ }
+ sVBSlotCursor = sVBSlotFree;
}
//static
@@ -124,12 +130,14 @@ void LLVOPartGroup::destroyGL()
//static
S32 LLVOPartGroup::findAvailableVBSlot()
{
- if (sVBSlotCursor >= LL_MAX_PARTICLE_COUNT)
+ if (sVBSlotCursor >= sVBSlotFree + LL_MAX_PARTICLE_COUNT)
{ //no more available slots
return -1;
}
- return sVBSlotCursor++;
+ S32 ret = *sVBSlotCursor;
+ sVBSlotCursor++;
+ return ret;
}
bool ll_is_part_idx_allocated(S32 idx, S32* start, S32* end)
@@ -150,7 +158,7 @@ bool ll_is_part_idx_allocated(S32 idx, S32* start, S32* end)
//static
void LLVOPartGroup::freeVBSlot(S32 idx)
{
- /*llassert(idx < LL_MAX_PARTICLE_COUNT && idx >= 0);
+ llassert(idx < LL_MAX_PARTICLE_COUNT && idx >= 0);
//llassert(sVBSlotCursor > sVBSlotFree);
//llassert(ll_is_part_idx_allocated(idx, sVBSlotCursor, sVBSlotFree+LL_MAX_PARTICLE_COUNT));
@@ -158,7 +166,7 @@ void LLVOPartGroup::freeVBSlot(S32 idx)
{
sVBSlotCursor--;
*sVBSlotCursor = idx;
- }*/
+ }
}
LLVOPartGroup::LLVOPartGroup(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
@@ -870,7 +878,7 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
LLFace* facep = *i;
LLAlphaObject* object = (LLAlphaObject*) facep->getViewerObject();
- //if (!facep->isState(LLFace::PARTICLE))
+ if (!facep->isState(LLFace::PARTICLE))
{ //set the indices of this face
S32 idx = LLVOPartGroup::findAvailableVBSlot();
if (idx >= 0)
@@ -879,7 +887,7 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
facep->setIndicesIndex(idx*6);
facep->setVertexBuffer(LLVOPartGroup::sVB);
facep->setPoolType(LLDrawPool::POOL_ALPHA);
- //facep->setState(LLFace::PARTICLE);
+ facep->setState(LLFace::PARTICLE);
}
else
{
@@ -964,7 +972,7 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
U32 count = facep->getIndicesCount();
LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(),
//facep->getTexture(),
- buffer, fullbright);
+ buffer, object->isSelected(), fullbright);
const LLVector4a* exts = group->getObjectExtents();
info->mExtents[0] = exts[0];
diff --git a/indra/newview/llvopartgroup.h b/indra/newview/llvopartgroup.h
index 2ef8b1c848..4e4d6e609d 100644
--- a/indra/newview/llvopartgroup.h
+++ b/indra/newview/llvopartgroup.h
@@ -42,7 +42,8 @@ public:
//vertex buffer for holding all particles
static LLPointer<LLVertexBuffer> sVB;
- static S32 sVBSlotCursor;
+ static S32 sVBSlotFree[LL_MAX_PARTICLE_COUNT];
+ static S32 *sVBSlotCursor;
static void initClass();
static void restoreGL();
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 7b4d8ef329..7d6881f8a8 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -78,6 +78,7 @@
#include "llvoavatar.h"
#include "llvocache.h"
#include "llmaterialmgr.h"
+#include "llsculptidsize.h"
const F32 FORCE_SIMPLE_RENDER_AREA = 512.f;
const F32 FORCE_CULL_AREA = 8.f;
@@ -222,7 +223,7 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re
mMediaImplList.resize(getNumTEs());
mLastFetchedMediaVersion = -1;
- mIndexInTex = 0;
+ memset(&mIndexInTex, 0, sizeof(S32) * LLRender::NUM_VOLUME_TEXTURE_CHANNELS);
mMDCImplCount = 0;
}
@@ -249,6 +250,8 @@ void LLVOVolume::markDead()
{
if (!mDead)
{
+ LLSculptIDSize::instance().rem(getVolume()->getParams().getSculptID());
+
if(getMDCImplCount() > 0)
{
LLMediaDataClientObject::ptr_t obj = new LLMediaDataClientObjectImpl(const_cast<LLVOVolume*>(this), false);
@@ -264,7 +267,12 @@ void LLVOVolume::markDead()
if (mSculptTexture.notNull())
{
- mSculptTexture->removeVolume(this);
+ mSculptTexture->removeVolume(LLRender::SCULPT_TEX, this);
+ }
+
+ if (mLightTexture.notNull())
+ {
+ mLightTexture->removeVolume(LLRender::LIGHT_TEX, this);
}
}
@@ -826,7 +834,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
{
LLLightImageParams* params = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
LLUUID id = params->getLightTexture();
- mLightTexture = LLViewerTextureManager::getFetchedTexture(id);
+ mLightTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM);
if (mLightTexture.notNull())
{
F32 rad = getLightRadius();
@@ -951,13 +959,14 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
// if it's a mesh
if ((volume_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH)
{ //meshes might not have all LODs, get the force detail to best existing LOD
- LLUUID mesh_id = volume_params.getSculptID();
-
- lod = gMeshRepo.getActualMeshLOD(volume_params, lod);
- if (lod == -1)
+ if (NO_LOD != lod)
{
- is404 = TRUE;
- lod = 0;
+ lod = gMeshRepo.getActualMeshLOD(volume_params, lod);
+ if (lod == -1)
+ {
+ is404 = TRUE;
+ lod = 0;
+ }
}
}
}
@@ -1054,12 +1063,13 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
LLFace::cacheFaceInVRAM(face);
}
}
-
return TRUE;
}
-
-
+ else if (NO_LOD == lod)
+ {
+ LLSculptIDSize::instance().resetSizeSum(volume_params.getSculptID());
+ }
return FALSE;
}
@@ -1086,11 +1096,11 @@ void LLVOVolume::updateSculptTexture()
{
if (old_sculpt.notNull())
{
- old_sculpt->removeVolume(this);
+ old_sculpt->removeVolume(LLRender::SCULPT_TEX, this);
}
if (mSculptTexture.notNull())
{
- mSculptTexture->addVolume(this);
+ mSculptTexture->addVolume(LLRender::SCULPT_TEX, this);
}
}
@@ -1200,12 +1210,12 @@ void LLVOVolume::sculpt()
mSculptTexture->updateBindStatsForTester() ;
}
}
- getVolume()->sculpt(sculpt_width, sculpt_height, sculpt_components, sculpt_data, discard_level);
+ getVolume()->sculpt(sculpt_width, sculpt_height, sculpt_components, sculpt_data, discard_level, mSculptTexture->isMissingAsset());
//notify rebuild any other VOVolumes that reference this sculpty volume
- for (S32 i = 0; i < mSculptTexture->getNumVolumes(); ++i)
+ for (S32 i = 0; i < mSculptTexture->getNumVolumes(LLRender::SCULPT_TEX); ++i)
{
- LLVOVolume* volume = (*(mSculptTexture->getVolumeList()))[i];
+ LLVOVolume* volume = (*(mSculptTexture->getVolumeList(LLRender::SCULPT_TEX)))[i];
if (volume != this && volume->getVolume() == getVolume())
{
gPipeline.markRebuild(volume->mDrawable, LLDrawable::REBUILD_GEOMETRY, FALSE);
@@ -1214,18 +1224,18 @@ void LLVOVolume::sculpt()
}
}
-S32 LLVOVolume::computeLODDetail(F32 distance, F32 radius)
+S32 LLVOVolume::computeLODDetail(F32 distance, F32 radius, F32 lod_factor)
{
S32 cur_detail;
if (LLPipeline::sDynamicLOD)
{
// We've got LOD in the profile, and in the twist. Use radius.
- F32 tan_angle = (LLVOVolume::sLODFactor*radius)/distance;
+ F32 tan_angle = (lod_factor*radius)/distance;
cur_detail = LLVolumeLODGroup::getDetailFromTan(ll_round(tan_angle, 0.01f));
}
else
{
- cur_detail = llclamp((S32) (sqrtf(radius)*LLVOVolume::sLODFactor*4.f), 0, 3);
+ cur_detail = llclamp((S32) (sqrtf(radius)*lod_factor*4.f), 0, 3);
}
return cur_detail;
}
@@ -1241,6 +1251,7 @@ BOOL LLVOVolume::calcLOD()
F32 radius;
F32 distance;
+ F32 lod_factor = LLVOVolume::sLODFactor;
if (mDrawable->isState(LLDrawable::RIGGED))
{
@@ -1276,12 +1287,18 @@ BOOL LLVOVolume::calcLOD()
distance *= rampDist;
}
- // DON'T Compensate for field of view changing on FOV zoom.
+
distance *= F_PI/3.f;
- cur_detail = computeLODDetail(ll_round(distance, 0.01f),
- ll_round(radius, 0.01f));
+ static LLCachedControl<bool> ignore_fov_zoom(gSavedSettings,"IgnoreFOVZoomForLODs");
+ if(!ignore_fov_zoom)
+ {
+ lod_factor *= DEFAULT_FIELD_OF_VIEW / LLViewerCamera::getInstance()->getDefaultFOV();
+ }
+ cur_detail = computeLODDetail(ll_round(distance, 0.01f),
+ ll_round(radius, 0.01f),
+ lod_factor);
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO) &&
mDrawable->getFace(0))
@@ -1294,7 +1311,8 @@ BOOL LLVOVolume::calcLOD()
if (cur_detail != mLOD)
{
mAppAngle = ll_round((F32) atan2( mDrawable->getRadius(), mDrawable->mDistanceWRTCamera) * RAD_TO_DEG, 0.01f);
- mLOD = cur_detail;
+ mLOD = cur_detail;
+
return TRUE;
}
@@ -1308,7 +1326,16 @@ BOOL LLVOVolume::updateLOD()
return FALSE;
}
- BOOL lod_changed = calcLOD();
+ BOOL lod_changed = FALSE;
+
+ if (!LLSculptIDSize::instance().isUnloaded(getVolume()->getParams().getSculptID()))
+ {
+ lod_changed = calcLOD();
+ }
+ else
+ {
+ return FALSE;
+ }
if (lod_changed)
{
@@ -1478,7 +1505,6 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)
res &= face->genVolumeBBoxes(*volume, i,
mRelativeXform,
(mVolumeImpl && mVolumeImpl->isVolumeGlobal()) || force_global);
-
if (rebuild)
{
if (i == 0)
@@ -1754,6 +1780,11 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1));
compiled = TRUE;
lodOrSculptChanged(drawable, compiled);
+
+ if(drawable->isState(LLDrawable::REBUILD_RIGGED | LLDrawable::RIGGED))
+ {
+ updateRiggedVolume(false);
+ }
genBBoxes(FALSE);
}
// it has its own drawable (it's moved) or it has changed UVs or it has changed xforms from global<->local
@@ -2172,7 +2203,7 @@ bool LLVOVolume::notifyAboutMissingAsset(LLViewerTexture *texture)
//setup new materials
for(map_te_material::const_iterator it = new_material.begin(), end = new_material.end(); it != end; ++it)
{
- LLMaterialMgr::getInstance()->put(getID(), it->first, *it->second);
+ LLMaterialMgr::getInstance()->setLocalMaterial(getRegion()->getRegionID(), it->second);
LLViewerObject::setTEMaterialParams(it->first, it->second);
}
@@ -2275,7 +2306,7 @@ S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialPa
if(new_material) {
pMaterial = new_material;
- LLMaterialMgr::getInstance()->put(getID(),te,*pMaterial);
+ LLMaterialMgr::getInstance()->setLocalMaterial(getRegion()->getRegionID(), pMaterial);
}
}
@@ -2525,7 +2556,9 @@ void LLVOVolume::mediaNavigateBounceBack(U8 texture_index)
LL_WARNS("MediaOnAPrim") << "FAILED to bounce back URL \"" << url << "\" -- unloading impl" << LL_ENDL;
impl->setMediaFailed(true);
}
- else {
+ // Make sure we are not bouncing to url we came from
+ else if (impl->getCurrentMediaURL() != url)
+ {
// Okay, navigate now
LL_INFOS("MediaOnAPrim") << "bouncing back to URL: " << url << LL_ENDL;
impl->navigateTo(url, "", false, true);
@@ -2837,27 +2870,42 @@ S32 LLVOVolume::getFaceIndexWithMediaImpl(const LLViewerMediaImpl* media_impl, S
void LLVOVolume::setLightTextureID(LLUUID id)
{
+ LLViewerTexture* old_texturep = getLightTexture(); // same as mLightTexture, but inits if nessesary
if (id.notNull())
{
if (!hasLightTexture())
{
setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE, TRUE, true);
}
+ else if (old_texturep)
+ {
+ old_texturep->removeVolume(LLRender::LIGHT_TEX, this);
+ }
LLLightImageParams* param_block = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
if (param_block && param_block->getLightTexture() != id)
{
param_block->setLightTexture(id);
parameterChanged(LLNetworkData::PARAMS_LIGHT_IMAGE, true);
}
+ LLViewerTexture* tex = getLightTexture();
+ if (tex)
+ {
+ tex->addVolume(LLRender::LIGHT_TEX, this); // new texture
+ }
+ else
+ {
+ LL_WARNS() << "Can't get light texture for ID " << id.asString() << LL_ENDL;
+ }
}
- else
+ else if (hasLightTexture())
{
- if (hasLightTexture())
+ if (old_texturep)
{
- setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE, FALSE, true);
- parameterChanged(LLNetworkData::PARAMS_LIGHT_IMAGE, true);
- mLightTexture = NULL;
+ old_texturep->removeVolume(LLRender::LIGHT_TEX, this);
}
+ setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE, FALSE, true);
+ parameterChanged(LLNetworkData::PARAMS_LIGHT_IMAGE, true);
+ mLightTexture = NULL;
}
}
@@ -3075,7 +3123,7 @@ LLViewerTexture* LLVOVolume::getLightTexture()
{
if (mLightTexture.isNull() || id != mLightTexture->getID())
{
- mLightTexture = LLViewerTextureManager::getFetchedTexture(id);
+ mLightTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM);
}
}
else
@@ -4203,7 +4251,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
LLVector4a* pos = dst_face.mPositions;
- if( pos && weight && dst_face.mExtents )
+ if (pos && dst_face.mExtents)
{
LL_RECORD_BLOCK_TIME(FTM_SKIN_RIGGED);
@@ -4389,7 +4437,9 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
LL_WARNS_ONCE("RenderMaterials") << "Oh no! No binormals for this alpha blended face!" << LL_ENDL;
}
- if (facep->getViewerObject()->isSelected() && LLSelectMgr::getInstance()->mHideSelectedObjects)
+ bool selected = facep->getViewerObject()->isSelected();
+
+ if (selected && LLSelectMgr::getInstance()->mHideSelectedObjects)
{
return;
}
@@ -4486,7 +4536,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
batchable = true;
}
}
-
+
if (idx >= 0 &&
draw_vec[idx]->mVertexBuffer == facep->getVertexBuffer() &&
draw_vec[idx]->mEnd == facep->getGeomIndex()-1 &&
@@ -4502,7 +4552,8 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
(!mat || (draw_vec[idx]->mShiny == shiny)) && // need to break batches when a material is shared, but legacy settings are different
draw_vec[idx]->mTextureMatrix == tex_mat &&
draw_vec[idx]->mModelMatrix == model_mat &&
- draw_vec[idx]->mShaderMask == shader_mask)
+ draw_vec[idx]->mShaderMask == shader_mask &&
+ draw_vec[idx]->mSelected == selected)
{
draw_vec[idx]->mCount += facep->getIndicesCount();
draw_vec[idx]->mEnd += facep->getGeomCount();
@@ -4524,7 +4575,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
U32 offset = facep->getIndicesStart();
U32 count = facep->getIndicesCount();
LLPointer<LLDrawInfo> draw_info = new LLDrawInfo(start,end,count,offset, tex,
- facep->getVertexBuffer(), fullbright, bump);
+ facep->getVertexBuffer(), selected, fullbright, bump);
draw_info->mGroup = group;
draw_info->mVSize = facep->getVirtualSize();
draw_vec.push_back(draw_info);
@@ -4551,26 +4602,25 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
if (mat)
{
- draw_info->mMaterialID = mat_id;
+ draw_info->mMaterialID = mat_id;
- // We have a material. Update our draw info accordingly.
+ // We have a material. Update our draw info accordingly.
- if (!mat->getSpecularID().isNull())
- {
- LLVector4 specColor;
- specColor.mV[0] = mat->getSpecularLightColor().mV[0] * (1.f / 255.f);
- specColor.mV[1] = mat->getSpecularLightColor().mV[1] * (1.f / 255.f);
- specColor.mV[2] = mat->getSpecularLightColor().mV[2] * (1.f / 255.f);
- specColor.mV[3] = mat->getSpecularLightExponent() * (1.f / 255.f);
- draw_info->mSpecColor = specColor;
- draw_info->mEnvIntensity = mat->getEnvironmentIntensity() * (1.f / 255.f);
- draw_info->mSpecularMap = facep->getViewerObject()->getTESpecularMap(facep->getTEOffset());
- }
+ if (!mat->getSpecularID().isNull())
+ {
+ LLVector4 specColor;
+ specColor.mV[0] = mat->getSpecularLightColor().mV[0] * (1.f / 255.f);
+ specColor.mV[1] = mat->getSpecularLightColor().mV[1] * (1.f / 255.f);
+ specColor.mV[2] = mat->getSpecularLightColor().mV[2] * (1.f / 255.f);
+ specColor.mV[3] = mat->getSpecularLightExponent() * (1.f / 255.f);
+ draw_info->mSpecColor = specColor;
+ draw_info->mEnvIntensity = mat->getEnvironmentIntensity() * (1.f / 255.f);
+ draw_info->mSpecularMap = facep->getViewerObject()->getTESpecularMap(facep->getTEOffset());
+ }
- draw_info->mAlphaMaskCutoff = mat->getAlphaMaskCutoff() * (1.f / 255.f);
- draw_info->mDiffuseAlphaMode = mat->getDiffuseAlphaMode();
- draw_info->mNormalMap = facep->getViewerObject()->getTENormalMap(facep->getTEOffset());
-
+ draw_info->mAlphaMaskCutoff = mat->getAlphaMaskCutoff() * (1.f / 255.f);
+ draw_info->mDiffuseAlphaMode = mat->getDiffuseAlphaMode();
+ draw_info->mNormalMap = facep->getViewerObject()->getTENormalMap(facep->getTEOffset());
}
else
{
@@ -4641,10 +4691,83 @@ static LLDrawPoolAvatar* get_avatar_drawpool(LLViewerObject* vobj)
return NULL;
}
-void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
+void handleRenderAutoMuteByteLimitChanged(const LLSD& new_value)
{
-
+ static LLCachedControl<U32> render_auto_mute_byte_limit(gSavedSettings, "RenderAutoMuteByteLimit", 0U);
+
+ if (0 != render_auto_mute_byte_limit)
+ {
+ //for unload
+ LLSculptIDSize::container_BY_SIZE_view::iterator
+ itL = LLSculptIDSize::instance().getSizeInfo().get<LLSculptIDSize::tag_BY_SIZE>().lower_bound(render_auto_mute_byte_limit),
+ itU = LLSculptIDSize::instance().getSizeInfo().get<LLSculptIDSize::tag_BY_SIZE>().end();
+
+ for (; itL != itU; ++itL)
+ {
+ const LLSculptIDSize::Info &nfo = *itL;
+ LLVOVolume *pVVol = nfo.getPtrLLDrawable()->getVOVolume();
+ if (pVVol
+ && !pVVol->isDead()
+ && pVVol->isAttachment()
+ && !pVVol->getAvatar()->isSelf()
+ && LLVOVolume::NO_LOD != pVVol->getLOD()
+ )
+ {
+ //postponed
+ pVVol->markForUnload();
+ LLSculptIDSize::instance().addToUnloaded(nfo.getSculptId());
+ }
+ }
+
+ //for load if it was unload
+ itL = LLSculptIDSize::instance().getSizeInfo().get<LLSculptIDSize::tag_BY_SIZE>().begin();
+ itU = LLSculptIDSize::instance().getSizeInfo().get<LLSculptIDSize::tag_BY_SIZE>().upper_bound(render_auto_mute_byte_limit);
+
+ for (; itL != itU; ++itL)
+ {
+ const LLSculptIDSize::Info &nfo = *itL;
+ LLVOVolume *pVVol = nfo.getPtrLLDrawable()->getVOVolume();
+ if (pVVol
+ && !pVVol->isDead()
+ && pVVol->isAttachment()
+ && !pVVol->getAvatar()->isSelf()
+ && LLVOVolume::NO_LOD == pVVol->getLOD()
+ )
+ {
+ LLSculptIDSize::instance().remFromUnloaded(nfo.getSculptId());
+ pVVol->updateLOD();
+ pVVol->markForUpdate(TRUE);
+ }
+ }
+ }
+ else
+ {
+ LLSculptIDSize::instance().clearUnloaded();
+
+ LLSculptIDSize::container_BY_SIZE_view::iterator
+ itL = LLSculptIDSize::instance().getSizeInfo().get<LLSculptIDSize::tag_BY_SIZE>().begin(),
+ itU = LLSculptIDSize::instance().getSizeInfo().get<LLSculptIDSize::tag_BY_SIZE>().end();
+ for (; itL != itU; ++itL)
+ {
+ const LLSculptIDSize::Info &nfo = *itL;
+ LLVOVolume *pVVol = nfo.getPtrLLDrawable()->getVOVolume();
+ if (pVVol
+ && !pVVol->isDead()
+ && pVVol->isAttachment()
+ && !pVVol->getAvatar()->isSelf()
+ && LLVOVolume::NO_LOD == pVVol->getLOD()
+ )
+ {
+ pVVol->updateLOD();
+ pVVol->markForUpdate(TRUE);
+ }
+ }
+ }
+}
+
+void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
+{
if (group->changeLOD())
{
group->mLastUpdateDistance = group->mDistance;
@@ -5205,13 +5328,19 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
fullbright_mask = fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX;
}
- genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sSimpleFaces, simple_count, FALSE, batch_textures, FALSE);
- genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sFullbrightFaces, fullbright_count, FALSE, batch_textures);
- genDrawInfo(group, alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sAlphaFaces, alpha_count, TRUE, batch_textures);
- genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sBumpFaces, bump_count, FALSE, FALSE);
- genDrawInfo(group, norm_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sNormFaces, norm_count, FALSE, FALSE);
- genDrawInfo(group, spec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sSpecFaces, spec_count, FALSE, FALSE);
- genDrawInfo(group, normspec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sNormSpecFaces, normspec_count, FALSE, FALSE);
+ group->mGeometryBytes = 0;
+
+ U32 geometryBytes = 0;
+
+ geometryBytes += genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sSimpleFaces, simple_count, FALSE, batch_textures, FALSE);
+ geometryBytes += genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sFullbrightFaces, fullbright_count, FALSE, batch_textures);
+ geometryBytes += genDrawInfo(group, alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sAlphaFaces, alpha_count, TRUE, batch_textures);
+ geometryBytes += genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sBumpFaces, bump_count, FALSE, FALSE);
+ geometryBytes += genDrawInfo(group, norm_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sNormFaces, norm_count, FALSE, FALSE);
+ geometryBytes += genDrawInfo(group, spec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sSpecFaces, spec_count, FALSE, FALSE);
+ geometryBytes += genDrawInfo(group, normspec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sNormSpecFaces, normspec_count, FALSE, FALSE);
+
+ group->mGeometryBytes = geometryBytes;
if (!LLPipeline::sDelayVBUpdate)
{
@@ -5269,6 +5398,8 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) )
{
LLVOVolume* vobj = drawablep->getVOVolume();
+ if (vobj->isNoLOD()) continue;
+
vobj->preRebuild();
if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
@@ -5401,10 +5532,11 @@ static LLTrace::BlockTimerStatHandle FTM_GEN_DRAW_INFO_RESIZE_VB("Resize VB");
-void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort, BOOL batch_textures, BOOL no_materials)
+U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort, BOOL batch_textures, BOOL no_materials)
{
LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_GEN_DRAW_INFO);
+ U32 geometryBytes = 0;
U32 buffer_usage = group->mBufferUsage;
static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false);
@@ -5654,7 +5786,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac
if (buffer)
{
- group->mGeometryBytes += buffer->getSize() + buffer->getIndicesSize();
+ geometryBytes += buffer->getSize() + buffer->getIndicesSize();
buffer_map[mask][*face_iter].push_back(buffer);
}
@@ -5942,7 +6074,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac
}
else
{
- registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT);
+ registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT);
}
if (LLPipeline::sRenderDeferred && !hud_group && LLPipeline::sRenderBump && use_legacy_bump)
{ //if this is the deferred render and a bump map is present, register in post deferred bump
@@ -5964,8 +6096,8 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac
}
else
{
- registerFace(group, facep, LLRenderPass::PASS_SIMPLE);
- }
+ registerFace(group, facep, LLRenderPass::PASS_SIMPLE);
+ }
}
}
@@ -6010,6 +6142,8 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac
{
group->mBufferMap[mask][i->first] = i->second;
}
+
+ return geometryBytes;
}
void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32 &index_count)
@@ -6076,4 +6210,3 @@ void LLHUDPartition::shift(const LLVector4a &offset)
{
//HUD objects don't shift with region crossing. That would be silly.
}
-
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index a331908320..a0342d31a2 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -35,6 +35,8 @@
#include "m3math.h" // LLMatrix3
#include "m4math.h" // LLMatrix4
#include <map>
+#include <set>
+
class LLViewerTextureAnim;
class LLDrawPool;
@@ -125,7 +127,9 @@ public:
void generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point);
/*virtual*/ BOOL setParent(LLViewerObject* parent);
- S32 getLOD() const { return mLOD; }
+ S32 getLOD() const { return mLOD; }
+ void setNoLOD() { mLOD = NO_LOD; mLODChanged = TRUE; }
+ bool isNoLOD() const { return NO_LOD == mLOD; }
const LLVector3 getPivotPositionAgent() const;
const LLMatrix4& getRelativeXform() const { return mRelativeXform; }
const LLMatrix3& getRelativeXformInvTrans() const { return mRelativeXformInvTrans; }
@@ -160,6 +164,7 @@ public:
const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const;
void markForUpdate(BOOL priority) { LLViewerObject::markForUpdate(priority); mVolumeChanged = TRUE; }
+ void markForUnload() { LLViewerObject::markForUnload(TRUE); mVolumeChanged = TRUE; }
void faceMappingChanged() { mFaceMappingChanged=TRUE; };
/*virtual*/ void onShift(const LLVector4a &shift_vector); // Called when the drawable shifts
@@ -202,10 +207,10 @@ public:
/*virtual*/ BOOL setMaterial(const U8 material);
void setTexture(const S32 face);
- S32 getIndexInTex() const {return mIndexInTex ;}
+ S32 getIndexInTex(U32 ch) const {return mIndexInTex[ch];}
/*virtual*/ BOOL setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume = false);
void updateSculptTexture();
- void setIndexInTex(S32 index) { mIndexInTex = index ;}
+ void setIndexInTex(U32 ch, S32 index) { mIndexInTex[ch] = index ;}
void sculpt();
static void rebuildMeshAssetCallback(LLVFS *vfs,
const LLUUID& asset_uuid,
@@ -327,7 +332,7 @@ public:
void clearRiggedVolume();
protected:
- S32 computeLODDetail(F32 distance, F32 radius);
+ S32 computeLODDetail(F32 distance, F32 radius, F32 lod_factor);
BOOL calcLOD();
LLFace* addFace(S32 face_index);
void updateTEData();
@@ -370,7 +375,7 @@ private:
LLPointer<LLViewerFetchedTexture> mLightTexture;
media_list_t mMediaImplList;
S32 mLastFetchedMediaVersion; // as fetched from the server, starts as -1
- S32 mIndexInTex;
+ S32 mIndexInTex[LLRender::NUM_VOLUME_TEXTURE_CHANNELS];
S32 mMDCImplCount;
LLPointer<LLRiggedVolume> mRiggedVolume;
diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp
index 5fb3d62445..ee2270c323 100644
--- a/indra/newview/llwearableitemslist.cpp
+++ b/indra/newview/llwearableitemslist.cpp
@@ -645,7 +645,7 @@ LLWearableItemsList::LLWearableItemsList(const LLWearableItemsList::Params& p)
setRightMouseDownCallback(boost::bind(&LLWearableItemsList::onRightClick, this, _2, _3));
}
mWornIndicationEnabled = p.worn_indication_enabled;
- setNoItemsCommentText(LLTrans::getString("NoneFound"));
+ setNoItemsCommentText(LLTrans::getString("LoadingData"));
}
// virtual
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 1d083bb2fd..e541c1054e 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -2656,7 +2656,7 @@ void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& d
{
scratch_space->copyContents(source,
0, 0, source.getWidth(), source.getHeight(),
- 0, 0, scratch_space->getWidth(), scratch_space->getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+ 0, 0, scratch_space->getWidth(), scratch_space->getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
}
dest.bindTarget();
@@ -3031,6 +3031,12 @@ void LLPipeline::updateGeom(F32 max_dtime)
}
}
+ if (drawablep->isUnload())
+ {
+ drawablep->unload();
+ drawablep->clearState(LLDrawable::FOR_UNLOAD);
+ }
+
if (updateDrawableGeom(drawablep, TRUE))
{
drawablep->clearState(LLDrawable::IN_REBUILD_Q1);
@@ -3424,6 +3430,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)
{
LLSpatialGroup* last_group = NULL;
+ BOOL fov_changed = LLViewerCamera::getInstance()->isDefaultFOVChanged();
for (LLCullResult::bridge_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i)
{
LLCullResult::bridge_iterator cur_iter = i;
@@ -3437,7 +3444,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
if (!bridge->isDead() && group && !group->isOcclusionState(LLSpatialGroup::OCCLUDED))
{
- stateSort(bridge, camera);
+ stateSort(bridge, camera, fov_changed);
}
if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD &&
@@ -3509,9 +3516,9 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera)
}
-void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera)
+void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera, BOOL fov_changed)
{
- if (bridge->getSpatialGroup()->changeLOD())
+ if (bridge->getSpatialGroup()->changeLOD() || fov_changed)
{
bool force_update = false;
bridge->updateDistance(camera, force_update);
@@ -4577,12 +4584,6 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
LLGLEnable cull(GL_CULL_FACE);
- LLGLEnable stencil(GL_STENCIL_TEST);
- glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF);
- stop_glerror();
- glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
- stop_glerror();
-
for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter)
{
LLDrawPool *poolp = *iter;
@@ -8138,7 +8139,7 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield)
if (LLRenderTarget::sUseFBO)
{ //copy depth buffer from mScreen to framebuffer
LLRenderTarget::copyContentsToFramebuffer(mScreen, 0, 0, mScreen.getWidth(), mScreen.getHeight(),
- 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+ 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
}
@@ -9019,7 +9020,7 @@ void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target)
{
LLGLDepthTest depth(GL_TRUE);
mDeferredDepth.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(),
- 0, 0, mDeferredDepth.getWidth(), mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+ 0, 0, mDeferredDepth.getWidth(), mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
}
LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
@@ -9994,7 +9995,19 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
}
else
{
- renderGeom(camera);
+ renderGeom(camera);
+
+ if (LLGLSLShader::sNoFixedFunction)
+ {
+ gUIProgram.bind();
+ }
+
+ LLWorld::getInstance()->renderPropertyLines();
+
+ if (LLGLSLShader::sNoFixedFunction)
+ {
+ gUIProgram.unbind();
+ }
}
if (LLPipeline::sRenderDeferred && materials_in_water)
@@ -10117,7 +10130,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
}
LLPipeline::sShadowRender = true;
- U32 types[] = {
+ static const U32 types[] = {
LLRenderPass::PASS_SIMPLE,
LLRenderPass::PASS_FULLBRIGHT,
LLRenderPass::PASS_SHINY,
@@ -11622,7 +11635,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
avatar->setImpostorDim(tdim);
- LLVOAvatar::sUseImpostors = true; // @TODO ???
+ LLVOAvatar::sUseImpostors = (0 != LLVOAvatar::sMaxNonImpostors);
sUseOcclusion = occlusion;
sReflectionRender = false;
sImpostorRender = false;
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index c9670a60f2..f43607ccb0 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -254,7 +254,7 @@ public:
void stateSort(LLCamera& camera, LLCullResult& result);
void stateSort(LLSpatialGroup* group, LLCamera& camera);
- void stateSort(LLSpatialBridge* bridge, LLCamera& camera);
+ void stateSort(LLSpatialBridge* bridge, LLCamera& camera, BOOL fov_changed = FALSE);
void stateSort(LLDrawable* drawablep, LLCamera& camera);
void postSort(LLCamera& camera);
void forAllVisibleDrawables(void (*func)(LLDrawable*));
diff --git a/indra/newview/skins/default/xui/da/floater_tos.xml b/indra/newview/skins/default/xui/da/floater_tos.xml
index af9ee0bd06..bd8ecb92e9 100644
--- a/indra/newview/skins/default/xui/da/floater_tos.xml
+++ b/indra/newview/skins/default/xui/da/floater_tos.xml
@@ -8,7 +8,9 @@
</floater.string>
<button label="Fortsæt" label_selected="Fortsæt" name="Continue"/>
<button label="Annullér" label_selected="Annullér" name="Cancel"/>
- <check_box label="Jeg er enig med &quot;Terms of Service and Privacy Policy&quot;" name="agree_chk"/>
+ <text name="agree_list">
+ Jeg er enig med &quot;Terms of Service and Privacy Policy&quot;
+ </text>
<text name="tos_heading">
Læs venligst følgende &quot;Terms of Service and Privacy Policy&quot; grundigt. For at fortsætte med at logge på [SECOND_LIFE], skal du acceptere aftale.
</text>
diff --git a/indra/newview/skins/default/xui/de/notifications.xml b/indra/newview/skins/default/xui/de/notifications.xml
index b64d7c8d49..8ff3ac770b 100644
--- a/indra/newview/skins/default/xui/de/notifications.xml
+++ b/indra/newview/skins/default/xui/de/notifications.xml
@@ -2368,7 +2368,7 @@ Möchten Sie den Nicht-stören-Modus deaktivieren, bevor Sie diese Transaktion a
<usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="OK"/>
</notification>
<notification name="ConfirmEmptyTrash">
- [COUNT] Objekte werden dauerhaft gelöscht. Möchten Sie den Inhalt Ihres Papierkorbs wirklich dauerhaft löschen?
+ [COUNT] Bestellungen und Ordner werden dauerhaft gelöscht. Sind Sie sicher, dass Sie den Inhalt Ihres Papierkorbs dauerhaft löschen möchten?
<usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="OK"/>
</notification>
<notification name="TrashIsFull">
@@ -3374,12 +3374,18 @@ Bitte überprüfen Sie Ihre Netzwerk- und Firewalleinstellungen.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="NoVoiceConnect">
- Verbindung mit Voice-Server ist leider nicht möglich:
+ Wir können uns nicht mit dem Voice-Server verbinden:
[HOSTID]
-Voice-Kommunikation ist leider nicht verfügbar.
-Bitte überprüfen Sie Ihr Netzwerk- und Firewall-Setup.
+Ports, die für Sprache erlaubt sein müssen, sind:
+:TCP: 80, 443
+:UDP: 3478, 3479, 5060, 5062, 6250, 12000-32000
+
+Bitte überprüfen Sie Ihre Netzwerk- und Firewall-Einstellungen.
+Deaktivieren Sie alle SIP-ALG-Funktionen in Ihrem Router.
+
+Sprachkommunikation ist nicht möglich.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="NoVoiceConnect-GIAB">
diff --git a/indra/newview/skins/default/xui/de/panel_main_inventory.xml b/indra/newview/skins/default/xui/de/panel_main_inventory.xml
index d265f040ab..a3adea9fa2 100644
--- a/indra/newview/skins/default/xui/de/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/de/panel_main_inventory.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="Sonstiges" name="main inventory panel">
<panel.string name="ItemcountFetching">
- Inventar ([ITEM_COUNT] Artikel werden abgerufen... [FILTER]
+ Holen von [ITEM_COUNT] Bestellungen und [CATEGORY_COUNT] Ordnern... [FILTER]
</panel.string>
<panel.string name="ItemcountCompleted">
- [ITEM_COUNT] Objekte [FILTER]
+ [ITEM_COUNT] Bestellungen und [CATEGORY_COUNT] Ordner [FILTER]
</panel.string>
<panel.string name="ItemcountUnknown">
- Abgerufen: [ITEM_COUNT] Artikel [FILTER]
+ Geholte [ITEM_COUNT] Bestellungen und [CATEGORY_COUNT] Ordner [FILTER]
</panel.string>
<text name="ItemcountText">
Objekte:
diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml
index 0344dff94f..3e66007627 100644
--- a/indra/newview/skins/default/xui/de/strings.xml
+++ b/indra/newview/skins/default/xui/de/strings.xml
@@ -277,9 +277,8 @@ Wenn Sie der Ansicht sind, dass Sie diese Meldung fälschlicherweise erhalten ha
Abmeldeanforderung führte zu einem Simulatorfehler.
</string>
<string name="LoginFailedPendingLogout">
- Das System meldet Sie gerade ab.
-Ihr Konto ist erst ab
-[TIME] Pacific Time wieder verfügbar.
+ Das System meldet Sie gerade ab.
+Bitte warten Sie eine Minute, bevor Sie sich erneut einloggen.
</string>
<string name="LoginFailedUnableToCreateSession">
Es kann keine gültige Sitzung erstellt werden.
@@ -1514,6 +1513,9 @@ Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich unter http://suppo
<string name="InventoryMarketplaceListingsNoItems">
Ziehen Sie Ordner in diesen Bereich, um sie im [[MARKETPLACE_DASHBOARD_URL] Marktplatz] zum Verkauf anzubieten.
</string>
+ <string name="InventoryItemsCount">
+ ( [ITEMS_COUNT] Artikel )
+ </string>
<string name="Marketplace Validation Warning Stock">
Bestandsordner müssen in einem Versionsordner gespeichert sein
</string>
diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml
index 535af317d9..cf843a07a6 100644
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -502,7 +502,7 @@
name="Buy Land..."
width="130" />
<button
- enabled="false"
+ enabled="true"
follows="left|top"
height="23"
label="Linden Sale"
diff --git a/indra/newview/skins/default/xui/en/floater_auction.xml b/indra/newview/skins/default/xui/en/floater_auction.xml
deleted file mode 100644
index 9c6d114c4c..0000000000
--- a/indra/newview/skins/default/xui/en/floater_auction.xml
+++ /dev/null
@@ -1,96 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater
- legacy_header_height="18"
- can_resize="true"
- height="412"
- layout="topleft"
- min_height="412"
- min_width="420"
- name="floater_auction"
- help_topic="floater_auction"
- title="START LINDEN LAND SALE"
- width="420">
- <floater.string
- name="already for sale">
- You cannot auction parcels which are already for sale.
- </floater.string>
- <icon
- bottom="280"
- follows="left|right|top|bottom"
- layout="topleft"
- left="4"
- name="snapshot_icon"
- right="-4"
- top="24" />
- <text
- follows="left|right|bottom"
- height="16"
- layout="topleft"
- left_delta="0"
- name="parcel_text"
- top_pad="12"
- width="400" />
- <check_box
- control_name="AuctionShowFence"
- follows="left|bottom"
- height="16"
- initial_value="true"
- label="Include yellow selection fence"
- layout="topleft"
- left_delta="0"
- name="fence_check"
- top_pad="12"
- width="199" />
- <button
- follows="left|bottom"
- height="20"
- label="Snapshot"
- label_selected="Snapshot"
- layout="topleft"
- left_delta="0"
- name="snapshot_btn"
- top_pad="4"
- width="150">
- <button.commit_callback
- function="ClickSnapshot" />
- </button>
- <button
- follows="left|bottom"
- height="20"
- label="Sell to Anyone"
- label_selected="Sell to Anyone"
- layout="topleft"
- left_delta="0"
- name="sell_to_anyone_btn"
- top_pad="4"
- width="150">
- <button.commit_callback
- function="ClickSellToAnyone" />
- </button>
- <button
- follows="left|bottom"
- height="20"
- label="Clear Settings"
- label_selected="Clear Settings"
- layout="topleft"
- left_delta="0"
- name="reset_parcel_btn"
- top_pad="4"
- width="150">
- <button.commit_callback
- function="ClickResetParcel" />
- </button>
- <button
- follows="left|bottom"
- height="20"
- label="Start Auction"
- label_selected="Start Auction"
- layout="topleft"
- left_pad="4"
- name="start_auction_btn"
- top_delta="0"
- width="150">
- <button.commit_callback
- function="ClickStartAuction" />
- </button>
-</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_buy_land.xml b/indra/newview/skins/default/xui/en/floater_buy_land.xml
index 22cc058e46..9fe56e447e 100644
--- a/indra/newview/skins/default/xui/en/floater_buy_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_buy_land.xml
@@ -702,16 +702,6 @@ This parcel is 512 m² of land.
right="400">
You have L$ 2,100.
</text>
- <check_box
- follows="bottom|left"
- height="20"
- label="Remove [AMOUNT] m² of contribution from group."
- layout="topleft"
- left_delta="3"
- name="remove_contribution"
- top_delta="14"
- visible="false"
- width="275" />
<button
follows="bottom|left"
height="20"
@@ -721,6 +711,15 @@ This parcel is 512 m² of land.
name="buy_btn"
top="460"
width="100" />
+ <check_box
+ follows="bottom|left"
+ height="20"
+ label="Remove [AMOUNT] m² of contribution from group."
+ layout="topleft"
+ left_pad="3"
+ name="remove_contribution"
+ visible="false"
+ width="275" />
<button
follows="bottom|right"
height="20"
diff --git a/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml
index 6667238232..45e16c59ae 100644
--- a/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml
+++ b/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml
@@ -418,30 +418,5 @@
width="90">
N:
</text-->
- <!--text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left="10"
- name="SaleLabel"
- top_pad="5"
- width="330">
- Mark Item:
- </text-->
-
- <!--text
- type="string"
- length="1"
- follows="left|top"
- height="16"
- layout="topleft"
- left="10"
- name="TextPrice"
- top_pad="5"
- width="78">
- Price: L$
- </text-->
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
index c6b91a8b2f..c2500951a6 100644
--- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
+++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
@@ -253,7 +253,7 @@
follows="left|top"
height="16"
layout="topleft"
- name="ShadersText"
+ name="HardwareText"
top_delta="20"
left="10"
width="128">
@@ -426,7 +426,7 @@
follows="left|top"
height="16"
layout="topleft"
- name="AvatarText"
+ name="MeshText"
top_delta="20"
left="400"
top="21"
@@ -509,6 +509,7 @@
label_width="185"
layout="topleft"
left="420"
+ min_val="1"
max_val="2"
name="ObjectMeshDetail"
show_text="false"
@@ -916,7 +917,7 @@ are saved in a preset file. -->
label="RenderAvatarMaxComplexity"
layout="topleft"
left="0"
- name="RenderAvatarMaxNonImpostors"
+ name="RenderAvatarMaxComplexity"
top_delta="0"
width="0">
</check_box>
diff --git a/indra/newview/skins/default/xui/en/floater_report_abuse.xml b/indra/newview/skins/default/xui/en/floater_report_abuse.xml
index 225266af86..8fa5b49573 100644
--- a/indra/newview/skins/default/xui/en/floater_report_abuse.xml
+++ b/indra/newview/skins/default/xui/en/floater_report_abuse.xml
@@ -188,6 +188,7 @@
tool_tip="Category -- select the category that best describes this report"
top_pad="5"
width="313">
+ <!-- Values can be populated from capability -->
<combo_box.item
label="Select category"
name="Select_category"
diff --git a/indra/newview/skins/default/xui/en/floater_snapshot.xml b/indra/newview/skins/default/xui/en/floater_snapshot.xml
index 76adaad57c..e50747cb5f 100644
--- a/indra/newview/skins/default/xui/en/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/en/floater_snapshot.xml
@@ -127,7 +127,7 @@
top_delta="0"
width="31" />
<panel
- height="154"
+ height="159"
layout="topleft"
follows="top|left"
left="0"
@@ -250,7 +250,7 @@
left="0"
name="panel_container"
default_panel_name="panel_snapshot_options"
- top_pad="10"
+ top_pad="5"
width="215">
<panel
class="llpanelsnapshotoptions"
diff --git a/indra/newview/skins/default/xui/en/fonts.xml b/indra/newview/skins/default/xui/en/fonts.xml
index 550af03683..82027d9e7c 100644
--- a/indra/newview/skins/default/xui/en/fonts.xml
+++ b/indra/newview/skins/default/xui/en/fonts.xml
@@ -4,6 +4,7 @@
<font name="default" comment="default font files (global fallbacks)">
<file>DejaVuSans.ttf</file>
<os name="Windows">
+ <file>meiryo.TTC</file>
<file>MSGOTHIC.TTC</file>
<file>gulim.ttc</file>
<file>simhei.ttf</file>
diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml
index 5b45364127..3ea9e77a03 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory.xml
@@ -88,14 +88,6 @@
function="Inventory.Share" />
</menu_item_call>
<menu_item_call
- label="Buy"
- layout="topleft"
- name="Task Buy">
- <menu_item_call.on_click
- function="Inventory.DoToSelected"
- parameter="task_buy" />
- </menu_item_call>
- <menu_item_call
label="Open"
layout="topleft"
name="Task Open">
diff --git a/indra/newview/skins/default/xui/en/menu_people_blocked_gear.xml b/indra/newview/skins/default/xui/en/menu_people_blocked_gear.xml
index 01ca38f51a..5e16707340 100644
--- a/indra/newview/skins/default/xui/en/menu_people_blocked_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_blocked_gear.xml
@@ -53,7 +53,7 @@
<menu_item_check
label="Block Particles"
layout="topleft"
- name="MuteText">
+ name="MuteParticles">
<on_check
function="Block.Check"
parameter="block_particles" />
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 81bb83f133..d28f47c2e1 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -1487,7 +1487,8 @@
</menu_item_call>
<menu_item_call
label="Set UI Size to Default"
- name="Set UI Size to Default">
+ name="Set UI Size to Default"
+ shortcut="control|alt|shift|R">
<menu_item_call.on_click
function="View.DefaultUISize" />
</menu_item_call>
@@ -2373,16 +2374,6 @@
function="ToggleControl"
parameter="DebugShowMemory" />
</menu_item_check>
- <menu_item_check
- label="Show Private Mem Info"
- name="Show Private Mem Info">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="DebugShowPrivateMem" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="DebugShowPrivateMem" />
- </menu_item_check>
<menu_item_separator/>
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 6aa6653f42..7f9dc0c41f 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -10414,14 +10414,6 @@ Not enough script resources available to attach object!
</notification>
<notification
- icon="alertmodal.tga"
- name="IllegalAttachment"
- type="notify">
- <tag>fail</tag>
- The attachment has requested a nonexistent point on the avatar. It has been attached to the chest instead.
- </notification>
-
- <notification
icon="alertmodal.tga"
name="CantDropItemTrialUser"
type="notify">
@@ -11031,7 +11023,7 @@ An internal error prevented us from properly updating your viewer. The L$ balan
name="LargePrimAgentIntersect"
type="notify">
<tag>fail</tag>
-Cannot create large prims that intersect other players. Please re-try when other players have moved.
+Cannot create large prims that intersect other residents. Please re-try when other residents have moved.
</notification>
<notification
diff --git a/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml
index 574e5f3cbc..c324e24a86 100644
--- a/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml
+++ b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml
@@ -109,6 +109,7 @@
layout="topleft"
left="3"
name="blocked"
+ keep_one_selected="false"
tool_tip="List of currently blocked Residents"
top_pad="4"
right="-1"/>
diff --git a/indra/newview/skins/default/xui/en/panel_group_notices.xml b/indra/newview/skins/default/xui/en/panel_group_notices.xml
index c8ce5cdebf..47aceb2c2e 100644
--- a/indra/newview/skins/default/xui/en/panel_group_notices.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_notices.xml
@@ -180,13 +180,20 @@ Maximum 200 per group daily
<line_editor
follows="left|top|right"
enabled="false"
- height="19"
+ height="20"
layout="topleft"
max_length_bytes="90"
mouse_opaque="false"
name="create_inventory_name"
top_pad="2"
width="285" />
+ <icon
+ height="16"
+ layout="topleft"
+ left_delta="5"
+ name="create_inv_icon"
+ top_delta="2"
+ width="16" />
<text
text_color="EmphasisColor"
follows="left|top"
@@ -350,6 +357,13 @@ Maximum 200 per group daily
name="view_inventory_name"
top_pad="8"
width="250"/>
+ <icon
+ height="16"
+ layout="topleft"
+ left_delta="5"
+ name="view_inv_icon"
+ top_delta="2"
+ width="16" />
<button
follows="left|top"
height="23"
diff --git a/indra/newview/skins/default/xui/en/panel_group_roles.xml b/indra/newview/skins/default/xui/en/panel_group_roles.xml
index dac4371a38..714d4166c0 100644
--- a/indra/newview/skins/default/xui/en/panel_group_roles.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_roles.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
- height="680"
+ height="750"
label="Members &amp; Roles"
layout="topleft"
left="0"
@@ -284,8 +284,7 @@ clicking on their names.
width="20" />
<scroll_list.columns
label=""
- name="action"
- width="270" />
+ name="action" />
</scroll_list>
</panel>
<panel
@@ -451,7 +450,39 @@ clicking on their names.
</scroll_list>
</panel>
<panel
- height="550"
+ height="90"
+ background_visible="false"
+ bg_alpha_color="FloaterUnfocusBorderColor"
+ layout="topleft"
+ follows="top|left|right"
+ left="0"
+ right="-1"
+ width="313"
+ mouse_opaque="false"
+ name="members_header"
+ top_pad="3"
+ visible="false">
+ <text_editor
+ bg_readonly_color="Transparent"
+ text_readonly_color="EmphasisColor"
+ font="SansSerifSmall"
+ type="string"
+ enabled="false"
+ halign="left"
+ layout="topleft"
+ top_pad="0"
+ follows="left|top|right"
+ left="0"
+ right="-1"
+ height="90"
+ max_length="512"
+ name="member_action_description"
+ word_wrap="true">
+ This Ability is &apos;Eject Members from this Group&apos;. Only an Owner can eject another Owner.
+ </text_editor>
+ </panel>
+ <panel
+ height="460"
background_visible="false"
bg_alpha_color="FloaterUnfocusBorderColor"
layout="topleft"
@@ -599,11 +630,42 @@ clicking on their names.
width="20" />
<scroll_list.columns
label=""
- name="action"
- width="270" />
+ name="action" />
</scroll_list>
</panel>
<panel
+ height="90"
+ background_visible="false"
+ bg_alpha_color="FloaterUnfocusBorderColor"
+ layout="topleft"
+ follows="top|left|right"
+ left="0"
+ right="-1"
+ width="313"
+ mouse_opaque="false"
+ name="roles_header"
+ top_pad="3"
+ visible="false">
+ <text_editor
+ bg_readonly_color="Transparent"
+ text_readonly_color="EmphasisColor"
+ font="SansSerifSmall"
+ type="string"
+ enabled="false"
+ halign="left"
+ layout="topleft"
+ top_pad="0"
+ follows="left|top|right"
+ left="0"
+ right="-1"
+ height="90"
+ max_length="512"
+ name="role_action_description"
+ word_wrap="true">
+ This Ability is &apos;Eject Members from this Group&apos;. Only an Owner can eject another Owner.
+ </text_editor>
+ </panel>
+ <panel
height="424"
background_visible="false"
bg_alpha_color="FloaterUnfocusBorderColor"
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index 2cb06d6877..8fc0f6f642 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -345,6 +345,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
left="0"
multi_select="true"
name="avatars_online"
+ keep_one_selected="false"
show_permissions_granted="true"
top="0"
width="307" />
@@ -362,6 +363,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
left="0"
multi_select="true"
name="avatars_all"
+ keep_one_selected="false"
show_permissions_granted="true"
top="0"
width="307" />
@@ -517,6 +519,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
height="388"
layout="topleft"
left="3"
+ keep_one_selected="false"
name="group_list"
right="-2"
top_pad="4" />
@@ -631,6 +634,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
multi_select="true"
name="avatar_list"
show_last_interaction_time="true"
+ keep_one_selected="false"
right="-2"
top_pad="4" />
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_uploads.xml b/indra/newview/skins/default/xui/en/panel_preferences_uploads.xml
index 343c2db2f1..67eff2b762 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_uploads.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_uploads.xml
@@ -104,7 +104,7 @@
height="12"
layout="topleft"
left="37"
- name="title_animation"
+ name="title_model"
top_pad="7"
width="100">
Models
diff --git a/indra/newview/skins/default/xui/en/panel_tools_texture.xml b/indra/newview/skins/default/xui/en/panel_tools_texture.xml
index ffdbc5d227..8c769d87de 100644
--- a/indra/newview/skins/default/xui/en/panel_tools_texture.xml
+++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml
@@ -11,14 +11,6 @@
name="Texture"
top="0"
width="295">
- <panel.string
- name="string repeats per meter">
- Repeats Per Meter
- </panel.string>
- <panel.string
- name="string repeats per face">
- Repeats Per Face
- </panel.string>
<text
type="string"
length="1"
diff --git a/indra/newview/skins/default/xui/en/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/en/panel_volume_pulldown.xml
index 6adede0362..2034409111 100644
--- a/indra/newview/skins/default/xui/en/panel_volume_pulldown.xml
+++ b/indra/newview/skins/default/xui/en/panel_volume_pulldown.xml
@@ -29,7 +29,7 @@
top="10"
volume="true">
<slider.commit_callback
- function="Pref.setControlFalse"
+ function="Vol.setControlFalse"
parameter="MuteAudio" />
</slider>
<button
@@ -61,7 +61,7 @@
top_pad="4"
volume="true">
<slider.commit_callback
- function="Pref.setControlFalse"
+ function="Vol.setControlFalse"
parameter="MuteUI" />
</slider>
<button
@@ -94,7 +94,7 @@
top_pad="4"
volume="true">
<slider.commit_callback
- function="Pref.setControlFalse"
+ function="Vol.setControlFalse"
parameter="MuteAmbient" />
</slider>
<button
@@ -127,7 +127,7 @@
top_pad="4"
volume="true">
<slider.commit_callback
- function="Pref.setControlFalse"
+ function="Vol.setControlFalse"
parameter="MuteSounds" />
</slider>
<button
@@ -144,7 +144,7 @@
tab_stop="false"
width="16">
<button.commit_callback
- function="Pref.SetSounds"/>
+ function="Vol.SetSounds"/>
</button>
<check_box
name="gesture_audio_play_btn"
@@ -173,7 +173,7 @@
top_pad="4"
volume="true">
<slider.commit_callback
- function="Pref.setControlFalse"
+ function="Vol.setControlFalse"
parameter="MuteMusic" />
</slider>
<button
@@ -199,7 +199,7 @@
top_delta="2"
width="350">
<check_box.commit_callback
- function="Pref.updateMediaAutoPlayCheckbox"/>
+ function="Vol.updateMediaAutoPlayCheckbox"/>
</check_box>
<slider
control_name="AudioLevelMedia"
@@ -218,7 +218,7 @@
top_pad="4"
volume="true">
<slider.commit_callback
- function="Pref.setControlFalse"
+ function="Vol.setControlFalse"
parameter="MuteMedia" />
</slider>
<button
@@ -246,7 +246,7 @@
name="enable_media"
width="110">
<check_box.commit_callback
- function="Pref.updateMediaAutoPlayCheckbox"/>
+ function="Vol.updateMediaAutoPlayCheckbox"/>
</check_box>
<slider
control_name="AudioLevelVoice"
@@ -265,7 +265,7 @@
show_text="false"
volume="true">
<slider.commit_callback
- function="Pref.setControlFalse"
+ function="Vol.setControlFalse"
parameter="MuteVoice" />
</slider>
<button
diff --git a/indra/newview/skins/default/xui/en/role_actions.xml b/indra/newview/skins/default/xui/en/role_actions.xml
index 8d058b0b53..f79d752fdb 100644
--- a/indra/newview/skins/default/xui/en/role_actions.xml
+++ b/indra/newview/skins/default/xui/en/role_actions.xml
@@ -4,10 +4,10 @@
description="These Abilities include powers to add and remove group Members, and allow new Members to join without an invitation."
name="Membership">
<action description="Invite People to this Group"
- longdescription="Invite People to this Group using the &apos;Invite&apos; button in the Roles section &gt; Members tab."
+ longdescription="Invite People to this Group using the &apos;Invite&apos; button in the Roles &amp; Members section &gt; Members tab."
name="member invite" value="1" />
- <action description="Eject Members from this Group"
- longdescription="Eject Members from this Group using the &apos;Eject&apos; button in the Roles section &gt; Members tab. An Owner can eject anyone except another Owner. If you&apos;re not an Owner, a Member can be ejected from a group if, and only if, they&apos;re only in the Everyone Role, and NO other Roles. To remove Members from Roles, you need to have the &apos;Remove Members from Roles&apos; Ability."
+ <action description="Eject Members belonging to the 'Everyone' role from this Group"
+ longdescription="Eject Members from this Group using the &apos;Eject&apos; button in the Roles &amp; Members section &gt; Members tab. An Owner can eject anyone except another Owner. If you&apos;re not an Owner, a Member can be ejected from a group if, and only if, they&apos;re only in the Everyone Role, and NO other Roles. To remove Members from Roles, you need to have the &apos;Remove Members from Roles&apos; Ability."
name="member eject" value="2" />
<action description="Manage ban list"
longdescription="Allows the group member to ban / un-ban Residents from this group."
@@ -21,25 +21,25 @@
description="These Abilities include powers to add, remove, and change group Roles, add and remove Members in Roles, and assign Abilities to Roles."
name="Roles">
<action description="Create new Roles"
- longdescription="Create new Roles in the Roles section &gt; Roles tab."
+ longdescription="Create new Roles in the Roles &amp; Members section &gt; Roles tab."
name="role create" value="4" />
<action description="Delete Roles"
- longdescription="Delete Roles in the Roles section &gt; Roles tab."
+ longdescription="Delete Roles in the Roles &amp; Members section &gt; Roles tab."
name="role delete" value="5" />
<action description="Change Role names, titles, descriptions, and whether Role members are publicly revealed"
- longdescription="Change Role names, titles, descriptions, and whether Role members are publicly revealed. This is done at the bottom of the the Roles section &gt; Roles tab after selecting a Role."
+ longdescription="Change Role names, titles, descriptions, and whether Role members are publicly revealed. This is done at the bottom of the the Roles &amp; Members section &gt; Roles tab after selecting a Role."
name="role properties" value="6" />
<action description="Assign Members to Assigner&apos;s Roles"
- longdescription="Assign Members to Roles in the list of Assigned Roles (Roles section &gt; Members tab). A Member with this Ability can only add Members to a Role that the assigner is already in."
+ longdescription="Assign Members to Roles in the list of Assigned Roles (Roles &amp; Members section &gt; Members tab). A Member with this Ability can only add Members to a Role that the assigner is already in."
name="role assign member limited" value="7" />
<action description="Assign Members to Any Role"
- longdescription="Assign Members to Any Role in the list of Assigned Roles (Roles section &gt; Members tab). *WARNING* Any Member in a Role with this Ability can assign themselves--and any other non-Owner Member--to Roles that have more powers than they currently have, potentially elevating themselves to near-Owner power. Be sure you know what you&apos;re doing before assigning this Ability."
+ longdescription="Assign Members to Any Role in the list of Assigned Roles (Roles &amp; Members section &gt; Members tab). *WARNING* Any Member in a Role with this Ability can assign themselves--and any other non-Owner Member--to Roles that have more powers than they currently have, potentially elevating themselves to near-Owner power. Be sure you know what you&apos;re doing before assigning this Ability."
name="role assign member" value="8" />
<action description="Remove Members from Roles"
- longdescription="Remove Members from Roles in the list of Assigned Roles (Roles section &gt; Members tab). Owners can&apos;t be removed."
+ longdescription="Remove Members from Roles in the list of Assigned Roles (Roles &amp; Members section &gt; Members tab). Owners can&apos;t be removed."
name="role remove member" value="9" />
<action description="Assign and Remove Abilities in Roles"
- longdescription="Assign and Remove Abilities for each Role in the list of Allowed Abilities (Roles section &gt; Roles tab). *WARNING* Any Member in a Role with this Ability can assign themselves--and any other non-Owner Member--all Abilities, potentially elevating themselves to near-Owner power. Be sure you know what you&apos;re doing before assigning this Ability."
+ longdescription="Assign and Remove Abilities for each Role in the list of Allowed Abilities (Roles &amp; Members section &gt; Roles tab). *WARNING* Any Member in a Role with this Ability can assign themselves--and any other non-Owner Member--all Abilities, potentially elevating themselves to near-Owner power. Be sure you know what you&apos;re doing before assigning this Ability."
name="role change actions" value="10" />
</action_set>
<action_set
diff --git a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml
index 1d98a84e25..2a1eb425ed 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml
@@ -131,15 +131,6 @@ width="333">
tab_group="1"
top_pad="6"
follows="all" />
- <!-- <button
- follows="bottom|left"
- height="23"
- label="New outfit"
- layout="topleft"
- left_pad="5"
- right="-10"
- name="newlook_btn"
- width="100" />-->
<panel
class="panel_outfit_edit"
filename="panel_outfit_edit.xml"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 5f30a7e87d..882fbaf634 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -159,8 +159,7 @@ Your account is not accessible until
If you feel this is an error, please contact support@secondlife.com.</string>
<string name="LoginFailedPendingLogoutFault">Request for logout responded with a fault from simulator.</string>
<string name="LoginFailedPendingLogout">The system is logging you out right now.
-Your Account will not be available until
-[TIME] Pacific Time.</string>
+Please wait a minute before you try logging in again.</string>
<string name="LoginFailedUnableToCreateSession">Unable to create valid session.</string>
<string name="LoginFailedUnableToConnectToSimulator">Unable to connect to a simulator.</string>
<string name="LoginFailedRestrictedHours">Your account can only access Second Life
@@ -4200,8 +4199,7 @@ Try enclosing path to the editor with double quotes.
<string name="ExperiencePermissionShort10">Control Camera</string>
<string name="ExperiencePermissionShort11">Teleport</string>
<string name="ExperiencePermissionShort12">Permission</string>
- <string name="ExperiencePermissionShortUnknown">Unknown: [Permission]</string>
-
+
<!-- Conversation log messages -->
<string name="logging_calls_disabled_log_empty">
Conversations are not being logged. To begin keeping a log, choose "Save: Log only" or "Save: Log and transcripts" under Preferences > Chat.
diff --git a/indra/newview/skins/default/xui/es/notifications.xml b/indra/newview/skins/default/xui/es/notifications.xml
index 7756f15576..fdf9003321 100644
--- a/indra/newview/skins/default/xui/es/notifications.xml
+++ b/indra/newview/skins/default/xui/es/notifications.xml
@@ -2359,7 +2359,7 @@ Linden Lab
<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Aceptar"/>
</notification>
<notification name="ConfirmEmptyTrash">
- [COUNT] elementos serán borrados de forma permanente. ¿Estás seguro de que quieres borrar de forma permanente el contenido de la Papelera?
+ [COUNT] los objetos y las carpetas se borrarán de forma permanente. ¿Estás seguro de que quieres borrar de forma permanente el contenido de la Papelera?
<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Aceptar"/>
</notification>
<notification name="TrashIsFull">
@@ -3357,12 +3357,18 @@ Comprueba la configuración de la red y del servidor de seguridad.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="NoVoiceConnect">
- Tenemos problemas de conexión con tu servidor de voz:
+ No se pudo establecer una conexión con el servidor de voz:
-[HOSTID]
+[HOSTID]
+
+Los puertos que deben estar activos para el servicio de voz son:
+:TCP: 80, 443
+:UDP: 3478, 3479, 5060, 5062, 6250, 12000-32000
+
+Comprueba la configuración de la red y del servidor de seguridad.
+Desactiva las funciones SIP ALG de tu router.
No podrás establecer comunicaciones de voz.
-Comprueba la configuración de la red y del servidor de seguridad.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="NoVoiceConnect-GIAB">
diff --git a/indra/newview/skins/default/xui/es/panel_main_inventory.xml b/indra/newview/skins/default/xui/es/panel_main_inventory.xml
index 5924dc7b9a..1252c7ce0d 100644
--- a/indra/newview/skins/default/xui/es/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/es/panel_main_inventory.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="Cosas" name="main inventory panel">
<panel.string name="ItemcountFetching">
- Obtenidos [ITEM_COUNT] ítems... [FILTER]
+ Obteniendo [ITEM_COUNT] Objetos y [CATEGORY_COUNT] Carpetas... [FILTER]
</panel.string>
<panel.string name="ItemcountCompleted">
- [ITEM_COUNT] ítems [FILTER]
+ [ITEM_COUNT] Objetos y [CATEGORY_COUNT] Carpetas [FILTER]
</panel.string>
<panel.string name="ItemcountUnknown">
- Obtenidos [ITEM_COUNT] ítems [FILTER]
+ [ITEM_COUNT] Objetos y [CATEGORY_COUNT] Carpetas Obtenidos [FILTER]
</panel.string>
<text name="ItemcountText">
Ãtems:
diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml
index e99bbd4aba..341c6d2fe8 100644
--- a/indra/newview/skins/default/xui/es/strings.xml
+++ b/indra/newview/skins/default/xui/es/strings.xml
@@ -269,9 +269,8 @@ Si crees que se trata de un error, ponte en contacto con support@secondlife.com.
La solicitud de cierre de sesión ha obtenido como resultado un error del simulador.
</string>
<string name="LoginFailedPendingLogout">
- El sistema está cerrando tu sesión en estos momentos.
-Tu cuenta no estará disponible hasta las
-[HORA] (horario de la costa del Pacífico).
+ El sistema te desconectará.
+Por favor, aguarda un momento antes de intentar conectarte nuevamente.
</string>
<string name="LoginFailedUnableToCreateSession">
No se ha podido crear una sesión válida.
@@ -1497,6 +1496,9 @@ Si sigues recibiendo el mismo mensaje, solicita ayuda al personal de asistencia
<string name="InventoryMarketplaceListingsNoItems">
Arrastra carpetas a esta sección para incluirlas en la lista de venta del [[MARKETPLACE_DASHBOARD_URL] Mercado].
</string>
+ <string name="InventoryItemsCount">
+ ( [ITEMS_COUNT] Objetos)
+ </string>
<string name="Marketplace Validation Warning Stock">
La carpeta de stock debe estar contenida en una carpeta de versión
</string>
diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml
index 051692b7b5..6225eba119 100644
--- a/indra/newview/skins/default/xui/fr/notifications.xml
+++ b/indra/newview/skins/default/xui/fr/notifications.xml
@@ -2352,7 +2352,7 @@ Voulez-vous désactiver Ne pas déranger avant de terminer cette transaction ?
<usetemplate name="okcancelbuttons" notext="Annuler" yestext="OK"/>
</notification>
<notification name="ConfirmEmptyTrash">
- [COUNT] objets seront supprimés définitivement. Êtes-vous certain de vouloir supprimer le contenu de votre corbeille de manière permanente ?
+ [COUNT] les objets et les dossiers seront supprimés définitivement. Êtes-vous certain de vouloir supprimer le contenu de votre corbeille de manière permanente ?
<usetemplate name="okcancelbuttons" notext="Annuler" yestext="OK"/>
</notification>
<notification name="TrashIsFull">
@@ -3358,12 +3358,18 @@ Veuillez vérifier la configuration de votre réseau et de votre pare-feu.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="NoVoiceConnect">
- Problèmes de connexion à votre serveur vocal :
+ La connexion au serveur vocal est impossible :
[HOSTID]
+Les ports autorisés pour la voix sont :
+:TCP: 80, 443
+:UDP: 3478, 3479, 5060, 5062, 6250, 12000-32000
+
+Veuillez vérifier la configuration de votre réseau et de votre pare-feu.
+Veuillez désactiver toute fonctionnalité SIP ALG dans votre routeur.
+
Aucune communication vocale n&apos;est disponible.
-Veuillez vérifier la configuration de votre réseau et de votre pare-feu.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="NoVoiceConnect-GIAB">
diff --git a/indra/newview/skins/default/xui/fr/panel_main_inventory.xml b/indra/newview/skins/default/xui/fr/panel_main_inventory.xml
index 11488af119..5bcee89752 100644
--- a/indra/newview/skins/default/xui/fr/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/fr/panel_main_inventory.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="Choses" name="main inventory panel">
<panel.string name="ItemcountFetching">
- [ITEM_COUNT] articles récupérés... [FILTER]
+ Recherche [ITEM_COUNT] d&apos;articles et [CATEGORY_COUNT] de dossiers... [FILTER]
</panel.string>
<panel.string name="ItemcountCompleted">
- [ITEM_COUNT] articles [FILTER]
+ [ITEM_COUNT] Articles et [CATEGORY_COUNT] dossiers [FILTER]
</panel.string>
<panel.string name="ItemcountUnknown">
- [ITEM_COUNT] articles [FILTER] récupérés
+ Recherche effectuée [ITEM_COUNT] d&apos;articles et [CATEGORY_COUNT] de dossiers [FILTER]
</panel.string>
<text name="ItemcountText">
Articles :
diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml
index 2414dd2e2c..d76beee93d 100644
--- a/indra/newview/skins/default/xui/fr/strings.xml
+++ b/indra/newview/skins/default/xui/fr/strings.xml
@@ -278,9 +278,8 @@ Si vous pensez qu&apos;il s&apos;agit d&apos;une erreur, contactez l&apos;Assist
Le simulateur a renvoyé une erreur en réponse à la demande de déconnexion.
</string>
<string name="LoginFailedPendingLogout">
- Le système est en train de vous déconnecter.
-Votre compte sera indisponible jusqu&apos;à
-[TIME], heure du Pacifique.
+ Le système est en train de vous déconnecter.
+Veuillez réessayer de vous connecter dans une minute.
</string>
<string name="LoginFailedUnableToCreateSession">
Impossible de créer de session valide.
@@ -1515,6 +1514,9 @@ Si vous continuez de recevoir ce message, contactez l’assistance Second Life Ã
<string name="InventoryMarketplaceListingsNoItems">
Pour mettre des dossiers en vente sur la [[MARKETPLACE_DASHBOARD_URL] Place du marché], faites-les glisser vers cette zone.
</string>
+ <string name="InventoryItemsCount">
+ ( [ITEMS_COUNT] Articles )
+ </string>
<string name="Marketplace Validation Warning Stock">
le dossier de stock doit être contenu dans un dossier de version
</string>
diff --git a/indra/newview/skins/default/xui/it/notifications.xml b/indra/newview/skins/default/xui/it/notifications.xml
index be9b60a7cf..cf354b8f4f 100644
--- a/indra/newview/skins/default/xui/it/notifications.xml
+++ b/indra/newview/skins/default/xui/it/notifications.xml
@@ -2356,7 +2356,7 @@ Vuoi disattivare la modalità Non disturbare prima di completare questa transazi
<usetemplate name="okcancelbuttons" notext="Annulla" yestext="OK"/>
</notification>
<notification name="ConfirmEmptyTrash">
- [COUNT] oggetti verranno eliminati definitivamente. Vuoi veramente eliminare in modo permanente il contenuto del tuo Cestino?
+ [COUNT] oggetti e cartelle verranno eliminati definitivamente. Vuoi veramente eliminare in modo permanente il contenuto del tuo Cestino?
<usetemplate name="okcancelbuttons" notext="Annulla" yestext="OK"/>
</notification>
<notification name="TrashIsFull">
@@ -3361,12 +3361,18 @@ Ti consigliamo di controllare le tue impostazioni di rete e della firewall.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="NoVoiceConnect">
- A causa di problemi di connessione al server vocale
+ Non riusciamo a collegarci al server voce:
[HOSTID]
-le comunicazioni tramite voce non saranno disponibili.
-Ti consigliamo di controllare le tue impostazioni di rete e della firewall.
+porte che devono avere il permesso voce sono:
+:TCP: 80, 443
+:UDP: 3478, 3479, 5060, 5062, 6250, 12000-32000
+
+Controlla le tue impostazione di rete e della firewall.
+Disabilita la funzione SIP ALG del router.
+
+La comunicazione voce non sará possibile.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="NoVoiceConnect-GIAB">
diff --git a/indra/newview/skins/default/xui/it/panel_main_inventory.xml b/indra/newview/skins/default/xui/it/panel_main_inventory.xml
index 6121651ea8..5d11967cee 100644
--- a/indra/newview/skins/default/xui/it/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/it/panel_main_inventory.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="Cose" name="main inventory panel">
<panel.string name="ItemcountFetching">
- Recupero di [ITEM_COUNT] oggetti... [FILTER]
+ Recupero di [ITEM_COUNT] oggetti e [CATEGORY_COUNT] cartelle... [FILTER]
</panel.string>
<panel.string name="ItemcountCompleted">
- [ITEM_COUNT] oggetti [FILTER]
+ [ITEM_COUNT] oggetti e [CATEGORY_COUNT] cartelle [FILTER]
</panel.string>
<panel.string name="ItemcountUnknown">
- Recuperati [ITEM_COUNT] elementi [FILTER]
+ Recuperati [ITEM_COUNT] oggetti e [CATEGORY_COUNT] cartelle [FILTER]
</panel.string>
<text name="ItemcountText">
Oggetti:
diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml
index 855498dee1..ad74e16170 100644
--- a/indra/newview/skins/default/xui/it/strings.xml
+++ b/indra/newview/skins/default/xui/it/strings.xml
@@ -274,9 +274,8 @@ Se ritieni che si tratta di un errore, contatta support@secondlife.com.
Errore del simulatore in seguito alla richiesta di logout.
</string>
<string name="LoginFailedPendingLogout">
- Il sistema sta eseguendo il logout in questo momento.
-Il tuo account non sarà disponibile fino alle
-[TIME] fuso orario del Pacifico.
+ Il sistema sta eseguendo il logout in questo momento.
+Prova ad accedere nuovamente tra un minuto.
</string>
<string name="LoginFailedUnableToCreateSession">
Non è possibile creare una sessione valida.
@@ -1505,6 +1504,9 @@ Se continui a ricevere questo messaggio, contatta l&apos;assistenza Second Life
<string name="InventoryMarketplaceListingsNoItems">
Trascina le cartelle in questa area per metterle in vendita su [[MARKETPLACE_DASHBOARD_URL] Marketplace].
</string>
+ <string name="InventoryItemsCount">
+ ( [ITEM_COUNT] oggetti )
+ </string>
<string name="Marketplace Validation Warning Stock">
la cartella di magazzino deve essere inclusa in una cartella di versione
</string>
diff --git a/indra/newview/skins/default/xui/ja/notifications.xml b/indra/newview/skins/default/xui/ja/notifications.xml
index d46ab94733..67586efc9e 100644
--- a/indra/newview/skins/default/xui/ja/notifications.xml
+++ b/indra/newview/skins/default/xui/ja/notifications.xml
@@ -2394,7 +2394,7 @@ Linden Lab
<usetemplate name="okcancelbuttons" notext="キャンセル" yestext="OK"/>
</notification>
<notification name="ConfirmEmptyTrash">
- [COUNT] アイテムãŒå®Œå…¨ã«å‰Šé™¤ã•ã‚Œã¾ã™ã€‚ã”ã¿ç®±ã®é …目をã™ã¹ã¦å‰Šé™¤ã—ã¾ã™ã‹ï¼Ÿ
+ [COUNT] 個ã®ã‚¢ã‚¤ãƒ†ãƒ ã¨ãƒ•ã‚©ãƒ«ãƒ€ãƒ¼ãŒå®Œå…¨ã«å‰Šé™¤ã•ã‚Œã¾ã™ã€‚ã”ã¿ç®±ã®é …目をã™ã¹ã¦å‰Šé™¤ã—ã¾ã™ã‹ï¼Ÿ
<usetemplate name="okcancelbuttons" notext="キャンセル" yestext="OK"/>
</notification>
<notification name="TrashIsFull">
@@ -3399,12 +3399,18 @@ M キーを押ã—ã¦å¤‰æ›´ã—ã¾ã™ã€‚
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="NoVoiceConnect">
- ボイスサーãƒãƒ¼ã«æŽ¥ç¶šã§ãã¾ã›ã‚“:
+ ボイスサーãƒãƒ¼ã«æŽ¥ç¶šã§ãã¾ã›ã‚“: 音声ã«è¨±å¯ã•ã‚Œã‚‹å¿…è¦ã®ã‚ã‚‹
[HOSTID]
-ボイスãƒãƒ£ãƒƒãƒˆã«ã‚ˆã‚‹ã‚³ãƒŸãƒ¥ãƒ‹ã‚±ãƒ¼ã‚·ãƒ§ãƒ³ãŒåˆ©ç”¨ã§ãã¾ã›ã‚“。
+ãƒãƒ¼ãƒˆ:
+:TCP:80, 443
+:UDP:3478, 3479, 5060, 5062, 6250, 12000-32000
+
ãŠä½¿ã„ã®ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‚„ファイアウォールã®è¨­å®šã‚’確èªã—ã¦ãã ã•ã„。
+ãŠä½¿ã„ã®ãƒ«ãƒ¼ã‚¿ãƒ¼ã® SIP ALG 機能をã™ã¹ã¦ç„¡åŠ¹ã«ã—ã¦ãã ã•ã„。
+
+ボイスãƒãƒ£ãƒƒãƒˆã«ã‚ˆã‚‹ã‚³ãƒŸãƒ¥ãƒ‹ã‚±ãƒ¼ã‚·ãƒ§ãƒ³ãŒåˆ©ç”¨ã§ãã¾ã›ã‚“。
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="NoVoiceConnect-GIAB">
diff --git a/indra/newview/skins/default/xui/ja/panel_main_inventory.xml b/indra/newview/skins/default/xui/ja/panel_main_inventory.xml
index dce3475585..5751154163 100644
--- a/indra/newview/skins/default/xui/ja/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/ja/panel_main_inventory.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="ã‚‚ã®" name="main inventory panel">
<panel.string name="ItemcountFetching">
- [ITEM_COUNT] 個ã®ã‚¢ã‚¤ãƒ†ãƒ ã‚’å–得中ã§ã™... [FILTER]
+ [ITEM_COUNT] 個ã®ã‚¢ã‚¤ãƒ†ãƒ ã¨ [CATEGORY_COUNT] 個ã®ãƒ•ã‚©ãƒ«ãƒ€ãƒ¼ã‚’å–得中ã§ã™... [FILTER]
</panel.string>
<panel.string name="ItemcountCompleted">
- [ITEM_COUNT] 個ã®ã‚¢ã‚¤ãƒ†ãƒ ã€€[FILTER]
+ [ITEM_COUNT] 個ã®ã‚¢ã‚¤ãƒ†ãƒ ã¨ [CATEGORY_COUNT] 個ã®ãƒ•ã‚©ãƒ«ãƒ€ãƒ¼ [FILTER]
</panel.string>
<panel.string name="ItemcountUnknown">
- [ITEM_COUNT] 個ã®å–得アイテム [FILTER]
+ [ITEM_COUNT] 個ã®ã‚¢ã‚¤ãƒ†ãƒ ã¨ [CATEGORY_COUNT] 個ã®ãƒ•ã‚©ãƒ«ãƒ€ãƒ¼ã‚’å–å¾—ã—ã¾ã—㟠[FILTER]
</panel.string>
<text name="ItemcountText">
アイテム:
diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml
index 263494bdcf..5ca7ddd92c 100644
--- a/indra/newview/skins/default/xui/ja/strings.xml
+++ b/indra/newview/skins/default/xui/ja/strings.xml
@@ -278,8 +278,7 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。
</string>
<string name="LoginFailedPendingLogout">
システムã«ã‚ˆã‚‹ãƒ­ã‚°ã‚¢ã‚¦ãƒˆãŒå®Ÿè¡Œã•ã‚Œã¾ã—ãŸã€‚
-ã‚ãªãŸã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã¯
-太平洋時間㮠[TIME] ã¾ã§ã”利用ã„ãŸã ã‘ã¾ã›ã‚“。
+ã—ã°ã‚‰ãã—ã¦ã‹ã‚‰å†åº¦ãŠè©¦ã—ãã ã•ã„。
</string>
<string name="LoginFailedUnableToCreateSession">
有効ãªã‚»ãƒƒã‚·ãƒ§ãƒ³ã‚’生æˆã§ãã¾ã›ã‚“。
@@ -1513,6 +1512,9 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。
<string name="InventoryMarketplaceListingsNoItems">
[[MARKETPLACE_DASHBOARD_URL] マーケットプレイス]ã«è²©å£²ã™ã‚‹ã‚¢ã‚¤ãƒ†ãƒ ã‚’一覧ã™ã‚‹ã«ã¯ã€ãƒ•ã‚©ãƒ«ãƒ€ã‚’ã“ã®ã‚¨ãƒªã‚¢ã«ãƒ‰ãƒ©ãƒƒã‚°ã—ã¾ã™ã€‚
</string>
+ <string name="InventoryItemsCount">
+ ([ITEMS_COUNT] 個ã®ã‚¢ã‚¤ãƒ†ãƒ ï¼‰
+ </string>
<string name="Marketplace Validation Warning Stock">
ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãƒ•ã‚©ãƒ«ãƒ€ã«åœ¨åº«ãƒ•ã‚©ãƒ«ãƒ€ãŒå«ã¾ã‚Œãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“
</string>
diff --git a/indra/newview/skins/default/xui/pl/floater_tos.xml b/indra/newview/skins/default/xui/pl/floater_tos.xml
index c3bc528d17..789c65a16e 100644
--- a/indra/newview/skins/default/xui/pl/floater_tos.xml
+++ b/indra/newview/skins/default/xui/pl/floater_tos.xml
@@ -5,7 +5,9 @@
</floater.string>
<button label="Kontynuuj" label_selected="Kontynuuj" name="Continue" />
<button label="Anuluj" label_selected="Anuluj" name="Cancel" />
- <check_box label="Zgadzam się na Warunki korzystania z Usług (Terms of Service) i Politykę Prywatności (Privacy Policy)" name="agree_chk" />
+ <text name="agree_list">
+ Zgadzam się na Warunki korzystania z Usług (Terms of Service) i Politykę Prywatności (Privacy Policy)
+ </text>
<text name="tos_heading">
Proszę dokładnie przeczytać Warunki korzystania z Usług (Terms of Service) i Politykę Prywatności (Privacy Policy). Musisz je zaakceptować, aby kontynuować logowanie.
</text>
diff --git a/indra/newview/skins/default/xui/pt/notifications.xml b/indra/newview/skins/default/xui/pt/notifications.xml
index 25192952af..b66f65c682 100644
--- a/indra/newview/skins/default/xui/pt/notifications.xml
+++ b/indra/newview/skins/default/xui/pt/notifications.xml
@@ -2344,7 +2344,7 @@ Deseja desativar o Não perturbe antes de concluir esta transação?
<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/>
</notification>
<notification name="ConfirmEmptyTrash">
- [COUNT] itens serão excluídos permanentemente. Tem certeza de que deseja excluir o conteúdo da Lixeira? Para sempre?
+ [COUNT] itens e pastas serão excluídas permanentemente. Tem certeza de que deseja excluir o conteúdo da Lixeira? Para sempre?
<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/>
</notification>
<notification name="TrashIsFull">
@@ -3346,12 +3346,18 @@ Verifique a configuração da sua rede e firewall.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="NoVoiceConnect">
- Estamos tendo problemas de conexão com o seu servidor de voz:
+ Não conseguimos conectar ao servidor de voz:
[HOSTID]
+As portas que devem ter permissão para voz são:
+:TCP: 80, 443
+:UDP: 3478, 3479, 5060, 5062, 6250, 12000-32000
+
+Verifique a configuração da sua rede e firewall.
+Desativar qualquer configuração SIP ALG em seu router.
+
Talvez não seja possível se comunicar via voz.
-Verifique a configuração da sua rede e firewall.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="NoVoiceConnect-GIAB">
diff --git a/indra/newview/skins/default/xui/pt/panel_main_inventory.xml b/indra/newview/skins/default/xui/pt/panel_main_inventory.xml
index cde53518d0..009b5b3193 100644
--- a/indra/newview/skins/default/xui/pt/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/pt/panel_main_inventory.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="Coisas" name="main inventory panel">
<panel.string name="ItemcountFetching">
- Reunindo [ITEM_COUNT] itens ... [FILTER]
+ Reunir [ITEM_COUNT] Itens e [CATEGORY_COUNT] Pastas... [FILTER]
</panel.string>
<panel.string name="ItemcountCompleted">
- [ITEM_COUNT] itens [FILTER]
+ [ITEM_COUNT] Itens e [CATEGORY_COUNT] Pastas [FILTER]
</panel.string>
<panel.string name="ItemcountUnknown">
- Recuperados [ITEM_COUNT] itens [FILTER]
+ Itens [ITEM_COUNT] e Pastas [CATEGORY_COUNT] Reunidos [FILTER]
</panel.string>
<text name="ItemcountText">
Itens:
diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml
index 48f4876d88..ee048e28e3 100644
--- a/indra/newview/skins/default/xui/pt/strings.xml
+++ b/indra/newview/skins/default/xui/pt/strings.xml
@@ -248,7 +248,8 @@ Entre em contato com o suporte do Second Life para obter ajuda em http://support
Reação à solicitação de saída foi uma falha do simulador.
</string>
<string name="LoginFailedPendingLogout">
- O sistema está passando para o modo offline. Sua conta não está disponível para acesso até [TIME], horário do Pacífico nos EUA (GMT-08).
+ O sistema o está desconectando no momento.
+Aguarde um minuto antes que tentar logar-se novamente.
</string>
<string name="LoginFailedUnableToCreateSession">
Impossível criar sessão válida.
@@ -1463,6 +1464,9 @@ Se você continuar a receber essa mensagem, entre em contato com o suporte do Se
<string name="InventoryMarketplaceListingsNoItems">
Arraste pastas para esta área para listá-las para venda no [Marketplace [MARKETPLACE_DASHBOARD_URL]].
</string>
+ <string name="InventoryItemsCount">
+ ( [ITEMS_COUNT] Items )
+ </string>
<string name="Marketplace Validation Warning Stock">
a pasta de estoque deve estar em uma pasta de versões
</string>
diff --git a/indra/newview/skins/default/xui/ru/notifications.xml b/indra/newview/skins/default/xui/ru/notifications.xml
index fe7f72a02b..483cebaac5 100644
--- a/indra/newview/skins/default/xui/ru/notifications.xml
+++ b/indra/newview/skins/default/xui/ru/notifications.xml
@@ -2351,7 +2351,7 @@
<usetemplate name="okcancelbuttons" notext="Отмена" yestext="OK"/>
</notification>
<notification name="ConfirmEmptyTrash">
- Предметы [COUNT] будут удалены навÑегда. Ð’Ñ‹ дейÑтвительно хотите удалить Ñодержимое корзины без возможноÑти воÑÑтановлениÑ?
+ [COUNT] предметов(а) и папки будут окончательно удалены. Ð’Ñ‹ дейÑтвительно хотите удалить Ñодержимое корзины без возможноÑти воÑÑтановлениÑ?
<usetemplate name="okcancelbuttons" notext="Отмена" yestext="OK"/>
</notification>
<notification name="TrashIsFull">
@@ -3357,12 +3357,18 @@
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="NoVoiceConnect">
- Возникли проблемы ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ñ Ð³Ð¾Ð»Ð¾Ñовым Ñервером:
+ Ðет ÑвÑзи Ñ Ñ€ÐµÑ‡ÐµÐ²Ñ‹Ð¼ Ñервером: порты
-[HOSTID]
+[HOSTID],
-ГолоÑÐ¾Ð²Ð°Ñ ÑвÑзь будет недоÑтупна.
-Проверьте наÑтройки Ñети и брандмауÑра.
+выделенные Ð´Ð»Ñ Ð³Ð¾Ð»Ð¾Ñового ÑоединениÑ:
+:TCP: 80, 443
+:UDP: 3478, 3479, 5060, 5062, 6250, 12000-32000
+
+Проверьте наÑтройки Ñети и брандмауÑра.
+Отключите любую функцию SIP ALG в маршрутизаторе.
+
+ГолоÑовое общение будет недоÑтупно.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="NoVoiceConnect-GIAB">
diff --git a/indra/newview/skins/default/xui/ru/panel_main_inventory.xml b/indra/newview/skins/default/xui/ru/panel_main_inventory.xml
index d83bb9b569..f2502bf6d3 100644
--- a/indra/newview/skins/default/xui/ru/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/ru/panel_main_inventory.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="Вещи" name="main inventory panel">
<panel.string name="ItemcountFetching">
- Обнаружено [ITEM_COUNT] вещей... [FILTER]
+ Выборка [ITEM_COUNT] предметов и [CATEGORY_COUNT] папок ... [FILTER]
</panel.string>
<panel.string name="ItemcountCompleted">
- [ITEM_COUNT] вещей [FILTER]
+ [ITEM_COUNT] предметов(а) и [CATEGORY_COUNT] папки(ок) [FILTER]
</panel.string>
<panel.string name="ItemcountUnknown">
- Извлечено [ITEM_COUNT] вещей [FILTER]
+ Выборка [ITEM_COUNT] предметов и [CATEGORY_COUNT] папок [FILTER]
</panel.string>
<text name="ItemcountText">
Вещи:
diff --git a/indra/newview/skins/default/xui/ru/strings.xml b/indra/newview/skins/default/xui/ru/strings.xml
index 7adac4ef28..95225da7d0 100644
--- a/indra/newview/skins/default/xui/ru/strings.xml
+++ b/indra/newview/skins/default/xui/ru/strings.xml
@@ -278,9 +278,8 @@ support@secondlife.com.
Ð’ ответ на Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð²Ñ‹Ñ…Ð¾Ð´Ð° ÑимулÑтор возвратил Ñообщение о Ñбое.
</string>
<string name="LoginFailedPendingLogout">
- Ð’ ÑиÑтеме выполнÑетÑÑ Ð²Ñ‹Ñ…Ð¾Ð´ Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ аккаунта.
-Она будет недоÑтупна до
-[TIME] по тихоокеанÑкому времени.
+ Ð’ ÑиÑтеме выполнÑетÑÑ Ð²Ñ‹Ñ…Ð¾Ð´ Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ аккаунта.
+Подождите минуту перед повторным входом в ÑиÑтему.
</string>
<string name="LoginFailedUnableToCreateSession">
Ðе удаетÑÑ Ñоздать допуÑтимый ÑеанÑ.
@@ -1512,6 +1511,9 @@ support@secondlife.com.
<string name="InventoryMarketplaceListingsNoItems">
Перетащите папки в Ñту облаÑÑ‚ÑŒ, чтобы выÑтавить их на продажу в [[MARKETPLACE_DASHBOARD_URL] Торговом центре].
</string>
+ <string name="InventoryItemsCount">
+ ( [ITEMS_COUNT] предметов(а))
+ </string>
<string name="Marketplace Validation Warning Stock">
Ð’ папке верÑии должна быть папка запаÑов
</string>
diff --git a/indra/newview/skins/default/xui/tr/notifications.xml b/indra/newview/skins/default/xui/tr/notifications.xml
index e37fcf7fb3..d218eb1957 100644
--- a/indra/newview/skins/default/xui/tr/notifications.xml
+++ b/indra/newview/skins/default/xui/tr/notifications.xml
@@ -2351,7 +2351,7 @@ Bu işlemi tamamlamadan önce Rahatsız Etme&apos;yi kapatmak ister misiniz?
<usetemplate name="okcancelbuttons" notext="Ä°ptal Et" yestext="Tamam"/>
</notification>
<notification name="ConfirmEmptyTrash">
- [COUNT] öğe kalıcı olarak silinecektir. Çöp kutunuzun içeriğini kalıcı olarak silmek istediğinize emin misiniz?
+ [COUNT] öğe ve klasör kalıcı olarak silinecektir. Çöp kutunuzun içeriğini kalıcı olarak silmek istediğinizden emin misiniz?
<usetemplate name="okcancelbuttons" notext="Ä°ptal Et" yestext="Tamam"/>
</notification>
<notification name="TrashIsFull">
@@ -3357,12 +3357,18 @@ Lütfen ağ ve güvenlik duvarı ayarlarınızı kontrol edin.
<usetemplate name="okbutton" yestext="Tamam"/>
</notification>
<notification name="NoVoiceConnect">
- Ses sunucunuz ile bağlantı kurma konusunda sorun yaşıyoruz.
+ Ses sunucusuna bağlanamıyoruz: Ses için izin verilmesi gereken
[HOSTID]
-Ses bağlantıları kullanılamayacak.
-Lütfen ağ ve güvenlik duvarı ayarlarınızı kontrol edin.
+Portları:
+:TCP: 80, 443
+:UDP: 3478, 3479, 5060, 5062, 6250, 12000-32000
+
+Lütfen ağ ve güvenlik duvarı ayarlarınızı kontrol edin.
+Yönlendiricinizdeki her SIP ALG özelliğini devre dışı bırakın.
+
+Sesli iletişim kullanılamayacak.
<usetemplate name="okbutton" yestext="Tamam"/>
</notification>
<notification name="NoVoiceConnect-GIAB">
diff --git a/indra/newview/skins/default/xui/tr/panel_main_inventory.xml b/indra/newview/skins/default/xui/tr/panel_main_inventory.xml
index 01252ff454..a11fd98b9a 100644
--- a/indra/newview/skins/default/xui/tr/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/tr/panel_main_inventory.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="EÅŸyalar" name="main inventory panel">
<panel.string name="ItemcountFetching">
- [ITEM_COUNT] Öge Alınıyor... [FILTER]
+ [ITEM_COUNT] Öğe ve [CATEGORY_COUNT] Klasör Alınıyor... [FILTER]
</panel.string>
<panel.string name="ItemcountCompleted">
- [ITEM_COUNT] Öge [FILTER]
+ [ITEM_COUNT] Öğe ve [CATEGORY_COUNT] Klasör [FILTER]
</panel.string>
<panel.string name="ItemcountUnknown">
- Alınan [ITEM_COUNT] Öğe [FILTER]
+ [ITEM_COUNT] Öğe ve [CATEGORY_COUNT] Klasör Alındı [FILTER]
</panel.string>
<text name="ItemcountText">
Ögeler:
diff --git a/indra/newview/skins/default/xui/tr/strings.xml b/indra/newview/skins/default/xui/tr/strings.xml
index fb9e1b03d1..6850c67df3 100644
--- a/indra/newview/skins/default/xui/tr/strings.xml
+++ b/indra/newview/skins/default/xui/tr/strings.xml
@@ -278,9 +278,8 @@ Bunun bir hata olduğunu düşünüyorsanız, lütfen şu adrese başvurun: supp
Oturum kapatma talebi simülatörden bir hata yanıtı gelmesine neden oldu.
</string>
<string name="LoginFailedPendingLogout">
- Sistem şu anda oturumunuzu sonlandırıyor.
-Hesabınıza şu zamana kadar erişemeyeceksiniz:
-Pasifik Saati ile [TIME].
+ Sistem şu anda oturumunuzu kapatıyor.
+Lütfen yeniden oturum açmayı denemeden önce bir dakika bekleyin.
</string>
<string name="LoginFailedUnableToCreateSession">
Geçerli bir oturum oluşturulamadı.
@@ -1512,6 +1511,9 @@ Bu mesaj size gelmeye devam ederse lütfen http://support.secondlife.com adresin
<string name="InventoryMarketplaceListingsNoItems">
Klasörleri [[MARKETPLACE_DASHBOARD_URL] Pazaryerinde] satılık olarak listelemek için bu alana sürükleyin.
</string>
+ <string name="InventoryItemsCount">
+ ( [ITEMS_COUNT] Öğe )
+ </string>
<string name="Marketplace Validation Warning Stock">
stok klasörü bir sürüm klasöründe bulunmalıdır
</string>
diff --git a/indra/newview/skins/default/xui/zh/notifications.xml b/indra/newview/skins/default/xui/zh/notifications.xml
index e2a96e8efb..5949d068c3 100644
--- a/indra/newview/skins/default/xui/zh/notifications.xml
+++ b/indra/newview/skins/default/xui/zh/notifications.xml
@@ -2348,7 +2348,7 @@ SHA1 指紋:[MD5_DIGEST]
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="ConfirmEmptyTrash">
- [COUNT]個物項將會永久刪除。 你確定你è¦æ°¸ä¹…刪除垃圾筒中的內容?
+ [COUNT]個物項與資料夾將會永久刪除。 你確定你è¦æ°¸ä¹…刪除垃圾筒中的內容?
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="TrashIsFull">
@@ -3353,12 +3353,18 @@ SHA1 指紋:[MD5_DIGEST]
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="NoVoiceConnect">
- 試圖連接語音伺æœå™¨æ™‚出了å•é¡Œï¼š
+ 無法連通語音伺æœå™¨ï¼š
[HOSTID]
-將無法用語音æºé€šã€‚
+å¿…é ˆå…許語音的資料埠如下:
+:TCP: 80, 443
+:UDP: 3478, 3479, 5060, 5062, 6250, 12000-32000
+
請檢查你的網路和防ç«ç‰†è¨­å®šã€‚
+關閉路由器中的SIP ALG(應用層閘é“)功能。
+
+將無法用語音æºé€šã€‚
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="NoVoiceConnect-GIAB">
diff --git a/indra/newview/skins/default/xui/zh/panel_main_inventory.xml b/indra/newview/skins/default/xui/zh/panel_main_inventory.xml
index 49553ecd18..1a28f4c3b5 100644
--- a/indra/newview/skins/default/xui/zh/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/zh/panel_main_inventory.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="事物" name="main inventory panel">
<panel.string name="ItemcountFetching">
- æ­£åœ¨æ“·å– [ITEM_COUNT] 個物項… [FILTER]
+ 正在擷å–[ITEM_COUNT]個物項åŠ[CATEGORY_COUNT]個資料夾… [FILTER]
</panel.string>
<panel.string name="ItemcountCompleted">
- [ITEM_COUNT] ç‰©å“ [FILTER]
+ [ITEM_COUNT]個物項åŠ[CATEGORY_COUNT]個資料夾[FILTER]
</panel.string>
<panel.string name="ItemcountUnknown">
- å·²å–å¾— [ITEM_COUNT] ç‰©å“ [FILTER]
+ æ“·å–了[ITEM_COUNT]個物項åŠ[CATEGORY_COUNT]個資料夾[FILTER]
</panel.string>
<text name="ItemcountText">
物å“:
diff --git a/indra/newview/skins/default/xui/zh/strings.xml b/indra/newview/skins/default/xui/zh/strings.xml
index bc9f02a5cf..e4f9c5d433 100644
--- a/indra/newview/skins/default/xui/zh/strings.xml
+++ b/indra/newview/skins/default/xui/zh/strings.xml
@@ -276,7 +276,7 @@ http://secondlife.com/viewer-access-faq
</string>
<string name="LoginFailedPendingLogout">
系統正在處ç†ä½ çš„登出。
-你的帳號è¦ç­‰åˆ° [TIME] (太平洋時間)æ‰å¯ä½¿ç”¨ã€‚
+è«‹ç¨å¾…一分é˜å†è©¦åœ–é‡æ–°ç™»å…¥ã€‚
</string>
<string name="LoginFailedUnableToCreateSession">
無法建立有效的時域。
@@ -1507,6 +1507,9 @@ http://secondlife.com/support 求助解決å•é¡Œã€‚
<string name="InventoryMarketplaceListingsNoItems">
將資料夾拖曳到這個å€åŸŸï¼Œå³å¯åœ¨[[MARKETPLACE_DASHBOARD_URL] Marketplace]刊登出售。
</string>
+ <string name="InventoryItemsCount">
+ ([ITEMS_COUNT]個物項)
+ </string>
<string name="Marketplace Validation Warning Stock">
é™é‡è³‡æ–™å¤¾å¿…須放在版本資料夾裡
</string>
diff --git a/indra/newview/tests/lldateutil_test.cpp b/indra/newview/tests/lldateutil_test.cpp
index 47353962e1..62158d8f66 100644
--- a/indra/newview/tests/lldateutil_test.cpp
+++ b/indra/newview/tests/lldateutil_test.cpp
@@ -45,7 +45,7 @@ std::map< std::string, std::string > gString;
typedef std::pair< std::string, int > count_string_t;
std::map< count_string_t, std::string > gCountString;
-std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args)
+std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args, bool def_string)
{
std::string text = gString[xml_desc];
LLStringUtil::format(text, args);
diff --git a/indra/newview/tests/llsechandler_basic_test.cpp b/indra/newview/tests/llsechandler_basic_test.cpp
index 3d01c5378f..63967fae37 100644
--- a/indra/newview/tests/llsechandler_basic_test.cpp
+++ b/indra/newview/tests/llsechandler_basic_test.cpp
@@ -210,133 +210,139 @@ namespace tut
"-----END CERTIFICATE-----\n"
);
+ /*
+ * The following certificates were generated using the instructions at
+ * https://jamielinux.com/docs/openssl-certificate-authority/sign-server-and-client-certificates.html
+ * with the exception that the server certificate has a longer expiration time, and the full text
+ * expansion was included in the certificates.
+ */
const std::string mPemRootCert(
"Certificate:\n"
" Data:\n"
" Version: 3 (0x2)\n"
" Serial Number:\n"
- " bb:28:84:73:42:18:8b:67\n"
+ " 82:2f:8f:eb:8d:06:24:b0\n"
" Signature Algorithm: sha256WithRSAEncryption\n"
" Issuer: C=US, ST=California, L=San Francisco, O=Linden Lab, OU=Second Life Engineering, CN=Integration Test Root CA/emailAddress=noreply@lindenlab.com\n"
" Validity\n"
- " Not Before: Apr 10 19:28:59 2017 GMT\n"
- " Not After : Apr 5 19:28:59 2037 GMT\n"
+ " Not Before: May 22 22:19:45 2018 GMT\n"
+ " Not After : May 17 22:19:45 2038 GMT\n"
" Subject: C=US, ST=California, L=San Francisco, O=Linden Lab, OU=Second Life Engineering, CN=Integration Test Root CA/emailAddress=noreply@lindenlab.com\n"
" Subject Public Key Info:\n"
" Public Key Algorithm: rsaEncryption\n"
" Public-Key: (4096 bit)\n"
" Modulus:\n"
- " 00:af:ea:5d:a6:b3:e2:28:d6:98:48:69:4e:10:b8:\n"
- " 03:3e:5c:6b:af:e3:d6:f5:e6:1e:b5:6e:77:f0:eb:\n"
- " 9c:72:2a:ba:f0:9e:f9:a9:d3:7f:9d:64:5c:a5:f2:\n"
- " 16:99:7c:96:67:69:aa:f1:3e:27:b6:03:c3:f6:8e:\n"
- " c1:f9:01:3e:35:04:bf:a4:ff:12:78:77:4b:39:e7:\n"
- " e4:93:09:e7:74:b3:3a:07:47:a2:9c:d2:1d:8c:e8:\n"
- " 77:d9:c2:1c:4e:eb:51:dd:28:82:d4:e0:22:6d:32:\n"
- " 4a:2e:25:53:b1:46:ff:49:18:99:8d:d6:ad:db:16:\n"
- " a5:0d:4a:d1:7c:19:d6:c7:08:7e:d2:90:1f:f9:e1:\n"
- " 9c:54:bd:bd:c4:75:4f:10:01:78:09:35:5a:f2:2f:\n"
- " e5:42:36:76:17:cf:42:c9:ab:ef:aa:23:1e:50:3d:\n"
- " f2:9d:17:d1:d0:e9:6c:94:8e:a8:5d:d1:a1:8b:13:\n"
- " be:45:cc:77:6b:cb:4b:ad:23:87:1d:16:4a:ac:9d:\n"
- " e2:b8:07:c4:17:2b:53:ca:87:7b:81:dd:ad:5c:0a:\n"
- " 87:00:8a:87:ae:84:cb:81:e2:9f:75:49:2b:e5:b7:\n"
- " 78:63:be:68:fd:2f:f1:ee:10:f9:51:ef:7f:f1:59:\n"
- " f1:43:8d:c3:6d:33:29:4a:e5:25:cb:e1:0f:2a:e7:\n"
- " e5:8a:92:cf:5e:56:25:79:92:5e:70:d7:5f:de:55:\n"
- " a5:09:77:cf:06:26:62:2d:f6:86:a8:39:02:1d:0b:\n"
- " 2d:d6:06:d1:68:2e:03:cf:7f:a5:2a:bb:b2:f5:48:\n"
- " 22:57:bc:1a:18:f0:f9:33:99:f7:20:b7:ac:b7:06:\n"
- " 01:5d:0b:62:7e:83:f0:00:a0:96:51:9b:0d:1d:23:\n"
- " c5:62:b9:27:ba:f8:bd:16:45:cf:13:31:79:6d:5f:\n"
- " a9:8b:59:f5:74:97:30:ac:a8:e8:05:fa:72:e5:f0:\n"
- " c7:33:8d:20:3d:4c:f3:6b:8e:43:3e:0e:51:9a:2e:\n"
- " e2:1d:e6:29:f2:d7:bc:a2:5d:54:e8:90:d3:07:20:\n"
- " b0:6e:71:3f:13:ef:c3:7e:9a:cb:57:83:1b:f6:32:\n"
- " 82:65:cd:69:73:9c:ab:95:76:97:47:2f:ab:b5:3c:\n"
- " eb:90:a9:5c:0c:03:24:02:0f:3a:00:08:37:ee:b4:\n"
- " e9:21:af:92:cd:a2:49:fe:d5:f3:8f:89:5d:2b:53:\n"
- " 66:cf:bc:78:d0:37:76:b8:16:d5:8d:21:bf:8f:98:\n"
- " b5:43:29:a1:32:ec:8c:58:9b:6b:3a:52:12:89:d1:\n"
- " 3f:63:01:5f:e5:1b:d2:be:75:d9:65:29:9e:12:a1:\n"
- " c4:de:3a:a9:25:94:94:32:d7:e8:ca:d3:02:9b:2f:\n"
- " 92:9a:11\n"
+ " 00:bd:e0:79:dd:3b:a6:ac:87:d0:39:f0:58:c7:a4:\n"
+ " 42:42:f6:5f:93:b0:36:04:b5:e2:d5:f7:2a:c0:6c:\n"
+ " a0:13:d2:1e:02:81:57:02:50:4c:57:b7:ef:27:9e:\n"
+ " f6:f1:f1:30:30:72:1e:57:34:e5:3f:82:3c:21:c4:\n"
+ " 66:d2:73:63:6c:91:e6:dd:49:9e:9c:b1:34:6a:81:\n"
+ " 45:a1:6e:c4:50:28:f2:d8:e3:fe:80:2f:83:aa:28:\n"
+ " 91:b4:8c:57:c9:f1:16:d9:0c:87:3c:25:80:a0:81:\n"
+ " 8d:71:f2:96:e2:16:f1:97:c4:b0:d8:53:bb:13:6c:\n"
+ " 73:54:2f:29:94:85:cf:86:6e:75:71:ad:39:e3:fc:\n"
+ " 39:12:53:93:1c:ce:39:e0:33:da:49:b7:3d:af:b0:\n"
+ " 37:ce:77:09:03:27:32:70:c0:9c:7f:9c:89:ce:90:\n"
+ " 45:b0:7d:94:8b:ff:13:27:ba:88:7f:ae:c4:aa:73:\n"
+ " d5:47:b8:87:69:89:80:0c:c1:22:18:78:c2:0d:47:\n"
+ " d9:10:ff:80:79:0d:46:71:ec:d9:ba:c9:f3:77:fd:\n"
+ " 92:6d:1f:0f:d9:54:18:6d:f6:72:24:5c:5c:3d:43:\n"
+ " 49:35:3e:1c:28:de:7e:44:dc:29:c3:9f:62:04:46:\n"
+ " aa:c4:e6:69:6a:15:f8:e3:74:1c:14:e9:f4:97:7c:\n"
+ " 30:6c:d4:28:fc:2a:0e:1d:6d:39:2e:1d:f9:17:43:\n"
+ " 35:5d:23:e7:ba:e3:a8:e9:97:6b:3c:3e:23:ef:d8:\n"
+ " bc:fb:7a:57:37:39:93:59:03:fc:78:ca:b1:31:ef:\n"
+ " 26:19:ed:56:e1:63:c3:ad:99:80:5b:47:b5:03:35:\n"
+ " 5f:fe:6a:a6:21:63:ec:50:fb:4e:c9:f9:ae:a5:66:\n"
+ " d0:55:33:8d:e6:c5:50:5a:c6:8f:5c:34:45:a7:72:\n"
+ " da:50:f6:66:4c:19:f5:d1:e4:fb:11:8b:a1:b5:4e:\n"
+ " 09:43:81:3d:39:28:86:3b:fe:07:28:97:02:b5:3a:\n"
+ " 07:5f:4a:20:80:1a:7d:a4:8c:f7:6c:f6:c5:9b:f6:\n"
+ " 61:e5:c7:b0:c3:d5:58:38:7b:bb:47:1e:34:d6:16:\n"
+ " 55:c5:d2:6c:b0:93:77:b1:90:69:06:b1:53:cb:1b:\n"
+ " 84:71:cf:b8:87:1b:1e:44:35:b4:2b:bb:04:59:58:\n"
+ " 0b:e8:93:d8:ae:21:9b:b1:1c:89:30:ae:11:80:77:\n"
+ " cc:16:f3:d6:35:ed:a1:b3:70:b3:4f:cd:a1:56:99:\n"
+ " ee:0e:c0:00:a4:09:70:c3:5b:0b:be:a1:07:18:dd:\n"
+ " c6:f4:6d:8b:58:bc:f9:bb:4b:01:2c:f6:cc:2c:9b:\n"
+ " 87:0e:b1:4f:9c:10:be:fc:45:e2:a4:ec:7e:fc:ff:\n"
+ " 45:b8:53\n"
" Exponent: 65537 (0x10001)\n"
" X509v3 extensions:\n"
" X509v3 Subject Key Identifier: \n"
- " CC:4E:CF:A0:E2:60:4F:BE:F2:77:51:1D:6E:3E:C6:B6:5A:38:23:A8\n"
+ " 8A:22:C6:9C:2E:11:F3:40:0C:CE:82:0C:22:59:FF:F8:7F:D0:B9:13\n"
" X509v3 Authority Key Identifier: \n"
- " keyid:CC:4E:CF:A0:E2:60:4F:BE:F2:77:51:1D:6E:3E:C6:B6:5A:38:23:A8\n"
+ " keyid:8A:22:C6:9C:2E:11:F3:40:0C:CE:82:0C:22:59:FF:F8:7F:D0:B9:13\n"
"\n"
" X509v3 Basic Constraints: critical\n"
" CA:TRUE\n"
" X509v3 Key Usage: critical\n"
" Digital Signature, Certificate Sign, CRL Sign\n"
" Signature Algorithm: sha256WithRSAEncryption\n"
- " 68:b8:c5:d6:dd:e2:2f:5d:29:0b:aa:9f:10:66:88:fd:61:5d:\n"
- " 3a:0a:e0:aa:29:7f:42:4f:db:86:57:c3:96:e3:97:ff:bd:e7:\n"
- " 1e:c5:4d:00:87:64:3c:80:68:d6:f9:61:00:47:5e:f1:92:7f:\n"
- " 6f:0c:c7:8a:87:2b:b3:10:ff:22:8c:0a:8f:9f:5d:14:88:90:\n"
- " 52:12:a0:32:29:ea:8c:21:90:ed:0c:6a:70:26:43:81:bb:6e:\n"
- " e2:36:4f:72:10:36:87:61:5d:27:f6:19:d9:83:ad:4b:51:7f:\n"
- " 5c:33:64:fd:2e:ac:86:80:95:bc:12:c6:26:02:06:9a:46:8b:\n"
- " 76:d9:89:e4:d6:02:bc:34:7c:f5:9a:51:e1:14:42:c9:7e:68:\n"
- " 16:be:b3:50:e1:42:4b:05:32:8c:d0:2d:44:df:3e:d2:86:a7:\n"
- " 89:20:b6:ee:bd:c8:dd:ad:f9:96:a2:1b:84:ad:51:87:23:66:\n"
- " c0:fa:09:df:c0:d1:72:5e:a8:28:60:3f:6d:75:1d:6b:bc:a6:\n"
- " d1:10:d7:be:d9:ac:26:b4:df:58:10:6e:09:33:6b:42:c8:79:\n"
- " f5:38:53:4d:56:11:15:b8:39:2c:97:e4:7e:a9:63:b7:9a:b4:\n"
- " b1:ab:7d:4c:3e:80:97:47:f8:dd:2e:74:e2:43:ad:6c:b4:88:\n"
- " 26:2c:1f:f2:88:ab:49:35:bc:65:27:db:59:c2:e6:1a:e5:ad:\n"
- " f1:c3:44:fb:92:8a:1c:0e:b5:11:7a:00:26:90:e7:73:ee:c0:\n"
- " 8b:d6:b8:fd:ec:e7:80:a7:d2:6f:68:8c:bc:4d:4c:90:20:97:\n"
- " 85:33:7e:03:1b:88:8a:4d:5e:3c:00:f7:78:ec:2d:80:ec:09:\n"
- " 37:27:50:62:54:da:48:64:c9:30:1c:8a:3e:de:08:82:60:8b:\n"
- " 19:da:e2:a7:19:fb:0e:1f:95:b7:cd:1c:c2:cb:07:06:97:c0:\n"
- " 03:65:d5:a0:6f:03:66:22:11:e8:23:c9:98:83:d4:0e:a4:4b:\n"
- " e5:62:02:62:67:b6:bd:3c:80:92:60:20:2e:0f:0a:59:75:7e:\n"
- " b1:8e:0c:53:08:bd:12:09:2f:a0:53:dc:8d:46:77:68:bc:99:\n"
- " 7d:1d:41:66:f6:93:86:d4:64:f7:f6:5e:97:8c:4a:1d:93:38:\n"
- " 9c:3b:7c:4e:e9:69:e8:83:c8:0f:f3:3a:42:b5:44:d1:5f:d2:\n"
- " 9a:33:e3:be:1b:8f:74:23:c4:4e:ca:cf:91:38:d6:ee:67:32:\n"
- " 25:62:4f:a1:64:1a:b9:52:98:39:c2:a0:e0:7f:b9:51:74:78:\n"
- " cc:af:55:08:d6:86:11:62:80:7f:b6:39:a2:60:ee:b7:99:a6:\n"
- " 59:04:76:51:85:e3:ba:59\n"
+ " b3:cb:33:eb:0e:02:64:f4:55:9a:3d:03:9a:cf:6a:4c:18:43:\n"
+ " f7:42:cb:65:dc:61:52:e5:9f:2f:42:97:3c:93:16:22:d4:af:\n"
+ " ae:b2:0f:c3:9b:ef:e0:cc:ee:b6:b1:69:a3:d8:da:26:c3:ad:\n"
+ " 3b:c5:64:dc:9f:d4:c2:53:4b:91:6d:c4:92:09:0b:ac:f0:99:\n"
+ " be:6f:b9:3c:03:4a:6d:9f:01:5d:ec:5a:9a:f3:a7:e5:3b:2c:\n"
+ " 99:57:7d:7e:25:15:68:20:12:30:96:16:86:f5:db:74:90:60:\n"
+ " fe:8b:df:99:f6:f7:62:49:9f:bc:8d:45:23:0a:c8:73:b8:79:\n"
+ " 80:3c:b9:e5:72:85:4b:b3:81:66:74:a2:72:92:4c:44:fd:7b:\n"
+ " 46:2e:21:a2:a9:81:a2:f3:26:4d:e3:89:7d:78:b0:c6:6f:b5:\n"
+ " 87:cb:ee:25:ed:27:1f:75:13:fa:6d:e9:37:73:ad:07:bb:af:\n"
+ " d3:6c:87:ea:02:01:70:bd:53:aa:ce:39:2c:d4:66:39:33:aa:\n"
+ " d1:9c:ee:67:e3:a9:45:d2:7b:2e:54:09:af:70:5f:3f:5a:67:\n"
+ " 2e:6c:72:ef:e0:9d:92:28:4a:df:ba:0b:b7:23:ca:5b:04:11:\n"
+ " 45:d1:51:e9:ea:c9:ec:54:fa:34:46:ae:fc:dc:6c:f8:1e:2c:\n"
+ " 9e:f4:71:51:8d:b5:a1:26:9a:13:30:be:1e:41:25:59:58:05:\n"
+ " 2c:64:c8:f9:5e:38:ae:dc:93:b0:8a:d6:38:74:02:cb:ce:ce:\n"
+ " 95:31:76:f6:7c:bf:a4:a1:8e:27:fd:ca:74:82:d1:e1:4d:b6:\n"
+ " 48:51:fa:c5:17:59:22:a3:84:be:82:c8:83:ec:61:a0:f4:ee:\n"
+ " 2c:e3:a3:ea:e5:51:c9:d3:4f:db:85:bd:ba:7a:52:14:b6:03:\n"
+ " ed:43:17:d8:d7:1c:22:5e:c9:56:d9:d6:81:96:11:e3:5e:01:\n"
+ " 40:91:30:09:da:a3:5f:d3:27:60:e5:9d:6c:da:d0:f0:39:01:\n"
+ " 23:4a:a6:15:7a:4a:82:eb:ec:72:4a:1d:36:dc:6f:83:c4:85:\n"
+ " 84:b5:8d:cd:09:e5:12:63:f3:21:56:c8:64:6b:db:b8:cf:d4:\n"
+ " df:ca:a8:24:8e:df:8d:63:a5:96:84:bf:ff:8b:7e:46:7a:f0:\n"
+ " c7:73:7c:70:8a:f5:17:d0:ac:c8:89:1e:d7:89:42:0f:4d:66:\n"
+ " c4:d8:bb:36:a8:ae:ca:e1:cf:e2:88:f6:cf:b0:44:4a:5f:81:\n"
+ " 50:4b:d6:28:81:cd:6c:f0:ec:e6:09:08:f2:59:91:a2:69:ac:\n"
+ " c7:81:fa:ab:61:3e:db:6f:f6:7f:db:1a:9e:b9:5d:cc:cc:33:\n"
+ " fa:95:c6:f7:8d:4b:30:f3\n"
"-----BEGIN CERTIFICATE-----\n"
- "MIIGXDCCBESgAwIBAgIJALsohHNCGItnMA0GCSqGSIb3DQEBCwUAMIG6MQswCQYD\n"
+ "MIIGXDCCBESgAwIBAgIJAIIvj+uNBiSwMA0GCSqGSIb3DQEBCwUAMIG6MQswCQYD\n"
"VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5j\n"
"aXNjbzETMBEGA1UECgwKTGluZGVuIExhYjEgMB4GA1UECwwXU2Vjb25kIExpZmUg\n"
"RW5naW5lZXJpbmcxITAfBgNVBAMMGEludGVncmF0aW9uIFRlc3QgUm9vdCBDQTEk\n"
- "MCIGCSqGSIb3DQEJARYVbm9yZXBseUBsaW5kZW5sYWIuY29tMB4XDTE3MDQxMDE5\n"
- "Mjg1OVoXDTM3MDQwNTE5Mjg1OVowgboxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApD\n"
+ "MCIGCSqGSIb3DQEJARYVbm9yZXBseUBsaW5kZW5sYWIuY29tMB4XDTE4MDUyMjIy\n"
+ "MTk0NVoXDTM4MDUxNzIyMTk0NVowgboxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApD\n"
"YWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMRMwEQYDVQQKDApMaW5k\n"
"ZW4gTGFiMSAwHgYDVQQLDBdTZWNvbmQgTGlmZSBFbmdpbmVlcmluZzEhMB8GA1UE\n"
"AwwYSW50ZWdyYXRpb24gVGVzdCBSb290IENBMSQwIgYJKoZIhvcNAQkBFhVub3Jl\n"
"cGx5QGxpbmRlbmxhYi5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC\n"
- "AQCv6l2ms+Io1phIaU4QuAM+XGuv49b15h61bnfw65xyKrrwnvmp03+dZFyl8haZ\n"
- "fJZnaarxPie2A8P2jsH5AT41BL+k/xJ4d0s55+STCed0szoHR6Kc0h2M6HfZwhxO\n"
- "61HdKILU4CJtMkouJVOxRv9JGJmN1q3bFqUNStF8GdbHCH7SkB/54ZxUvb3EdU8Q\n"
- "AXgJNVryL+VCNnYXz0LJq++qIx5QPfKdF9HQ6WyUjqhd0aGLE75FzHdry0utI4cd\n"
- "FkqsneK4B8QXK1PKh3uB3a1cCocAioeuhMuB4p91SSvlt3hjvmj9L/HuEPlR73/x\n"
- "WfFDjcNtMylK5SXL4Q8q5+WKks9eViV5kl5w11/eVaUJd88GJmIt9oaoOQIdCy3W\n"
- "BtFoLgPPf6Uqu7L1SCJXvBoY8Pkzmfcgt6y3BgFdC2J+g/AAoJZRmw0dI8ViuSe6\n"
- "+L0WRc8TMXltX6mLWfV0lzCsqOgF+nLl8MczjSA9TPNrjkM+DlGaLuId5iny17yi\n"
- "XVTokNMHILBucT8T78N+mstXgxv2MoJlzWlznKuVdpdHL6u1POuQqVwMAyQCDzoA\n"
- "CDfutOkhr5LNokn+1fOPiV0rU2bPvHjQN3a4FtWNIb+PmLVDKaEy7IxYm2s6UhKJ\n"
- "0T9jAV/lG9K+ddllKZ4SocTeOqkllJQy1+jK0wKbL5KaEQIDAQABo2MwYTAdBgNV\n"
- "HQ4EFgQUzE7PoOJgT77yd1Edbj7Gtlo4I6gwHwYDVR0jBBgwFoAUzE7PoOJgT77y\n"
- "d1Edbj7Gtlo4I6gwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJ\n"
- "KoZIhvcNAQELBQADggIBAGi4xdbd4i9dKQuqnxBmiP1hXToK4Kopf0JP24ZXw5bj\n"
- "l/+95x7FTQCHZDyAaNb5YQBHXvGSf28Mx4qHK7MQ/yKMCo+fXRSIkFISoDIp6owh\n"
- "kO0ManAmQ4G7buI2T3IQNodhXSf2GdmDrUtRf1wzZP0urIaAlbwSxiYCBppGi3bZ\n"
- "ieTWArw0fPWaUeEUQsl+aBa+s1DhQksFMozQLUTfPtKGp4kgtu69yN2t+ZaiG4St\n"
- "UYcjZsD6Cd/A0XJeqChgP211HWu8ptEQ177ZrCa031gQbgkza0LIefU4U01WERW4\n"
- "OSyX5H6pY7eatLGrfUw+gJdH+N0udOJDrWy0iCYsH/KIq0k1vGUn21nC5hrlrfHD\n"
- "RPuSihwOtRF6ACaQ53PuwIvWuP3s54Cn0m9ojLxNTJAgl4UzfgMbiIpNXjwA93js\n"
- "LYDsCTcnUGJU2khkyTAcij7eCIJgixna4qcZ+w4flbfNHMLLBwaXwANl1aBvA2Yi\n"
- "EegjyZiD1A6kS+ViAmJntr08gJJgIC4PCll1frGODFMIvRIJL6BT3I1Gd2i8mX0d\n"
- "QWb2k4bUZPf2XpeMSh2TOJw7fE7paeiDyA/zOkK1RNFf0poz474bj3QjxE7Kz5E4\n"
- "1u5nMiViT6FkGrlSmDnCoOB/uVF0eMyvVQjWhhFigH+2OaJg7reZplkEdlGF47pZ\n"
+ "AQC94HndO6ash9A58FjHpEJC9l+TsDYEteLV9yrAbKAT0h4CgVcCUExXt+8nnvbx\n"
+ "8TAwch5XNOU/gjwhxGbSc2NskebdSZ6csTRqgUWhbsRQKPLY4/6AL4OqKJG0jFfJ\n"
+ "8RbZDIc8JYCggY1x8pbiFvGXxLDYU7sTbHNULymUhc+GbnVxrTnj/DkSU5Mczjng\n"
+ "M9pJtz2vsDfOdwkDJzJwwJx/nInOkEWwfZSL/xMnuoh/rsSqc9VHuIdpiYAMwSIY\n"
+ "eMINR9kQ/4B5DUZx7Nm6yfN3/ZJtHw/ZVBht9nIkXFw9Q0k1Phwo3n5E3CnDn2IE\n"
+ "RqrE5mlqFfjjdBwU6fSXfDBs1Cj8Kg4dbTkuHfkXQzVdI+e646jpl2s8PiPv2Lz7\n"
+ "elc3OZNZA/x4yrEx7yYZ7VbhY8OtmYBbR7UDNV/+aqYhY+xQ+07J+a6lZtBVM43m\n"
+ "xVBaxo9cNEWnctpQ9mZMGfXR5PsRi6G1TglDgT05KIY7/gcolwK1OgdfSiCAGn2k\n"
+ "jPds9sWb9mHlx7DD1Vg4e7tHHjTWFlXF0mywk3exkGkGsVPLG4Rxz7iHGx5ENbQr\n"
+ "uwRZWAvok9iuIZuxHIkwrhGAd8wW89Y17aGzcLNPzaFWme4OwACkCXDDWwu+oQcY\n"
+ "3cb0bYtYvPm7SwEs9swsm4cOsU+cEL78ReKk7H78/0W4UwIDAQABo2MwYTAdBgNV\n"
+ "HQ4EFgQUiiLGnC4R80AMzoIMIln/+H/QuRMwHwYDVR0jBBgwFoAUiiLGnC4R80AM\n"
+ "zoIMIln/+H/QuRMwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJ\n"
+ "KoZIhvcNAQELBQADggIBALPLM+sOAmT0VZo9A5rPakwYQ/dCy2XcYVLlny9ClzyT\n"
+ "FiLUr66yD8Ob7+DM7raxaaPY2ibDrTvFZNyf1MJTS5FtxJIJC6zwmb5vuTwDSm2f\n"
+ "AV3sWprzp+U7LJlXfX4lFWggEjCWFob123SQYP6L35n292JJn7yNRSMKyHO4eYA8\n"
+ "ueVyhUuzgWZ0onKSTET9e0YuIaKpgaLzJk3jiX14sMZvtYfL7iXtJx91E/pt6Tdz\n"
+ "rQe7r9Nsh+oCAXC9U6rOOSzUZjkzqtGc7mfjqUXSey5UCa9wXz9aZy5scu/gnZIo\n"
+ "St+6C7cjylsEEUXRUenqyexU+jRGrvzcbPgeLJ70cVGNtaEmmhMwvh5BJVlYBSxk\n"
+ "yPleOK7ck7CK1jh0AsvOzpUxdvZ8v6Shjif9ynSC0eFNtkhR+sUXWSKjhL6CyIPs\n"
+ "YaD07izjo+rlUcnTT9uFvbp6UhS2A+1DF9jXHCJeyVbZ1oGWEeNeAUCRMAnao1/T\n"
+ "J2DlnWza0PA5ASNKphV6SoLr7HJKHTbcb4PEhYS1jc0J5RJj8yFWyGRr27jP1N/K\n"
+ "qCSO341jpZaEv/+LfkZ68MdzfHCK9RfQrMiJHteJQg9NZsTYuzaorsrhz+KI9s+w\n"
+ "REpfgVBL1iiBzWzw7OYJCPJZkaJprMeB+qthPttv9n/bGp65XczMM/qVxveNSzDz\n"
"-----END CERTIFICATE-----\n"
);
@@ -348,124 +354,124 @@ namespace tut
" Signature Algorithm: sha256WithRSAEncryption\n"
" Issuer: C=US, ST=California, L=San Francisco, O=Linden Lab, OU=Second Life Engineering, CN=Integration Test Root CA/emailAddress=noreply@lindenlab.com\n"
" Validity\n"
- " Not Before: Apr 10 20:24:52 2017 GMT\n"
- " Not After : Apr 8 20:24:52 2027 GMT\n"
+ " Not Before: May 22 22:39:08 2018 GMT\n"
+ " Not After : May 19 22:39:08 2028 GMT\n"
" Subject: C=US, ST=California, O=Linden Lab, OU=Second Life Engineering, CN=Integration Test Intermediate CA/emailAddress=noreply@lindenlab.com\n"
" Subject Public Key Info:\n"
" Public Key Algorithm: rsaEncryption\n"
" Public-Key: (4096 bit)\n"
" Modulus:\n"
- " 00:b4:9b:29:c6:22:c4:de:78:71:ed:2d:0d:90:32:\n"
- " fc:da:e7:8c:51:51:d2:fe:ec:e4:ca:5c:c8:5e:e0:\n"
- " c2:97:50:b7:c2:bd:22:91:35:4b:fd:b4:ac:20:21:\n"
- " b0:59:15:49:40:ff:91:9e:94:22:91:59:68:f4:ed:\n"
- " 84:81:8d:be:15:67:02:8e:bf:6d:86:39:7e:42:3a:\n"
- " ea:72:9e:ca:5b:ef:1e:96:6c:bc:30:65:c1:73:f6:\n"
- " 87:92:1f:24:f7:fb:39:77:b1:49:6b:27:5c:21:ba:\n"
- " f6:f9:1d:d5:6d:cc:58:8e:6d:d1:6b:fe:ec:89:34:\n"
- " 34:80:d9:03:27:d5:6f:bc:7f:c7:b3:8c:63:4d:34:\n"
- " 37:61:d0:f9:54:2e:2a:a8:85:03:04:22:b7:19:5b:\n"
- " a3:57:e4:43:a1:88:3c:42:04:c8:c3:fb:ef:0c:78:\n"
- " da:76:8c:e1:27:90:b1:b4:e2:c5:f3:b0:7c:0c:95:\n"
- " 3e:cd:ed:ee:f8:28:28:c0:ba:64:e9:b5:0a:42:f3:\n"
- " 8f:b1:dd:cc:41:58:a7:e7:a1:b0:2c:8e:58:55:3e:\n"
- " 8c:d7:db:f2:51:38:96:4f:ae:1d:8e:ae:e3:87:1a:\n"
- " 6c:8f:6b:3b:5a:1a:a9:49:bc:69:79:9f:28:6f:e2:\n"
- " ac:08:40:52:d9:87:c9:f2:27:d7:fb:62:85:5f:7f:\n"
- " 09:a9:64:07:7b:7a:0e:ba:a5:58:18:23:aa:b2:df:\n"
- " 66:77:f6:6a:ee:f7:79:18:30:12:b2:cf:60:79:af:\n"
- " 86:d5:b8:db:ee:a0:13:2f:80:e1:69:0d:67:14:e5:\n"
- " 9a:99:4c:10:2d:b1:26:6c:b8:3c:10:2f:8e:db:cb:\n"
- " 4a:9e:9e:50:a2:98:76:49:7b:26:c1:8f:bf:50:00:\n"
- " f3:af:06:98:0a:af:78:03:84:5d:56:41:e0:90:7c:\n"
- " 9a:a7:4d:5a:62:4d:8f:6a:cd:0e:27:c3:0c:4a:ba:\n"
- " 68:8c:ff:e5:b9:21:a1:60:a3:d6:7b:2c:5c:09:3d:\n"
- " 46:ec:4d:c9:b3:09:72:2a:ce:9b:65:f9:56:5e:6e:\n"
- " 2e:24:64:4a:29:7f:17:1d:92:1d:bd:6e:d7:ce:73:\n"
- " cf:57:23:00:1d:db:bc:77:d4:fe:b1:ea:40:34:5c:\n"
- " 01:94:ee:c5:6a:5e:ce:63:d2:61:c9:55:ca:13:93:\n"
- " e8:be:0f:00:0a:f5:6c:fc:31:e3:08:05:a4:9a:b2:\n"
- " 8e:85:b5:0d:fd:fd:6f:d9:10:e4:68:8a:1b:81:27:\n"
- " da:14:c6:08:5a:bd:f1:ec:c6:41:ac:05:d7:cc:63:\n"
- " 4e:e8:e0:18:7e:f3:ed:4b:60:81:dd:07:fe:5d:ad:\n"
- " 9a:7c:80:99:6b:06:0f:ae:f6:7d:27:27:a0:3d:05:\n"
- " c6:cb:dd\n"
+ " 00:ce:a3:70:e2:c4:fb:4b:97:90:a1:30:bb:c1:1b:\n"
+ " 13:b9:aa:7e:46:17:a3:26:8d:69:3f:5e:73:95:e8:\n"
+ " 6a:b1:0a:b4:8f:50:65:e3:c6:5c:39:24:34:df:0b:\n"
+ " b7:cc:ce:62:0c:36:5a:12:2c:fe:35:4c:e9:1c:ac:\n"
+ " 80:5e:24:99:d7:aa:bd:be:48:c0:62:64:77:36:88:\n"
+ " 66:ce:f4:a8:dd:d2:76:24:62:90:55:41:fc:1d:13:\n"
+ " 4e:a7:4e:57:bc:a8:a4:59:4b:2c:5a:1c:d8:cc:16:\n"
+ " de:e8:88:30:c9:95:df:2f:a6:14:28:0f:eb:34:46:\n"
+ " 12:58:ba:da:0e:e6:de:9c:15:f6:f4:e3:9f:74:aa:\n"
+ " 70:89:79:8b:e9:5a:7b:18:54:15:94:3a:23:0a:65:\n"
+ " 78:05:d9:33:90:2a:ce:15:18:0d:52:fc:5c:31:65:\n"
+ " 20:d0:12:37:8c:11:80:ba:d4:b0:82:73:00:4b:49:\n"
+ " be:cb:d6:bc:e7:cd:61:f3:00:98:99:74:5a:37:81:\n"
+ " 49:96:7e:14:01:1b:86:d2:d0:06:94:40:63:63:46:\n"
+ " 11:fc:33:5c:bd:3a:5e:d4:e5:44:47:64:50:bd:a6:\n"
+ " 97:55:70:64:9b:26:cc:de:20:82:90:6a:83:41:9c:\n"
+ " 6f:71:47:14:be:cb:68:7c:85:be:ef:2e:76:12:19:\n"
+ " d3:c9:87:32:b4:ac:60:20:16:28:2d:af:bc:e8:01:\n"
+ " c6:7f:fb:d8:11:d5:f4:b7:14:bd:27:08:5b:72:be:\n"
+ " 09:e0:91:c8:9c:7b:b4:b3:12:ef:32:36:be:b1:b9:\n"
+ " a2:b7:e3:69:47:30:76:ba:9c:9b:19:99:4d:53:dd:\n"
+ " 5c:e8:2c:f1:b2:64:69:cf:15:bd:f8:bb:58:95:73:\n"
+ " 58:38:95:b4:7a:cf:84:29:a6:c2:db:f0:bd:ef:97:\n"
+ " 26:d4:99:ac:d7:c7:be:b0:0d:11:f4:26:86:2d:77:\n"
+ " 42:52:25:d7:56:c7:e3:97:b1:36:5c:97:71:d0:9b:\n"
+ " f5:b5:50:8d:f9:ff:fb:10:77:3c:b5:53:6d:a1:43:\n"
+ " 35:a9:03:32:05:ab:d7:f5:d1:19:bd:5f:92:a3:00:\n"
+ " 2a:79:37:a4:76:4f:e9:32:0d:e4:86:bb:ea:c3:1a:\n"
+ " c5:33:e8:16:d4:a5:d8:e0:e8:bb:c2:f0:22:15:e2:\n"
+ " d9:8c:ae:ac:7d:2b:bf:eb:a3:4c:3b:29:1d:94:ac:\n"
+ " a3:bb:6d:ba:6d:03:91:03:cf:46:12:c4:66:21:c5:\n"
+ " c6:67:d8:11:19:79:01:0e:6e:84:1c:76:6f:11:3d:\n"
+ " eb:94:89:c5:6a:26:1f:cd:e0:11:8b:51:ee:99:35:\n"
+ " 69:e5:7f:0b:77:2a:94:e4:4b:64:b9:83:04:30:05:\n"
+ " e4:a2:e3\n"
" Exponent: 65537 (0x10001)\n"
" X509v3 extensions:\n"
" X509v3 Subject Key Identifier: \n"
- " CC:57:77:7A:16:10:AE:94:99:A1:9F:AB:2F:79:42:74:D7:BE:8E:63\n"
+ " 83:21:DE:EC:C0:79:03:6D:1E:83:F3:E5:97:29:D5:5A:C0:96:40:FA\n"
" X509v3 Authority Key Identifier: \n"
- " keyid:CC:4E:CF:A0:E2:60:4F:BE:F2:77:51:1D:6E:3E:C6:B6:5A:38:23:A8\n"
+ " keyid:8A:22:C6:9C:2E:11:F3:40:0C:CE:82:0C:22:59:FF:F8:7F:D0:B9:13\n"
"\n"
" X509v3 Basic Constraints: critical\n"
" CA:TRUE, pathlen:0\n"
" X509v3 Key Usage: critical\n"
" Digital Signature, Certificate Sign, CRL Sign\n"
" Signature Algorithm: sha256WithRSAEncryption\n"
- " 41:78:c6:7d:0f:1f:0e:82:c8:7e:3a:56:7d:f7:a6:5e:c3:dc:\n"
- " 88:9e:e5:77:7d:c5:3c:70:2f:8a:cf:93:59:92:8f:17:04:5b:\n"
- " d7:d5:58:d9:cc:d6:df:77:0b:5f:db:ea:54:b6:3b:ec:d6:c4:\n"
- " 26:4f:63:54:06:ae:bc:5f:c3:b5:00:52:6f:2a:f6:c0:84:0b:\n"
- " 3e:fd:fe:82:87:82:40:5f:f7:08:5b:17:42:5e:46:60:66:77:\n"
- " 8f:04:2d:c0:7a:50:c2:58:42:10:fc:99:f8:30:3a:c6:ba:fa:\n"
- " 13:a5:ee:19:f8:4c:c8:72:37:64:16:16:ef:7e:a1:cb:df:af:\n"
- " 26:c5:ff:88:46:30:04:80:4c:cd:1a:56:f6:7a:4a:7b:c2:5e:\n"
- " 58:3b:ec:84:30:92:9c:7c:83:39:59:7f:57:f2:e7:1a:2c:ed:\n"
- " d9:e4:8a:1f:7e:ce:92:25:d9:78:c5:1b:f4:c6:31:10:79:3d:\n"
- " 8b:1d:e9:50:6d:87:2d:01:55:e0:59:c1:45:cd:ad:de:68:00:\n"
- " 91:9b:2a:9d:f5:aa:56:8d:48:9a:bf:aa:46:57:90:ba:4b:5d:\n"
- " 70:cf:1b:b2:9d:5d:21:8d:5d:b5:9e:35:96:e5:34:2b:37:52:\n"
- " ec:f7:03:9e:ca:e4:80:dd:1c:e3:89:e4:cd:67:5e:45:5e:88:\n"
- " 3b:2c:28:19:f2:ae:d2:51:7d:9b:12:5a:74:64:ea:41:b4:98:\n"
- " 6c:85:87:58:45:01:29:c3:0f:e7:1a:76:72:0f:d1:2a:c8:62:\n"
- " b6:2d:67:42:3c:0b:bf:1d:2a:ab:85:19:aa:7c:42:b3:0f:c1:\n"
- " 9f:1b:b7:b5:ff:19:cb:2e:d8:98:b7:99:35:a3:34:ba:31:0a:\n"
- " ba:59:fd:fe:72:53:3d:19:a7:36:4f:e1:a5:51:dd:ff:9f:6d:\n"
- " a1:22:64:01:dc:f4:8a:19:d3:5a:95:b6:a0:59:f8:28:f8:a1:\n"
- " bc:50:41:f5:f7:1a:42:e2:a1:aa:cc:44:36:64:ba:eb:b0:06:\n"
- " 05:58:2c:92:57:cd:8f:6a:ac:04:ba:4f:4d:71:4b:d4:c4:0d:\n"
- " 13:a2:75:de:48:c7:af:ef:1a:0d:d1:ac:94:53:68:c4:b8:2b:\n"
- " 88:4f:9d:78:b0:9b:a7:c4:a6:57:ad:3d:f5:1e:b4:fe:1d:d7:\n"
- " 42:6c:c4:c5:f6:8c:29:5c:92:3a:7d:79:f2:0d:01:ff:3c:29:\n"
- " 01:b9:91:59:7a:ea:e3:59:bd:67:28:3b:46:60:2c:e4:fd:61:\n"
- " 49:8d:3d:7f:ce:c2:d7:1d:2f:da:74:2f:38:e6:b2:f0:1f:5f:\n"
- " 43:dc:43:6c:e2:e3:c8:25:e6:6e:72:6b:90:50:f8:5c:9a:98:\n"
- " 20:0e:04:e2:b3:59:c9:3a\n"
+ " a3:6c:85:9a:2e:4e:7e:5d:83:63:0f:f5:4f:a9:7d:ec:0e:6f:\n"
+ " ae:d7:ba:df:64:e0:46:0e:3d:da:18:15:2c:f3:73:ca:81:b1:\n"
+ " 10:d9:53:14:21:7d:72:5c:94:88:a5:9d:ad:ab:45:42:c6:64:\n"
+ " a9:d9:2e:4e:29:47:2c:b1:95:07:b7:62:48:68:1f:68:13:1c:\n"
+ " d2:a0:fb:5e:38:24:4a:82:0a:87:c9:93:20:43:7e:e9:f9:79:\n"
+ " ef:03:a2:bd:9e:24:6b:0a:01:5e:4a:36:c5:7d:7a:fe:d6:aa:\n"
+ " 2f:c2:8c:38:8a:99:3c:b0:6a:e5:60:be:56:d6:eb:60:03:55:\n"
+ " 24:42:a0:1a:fa:91:24:a3:53:15:75:5d:c8:eb:7c:1e:68:5a:\n"
+ " 7e:13:34:e3:85:37:1c:76:3f:77:67:1b:ed:1b:52:17:fc:4a:\n"
+ " a3:e2:74:84:80:2c:69:fc:dd:7d:26:97:c4:2a:69:7d:9c:dc:\n"
+ " 61:97:70:29:a7:3f:2b:5b:2b:22:51:fd:fe:6a:5d:f9:e7:14:\n"
+ " 48:b7:2d:c8:33:58:fc:f2:5f:27:f7:26:16:be:be:b5:aa:a2:\n"
+ " 64:53:3c:69:e8:b5:61:eb:ab:91:a5:b4:09:9b:f6:98:b8:5c:\n"
+ " 5b:24:2f:93:f5:2b:9c:8c:58:fb:26:3f:67:53:d7:42:64:e8:\n"
+ " 79:77:73:41:4e:e3:02:39:0b:b6:68:97:8b:84:e8:1d:83:a8:\n"
+ " 15:f1:06:46:47:80:42:5e:14:e2:61:8a:76:84:d5:d4:71:7f:\n"
+ " 4e:ff:d9:74:87:ff:32:c5:87:20:0a:d4:59:40:3e:d8:17:ef:\n"
+ " da:65:e9:0a:51:fe:1e:c3:46:91:d2:ee:e4:23:57:97:87:d4:\n"
+ " a6:a5:eb:ef:81:6a:d8:8c:d6:1f:8e:b1:18:4c:6b:89:32:55:\n"
+ " 53:68:26:9e:bb:03:be:2c:e9:8b:ff:97:9c:1c:ac:28:c3:9f:\n"
+ " 0b:b7:93:23:24:31:63:e4:19:13:f2:bb:08:71:b7:c5:c5:c4:\n"
+ " 10:ff:dc:fc:33:54:a4:5e:ec:a3:fe:0a:80:ca:9c:bc:95:6f:\n"
+ " 5f:39:91:3b:61:69:16:94:0f:57:4b:fc:4b:b1:be:72:98:5d:\n"
+ " 10:f9:08:a7:d6:e0:e8:3d:5d:54:7d:fa:4b:6a:dd:98:41:ed:\n"
+ " 84:a1:39:67:5c:6c:7f:0c:b0:e1:98:c1:14:ed:fe:1e:e8:05:\n"
+ " 8d:7f:6a:24:cb:1b:05:42:0d:7f:13:ba:ca:b5:91:db:a5:f0:\n"
+ " 40:2b:70:7a:2a:a5:5d:ed:56:0c:f0:c2:72:ee:63:dd:cb:5d:\n"
+ " 76:f6:08:e6:e6:30:ef:3a:b2:16:34:41:a4:e1:30:14:bc:c7:\n"
+ " f9:23:3a:1a:70:df:b8:cc\n"
"-----BEGIN CERTIFICATE-----\n"
"MIIGSDCCBDCgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgboxCzAJBgNVBAYTAlVT\n"
"MRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMRMw\n"
"EQYDVQQKDApMaW5kZW4gTGFiMSAwHgYDVQQLDBdTZWNvbmQgTGlmZSBFbmdpbmVl\n"
"cmluZzEhMB8GA1UEAwwYSW50ZWdyYXRpb24gVGVzdCBSb290IENBMSQwIgYJKoZI\n"
- "hvcNAQkBFhVub3JlcGx5QGxpbmRlbmxhYi5jb20wHhcNMTcwNDEwMjAyNDUyWhcN\n"
- "MjcwNDA4MjAyNDUyWjCBqjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3Ju\n"
+ "hvcNAQkBFhVub3JlcGx5QGxpbmRlbmxhYi5jb20wHhcNMTgwNTIyMjIzOTA4WhcN\n"
+ "MjgwNTE5MjIzOTA4WjCBqjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3Ju\n"
"aWExEzARBgNVBAoMCkxpbmRlbiBMYWIxIDAeBgNVBAsMF1NlY29uZCBMaWZlIEVu\n"
"Z2luZWVyaW5nMSkwJwYDVQQDDCBJbnRlZ3JhdGlvbiBUZXN0IEludGVybWVkaWF0\n"
"ZSBDQTEkMCIGCSqGSIb3DQEJARYVbm9yZXBseUBsaW5kZW5sYWIuY29tMIICIjAN\n"
- "BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtJspxiLE3nhx7S0NkDL82ueMUVHS\n"
- "/uzkylzIXuDCl1C3wr0ikTVL/bSsICGwWRVJQP+RnpQikVlo9O2EgY2+FWcCjr9t\n"
- "hjl+Qjrqcp7KW+8elmy8MGXBc/aHkh8k9/s5d7FJaydcIbr2+R3VbcxYjm3Ra/7s\n"
- "iTQ0gNkDJ9VvvH/Hs4xjTTQ3YdD5VC4qqIUDBCK3GVujV+RDoYg8QgTIw/vvDHja\n"
- "dozhJ5CxtOLF87B8DJU+ze3u+CgowLpk6bUKQvOPsd3MQVin56GwLI5YVT6M19vy\n"
- "UTiWT64djq7jhxpsj2s7WhqpSbxpeZ8ob+KsCEBS2YfJ8ifX+2KFX38JqWQHe3oO\n"
- "uqVYGCOqst9md/Zq7vd5GDASss9gea+G1bjb7qATL4DhaQ1nFOWamUwQLbEmbLg8\n"
- "EC+O28tKnp5Qoph2SXsmwY+/UADzrwaYCq94A4RdVkHgkHyap01aYk2Pas0OJ8MM\n"
- "SrpojP/luSGhYKPWeyxcCT1G7E3JswlyKs6bZflWXm4uJGRKKX8XHZIdvW7XznPP\n"
- "VyMAHdu8d9T+sepANFwBlO7Fal7OY9JhyVXKE5Povg8ACvVs/DHjCAWkmrKOhbUN\n"
- "/f1v2RDkaIobgSfaFMYIWr3x7MZBrAXXzGNO6OAYfvPtS2CB3Qf+Xa2afICZawYP\n"
- "rvZ9JyegPQXGy90CAwEAAaNmMGQwHQYDVR0OBBYEFMxXd3oWEK6UmaGfqy95QnTX\n"
- "vo5jMB8GA1UdIwQYMBaAFMxOz6DiYE++8ndRHW4+xrZaOCOoMBIGA1UdEwEB/wQI\n"
- "MAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBBeMZ9\n"
- "Dx8Ogsh+OlZ996Zew9yInuV3fcU8cC+Kz5NZko8XBFvX1VjZzNbfdwtf2+pUtjvs\n"
- "1sQmT2NUBq68X8O1AFJvKvbAhAs+/f6Ch4JAX/cIWxdCXkZgZnePBC3AelDCWEIQ\n"
- "/Jn4MDrGuvoTpe4Z+EzIcjdkFhbvfqHL368mxf+IRjAEgEzNGlb2ekp7wl5YO+yE\n"
- "MJKcfIM5WX9X8ucaLO3Z5Ioffs6SJdl4xRv0xjEQeT2LHelQbYctAVXgWcFFza3e\n"
- "aACRmyqd9apWjUiav6pGV5C6S11wzxuynV0hjV21njWW5TQrN1Ls9wOeyuSA3Rzj\n"
- "ieTNZ15FXog7LCgZ8q7SUX2bElp0ZOpBtJhshYdYRQEpww/nGnZyD9EqyGK2LWdC\n"
- "PAu/HSqrhRmqfEKzD8GfG7e1/xnLLtiYt5k1ozS6MQq6Wf3+clM9Gac2T+GlUd3/\n"
- "n22hImQB3PSKGdNalbagWfgo+KG8UEH19xpC4qGqzEQ2ZLrrsAYFWCySV82PaqwE\n"
- "uk9NcUvUxA0TonXeSMev7xoN0ayUU2jEuCuIT514sJunxKZXrT31HrT+HddCbMTF\n"
- "9owpXJI6fXnyDQH/PCkBuZFZeurjWb1nKDtGYCzk/WFJjT1/zsLXHS/adC845rLw\n"
- "H19D3ENs4uPIJeZucmuQUPhcmpggDgTis1nJOg==\n"
+ "BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAzqNw4sT7S5eQoTC7wRsTuap+Rhej\n"
+ "Jo1pP15zlehqsQq0j1Bl48ZcOSQ03wu3zM5iDDZaEiz+NUzpHKyAXiSZ16q9vkjA\n"
+ "YmR3NohmzvSo3dJ2JGKQVUH8HRNOp05XvKikWUssWhzYzBbe6IgwyZXfL6YUKA/r\n"
+ "NEYSWLraDubenBX29OOfdKpwiXmL6Vp7GFQVlDojCmV4BdkzkCrOFRgNUvxcMWUg\n"
+ "0BI3jBGAutSwgnMAS0m+y9a8581h8wCYmXRaN4FJln4UARuG0tAGlEBjY0YR/DNc\n"
+ "vTpe1OVER2RQvaaXVXBkmybM3iCCkGqDQZxvcUcUvstofIW+7y52EhnTyYcytKxg\n"
+ "IBYoLa+86AHGf/vYEdX0txS9Jwhbcr4J4JHInHu0sxLvMja+sbmit+NpRzB2upyb\n"
+ "GZlNU91c6CzxsmRpzxW9+LtYlXNYOJW0es+EKabC2/C975cm1Jms18e+sA0R9CaG\n"
+ "LXdCUiXXVsfjl7E2XJdx0Jv1tVCN+f/7EHc8tVNtoUM1qQMyBavX9dEZvV+SowAq\n"
+ "eTekdk/pMg3khrvqwxrFM+gW1KXY4Oi7wvAiFeLZjK6sfSu/66NMOykdlKyju226\n"
+ "bQORA89GEsRmIcXGZ9gRGXkBDm6EHHZvET3rlInFaiYfzeARi1HumTVp5X8LdyqU\n"
+ "5EtkuYMEMAXkouMCAwEAAaNmMGQwHQYDVR0OBBYEFIMh3uzAeQNtHoPz5Zcp1VrA\n"
+ "lkD6MB8GA1UdIwQYMBaAFIoixpwuEfNADM6CDCJZ//h/0LkTMBIGA1UdEwEB/wQI\n"
+ "MAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQCjbIWa\n"
+ "Lk5+XYNjD/VPqX3sDm+u17rfZOBGDj3aGBUs83PKgbEQ2VMUIX1yXJSIpZ2tq0VC\n"
+ "xmSp2S5OKUcssZUHt2JIaB9oExzSoPteOCRKggqHyZMgQ37p+XnvA6K9niRrCgFe\n"
+ "SjbFfXr+1qovwow4ipk8sGrlYL5W1utgA1UkQqAa+pEko1MVdV3I63weaFp+EzTj\n"
+ "hTccdj93ZxvtG1IX/Eqj4nSEgCxp/N19JpfEKml9nNxhl3Appz8rWysiUf3+al35\n"
+ "5xRIty3IM1j88l8n9yYWvr61qqJkUzxp6LVh66uRpbQJm/aYuFxbJC+T9SucjFj7\n"
+ "Jj9nU9dCZOh5d3NBTuMCOQu2aJeLhOgdg6gV8QZGR4BCXhTiYYp2hNXUcX9O/9l0\n"
+ "h/8yxYcgCtRZQD7YF+/aZekKUf4ew0aR0u7kI1eXh9SmpevvgWrYjNYfjrEYTGuJ\n"
+ "MlVTaCaeuwO+LOmL/5ecHKwow58Lt5MjJDFj5BkT8rsIcbfFxcQQ/9z8M1SkXuyj\n"
+ "/gqAypy8lW9fOZE7YWkWlA9XS/xLsb5ymF0Q+Qin1uDoPV1UffpLat2YQe2EoTln\n"
+ "XGx/DLDhmMEU7f4e6AWNf2okyxsFQg1/E7rKtZHbpfBAK3B6KqVd7VYM8MJy7mPd\n"
+ "y1129gjm5jDvOrIWNEGk4TAUvMf5IzoacN+4zA==\n"
"-----END CERTIFICATE-----\n"
);
@@ -477,31 +483,31 @@ namespace tut
" Signature Algorithm: sha256WithRSAEncryption\n"
" Issuer: C=US, ST=California, O=Linden Lab, OU=Second Life Engineering, CN=Integration Test Intermediate CA/emailAddress=noreply@lindenlab.com\n"
" Validity\n"
- " Not Before: Apr 10 21:35:07 2017 GMT\n"
- " Not After : Apr 20 21:35:07 2018 GMT\n"
+ " Not Before: May 22 22:58:15 2018 GMT\n"
+ " Not After : Jul 19 22:58:15 2024 GMT\n"
" Subject: C=US, ST=California, L=San Francisco, O=Linden Lab, OU=Second Life Engineering, CN=Integration Test Server Cert/emailAddress=noreply@lindenlab.com\n"
" Subject Public Key Info:\n"
" Public Key Algorithm: rsaEncryption\n"
" Public-Key: (2048 bit)\n"
" Modulus:\n"
- " 00:ba:51:fb:01:57:44:2f:99:03:36:82:c0:6a:d2:\n"
- " 17:1d:f9:e1:49:71:b1:d1:61:c4:90:61:40:99:aa:\n"
- " 8e:78:99:40:c8:b7:f5:bd:78:a5:7a:c8:fb:73:33:\n"
- " 74:c0:78:ee:2d:55:08:78:6c:e4:e0:87:4a:34:df:\n"
- " 6a:25:f7:8c:86:87:0e:f6:df:00:a7:42:4f:89:e3:\n"
- " b1:c0:db:2a:9d:96:2b:6f:47:66:04:9b:e8:f0:18:\n"
- " ce:7b:4b:bf:8b:6e:24:7e:df:89:07:b4:f5:69:1d:\n"
- " 4e:9d:9d:c1:6b:19:51:60:56:3e:4a:b8:c2:c0:9d:\n"
- " 67:fb:fe:d7:73:fa:61:38:85:9b:b0:5f:80:db:a1:\n"
- " 57:5e:9f:90:af:7d:33:31:7d:bd:73:0b:a2:d5:1e:\n"
- " ff:10:a5:6d:fb:c7:55:e6:a0:81:21:f5:d7:23:e5:\n"
- " 9c:c1:f2:29:8a:aa:83:9f:75:9f:84:fc:65:4c:29:\n"
- " b3:98:1f:a6:05:0b:1a:a8:0d:68:2e:20:47:2d:06:\n"
- " 46:de:92:3d:eb:02:a3:b2:9f:65:66:44:7c:b0:da:\n"
- " 55:77:f5:5a:9f:c0:58:b6:ff:7d:31:41:72:cc:bd:\n"
- " 7a:1d:58:36:a8:f2:ca:6a:ca:6b:03:29:ac:94:ad:\n"
- " 93:f4:7a:14:52:b3:ce:61:e1:7e:6c:8f:08:ad:a9:\n"
- " 5d:37\n"
+ " 00:bf:a1:1c:76:82:4a:10:1d:25:0e:02:e2:7a:64:\n"
+ " 54:c7:94:c5:c0:98:d5:35:f3:cb:cb:30:ba:31:9c:\n"
+ " bd:4c:2f:4a:4e:24:03:4b:87:5c:c1:5c:fe:d9:89:\n"
+ " 3b:cb:01:bc:eb:a5:b7:78:dc:b3:58:e5:78:a7:15:\n"
+ " 34:50:30:aa:16:3a:b2:94:17:6d:1e:7f:b2:70:1e:\n"
+ " 96:41:bb:1d:e3:22:80:fa:dc:00:6a:fb:34:3e:67:\n"
+ " e7:c2:21:2f:1b:d3:af:04:49:91:eb:bb:60:e0:26:\n"
+ " 52:75:28:8a:08:5b:91:56:4e:51:50:40:51:70:af:\n"
+ " cb:80:66:c8:59:e9:e2:48:a8:62:d0:26:67:80:0a:\n"
+ " 12:16:d1:f6:15:9e:1f:f5:92:37:f3:c9:2f:03:9e:\n"
+ " 22:f6:60:5a:76:45:8c:01:2c:99:54:72:19:db:b7:\n"
+ " 72:e6:5a:69:f3:e9:31:65:5d:0f:c7:5c:9c:17:29:\n"
+ " 71:14:7f:db:47:c9:1e:65:a2:41:b0:2f:14:17:ec:\n"
+ " 4b:25:f2:43:8f:b4:a3:8d:37:1a:07:34:b3:29:bb:\n"
+ " 8a:44:8e:84:08:a2:1b:76:7a:cb:c2:39:2f:6e:e3:\n"
+ " fc:d6:91:b5:1f:ce:58:91:57:70:35:6e:25:a9:48:\n"
+ " 0e:07:cf:4e:dd:16:42:65:cf:8a:42:b3:27:e6:fe:\n"
+ " 6a:e3\n"
" Exponent: 65537 (0x10001)\n"
" X509v3 extensions:\n"
" X509v3 Basic Constraints: \n"
@@ -511,9 +517,9 @@ namespace tut
" Netscape Comment: \n"
" OpenSSL Generated Server Certificate\n"
" X509v3 Subject Key Identifier: \n"
- " 6B:69:AA:91:99:C8:8C:01:72:58:D3:1F:F8:29:73:9C:98:F7:3F:5F\n"
+ " BB:59:9F:DE:6B:51:A7:6C:B3:6D:5B:8B:42:F7:B1:65:77:17:A4:E4\n"
" X509v3 Authority Key Identifier: \n"
- " keyid:CC:57:77:7A:16:10:AE:94:99:A1:9F:AB:2F:79:42:74:D7:BE:8E:63\n"
+ " keyid:83:21:DE:EC:C0:79:03:6D:1E:83:F3:E5:97:29:D5:5A:C0:96:40:FA\n"
" DirName:/C=US/ST=California/L=San Francisco/O=Linden Lab/OU=Second Life Engineering/CN=Integration Test Root CA/emailAddress=noreply@lindenlab.com\n"
" serial:10:00\n"
"\n"
@@ -522,71 +528,71 @@ namespace tut
" X509v3 Extended Key Usage: \n"
" TLS Web Server Authentication\n"
" Signature Algorithm: sha256WithRSAEncryption\n"
- " ac:35:1a:96:65:28:7c:ed:c5:e3:b9:ef:52:9e:66:b8:63:2e:\n"
- " de:73:97:3c:91:d5:02:a3:62:9e:c6:5f:f7:18:ed:7f:f8:a1:\n"
- " 66:d2:bc:12:fd:90:b8:fb:ef:ce:fe:e4:21:5e:b9:d1:c9:65:\n"
- " 13:4b:d0:e5:d0:9a:9b:f3:d6:79:bd:9b:af:25:93:01:32:5c:\n"
- " 14:48:03:c1:f7:c6:19:80:d4:1b:f7:e3:82:59:0c:50:0d:85:\n"
- " 97:64:e5:4e:2f:5e:cb:b6:dc:a0:44:64:32:ba:57:ee:45:26:\n"
- " 58:c2:36:71:a8:90:3a:37:48:33:75:79:8e:4f:b1:2d:65:6e:\n"
- " 04:9f:35:28:40:97:f3:80:c1:c8:bb:b9:cd:a2:aa:42:a9:9a:\n"
- " c6:ab:ac:48:a4:eb:0a:17:19:a0:44:9d:8a:7f:b1:21:a1:14:\n"
- " ac:0f:71:e0:e8:28:07:44:8a:e7:70:c9:af:19:08:8f:be:2c:\n"
- " 79:af:62:af:9f:8e:d8:4a:c5:09:d5:27:1a:29:c3:2a:f1:b9:\n"
- " a2:df:0b:e4:22:22:4e:26:11:ad:3d:39:4c:e6:53:49:d5:65:\n"
- " 8c:e8:68:98:91:50:40:ff:fd:ac:ef:71:12:28:a8:b3:5f:f7:\n"
- " b3:26:2e:eb:f4:d0:d4:68:31:ee:4a:78:b3:85:60:37:1b:21:\n"
- " 2d:e9:f2:67:5a:64:17:e5:30:fc:2d:ed:59:a0:06:8d:90:ea:\n"
- " ba:26:2f:d8:ac:68:98:db:42:87:39:65:64:b6:08:9f:70:dc:\n"
- " 74:8d:ac:26:ce:8e:a7:dc:1d:41:de:82:7c:00:46:d0:23:74:\n"
- " b5:5a:4c:91:e4:92:11:a4:13:fd:50:05:86:89:c4:fd:11:ce:\n"
- " 17:44:8f:35:ea:c8:4e:8c:a5:e1:ed:62:32:ff:2f:f7:92:f3:\n"
- " f7:5c:d2:e7:27:d8:ff:f7:92:7d:dc:a6:ca:d9:e0:92:9d:db:\n"
- " 34:9e:6e:c8:f4:f1:d0:d8:30:c2:85:87:c5:f6:ed:0b:d4:b1:\n"
- " a6:7c:c1:cd:55:41:c0:e4:cf:06:62:31:fd:4e:b1:eb:45:71:\n"
- " 5b:7c:42:02:4c:ee:74:27:8a:81:11:f1:32:89:40:c9:85:03:\n"
- " bb:e8:73:55:53:f0:73:eb:47:68:4c:34:9a:1d:7d:cb:54:50:\n"
- " 59:c7:82:3e:42:5c:81:51:7a:01:71:86:a1:b0:da:e6:09:3a:\n"
- " 29:ee:e9:9e:58:19:d7:81:69:bd:3c:5a:02:49:6f:3c:03:0e:\n"
- " 4a:79:06:50:40:8a:60:11:35:6b:56:fc:34:46:52:68:ca:d3:\n"
- " 3a:c1:85:bc:e4:25:57:70:b4:ab:36:d8:8b:0a:6b:8d:7b:b7:\n"
- " 88:7d:10:33:6e:be:83:e6\n"
+ " 18:a6:58:55:9b:d4:af:7d:8a:27:d3:28:3a:4c:4b:42:4e:f0:\n"
+ " 30:d6:d9:95:11:48:12:0a:96:40:d9:2b:21:39:c5:d4:8d:e5:\n"
+ " 10:bc:68:78:69:0b:9f:15:4a:0b:f1:ab:99:45:0c:20:5f:27:\n"
+ " df:e7:14:2d:4a:30:f2:c2:8d:37:73:36:1a:27:55:5a:08:5f:\n"
+ " 71:a1:5e:05:83:b2:59:fe:02:5e:d7:4a:30:15:23:58:04:cf:\n"
+ " 48:cc:b0:71:88:9c:6b:57:f0:04:0a:d3:a0:64:6b:ee:f3:5f:\n"
+ " ea:ac:e1:2b:b9:7f:79:b8:db:ce:72:48:72:db:c8:5c:38:72:\n"
+ " 31:55:d0:ff:6b:bd:73:23:a7:30:18:5d:ed:47:18:0a:67:8e:\n"
+ " 53:32:0e:99:9b:96:72:45:7f:c6:00:2c:5d:1a:97:53:75:3a:\n"
+ " 0b:49:3d:3a:00:37:14:67:0c:28:97:34:87:aa:c5:32:e4:ae:\n"
+ " 34:83:12:4a:10:f7:0e:74:d4:5f:73:bd:ef:0c:b7:d8:0a:7d:\n"
+ " 8e:8d:5a:48:bd:f4:8e:7b:f9:4a:15:3b:61:c9:5e:40:59:6e:\n"
+ " c7:a8:a4:02:28:72:c5:54:8c:77:f4:55:a7:86:c0:38:a0:68:\n"
+ " 19:da:0f:72:5a:a9:7e:69:9f:9c:3a:d6:66:aa:e1:f4:fd:f9:\n"
+ " b8:4b:6c:71:9e:f0:38:02:c7:6a:9e:dc:e6:fb:ef:23:59:4f:\n"
+ " 5c:84:0a:df:ea:86:1f:fd:0e:5c:fa:c4:e5:50:1c:10:cf:89:\n"
+ " 4e:08:0e:4c:4b:61:1a:49:12:f7:e9:4b:17:71:43:7b:6d:b6:\n"
+ " b5:9f:d4:3b:c7:88:53:48:63:b6:00:80:8f:49:0a:c5:7e:58:\n"
+ " ac:78:d8:b9:06:b0:bc:86:e2:2e:48:5b:c3:24:fa:aa:72:d8:\n"
+ " ec:f6:c7:91:9f:0f:c8:b5:fd:2b:b2:a7:bc:2f:40:20:2b:47:\n"
+ " e0:d1:1d:94:52:6f:6b:be:12:b6:8c:dc:11:db:71:e6:19:ef:\n"
+ " a8:71:8b:ad:d3:32:c0:1c:a4:3f:b3:0f:af:e5:50:e1:ff:41:\n"
+ " a4:b7:6f:57:71:af:fd:16:4c:e8:24:b3:99:1b:cf:12:8f:43:\n"
+ " 05:80:ba:18:19:0a:a5:ec:49:81:41:4c:7e:28:b2:21:f2:59:\n"
+ " 6e:4a:ed:de:f9:fa:99:85:60:1f:e6:c2:42:5c:08:00:3c:84:\n"
+ " 06:a9:24:d4:cf:7b:6e:1b:59:1d:f4:70:16:03:a1:e0:0b:00:\n"
+ " 95:5c:39:03:fc:9d:1c:8e:f7:59:0c:61:47:f6:7f:07:22:48:\n"
+ " 83:40:ac:e1:98:5f:c7:be:05:d5:29:2b:bf:0d:03:0e:e9:5e:\n"
+ " 2b:dd:09:18:fe:5e:30:61\n"
"-----BEGIN CERTIFICATE-----\n"
"MIIGbjCCBFagAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgaoxCzAJBgNVBAYTAlVT\n"
"MRMwEQYDVQQIDApDYWxpZm9ybmlhMRMwEQYDVQQKDApMaW5kZW4gTGFiMSAwHgYD\n"
"VQQLDBdTZWNvbmQgTGlmZSBFbmdpbmVlcmluZzEpMCcGA1UEAwwgSW50ZWdyYXRp\n"
"b24gVGVzdCBJbnRlcm1lZGlhdGUgQ0ExJDAiBgkqhkiG9w0BCQEWFW5vcmVwbHlA\n"
- "bGluZGVubGFiLmNvbTAeFw0xNzA0MTAyMTM1MDdaFw0xODA0MjAyMTM1MDdaMIG+\n"
+ "bGluZGVubGFiLmNvbTAeFw0xODA1MjIyMjU4MTVaFw0yNDA3MTkyMjU4MTVaMIG+\n"
"MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2Fu\n"
"IEZyYW5jaXNjbzETMBEGA1UECgwKTGluZGVuIExhYjEgMB4GA1UECwwXU2Vjb25k\n"
"IExpZmUgRW5naW5lZXJpbmcxJTAjBgNVBAMMHEludGVncmF0aW9uIFRlc3QgU2Vy\n"
"dmVyIENlcnQxJDAiBgkqhkiG9w0BCQEWFW5vcmVwbHlAbGluZGVubGFiLmNvbTCC\n"
- "ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALpR+wFXRC+ZAzaCwGrSFx35\n"
- "4UlxsdFhxJBhQJmqjniZQMi39b14pXrI+3MzdMB47i1VCHhs5OCHSjTfaiX3jIaH\n"
- "DvbfAKdCT4njscDbKp2WK29HZgSb6PAYzntLv4tuJH7fiQe09WkdTp2dwWsZUWBW\n"
- "Pkq4wsCdZ/v+13P6YTiFm7BfgNuhV16fkK99MzF9vXMLotUe/xClbfvHVeaggSH1\n"
- "1yPlnMHyKYqqg591n4T8ZUwps5gfpgULGqgNaC4gRy0GRt6SPesCo7KfZWZEfLDa\n"
- "VXf1Wp/AWLb/fTFBcsy9eh1YNqjyymrKawMprJStk/R6FFKzzmHhfmyPCK2pXTcC\n"
+ "ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL+hHHaCShAdJQ4C4npkVMeU\n"
+ "xcCY1TXzy8swujGcvUwvSk4kA0uHXMFc/tmJO8sBvOult3jcs1jleKcVNFAwqhY6\n"
+ "spQXbR5/snAelkG7HeMigPrcAGr7ND5n58IhLxvTrwRJkeu7YOAmUnUoighbkVZO\n"
+ "UVBAUXCvy4BmyFnp4kioYtAmZ4AKEhbR9hWeH/WSN/PJLwOeIvZgWnZFjAEsmVRy\n"
+ "Gdu3cuZaafPpMWVdD8dcnBcpcRR/20fJHmWiQbAvFBfsSyXyQ4+0o403Ggc0sym7\n"
+ "ikSOhAiiG3Z6y8I5L27j/NaRtR/OWJFXcDVuJalIDgfPTt0WQmXPikKzJ+b+auMC\n"
"AwEAAaOCAYYwggGCMAkGA1UdEwQCMAAwEQYJYIZIAYb4QgEBBAQDAgZAMDMGCWCG\n"
"SAGG+EIBDQQmFiRPcGVuU1NMIEdlbmVyYXRlZCBTZXJ2ZXIgQ2VydGlmaWNhdGUw\n"
- "HQYDVR0OBBYEFGtpqpGZyIwBcljTH/gpc5yY9z9fMIHoBgNVHSMEgeAwgd2AFMxX\n"
- "d3oWEK6UmaGfqy95QnTXvo5joYHApIG9MIG6MQswCQYDVQQGEwJVUzETMBEGA1UE\n"
+ "HQYDVR0OBBYEFLtZn95rUadss21bi0L3sWV3F6TkMIHoBgNVHSMEgeAwgd2AFIMh\n"
+ "3uzAeQNtHoPz5Zcp1VrAlkD6oYHApIG9MIG6MQswCQYDVQQGEwJVUzETMBEGA1UE\n"
"CAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzETMBEGA1UECgwK\n"
"TGluZGVuIExhYjEgMB4GA1UECwwXU2Vjb25kIExpZmUgRW5naW5lZXJpbmcxITAf\n"
"BgNVBAMMGEludGVncmF0aW9uIFRlc3QgUm9vdCBDQTEkMCIGCSqGSIb3DQEJARYV\n"
"bm9yZXBseUBsaW5kZW5sYWIuY29tggIQADAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0l\n"
- "BAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggIBAKw1GpZlKHztxeO571Ke\n"
- "ZrhjLt5zlzyR1QKjYp7GX/cY7X/4oWbSvBL9kLj7787+5CFeudHJZRNL0OXQmpvz\n"
- "1nm9m68lkwEyXBRIA8H3xhmA1Bv344JZDFANhZdk5U4vXsu23KBEZDK6V+5FJljC\n"
- "NnGokDo3SDN1eY5PsS1lbgSfNShAl/OAwci7uc2iqkKpmsarrEik6woXGaBEnYp/\n"
- "sSGhFKwPceDoKAdEiudwya8ZCI++LHmvYq+fjthKxQnVJxopwyrxuaLfC+QiIk4m\n"
- "Ea09OUzmU0nVZYzoaJiRUED//azvcRIoqLNf97MmLuv00NRoMe5KeLOFYDcbIS3p\n"
- "8mdaZBflMPwt7VmgBo2Q6romL9isaJjbQoc5ZWS2CJ9w3HSNrCbOjqfcHUHegnwA\n"
- "RtAjdLVaTJHkkhGkE/1QBYaJxP0RzhdEjzXqyE6MpeHtYjL/L/eS8/dc0ucn2P/3\n"
- "kn3cpsrZ4JKd2zSebsj08dDYMMKFh8X27QvUsaZ8wc1VQcDkzwZiMf1OsetFcVt8\n"
- "QgJM7nQnioER8TKJQMmFA7voc1VT8HPrR2hMNJodfctUUFnHgj5CXIFRegFxhqGw\n"
- "2uYJOinu6Z5YGdeBab08WgJJbzwDDkp5BlBAimARNWtW/DRGUmjK0zrBhbzkJVdw\n"
- "tKs22IsKa417t4h9EDNuvoPm\n"
+ "BAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggIBABimWFWb1K99iifTKDpM\n"
+ "S0JO8DDW2ZURSBIKlkDZKyE5xdSN5RC8aHhpC58VSgvxq5lFDCBfJ9/nFC1KMPLC\n"
+ "jTdzNhonVVoIX3GhXgWDsln+Al7XSjAVI1gEz0jMsHGInGtX8AQK06Bka+7zX+qs\n"
+ "4Su5f3m4285ySHLbyFw4cjFV0P9rvXMjpzAYXe1HGApnjlMyDpmblnJFf8YALF0a\n"
+ "l1N1OgtJPToANxRnDCiXNIeqxTLkrjSDEkoQ9w501F9zve8Mt9gKfY6NWki99I57\n"
+ "+UoVO2HJXkBZbseopAIocsVUjHf0VaeGwDigaBnaD3JaqX5pn5w61maq4fT9+bhL\n"
+ "bHGe8DgCx2qe3Ob77yNZT1yECt/qhh/9Dlz6xOVQHBDPiU4IDkxLYRpJEvfpSxdx\n"
+ "Q3tttrWf1DvHiFNIY7YAgI9JCsV+WKx42LkGsLyG4i5IW8Mk+qpy2Oz2x5GfD8i1\n"
+ "/Suyp7wvQCArR+DRHZRSb2u+EraM3BHbceYZ76hxi63TMsAcpD+zD6/lUOH/QaS3\n"
+ "b1dxr/0WTOgks5kbzxKPQwWAuhgZCqXsSYFBTH4osiHyWW5K7d75+pmFYB/mwkJc\n"
+ "CAA8hAapJNTPe24bWR30cBYDoeALAJVcOQP8nRyO91kMYUf2fwciSINArOGYX8e+\n"
+ "BdUpK78NAw7pXivdCRj+XjBh\n"
"-----END CERTIFICATE-----\n"
);
@@ -704,8 +710,8 @@ namespace tut
(std::string)llsd_cert["subject_name_string"],
"emailAddress=noreply@lindenlab.com,CN=Integration Test Server Cert,OU=Second Life Engineering,O=Linden Lab,L=San Francisco,ST=California,C=US");
ensure_equals("serial number", (std::string)llsd_cert["serial_number"], "1000");
- ensure_equals("valid from", (std::string)llsd_cert["valid_from"], "2017-04-10T21:35:07Z");
- ensure_equals("valid to", (std::string)llsd_cert["valid_to"], "2018-04-20T21:35:07Z");
+ ensure_equals("valid from", (std::string)llsd_cert["valid_from"], "2018-05-22T22:58:15Z");
+ ensure_equals("valid to", (std::string)llsd_cert["valid_to"], "2024-07-19T22:58:15Z");
LLSD expectedKeyUsage = LLSD::emptyArray();
expectedKeyUsage.append(LLSD((std::string)"digitalSignature"));
expectedKeyUsage.append(LLSD((std::string)"keyEncipherment"));
@@ -1024,7 +1030,7 @@ namespace tut
//validate find
LLSD find_info = LLSD::emptyMap();
- find_info["subjectKeyIdentifier"] = "6b:69:aa:91:99:c8:8c:01:72:58:d3:1f:f8:29:73:9c:98:f7:3f:5f";
+ find_info["subjectKeyIdentifier"] = "bb:59:9f:de:6b:51:a7:6c:b3:6d:5b:8b:42:f7:b1:65:77:17:a4:e4";
LLBasicCertificateVector::iterator found_cert = test_vector->find(find_info);
ensure("found some cert", found_cert != test_vector->end());
X509* found_x509 = (*found_cert).get()->getOpenSSLX509();
diff --git a/indra/newview/tests/llslurl_test.cpp b/indra/newview/tests/llslurl_test.cpp
index 4694f657b6..eabf922875 100644
--- a/indra/newview/tests/llslurl_test.cpp
+++ b/indra/newview/tests/llslurl_test.cpp
@@ -46,10 +46,10 @@ static const char * const TEST_FILENAME("llslurl_test.xml");
class LLTrans
{
public:
- static std::string getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args);
+ static std::string getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args, bool def_string = false);
};
-std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args)
+std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args, bool def_string)
{
return std::string();
}
diff --git a/indra/newview/tests/llviewernetwork_test.cpp b/indra/newview/tests/llviewernetwork_test.cpp
index e68da14fe9..3dd327591e 100644
--- a/indra/newview/tests/llviewernetwork_test.cpp
+++ b/indra/newview/tests/llviewernetwork_test.cpp
@@ -45,10 +45,10 @@ static const char * const TEST_FILENAME("llviewernetwork_test.xml");
class LLTrans
{
public:
- static std::string getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args);
+ static std::string getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args, bool def_string = false);
};
-std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args)
+std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args, bool def_string)
{
std::string grid_label = std::string();
if(xml_desc == "AgniGridLabel")
diff --git a/indra/newview/tests/llworldmap_test.cpp b/indra/newview/tests/llworldmap_test.cpp
index 84194adb5d..f1dd8acccf 100644
--- a/indra/newview/tests/llworldmap_test.cpp
+++ b/indra/newview/tests/llworldmap_test.cpp
@@ -66,7 +66,7 @@ void LLWorldMipmap::equalizeBoostLevels() { }
LLPointer<LLViewerFetchedTexture> LLWorldMipmap::getObjectsTile(U32 grid_x, U32 grid_y, S32 level, bool load) { return NULL; }
// Stub other stuff
-std::string LLTrans::getString(const std::string &, const LLStringUtil::format_map_t& ) { return std::string("test_trans"); }
+std::string LLTrans::getString(const std::string &, const LLStringUtil::format_map_t&, bool def_string) { return std::string("test_trans"); }
void LLUIString::updateResult() const { }
void LLUIString::setArg(const std::string& , const std::string& ) { }
void LLUIString::assign(const std::string& ) { }
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index e823228681..541112a765 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -87,7 +87,6 @@ class ViewerManifest(LLManifest):
pkgdir = os.path.join(self.args['build'], os.pardir, 'packages')
with self.prefix(src=pkgdir,dst=""):
self.path("dictionaries")
- self.path("ca-bundle.crt")
# include the extracted packages information (see BuildPackagesInfo.cmake)
self.path(src=os.path.join(self.args['build'],"packages-info.txt"), dst="packages-info.txt")
@@ -593,7 +592,9 @@ class WindowsManifest(ViewerManifest):
self.path(src="licenses-win32.txt", dst="licenses.txt")
self.path("featuretable.txt")
- self.path("ca-bundle.crt")
+
+ with self.prefix(src=pkgdir,dst=""):
+ self.path("ca-bundle.crt")
# Media plugins - CEF
with self.prefix(src='../media_plugins/cef/%s' % self.args['configuration'], dst="llplugin"):
@@ -1050,7 +1051,9 @@ open "%s" --args "$@"
self.path("licenses-mac.txt", dst="licenses.txt")
self.path("featuretable_mac.txt")
self.path("SecondLife.nib")
- self.path("ca-bundle.crt")
+
+ with self.prefix(src=pkgdir,dst=""):
+ self.path("ca-bundle.crt")
self.path("SecondLife.nib")
@@ -1508,7 +1511,9 @@ class LinuxManifest(ViewerManifest):
print "Skipping llcommon.so (assuming llcommon was linked statically)"
self.path("featuretable_linux.txt")
- self.path("ca-bundle.crt")
+
+ with self.prefix(src=pkgdir,dst=""):
+ self.path("ca-bundle.crt")
def package_finish(self):
installer_name = self.installer_base_name()