You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by je...@apache.org on 2015/10/19 13:37:26 UTC

[01/50] [abbrv] allura git commit: [#7971] fix a easywidgets mimetype issue

Repository: allura
Updated Branches:
  refs/heads/ib/7924 4da6c3bbd -> 2505c075f (forced update)


[#7971] fix a easywidgets mimetype issue


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/90fe547a
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/90fe547a
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/90fe547a

Branch: refs/heads/ib/7924
Commit: 90fe547aa28ebac98de9d7040d9202fdfb482835
Parents: 7d21b9b
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Wed Sep 23 15:55:54 2015 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Sep 23 15:57:33 2015 +0000

----------------------------------------------------------------------
 requirements.txt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/90fe547a/requirements.txt
----------------------------------------------------------------------
diff --git a/requirements.txt b/requirements.txt
index e33b957..ee8b586 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -9,7 +9,7 @@ Creoleparser==0.7.3
 decorator==3.3.2
 # dep of pypeline, sphinx
 docutils==0.12
-EasyWidgets==0.2dev-20130716
+EasyWidgets==0.2dev-20150922
 faulthandler==2.1
 feedparser==5.1.3
 FormEncode==1.2.4
@@ -88,4 +88,4 @@ sphinx-rtd-theme==0.1.6
 sphinxcontrib-programoutput==0.8
 
 # deployment
-gunicorn==19.3.0
\ No newline at end of file
+gunicorn==19.3.0


[38/50] [abbrv] allura git commit: [#7924] ticket:830 Update Font Awesome to include new icons

Posted by je...@apache.org.
http://git-wip-us.apache.org/repos/asf/allura/blob/47743877/Allura/allura/public/nf/fonts/fontawesome-webfont.woff
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/fonts/fontawesome-webfont.woff b/Allura/allura/public/nf/fonts/fontawesome-webfont.woff
index 8b280b9..6fd4ede 100644
Binary files a/Allura/allura/public/nf/fonts/fontawesome-webfont.woff and b/Allura/allura/public/nf/fonts/fontawesome-webfont.woff differ

http://git-wip-us.apache.org/repos/asf/allura/blob/47743877/Allura/allura/public/nf/fonts/fontawesome-webfont.woff2
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/fonts/fontawesome-webfont.woff2 b/Allura/allura/public/nf/fonts/fontawesome-webfont.woff2
index 3311d58..5560193 100644
Binary files a/Allura/allura/public/nf/fonts/fontawesome-webfont.woff2 and b/Allura/allura/public/nf/fonts/fontawesome-webfont.woff2 differ


[21/50] [abbrv] allura git commit: [#7943] ticket:842 Remove /_discuss/ endpoint

Posted by je...@apache.org.
[#7943] ticket:842 Remove /_discuss/ endpoint


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/dcec6157
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/dcec6157
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/dcec6157

Branch: refs/heads/ib/7924
Commit: dcec6157ef78a5706d97d33170414f84c352d5b6
Parents: 70001e2
Author: Igor Bondarenko <je...@gmail.com>
Authored: Thu Oct 1 14:21:54 2015 +0000
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Fri Oct 2 10:06:07 2015 -0400

----------------------------------------------------------------------
 Allura/allura/controllers/discuss.py                | 16 +++-------------
 .../forgediscussion/controllers/forum.py            | 11 +++++++----
 2 files changed, 10 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/dcec6157/Allura/allura/controllers/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/discuss.py b/Allura/allura/controllers/discuss.py
index df8076d..36a9b97 100644
--- a/Allura/allura/controllers/discuss.py
+++ b/Allura/allura/controllers/discuss.py
@@ -89,18 +89,12 @@ class DiscussionController(BaseController, FeedController):
         if not hasattr(self, 'moderate'):
             self.moderate = ModerationController(self)
 
-    @with_trailing_slash
-    @expose('jinja:allura:templates/discussion/index.html')
-    def index(self, threads=None, limit=None, page=0, count=0, **kw):
-        c.discussion = self.W.discussion
-        c.discussion_header = self.W.discussion_header
-        if threads is None:
-            threads = self.discussion.threads
-        return dict(discussion=self.discussion, limit=limit, page=page, count=count, threads=threads)
+    def error_handler(self, *args, **kwargs):
+        redirect(request.referer)
 
     @h.vardec
     @expose()
-    @validate(pass_validator, error_handler=index)
+    @validate(pass_validator, error_handler=error_handler)
     def subscribe(self, **kw):
         threads = kw.pop('threads', [])
         for t in threads:
@@ -528,7 +522,3 @@ class ThreadRestController(ThreadController):
 class AppDiscussionRestController(AppDiscussionController):
     ThreadController = ThreadRestController
     PostController = PostRestController
-
-    @expose('json:')
-    def index(self, **kw):
-        return dict(discussion=self.discussion)

http://git-wip-us.apache.org/repos/asf/allura/blob/dcec6157/ForgeDiscussion/forgediscussion/controllers/forum.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/controllers/forum.py b/ForgeDiscussion/forgediscussion/controllers/forum.py
index 8d0117d..8229151 100644
--- a/ForgeDiscussion/forgediscussion/controllers/forum.py
+++ b/ForgeDiscussion/forgediscussion/controllers/forum.py
@@ -107,12 +107,15 @@ class ForumController(DiscussionController):
         c.subscribed = M.Mailbox.subscribed(artifact=self.discussion)
         threads = DM.ForumThread.query.find(dict(discussion_id=self.discussion._id, num_replies={'$gt': 0})) \
                                       .sort([('flags', pymongo.DESCENDING), ('last_post_date', pymongo.DESCENDING)])
-        response = super(
-            ForumController, self).index(threads=threads.skip(start).limit(int(limit)).all(),
-                                         limit=limit, page=page, count=threads.count(), **kw)
+        c.discussion = self.W.discussion
         c.discussion_header = self.W.discussion_header
         c.whole_forum_subscription_form = self.W.subscribe_form
-        return response
+        return dict(
+            discussion=self.discussion,
+            count=threads.count(),
+            threads=threads.skip(start).limit(int(limit)).all(),
+            limit=limit,
+            page=page)
 
     @expose()
     def icon(self):


[28/50] [abbrv] allura git commit: [#7980] Fix many pep8 / pyflakes and related issues

Posted by je...@apache.org.
[#7980] Fix many pep8 / pyflakes and related issues

* line length
* legit uses of has_key
* unused vars
* unused imports
* etc


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/9d39b9a7
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/9d39b9a7
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/9d39b9a7

Branch: refs/heads/ib/7924
Commit: 9d39b9a74cd64da27ec80f26fee992d6d763a07f
Parents: b79b854
Author: Dave Brondsema <da...@brondsema.net>
Authored: Wed Sep 30 09:48:31 2015 -0400
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Tue Oct 6 10:34:02 2015 +0000

----------------------------------------------------------------------
 Allura/allura/command/__init__.py               |   5 +
 .../allura/command/create_trove_categories.py   |  66 ++++-----
 Allura/allura/controllers/__init__.py           |   8 +-
 Allura/allura/controllers/auth.py               |  12 +-
 Allura/allura/lib/helpers.py                    |  53 +++----
 Allura/allura/lib/widgets/__init__.py           |   4 +
 Allura/allura/lib/widgets/forms.py              |  40 +++--
 Allura/allura/model/__init__.py                 |  15 +-
 Allura/allura/model/repo.py                     |   5 +
 Allura/allura/model/repository.py               |  34 +++--
 Allura/allura/tests/functional/test_auth.py     | 105 +++++++------
 Allura/allura/tests/functional/test_discuss.py  |  30 ++--
 .../tests/functional/test_neighborhood.py       |  55 +++----
 Allura/allura/tests/functional/test_rest.py     |   6 +-
 .../tests/functional/test_user_profile.py       |   6 +-
 Allura/allura/tests/test_globals.py             |  34 +++--
 Allura/allura/tests/test_utils.py               |  22 +--
 Allura/allura/websetup/bootstrap.py             |  38 ++---
 Allura/setup.cfg                                |   6 +
 .../forgeactivity/tests/functional/test_rest.py |   6 +-
 .../forgeblog/tests/functional/test_rest.py     |   6 +-
 .../tests/functional/test_forum.py              |  92 ++++++------
 .../tests/functional/test_forum_admin.py        |  23 ++-
 .../tests/functional/test_rest.py               |  11 +-
 .../forgediscussion/widgets/__init__.py         |   4 +
 .../tests/functional/test_controllers.py        | 148 ++++++++-----------
 .../tests/google/test_extractor.py              |  23 ++-
 .../forgelink/tests/functional/test_rest.py     |   6 +-
 .../forgetracker/tests/functional/test_rest.py  |   6 +-
 .../forgetracker/tests/functional/test_root.py  |  77 +++++-----
 .../forgewiki/tests/functional/test_rest.py     |   6 +-
 .../forgewiki/tests/functional/test_root.py     |  23 ++-
 scripts/teamforge-import.py                     |  20 +--
 33 files changed, 499 insertions(+), 496 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/9d39b9a7/Allura/allura/command/__init__.py
----------------------------------------------------------------------
diff --git a/Allura/allura/command/__init__.py b/Allura/allura/command/__init__.py
index 24254aa..0221b7b 100644
--- a/Allura/allura/command/__init__.py
+++ b/Allura/allura/command/__init__.py
@@ -22,3 +22,8 @@ from smtp_server import SMTPServerCommand
 from create_neighborhood import CreateNeighborhoodCommand, UpdateNeighborhoodCommand
 from create_trove_categories import CreateTroveCategoriesCommand
 from set_neighborhood_features import SetNeighborhoodFeaturesCommand
+
+__all__ = [
+    'Command', 'ShowModelsCommand', 'ReindexCommand', 'EnsureIndexCommand', 'ScriptCommand', 'SetToolAccessCommand',
+    'SMTPServerCommand', 'CreateNeighborhoodCommand', 'UpdateNeighborhoodCommand', 'CreateTroveCategoriesCommand',
+    'SetNeighborhoodFeaturesCommand']

http://git-wip-us.apache.org/repos/asf/allura/blob/9d39b9a7/Allura/allura/command/create_trove_categories.py
----------------------------------------------------------------------
diff --git a/Allura/allura/command/create_trove_categories.py b/Allura/allura/command/create_trove_categories.py
index eba9244..288117c 100644
--- a/Allura/allura/command/create_trove_categories.py
+++ b/Allura/allura/command/create_trove_categories.py
@@ -233,7 +233,7 @@ class CreateTroveCategoriesCommand(base.Command):
                                "User Interface :: Toolkits/Libraries :: ClanLib", True))
         self.create_trove_cat(
             (516, 500, "db_group_objmap", "Project is a relational object mapper",
-             "Database Environment :: Grouping and Descriptive Categories (DB) :: Project is a relational object mapper",
+             "Database Environment :: Grouping and Descriptive Categories (DB) :: Project is a relational object mapper",  # nopep8
              True))
         self.create_trove_cat(
             (487, 458, "ui_ggi", "GGI", "User Interface :: Toolkits/Libraries :: GGI", True))
@@ -245,7 +245,7 @@ class CreateTroveCategoriesCommand(base.Command):
                                "User Interface :: Toolkits/Libraries :: wxWidgets", True))
         self.create_trove_cat(
             (511, 500, "db_group_mgmt", "Project is a database management tool",
-             "Database Environment :: Grouping and Descriptive Categories (DB) :: Project is a database management tool",
+             "Database Environment :: Grouping and Descriptive Categories (DB) :: Project is a database management tool",  # nopep8
              True))
         self.create_trove_cat(
             (479, 458, "ui_qt", "Qt", "User Interface :: Toolkits/Libraries :: Qt", True))
@@ -253,7 +253,7 @@ class CreateTroveCategoriesCommand(base.Command):
             (477, 458, "ui_gtk", "GTK+", "User Interface :: Toolkits/Libraries :: GTK+", True))
         self.create_trove_cat(
             (513, 500, "db_group_netdbms", "Project is a network-based DBMS (database system)",
-             "Database Environment :: Grouping and Descriptive Categories (DB) :: Project is a network-based DBMS (database system)",
+             "Database Environment :: Grouping and Descriptive Categories (DB) :: Project is a network-based DBMS (database system)",  # nopep8
              True))
         self.create_trove_cat(
             (228, 458, "newt", "Newt", "User Interface :: Toolkits/Libraries :: Newt", True))
@@ -261,7 +261,7 @@ class CreateTroveCategoriesCommand(base.Command):
                                "User Interface :: Toolkits/Libraries :: Curses/Ncurses", True))
         self.create_trove_cat(
             (515, 500, "db_group_conv", "Project is a database conversion tool",
-             "Database Environment :: Grouping and Descriptive Categories (DB) :: Project is a database conversion tool",
+             "Database Environment :: Grouping and Descriptive Categories (DB) :: Project is a database conversion tool",  # nopep8
              True))
         self.create_trove_cat(
             (478, 458, "ui_tk", "Tk", "User Interface :: Toolkits/Libraries :: Tk", True))
@@ -271,7 +271,7 @@ class CreateTroveCategoriesCommand(base.Command):
                                "Topic :: Communications :: Email :: Post-Office", True))
         self.create_trove_cat(
             (514, 500, "db_group_propfmt", "Project is a tool for a proprietary database file format",
-             "Database Environment :: Grouping and Descriptive Categories (DB) :: Project is a tool for a proprietary database file format",
+             "Database Environment :: Grouping and Descriptive Categories (DB) :: Project is a tool for a proprietary database file format",  # nopep8
              True))
         self.create_trove_cat(
             (482, 458, "ui_aalib", "AAlib", "User Interface :: Toolkits/Libraries :: AAlib", True))
@@ -279,7 +279,7 @@ class CreateTroveCategoriesCommand(base.Command):
             (484, 458, "ui_fltk", "FLTK", "User Interface :: Toolkits/Libraries :: FLTK", True))
         self.create_trove_cat(
             (512, 500, "db_group_filedbms", "Project is a file-based DBMS (database system)",
-             "Database Environment :: Grouping and Descriptive Categories (DB) :: Project is a file-based DBMS (database system)",
+             "Database Environment :: Grouping and Descriptive Categories (DB) :: Project is a file-based DBMS (database system)",  # nopep8
              True))
         self.create_trove_cat(
             (486, 458, "ui_plib", "Plib", "User Interface :: Toolkits/Libraries :: Plib", True))
@@ -287,7 +287,7 @@ class CreateTroveCategoriesCommand(base.Command):
             (488, 458, "ui_glide", "Glide", "User Interface :: Toolkits/Libraries :: Glide", True))
         self.create_trove_cat(
             (510, 500, "db_group_api", "Project is a database abstraction layer (API)",
-             "Database Environment :: Grouping and Descriptive Categories (DB) :: Project is a database abstraction layer (API)",
+             "Database Environment :: Grouping and Descriptive Categories (DB) :: Project is a database abstraction layer (API)",  # nopep8
              True))
         self.create_trove_cat(
             (490, 458, "ui_glut", "GLUT", "User Interface :: Toolkits/Libraries :: GLUT", True))
@@ -828,14 +828,14 @@ class CreateTroveCategoriesCommand(base.Command):
             (441, 315, "ecos", "eCos", "Operating System :: Handheld/Embedded Operating Systems :: eCos", True))
         self.create_trove_cat(
             (
-            443, 315, "vxworks", "VxWorks", "Operating System :: Handheld/Embedded Operating Systems :: VxWorks", True))
+            443, 315, "vxworks", "VxWorks", "Operating System :: Handheld/Embedded Operating Systems :: VxWorks", True))  # nopep8
         self.create_trove_cat((444, 315, "symbianos", "SymbianOS",
                                "Operating System :: Handheld/Embedded Operating Systems :: SymbianOS", True))
         self.create_trove_cat(
             (442, 315, "qnx", "QNX", "Operating System :: Handheld/Embedded Operating Systems :: QNX", True))
         self.create_trove_cat(
             (
-            440, 315, "uclinux", "uClinux", "Operating System :: Handheld/Embedded Operating Systems :: uClinux", True))
+            440, 315, "uclinux", "uClinux", "Operating System :: Handheld/Embedded Operating Systems :: uClinux", True))  # nopep8
         self.create_trove_cat(
             (418, 199, "modern_oses", "Modern (Vendor-Supported) Desktop Operating Systems",
              "Operating System :: Modern (Vendor-Supported) Desktop Operating Systems", True))
@@ -871,13 +871,13 @@ class CreateTroveCategoriesCommand(base.Command):
             (634, 236, "console-platforms", "Console-based Platforms",
              "Operating System :: Other Operating Systems :: Console-based Platforms", True))
         self.create_trove_cat((637, 634, "sega-dreamcast", "Sega Dreamcast",
-                               "Operating System :: Other Operating Systems :: Console-based Platforms :: Sega Dreamcast",
+                               "Operating System :: Other Operating Systems :: Console-based Platforms :: Sega Dreamcast",  # nopep8
                                True))
         self.create_trove_cat((635, 634, "xbox", "Microsoft Xbox",
-                               "Operating System :: Other Operating Systems :: Console-based Platforms :: Microsoft Xbox",
+                               "Operating System :: Other Operating Systems :: Console-based Platforms :: Microsoft Xbox",  # nopep8
                                True))
         self.create_trove_cat((636, 634, "sony-ps2", "Sony Playstation 2",
-                               "Operating System :: Other Operating Systems :: Console-based Platforms :: Sony Playstation 2",
+                               "Operating System :: Other Operating Systems :: Console-based Platforms :: Sony Playstation 2",  # nopep8
                                True))
         self.create_trove_cat(
             (422, 236, "mswin_98", "Win98", "Operating System :: Other Operating Systems :: Win98", True))
@@ -923,11 +923,11 @@ class CreateTroveCategoriesCommand(base.Command):
              "Operating System :: Grouping and Descriptive Categories :: Project is OS Distribution-Specific", True))
         self.create_trove_cat(
             (449, 432, "eightbit_oses", "Classic 8-bit Operating Systems (Apple, Atari, Commodore, etc.)",
-             "Operating System :: Grouping and Descriptive Categories :: Classic 8-bit Operating Systems (Apple, Atari, Commodore, etc.)",
+             "Operating System :: Grouping and Descriptive Categories :: Classic 8-bit Operating Systems (Apple, Atari, Commodore, etc.)",  # nopep8
              True))
         self.create_trove_cat(
             (436, 432, "os_portable", "OS Portable (Source code to work with many OS platforms)",
-             "Operating System :: Grouping and Descriptive Categories :: OS Portable (Source code to work with many OS platforms)",
+             "Operating System :: Grouping and Descriptive Categories :: OS Portable (Source code to work with many OS platforms)",  # nopep8
              True))
         self.create_trove_cat(
             (438, 432, "os_projectdistro", "Project is an Operating System Distribution",
@@ -935,7 +935,7 @@ class CreateTroveCategoriesCommand(base.Command):
              True))
         self.create_trove_cat(
             (235, 432, "independent", "OS Independent (Written in an interpreted language)",
-             "Operating System :: Grouping and Descriptive Categories :: OS Independent (Written in an interpreted language)",
+             "Operating System :: Grouping and Descriptive Categories :: OS Independent (Written in an interpreted language)",  # nopep8
              True))
         self.create_trove_cat(
             (200, 432, "posix", "All POSIX (Linux/BSD/UNIX-like OSes)",
@@ -945,7 +945,7 @@ class CreateTroveCategoriesCommand(base.Command):
              "Operating System :: Grouping and Descriptive Categories :: 32-bit MS Windows (NT/2000/XP)", True))
         self.create_trove_cat(
             (202, 432, "bsd", "All BSD Platforms (FreeBSD/NetBSD/OpenBSD/Apple Mac OS X)",
-             "Operating System :: Grouping and Descriptive Categories :: All BSD Platforms (FreeBSD/NetBSD/OpenBSD/Apple Mac OS X)",
+             "Operating System :: Grouping and Descriptive Categories :: All BSD Platforms (FreeBSD/NetBSD/OpenBSD/Apple Mac OS X)",  # nopep8
              True))
         self.create_trove_cat(
             (435, 432, "mswin_all32bit", "All 32-bit MS Windows (95/98/NT/2000/XP)",
@@ -1107,7 +1107,7 @@ class CreateTroveCategoriesCommand(base.Command):
         self.create_trove_cat((57, 55, "kde", "K Desktop Environment (KDE)",
                                "Topic :: Desktop Environment :: K Desktop Environment (KDE)", True))
         self.create_trove_cat(
-            (61, 57, "themes", "Themes", "Topic :: Desktop Environment :: K Desktop Environment (KDE) :: Themes", True))
+            (61, 57, "themes", "Themes", "Topic :: Desktop Environment :: K Desktop Environment (KDE) :: Themes", True))  # nopep8
         self.create_trove_cat(
             (58, 55, "gnome", "Gnome", "Topic :: Desktop Environment :: Gnome", True))
         self.create_trove_cat((62, 55, "screensavers", "Screen Savers",
@@ -1473,7 +1473,7 @@ class CreateTroveCategoriesCommand(base.Command):
              "Operating System :: Modern (Vendor-Supported) Desktop Operating Systems :: Windows 7", True))
         self.create_trove_cat(
             (
-            728, 315, "android", "Android", "Operating System :: Handheld/Embedded Operating Systems :: Android", True))
+            728, 315, "android", "Android", "Operating System :: Handheld/Embedded Operating Systems :: Android", True))  # nopep8
         self.create_trove_cat((780, 315, "ios", "Apple iPhone",
                                "Operating System :: Handheld/Embedded Operating Systems :: Apple iPhone", True))
         self.create_trove_cat((863, 534, "architects", "Architects",
@@ -1564,7 +1564,7 @@ class CreateTroveCategoriesCommand(base.Command):
         self.create_trove_cat((673, 576, "bsm", "Business Service Management",
                                "Topic :: Office/Business :: Enterprise :: Business Service Management"))
         self.create_trove_cat((674, 673, "servicesupport", "Service Support",
-                               "Topic :: Office/Business :: Enterprise :: Business Service Management :: Service Support"))
+                               "Topic :: Office/Business :: Enterprise :: Business Service Management :: Service Support"))  # nopep8
         self.create_trove_cat(
             (675, 673, "serviceassurance", "Service Assurance",
              "Topic :: Office/Business :: Enterprise :: Business Service Management :: Service Assurance"))
@@ -1593,14 +1593,14 @@ class CreateTroveCategoriesCommand(base.Command):
              "License :: OSI-Approved Open Source :: Simple Public License 2.0"))
         self.create_trove_cat(
             (687, 673, "cmdb", "Configuration Management Database (CMDB)",
-             "Topic :: Office/Business :: Enterprise :: Business Service Management :: Configuration Management Database (CMDB)"))
+             "Topic :: Office/Business :: Enterprise :: Business Service Management :: Configuration Management Database (CMDB)"))  # nopep8
         self.create_trove_cat(
             (688, 18, "mobileapps", "Mobile", "Topic :: Mobile"))
         self.create_trove_cat((689, 315, "winmobile", "Windows Mobile",
                                "Operating System :: Handheld/Embedded Operating Systems :: Windows Mobile"))
         self.create_trove_cat(
             (690, 315, "brew", "BREW (Binary Runtime Environment for Wireless)",
-             "Operating System :: Handheld/Embedded Operating Systems :: BREW (Binary Runtime Environment for Wireless)"))
+             "Operating System :: Handheld/Embedded Operating Systems :: BREW (Binary Runtime Environment for Wireless)"))  # nopep8
         self.create_trove_cat(
             (691, 315, "j2me", "J2ME (Java Platform, Micro Edition)",
              "Operating System :: Handheld/Embedded Operating Systems :: J2ME (Java Platform, Micro Edition)"))
@@ -1658,16 +1658,16 @@ class CreateTroveCategoriesCommand(base.Command):
             (717, 160, "proglangmeta", "Project is a programming language",
              "Programming Language :: Project is a programming language"))
         self.create_trove_cat((718, 634, "msxb360", "Microsoft Xbox 360",
-                               "Operating System :: Other Operating Systems :: Console-based Platforms :: Microsoft Xbox 360"))
+                               "Operating System :: Other Operating Systems :: Console-based Platforms :: Microsoft Xbox 360"))  # nopep8
         self.create_trove_cat((719, 634, "nintendogc", "Nintendo GameCube",
-                               "Operating System :: Other Operating Systems :: Console-based Platforms :: Nintendo GameCube"))
+                               "Operating System :: Other Operating Systems :: Console-based Platforms :: Nintendo GameCube"))  # nopep8
         self.create_trove_cat((720, 634, "nintendowii", "Nintendo Wii",
-                               "Operating System :: Other Operating Systems :: Console-based Platforms :: Nintendo Wii"))
+                               "Operating System :: Other Operating Systems :: Console-based Platforms :: Nintendo Wii"))  # nopep8
         self.create_trove_cat((721, 634, "sonyps3", "Sony PlayStation 3",
-                               "Operating System :: Other Operating Systems :: Console-based Platforms :: Sony PlayStation 3"))
+                               "Operating System :: Other Operating Systems :: Console-based Platforms :: Sony PlayStation 3"))  # nopep8
         self.create_trove_cat(
             (722, 634, "sonypsp", "Sony PlayStation Portable (PSP)",
-             "Operating System :: Other Operating Systems :: Console-based Platforms :: Sony PlayStation Portable (PSP)"))
+             "Operating System :: Other Operating Systems :: Console-based Platforms :: Sony PlayStation Portable (PSP)"))  # nopep8
         self.create_trove_cat(
             (723, 160, "scilab", "Scilab", "Programming Language :: Scilab"))
         self.create_trove_cat(
@@ -1685,10 +1685,10 @@ class CreateTroveCategoriesCommand(base.Command):
             (730, 274, "basque", "Basque (Euskara)", "Translations :: Basque (Euskara)"))
         self.create_trove_cat(
             (731, 14, "classpath", "GNU General Public License with Classpath exception (Classpath::License)",
-             "License :: OSI-Approved Open Source :: GNU General Public License with Classpath exception (Classpath::License)"))
+             "License :: OSI-Approved Open Source :: GNU General Public License with Classpath exception (Classpath::License)"))  # nopep8
         self.create_trove_cat(
             (732, 727, "caddcam", "Computer-aided technologies (CADD/CAM/CAE)",
-             "Topic :: Scientific/Engineering :: Mechanical and Civil Engineering :: Computer-aided technologies (CADD/CAM/CAE)"))
+             "Topic :: Scientific/Engineering :: Mechanical and Civil Engineering :: Computer-aided technologies (CADD/CAM/CAE)"))  # nopep8
         self.create_trove_cat((733, 576, "humanresources", "Human Resources",
                                "Topic :: Office/Business :: Enterprise :: Human Resources"))
         self.create_trove_cat(
@@ -1983,7 +1983,7 @@ class CreateTroveCategoriesCommand(base.Command):
         self.update_trove_cat(
             16, dict(
                 fullname="GNU Library or Lesser General Public License version 2.0 (LGPLv2)",
-                fullpath="License :: OSI-Approved Open Source :: GNU Library or Lesser General Public License version 2.0 (LGPLv2)"))
+                fullpath="License :: OSI-Approved Open Source :: GNU Library or Lesser General Public License version 2.0 (LGPLv2)"))  # nopep8
         self.update_trove_cat(
             15, dict(fullname="GNU General Public License version 2.0 (GPLv2)",
                      fullpath="License :: OSI-Approved Open Source :: GNU General Public License version 2.0 (GPLv2)"))
@@ -1995,16 +1995,16 @@ class CreateTroveCategoriesCommand(base.Command):
              "License :: Creative Commons Attribution License"))
         self.create_trove_cat(
             (869, 868, "ccaslv2", "Creative Commons Attribution ShareAlike License V2.0",
-             "License :: Creative Commons Attribution License :: Creative Commons Attribution ShareAlike License V2.0"))
+             "License :: Creative Commons Attribution License :: Creative Commons Attribution ShareAlike License V2.0"))  # nopep8
         self.create_trove_cat(
             (870, 868, "ccaslv3", "Creative Commons Attribution ShareAlike License V3.0",
-             "License :: Creative Commons Attribution License :: Creative Commons Attribution ShareAlike License V3.0"))
+             "License :: Creative Commons Attribution License :: Creative Commons Attribution ShareAlike License V3.0"))  # nopep8
         self.create_trove_cat(
             (871, 868, "ccanclv2", "Creative Commons Attribution Non-Commercial License V2.0",
-             "License :: Creative Commons Attribution License :: Creative Commons Attribution Non-Commercial License V2.0"))
+             "License :: Creative Commons Attribution License :: Creative Commons Attribution Non-Commercial License V2.0"))  # nopep8
         self.create_trove_cat(
             (680, 14, "lgplv3", "GNU Library or Lesser General Public License version 3.0 (LGPLv3)",
-             "License :: OSI-Approved Open Source :: GNU Library or Lesser General Public License version 3.0 (LGPLv3)"))
+             "License :: OSI-Approved Open Source :: GNU Library or Lesser General Public License version 3.0 (LGPLv3)"))  # nopep8
         self.create_trove_cat(
             (679, 14, "gplv3", "GNU General Public License version 3.0 (GPLv3)",
              "License :: OSI-Approved Open Source :: GNU General Public License version 3.0 (GPLv3)"))

http://git-wip-us.apache.org/repos/asf/allura/blob/9d39b9a7/Allura/allura/controllers/__init__.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/__init__.py b/Allura/allura/controllers/__init__.py
index a69bafb..417b8ad 100644
--- a/Allura/allura/controllers/__init__.py
+++ b/Allura/allura/controllers/__init__.py
@@ -18,6 +18,10 @@
 #       under the License.
 
 """Controllers for the allura application."""
-from .discuss import DiscussionController, AppDiscussionController, ThreadController, PostController, ModerationController
-from .discuss import AppDiscussionRestController
+from .discuss import DiscussionController, AppDiscussionController, ThreadController, PostController
+from .discuss import ModerationController, AppDiscussionRestController
 from .base import BaseController, DispatchIndex
+
+__all__ = [
+    'DiscussionController', 'AppDiscussionController', 'ThreadController', 'PostController', 'ModerationController',
+    'AppDiscussionRestController', 'BaseController', 'DispatchIndex']

http://git-wip-us.apache.org/repos/asf/allura/blob/9d39b9a7/Allura/allura/controllers/auth.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/auth.py b/Allura/allura/controllers/auth.py
index f4f03c9..e3c4d38 100644
--- a/Allura/allura/controllers/auth.py
+++ b/Allura/allura/controllers/auth.py
@@ -51,6 +51,7 @@ from allura.controllers import BaseController
 
 log = logging.getLogger(__name__)
 
+
 class F(object):
     login_form = LoginForm()
     password_change_form = forms.PasswordChangeForm(action='/auth/preferences/change_password')
@@ -183,20 +184,19 @@ class AuthController(BaseController):
         user_record = M.User.by_email_address(email)
         allow_non_primary_email_reset = asbool(config.get('auth.allow_non_primary_email_password_reset', True))
 
-
         if not re.match(r"[^@]+@[^@]+\.[^@]+", email):
             flash('Enter email in correct format!','error')
             redirect('/auth/forgotten_password')
 
         if not allow_non_primary_email_reset:
-            message = 'If the given email address is on record, a password reset email has been sent to the account\'s primary email address.'
+            message = 'If the given email address is on record, '\
+                      'a password reset email has been sent to the account\'s primary email address.'
             email_record = M.EmailAddress.get(email=provider.get_primary_email_address(user_record=user_record),
                                                     confirmed=True)
         else:
             message = 'A password reset email has been sent, if the given email address is on record in our system.'
             email_record = M.EmailAddress.get(email=email, confirmed=True)
 
-
         if user_record and email_record and email_record.confirmed:
             hash = h.nonce(42)
             user_record.set_tool_data('AuthPasswordReset',
@@ -459,10 +459,8 @@ class PreferencesController(BaseController):
         # not using **kw in method signature, to ensure 'admin' can't be passed in via a form submit
         kw = form_params
         addr = kw.pop('addr', None)
-        new_addr= kw.pop('new_addr', None)
+        new_addr = kw.pop('new_addr', None)
         primary_addr = kw.pop('primary_addr', None)
-        oid = kw.pop('oid', None)
-        new_oid = kw.pop('new_oid', None)
         provider = plugin.AuthenticationProvider.get(request)
         for i, (old_a, data) in enumerate(zip(user.email_addresses, addr or [])):
             obj = user.address_object(old_a)
@@ -1011,7 +1009,7 @@ class OAuthController(BaseController):
             validation_pin=h.nonce(20),
             is_bearer=True,
         )
-        access_token = M.OAuthAccessToken(
+        M.OAuthAccessToken(
             consumer_token_id=consumer_token._id,
             request_token_id=c.user._id,
             user_id=request_token.user_id,

http://git-wip-us.apache.org/repos/asf/allura/blob/9d39b9a7/Allura/allura/lib/helpers.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/helpers.py b/Allura/allura/lib/helpers.py
index 68330ba..bf5a580 100644
--- a/Allura/allura/lib/helpers.py
+++ b/Allura/allura/lib/helpers.py
@@ -133,9 +133,11 @@ def make_safe_path_portion(ustr, relaxed=True):
     s = s.replace('--', '-')
     return s
 
+
 def escape_json(data):
     return json.dumps(data).replace('<', '\u003C')
 
+
 def monkeypatch(*objs):
     def patchem(func):
         for obj in objs:
@@ -695,9 +697,9 @@ def paging_sanitizer(limit, page, total_count, zero_based_pages=True):
     return limit, page
 
 
-def _add_inline_line_numbers_to_text(text):
+def _add_inline_line_numbers_to_text(txt):
     markup_text = '<div class="codehilite"><pre>'
-    for line_num, line in enumerate(text.splitlines(), 1):
+    for line_num, line in enumerate(txt.splitlines(), 1):
         markup_text = markup_text + \
             '<span id="l%s" class="code_block"><span class="lineno">%s</span> %s</span>' % (
                 line_num, line_num, line)
@@ -705,7 +707,7 @@ def _add_inline_line_numbers_to_text(text):
     return markup_text
 
 
-def _add_table_line_numbers_to_text(text):
+def _add_table_line_numbers_to_text(txt):
     def _prepend_whitespaces(num, max_num):
         num, max_num = str(num), str(max_num)
         diff = len(max_num) - len(num)
@@ -715,7 +717,7 @@ def _add_table_line_numbers_to_text(text):
         max_num = l + start
         return '\n'.join(map(_prepend_whitespaces, range(start, max_num), [max_num] * l))
 
-    lines = text.splitlines(True)
+    lines = txt.splitlines(True)
     linenumbers = '<td class="linenos"><div class="linenodiv"><pre>' + \
         _len_to_str_column(len(lines)) + '</pre></div></td>'
     markup_text = '<table class="codehilitetable"><tbody><tr>' + \
@@ -731,28 +733,28 @@ INLINE = 'inline'
 TABLE = 'table'
 
 
-def render_any_markup(name, text, code_mode=False, linenumbers_style=TABLE):
+def render_any_markup(name, txt, code_mode=False, linenumbers_style=TABLE):
     """
     renders markdown using allura enhacements if file is in markdown format
     renders any other markup format using the pypeline
     Returns jinja-safe text
     """
-    if text == '':
-        text = '<p><em>Empty File</em></p>'
+    if txt == '':
+        txt = '<p><em>Empty File</em></p>'
     else:
         fmt = g.pypeline_markup.can_render(name)
         if fmt == 'markdown':
-            text = g.markdown.convert(text)
+            txt = g.markdown.convert(txt)
         else:
-            text = g.pypeline_markup.render(name, text)
+            txt = g.pypeline_markup.render(name, txt)
         if not fmt:
             if code_mode and linenumbers_style == INLINE:
-                text = _add_inline_line_numbers_to_text(text)
+                txt = _add_inline_line_numbers_to_text(txt)
             elif code_mode and linenumbers_style == TABLE:
-                text = _add_table_line_numbers_to_text(text)
+                txt = _add_table_line_numbers_to_text(txt)
             else:
-                text = '<pre>%s</pre>' % text
-    return Markup(text)
+                txt = '<pre>%s</pre>' % txt
+    return Markup(txt)
 
 # copied from jinja2 dev
 # latest release, 2.6, implements this incorrectly
@@ -1053,28 +1055,28 @@ def urlopen(url, retries=3, codes=(408, 500, 502, 503, 504), timeout=None):
                 raise e
 
 
-def plain2markdown(text, preserve_multiple_spaces=False, has_html_entities=False):
+def plain2markdown(txt, preserve_multiple_spaces=False, has_html_entities=False):
     if not has_html_entities:
         # prevent &foo; and &#123; from becoming HTML entities
-        text = re_amp.sub('&amp;', text)
+        txt = re_amp.sub('&amp;', txt)
     # avoid accidental 4-space indentations creating code blocks
     if preserve_multiple_spaces:
-        text = text.replace('\t', ' ' * 4)
-        text = re_preserve_spaces.sub('&nbsp;', text)
+        txt = txt.replace('\t', ' ' * 4)
+        txt = re_preserve_spaces.sub('&nbsp;', txt)
     else:
-        text = re_leading_spaces.sub('', text)
+        txt = re_leading_spaces.sub('', txt)
     try:
         # try to use html2text for most of the escaping
         import html2text
         html2text.BODY_WIDTH = 0
-        text = html2text.escape_md_section(text, snob=True)
+        txt = html2text.escape_md_section(txt, snob=True)
     except ImportError:
         # fall back to just escaping any MD-special chars
-        text = md_chars_matcher_all.sub(r"\\\1", text)
+        txt = md_chars_matcher_all.sub(r"\\\1", txt)
     # prevent < and > from becoming tags
-    text = re_angle_bracket_open.sub('&lt;', text)
-    text = re_angle_bracket_close.sub('&gt;', text)
-    return text
+    txt = re_angle_bracket_open.sub('&lt;', txt)
+    txt = re_angle_bracket_close.sub('&gt;', txt)
+    return txt
 
 
 def iter_entry_points(group, *a, **kw):
@@ -1166,7 +1168,7 @@ def login_overlay(exceptions=None):
     """
     try:
         yield
-    except HTTPUnauthorized as e:
+    except HTTPUnauthorized:
         if exceptions:
             for exception in exceptions:
                 if request.path.rstrip('/').endswith('/%s' % exception):
@@ -1251,7 +1253,6 @@ def rate_limit(cfg_opt, artifact_count, start_date, exception=None):
     now = datetime.utcnow()
     for rate, count in rate_limits.items():
         age = now - start_date
-        age = (age.microseconds +
-                (age.seconds + age.days * 24 * 3600) * 10 ** 6) / 10 ** 6
+        age = (age.microseconds + (age.seconds + age.days * 24 * 3600) * 10 ** 6) / 10 ** 6
         if age < int(rate) and artifact_count >= count:
             raise exception()

http://git-wip-us.apache.org/repos/asf/allura/blob/9d39b9a7/Allura/allura/lib/widgets/__init__.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/__init__.py b/Allura/allura/lib/widgets/__init__.py
index 6e13a39..9d21e37 100644
--- a/Allura/allura/lib/widgets/__init__.py
+++ b/Allura/allura/lib/widgets/__init__.py
@@ -20,3 +20,7 @@ from .subscriptions import SubscriptionForm
 from .oauth_widgets import OAuthApplicationForm, OAuthRevocationForm
 from .auth_widgets import LoginForm, ForgottenPasswordForm, DisableAccountForm
 from .vote import VoteForm
+
+__all__ = [
+    'Post', 'Thread', 'Discussion', 'SubscriptionForm', 'OAuthApplicationForm', 'OAuthRevocationForm', 'LoginForm',
+    'ForgottenPasswordForm', 'DisableAccountForm', 'VoteForm']

http://git-wip-us.apache.org/repos/asf/allura/blob/9d39b9a7/Allura/allura/lib/widgets/forms.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/forms.py b/Allura/allura/lib/widgets/forms.py
index cfbad2c..5d35788 100644
--- a/Allura/allura/lib/widgets/forms.py
+++ b/Allura/allura/lib/widgets/forms.py
@@ -18,7 +18,6 @@
 import logging
 import warnings
 
-from collections import defaultdict
 from pylons import app_globals as g, tmpl_context as c
 from formencode import validators as fev
 import formencode
@@ -686,13 +685,12 @@ class SelectSubCategoryForm(ForgeForm):
     def display(self, **kw):
         categories = kw.get('categories')
 
-        self.fields['selected_category'].options = \
-            [ew.Option(py_value=el.trove_cat_id, label=el.fullname)
-             for el in categories]
-        self.fields['selected_category'].validator = \
-            validator = formencode.All(
-                V.OneOfValidator(categories),
-                fev.UnicodeString(not_empty=True))
+        self.fields['selected_category'].options = [
+            ew.Option(py_value=el.trove_cat_id, label=el.fullname) for el in categories
+        ]
+        self.fields['selected_category'].validator = formencode.All(
+            V.OneOfValidator(categories),
+            fev.UnicodeString(not_empty=True))
         return super(ForgeForm, self).display(**kw)
 
 
@@ -830,18 +828,19 @@ class NeighborhoodOverviewForm(ForgeForm):
                 empty_val = False
                 if inp['value'] is None or inp['value'] == '':
                     empty_val = True
-                display += '<tr><td class="left"><label>%(label)s</label></td>'\
-                           '<td><input type="checkbox" name="%(ctx_name)s-%(inp_name)s-def" %(def_checked)s>default</td>'\
-                           '<td class="right"><div class="%(ctx_name)s-%(inp_name)s-inp"><table class="input_inner">'\
-                           '<tr><td><input type="text" class="%(inp_type)s" name="%(ctx_name)s-%(inp_name)s" '\
-                           'value="%(inp_value)s"></td><td>%(inp_additional)s</td></tr></table></div></td></tr>\n' % {'ctx_id': ctx['id'],
-                                                                                                                      'ctx_name': ctx['name'],
-                                                                                                                      'inp_name': inp['name'],
-                                                                                                                      'inp_value': inp['value'],
-                                                                                                                      'label': inp['label'],
-                                                                                                                      'inp_type': inp['type'],
-                                                                                                                      'def_checked': 'checked="checked"' if empty_val else '',
-                                                                                                                      'inp_additional': additional_inputs}
+                display += '<tr><td class="left"><label>%(label)s</label></td>' \
+                           '<td><input type="checkbox" name="%(ctx_name)s-%(inp_name)s-def" %(def_checked)s>default</td>' \
+                           '<td class="right"><div class="%(ctx_name)s-%(inp_name)s-inp"><table class="input_inner">' \
+                           '<tr><td><input type="text" class="%(inp_type)s" name="%(ctx_name)s-%(inp_name)s" ' \
+                           'value="%(inp_value)s"></td><td>%(inp_additional)s</td></tr></table></div></td></tr>\n' % {
+                               'ctx_id': ctx['id'],
+                               'ctx_name': ctx['name'],
+                               'inp_name': inp['name'],
+                               'inp_value': inp['value'],
+                               'label': inp['label'],
+                               'inp_type': inp['type'],
+                               'def_checked': 'checked="checked"' if empty_val else '',
+                               'inp_additional': additional_inputs}
             display += '</table>'
 
             if ctx['errors'] and field.show_errors and not ignore_errors:
@@ -1105,7 +1104,6 @@ class AwardGrantForm(ForgeForm):
         self._project_select_url = kw.pop('project_select_url', '')
         super(AwardGrantForm, self).__init__(*args, **kw)
 
-
     def award_options(self):
         return [ew.Option(py_value=a.short, label=a.short) for a in self._awards]
 

http://git-wip-us.apache.org/repos/asf/allura/blob/9d39b9a7/Allura/allura/model/__init__.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/__init__.py b/Allura/allura/model/__init__.py
index 784d1af..cb817b4 100644
--- a/Allura/allura/model/__init__.py
+++ b/Allura/allura/model/__init__.py
@@ -22,7 +22,8 @@
 from .neighborhood import Neighborhood, NeighborhoodFile
 from .project import Project, ProjectCategory, TroveCategory, ProjectFile, AppConfig
 from .index import ArtifactReference, Shortlink
-from .artifact import Artifact, MovedArtifact, Message, VersionedArtifact, Snapshot, Feed, AwardFile, Award, AwardGrant, VotableArtifact
+from .artifact import Artifact, MovedArtifact, Message, VersionedArtifact, Snapshot, Feed, AwardFile, Award, AwardGrant
+from .artifact import VotableArtifact
 from .discuss import Discussion, Thread, PostHistory, Post, DiscussionAttachment
 from .attachments import BaseAttachment
 from .auth import AuthGlobals, User, ProjectRole, EmailAddress, OldProjectRole
@@ -48,3 +49,15 @@ from . import repo_refresh
 
 from ming.orm import Mapper
 Mapper.compile_all()
+
+__all__ = [
+    'Neighborhood', 'NeighborhoodFile', 'Project', 'ProjectCategory', 'TroveCategory', 'ProjectFile', 'AppConfig',
+    'ArtifactReference', 'Shortlink', 'Artifact', 'MovedArtifact', 'Message', 'VersionedArtifact', 'Snapshot', 'Feed',
+    'AwardFile', 'Award', 'AwardGrant', 'VotableArtifact', 'Discussion', 'Thread', 'PostHistory', 'Post',
+    'DiscussionAttachment', 'BaseAttachment', 'AuthGlobals', 'User', 'ProjectRole', 'EmailAddress', 'OldProjectRole',
+    'AuditLog', 'audit_log', 'AlluraUserProperty', 'File', 'Notification', 'Mailbox', 'Repository',
+    'RepositoryImplementation', 'MergeRequest', 'GitLikeTree', 'Stats', 'OAuthToken', 'OAuthConsumerToken',
+    'OAuthRequestToken', 'OAuthAccessToken', 'MonQTask', 'Webhook', 'ACE', 'ACL', 'EVERYONE', 'ALL_PERMISSIONS',
+    'DENY_ALL', 'MarkdownCache', 'main_doc_session', 'main_orm_session', 'project_doc_session', 'project_orm_session',
+    'artifact_orm_session', 'repository_orm_session', 'task_orm_session', 'ArtifactSessionExtension', 'repository',
+    'repo_refresh', ]

http://git-wip-us.apache.org/repos/asf/allura/blob/9d39b9a7/Allura/allura/model/repo.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/repo.py b/Allura/allura/model/repo.py
index f041116..6ba6633 100644
--- a/Allura/allura/model/repo.py
+++ b/Allura/allura/model/repo.py
@@ -24,3 +24,8 @@ from .repository import QSIZE, README_RE, VIEWABLE_EXTENSIONS, PYPELINE_EXTENSIO
 from .repository import CommitDoc, TreeDoc, LastCommitDoc, TreesDoc, CommitRunDoc
 from .repository import RepoObject, Commit, Tree, Blob, LastCommit
 from .repository import ModelCache
+
+__all__ = [
+    'SUser', 'SObjType', 'QSIZE', 'README_RE', 'VIEWABLE_EXTENSIONS', 'PYPELINE_EXTENSIONS',
+    'DIFF_SIMILARITY_THRESHOLD', 'CommitDoc', 'TreeDoc', 'LastCommitDoc', 'TreesDoc', 'CommitRunDoc', 'RepoObject',
+    'Commit', 'Tree', 'Blob', 'LastCommit', 'ModelCache']

http://git-wip-us.apache.org/repos/asf/allura/blob/9d39b9a7/Allura/allura/model/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/repository.py b/Allura/allura/model/repository.py
index 77c3fc4..75ed2dc 100644
--- a/Allura/allura/model/repository.py
+++ b/Allura/allura/model/repository.py
@@ -30,7 +30,7 @@ from urlparse import urljoin
 from threading import Thread
 from Queue import Queue
 from itertools import chain
-from difflib import SequenceMatcher, unified_diff
+from difflib import SequenceMatcher
 
 import tg
 from paste.deploy.converters import asint, asbool
@@ -56,7 +56,7 @@ from .timeline import ActivityObject
 from .monq_model import MonQTask
 from .project import AppConfig
 from .session import main_doc_session
-from .session import repository_orm_session, artifact_orm_session
+from .session import repository_orm_session
 
 
 log = logging.getLogger(__name__)
@@ -78,18 +78,20 @@ SObjType = S.OneOf('blob', 'tree', 'submodule')
 # Used for when we're going to batch queries using $in
 QSIZE = 100
 BINARY_EXTENSIONS = frozenset([
-    ".3ds", ".3g2", ".3gp", ".7z", ".a", ".aac", ".adp", ".ai", ".aif", ".apk", ".ar", ".asf", ".au", ".avi",
-    ".bak", ".bin", ".bk", ".bmp", ".btif", ".bz2", ".cab", ".caf", ".cgm", ".cmx", ".cpio", ".cr2", ".dat", ".deb", ".djvu", ".dll",
-    ".dmg", ".dng", ".doc", ".docx", ".dra", ".DS_Store", ".dsk", ".dts", ".dtshd", ".dvb", ".dwg", ".dxf", ".ecelp4800",
-    ".ecelp7470", ".ecelp9600", ".egg", ".eol", ".eot", ".epub", ".exe", ".f4v", ".fbs", ".fh", ".fla", ".flac", ".fli", ".flv",
-    ".fpx", ".fst", ".fvt", ".g3", ".gif", ".gz", ".h261", ".h263", ".h264", ".ico", ".ief", ".img", ".ipa", ".iso", ".jar", ".jpeg",
-    ".jpg", ".jpgv", ".jpm", ".jxr", ".ktx", ".lvp", ".lz", ".lzma", ".lzo", ".m3u", ".m4a", ".m4v", ".mar", ".mdi", ".mid", ".mj2",
-    ".mka", ".mkv", ".mmr", ".mng", ".mov", ".movie", ".mp3", ".mp4", ".mp4a", ".mpeg", ".mpg", ".mpga", ".mxu", ".nef", ".npx", ".o",
-    ".oga", ".ogg", ".ogv", ".otf", ".pbm", ".pcx", ".pdf", ".pea", ".pgm", ".pic", ".png", ".pnm", ".ppm", ".psd", ".pya", ".pyc",
-    ".pyo", ".pyv", ".qt", ".rar", ".ras", ".raw", ".rgb", ".rip", ".rlc", ".rz", ".s3m", ".s7z", ".scpt", ".sgi", ".shar", ".sil",
-    ".smv", ".so", ".sub", ".swf", ".tar", ".tbz2", ".tga", ".tgz", ".tif", ".tiff", ".tlz", ".ts", ".ttf", ".uvh", ".uvi", ".uvm",
-    ".uvp", ".uvs", ".uvu", ".viv", ".vob", ".war", ".wav", ".wax", ".wbmp", ".wdp", ".weba", ".webm", ".webp", ".whl", ".wm", ".wma",
-    ".wmv", ".wmx", ".woff", ".woff2", ".wvx", ".xbm", ".xif", ".xm", ".xpi", ".xpm", ".xwd", ".xz", ".z", ".zip", ".zipx"
+    ".3ds", ".3g2", ".3gp", ".7z", ".a", ".aac", ".adp", ".ai", ".aif", ".apk", ".ar", ".asf", ".au", ".avi", ".bak",
+    ".bin", ".bk", ".bmp", ".btif", ".bz2", ".cab", ".caf", ".cgm", ".cmx", ".cpio", ".cr2", ".dat", ".deb", ".djvu",
+    ".dll", ".dmg", ".dng", ".doc", ".docx", ".dra", ".DS_Store", ".dsk", ".dts", ".dtshd", ".dvb", ".dwg", ".dxf",
+    ".ecelp4800", ".ecelp7470", ".ecelp9600", ".egg", ".eol", ".eot", ".epub", ".exe", ".f4v", ".fbs", ".fh", ".fla",
+    ".flac", ".fli", ".flv", ".fpx", ".fst", ".fvt", ".g3", ".gif", ".gz", ".h261", ".h263", ".h264", ".ico", ".ief",
+    ".img", ".ipa", ".iso", ".jar", ".jpeg", ".jpg", ".jpgv", ".jpm", ".jxr", ".ktx", ".lvp", ".lz", ".lzma", ".lzo",
+    ".m3u", ".m4a", ".m4v", ".mar", ".mdi", ".mid", ".mj2", ".mka", ".mkv", ".mmr", ".mng", ".mov", ".movie", ".mp3",
+    ".mp4", ".mp4a", ".mpeg", ".mpg", ".mpga", ".mxu", ".nef", ".npx", ".o", ".oga", ".ogg", ".ogv", ".otf", ".pbm",
+    ".pcx", ".pdf", ".pea", ".pgm", ".pic", ".png", ".pnm", ".ppm", ".psd", ".pya", ".pyc", ".pyo", ".pyv", ".qt",
+    ".rar", ".ras", ".raw", ".rgb", ".rip", ".rlc", ".rz", ".s3m", ".s7z", ".scpt", ".sgi", ".shar", ".sil", ".smv",
+    ".so", ".sub", ".swf", ".tar", ".tbz2", ".tga", ".tgz", ".tif", ".tiff", ".tlz", ".ts", ".ttf", ".uvh", ".uvi",
+    ".uvm", ".uvp", ".uvs", ".uvu", ".viv", ".vob", ".war", ".wav", ".wax", ".wbmp", ".wdp", ".weba", ".webm", ".webp",
+    ".whl", ".wm", ".wma", ".wmv", ".wmx", ".woff", ".woff2", ".wvx", ".xbm", ".xif", ".xm", ".xpi", ".xpm", ".xwd",
+    ".xz", ".z", ".zip", ".zipx"
 ])
 
 PYPELINE_EXTENSIONS = frozenset(utils.MARKDOWN_EXTENSIONS + ['.rst'])
@@ -895,7 +897,7 @@ class MergeRequest(VersionedArtifact, ActivityObject):
             'state': {'$in': ['busy', 'complete', 'error', 'ready']},  # needed to use index
             'task_name': 'allura.tasks.repo_tasks.merge',
             'args': [self._id],
-            'time_queue': {'$gt': datetime.utcnow() - timedelta(days=1)}, # constrain on index further
+            'time_queue': {'$gt': datetime.utcnow() - timedelta(days=1)},  # constrain on index further
         }).sort('_id', -1).limit(1).first()
         if task:
             return task.state
@@ -906,7 +908,7 @@ class MergeRequest(VersionedArtifact, ActivityObject):
             'state': {'$in': ['busy', 'complete', 'error', 'ready']},  # needed to use index
             'task_name': 'allura.tasks.repo_tasks.can_merge',
             'args': [self._id],
-            'time_queue': {'$gt': datetime.utcnow() - timedelta(days=1)}, # constrain on index further
+            'time_queue': {'$gt': datetime.utcnow() - timedelta(days=1)},  # constrain on index further
         }).sort('_id', -1).limit(1).first()
         if task:
             return task.state

http://git-wip-us.apache.org/repos/asf/allura/blob/9d39b9a7/Allura/allura/tests/functional/test_auth.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_auth.py b/Allura/allura/tests/functional/test_auth.py
index 388be1a..5ad86ea 100644
--- a/Allura/allura/tests/functional/test_auth.py
+++ b/Allura/allura/tests/functional/test_auth.py
@@ -1063,7 +1063,7 @@ class TestPreferences(TestController):
                               weekday=weekday2,
                               starttime=starttime2.strftime('%H:%M'),
                               endtime=endtime2.strftime('%H:%M'),
-                            _session_id=self.app.cookies['_session_id'],
+                              _session_id=self.app.cookies['_session_id'],
                           ))
         user = M.User.query.get(username='test-admin')
         timeslot2dict = dict(week_day=weekday2,
@@ -1159,14 +1159,14 @@ class TestPreferences(TestController):
         skill_cat = M.TroveCategory.query.get(show_as_skill=True)
         level = 'low'
         comment = 'test comment'
-        result = self.app.get('/auth/user_info/skills/')
-        r = self.app.post('/auth/user_info/skills/save_skill',
-                          params=dict(
-                              level=level,
-                              comment=comment,
-                              selected_skill=str(skill_cat.trove_cat_id),
-                              _session_id=self.app.cookies['_session_id'],
-                          ))
+        self.app.get('/auth/user_info/skills/')
+        self.app.post('/auth/user_info/skills/save_skill',
+                      params=dict(
+                          level=level,
+                          comment=comment,
+                          selected_skill=str(skill_cat.trove_cat_id),
+                          _session_id=self.app.cookies['_session_id'],
+                      ))
         user = M.User.query.get(username='test-admin')
         skilldict = dict(category_id=skill_cat._id,
                          comment=comment, level=level)
@@ -1175,14 +1175,14 @@ class TestPreferences(TestController):
         # Add again the same skill
         level = 'medium'
         comment = 'test comment 2'
-        result = self.app.get('/auth/user_info/skills/')
-        r = self.app.post('/auth/user_info/skills/save_skill',
-                          params=dict(
-                              level=level,
-                              comment=comment,
-                              selected_skill=str(skill_cat.trove_cat_id),
-                              _session_id=self.app.cookies['_session_id'],
-                          ))
+        self.app.get('/auth/user_info/skills/')
+        self.app.post('/auth/user_info/skills/save_skill',
+                      params=dict(
+                          level=level,
+                          comment=comment,
+                          selected_skill=str(skill_cat.trove_cat_id),
+                          _session_id=self.app.cookies['_session_id'],
+                      ))
         user = M.User.query.get(username='test-admin')
         skilldict = dict(category_id=skill_cat._id,
                          comment=comment, level=level)
@@ -1191,13 +1191,13 @@ class TestPreferences(TestController):
         # Add an invalid skill
         level2 = 'not a level'
         comment2 = 'test comment 2'
-        r = self.app.post('/auth/user_info/skills/save_skill',
-                          params=dict(
-                              level=level2,
-                              comment=comment2,
-                              selected_skill=str(skill_cat.trove_cat_id),
-                              _session_id=self.app.cookies['_session_id'],
-                          ))
+        self.app.post('/auth/user_info/skills/save_skill',
+                      params=dict(
+                          level=level2,
+                          comment=comment2,
+                          selected_skill=str(skill_cat.trove_cat_id),
+                          _session_id=self.app.cookies['_session_id'],
+                      ))
         user = M.User.query.get(username='test-admin')
         # Check that everything is as it was before
         assert len(user.skills) == 1 and skilldict in user.skills
@@ -1450,13 +1450,13 @@ class TestOAuth(TestController):
     def test_interactive(self, Request, Server):
         M.OAuthConsumerToken.consumer = mock.Mock()
         user = M.User.by_username('test-admin')
-        consumer_token = M.OAuthConsumerToken(
+        M.OAuthConsumerToken(
             api_key='api_key',
             user_id=user._id,
             description='ctok_desc',
         )
         ThreadLocalORMSession.flush_all()
-        req = Request.from_request.return_value = {
+        Request.from_request.return_value = {
             'oauth_consumer_key': 'api_key',
             'oauth_callback': 'http://my.domain.com/callback',
         }
@@ -1467,7 +1467,7 @@ class TestOAuth(TestController):
         r = r.forms[0].submit('yes')
         assert r.location.startswith('http://my.domain.com/callback')
         pin = parse_qs(urlparse(r.location).query)['oauth_verifier'][0]
-        req = Request.from_request.return_value = {
+        Request.from_request.return_value = {
             'oauth_consumer_key': 'api_key',
             'oauth_token': rtok,
             'oauth_verifier': pin,
@@ -1502,10 +1502,10 @@ class TestOAuth(TestController):
     @mock.patch('allura.controllers.rest.oauth.Server')
     @mock.patch('allura.controllers.rest.oauth.Request')
     def test_request_token_no_consumer_token(self, Request, Server):
-        req = Request.from_request.return_value = {
+        Request.from_request.return_value = {
             'oauth_consumer_key': 'api_key'}
-        r = self.app.post('/rest/oauth/request_token',
-                          params={'key': 'value'}, status=403)
+        self.app.post('/rest/oauth/request_token',
+                      params={'key': 'value'}, status=403)
 
     @mock.patch('allura.controllers.rest.oauth.Server')
     @mock.patch('allura.controllers.rest.oauth.Request')
@@ -1513,12 +1513,12 @@ class TestOAuth(TestController):
         Server().verify_request.side_effect = ValueError
         M.OAuthConsumerToken.consumer = mock.Mock()
         user = M.User.by_username('test-user')
-        consumer_token = M.OAuthConsumerToken(
+        M.OAuthConsumerToken(
             api_key='api_key',
             user_id=user._id,
         )
         ThreadLocalORMSession.flush_all()
-        req = Request.from_request.return_value = {'oauth_consumer_key': 'api_key'}
+        Request.from_request.return_value = {'oauth_consumer_key': 'api_key'}
         self.app.post('/rest/oauth/request_token', params={'key': 'value'}, status=403)
 
     def test_authorize_ok(self):
@@ -1528,7 +1528,7 @@ class TestOAuth(TestController):
             user_id=user._id,
             description='ctok_desc',
         )
-        rtok = M.OAuthRequestToken(
+        M.OAuthRequestToken(
             api_key='api_key',
             consumer_token_id=ctok._id,
             callback='oob',
@@ -1549,7 +1549,7 @@ class TestOAuth(TestController):
             user_id=user._id,
             description='ctok_desc',
         )
-        rtok = M.OAuthRequestToken(
+        M.OAuthRequestToken(
             api_key='api_key',
             consumer_token_id=ctok._id,
             callback='oob',
@@ -1567,7 +1567,7 @@ class TestOAuth(TestController):
             user_id=user._id,
             description='ctok_desc',
         )
-        rtok = M.OAuthRequestToken(
+        M.OAuthRequestToken(
             api_key='api_key',
             consumer_token_id=ctok._id,
             callback='oob',
@@ -1584,7 +1584,7 @@ class TestOAuth(TestController):
             user_id=user._id,
             description='ctok_desc',
         )
-        rtok = M.OAuthRequestToken(
+        M.OAuthRequestToken(
             api_key='api_key',
             consumer_token_id=ctok._id,
             callback='http://my.domain.com/callback',
@@ -1601,7 +1601,7 @@ class TestOAuth(TestController):
             user_id=user._id,
             description='ctok_desc',
         )
-        rtok = M.OAuthRequestToken(
+        M.OAuthRequestToken(
             api_key='api_key',
             consumer_token_id=ctok._id,
             callback='http://my.domain.com/callback?myparam=foo',
@@ -1613,7 +1613,7 @@ class TestOAuth(TestController):
 
     @mock.patch('allura.controllers.rest.oauth.Request')
     def test_access_token_no_consumer(self, Request):
-        req = Request.from_request.return_value = {
+        Request.from_request.return_value = {
             'oauth_consumer_key': 'api_key',
             'oauth_token': 'api_key',
             'oauth_verifier': 'good',
@@ -1622,13 +1622,13 @@ class TestOAuth(TestController):
 
     @mock.patch('allura.controllers.rest.oauth.Request')
     def test_access_token_no_request(self, Request):
-        req = Request.from_request.return_value = {
+        Request.from_request.return_value = {
             'oauth_consumer_key': 'api_key',
             'oauth_token': 'api_key',
             'oauth_verifier': 'good',
         }
         user = M.User.by_username('test-admin')
-        ctok = M.OAuthConsumerToken(
+        M.OAuthConsumerToken(
             api_key='api_key',
             user_id=user._id,
             description='ctok_desc',
@@ -1638,7 +1638,7 @@ class TestOAuth(TestController):
 
     @mock.patch('allura.controllers.rest.oauth.Request')
     def test_access_token_bad_pin(self, Request):
-        req = Request.from_request.return_value = {
+        Request.from_request.return_value = {
             'oauth_consumer_key': 'api_key',
             'oauth_token': 'api_key',
             'oauth_verifier': 'bad',
@@ -1649,7 +1649,7 @@ class TestOAuth(TestController):
             user_id=user._id,
             description='ctok_desc',
         )
-        rtok = M.OAuthRequestToken(
+        M.OAuthRequestToken(
             api_key='api_key',
             consumer_token_id=ctok._id,
             callback='http://my.domain.com/callback?myparam=foo',
@@ -1662,7 +1662,7 @@ class TestOAuth(TestController):
     @mock.patch('allura.controllers.rest.oauth.Server')
     @mock.patch('allura.controllers.rest.oauth.Request')
     def test_access_token_bad_sig(self, Request, Server):
-        req = Request.from_request.return_value = {
+        Request.from_request.return_value = {
             'oauth_consumer_key': 'api_key',
             'oauth_token': 'api_key',
             'oauth_verifier': 'good',
@@ -1673,7 +1673,7 @@ class TestOAuth(TestController):
             user_id=user._id,
             description='ctok_desc',
         )
-        rtok = M.OAuthRequestToken(
+        M.OAuthRequestToken(
             api_key='api_key',
             consumer_token_id=ctok._id,
             callback='http://my.domain.com/callback?myparam=foo',
@@ -1687,7 +1687,7 @@ class TestOAuth(TestController):
     @mock.patch('allura.controllers.rest.oauth.Server')
     @mock.patch('allura.controllers.rest.oauth.Request')
     def test_access_token_ok(self, Request, Server):
-        req = Request.from_request.return_value = {
+        Request.from_request.return_value = {
             'oauth_consumer_key': 'api_key',
             'oauth_token': 'api_key',
             'oauth_verifier': 'good',
@@ -1698,7 +1698,7 @@ class TestOAuth(TestController):
             user_id=user._id,
             description='ctok_desc',
         )
-        rtok = M.OAuthRequestToken(
+        M.OAuthRequestToken(
             api_key='api_key',
             consumer_token_id=ctok._id,
             callback='http://my.domain.com/callback?myparam=foo',
@@ -1735,8 +1735,8 @@ class TestDisableAccount(TestController):
 
     def test_bad_password(self):
         self.app.get('/')  # establish session
-        r = self.app.post('/auth/disable/do_disable',{'password': 'bad',
-                                                      '_session_id': self.app.cookies['_session_id'],})
+        r = self.app.post('/auth/disable/do_disable', {'password': 'bad',
+                                                       '_session_id': self.app.cookies['_session_id'], })
         assert_in('Invalid password', r)
         user = M.User.by_username('test-admin')
         assert_equal(user.disabled, False)
@@ -1744,7 +1744,7 @@ class TestDisableAccount(TestController):
     def test_disable(self):
         self.app.get('/')  # establish session
         r = self.app.post('/auth/disable/do_disable', {'password': 'foo',
-                                                       '_session_id': self.app.cookies['_session_id'],})
+                                                       '_session_id': self.app.cookies['_session_id'], })
         assert_equal(r.status_int, 302)
         assert_equal(r.location, 'http://localhost/')
         flash = json.loads(self.webflash(r))
@@ -1866,8 +1866,8 @@ class TestPasswordExpire(TestController):
             self.assert_redirects()
             user = M.User.by_username('test-user')
             user.set_tool_data('AuthPasswordReset',
-                          hash="generated_hash_value",
-                          hash_expiry="04-08-2020")
+                               hash="generated_hash_value",
+                               hash_expiry="04-08-2020")
             hash = user.get_tool_data('AuthPasswordReset', 'hash')
             hash_expiry = user.get_tool_data('AuthPasswordReset', 'hash_expiry')
             assert_equal(hash, 'generated_hash_value')
@@ -1890,7 +1890,6 @@ class TestPasswordExpire(TestController):
             assert_equal(hash, '')
             assert_equal(hash_expiry, '')
 
-
     def check_validation(self, oldpw, pw, pw2):
         user = M.User.by_username('test-user')
         old_update_time = user.last_password_updated
@@ -1950,7 +1949,6 @@ class TestPasswordExpire(TestController):
 
 
 class TestCSRFProtection(TestController):
-
     def test_blocks_invalid(self):
         # so test-admin isn't automatically logged in for all requests
         self.app.extra_environ = {'disable_auth_magic': 'True'}
@@ -1980,4 +1978,3 @@ class TestCSRFProtection(TestController):
     def test_token_present_on_first_request(self):
         r = self.app.get('/auth/')
         assert_true(r.form['_session_id'].value)
-

http://git-wip-us.apache.org/repos/asf/allura/blob/9d39b9a7/Allura/allura/tests/functional/test_discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_discuss.py b/Allura/allura/tests/functional/test_discuss.py
index 21b5d3b..f5e5b05 100644
--- a/Allura/allura/tests/functional/test_discuss.py
+++ b/Allura/allura/tests/functional/test_discuss.py
@@ -69,9 +69,8 @@ class TestDiscuss(TestDiscussBase):
         params = dict()
         inputs = f.findAll('input')
         for field in inputs:
-            if field.has_key('name'):
-                params[field['name']] = field.has_key(
-                    'value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = text
         r = self.app.post(f['action'].encode('utf-8'), params=params,
                           headers={'Referer': thread_link.encode("utf-8")},
@@ -92,9 +91,8 @@ class TestDiscuss(TestDiscussBase):
         params = dict()
         inputs = post_form.findAll('input')
         for field in inputs:
-            if field.has_key('name'):
-                params[field['name']] = field.has_key(
-                    'value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params[post_form.find('textarea')['name']] = 'This is a new post'
         r = self.app.post(post_link,
                           params=params,
@@ -107,9 +105,8 @@ class TestDiscuss(TestDiscussBase):
         params = dict()
         inputs = post_form.findAll('input')
         for field in inputs:
-            if field.has_key('name'):
-                params[field['name']] = field.has_key(
-                    'value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params[post_form.find('textarea')['name']] = 'Tis a reply'
         r = self.app.post(post_link + 'reply',
                           params=params,
@@ -214,9 +211,8 @@ class TestDiscuss(TestDiscussBase):
         params = dict()
         inputs = reply_form.findAll('input')
         for field in inputs:
-            if field.has_key('name'):
-                params[field['name']] = field.has_key(
-                    'value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params[reply_form.find('textarea')['name']] = 'zzz'
         self.app.post(post_link, params)
         assert create_activity.call_count == 1, create_activity.call_count
@@ -252,9 +248,8 @@ class TestAttachment(TestDiscussBase):
         params = dict()
         inputs = f.findAll('input')
         for field in inputs:
-            if field.has_key('name'):
-                params[field['name']] = field.has_key(
-                    'value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = 'Test Post'
         r = self.app.post(f['action'].encode('utf-8'), params=params,
                           headers={'Referer': self.thread_link.encode('utf-8')})
@@ -292,9 +287,8 @@ class TestAttachment(TestDiscussBase):
         inputs = post_form.findAll('input')
 
         for field in inputs:
-            if field.has_key('name') and (field['name'] != 'file_info'):
-                params[field['name']] = field.has_key(
-                    'value') and field['value'] or ''
+            if field.has_key('name') and field['name'] != 'file_info':  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params[post_form.find('textarea')['name']] = 'Reply'
         r = self.app.post(self.post_link + 'reply',
                           params=params,

http://git-wip-us.apache.org/repos/asf/allura/blob/9d39b9a7/Allura/allura/tests/functional/test_neighborhood.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_neighborhood.py b/Allura/allura/tests/functional/test_neighborhood.py
index 9b8b215..13c2808 100644
--- a/Allura/allura/tests/functional/test_neighborhood.py
+++ b/Allura/allura/tests/functional/test_neighborhood.py
@@ -38,7 +38,6 @@ from alluratest.controller import setup_trove_categories
 
 
 class TestNeighborhood(TestController):
-
     def test_home_project(self):
         r = self.app.get('/adobe/wiki/')
         assert r.location.endswith('/adobe/wiki/Home/')
@@ -120,9 +119,9 @@ class TestNeighborhood(TestController):
 
     def test_prohibited_tools(self):
         self.app.post('/p/_admin/update',
-                          params=dict(name='Projects',
-                          prohibited_tools='wiki, tickets'),
-                          extra_environ=dict(username='root'))
+                      params=dict(name='Projects',
+                                  prohibited_tools='wiki, tickets'),
+                      extra_environ=dict(username='root'))
 
         r = self.app.get('/p/_admin/overview', extra_environ=dict(username='root'))
         assert 'wiki, tickets' in r
@@ -133,7 +132,7 @@ class TestNeighborhood(TestController):
 
         r = self.app.post('/p/_admin/update',
                           params=dict(name='Projects',
-                          prohibited_tools='wiki, test'),
+                                      prohibited_tools='wiki, test'),
                           extra_environ=dict(username='root'))
         assert 'error' in self.webflash(r), self.webflash(r)
 
@@ -361,8 +360,8 @@ class TestNeighborhood(TestController):
         assert '/*projecttitlecolor*/.project_title{color:green;}' in neighborhood.css
         assert '/*barontop*/.pad h2.colored {background-color:#555555; background-image: none;}' in neighborhood.css
         assert '/*titlebarbackground*/.pad h2.title{background-color:#333; background-image: none;}' in neighborhood.css
-        assert "/*titlebarcolor*/.pad h2.title, .pad h2.title small a {color:#444;} "\
-               ".pad h2.dark small b.ico {background-image: "\
+        assert "/*titlebarcolor*/.pad h2.title, .pad h2.title small a {color:#444;} " \
+               ".pad h2.dark small b.ico {background-image: " \
                "url('/nf/_ew_/theme/allura/images/neo-icon-set-ffffff-256x350.png');}" in neighborhood.css
 
     def test_max_projects(self):
@@ -647,8 +646,8 @@ class TestNeighborhood(TestController):
     def test_project_template(self):
         setup_trove_categories()
         icon_url = 'file://' + \
-            os.path.join(allura.__path__[0], 'nf', 'allura',
-                         'images', 'neo-icon-set-454545-256x350.png')
+                   os.path.join(allura.__path__[0], 'nf', 'allura',
+                                'images', 'neo-icon-set-454545-256x350.png')
         test_groups = [{
             "name": "Viewer",  # group will be created, all params are valid
             "permissions": ["read"],
@@ -670,7 +669,9 @@ class TestNeighborhood(TestController):
             "permissions": ["admin"]
         }]
         r = self.app.post('/adobe/_admin/update', params=dict(name='Mozq1',
-                                                              css='', homepage='# MozQ1!\n[Root]', project_template="""{
+                                                              css='',
+                                                              homepage='# MozQ1!\n[Root]',
+                                                              project_template="""{
                 "private":true,
                 "icon":{
                     "url":"%s",
@@ -717,22 +718,14 @@ class TestNeighborhood(TestController):
         p = M.Project.query.get(shortname='testtemp')
         # make sure the correct tools got installed in the right order
         top_nav = r.html.find('div', {'id': 'top_nav'})
-        assert top_nav.contents[1].contents[1].contents[
-            1]['href'] == '/adobe/testtemp/wiki/'
-        assert 'Wiki' in top_nav.contents[
-            1].contents[1].contents[1].contents[0]
-        assert top_nav.contents[1].contents[3].contents[
-            1]['href'] == '/adobe/testtemp/discussion/'
-        assert 'Discussion' in top_nav.contents[
-            1].contents[3].contents[1].contents[0]
-        assert top_nav.contents[1].contents[5].contents[
-            1]['href'] == '/adobe/testtemp/news/'
-        assert 'News' in top_nav.contents[
-            1].contents[5].contents[1].contents[0]
-        assert top_nav.contents[1].contents[7].contents[
-            1]['href'] == '/adobe/testtemp/admin/'
-        assert 'Admin' in top_nav.contents[
-            1].contents[7].contents[1].contents[0]
+        assert top_nav.contents[1].contents[1].contents[1]['href'] == '/adobe/testtemp/wiki/'
+        assert 'Wiki' in top_nav.contents[1].contents[1].contents[1].contents[0]
+        assert top_nav.contents[1].contents[3].contents[1]['href'] == '/adobe/testtemp/discussion/'
+        assert 'Discussion' in top_nav.contents[1].contents[3].contents[1].contents[0]
+        assert top_nav.contents[1].contents[5].contents[1]['href'] == '/adobe/testtemp/news/'
+        assert 'News' in top_nav.contents[1].contents[5].contents[1].contents[0]
+        assert top_nav.contents[1].contents[7].contents[1]['href'] == '/adobe/testtemp/admin/'
+        assert 'Admin' in top_nav.contents[1].contents[7].contents[1].contents[0]
         # make sure project is private
         r = self.app.get(
             '/adobe/testtemp/wiki/',
@@ -804,7 +797,7 @@ class TestNeighborhood(TestController):
                 },
                 "tool_order":["wiki","admin"],
 
-                }""" ),
+                }"""),
                           extra_environ=dict(username='root'))
         neighborhood = M.Neighborhood.query.get(name='Adobe')
         neighborhood.anchored_tools = 'wiki:Wiki'
@@ -835,7 +828,8 @@ class TestNeighborhood(TestController):
             r = self.app.get(
                 '/p/check_names?neighborhood=Projects&project_unixname=%s' % name)
             assert_equal(
-                r.json, {'project_unixname': 'Please use only small letters, numbers, and dashes 3-15 characters long.'})
+                r.json,
+                {'project_unixname': 'Please use only small letters, numbers, and dashes 3-15 characters long.'})
         r = self.app.get(
             '/p/check_names?neighborhood=Projects&project_unixname=mymoz')
         assert_equal(r.json, {})
@@ -895,8 +889,8 @@ class TestNeighborhood(TestController):
         image = PIL.Image.open(StringIO(r.body))
         assert image.size == (48, 48)
         self.app.post('/adobe/_admin/awards/grant',
-                params=dict(grant='FOO', recipient='adobe-1',
-                            url='http://award.org', comment='Winner!'),
+                      params=dict(grant='FOO', recipient='adobe-1',
+                                  url='http://award.org', comment='Winner!'),
                       extra_environ=dict(username='root'))
         r = self.app.get('/adobe/_admin/accolades',
                          extra_environ=dict(username='root'))
@@ -960,7 +954,6 @@ class TestNeighborhood(TestController):
 
 
 class TestPhoneVerificationOnProjectRegistration(TestController):
-
     def test_phone_verification_fragment_renders(self):
         self.app.get('/p/phone_verification_fragment', status=200)
         self.app.get('/adobe/phone_verification_fragment', status=200)

http://git-wip-us.apache.org/repos/asf/allura/blob/9d39b9a7/Allura/allura/tests/functional/test_rest.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_rest.py b/Allura/allura/tests/functional/test_rest.py
index 903cda7..1a2006d 100644
--- a/Allura/allura/tests/functional/test_rest.py
+++ b/Allura/allura/tests/functional/test_rest.py
@@ -249,9 +249,9 @@ class TestRestHome(TestRestApiBase):
         assert_equal(r.json['result'], False)
 
     def test_project_has_access_no_params(self):
-        r = self.api_get('/rest/p/test/has_access', status=404)
-        r = self.api_get('/rest/p/test/has_access?user=root', status=404)
-        r = self.api_get('/rest/p/test/has_access?perm=read', status=404)
+        self.api_get('/rest/p/test/has_access', status=404)
+        self.api_get('/rest/p/test/has_access?user=root', status=404)
+        self.api_get('/rest/p/test/has_access?perm=read', status=404)
 
     def test_project_has_access_unknown_params(self):
         """Unknown user and/or permission always False for has_access API"""

http://git-wip-us.apache.org/repos/asf/allura/blob/9d39b9a7/Allura/allura/tests/functional/test_user_profile.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_user_profile.py b/Allura/allura/tests/functional/test_user_profile.py
index 4425ace..14c28bf 100644
--- a/Allura/allura/tests/functional/test_user_profile.py
+++ b/Allura/allura/tests/functional/test_user_profile.py
@@ -194,9 +194,9 @@ class TestUserProfileHasAccessAPI(TestRestApiBase):
 
     @td.with_user_project('test-admin')
     def test_has_access_no_params(self):
-        r = self.api_get('/rest/u/test-admin/profile/has_access', status=404)
-        r = self.api_get('/rest/u/test-admin/profile/has_access?user=root', status=404)
-        r = self.api_get('/rest/u/test-admin/profile/has_access?perm=read', status=404)
+        self.api_get('/rest/u/test-admin/profile/has_access', status=404)
+        self.api_get('/rest/u/test-admin/profile/has_access?user=root', status=404)
+        self.api_get('/rest/u/test-admin/profile/has_access?perm=read', status=404)
 
     @td.with_user_project('test-admin')
     def test_has_access_unknown_params(self):

http://git-wip-us.apache.org/repos/asf/allura/blob/9d39b9a7/Allura/allura/tests/test_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_globals.py b/Allura/allura/tests/test_globals.py
index 0203969..bb5d80e 100644
--- a/Allura/allura/tests/test_globals.py
+++ b/Allura/allura/tests/test_globals.py
@@ -48,6 +48,7 @@ from allura.tests import decorators as td
 from forgewiki import model as WM
 from forgeblog import model as BM
 
+
 def squish_spaces(text):
     return re.sub(r'\s+', ' ', text)
 
@@ -171,7 +172,9 @@ def test_macro_gittip_button():
     with h.push_config(c, project=p_test):
         r = g.markdown_wiki.convert('[[gittip_button username=test]]')
     assert_equal(
-        r, u'<div class="markdown_content"><p><iframe height="22pt" src="https://www.gittip.com/test/widget.html" style="border: 0; margin: 0; padding: 0;" width="48pt"></iframe>\n</p></div>')
+        r,
+        u'<div class="markdown_content"><p><iframe height="22pt" src="https://www.gittip.com/test/widget.html" '
+        u'style="border: 0; margin: 0; padding: 0;" width="48pt"></iframe>\n</p></div>')
 
 
 def test_macro_neighborhood_feeds():
@@ -213,7 +216,7 @@ def test_macro_members():
     p_test.add_user(M.User.by_username('test-user'), ['Developer'])
     p_test.add_user(M.User.by_username('test-user-0'), ['Member'])
     ThreadLocalORMSession.flush_all()
-    r = g.markdown_wiki.convert('[[members limit=2]]').replace('\t','').replace('\n','')
+    r = g.markdown_wiki.convert('[[members limit=2]]').replace('\t', '').replace('\n', '')
     assert_equal(r,
                  '<div class="markdown_content"><h6>Project Members:</h6>'
                  '<ul class="md-users-list">'
@@ -258,7 +261,7 @@ def test_macro_project_admins_one_br():
     with h.push_config(c, project=p_test):
         r = g.markdown_wiki.convert('[[project_admins]]\n[[download_button]]')
 
-    assert not '</a><br/><br/><a href=' in r, r
+    assert '</a><br/><br/><a href=' not in r, r
     assert '</a></li><li><a href=' in r, r
 
 
@@ -293,6 +296,7 @@ def test_macro_include_no_extra_br():
 <p></p></div>'''
     assert_equal(squish_spaces(html), squish_spaces(expected_html))
 
+
 @with_setup(setUp, tearDown)
 @td.with_wiki
 @td.with_tool('test', 'Wiki', 'wiki2')
@@ -330,11 +334,13 @@ def test_macro_include_permissions():
 @patch('oembed.OEmbedEndpoint.fetch')
 def test_macro_embed(oembed_fetch):
     oembed_fetch.return_value = {
-        "html": '<iframe width="480" height="270" src="http://www.youtube.com/embed/kOLpSPEA72U?feature=oembed" frameborder="0" allowfullscreen></iframe>)',
+        "html": '<iframe width="480" height="270" src="http://www.youtube.com/embed/kOLpSPEA72U?feature=oembed" '
+                'frameborder="0" allowfullscreen></iframe>)',
         "title": "Nature's 3D Printer: MIND BLOWING Cocoon in Rainforest - Smarter Every Day 94",
     }
     r = g.markdown_wiki.convert('[[embed url=http://www.youtube.com/watch?v=kOLpSPEA72U]]')
-    assert_in('<div class="grid-20"><iframe height="270" src="https://www.youtube.com/embed/kOLpSPEA72U?feature=oembed" width="480"></iframe></div>',
+    assert_in('<div class="grid-20"><iframe height="270" '
+              'src="https://www.youtube.com/embed/kOLpSPEA72U?feature=oembed" width="480"></iframe></div>',
               r.replace('\n', ''))
 
 
@@ -484,13 +490,20 @@ def test_markdown_invalid_tagslash():
     r = g.markdown.convert('<div/onload><img src=x onerror=alert(document.cookie)>')
     assert_not_in('onerror', r)
 
+
 def test_markdown_invalid_script_in_link():
     r = g.markdown.convert('[xss](http://"><a onmouseover=prompt(document.domain)>xss</a>)')
-    assert_equal('''<div class="markdown_content"><p><a class="" href='http://"&gt;&lt;a%20onmouseover=prompt(document.domain)&gt;xss&lt;/a&gt;' rel="nofollow">xss</a></p></div>''', r)
+    assert_equal('<div class="markdown_content"><p><a class="" '
+                 '''href='http://"&gt;&lt;a%20onmouseover=prompt(document.domain)&gt;xss&lt;/a&gt;' '''
+                 'rel="nofollow">xss</a></p></div>', r)
+
 
 def test_markdown_invalid_script_in_link2():
     r = g.markdown.convert('[xss](http://"><img src=x onerror=alert(document.cookie)>)')
-    assert_equal('''<div class="markdown_content"><p><a class="" href='http://"&gt;&lt;img%20src=x%20onerror=alert(document.cookie)&gt;' rel="nofollow">xss</a></p></div>''', r)
+    assert_equal('<div class="markdown_content"><p><a class="" '
+                 '''href='http://"&gt;&lt;img%20src=x%20onerror=alert(document.cookie)&gt;' '''
+                 'rel="nofollow">xss</a></p></div>', r)
+
 
 @td.with_wiki
 def test_macro_include():
@@ -629,7 +642,8 @@ def test_hideawards_macro():
 
     with h.push_context(p_nbhd.neighborhood_project._id):
         r = g.markdown_wiki.convert('[[projects]]')
-        assert_in('<div class="feature"> <a href="http://award.org" rel="nofollow" title="Winner!">Award short</a> </div>',
+        assert_in('<div class="feature"> <a href="http://award.org" rel="nofollow" title="Winner!">'
+                  'Award short</a> </div>',
                   squish_spaces(r))
 
         r = g.markdown_wiki.convert('[[projects show_awards_banner=False]]')
@@ -642,7 +656,7 @@ def get_project_names(r):
     """
     # projects short names are in h2 elements without any attributes
     # there is one more h2 element, but it has `class` attribute
-    #re_proj_names = re.compile('<h2><a[^>]>(.+)<\/a><\/h2>')
+    # re_proj_names = re.compile('<h2><a[^>]>(.+)<\/a><\/h2>')
     re_proj_names = re.compile('<h2><a[^>]+>(.+)<\/a><\/h2>')
     return [e for e in re_proj_names.findall(r)]
 
@@ -754,8 +768,10 @@ class TestHandlePaging(unittest.TestCase):
     def setUp(self):
         prefs = {}
         c.user = Mock()
+
         def get_pref(name):
             return prefs.get(name)
+
         def set_pref(name, value):
             prefs[name] = value
         c.user.get_pref = get_pref

http://git-wip-us.apache.org/repos/asf/allura/blob/9d39b9a7/Allura/allura/tests/test_utils.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_utils.py b/Allura/allura/tests/test_utils.py
index dd67ded..413165a 100644
--- a/Allura/allura/tests/test_utils.py
+++ b/Allura/allura/tests/test_utils.py
@@ -22,7 +22,6 @@ import time
 import unittest
 import datetime as dt
 from ming.odm import session
-import model as M
 from os import path
 
 from webob import Request
@@ -169,12 +168,12 @@ class TestTruthyCallable(unittest.TestCase):
             return utils.TruthyCallable(predicate)
         true_predicate = wrapper_func(True)
         false_predicate = wrapper_func(False)
-        assert true_predicate(True) == True
-        assert false_predicate(False) == False
-        assert true_predicate() == True
-        assert false_predicate() == False
-        assert bool(true_predicate) == True
-        assert bool(false_predicate) == False
+        assert true_predicate(True) is True
+        assert false_predicate(False) is False
+        assert true_predicate() is True
+        assert false_predicate() is False
+        assert bool(true_predicate) is True
+        assert bool(false_predicate) is False
 
 
 class TestCaseInsensitiveDict(unittest.TestCase):
@@ -260,7 +259,8 @@ class TestHTMLSanitizer(unittest.TestCase):
         assert_equal(self.simple_tag_list(p), ['div', 'div'])
 
     def test_html_sanitizer_youtube_iframe(self):
-        p = utils.ForgeHTMLSanitizer('<div><iframe src="https://www.youtube.com/embed/kOLpSPEA72U?feature=oembed"></iframe></div>')
+        p = utils.ForgeHTMLSanitizer(
+            '<div><iframe src="https://www.youtube.com/embed/kOLpSPEA72U?feature=oembed"></iframe></div>')
         assert_equal(
             self.simple_tag_list(p), ['div', 'iframe', 'div'])
 
@@ -272,6 +272,7 @@ def test_ip_address():
     assert_equal(utils.ip_address(req),
                  '1.2.3.4')
 
+
 def test_ip_address_header():
     req = Mock()
     req.remote_addr = '1.2.3.4'
@@ -280,6 +281,7 @@ def test_ip_address_header():
         assert_equal(utils.ip_address(req),
                      '5.6.7.8')
 
+
 def test_ip_address_header_not_set():
     req = Mock()
     req.remote_addr = '1.2.3.4'
@@ -329,5 +331,5 @@ def test_phone_number_hash():
 
 def test_skip_mod_date():
     with utils.skip_mod_date(M.Artifact):
-        assert getattr(session(M.Artifact)._get(), 'skip_mod_date', None) == True
-    assert getattr(session(M.Artifact)._get(), 'skip_mod_date', None) == False
\ No newline at end of file
+        assert getattr(session(M.Artifact)._get(), 'skip_mod_date', None) is True
+    assert getattr(session(M.Artifact)._get(), 'skip_mod_date', None) is False

http://git-wip-us.apache.org/repos/asf/allura/blob/9d39b9a7/Allura/allura/websetup/bootstrap.py
----------------------------------------------------------------------
diff --git a/Allura/allura/websetup/bootstrap.py b/Allura/allura/websetup/bootstrap.py
index 33a3f3c..8bc04fe 100644
--- a/Allura/allura/websetup/bootstrap.py
+++ b/Allura/allura/websetup/bootstrap.py
@@ -22,7 +22,6 @@ import os
 import sys
 import logging
 import shutil
-from collections import defaultdict
 from textwrap import dedent
 
 import tg
@@ -110,7 +109,7 @@ def bootstrap(command, conf, vars):
     log.info('Initializing search')
 
     log.info('Registering root user & default neighborhoods')
-    anonymous = M.User(
+    M.User(
         _id=None,
         username='*anonymous',
         display_name='Anonymous')
@@ -172,7 +171,8 @@ def bootstrap(command, conf, vars):
         [[projects show_total=yes]]
         '''))
     set_nbhd_wiki_content(p_users, dedent('''
-        This is the "Users" neighborhood.  All users automatically get a user-project created for them, using their username.
+        This is the "Users" neighborhood.
+        All users automatically get a user-project created for them, using their username.
 
         [Neighborhood administration](/u/admin)
 
@@ -208,19 +208,19 @@ def bootstrap(command, conf, vars):
             make_user('Test User %d' % unum)
 
     log.info('Creating basic project categories')
-    cat1 = M.ProjectCategory(name='clustering', label='Clustering')
+    M.ProjectCategory(name='clustering', label='Clustering')
     cat2 = M.ProjectCategory(name='communications', label='Communications')
-    cat2_1 = M.ProjectCategory(
+    M.ProjectCategory(
         name='synchronization', label='Synchronization', parent_id=cat2._id)
-    cat2_2 = M.ProjectCategory(
+    M.ProjectCategory(
         name='streaming', label='Streaming', parent_id=cat2._id)
-    cat2_3 = M.ProjectCategory(name='fax', label='Fax', parent_id=cat2._id)
-    cat2_4 = M.ProjectCategory(name='bbs', label='BBS', parent_id=cat2._id)
+    M.ProjectCategory(name='fax', label='Fax', parent_id=cat2._id)
+    M.ProjectCategory(name='bbs', label='BBS', parent_id=cat2._id)
 
     cat3 = M.ProjectCategory(name='database', label='Database')
-    cat3_1 = M.ProjectCategory(
+    M.ProjectCategory(
         name='front_ends', label='Front-Ends', parent_id=cat3._id)
-    cat3_2 = M.ProjectCategory(
+    M.ProjectCategory(
         name='engines_servers', label='Engines/Servers', parent_id=cat3._id)
 
     if create_test_data:
@@ -244,12 +244,12 @@ def bootstrap(command, conf, vars):
             p_projects.add_user(u_admin, ['Admin'])
             p_users.add_user(u_admin, ['Admin'])
 
-            p_allura = n_projects.register_project('allura', u_admin, 'Allura')
-        u1 = make_user('Test User')
-        p_adobe1 = n_adobe.register_project('adobe-1', u_admin, 'Adobe project 1')
+            n_projects.register_project('allura', u_admin, 'Allura')
+        make_user('Test User')
+        n_adobe.register_project('adobe-1', u_admin, 'Adobe project 1')
         p_adobe.add_user(u_admin, ['Admin'])
         p0 = n_projects.register_project('test', u_admin, 'Test Project')
-        p1 = n_projects.register_project('test2', u_admin, 'Test 2')
+        n_projects.register_project('test2', u_admin, 'Test 2')
         p0._extra_tool_status = ['alpha', 'beta']
 
     sess = session(M.Neighborhood)  # all the sessions are the same
@@ -279,11 +279,11 @@ def bootstrap(command, conf, vars):
             log.info('Registering initial apps')
             with h.push_config(c, user=u_admin):
                 p0.install_apps([{'ep_name': ep_name}
-                    for ep_name, app in g.entry_points['tool'].iteritems()
-                    if app._installable(tool_name=ep_name,
-                                        nbhd=n_projects,
-                                        project_tools=[])
-                ])
+                                 for ep_name, app in g.entry_points['tool'].iteritems()
+                                 if app._installable(tool_name=ep_name,
+                                                     nbhd=n_projects,
+                                                     project_tools=[])
+                                 ])
 
     ThreadLocalORMSession.flush_all()
     ThreadLocalORMSession.close_all()


[09/50] [abbrv] allura git commit: [#7995] expose port 27017 for mongo access from host

Posted by je...@apache.org.
[#7995] expose port 27017 for mongo access from host


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/b036c1c9
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/b036c1c9
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/b036c1c9

Branch: refs/heads/ib/7924
Commit: b036c1c9f963c713183fe8de2d6c2959f0283cbe
Parents: 8142fb6
Author: Dave Brondsema <da...@brondsema.net>
Authored: Thu Sep 24 12:40:10 2015 -0400
Committer: Heith Seewald <hs...@hsmb.local>
Committed: Fri Sep 25 16:07:28 2015 -0500

----------------------------------------------------------------------
 Allura/docs/getting_started/installation.rst | 4 ++--
 docker-compose.yml                           | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/b036c1c9/Allura/docs/getting_started/installation.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/getting_started/installation.rst b/Allura/docs/getting_started/installation.rst
index 18a740e..203d6f5 100644
--- a/Allura/docs/getting_started/installation.rst
+++ b/Allura/docs/getting_started/installation.rst
@@ -264,7 +264,7 @@ Ports, exposed to host system
 - 8080 - webapp
 - 8983 - SOLR admin panel (http://localhost:8983/solr/)
 - 8825 - incoming mail listener
-
+- 27017 - mongodb
 
 First run
 ^^^^^^^^^
@@ -353,7 +353,7 @@ Running subset of tests:
 
     ~$ docker-compose run web bash -c 'cd ForgeGit && nosetests forgegit.tests.functional.test_controllers:TestFork'
 
-Connecting to mongo directly:
+Connecting to mongo using a container:
 
 .. code-block:: bash
 

http://git-wip-us.apache.org/repos/asf/allura/blob/b036c1c9/docker-compose.yml
----------------------------------------------------------------------
diff --git a/docker-compose.yml b/docker-compose.yml
index 3606980..155a421 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -58,8 +58,8 @@ solr:
 
 mongo:
   image: mongo:2.6
-  expose:
-    - "27017"
+  ports:
+    - "27017:27017"
   volumes:
     - /allura-data/mongo:/data/db
   command: mongod --smallfiles


[37/50] [abbrv] allura git commit: Update Ming and pymongo to latest version (pymongo >= 3 not yet supported by Ming)

Posted by je...@apache.org.
Update Ming and pymongo to latest version (pymongo >= 3 not yet supported by Ming)


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/bae38ad9
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/bae38ad9
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/bae38ad9

Branch: refs/heads/ib/7924
Commit: bae38ad961ed4126d2c67f91573099660a2a37e2
Parents: e97c5ff
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Wed Oct 14 21:38:29 2015 +0000
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Thu Oct 15 13:00:22 2015 +0000

----------------------------------------------------------------------
 requirements.txt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/bae38ad9/requirements.txt
----------------------------------------------------------------------
diff --git a/requirements.txt b/requirements.txt
index b2b6ea5..324fa33 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -21,7 +21,7 @@ httplib2==0.7.4
 iso8601==0.1.4
 Jinja2==2.6
 Markdown==2.2.0
-Ming==0.4.7
+Ming==0.5.2
 oauth2==1.5.170
 # tg2 dep PasteDeploy must specified before TurboGears2, to avoid a version/allow-hosts problem
 Paste==1.7.5.1
@@ -30,7 +30,7 @@ PasteScript==1.7.4.2
 Pillow==2.9.0
 poster==0.8.1
 Pygments==2.0.2
-pymongo==2.4.2
+pymongo==2.8.1
 Pypeline==0.2
 pysolr==2.1.0-beta
 python-dateutil==1.5


[25/50] [abbrv] allura git commit: [#7991] limit phone number usage to once

Posted by je...@apache.org.
[#7991] limit phone number usage to once


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/b79b8546
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/b79b8546
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/b79b8546

Branch: refs/heads/ib/7924
Commit: b79b854693f1aadebe408e7f95bad2a747cbf047
Parents: c8300e1
Author: Dave Brondsema <da...@brondsema.net>
Authored: Mon Oct 5 15:19:55 2015 -0400
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Mon Oct 5 15:38:26 2015 -0400

----------------------------------------------------------------------
 Allura/allura/lib/plugin.py                         |  7 ++++++-
 Allura/allura/tests/functional/test_neighborhood.py | 16 +++++++++++++++-
 2 files changed, 21 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/b79b8546/Allura/allura/lib/plugin.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/plugin.py b/Allura/allura/lib/plugin.py
index 2270dcb..46cd3e8 100644
--- a/Allura/allura/lib/plugin.py
+++ b/Allura/allura/lib/plugin.py
@@ -726,11 +726,16 @@ class ProjectRegistrationProvider(object):
             return True
         return bool(user.get_tool_data('phone_verification', 'number_hash'))
 
-    def verify_phone(self, user, number):
+    def verify_phone(self, user, number, allow_reuse=False):
+        from allura import model as M
         ok = {'status': 'ok'}
         if not asbool(config.get('project.verify_phone')):
             return ok
         number = utils.clean_phone_number(number)
+        number_hash = utils.phone_number_hash(number)
+        if not allow_reuse and M.User.query.find({'tool_data.phone_verification.number_hash': number_hash}).count():
+            return {'status': 'error',
+                    'error': 'That phone number has already been used.'}
         return g.phone_service.verify(number)
 
     def check_phone_verification(self, user, request_id, pin, number_hash):

http://git-wip-us.apache.org/repos/asf/allura/blob/b79b8546/Allura/allura/tests/functional/test_neighborhood.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_neighborhood.py b/Allura/allura/tests/functional/test_neighborhood.py
index 8b6a74f..9b8b215 100644
--- a/Allura/allura/tests/functional/test_neighborhood.py
+++ b/Allura/allura/tests/functional/test_neighborhood.py
@@ -24,7 +24,7 @@ import PIL
 from mock import patch
 from tg import config
 from nose.tools import assert_equal, assert_in, assert_not_equal
-from ming.orm.ormsession import ThreadLocalORMSession
+from ming.orm.ormsession import ThreadLocalORMSession, session
 from paste.httpexceptions import HTTPFound
 from pylons import app_globals as g
 
@@ -33,6 +33,7 @@ from allura import model as M
 from allura.tests import TestController
 from allura.tests import decorators as td
 from allura.lib import helpers as h
+from allura.lib import utils
 from alluratest.controller import setup_trove_categories
 
 
@@ -1006,6 +1007,19 @@ class TestPhoneVerificationOnProjectRegistration(TestController):
         }
         assert_equal(r.json, expected)
 
+    @patch.object(g, 'phone_service', autospec=True)
+    def test_verify_phone_already_used(self, phone_service):
+        with h.push_config(config, **{'project.verify_phone': 'true'}):
+            u = M.User.register(dict(username='existing-user'), make_project=False)
+            u.set_tool_data('phone_verification', number_hash=utils.phone_number_hash('1-555-444-9999'))
+            session(u).flush(u)
+            phone_service.verify.return_value = {'request_id': 'request-id', 'status': 'ok'}
+            r = self.app.get('/p/verify_phone', {'number': '1-555-444-9999'})
+            assert_equal(r.json, {
+                'status': 'error',
+                'error': u'That phone number has already been used.'
+            })
+
     def test_check_phone_verification_no_params(self):
         with h.push_config(config, **{'project.verify_phone': 'true'}):
             self.app.get('/p/check_phone_verification', status=404)


[05/50] [abbrv] allura git commit: Bump versions of Pillow and setproctitle (these will install without issue on osx)

Posted by je...@apache.org.
Bump versions of Pillow and setproctitle (these will install without issue on osx)


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/e9a4eea1
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/e9a4eea1
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/e9a4eea1

Branch: refs/heads/ib/7924
Commit: e9a4eea14e0166c3128b51e6a6c7cf3fa3a093c1
Parents: d2ebf89
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Wed Sep 23 21:46:54 2015 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Sep 23 21:46:54 2015 +0000

----------------------------------------------------------------------
 requirements.txt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/e9a4eea1/requirements.txt
----------------------------------------------------------------------
diff --git a/requirements.txt b/requirements.txt
index ee8b586..b2b6ea5 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -27,7 +27,7 @@ oauth2==1.5.170
 Paste==1.7.5.1
 PasteDeploy==1.5.0
 PasteScript==1.7.4.2
-Pillow==2.0.0
+Pillow==2.9.0
 poster==0.8.1
 Pygments==2.0.2
 pymongo==2.4.2
@@ -41,7 +41,7 @@ requests==2.0.0
 oauthlib==0.4.2
 requests-oauthlib==0.4.0
 # for taskd proc name switching
-setproctitle==1.1.7
+setproctitle==1.1.9
 six==1.7.3
 # dep of pypeline
 textile==2.1.5


[13/50] [abbrv] allura git commit: [#7990] change link

Posted by je...@apache.org.
[#7990] change link


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/79b2b98d
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/79b2b98d
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/79b2b98d

Branch: refs/heads/ib/7924
Commit: 79b2b98d1d5f4f17d972d1fe52dc9b2bf807100f
Parents: aa6e158
Author: Dave Brondsema <da...@brondsema.net>
Authored: Tue Sep 29 10:44:30 2015 -0400
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Tue Sep 29 10:44:30 2015 -0400

----------------------------------------------------------------------
 Allura/allura/templates/site_admin_new_projects.html | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/79b2b98d/Allura/allura/templates/site_admin_new_projects.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/site_admin_new_projects.html b/Allura/allura/templates/site_admin_new_projects.html
index 81902d6..9013c5d 100644
--- a/Allura/allura/templates/site_admin_new_projects.html
+++ b/Allura/allura/templates/site_admin_new_projects.html
@@ -66,7 +66,7 @@
       <td><small>{{ p.short_description|truncate(100) }}</small></td>
       <td><small>{{ p.summary }}</small></td>
       <td><small>{{ p.external_homepage|urlize(22) }}</small></td>
-      <td>{% for a in p.admins() %}<small><a href="{{ a.url() }}">{{ a.username }}</a></small> {% endfor %}</td>
+      <td>{% for a in p.admins() %}<small><a href="/nf/admin/user/{{ a.username }}">{{ a.username }}</a></small> {% endfor %}</td>
     </tr>
     {% endfor %}
   </table>


[30/50] [abbrv] allura git commit: [#7980] don't time a removed and unused function

Posted by je...@apache.org.
[#7980] don't time a removed and unused function


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/2bdcb95a
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/2bdcb95a
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/2bdcb95a

Branch: refs/heads/ib/7924
Commit: 2bdcb95a3d8138cf6e917e78ec7ca069ce03b713
Parents: e5023ae
Author: Dave Brondsema <da...@brondsema.net>
Authored: Thu Oct 1 10:33:34 2015 -0400
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Tue Oct 6 10:34:04 2015 +0000

----------------------------------------------------------------------
 Allura/allura/lib/custom_middleware.py | 1 -
 1 file changed, 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/2bdcb95a/Allura/allura/lib/custom_middleware.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/custom_middleware.py b/Allura/allura/lib/custom_middleware.py
index 1938e51..fce19e5 100644
--- a/Allura/allura/lib/custom_middleware.py
+++ b/Allura/allura/lib/custom_middleware.py
@@ -322,7 +322,6 @@ class AlluraTimerMiddleware(TimerMiddleware):
             Timer('urlopen', urllib2, 'urlopen'),
             Timer('base_repo_tool.{method_name}',
                   allura.model.repository.RepositoryImplementation, 'last_commit_ids'),
-            Timer('unified_diff', allura.model.repository, 'unified_diff'),
         ] + [Timer('sidebar', ep.load(), 'sidebar_menu') for ep in tool_entry_points]
 
         try:


[12/50] [abbrv] allura git commit: Fix JS issue with subscriptions. Blog post subscribe action to say "post".

Posted by je...@apache.org.
Fix JS issue with subscriptions. Blog post subscribe action to say "post".

Don't include subscriptions.js which needs react.js, when logged out. The
subscription widget only is meant for logged-in users.  And the template
which includes react.js is only included when logged in already.


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/bcf93e11
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/bcf93e11
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/bcf93e11

Branch: refs/heads/ib/7924
Commit: bcf93e117a175c2fde54175df38defabee23fe2a
Parents: aa6e158
Author: Dave Brondsema <da...@brondsema.net>
Authored: Mon Sep 28 17:52:00 2015 -0400
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Mon Sep 28 17:52:00 2015 -0400

----------------------------------------------------------------------
 Allura/allura/lib/widgets/subscriptions.py   | 4 +++-
 ForgeBlog/forgeblog/main.py                  | 2 +-
 ForgeBlog/forgeblog/templates/blog/post.html | 4 +++-
 3 files changed, 7 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/bcf93e11/Allura/allura/lib/widgets/subscriptions.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/subscriptions.py b/Allura/allura/lib/widgets/subscriptions.py
index c8d3dcd..4e3324a 100644
--- a/Allura/allura/lib/widgets/subscriptions.py
+++ b/Allura/allura/lib/widgets/subscriptions.py
@@ -17,6 +17,7 @@
 
 import ew as ew_core
 import ew.jinja2_ew as ew
+from pylons import tmpl_context as c
 
 from allura.lib import validators as V
 from allura.lib.widgets import form_fields as ffw
@@ -90,4 +91,5 @@ class SubscribeForm(ew.SimpleForm):
     def resources(self):
         for r in super(SubscribeForm, self).resources():
             yield r
-        yield ew.JSLink('js/subscriptions.js')
+        if not c.user.is_anonymous():
+            yield ew.JSLink('js/subscriptions.js')

http://git-wip-us.apache.org/repos/asf/allura/blob/bcf93e11/ForgeBlog/forgeblog/main.py
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/main.py b/ForgeBlog/forgeblog/main.py
index b4f4641..a3483cf 100644
--- a/ForgeBlog/forgeblog/main.py
+++ b/ForgeBlog/forgeblog/main.py
@@ -70,7 +70,7 @@ class W:
     attachment_add = ffw.AttachmentAdd()
     attachment_list = ffw.AttachmentList()
     preview_post_form = widgets.PreviewPostForm()
-    subscribe_form = SubscribeForm()
+    subscribe_form = SubscribeForm(thing='post')
     search_results = SearchResults()
     help_modal = SearchHelp()
 

http://git-wip-us.apache.org/repos/asf/allura/blob/bcf93e11/ForgeBlog/forgeblog/templates/blog/post.html
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/templates/blog/post.html b/ForgeBlog/forgeblog/templates/blog/post.html
index c0caad3..d0a3434 100644
--- a/ForgeBlog/forgeblog/templates/blog/post.html
+++ b/ForgeBlog/forgeblog/templates/blog/post.html
@@ -27,7 +27,9 @@
     <a href="edit" title="Edit"><b data-icon="{{g.icons['pencil'].char}}" class="ico {{g.icons['pencil'].css}}"></b></a>
   {% endif %}
   <a href="history" title="History"><b data-icon="{{g.icons['history'].char}}" class="ico {{g.icons['history'].css}}"></b></a>
-  {{c.subscribe_form.display(value=subscribed, action='subscribe', style='icon')}}
+  {% if c.user and c.user != c.user.anonymous() %}
+    {{c.subscribe_form.display(value=subscribed, action='subscribe', style='icon')}}
+  {% endif %}
   <a href="feed" title="RSS"><b data-icon="{{g.icons['feed'].char}}" class="ico {{g.icons['feed'].css}}"></b></a>
 {% endblock %}
 


[48/50] [abbrv] allura git commit: [#7924] ticket:837 Add expand/resore icons back

Posted by je...@apache.org.
[#7924] ticket:837 Add expand/resore icons back


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/4dae87ef
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/4dae87ef
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/4dae87ef

Branch: refs/heads/ib/7924
Commit: 4dae87efae6b2bcaafc68de21693a51dde3af4e7
Parents: 4e37a23
Author: Igor Bondarenko <je...@gmail.com>
Authored: Thu Oct 15 15:57:27 2015 +0000
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Thu Oct 15 15:57:27 2015 +0000

----------------------------------------------------------------------
 Allura/allura/lib/app_globals.py              | 2 ++
 Allura/allura/templates/jinja_master/lib.html | 8 ++------
 2 files changed, 4 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/4dae87ef/Allura/allura/lib/app_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/app_globals.py b/Allura/allura/lib/app_globals.py
index faf82b4..ff5ecdb 100644
--- a/Allura/allura/lib/app_globals.py
+++ b/Allura/allura/lib/app_globals.py
@@ -253,6 +253,8 @@ class Globals(object):
             secure=Icon('fa fa-lock', 'Lock'),
             unsecure=Icon('fa fa-unlock', 'Unlock'),
             star=Icon('fa fa-star', 'Star'),
+            expand=Icon('fa fa-expand', 'Maximize'),
+            restore=Icon('fa fa-compress', 'Restore'),
             # Permissions
             perm_read=Icon('fa fa-eye', 'Read'),
             perm_update=Icon('fa fa-rotate-left', 'Update'),

http://git-wip-us.apache.org/repos/asf/allura/blob/4dae87ef/Allura/allura/templates/jinja_master/lib.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/jinja_master/lib.html b/Allura/allura/templates/jinja_master/lib.html
index 83ea02e..e427279 100644
--- a/Allura/allura/templates/jinja_master/lib.html
+++ b/Allura/allura/templates/jinja_master/lib.html
@@ -196,12 +196,8 @@
 
 {%- macro maximize_content_button() %}
     {% do g.register_forge_js('js/maximize-content.js') %}
-    <a id="maximize-content" href="#">
-      <b data-icon="{{g.icons.expand.char}}" class="ico {{g.icons.expand.css}}" title="Maximize"> </b> Maximize
-    </a>
-    <a id="restore-content" href="#">
-      <b data-icon="{{g.icons.restore.char}}" class="ico {{g.icons.restore.css}}" title="Restore"> </b> Restore
-    </a>
+    {{ g.icons['expand'].render(show_title=True, id='maximize-content') }}
+    {{ g.icons['restore'].render(show_title=True, id='restore-content') }}
 {%- endmacro %}
 
 


[29/50] [abbrv] allura git commit: [#7980] set default line length settings for pep8 & flake8

Posted by je...@apache.org.
[#7980] set default line length settings for pep8 & flake8


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/e5023ae1
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/e5023ae1
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/e5023ae1

Branch: refs/heads/ib/7924
Commit: e5023ae108f85207176e64c47b1dff3784dbe222
Parents: 9d39b9a
Author: Dave Brondsema <da...@brondsema.net>
Authored: Wed Sep 30 10:53:49 2015 -0400
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Tue Oct 6 10:34:03 2015 +0000

----------------------------------------------------------------------
 ForgeActivity/setup.cfg   |  6 ++++++
 ForgeBlog/setup.cfg       |  6 ++++++
 ForgeChat/setup.cfg       |  6 ++++++
 ForgeDiscussion/setup.cfg |  6 ++++++
 ForgeGit/setup.cfg        |  6 ++++++
 ForgeLink/setup.cfg       |  6 ++++++
 ForgeSVN/setup.cfg        |  6 ++++++
 ForgeTracker/setup.cfg    |  6 ++++++
 ForgeWiki/setup.cfg       |  6 ++++++
 setup.cfg                 | 22 ++++++++++++++++++++++
 10 files changed, 76 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/e5023ae1/ForgeActivity/setup.cfg
----------------------------------------------------------------------
diff --git a/ForgeActivity/setup.cfg b/ForgeActivity/setup.cfg
index 2637327..f054a10 100644
--- a/ForgeActivity/setup.cfg
+++ b/ForgeActivity/setup.cfg
@@ -1,2 +1,8 @@
+[pep8]
+max-line-length = 119
+
+[flake8]
+max-line-length = 119
+
 [egg_info]
 tag_build = dev0

http://git-wip-us.apache.org/repos/asf/allura/blob/e5023ae1/ForgeBlog/setup.cfg
----------------------------------------------------------------------
diff --git a/ForgeBlog/setup.cfg b/ForgeBlog/setup.cfg
index 2637327..f054a10 100644
--- a/ForgeBlog/setup.cfg
+++ b/ForgeBlog/setup.cfg
@@ -1,2 +1,8 @@
+[pep8]
+max-line-length = 119
+
+[flake8]
+max-line-length = 119
+
 [egg_info]
 tag_build = dev0

http://git-wip-us.apache.org/repos/asf/allura/blob/e5023ae1/ForgeChat/setup.cfg
----------------------------------------------------------------------
diff --git a/ForgeChat/setup.cfg b/ForgeChat/setup.cfg
index 2637327..f054a10 100644
--- a/ForgeChat/setup.cfg
+++ b/ForgeChat/setup.cfg
@@ -1,2 +1,8 @@
+[pep8]
+max-line-length = 119
+
+[flake8]
+max-line-length = 119
+
 [egg_info]
 tag_build = dev0

http://git-wip-us.apache.org/repos/asf/allura/blob/e5023ae1/ForgeDiscussion/setup.cfg
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/setup.cfg b/ForgeDiscussion/setup.cfg
index 2637327..f054a10 100644
--- a/ForgeDiscussion/setup.cfg
+++ b/ForgeDiscussion/setup.cfg
@@ -1,2 +1,8 @@
+[pep8]
+max-line-length = 119
+
+[flake8]
+max-line-length = 119
+
 [egg_info]
 tag_build = dev0

http://git-wip-us.apache.org/repos/asf/allura/blob/e5023ae1/ForgeGit/setup.cfg
----------------------------------------------------------------------
diff --git a/ForgeGit/setup.cfg b/ForgeGit/setup.cfg
index 2637327..f054a10 100644
--- a/ForgeGit/setup.cfg
+++ b/ForgeGit/setup.cfg
@@ -1,2 +1,8 @@
+[pep8]
+max-line-length = 119
+
+[flake8]
+max-line-length = 119
+
 [egg_info]
 tag_build = dev0

http://git-wip-us.apache.org/repos/asf/allura/blob/e5023ae1/ForgeLink/setup.cfg
----------------------------------------------------------------------
diff --git a/ForgeLink/setup.cfg b/ForgeLink/setup.cfg
index 2637327..f054a10 100644
--- a/ForgeLink/setup.cfg
+++ b/ForgeLink/setup.cfg
@@ -1,2 +1,8 @@
+[pep8]
+max-line-length = 119
+
+[flake8]
+max-line-length = 119
+
 [egg_info]
 tag_build = dev0

http://git-wip-us.apache.org/repos/asf/allura/blob/e5023ae1/ForgeSVN/setup.cfg
----------------------------------------------------------------------
diff --git a/ForgeSVN/setup.cfg b/ForgeSVN/setup.cfg
index 2637327..f054a10 100644
--- a/ForgeSVN/setup.cfg
+++ b/ForgeSVN/setup.cfg
@@ -1,2 +1,8 @@
+[pep8]
+max-line-length = 119
+
+[flake8]
+max-line-length = 119
+
 [egg_info]
 tag_build = dev0

http://git-wip-us.apache.org/repos/asf/allura/blob/e5023ae1/ForgeTracker/setup.cfg
----------------------------------------------------------------------
diff --git a/ForgeTracker/setup.cfg b/ForgeTracker/setup.cfg
index 2637327..f054a10 100644
--- a/ForgeTracker/setup.cfg
+++ b/ForgeTracker/setup.cfg
@@ -1,2 +1,8 @@
+[pep8]
+max-line-length = 119
+
+[flake8]
+max-line-length = 119
+
 [egg_info]
 tag_build = dev0

http://git-wip-us.apache.org/repos/asf/allura/blob/e5023ae1/ForgeWiki/setup.cfg
----------------------------------------------------------------------
diff --git a/ForgeWiki/setup.cfg b/ForgeWiki/setup.cfg
index 2637327..f054a10 100644
--- a/ForgeWiki/setup.cfg
+++ b/ForgeWiki/setup.cfg
@@ -1,2 +1,8 @@
+[pep8]
+max-line-length = 119
+
+[flake8]
+max-line-length = 119
+
 [egg_info]
 tag_build = dev0

http://git-wip-us.apache.org/repos/asf/allura/blob/e5023ae1/setup.cfg
----------------------------------------------------------------------
diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 0000000..1ba576a
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,22 @@
+#       Licensed to the Apache Software Foundation (ASF) under one
+#       or more contributor license agreements.  See the NOTICE file
+#       distributed with this work for additional information
+#       regarding copyright ownership.  The ASF licenses this file
+#       to you under the Apache License, Version 2.0 (the
+#       "License"); you may not use this file except in compliance
+#       with the License.  You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#       Unless required by applicable law or agreed to in writing,
+#       software distributed under the License is distributed on an
+#       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#       KIND, either express or implied.  See the License for the
+#       specific language governing permissions and limitations
+#       under the License.
+
+[pep8]
+max-line-length = 119
+
+[flake8]
+max-line-length = 119


[10/50] [abbrv] allura git commit: [#7946] ticket:846 Don't insert redundant csrf input in admin modals

Posted by je...@apache.org.
[#7946] ticket:846 Don't insert redundant csrf input in admin modals


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/aa6e158b
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/aa6e158b
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/aa6e158b

Branch: refs/heads/ib/7924
Commit: aa6e158b6443d7e59ee69c4fc2b3b6305afac5d0
Parents: 367525f
Author: Igor Bondarenko <je...@gmail.com>
Authored: Tue Sep 22 16:23:08 2015 +0300
Committer: Heith Seewald <hs...@hsmb.local>
Committed: Mon Sep 28 14:33:47 2015 -0400

----------------------------------------------------------------------
 Allura/allura/lib/widgets/resources/js/admin_modal.js | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/aa6e158b/Allura/allura/lib/widgets/resources/js/admin_modal.js
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/resources/js/admin_modal.js b/Allura/allura/lib/widgets/resources/js/admin_modal.js
index 41a5264..b1a521d 100644
--- a/Allura/allura/lib/widgets/resources/js/admin_modal.js
+++ b/Allura/allura/lib/widgets/resources/js/admin_modal.js
@@ -17,8 +17,6 @@
        under the License.
 */
 $(function() {
-    var cval = $.cookie('_session_id');
-    var csrf_input = $('<input name="_session_id" type="hidden" value="'+cval+'">');
     var $popup_title = $('#admin_modal_title');
     var $popup_contents = $('#admin_modal_contents');
     $('a.admin_modal').click(function () {
@@ -28,7 +26,12 @@ $(function() {
         $.get(link.href, function (data) {
             $popup_title.html($(link).html());
             $popup_contents.html(data);
-            $popup_contents.find('form').append(csrf_input);
+            var csrf_exists = $popup_contents.find('form > input[name="_session_id"]').length;
+            if (!csrf_exists) {
+              var cval = $.cookie('_session_id');
+              var csrf_input = $('<input name="_session_id" type="hidden" value="'+cval+'">');
+              $popup_contents.find('form').append(csrf_input);
+            }
         });
     });
 });


[32/50] [abbrv] allura git commit: Merge remote-tracking branch 'dave/fix_subscribe_errors'

Posted by je...@apache.org.
Merge remote-tracking branch 'dave/fix_subscribe_errors'


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/77c45dac
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/77c45dac
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/77c45dac

Branch: refs/heads/ib/7924
Commit: 77c45dacd1096fcc679d9d5693ca629e689a1e81
Parents: 93be151 bcf93e1
Author: Heith Seewald <hs...@hsmb.local>
Authored: Tue Oct 13 14:47:56 2015 -0400
Committer: Heith Seewald <hs...@hsmb.local>
Committed: Tue Oct 13 14:47:56 2015 -0400

----------------------------------------------------------------------
 Allura/allura/lib/widgets/subscriptions.py   | 4 +++-
 ForgeBlog/forgeblog/main.py                  | 2 +-
 ForgeBlog/forgeblog/templates/blog/post.html | 4 +++-
 3 files changed, 7 insertions(+), 3 deletions(-)
----------------------------------------------------------------------



[40/50] [abbrv] allura git commit: [#7924] ticket:830 Update Font Awesome to include new icons

Posted by je...@apache.org.
[#7924] ticket:830 Update Font Awesome to include new icons


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/47743877
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/47743877
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/47743877

Branch: refs/heads/ib/7924
Commit: 477438772ca3c6ea26ca7e6ed0aaf4016ebccf32
Parents: bae38ad
Author: Igor Bondarenko <je...@gmail.com>
Authored: Fri Aug 7 18:02:03 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Thu Oct 15 15:03:38 2015 +0000

----------------------------------------------------------------------
 .../allura/public/nf/css/font-awesome.min.css   |   4 +-
 Allura/allura/public/nf/fonts/FontAwesome.otf   | Bin 93888 -> 106260 bytes
 .../public/nf/fonts/fontawesome-webfont.eot     | Bin 60767 -> 68875 bytes
 .../public/nf/fonts/fontawesome-webfont.svg     | 105 ++++++++++++++++---
 .../public/nf/fonts/fontawesome-webfont.ttf     | Bin 122092 -> 138204 bytes
 .../public/nf/fonts/fontawesome-webfont.woff    | Bin 71508 -> 81284 bytes
 .../public/nf/fonts/fontawesome-webfont.woff2   | Bin 56780 -> 64464 bytes
 7 files changed, 92 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/47743877/Allura/allura/public/nf/css/font-awesome.min.css
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/css/font-awesome.min.css b/Allura/allura/public/nf/css/font-awesome.min.css
index 24fcc04..ee4e978 100644
--- a/Allura/allura/public/nf/css/font-awesome.min.css
+++ b/Allura/allura/public/nf/css/font-awesome.min.css
@@ -1,4 +1,4 @@
 /*!
- *  Font Awesome 4.3.0 by @davegandy - http://fontawesome.io - @fontawesome
+ *  Font Awesome 4.4.0 by @davegandy - http://fontawesome.io - @fontawesome
  *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
- */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.3.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.3.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.3.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.3.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.3.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.3.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;transform:translate(0, 0)}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{p
 osition:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Micr
 osoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size
 :2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o
 -up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:
 "\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}
 .fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-sl
 ash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:be
 fore{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-h
 and-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-
 underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-
 flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content
 :"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content
 :"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-c
 ircle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{conten
 t:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:bef
 ore{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-arc
 hive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{c
 ontent:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{cont
 ent:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:
 "\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-genderless:before,.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:
 "\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"
 \f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"
 }.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}
\ No newline at end of file
+ */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.4.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.4.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.4.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.4.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.4.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.4.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.1
 4285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-tr
 ansform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:abso
 lute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-d
 ownload:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-lef
 t:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:
 before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:
 before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f0
 87"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-
 o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa
 -list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-t
 achometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-dou
 ble-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content
 :"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f1
 36"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:be
 fore,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:be
 fore{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:befor
 e,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mo
 rtar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{conten
 t:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before
 ,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content
 :"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{conte
 nt:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:be
 fore{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:bef
 ore{content:"\f23e"}.fa-battery-4:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254
 "}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-50
 0px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}

http://git-wip-us.apache.org/repos/asf/allura/blob/47743877/Allura/allura/public/nf/fonts/FontAwesome.otf
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/fonts/FontAwesome.otf b/Allura/allura/public/nf/fonts/FontAwesome.otf
index f7936cc..681bdd4 100644
Binary files a/Allura/allura/public/nf/fonts/FontAwesome.otf and b/Allura/allura/public/nf/fonts/FontAwesome.otf differ

http://git-wip-us.apache.org/repos/asf/allura/blob/47743877/Allura/allura/public/nf/fonts/fontawesome-webfont.eot
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/fonts/fontawesome-webfont.eot b/Allura/allura/public/nf/fonts/fontawesome-webfont.eot
index 33b2bb8..a30335d 100644
Binary files a/Allura/allura/public/nf/fonts/fontawesome-webfont.eot and b/Allura/allura/public/nf/fonts/fontawesome-webfont.eot differ


[39/50] [abbrv] allura git commit: [#7924] ticket:830 Update Font Awesome to include new icons

Posted by je...@apache.org.
http://git-wip-us.apache.org/repos/asf/allura/blob/47743877/Allura/allura/public/nf/fonts/fontawesome-webfont.svg
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/fonts/fontawesome-webfont.svg b/Allura/allura/public/nf/fonts/fontawesome-webfont.svg
index 1ee89d4..6fd19ab 100644
--- a/Allura/allura/public/nf/fonts/fontawesome-webfont.svg
+++ b/Allura/allura/public/nf/fonts/fontawesome-webfont.svg
@@ -399,7 +399,7 @@
 <glyph unicode="&#xf191;" d="M1024 960v-640q0 -26 -19 -45t-45 -19q-20 0 -37 12l-448 320q-27 19 -27 52t27 52l448 320q17 12 37 12q26 0 45 -19t19 -45zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5z M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
 <glyph unicode="&#xf192;" d="M1024 640q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5 t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
 <glyph unicode="&#xf193;" horiz-adv-x="1664" d="M1023 349l102 -204q-58 -179 -210 -290t-339 -111q-156 0 -288.5 77.5t-210 210t-77.5 288.5q0 181 104.5 330t274.5 211l17 -131q-122 -54 -195 -165.5t-73 -244.5q0 -185 131.5 -316.5t316.5 -131.5q126 0 232.5 65t165 175.5t49.5 236.5zM1571 249l58 -114l-256 -128 q-13 -7 -29 -7q-40 0 -57 35l-239 477h-472q-24 0 -42.5 16.5t-21.5 40.5l-96 779q-2 16 6 42q14 51 57 82.5t97 31.5q66 0 113 -47t47 -113q0 -69 -52 -117.5t-120 -41.5l37 -289h423v-128h-407l16 -128h455q40 0 57 -35l228 -455z" />
-<glyph unicode="&#xf194;" d="M1254 899q16 85 -21 132q-52 65 -187 45q-17 -3 -41 -12.5t-57.5 -30.5t-64.5 -48.5t-59.5 -70t-44.5 -91.5q80 7 113.5 -16t26.5 -99q-5 -52 -52 -143q-43 -78 -71 -99q-44 -32 -87 14q-23 24 -37.5 64.5t-19 73t-10 84t-8.5 71.5q-23 129 -34 164q-12 37 -35.5 69 t-50.5 40q-57 16 -127 -25q-54 -32 -136.5 -106t-122.5 -102v-7q16 -8 25.5 -26t21.5 -20q21 -3 54.5 8.5t58 10.5t41.5 -30q11 -18 18.5 -38.5t15 -48t12.5 -40.5q17 -46 53 -187q36 -146 57 -197q42 -99 103 -125q43 -12 85 -1.5t76 31.5q131 77 250 237 q104 139 172.5 292.5t82.5 226.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+<glyph unicode="&#xf194;" d="M1292 898q10 216 -161 222q-231 8 -312 -261q44 19 82 19q85 0 74 -96q-4 -57 -74 -167t-105 -110q-43 0 -82 169q-13 54 -45 255q-30 189 -160 177q-59 -7 -164 -100l-81 -72l-81 -72l52 -67q76 52 87 52q57 0 107 -179q15 -55 45 -164.5t45 -164.5q68 -179 164 -179 q157 0 383 294q220 283 226 444zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
 <glyph unicode="&#xf195;" horiz-adv-x="1152" d="M1152 704q0 -191 -94.5 -353t-256.5 -256.5t-353 -94.5h-160q-14 0 -23 9t-9 23v611l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26v128q0 23 23 31l233 71v93l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26v128q0 23 23 31l233 71v250q0 14 9 23t23 9h160 q14 0 23 -9t9 -23v-181l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31l-393 -121v-93l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31l-393 -121v-487q188 13 318 151t130 328q0 14 9 23t23 9h160q14 0 23 -9t9 -23z" />
 <glyph unicode="&#xf196;" horiz-adv-x="1408" d="M1152 736v-64q0 -14 -9 -23t-23 -9h-352v-352q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v352h-352q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h352v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-352h352q14 0 23 -9t9 -23zM1280 288v832q0 66 -47 113t-113 47h-832 q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113zM1408 1120v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5z" />
 <glyph unicode="&#xf197;" horiz-adv-x="2176" d="M620 416q-110 -64 -268 -64h-128v64h-64q-13 0 -22.5 23.5t-9.5 56.5q0 24 7 49q-58 2 -96.5 10.5t-38.5 20.5t38.5 20.5t96.5 10.5q-7 25 -7 49q0 33 9.5 56.5t22.5 23.5h64v64h128q158 0 268 -64h1113q42 -7 106.5 -18t80.5 -14q89 -15 150 -40.5t83.5 -47.5t22.5 -40 t-22.5 -40t-83.5 -47.5t-150 -40.5q-16 -3 -80.5 -14t-106.5 -18h-1113zM1739 668q53 -36 53 -92t-53 -92l81 -30q68 48 68 122t-68 122zM625 400h1015q-217 -38 -456 -80q-57 0 -113 -24t-83 -48l-28 -24l-288 -288q-26 -26 -70.5 -45t-89.5 -19h-96l-93 464h29 q157 0 273 64zM352 816h-29l93 464h96q46 0 90 -19t70 -45l288 -288q4 -4 11 -10.5t30.5 -23t48.5 -29t61.5 -23t72.5 -10.5l456 -80h-1015q-116 64 -273 64z" />
@@ -411,8 +411,8 @@
 <glyph unicode="&#xf19d;" horiz-adv-x="2304" d="M1774 700l18 -316q4 -69 -82 -128t-235 -93.5t-323 -34.5t-323 34.5t-235 93.5t-82 128l18 316l574 -181q22 -7 48 -7t48 7zM2304 1024q0 -23 -22 -31l-1120 -352q-4 -1 -10 -1t-10 1l-652 206q-43 -34 -71 -111.5t-34 -178.5q63 -36 63 -109q0 -69 -58 -107l58 -433 q2 -14 -8 -25q-9 -11 -24 -11h-192q-15 0 -24 11q-10 11 -8 25l58 433q-58 38 -58 107q0 73 65 111q11 207 98 330l-333 104q-22 8 -22 31t22 31l1120 352q4 1 10 1t10 -1l1120 -352q22 -8 22 -31z" />
 <glyph unicode="&#xf19e;" d="M859 579l13 -707q-62 11 -105 11q-41 0 -105 -11l13 707q-40 69 -168.5 295.5t-216.5 374.5t-181 287q58 -15 108 -15q43 0 111 15q63 -111 133.5 -229.5t167 -276.5t138.5 -227q37 61 109.5 177.5t117.5 190t105 176t107 189.5q54 -14 107 -14q56 0 114 14v0 q-28 -39 -60 -88.5t-49.5 -78.5t-56.5 -96t-49 -84q-146 -248 -353 -610z" />
 <glyph unicode="&#xf1a0;" horiz-adv-x="1280" d="M981 197q0 25 -7 49t-14.5 42t-27 41.5t-29.5 35t-38.5 34.5t-36.5 29t-41.5 30t-36.5 26q-16 2 -49 2q-53 0 -104.5 -7t-107 -25t-97 -46t-68.5 -74.5t-27 -105.5q0 -56 23.5 -102t61 -75.5t87 -50t100 -29t101.5 -8.5q58 0 111.5 13t99 39t73 73t27.5 109zM864 1055 q0 59 -17 125.5t-48 129t-84 103.5t-117 41q-42 0 -82.5 -19.5t-66.5 -52.5q-46 -59 -46 -160q0 -46 10 -97.5t31.5 -103t52 -92.5t75 -67t96.5 -26q37 0 77.5 16.5t65.5 43.5q53 56 53 159zM752 1536h417l-137 -88h-132q75 -63 113 -133t38 -160q0 -72 -24.5 -129.5 t-59.5 -93t-69.5 -65t-59 -61.5t-24.5 -66q0 -36 32 -70.5t77 -68t90.5 -73.5t77.5 -104t32 -142q0 -91 -49 -173q-71 -122 -209.5 -179.5t-298.5 -57.5q-132 0 -246.5 41.5t-172.5 137.5q-36 59 -36 131q0 81 44.5 150t118.5 115q131 82 404 100q-32 41 -47.5 73.5 t-15.5 73.5q0 40 21 85q-46 -4 -68 -4q-148 0 -249.5 96.5t-101.5 244.5q0 82 36 159t99 131q76 66 182 98t218 32z" />
-<glyph unicode="&#xf1a1;" horiz-adv-x="2304" d="M1509 107q0 -14 -12 -29q-52 -59 -147.5 -83t-196.5 -24q-252 0 -346 107q-12 15 -12 29q0 17 12 29.5t29 12.5q15 0 30 -12q58 -49 125.5 -66t159.5 -17t160 17t127 66q15 12 30 12q17 0 29 -12.5t12 -29.5zM978 498q0 -61 -43 -104t-104 -43q-60 0 -104.5 43.5 t-44.5 103.5q0 61 44 105t105 44t104 -44t43 -105zM1622 498q0 -61 -43 -104t-104 -43q-60 0 -104.5 43.5t-44.5 103.5q0 61 44 105t105 44t104 -44t43 -105zM415 793q-39 27 -88 27q-66 0 -113 -47t-47 -113q0 -72 54 -121q53 141 194 254zM2020 382q0 222 -249 387 q-128 85 -291.5 126.5t-331.5 41.5t-331.5 -41.5t-292.5 -126.5q-249 -165 -249 -387t249 -387q129 -85 292.5 -126.5t331.5 -41.5t331.5 41.5t291.5 126.5q249 165 249 387zM2137 660q0 66 -47 113t-113 47q-50 0 -93 -30q140 -114 192 -256q61 48 61 126zM1993 1335 q0 49 -34.5 83.5t-82.5 34.5q-49 0 -83.5 -34.5t-34.5 -83.5q0 -48 34.5 -82.5t83.5 -34.5q48 0 82.5 34.5t34.5 82.5zM2220 660q0 -65 -33 -122t-89 -90q5 -35 5 -66q0 -139 -79 -255.5t-208 -201.5q-140 -92 -313.5 -136.5
 t-354.5 -44.5t-355 44.5t-314 136.5 q-129 85 -208 201.5t-79 255.5q0 36 6 71q-53 33 -83.5 88.5t-30.5 118.5q0 100 71 171.5t172 71.5q91 0 159 -60q265 170 638 177l144 456q10 29 40 29q24 0 384 -90q24 55 74 88t110 33q82 0 141 -59t59 -142t-59 -141.5t-141 -58.5q-83 0 -141.5 58.5t-59.5 140.5 l-339 80l-125 -395q349 -15 603 -179q71 63 163 63q101 0 172 -71.5t71 -171.5z" />
-<glyph unicode="&#xf1a2;" d="M950 393q7 7 17.5 7t17.5 -7t7 -18t-7 -18q-65 -64 -208 -64h-1h-1q-143 0 -207 64q-8 7 -8 18t8 18q7 7 17.5 7t17.5 -7q49 -51 172 -51h1h1q122 0 173 51zM671 613q0 -37 -26 -64t-63 -27t-63 27t-26 64t26 63t63 26t63 -26t26 -63zM1214 1049q-29 0 -50 21t-21 50 q0 30 21 51t50 21q30 0 51 -21t21 -51q0 -29 -21 -50t-51 -21zM1216 1408q132 0 226 -94t94 -227v-894q0 -133 -94 -227t-226 -94h-896q-132 0 -226 94t-94 227v894q0 133 94 227t226 94h896zM1321 596q35 14 57 45.5t22 70.5q0 51 -36 87.5t-87 36.5q-60 0 -98 -48 q-151 107 -375 115l83 265l206 -49q1 -50 36.5 -85t84.5 -35q50 0 86 35.5t36 85.5t-36 86t-86 36q-36 0 -66 -20.5t-45 -53.5l-227 54q-9 2 -17.5 -2.5t-11.5 -14.5l-95 -302q-224 -4 -381 -113q-36 43 -93 43q-51 0 -87 -36.5t-36 -87.5q0 -37 19.5 -67.5t52.5 -45.5 q-7 -25 -7 -54q0 -98 74 -181.5t201.5 -132t278.5 -48.5q150 0 277.5 48.5t201.5 132t74 181.5q0 27 -6 54zM971 702q37 0 63 -26t26 -63t-26 -64t-63 -27t-63 27t-26 64t26 63t63 26z" />
+<glyph unicode="&#xf1a1;" horiz-adv-x="1792" d="M1095 369q16 -16 0 -31q-62 -62 -199 -62t-199 62q-16 15 0 31q6 6 15 6t15 -6q48 -49 169 -49q120 0 169 49q6 6 15 6t15 -6zM788 550q0 -37 -26 -63t-63 -26t-63.5 26t-26.5 63q0 38 26.5 64t63.5 26t63 -26.5t26 -63.5zM1183 550q0 -37 -26.5 -63t-63.5 -26t-63 26 t-26 63t26 63.5t63 26.5t63.5 -26t26.5 -64zM1434 670q0 49 -35 84t-85 35t-86 -36q-130 90 -311 96l63 283l200 -45q0 -37 26 -63t63 -26t63.5 26.5t26.5 63.5t-26.5 63.5t-63.5 26.5q-54 0 -80 -50l-221 49q-19 5 -25 -16l-69 -312q-180 -7 -309 -97q-35 37 -87 37 q-50 0 -85 -35t-35 -84q0 -35 18.5 -64t49.5 -44q-6 -27 -6 -56q0 -142 140 -243t337 -101q198 0 338 101t140 243q0 32 -7 57q30 15 48 43.5t18 63.5zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191 t348 71t348 -71t286 -191t191 -286t71 -348z" />
+<glyph unicode="&#xf1a2;" d="M939 407q13 -13 0 -26q-53 -53 -171 -53t-171 53q-13 13 0 26q5 6 13 6t13 -6q42 -42 145 -42t145 42q5 6 13 6t13 -6zM676 563q0 -31 -23 -54t-54 -23t-54 23t-23 54q0 32 22.5 54.5t54.5 22.5t54.5 -22.5t22.5 -54.5zM1014 563q0 -31 -23 -54t-54 -23t-54 23t-23 54 q0 32 22.5 54.5t54.5 22.5t54.5 -22.5t22.5 -54.5zM1229 666q0 42 -30 72t-73 30q-42 0 -73 -31q-113 78 -267 82l54 243l171 -39q1 -32 23.5 -54t53.5 -22q32 0 54.5 22.5t22.5 54.5t-22.5 54.5t-54.5 22.5q-48 0 -69 -43l-189 42q-17 5 -21 -13l-60 -268q-154 -6 -265 -83 q-30 32 -74 32q-43 0 -73 -30t-30 -72q0 -30 16 -55t42 -38q-5 -25 -5 -48q0 -122 120 -208.5t289 -86.5q170 0 290 86.5t120 208.5q0 25 -6 49q25 13 40.5 37.5t15.5 54.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960 q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
 <glyph unicode="&#xf1a3;" d="M866 697l90 27v62q0 79 -58 135t-138 56t-138 -55.5t-58 -134.5v-283q0 -20 -14 -33.5t-33 -13.5t-32.5 13.5t-13.5 33.5v120h-151v-122q0 -82 57.5 -139t139.5 -57q81 0 138.5 56.5t57.5 136.5v280q0 19 13.5 33t33.5 14q19 0 32.5 -14t13.5 -33v-54zM1199 502v122h-150 v-126q0 -20 -13.5 -33.5t-33.5 -13.5q-19 0 -32.5 14t-13.5 33v123l-90 -26l-60 28v-123q0 -80 58 -137t139 -57t138.5 57t57.5 139zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103 t385.5 -103t279.5 -279.5t103 -385.5z" />
 <glyph unicode="&#xf1a4;" horiz-adv-x="1920" d="M1062 824v118q0 42 -30 72t-72 30t-72 -30t-30 -72v-612q0 -175 -126 -299t-303 -124q-178 0 -303.5 125.5t-125.5 303.5v266h328v-262q0 -43 30 -72.5t72 -29.5t72 29.5t30 72.5v620q0 171 126.5 292t301.5 121q176 0 302 -122t126 -294v-136l-195 -58zM1592 602h328 v-266q0 -178 -125.5 -303.5t-303.5 -125.5q-177 0 -303 124.5t-126 300.5v268l131 -61l195 58v-270q0 -42 30 -71.5t72 -29.5t72 29.5t30 71.5v275z" />
 <glyph unicode="&#xf1a5;" d="M1472 160v480h-704v704h-480q-93 0 -158.5 -65.5t-65.5 -158.5v-480h704v-704h480q93 0 158.5 65.5t65.5 158.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5 t84.5 -203.5z" />
@@ -459,7 +459,7 @@
 <glyph unicode="&#xf1d1;" horiz-adv-x="1792" d="M874 -102v-66q-208 6 -385 109.5t-283 275.5l58 34q29 -49 73 -99l65 57q148 -168 368 -212l-17 -86q65 -12 121 -13zM276 428l-83 -28q22 -60 49 -112l-57 -33q-98 180 -98 385t98 385l57 -33q-30 -56 -49 -112l82 -28q-35 -100 -35 -212q0 -109 36 -212zM1528 251 l58 -34q-106 -172 -283 -275.5t-385 -109.5v66q56 1 121 13l-17 86q220 44 368 212l65 -57q44 50 73 99zM1377 805l-233 -80q14 -42 14 -85t-14 -85l232 -80q-31 -92 -98 -169l-185 162q-57 -67 -147 -85l48 -241q-52 -10 -98 -10t-98 10l48 241q-90 18 -147 85l-185 -162 q-67 77 -98 169l232 80q-14 42 -14 85t14 85l-233 80q33 93 99 169l185 -162q59 68 147 86l-48 240q44 10 98 10t98 -10l-48 -240q88 -18 147 -86l185 162q66 -76 99 -169zM874 1448v-66q-65 -2 -121 -13l17 -86q-220 -42 -368 -211l-65 56q-38 -42 -73 -98l-57 33 q106 172 282 275.5t385 109.5zM1705 640q0 -205 -98 -385l-57 33q27 52 49 112l-83 28q36 103 36 212q0 112 -35 212l82 28q-19 56 -49 112l57 33q98 -180 98 -385zM1585 1063l-57 -33q-35 56 -73 98l-65 -56q-148 169 
 -368 211l17 86q-56 11 -121 13v66q209 -6 385 -109.5 t282 -275.5zM1748 640q0 173 -67.5 331t-181.5 272t-272 181.5t-331 67.5t-331 -67.5t-272 -181.5t-181.5 -272t-67.5 -331t67.5 -331t181.5 -272t272 -181.5t331 -67.5t331 67.5t272 181.5t181.5 272t67.5 331zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71 t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
 <glyph unicode="&#xf1d2;" d="M582 228q0 -66 -93 -66q-107 0 -107 63q0 64 98 64q102 0 102 -61zM546 694q0 -85 -74 -85q-77 0 -77 84q0 90 77 90q36 0 55 -25.5t19 -63.5zM712 769v125q-78 -29 -135 -29q-50 29 -110 29q-86 0 -145 -57t-59 -143q0 -50 29.5 -102t73.5 -67v-3q-38 -17 -38 -85 q0 -53 41 -77v-3q-113 -37 -113 -139q0 -45 20 -78.5t54 -51t72 -25.5t81 -8q224 0 224 188q0 67 -48 99t-126 46q-27 5 -51.5 20.5t-24.5 39.5q0 44 49 52q77 15 122 70t45 134q0 24 -10 52q37 9 49 13zM771 350h137q-2 27 -2 82v387q0 46 2 69h-137q3 -23 3 -71v-392 q0 -50 -3 -75zM1280 366v121q-30 -21 -68 -21q-53 0 -53 82v225h52q9 0 26.5 -1t26.5 -1v117h-105q0 82 3 102h-140q4 -24 4 -55v-47h-60v-117q36 3 37 3q3 0 11 -0.5t12 -0.5v-2h-2v-217q0 -37 2.5 -64t11.5 -56.5t24.5 -48.5t43.5 -31t66 -12q64 0 108 24zM924 1072 q0 36 -24 63.5t-60 27.5t-60.5 -27t-24.5 -64q0 -36 25 -62.5t60 -26.5t59.5 27t24.5 62zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t
 84.5 -203.5z" />
 <glyph unicode="&#xf1d3;" horiz-adv-x="1792" d="M595 22q0 100 -165 100q-158 0 -158 -104q0 -101 172 -101q151 0 151 105zM536 777q0 61 -30 102t-89 41q-124 0 -124 -145q0 -135 124 -135q119 0 119 137zM805 1101v-202q-36 -12 -79 -22q16 -43 16 -84q0 -127 -73 -216.5t-197 -112.5q-40 -8 -59.5 -27t-19.5 -58 q0 -31 22.5 -51.5t58 -32t78.5 -22t86 -25.5t78.5 -37.5t58 -64t22.5 -98.5q0 -304 -363 -304q-69 0 -130 12.5t-116 41t-87.5 82t-32.5 127.5q0 165 182 225v4q-67 41 -67 126q0 109 63 137v4q-72 24 -119.5 108.5t-47.5 165.5q0 139 95 231.5t235 92.5q96 0 178 -47 q98 0 218 47zM1123 220h-222q4 45 4 134v609q0 94 -4 128h222q-4 -33 -4 -124v-613q0 -89 4 -134zM1724 442v-196q-71 -39 -174 -39q-62 0 -107 20t-70 50t-39.5 78t-18.5 92t-4 103v351h2v4q-7 0 -19 1t-18 1q-21 0 -59 -6v190h96v76q0 54 -6 89h227q-6 -41 -6 -165h171 v-190q-15 0 -43.5 2t-42.5 2h-85v-365q0 -131 87 -131q61 0 109 33zM1148 1389q0 -58 -39 -101.5t-96 -43.5q-58 0 -98 43.5t-40 101.5q0 59 39.5 103t98.5 44q58 0 96.5 -44.5t38.5 -102.5z" />
-<glyph unicode="&#xf1d4;" d="M825 547l343 588h-150q-21 -39 -63.5 -118.5t-68 -128.5t-59.5 -118.5t-60 -128.5h-3q-21 48 -44.5 97t-52 105.5t-46.5 92t-54 104.5t-49 95h-150l323 -589v-435h134v436zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960 q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+<glyph unicode="&#xf1d4;" d="M809 532l266 499h-112l-157 -312q-24 -48 -44 -92l-42 92l-155 312h-120l263 -493v-324h101v318zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
 <glyph unicode="&#xf1d5;" horiz-adv-x="1280" d="M842 964q0 -80 -57 -136.5t-136 -56.5q-60 0 -111 35q-62 -67 -115 -146q-247 -371 -202 -859q1 -22 -12.5 -38.5t-34.5 -18.5h-5q-20 0 -35 13.5t-17 33.5q-14 126 -3.5 247.5t29.5 217t54 186t69 155.5t74 125q61 90 132 165q-16 35 -16 77q0 80 56.5 136.5t136.5 56.5 t136.5 -56.5t56.5 -136.5zM1223 953q0 -158 -78 -292t-212.5 -212t-292.5 -78q-64 0 -131 14q-21 5 -32.5 23.5t-6.5 39.5q5 20 23 31.5t39 7.5q51 -13 108 -13q97 0 186 38t153 102t102 153t38 186t-38 186t-102 153t-153 102t-186 38t-186 -38t-153 -102t-102 -153 t-38 -186q0 -114 52 -218q10 -20 3.5 -40t-25.5 -30t-39.5 -3t-30.5 26q-64 123 -64 265q0 119 46.5 227t124.5 186t186 124t226 46q158 0 292.5 -78t212.5 -212.5t78 -292.5z" />
 <glyph unicode="&#xf1d6;" horiz-adv-x="1792" d="M270 730q-8 19 -8 52q0 20 11 49t24 45q-1 22 7.5 53t22.5 43q0 139 92.5 288.5t217.5 209.5q139 66 324 66q133 0 266 -55q49 -21 90 -48t71 -56t55 -68t42 -74t32.5 -84.5t25.5 -89.5t22 -98l1 -5q55 -83 55 -150q0 -14 -9 -40t-9 -38q0 -1 1.5 -3.5t3.5 -5t2 -3.5 q77 -114 120.5 -214.5t43.5 -208.5q0 -43 -19.5 -100t-55.5 -57q-9 0 -19.5 7.5t-19 17.5t-19 26t-16 26.5t-13.5 26t-9 17.5q-1 1 -3 1l-5 -4q-59 -154 -132 -223q20 -20 61.5 -38.5t69 -41.5t35.5 -65q-2 -4 -4 -16t-7 -18q-64 -97 -302 -97q-53 0 -110.5 9t-98 20 t-104.5 30q-15 5 -23 7q-14 4 -46 4.5t-40 1.5q-41 -45 -127.5 -65t-168.5 -20q-35 0 -69 1.5t-93 9t-101 20.5t-74.5 40t-32.5 64q0 40 10 59.5t41 48.5q11 2 40.5 13t49.5 12q4 0 14 2q2 2 2 4l-2 3q-48 11 -108 105.5t-73 156.5l-5 3q-4 0 -12 -20q-18 -41 -54.5 -74.5 t-77.5 -37.5h-1q-4 0 -6 4.5t-5 5.5q-23 54 -23 100q0 275 252 466z" />
 <glyph unicode="&#xf1d7;" horiz-adv-x="2048" d="M580 1075q0 41 -25 66t-66 25q-43 0 -76 -25.5t-33 -65.5q0 -39 33 -64.5t76 -25.5q41 0 66 24.5t25 65.5zM1323 568q0 28 -25.5 50t-65.5 22q-27 0 -49.5 -22.5t-22.5 -49.5q0 -28 22.5 -50.5t49.5 -22.5q40 0 65.5 22t25.5 51zM1087 1075q0 41 -24.5 66t-65.5 25 q-43 0 -76 -25.5t-33 -65.5q0 -39 33 -64.5t76 -25.5q41 0 65.5 24.5t24.5 65.5zM1722 568q0 28 -26 50t-65 22q-27 0 -49.5 -22.5t-22.5 -49.5q0 -28 22.5 -50.5t49.5 -22.5q39 0 65 22t26 51zM1456 965q-31 4 -70 4q-169 0 -311 -77t-223.5 -208.5t-81.5 -287.5 q0 -78 23 -152q-35 -3 -68 -3q-26 0 -50 1.5t-55 6.5t-44.5 7t-54.5 10.5t-50 10.5l-253 -127l72 218q-290 203 -290 490q0 169 97.5 311t264 223.5t363.5 81.5q176 0 332.5 -66t262 -182.5t136.5 -260.5zM2048 404q0 -117 -68.5 -223.5t-185.5 -193.5l55 -181l-199 109 q-150 -37 -218 -37q-169 0 -311 70.5t-223.5 191.5t-81.5 264t81.5 264t223.5 191.5t311 70.5q161 0 303 -70.5t227.5 -192t85.5 -263.5z" />
@@ -483,13 +483,13 @@
 <glyph unicode="&#xf1ea;" horiz-adv-x="2048" d="M1024 1024h-384v-384h384v384zM1152 384v-128h-640v128h640zM1152 1152v-640h-640v640h640zM1792 384v-128h-512v128h512zM1792 640v-128h-512v128h512zM1792 896v-128h-512v128h512zM1792 1152v-128h-512v128h512zM256 192v960h-128v-960q0 -26 19 -45t45 -19t45 19 t19 45zM1920 192v1088h-1536v-1088q0 -33 -11 -64h1483q26 0 45 19t19 45zM2048 1408v-1216q0 -80 -56 -136t-136 -56h-1664q-80 0 -136 56t-56 136v1088h256v128h1792z" />
 <glyph unicode="&#xf1eb;" horiz-adv-x="2048" d="M1024 13q-20 0 -93 73.5t-73 93.5q0 32 62.5 54t103.5 22t103.5 -22t62.5 -54q0 -20 -73 -93.5t-93 -73.5zM1294 284q-2 0 -40 25t-101.5 50t-128.5 25t-128.5 -25t-101 -50t-40.5 -25q-18 0 -93.5 75t-75.5 93q0 13 10 23q78 77 196 121t233 44t233 -44t196 -121 q10 -10 10 -23q0 -18 -75.5 -93t-93.5 -75zM1567 556q-11 0 -23 8q-136 105 -252 154.5t-268 49.5q-85 0 -170.5 -22t-149 -53t-113.5 -62t-79 -53t-31 -22q-17 0 -92 75t-75 93q0 12 10 22q132 132 320 205t380 73t380 -73t320 -205q10 -10 10 -22q0 -18 -75 -93t-92 -75z M1838 827q-11 0 -22 9q-179 157 -371.5 236.5t-420.5 79.5t-420.5 -79.5t-371.5 -236.5q-11 -9 -22 -9q-17 0 -92.5 75t-75.5 93q0 13 10 23q187 186 445 288t527 102t527 -102t445 -288q10 -10 10 -23q0 -18 -75.5 -93t-92.5 -75z" />
 <glyph unicode="&#xf1ec;" horiz-adv-x="1792" d="M384 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM384 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5 t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1152 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5 t37.5 90.5zM384 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1152 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 768q0 53 -37.5 90.5t-90.5 37.5 t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1536 0v384q0 52 -38 90t-90 38t-90 -38t-38 -90v-384q0 -52 38 -90t90 -38t90 38t38 90zM1152 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-
 37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5z M1536 1088v256q0 26 -19 45t-45 19h-1280q-26 0 -45 -19t-19 -45v-256q0 -26 19 -45t45 -19h1280q26 0 45 19t19 45zM1536 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 1408v-1536q0 -52 -38 -90t-90 -38 h-1408q-52 0 -90 38t-38 90v1536q0 52 38 90t90 38h1408q52 0 90 -38t38 -90z" />
-<glyph unicode="&#xf1ed;" horiz-adv-x="1792" d="M1112 1090q0 159 -237 159h-70q-32 0 -59.5 -21.5t-34.5 -52.5l-63 -276q-2 -5 -2 -16q0 -24 17 -39.5t41 -15.5h53q69 0 128.5 13t112.5 41t83.5 81.5t30.5 126.5zM1716 938q0 -265 -220 -428q-219 -161 -612 -161h-61q-32 0 -59 -21.5t-34 -52.5l-73 -316 q-8 -36 -40.5 -61.5t-69.5 -25.5h-213q-31 0 -53 20t-22 51q0 10 13 65h151q34 0 64 23.5t38 56.5l73 316q8 33 37.5 57t63.5 24h61q390 0 607 160t217 421q0 129 -51 207q183 -92 183 -335zM1533 1123q0 -264 -221 -428q-218 -161 -612 -161h-60q-32 0 -59.5 -22t-34.5 -53 l-73 -315q-8 -36 -40 -61.5t-69 -25.5h-214q-31 0 -52.5 19.5t-21.5 51.5q0 8 2 20l300 1301q8 36 40.5 61.5t69.5 25.5h444q68 0 125 -4t120.5 -15t113.5 -30t96.5 -50.5t77.5 -74t49.5 -103.5t18.5 -136z" />
+<glyph unicode="&#xf1ed;" d="M1519 890q18 -84 -4 -204q-87 -444 -565 -444h-44q-25 0 -44 -16.5t-24 -42.5l-4 -19l-55 -346l-2 -15q-5 -26 -24.5 -42.5t-44.5 -16.5h-251q-21 0 -33 15t-9 36q9 56 26.5 168t26.5 168t27 167.5t27 167.5q5 37 43 37h131q133 -2 236 21q175 39 287 144q102 95 155 246 q24 70 35 133q1 6 2.5 7.5t3.5 1t6 -3.5q79 -59 98 -162zM1347 1172q0 -107 -46 -236q-80 -233 -302 -315q-113 -40 -252 -42q0 -1 -90 -1l-90 1q-100 0 -118 -96q-2 -8 -85 -530q-1 -10 -12 -10h-295q-22 0 -36.5 16.5t-11.5 38.5l232 1471q5 29 27.5 48t51.5 19h598 q34 0 97.5 -13t111.5 -32q107 -41 163.5 -123t56.5 -196z" />
 <glyph unicode="&#xf1ee;" horiz-adv-x="1792" d="M602 949q19 -61 31 -123.5t17 -141.5t-14 -159t-62 -145q-21 81 -67 157t-95.5 127t-99 90.5t-78.5 57.5t-33 19q-62 34 -81.5 100t14.5 128t101 81.5t129 -14.5q138 -83 238 -177zM927 1236q11 -25 20.5 -46t36.5 -100.5t42.5 -150.5t25.5 -179.5t0 -205.5t-47.5 -209.5 t-105.5 -208.5q-51 -72 -138 -72q-54 0 -98 31q-57 40 -69 109t28 127q60 85 81 195t13 199.5t-32 180.5t-39 128t-22 52q-31 63 -8.5 129.5t85.5 97.5q34 17 75 17q47 0 88.5 -25t63.5 -69zM1248 567q-17 -160 -72 -311q-17 131 -63 246q25 174 -5 361q-27 178 -94 342 q114 -90 212 -211q9 -37 15 -80q26 -179 7 -347zM1520 1440q9 -17 23.5 -49.5t43.5 -117.5t50.5 -178t34 -227.5t5 -269t-47 -300t-112.5 -323.5q-22 -48 -66 -75.5t-95 -27.5q-39 0 -74 16q-67 31 -92.5 100t4.5 136q58 126 90 257.5t37.5 239.5t-3.5 213.5t-26.5 180.5 t-38.5 138.5t-32.5 90t-15.5 32.5q-34 65 -11.5 135.5t87.5 104.5q37 20 81 20q49 0 91.5 -25.5t66.5 -70.5z" />
 <glyph unicode="&#xf1f0;" horiz-adv-x="2304" d="M1975 546h-138q14 37 66 179l3 9q4 10 10 26t9 26l12 -55zM531 611l-58 295q-11 54 -75 54h-268l-2 -13q311 -79 403 -336zM710 960l-162 -438l-17 89q-26 70 -85 129.5t-131 88.5l135 -510h175l261 641h-176zM849 318h166l104 642h-166zM1617 944q-69 27 -149 27 q-123 0 -201 -59t-79 -153q-1 -102 145 -174q48 -23 67 -41t19 -39q0 -30 -30 -46t-69 -16q-86 0 -156 33l-22 11l-23 -144q74 -34 185 -34q130 -1 208.5 59t80.5 160q0 106 -140 174q-49 25 -71 42t-22 38q0 22 24.5 38.5t70.5 16.5q70 1 124 -24l15 -8zM2042 960h-128 q-65 0 -87 -54l-246 -588h174l35 96h212q5 -22 20 -96h154zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
 <glyph unicode="&#xf1f1;" horiz-adv-x="2304" d="M671 603h-13q-47 0 -47 -32q0 -22 20 -22q17 0 28 15t12 39zM1066 639h62v3q1 4 0.5 6.5t-1 7t-2 8t-4.5 6.5t-7.5 5t-11.5 2q-28 0 -36 -38zM1606 603h-12q-48 0 -48 -32q0 -22 20 -22q17 0 28 15t12 39zM1925 629q0 41 -30 41q-19 0 -31 -20t-12 -51q0 -42 28 -42 q20 0 32.5 20t12.5 52zM480 770h87l-44 -262h-56l32 201l-71 -201h-39l-4 200l-34 -200h-53l44 262h81l2 -163zM733 663q0 -6 -4 -42q-16 -101 -17 -113h-47l1 22q-20 -26 -58 -26q-23 0 -37.5 16t-14.5 42q0 39 26 60.5t73 21.5q14 0 23 -1q0 3 0.5 5.5t1 4.5t0.5 3 q0 20 -36 20q-29 0 -59 -10q0 4 7 48q38 11 67 11q74 0 74 -62zM889 721l-8 -49q-22 3 -41 3q-27 0 -27 -17q0 -8 4.5 -12t21.5 -11q40 -19 40 -60q0 -72 -87 -71q-34 0 -58 6q0 2 7 49q29 -8 51 -8q32 0 32 19q0 7 -4.5 11.5t-21.5 12.5q-43 20 -43 59q0 72 84 72 q30 0 50 -4zM977 721h28l-7 -52h-29q-2 -17 -6.5 -40.5t-7 -38.5t-2.5 -18q0 -16 19 -16q8 0 16 2l-8 -47q-21 -7 -40 -7q-43 0 -45 47q0 12 8 56q3 20 25 146h55zM1180 648q0 -23 -7 -52h-111q-3 -22 10 -33t38 -11q30 0 58
  14l-9 -54q-30 -8 -57 -8q-95 0 -95 95 q0 55 27.5 90.5t69.5 35.5q35 0 55.5 -21t20.5 -56zM1319 722q-13 -23 -22 -62q-22 2 -31 -24t-25 -128h-56l3 14q22 130 29 199h51l-3 -33q14 21 25.5 29.5t28.5 4.5zM1506 763l-9 -57q-28 14 -50 14q-31 0 -51 -27.5t-20 -70.5q0 -30 13.5 -47t38.5 -17q21 0 48 13 l-10 -59q-28 -8 -50 -8q-45 0 -71.5 30.5t-26.5 82.5q0 70 35.5 114.5t91.5 44.5q26 0 61 -13zM1668 663q0 -18 -4 -42q-13 -79 -17 -113h-46l1 22q-20 -26 -59 -26q-23 0 -37 16t-14 42q0 39 25.5 60.5t72.5 21.5q15 0 23 -1q2 7 2 13q0 20 -36 20q-29 0 -59 -10q0 4 8 48 q38 11 67 11q73 0 73 -62zM1809 722q-14 -24 -21 -62q-23 2 -31.5 -23t-25.5 -129h-56l3 14q19 104 29 199h52q0 -11 -4 -33q15 21 26.5 29.5t27.5 4.5zM1950 770h56l-43 -262h-53l3 19q-23 -23 -52 -23q-31 0 -49.5 24t-18.5 64q0 53 27.5 92t64.5 39q31 0 53 -29z M2061 640q0 148 -72.5 273t-198 198t-273.5 73q-181 0 -328 -110q127 -116 171 -284h-50q-44 150 -158 253q-114 -103 -158 -253h-50q44 168 171 284q-147 110 -328 110q-148 0 -273.5 -73t-198 -198t-72.5 -273t72.5 -273t198
  -198t273.5 -73q181 0 328 110 q-120 111 -165 264h50q46 -138 152 -233q106 95 152 233h50q-45 -153 -165 -264q147 -110 328 -110q148 0 273.5 73t198 198t72.5 273zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
 <glyph unicode="&#xf1f2;" horiz-adv-x="2304" d="M313 759q0 -51 -36 -84q-29 -26 -89 -26h-17v220h17q61 0 89 -27q36 -31 36 -83zM2089 824q0 -52 -64 -52h-19v101h20q63 0 63 -49zM380 759q0 74 -50 120.5t-129 46.5h-95v-333h95q74 0 119 38q60 51 60 128zM410 593h65v333h-65v-333zM730 694q0 40 -20.5 62t-75.5 42 q-29 10 -39.5 19t-10.5 23q0 16 13.5 26.5t34.5 10.5q29 0 53 -27l34 44q-41 37 -98 37q-44 0 -74 -27.5t-30 -67.5q0 -35 18 -55.5t64 -36.5q37 -13 45 -19q19 -12 19 -34q0 -20 -14 -33.5t-36 -13.5q-48 0 -71 44l-42 -40q44 -64 115 -64q51 0 83 30.5t32 79.5zM1008 604 v77q-37 -37 -78 -37q-49 0 -80.5 32.5t-31.5 82.5q0 48 31.5 81.5t77.5 33.5q43 0 81 -38v77q-40 20 -80 20q-74 0 -125.5 -50.5t-51.5 -123.5t51 -123.5t125 -50.5q42 0 81 19zM2240 0v527q-65 -40 -144.5 -84t-237.5 -117t-329.5 -137.5t-417.5 -134.5t-504 -118h1569 q26 0 45 19t19 45zM1389 757q0 75 -53 128t-128 53t-128 -53t-53 -128t53 -128t128 -53t128 53t53 128zM1541 584l144 342h-71l-90 -224l-89 224h-71l142 -342h35zM1714 593h184v56h-119v90h115v56h-115v74h1
 19v57h-184v-333zM2105 593h80l-105 140q76 16 76 94q0 47 -31 73 t-87 26h-97v-333h65v133h9zM2304 1274v-1268q0 -56 -38.5 -95t-93.5 -39h-2040q-55 0 -93.5 39t-38.5 95v1268q0 56 38.5 95t93.5 39h2040q55 0 93.5 -39t38.5 -95z" />
 <glyph unicode="&#xf1f3;" horiz-adv-x="2304" d="M119 854h89l-45 108zM740 328l74 79l-70 79h-163v-49h142v-55h-142v-54h159zM898 406l99 -110v217zM1186 453q0 33 -40 33h-84v-69h83q41 0 41 36zM1475 457q0 29 -42 29h-82v-61h81q43 0 43 32zM1197 923q0 29 -42 29h-82v-60h81q43 0 43 31zM1656 854h89l-44 108z M699 1009v-271h-66v212l-94 -212h-57l-94 212v-212h-132l-25 60h-135l-25 -60h-70l116 271h96l110 -257v257h106l85 -184l77 184h108zM1255 453q0 -20 -5.5 -35t-14 -25t-22.5 -16.5t-26 -10t-31.5 -4.5t-31.5 -1t-32.5 0.5t-29.5 0.5v-91h-126l-80 90l-83 -90h-256v271h260 l80 -89l82 89h207q109 0 109 -89zM964 794v-56h-217v271h217v-57h-152v-49h148v-55h-148v-54h152zM2304 235v-229q0 -55 -38.5 -94.5t-93.5 -39.5h-2040q-55 0 -93.5 39.5t-38.5 94.5v678h111l25 61h55l25 -61h218v46l19 -46h113l20 47v-47h541v99l10 1q10 0 10 -14v-86h279 v23q23 -12 55 -18t52.5 -6.5t63 0.5t51.5 1l25 61h56l25 -61h227v58l34 -58h182v378h-180v-44l-25 44h-185v-44l-23 44h-249q-69 0 -109 -22v22h-172v-22q-24 22 -73 22h-628l-43 -97l-43 97h-198v-44l-22 4
 4h-169l-78 -179v391q0 55 38.5 94.5t93.5 39.5h2040 q55 0 93.5 -39.5t38.5 -94.5v-678h-120q-51 0 -81 -22v22h-177q-55 0 -78 -22v22h-316v-22q-31 22 -87 22h-209v-22q-23 22 -91 22h-234l-54 -58l-50 58h-349v-378h343l55 59l52 -59h211v89h21q59 0 90 13v-102h174v99h8q8 0 10 -2t2 -10v-87h529q57 0 88 24v-24h168 q60 0 95 17zM1546 469q0 -23 -12 -43t-34 -29q25 -9 34 -26t9 -46v-54h-65v45q0 33 -12 43.5t-46 10.5h-69v-99h-65v271h154q48 0 77 -15t29 -58zM1269 936q0 -24 -12.5 -44t-33.5 -29q26 -9 34.5 -25.5t8.5 -46.5v-53h-65q0 9 0.5 26.5t0 25t-3 18.5t-8.5 16t-17.5 8.5 t-29.5 3.5h-70v-98h-64v271l153 -1q49 0 78 -14.5t29 -57.5zM1798 327v-56h-216v271h216v-56h-151v-49h148v-55h-148v-54zM1372 1009v-271h-66v271h66zM2065 357q0 -86 -102 -86h-126v58h126q34 0 34 25q0 16 -17 21t-41.5 5t-49.5 3.5t-42 22.5t-17 55q0 39 26 60t66 21 h130v-57h-119q-36 0 -36 -25q0 -16 17.5 -20.5t42 -4t49 -2.5t42 -21.5t17.5 -54.5zM2304 407v-101q-24 -35 -88 -35h-125v58h125q33 0 33 25q0 13 -12.5 19t-31 5.5t-40 2t-40 8t-31 24t-12.5 48.5q0 39 26.5 6
 0t66.5 21h129v-57h-118q-36 0 -36 -25q0 -20 29 -22t68.5 -5 t56.5 -26zM2139 1008v-270h-92l-122 203v-203h-132l-26 60h-134l-25 -60h-75q-129 0 -129 133q0 138 133 138h63v-59q-7 0 -28 1t-28.5 0.5t-23 -2t-21.5 -6.5t-14.5 -13.5t-11.5 -23t-3 -33.5q0 -38 13.5 -58t49.5 -20h29l92 213h97l109 -256v256h99l114 -188v188h66z" />
-<glyph unicode="&#xf1f4;" horiz-adv-x="2304" d="M322 689h-15q-19 0 -19 18q0 28 19 85q5 15 15 19.5t28 4.5q77 0 77 -49q0 -41 -30.5 -59.5t-74.5 -18.5zM664 528q-47 0 -47 29q0 62 123 62l3 -3q-5 -88 -79 -88zM1438 687h-15q-19 0 -19 19q0 28 19 85q5 15 14.5 19t28.5 4q77 0 77 -49q0 -41 -30.5 -59.5 t-74.5 -18.5zM1780 527q-47 0 -47 30q0 62 123 62l3 -3q-5 -89 -79 -89zM373 894h-128q-8 0 -14.5 -4t-8.5 -7.5t-7 -12.5q-3 -7 -45 -190t-42 -192q0 -7 5.5 -12.5t13.5 -5.5h62q25 0 32.5 34.5l15 69t32.5 34.5q47 0 87.5 7.5t80.5 24.5t63.5 52.5t23.5 84.5 q0 36 -14.5 61t-41 36.5t-53.5 15.5t-62 4zM719 798q-38 0 -74 -6q-2 0 -8.5 -1t-9 -1.5l-7.5 -1.5t-7.5 -2t-6.5 -3t-6.5 -4t-5 -5t-4.5 -7t-4 -9q-9 -29 -9 -39t9 -10q5 0 21.5 5t19.5 6q30 8 58 8q74 0 74 -36q0 -11 -10 -14q-8 -2 -18 -3t-21.5 -1.5t-17.5 -1.5 q-38 -4 -64.5 -10t-56.5 -19.5t-45.5 -39t-15.5 -62.5q0 -38 26 -59.5t64 -21.5q24 0 45.5 6.5t33 13t38.5 23.5q-3 -7 -3 -15t5.5 -13.5t12.5 -5.5h56q1 1 7 3.5t7.5 3.5t5 3.5t5 5.5t2.5 8l45 194q4 13 4 30q0 81 -145 81zM1247 793h-
 74q-22 0 -39 -23q-5 -7 -29.5 -51 t-46.5 -81.5t-26 -38.5l-5 4q0 77 -27 166q-1 5 -3.5 8.5t-6 6.5t-6.5 5t-8.5 3t-8.5 1.5t-9.5 1t-9 0.5h-10h-8.5q-38 0 -38 -21l1 -5q5 -53 25 -151t25 -143q2 -16 2 -24q0 -19 -30.5 -61.5t-30.5 -58.5q0 -13 40 -13q61 0 76 25l245 415q10 20 10 26q0 9 -8 9zM1489 892 h-129q-18 0 -29 -23q-6 -13 -46.5 -191.5t-40.5 -190.5q0 -20 43 -20h7.5h9h9t9.5 1t8.5 2t8.5 3t6.5 4.5t5.5 6t3 8.5l21 91q2 10 10.5 17t19.5 7q47 0 87.5 7t80.5 24.5t63.5 52.5t23.5 84q0 36 -14.5 61t-41 36.5t-53.5 15.5t-62 4zM1835 798q-26 0 -74 -6 q-38 -6 -48 -16q-7 -8 -11 -19q-8 -24 -8 -39q0 -10 8 -10q1 0 41 12q30 8 58 8q74 0 74 -36q0 -12 -10 -14q-4 -1 -57 -7q-38 -4 -64.5 -10t-56.5 -19.5t-45.5 -39t-15.5 -62.5t26 -58.5t64 -21.5q24 0 45 6t34 13t38 24q-3 -15 -3 -16q0 -5 2 -8.5t6.5 -5.5t8 -3.5 t10.5 -2t9.5 -0.5h9.5h8q42 0 48 25l45 194q3 15 3 31q0 81 -145 81zM2157 889h-55q-25 0 -33 -40q-10 -44 -36.5 -167t-42.5 -190v-5q0 -16 16 -18h1h57q10 0 18.5 6.5t10.5 16.5l83 374h-1l1 5q0 7 -5.5 12.5t-13.5 5.5zM2304 1280v-128
 0q0 -52 -38 -90t-90 -38h-2048 q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
+<glyph unicode="&#xf1f4;" horiz-adv-x="2304" d="M745 630q0 -37 -25.5 -61.5t-62.5 -24.5q-29 0 -46.5 16t-17.5 44q0 37 25 62.5t62 25.5q28 0 46.5 -16.5t18.5 -45.5zM1530 779q0 -42 -22 -57t-66 -15l-32 -1l17 107q2 11 13 11h18q22 0 35 -2t25 -12.5t12 -30.5zM1881 630q0 -36 -25.5 -61t-61.5 -25q-29 0 -47 16 t-18 44q0 37 25 62.5t62 25.5q28 0 46.5 -16.5t18.5 -45.5zM513 801q0 59 -38.5 85.5t-100.5 26.5h-160q-19 0 -21 -19l-65 -408q-1 -6 3 -11t10 -5h76q20 0 22 19l18 110q1 8 7 13t15 6.5t17 1.5t19 -1t14 -1q86 0 135 48.5t49 134.5zM822 489l41 261q1 6 -3 11t-10 5h-76 q-14 0 -17 -33q-27 40 -95 40q-72 0 -122.5 -54t-50.5 -127q0 -59 34.5 -94t92.5 -35q28 0 58 12t48 32q-4 -12 -4 -21q0 -16 13 -16h69q19 0 22 19zM1269 752q0 5 -4 9.5t-9 4.5h-77q-11 0 -18 -10l-106 -156l-44 150q-5 16 -22 16h-75q-5 0 -9 -4.5t-4 -9.5q0 -2 19.5 -59 t42 -123t23.5 -70q-82 -112 -82 -120q0 -13 13 -13h77q11 0 18 10l255 368q2 2 2 7zM1649 801q0 59 -38.5 85.5t-100.5 26.5h-159q-20 0 -22 -19l-65 -408q-1 -6 3 -11t10 -5h82q12 0 16 13l18 116q1 8 7 1
 3t15 6.5t17 1.5t19 -1t14 -1q86 0 135 48.5t49 134.5zM1958 489 l41 261q1 6 -3 11t-10 5h-76q-14 0 -17 -33q-26 40 -95 40q-72 0 -122.5 -54t-50.5 -127q0 -59 34.5 -94t92.5 -35q29 0 59 12t47 32q0 -1 -2 -9t-2 -12q0 -16 13 -16h69q19 0 22 19zM2176 898v1q0 14 -13 14h-74q-11 0 -13 -11l-65 -416l-1 -2q0 -5 4 -9.5t10 -4.5h66 q19 0 21 19zM392 764q-5 -35 -26 -46t-60 -11l-33 -1l17 107q2 11 13 11h19q40 0 58 -11.5t12 -48.5zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
 <glyph unicode="&#xf1f5;" horiz-adv-x="2304" d="M1597 633q0 -69 -21 -106q-19 -35 -52 -35q-23 0 -41 9v224q29 30 57 30q57 0 57 -122zM2035 669h-110q6 98 56 98q51 0 54 -98zM476 534q0 59 -33 91.5t-101 57.5q-36 13 -52 24t-16 25q0 26 38 26q58 0 124 -33l18 112q-67 32 -149 32q-77 0 -123 -38q-48 -39 -48 -109 q0 -58 32.5 -90.5t99.5 -56.5q39 -14 54.5 -25.5t15.5 -27.5q0 -31 -48 -31q-29 0 -70 12.5t-72 30.5l-18 -113q72 -41 168 -41q81 0 129 37q51 41 51 117zM771 749l19 111h-96v135l-129 -21l-18 -114l-46 -8l-17 -103h62v-219q0 -84 44 -120q38 -30 111 -30q32 0 79 11v118 q-32 -7 -44 -7q-42 0 -42 50v197h77zM1087 724v139q-15 3 -28 3q-32 0 -55.5 -16t-33.5 -46l-10 56h-131v-471h150v306q26 31 82 31q16 0 26 -2zM1124 389h150v471h-150v-471zM1746 638q0 122 -45 179q-40 52 -111 52q-64 0 -117 -56l-8 47h-132v-645l150 25v151 q36 -11 68 -11q83 0 134 56q61 65 61 202zM1278 986q0 33 -23 56t-56 23t-56 -23t-23 -56t23 -56.5t56 -23.5t56 23.5t23 56.5zM2176 629q0 113 -48 176q-50 64 -144 64q-96 0 -151.5 -66t-55.5 -180q0 -128 63 -1
 88q55 -55 161 -55q101 0 160 40l-16 103q-57 -31 -128 -31 q-43 0 -63 19q-23 19 -28 66h248q2 14 2 52zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
 <glyph unicode="&#xf1f6;" horiz-adv-x="2048" d="M1558 684q61 -356 298 -556q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-180.5 74.5t-75.5 180.5zM1024 -176q16 0 16 16t-16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5zM2026 1424q8 -10 7.5 -23.5t-10.5 -22.5 l-1872 -1622q-10 -8 -23.5 -7t-21.5 11l-84 96q-8 10 -7.5 23.5t10.5 21.5l186 161q-19 32 -19 66q50 42 91 88t85 119.5t74.5 158.5t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q124 -18 219 -82.5t148 -157.5 l418 363q10 8 23.5 7t21.5 -11z" />
 <glyph unicode="&#xf1f7;" horiz-adv-x="2048" d="M1040 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM503 315l877 760q-42 88 -132.5 146.5t-223.5 58.5q-93 0 -169.5 -31.5t-121.5 -80.5t-69 -103t-24 -105q0 -384 -137 -645zM1856 128 q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-180.5 74.5t-75.5 180.5l149 129h757q-166 187 -227 459l111 97q61 -356 298 -556zM1942 1520l84 -96q8 -10 7.5 -23.5t-10.5 -22.5l-1872 -1622q-10 -8 -23.5 -7t-21.5 11l-84 96q-8 10 -7.5 23.5t10.5 21.5l186 161 q-19 32 -19 66q50 42 91 88t85 119.5t74.5 158.5t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q124 -18 219 -82.5t148 -157.5l418 363q10 8 23.5 7t21.5 -11z" />
@@ -523,7 +523,7 @@
 <glyph unicode="&#xf215;" horiz-adv-x="2048" d="M863 504q0 112 -79.5 191.5t-191.5 79.5t-191 -79.5t-79 -191.5t79 -191t191 -79t191.5 79t79.5 191zM1726 505q0 112 -79 191t-191 79t-191.5 -79t-79.5 -191q0 -113 79.5 -192t191.5 -79t191 79.5t79 191.5zM2048 1314v-1348q0 -44 -31.5 -75.5t-76.5 -31.5h-1832 q-45 0 -76.5 31.5t-31.5 75.5v1348q0 44 31.5 75.5t76.5 31.5h431q44 0 76 -31.5t32 -75.5v-161h754v161q0 44 32 75.5t76 31.5h431q45 0 76.5 -31.5t31.5 -75.5z" />
 <glyph unicode="&#xf216;" horiz-adv-x="2048" d="M1430 953zM1690 749q148 0 253 -98.5t105 -244.5q0 -157 -109 -261.5t-267 -104.5q-85 0 -162 27.5t-138 73.5t-118 106t-109 126.5t-103.5 132.5t-108.5 126t-117 106t-136 73.5t-159 27.5q-154 0 -251.5 -91.5t-97.5 -244.5q0 -157 104 -250t263 -93q100 0 208 37.5 t193 98.5q5 4 21 18.5t30 24t22 9.5q14 0 24.5 -10.5t10.5 -24.5q0 -24 -60 -77q-101 -88 -234.5 -142t-260.5 -54q-133 0 -245.5 58t-180 165t-67.5 241q0 205 141.5 341t347.5 136q120 0 226.5 -43.5t185.5 -113t151.5 -153t139 -167.5t133.5 -153.5t149.5 -113 t172.5 -43.5q102 0 168.5 61.5t66.5 162.5q0 95 -64.5 159t-159.5 64q-30 0 -81.5 -18.5t-68.5 -18.5q-20 0 -35.5 15t-15.5 35q0 18 8.5 57t8.5 59q0 159 -107.5 263t-266.5 104q-58 0 -111.5 -18.5t-84 -40.5t-55.5 -40.5t-33 -18.5q-15 0 -25.5 10.5t-10.5 25.5 q0 19 25 46q59 67 147 103.5t182 36.5q191 0 318 -125.5t127 -315.5q0 -37 -4 -66q57 15 115 15z" />
 <glyph unicode="&#xf217;" horiz-adv-x="1664" d="M1216 832q0 26 -19 45t-45 19h-128v128q0 26 -19 45t-45 19t-45 -19t-19 -45v-128h-128q-26 0 -45 -19t-19 -45t19 -45t45 -19h128v-128q0 -26 19 -45t45 -19t45 19t19 45v128h128q26 0 45 19t19 45zM640 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5 t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1536 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1664 1088v-512q0 -24 -16 -42.5t-41 -21.5l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920 q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf218;" horiz-adv-x="1792" d="M1280 832q0 26 -19 45t-45 19t-45 -19l-147 -146v293q0 26 -19 45t-45 19t-45 -19t-19 -45v-293l-147 146q-19 19 -45 19t-45 -19t-19 -45t19 -45l256 -256q19 -19 45 -19t45 19l256 256q19 19 19 45zM640 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5 t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1536 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1664 1088v-512q0 -24 -16 -42.5t-41 -21.5l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920 q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf218;" horiz-adv-x="1664" d="M1280 832q0 26 -19 45t-45 19t-45 -19l-147 -146v293q0 26 -19 45t-45 19t-45 -19t-19 -45v-293l-147 146q-19 19 -45 19t-45 -19t-19 -45t19 -45l256 -256q19 -19 45 -19t45 19l256 256q19 19 19 45zM640 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5 t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1536 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1664 1088v-512q0 -24 -16 -42.5t-41 -21.5l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920 q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45z" />
 <glyph unicode="&#xf219;" horiz-adv-x="2048" d="M212 768l623 -665l-300 665h-323zM1024 -4l349 772h-698zM538 896l204 384h-262l-288 -384h346zM1213 103l623 665h-323zM683 896h682l-204 384h-274zM1510 896h346l-288 384h-262zM1651 1382l384 -512q14 -18 13 -41.5t-17 -40.5l-960 -1024q-18 -20 -47 -20t-47 20 l-960 1024q-16 17 -17 40.5t13 41.5l384 512q18 26 51 26h1152q33 0 51 -26z" />
 <glyph unicode="&#xf21a;" horiz-adv-x="2048" d="M1811 -19q19 19 45 19t45 -19l128 -128l-90 -90l-83 83l-83 -83q-18 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83 q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-128 128l90 90l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83 q19 19 45 19t45 -19l83 -83zM237 19q-19 -19 -45 -19t-45 19l-128 128l90 90l83 -82l83 82q19 19 45 19t45 -19l83 -82l64 64v293l-210 314q-17 26 -7 56.5t40 40.5l177 58v299h128v128h256v128h256v-128h256v-128h128v-299l177 -58q30 -10 40 -40.5t-7 -56.5l-210 -314 v-293l19 18q19 19 45 19t45 -19l83 -82l83 82q19 19 45 19t45 -19l128 -128l-90 -90l-83 83l-83 -83q-18 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83
  83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83 q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83zM640 1152v-128l384 128l384 -128v128h-128v128h-512v-128h-128z" />
 <glyph unicode="&#xf21b;" d="M576 0l96 448l-96 128l-128 64zM832 0l128 640l-128 -64l-96 -128zM992 1010q-2 4 -4 6q-10 8 -96 8q-70 0 -167 -19q-7 -2 -21 -2t-21 2q-97 19 -167 19q-86 0 -96 -8q-2 -2 -4 -6q2 -18 4 -27q2 -3 7.5 -6.5t7.5 -10.5q2 -4 7.5 -20.5t7 -20.5t7.5 -17t8.5 -17t9 -14 t12 -13.5t14 -9.5t17.5 -8t20.5 -4t24.5 -2q36 0 59 12.5t32.5 30t14.5 34.5t11.5 29.5t17.5 12.5h12q11 0 17.5 -12.5t11.5 -29.5t14.5 -34.5t32.5 -30t59 -12.5q13 0 24.5 2t20.5 4t17.5 8t14 9.5t12 13.5t9 14t8.5 17t7.5 17t7 20.5t7.5 20.5q2 7 7.5 10.5t7.5 6.5 q2 9 4 27zM1408 131q0 -121 -73 -190t-194 -69h-874q-121 0 -194 69t-73 190q0 61 4.5 118t19 125.5t37.5 123.5t63.5 103.5t93.5 74.5l-90 220h214q-22 64 -22 128q0 12 2 32q-194 40 -194 96q0 57 210 99q17 62 51.5 134t70.5 114q32 37 76 37q30 0 84 -31t84 -31t84 31 t84 31q44 0 76 -37q36 -42 70.5 -114t51.5 -134q210 -42 210 -99q0 -56 -194 -96q7 -81 -20 -160h214l-82 -225q63 -33 107.5 -96.5t65.5 -143.5t29 -151.5t8 -148.5z" />
@@ -531,18 +531,18 @@
 <glyph unicode="&#xf21d;" d="M1408 0q0 -63 -61.5 -113.5t-164 -81t-225 -46t-253.5 -15.5t-253.5 15.5t-225 46t-164 81t-61.5 113.5q0 49 33 88.5t91 66.5t118 44.5t131 29.5q26 5 48 -10.5t26 -41.5q5 -26 -10.5 -48t-41.5 -26q-58 -10 -106 -23.5t-76.5 -25.5t-48.5 -23.5t-27.5 -19.5t-8.5 -12 q3 -11 27 -26.5t73 -33t114 -32.5t160.5 -25t201.5 -10t201.5 10t160.5 25t114 33t73 33.5t27 27.5q-1 4 -8.5 11t-27.5 19t-48.5 23.5t-76.5 25t-106 23.5q-26 4 -41.5 26t-10.5 48q4 26 26 41.5t48 10.5q71 -12 131 -29.5t118 -44.5t91 -66.5t33 -88.5zM1024 896v-384 q0 -26 -19 -45t-45 -19h-64v-384q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v384h-64q-26 0 -45 19t-19 45v384q0 53 37.5 90.5t90.5 37.5h384q53 0 90.5 -37.5t37.5 -90.5zM928 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5 t158.5 -65.5t65.5 -158.5z" />
 <glyph unicode="&#xf21e;" horiz-adv-x="1792" d="M1280 512h305q-5 -6 -10 -10.5t-9 -7.5l-3 -4l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-5 2 -21 20h369q22 0 39.5 13.5t22.5 34.5l70 281l190 -667q6 -20 23 -33t39 -13q21 0 38 13t23 33l146 485l56 -112q18 -35 57 -35zM1792 940q0 -145 -103 -300h-369l-111 221 q-8 17 -25.5 27t-36.5 8q-45 -5 -56 -46l-129 -430l-196 686q-6 20 -23.5 33t-39.5 13t-39 -13.5t-22 -34.5l-116 -464h-423q-103 155 -103 300q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5q224 0 351 -124 t127 -344z" />
 <glyph unicode="&#xf221;" horiz-adv-x="1280" d="M1152 960q0 -221 -147.5 -384.5t-364.5 -187.5v-260h224q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-224q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v260q-150 16 -271.5 103t-186 224t-52.5 292 q11 134 80.5 249t182 188t245.5 88q170 19 319 -54t236 -212t87 -306zM128 960q0 -185 131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5z" />
-<glyph unicode="&#xf222;" horiz-adv-x="1792" d="M1280 1504q0 14 9 23t23 9h416q26 0 45 -19t19 -45v-416q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v262l-419 -420q87 -104 129.5 -236.5t30.5 -276.5q-22 -250 -200.5 -431t-428.5 -206q-163 -17 -314 39.5t-256.5 162t-162 256.5t-39.5 314q25 250 206 428.5 t431 200.5q144 12 276.5 -30.5t236.5 -129.5l419 419h-261q-14 0 -23 9t-9 23v64zM704 -128q117 0 223.5 45.5t184 123t123 184t45.5 223.5t-45.5 223.5t-123 184t-184 123t-223.5 45.5t-223.5 -45.5t-184 -123t-123 -184t-45.5 -223.5t45.5 -223.5t123 -184t184 -123 t223.5 -45.5z" />
+<glyph unicode="&#xf222;" d="M1472 1408q26 0 45 -19t19 -45v-416q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v262l-382 -383q126 -156 126 -359q0 -117 -45.5 -223.5t-123 -184t-184 -123t-223.5 -45.5t-223.5 45.5t-184 123t-123 184t-45.5 223.5t45.5 223.5t123 184t184 123t223.5 45.5 q203 0 359 -126l382 382h-261q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h416zM576 0q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
 <glyph unicode="&#xf223;" horiz-adv-x="1280" d="M830 1220q145 -72 233.5 -210.5t88.5 -305.5q0 -221 -147.5 -384.5t-364.5 -187.5v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-217 24 -364.5 187.5 t-147.5 384.5q0 167 88.5 305.5t233.5 210.5q-165 96 -228 273q-6 16 3.5 29.5t26.5 13.5h69q21 0 29 -20q44 -106 140 -171t214 -65t214 65t140 171q8 20 37 20h61q17 0 26.5 -13.5t3.5 -29.5q-63 -177 -228 -273zM576 256q185 0 316.5 131.5t131.5 316.5t-131.5 316.5 t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
 <glyph unicode="&#xf224;" d="M1024 1504q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q126 -158 126 -359q0 -221 -147.5 -384.5t-364.5 -187.5v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64 q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-149 16 -270.5 103t-186.5 223.5t-53 291.5q16 204 160 353.5t347 172.5q118 14 228 -19t198 -103l255 254h-134q-14 0 -23 9t-9 23v64zM576 256q185 0 316.5 131.5t131.5 316.5t-131.5 316.5 t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
 <glyph unicode="&#xf225;" horiz-adv-x="1792" d="M1280 1504q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q126 -158 126 -359q0 -221 -147.5 -384.5t-364.5 -187.5v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64 q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-217 24 -364.5 187.5t-147.5 384.5q0 201 126 359l-52 53l-101 -111q-9 -10 -22 -10.5t-23 7.5l-48 44q-10 8 -10.5 21.5t8.5 23.5l105 115l-111 112v-134q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9 t-9 23v288q0 26 19 45t45 19h288q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-133l106 -107l86 94q9 10 22 10.5t23 -7.5l48 -44q10 -8 10.5 -21.5t-8.5 -23.5l-90 -99l57 -56q158 126 359 126t359 -126l255 254h-134q-14 0 -23 9t-9 23v64zM832 256q185 0 316.5 131.5 t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
 <glyph unicode="&#xf226;" horiz-adv-x="1792" d="M1790 1007q12 -155 -52.5 -292t-186 -224t-271.5 -103v-260h224q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-512v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-224q-14 0 -23 9t-9 23v64q0 14 9 23 t23 9h224v260q-150 16 -271.5 103t-186 224t-52.5 292q17 206 164.5 356.5t352.5 169.5q206 21 377 -94q171 115 377 94q205 -19 352.5 -169.5t164.5 -356.5zM896 647q128 131 128 313t-128 313q-128 -131 -128 -313t128 -313zM576 512q115 0 218 57q-154 165 -154 391 q0 224 154 391q-103 57 -218 57q-185 0 -316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5zM1152 128v260q-137 15 -256 94q-119 -79 -256 -94v-260h512zM1216 512q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5q-115 0 -218 -57q154 -167 154 -391 q0 -226 -154 -391q103 -57 218 -57z" />
 <glyph unicode="&#xf227;" horiz-adv-x="1920" d="M1536 1120q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q76 -95 107.5 -214t9.5 -247q-31 -182 -166 -312t-318 -156q-210 -29 -384.5 80t-241.5 300q-117 6 -221 57.5t-177.5 133t-113.5 192.5t-32 230 q9 135 78 252t182 191.5t248 89.5q118 14 227.5 -19t198.5 -103l255 254h-134q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q59 -74 93 -169q182 -9 328 -124l255 254h-134q-14 0 -23 9 t-9 23v64zM1024 704q0 20 -4 58q-162 -25 -271 -150t-109 -292q0 -20 4 -58q162 25 271 150t109 292zM128 704q0 -168 111 -294t276 -149q-3 29 -3 59q0 210 135 369.5t338 196.5q-53 120 -163.5 193t-245.5 73q-185 0 -316.5 -131.5t-131.5 -316.5zM1088 -128 q185 0 316.5 131.5t131.5 316.5q0 168 -111 294t-276 149q3 -29 3 -59q0 -210 -135 -369.5t-338 -196.5q53 -120 163.5 -193t245.5 -73z" />
 <glyph unicode="&#xf228;" horiz-adv-x="2048" d="M1664 1504q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q76 -95 107.5 -214t9.5 -247q-32 -180 -164.5 -310t-313.5 -157q-223 -34 -409 90q-117 -78 -256 -93v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23 t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-155 17 -279.5 109.5t-187 237.5t-39.5 307q25 187 159.5 322.5t320.5 164.5q224 34 410 -90q146 97 320 97q201 0 359 -126l255 254h-134q-14 0 -23 9 t-9 23v64zM896 391q128 131 128 313t-128 313q-128 -131 -128 -313t128 -313zM128 704q0 -185 131.5 -316.5t316.5 -131.5q117 0 218 57q-154 167 -154 391t154 391q-101 57 -218 57q-185 0 -316.5 -131.5t-131.5 -316.5zM1216 256q185 0 316.5 131.5t131.5 316.5 t-131.5 316.5t-316.5 131.5q-117 0 -218 -57q154 -167 154 -391t-154 -391q101 -57 218 -57z" />
-<glyph unicode="&#xf229;" horiz-adv-x="1792" d="M1728 1536q26 0 45 -19t19 -45v-416q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v262l-229 -230l156 -156q9 -10 9 -23t-9 -22l-46 -46q-9 -9 -22 -9t-23 9l-156 157l-99 -100q87 -104 129.5 -236.5t30.5 -276.5q-22 -250 -200.5 -431t-428.5 -206q-163 -17 -314 39.5 t-256.5 162t-162 256.5t-39.5 314q25 250 206 428.5t431 200.5q144 12 276.5 -30.5t236.5 -129.5l99 99l-156 156q-9 10 -9 23t9 22l46 46q9 9 22 9t23 -9l156 -156l229 229h-261q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h416zM1280 448q0 117 -45.5 223.5t-123 184t-184 123 t-223.5 45.5t-223.5 -45.5t-184 -123t-123 -184t-45.5 -223.5t45.5 -223.5t123 -184t184 -123t223.5 -45.5t223.5 45.5t184 123t123 184t45.5 223.5z" />
+<glyph unicode="&#xf229;" d="M1472 1408q26 0 45 -19t19 -45v-416q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v262l-213 -214l140 -140q9 -10 9 -23t-9 -22l-46 -46q-9 -9 -22 -9t-23 9l-140 141l-78 -79q126 -156 126 -359q0 -117 -45.5 -223.5t-123 -184t-184 -123t-223.5 -45.5t-223.5 45.5 t-184 123t-123 184t-45.5 223.5t45.5 223.5t123 184t184 123t223.5 45.5q203 0 359 -126l78 78l-172 172q-9 10 -9 23t9 22l46 46q9 9 22 9t23 -9l172 -172l213 213h-261q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h416zM576 0q185 0 316.5 131.5t131.5 316.5t-131.5 316.5 t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
 <glyph unicode="&#xf22a;" horiz-adv-x="1280" d="M640 892q217 -24 364.5 -187.5t147.5 -384.5q0 -167 -87 -306t-236 -212t-319 -54q-133 15 -245.5 88t-182 188t-80.5 249q-12 155 52.5 292t186 224t271.5 103v132h-160q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h160v165l-92 -92q-10 -9 -23 -9t-22 9l-46 46q-9 9 -9 22 t9 23l202 201q19 19 45 19t45 -19l202 -201q9 -10 9 -23t-9 -22l-46 -46q-9 -9 -22 -9t-23 9l-92 92v-165h160q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-160v-132zM576 -128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5 t131.5 -316.5t316.5 -131.5z" />
-<glyph unicode="&#xf22b;" horiz-adv-x="2048" d="M2029 685q19 -19 19 -45t-19 -45l-294 -294q-9 -10 -22.5 -10t-22.5 10l-45 45q-10 9 -10 22.5t10 22.5l185 185h-294v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-131q-12 -119 -67 -226t-139 -183.5t-196.5 -121.5t-234.5 -45q-180 0 -330.5 91t-234.5 247 t-74 337q8 162 94 300t226.5 219.5t302.5 85.5q166 4 310.5 -71.5t235.5 -208.5t107 -296h131v224q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-224h294l-185 185q-10 9 -10 22.5t10 22.5l45 45q9 10 22.5 10t22.5 -10zM640 128q104 0 198.5 40.5t163.5 109.5t109.5 163.5 t40.5 198.5t-40.5 198.5t-109.5 163.5t-163.5 109.5t-198.5 40.5t-198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5z" />
+<glyph unicode="&#xf22b;" horiz-adv-x="2048" d="M1901 621q19 -19 19 -45t-19 -45l-294 -294q-9 -10 -22.5 -10t-22.5 10l-45 45q-10 9 -10 22.5t10 22.5l185 185h-294v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-132q-24 -217 -187.5 -364.5t-384.5 -147.5q-167 0 -306 87t-212 236t-54 319q15 133 88 245.5 t188 182t249 80.5q155 12 292 -52.5t224 -186t103 -271.5h132v224q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-224h294l-185 185q-10 9 -10 22.5t10 22.5l45 45q9 10 22.5 10t22.5 -10zM576 128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5 t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
 <glyph unicode="&#xf22c;" horiz-adv-x="1280" d="M1152 960q0 -221 -147.5 -384.5t-364.5 -187.5v-612q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v612q-217 24 -364.5 187.5t-147.5 384.5q0 117 45.5 223.5t123 184t184 123t223.5 45.5t223.5 -45.5t184 -123t123 -184t45.5 -223.5zM576 512q185 0 316.5 131.5 t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
-<glyph unicode="&#xf22d;" horiz-adv-x="1792" />
+<glyph unicode="&#xf22d;" horiz-adv-x="1280" d="M1024 576q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1152 576q0 -117 -45.5 -223.5t-123 -184t-184 -123t-223.5 -45.5t-223.5 45.5t-184 123t-123 184t-45.5 223.5t45.5 223.5t123 184t184 123 t223.5 45.5t223.5 -45.5t184 -123t123 -184t45.5 -223.5z" />
 <glyph unicode="&#xf22e;" horiz-adv-x="1792" />
 <glyph unicode="&#xf22f;" horiz-adv-x="1792" />
 <glyph unicode="&#xf230;" d="M1451 1408q35 0 60 -25t25 -60v-1366q0 -35 -25 -60t-60 -25h-391v595h199l30 232h-229v148q0 56 23.5 84t91.5 28l122 1v207q-63 9 -178 9q-136 0 -217.5 -80t-81.5 -226v-171h-200v-232h200v-595h-735q-35 0 -60 25t-25 60v1366q0 35 25 60t60 25h1366z" />
@@ -556,10 +556,85 @@
 <glyph unicode="&#xf238;" d="M1088 1536q185 0 316.5 -93.5t131.5 -226.5v-896q0 -130 -125.5 -222t-305.5 -97l213 -202q16 -15 8 -35t-30 -20h-1056q-22 0 -30 20t8 35l213 202q-180 5 -305.5 97t-125.5 222v896q0 133 131.5 226.5t316.5 93.5h640zM768 192q80 0 136 56t56 136t-56 136t-136 56 t-136 -56t-56 -136t56 -136t136 -56zM1344 768v512h-1152v-512h1152z" />
 <glyph unicode="&#xf239;" d="M1088 1536q185 0 316.5 -93.5t131.5 -226.5v-896q0 -130 -125.5 -222t-305.5 -97l213 -202q16 -15 8 -35t-30 -20h-1056q-22 0 -30 20t8 35l213 202q-180 5 -305.5 97t-125.5 222v896q0 133 131.5 226.5t316.5 93.5h640zM288 224q66 0 113 47t47 113t-47 113t-113 47 t-113 -47t-47 -113t47 -113t113 -47zM704 768v512h-544v-512h544zM1248 224q66 0 113 47t47 113t-47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47zM1408 768v512h-576v-512h576z" />
 <glyph unicode="&#xf23a;" horiz-adv-x="1792" d="M1792 204v-209h-642v209h134v926h-6l-314 -1135h-243l-310 1135h-8v-926h135v-209h-538v209h69q21 0 43 19.5t22 37.5v881q0 18 -22 40t-43 22h-69v209h672l221 -821h6l223 821h670v-209h-71q-19 0 -41 -22t-22 -40v-881q0 -18 21.5 -37.5t41.5 -19.5h71z" />
-<glyph unicode="&#xf23b;" horiz-adv-x="1792" />
-<glyph unicode="&#xf23c;" horiz-adv-x="1792" />
-<glyph unicode="&#xf23d;" horiz-adv-x="1792" />
-<glyph unicode="&#xf23e;" horiz-adv-x="1792" />
+<glyph unicode="&#xf23b;" d="M809 532l266 499h-112l-157 -312q-24 -48 -44 -92l-42 92l-155 312h-120l263 -493v-324h101v318zM1536 1408v-1536h-1536v1536h1536z" />
+<glyph unicode="&#xf23c;" horiz-adv-x="2296" d="M478 -139q-8 -16 -27 -34.5t-37 -25.5q-25 -9 -51.5 3.5t-28.5 31.5q-1 22 40 55t68 38q23 4 34 -21.5t2 -46.5zM1819 -139q7 -16 26 -34.5t38 -25.5q25 -9 51.5 3.5t27.5 31.5q2 22 -39.5 55t-68.5 38q-22 4 -33 -21.5t-2 -46.5zM1867 -30q13 -27 56.5 -59.5t77.5 -41.5 q45 -13 82 4.5t37 50.5q0 46 -67.5 100.5t-115.5 59.5q-40 5 -63.5 -37.5t-6.5 -76.5zM428 -30q-13 -27 -56 -59.5t-77 -41.5q-45 -13 -82 4.5t-37 50.5q0 46 67.5 100.5t115.5 59.5q40 5 63 -37.5t6 -76.5zM1158 1094h1q-41 0 -76 -15q27 -8 44 -30.5t17 -49.5 q0 -35 -27 -60t-65 -25q-52 0 -80 43q-5 -23 -5 -42q0 -74 56 -126.5t135 -52.5q80 0 136 52.5t56 126.5t-56 126.5t-136 52.5zM1462 1312q-99 109 -220.5 131.5t-245.5 -44.5q27 60 82.5 96.5t118 39.5t121.5 -17t99.5 -74.5t44.5 -131.5zM2212 73q8 -11 -11 -42 q7 -23 7 -40q1 -56 -44.5 -112.5t-109.5 -91.5t-118 -37q-48 -2 -92 21.5t-66 65.5q-687 -25 -1259 0q-23 -41 -66.5 -65t-92.5 -22q-86 3 -179.5 80.5t-92.5 160.5q2 22 7 40q-19 31 -11 42q6 10 31 1q14 22 41 51q-7 29 2 3
 8q11 10 39 -4q29 20 59 34q0 29 13 37 q23 12 51 -16q35 5 61 -2q18 -4 38 -19v73q-11 0 -18 2q-53 10 -97 44.5t-55 87.5q-9 38 0 81q15 62 93 95q2 17 19 35.5t36 23.5t33 -7.5t19 -30.5h13q46 -5 60 -23q3 -3 5 -7q10 1 30.5 3.5t30.5 3.5q-15 11 -30 17q-23 40 -91 43q0 6 1 10q-62 2 -118.5 18.5t-84.5 47.5 q-32 36 -42.5 92t-2.5 112q16 126 90 179q23 16 52 4.5t32 -40.5q0 -1 1.5 -14t2.5 -21t3 -20t5.5 -19t8.5 -10q27 -14 76 -12q48 46 98 74q-40 4 -162 -14l47 46q61 58 163 111q145 73 282 86q-20 8 -41 15.5t-47 14t-42.5 10.5t-47.5 11t-43 10q595 126 904 -139 q98 -84 158 -222q85 -10 121 9h1q5 3 8.5 10t5.5 19t3 19.5t3 21.5l1 14q3 28 32 40t52 -5q73 -52 91 -178q7 -57 -3.5 -113t-42.5 -91q-28 -32 -83.5 -48.5t-115.5 -18.5v-10q-71 -2 -95 -43q-14 -5 -31 -17q11 -1 32 -3.5t30 -3.5q1 4 5 8q16 18 60 23h13q5 18 19 30t33 8 t36 -23t19 -36q79 -32 93 -95q9 -40 1 -81q-12 -53 -56 -88t-97 -44q-10 -2 -17 -2q0 -49 -1 -73q20 15 38 19q26 7 61 2q28 28 51 16q14 -9 14 -37q33 -16 59 -34q27 13 38 4q10 -10 2 -38q28 -30 41 -51q23 8 31 -1zM19
 37 1025q0 -29 -9 -54q82 -32 112 -132 q4 37 -9.5 98.5t-41.5 90.5q-20 19 -36 17t-16 -20zM1859 925q35 -42 47.5 -108.5t-0.5 -124.5q67 13 97 45q13 14 18 28q-3 64 -31 114.5t-79 66.5q-15 -15 -52 -21zM1822 921q-30 0 -44 1q42 -115 53 -239q21 0 43 3q16 68 1 135t-53 100zM258 839q30 100 112 132 q-9 25 -9 54q0 18 -16.5 20t-35.5 -17q-28 -29 -41.5 -90.5t-9.5 -98.5zM294 737q29 -31 97 -45q-13 58 -0.5 124.5t47.5 108.5v0q-37 6 -52 21q-51 -16 -78.5 -66t-31.5 -115q9 -17 18 -28zM471 683q14 124 73 235q-19 -4 -55 -18l-45 -19v1q-46 -89 -20 -196q25 -3 47 -3z M1434 644q8 -38 16.5 -108.5t11.5 -89.5q3 -18 9.5 -21.5t23.5 4.5q40 20 62 85.5t23 125.5q-24 2 -146 4zM1152 1285q-116 0 -199 -82.5t-83 -198.5q0 -117 83 -199.5t199 -82.5t199 82.5t83 199.5q0 116 -83 198.5t-199 82.5zM1380 646q-106 2 -211 0v1q-1 -27 2.5 -86 t13.5 -66q29 -14 93.5 -14.5t95.5 10.5q9 3 11 39t-0.5 69.5t-4.5 46.5zM1112 447q8 4 9.5 48t-0.5 88t-4 63v1q-212 -3 -214 -3q-4 -20 -7 -62t0 -83t14 -46q34 -15 101 -16t101 10zM718 636q-16 -59 4.5 -118.5t77.5 -84
 .5q15 -8 24 -5t12 21q3 16 8 90t10 103 q-69 -2 -136 -6zM591 510q3 -23 -34 -36q132 -141 271.5 -240t305.5 -154q172 49 310.5 146t293.5 250q-33 13 -30 34l3 9v1v-1q-17 2 -50 5.5t-48 4.5q-26 -90 -82 -132q-51 -38 -82 1q-5 6 -9 14q-7 13 -17 62q-2 -5 -5 -9t-7.5 -7t-8 -5.5t-9.5 -4l-10 -2.5t-12 -2 l-12 -1.5t-13.5 -1t-13.5 -0.5q-106 -9 -163 11q-4 -17 -10 -26.5t-21 -15t-23 -7t-36 -3.5q-2 0 -3 -0.5t-3 -0.5h-3q-179 -17 -203 40q-2 -63 -56 -54q-47 8 -91 54q-12 13 -20 26q-17 29 -26 65q-58 -6 -87 -10q1 -2 4 -10zM507 -118q3 14 3 30q-17 71 -51 130t-73 70 q-41 12 -101.5 -14.5t-104.5 -80t-39 -107.5q35 -53 100 -93t119 -42q51 -2 94 28t53 79zM510 53q23 -63 27 -119q195 113 392 174q-98 52 -180.5 120t-179.5 165q-6 -4 -29 -13q0 -2 -1 -5t-1 -4q31 -18 22 -37q-12 -23 -56 -34q-10 -13 -29 -24h-1q-2 -83 1 -150 q19 -34 35 -73zM579 -113q532 -21 1145 0q-254 147 -428 196q-76 -35 -156 -57q-8 -3 -16 0q-65 21 -129 49q-208 -60 -416 -188h-1v-1q1 0 1 1zM1763 -67q4 54 28 120q14 38 33 71l-1 -1q3 77 3 153q-15 8 -30 25q-42 9 -56 33q
 -9 20 22 38q-2 4 -2 9q-16 4 -28 12 q-204 -190 -383 -284q198 -59 414 -176zM2155 -90q5 54 -39 107.5t-104 80t-102 14.5q-38 -11 -72.5 -70.5t-51.5 -129.5q0 -16 3 -30q10 -49 53 -79t94 -28q54 2 119 42t100 93z" />
+<glyph unicode="&#xf23d;" horiz-adv-x="2304" d="M1524 -25q0 -68 -48 -116t-116 -48t-116.5 48t-48.5 116t48.5 116.5t116.5 48.5t116 -48.5t48 -116.5zM775 -25q0 -68 -48.5 -116t-116.5 -48t-116 48t-48 116t48 116.5t116 48.5t116.5 -48.5t48.5 -116.5zM0 1469q57 -60 110.5 -104.5t121 -82t136 -63t166 -45.5 t200 -31.5t250 -18.5t304 -9.5t372.5 -2.5q139 0 244.5 -5t181 -16.5t124 -27.5t71 -39.5t24 -51.5t-19.5 -64t-56.5 -76.5t-89.5 -91t-116 -104.5t-139 -119q-185 -157 -286 -247q29 51 76.5 109t94 105.5t94.5 98.5t83 91.5t54 80.5t13 70t-45.5 55.5t-116.5 41t-204 23.5 t-304 5q-168 -2 -314 6t-256 23t-204.5 41t-159.5 51.5t-122.5 62.5t-91.5 66.5t-68 71.5t-50.5 69.5t-40 68t-36.5 59.5z" />
+<glyph unicode="&#xf23e;" horiz-adv-x="1792" d="M896 1472q-169 0 -323 -66t-265.5 -177.5t-177.5 -265.5t-66 -323t66 -323t177.5 -265.5t265.5 -177.5t323 -66t323 66t265.5 177.5t177.5 265.5t66 323t-66 323t-177.5 265.5t-265.5 177.5t-323 66zM896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348 t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM496 704q16 0 16 -16v-480q0 -16 -16 -16h-32q-16 0 -16 16v480q0 16 16 16h32zM896 640q53 0 90.5 -37.5t37.5 -90.5q0 -35 -17.5 -64t-46.5 -46v-114q0 -14 -9 -23 t-23 -9h-64q-14 0 -23 9t-9 23v114q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5zM896 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM544 928v-96 q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v96q0 93 65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5v-96q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v96q0 146 -103 249t-249 103t-249 -103t-103 -249zM1408 192v512q0 26 -19 45
 t-45 19h-896q-26 0 -45 -19t-19 -45v-512 q0 -26 19 -45t45 -19h896q26 0 45 19t19 45z" />
+<glyph unicode="&#xf240;" horiz-adv-x="2304" d="M1920 1024v-768h-1664v768h1664zM2048 448h128v384h-128v288q0 14 -9 23t-23 9h-1856q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288zM2304 832v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113 v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160q53 0 90.5 -37.5t37.5 -90.5z" />
+<glyph unicode="&#xf241;" horiz-adv-x="2304" d="M256 256v768h1280v-768h-1280zM2176 960q53 0 90.5 -37.5t37.5 -90.5v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160zM2176 448v384h-128v288q0 14 -9 23t-23 9 h-1856q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288h128z" />
+<glyph unicode="&#xf242;" horiz-adv-x="2304" d="M256 256v768h896v-768h-896zM2176 960q53 0 90.5 -37.5t37.5 -90.5v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160zM2176 448v384h-128v288q0 14 -9 23t-23 9 h-1856q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288h128z" />
+<glyph unicode="&#xf243;" horiz-adv-x="2304" d="M256 256v768h512v-768h-512zM2176 960q53 0 90.5 -37.5t37.5 -90.5v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160zM2176 448v384h-128v288q0 14 -9 23t-23 9 h-1856q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288h128z" />
+<glyph unicode="&#xf244;" horiz-adv-x="2304" d="M2176 960q53 0 90.5 -37.5t37.5 -90.5v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160zM2176 448v384h-128v288q0 14 -9 23t-23 9h-1856q-14 0 -23 -9t-9 -23 v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288h128z" />
+<glyph unicode="&#xf245;" horiz-adv-x="1280" d="M1133 493q31 -30 14 -69q-17 -40 -59 -40h-382l201 -476q10 -25 0 -49t-34 -35l-177 -75q-25 -10 -49 0t-35 34l-191 452l-312 -312q-19 -19 -45 -19q-12 0 -24 5q-40 17 -40 59v1504q0 42 40 59q12 5 24 5q27 0 45 -19z" />
+<glyph unicode="&#xf246;" horiz-adv-x="1024" d="M832 1408q-320 0 -320 -224v-416h128v-128h-128v-544q0 -224 320 -224h64v-128h-64q-272 0 -384 146q-112 -146 -384 -146h-64v128h64q320 0 320 224v544h-128v128h128v416q0 224 -320 224h-64v128h64q272 0 384 -146q112 146 384 146h64v-128h-64z" />
+<glyph unicode="&#xf247;" horiz-adv-x="2048" d="M2048 1152h-128v-1024h128v-384h-384v128h-1280v-128h-384v384h128v1024h-128v384h384v-128h1280v128h384v-384zM1792 1408v-128h128v128h-128zM128 1408v-128h128v128h-128zM256 -128v128h-128v-128h128zM1664 0v128h128v1024h-128v128h-1280v-128h-128v-1024h128v-128 h1280zM1920 -128v128h-128v-128h128zM1280 896h384v-768h-896v256h-384v768h896v-256zM512 512h640v512h-640v-512zM1536 256v512h-256v-384h-384v-128h640z" />
+<glyph unicode="&#xf248;" horiz-adv-x="2304" d="M2304 768h-128v-640h128v-384h-384v128h-896v-128h-384v384h128v128h-384v-128h-384v384h128v640h-128v384h384v-128h896v128h384v-384h-128v-128h384v128h384v-384zM2048 1024v-128h128v128h-128zM1408 1408v-128h128v128h-128zM128 1408v-128h128v128h-128zM256 256 v128h-128v-128h128zM1536 384h-128v-128h128v128zM384 384h896v128h128v640h-128v128h-896v-128h-128v-640h128v-128zM896 -128v128h-128v-128h128zM2176 -128v128h-128v-128h128zM2048 128v640h-128v128h-384v-384h128v-384h-384v128h-384v-128h128v-128h896v128h128z" />
+<glyph unicode="&#xf249;" d="M1024 288v-416h-928q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h1344q40 0 68 -28t28 -68v-928h-416q-40 0 -68 -28t-28 -68zM1152 256h381q-15 -82 -65 -132l-184 -184q-50 -50 -132 -65v381z" />
+<glyph unicode="&#xf24a;" d="M1400 256h-248v-248q29 10 41 22l185 185q12 12 22 41zM1120 384h288v896h-1280v-1280h896v288q0 40 28 68t68 28zM1536 1312v-1024q0 -40 -20 -88t-48 -76l-184 -184q-28 -28 -76 -48t-88 -20h-1024q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h1344q40 0 68 -28t28 -68 z" />
+<glyph unicode="&#xf24b;" horiz-adv-x="2304" d="M1951 538q0 -26 -15.5 -44.5t-38.5 -23.5q-8 -2 -18 -2h-153v140h153q10 0 18 -2q23 -5 38.5 -23.5t15.5 -44.5zM1933 751q0 -25 -15 -42t-38 -21q-3 -1 -15 -1h-139v129h139q3 0 8.5 -0.5t6.5 -0.5q23 -4 38 -21.5t15 -42.5zM728 587v308h-228v-308q0 -58 -38 -94.5 t-105 -36.5q-108 0 -229 59v-112q53 -15 121 -23t109 -9l42 -1q328 0 328 217zM1442 403v113q-99 -52 -200 -59q-108 -8 -169 41t-61 142t61 142t169 41q101 -7 200 -58v112q-48 12 -100 19.5t-80 9.5l-28 2q-127 6 -218.5 -14t-140.5 -60t-71 -88t-22 -106t22 -106t71 -88 t140.5 -60t218.5 -14q101 4 208 31zM2176 518q0 54 -43 88.5t-109 39.5v3q57 8 89 41.5t32 79.5q0 55 -41 88t-107 36q-3 0 -12 0.5t-14 0.5h-455v-510h491q74 0 121.5 36.5t47.5 96.5zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90 t90 38h2048q52 0 90 -38t38 -90z" />
+<glyph unicode="&#xf24c;" horiz-adv-x="2304" d="M858 295v693q-106 -41 -172 -135.5t-66 -211.5t66 -211.5t172 -134.5zM1362 641q0 117 -66 211.5t-172 135.5v-694q106 41 172 135.5t66 211.5zM1577 641q0 -159 -78.5 -294t-213.5 -213.5t-294 -78.5q-119 0 -227.5 46.5t-187 125t-125 187t-46.5 227.5q0 159 78.5 294 t213.5 213.5t294 78.5t294 -78.5t213.5 -213.5t78.5 -294zM1960 634q0 139 -55.5 261.5t-147.5 205.5t-213.5 131t-252.5 48h-301q-176 0 -323.5 -81t-235 -230t-87.5 -335q0 -171 87 -317.5t236 -231.5t323 -85h301q129 0 251.5 50.5t214.5 135t147.5 202.5t55.5 246z M2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
+<glyph unicode="&#xf24d;" horiz-adv-x="1792" d="M1664 -96v1088q0 13 -9.5 22.5t-22.5 9.5h-1088q-13 0 -22.5 -9.5t-9.5 -22.5v-1088q0 -13 9.5 -22.5t22.5 -9.5h1088q13 0 22.5 9.5t9.5 22.5zM1792 992v-1088q0 -66 -47 -113t-113 -47h-1088q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1088q66 0 113 -47t47 -113 zM1408 1376v-160h-128v160q0 13 -9.5 22.5t-22.5 9.5h-1088q-13 0 -22.5 -9.5t-9.5 -22.5v-1088q0 -13 9.5 -22.5t22.5 -9.5h160v-128h-160q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1088q66 0 113 -47t47 -113z" />
+<glyph unicode="&#xf24e;" horiz-adv-x="2304" d="M1728 1088l-384 -704h768zM448 1088l-384 -704h768zM1269 1280q-14 -40 -45.5 -71.5t-71.5 -45.5v-1291h608q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1344q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h608v1291q-40 14 -71.5 45.5t-45.5 71.5h-491q-14 0 -23 9t-9 23v64 q0 14 9 23t23 9h491q21 57 70 92.5t111 35.5t111 -35.5t70 -92.5h491q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-491zM1088 1264q33 0 56.5 23.5t23.5 56.5t-23.5 56.5t-56.5 23.5t-56.5 -23.5t-23.5 -56.5t23.5 -56.5t56.5 -23.5zM2176 384q0 -73 -46.5 -131t-117.5 -91 t-144.5 -49.5t-139.5 -16.5t-139.5 16.5t-144.5 49.5t-117.5 91t-46.5 131q0 11 35 81t92 174.5t107 195.5t102 184t56 100q18 33 56 33t56 -33q4 -7 56 -100t102 -184t107 -195.5t92 -174.5t35 -81zM896 384q0 -73 -46.5 -131t-117.5 -91t-144.5 -49.5t-139.5 -16.5 t-139.5 16.5t-144.5 49.5t-117.5 91t-46.5 131q0 11 35 81t92 174.5t107 195.5t102 184t56 100q18 33 56 33t56 -33q4 -7 56 -100t102 -184t107 -195.5t92 -174.5t35 -81z" />
+<glyph unicode="&#xf250;" d="M1408 1408q0 -261 -106.5 -461.5t-266.5 -306.5q160 -106 266.5 -306.5t106.5 -461.5h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96q0 261 106.5 461.5t266.5 306.5q-160 106 -266.5 306.5t-106.5 461.5h-96q-14 0 -23 9 t-9 23v64q0 14 9 23t23 9h1472q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96zM874 700q77 29 149 92.5t129.5 152.5t92.5 210t35 253h-1024q0 -132 35 -253t92.5 -210t129.5 -152.5t149 -92.5q19 -7 30.5 -23.5t11.5 -36.5t-11.5 -36.5t-30.5 -23.5q-77 -29 -149 -92.5 t-129.5 -152.5t-92.5 -210t-35 -253h1024q0 132 -35 253t-92.5 210t-129.5 152.5t-149 92.5q-19 7 -30.5 23.5t-11.5 36.5t11.5 36.5t30.5 23.5z" />
+<glyph unicode="&#xf251;" d="M1408 1408q0 -261 -106.5 -461.5t-266.5 -306.5q160 -106 266.5 -306.5t106.5 -461.5h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96q0 261 106.5 461.5t266.5 306.5q-160 106 -266.5 306.5t-106.5 461.5h-96q-14 0 -23 9 t-9 23v64q0 14 9 23t23 9h1472q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96zM1280 1408h-1024q0 -66 9 -128h1006q9 61 9 128zM1280 -128q0 130 -34 249.5t-90.5 208t-126.5 152t-146 94.5h-230q-76 -31 -146 -94.5t-126.5 -152t-90.5 -208t-34 -249.5h1024z" />
+<glyph unicode="&#xf252;" d="M1408 1408q0 -261 -106.5 -461.5t-266.5 -306.5q160 -106 266.5 -306.5t106.5 -461.5h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96q0 261 106.5 461.5t266.5 306.5q-160 106 -266.5 306.5t-106.5 461.5h-96q-14 0 -23 9 t-9 23v64q0 14 9 23t23 9h1472q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96zM1280 1408h-1024q0 -206 85 -384h854q85 178 85 384zM1223 192q-54 141 -145.5 241.5t-194.5 142.5h-230q-103 -42 -194.5 -142.5t-145.5 -241.5h910z" />
+<glyph unicode="&#xf253;" d="M1408 1408q0 -261 -106.5 -461.5t-266.5 -306.5q160 -106 266.5 -306.5t106.5 -461.5h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96q0 261 106.5 461.5t266.5 306.5q-160 106 -266.5 306.5t-106.5 461.5h-96q-14 0 -23 9 t-9 23v64q0 14 9 23t23 9h1472q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96zM874 700q77 29 149 92.5t129.5 152.5t92.5 210t35 253h-1024q0 -132 35 -253t92.5 -210t129.5 -152.5t149 -92.5q19 -7 30.5 -23.5t11.5 -36.5t-11.5 -36.5t-30.5 -23.5q-137 -51 -244 -196 h700q-107 145 -244 196q-19 7 -30.5 23.5t-11.5 36.5t11.5 36.5t30.5 23.5z" />
+<glyph unicode="&#xf254;" d="M1504 -64q14 0 23 -9t9 -23v-128q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v128q0 14 9 23t23 9h1472zM130 0q3 55 16 107t30 95t46 87t53.5 76t64.5 69.5t66 60t70.5 55t66.5 47.5t65 43q-43 28 -65 43t-66.5 47.5t-70.5 55t-66 60t-64.5 69.5t-53.5 76t-46 87 t-30 95t-16 107h1276q-3 -55 -16 -107t-30 -95t-46 -87t-53.5 -76t-64.5 -69.5t-66 -60t-70.5 -55t-66.5 -47.5t-65 -43q43 -28 65 -43t66.5 -47.5t70.5 -55t66 -60t64.5 -69.5t53.5 -76t46 -87t30 -95t16 -107h-1276zM1504 1536q14 0 23 -9t9 -23v-128q0 -14 -9 -23t-23 -9 h-1472q-14 0 -23 9t-9 23v128q0 14 9 23t23 9h1472z" />
+<glyph unicode="&#xf255;" d="M768 1152q-53 0 -90.5 -37.5t-37.5 -90.5v-128h-32v93q0 48 -32 81.5t-80 33.5q-46 0 -79 -33t-33 -79v-429l-32 30v172q0 48 -32 81.5t-80 33.5q-46 0 -79 -33t-33 -79v-224q0 -47 35 -82l310 -296q39 -39 39 -102q0 -26 19 -45t45 -19h640q26 0 45 19t19 45v25 q0 41 10 77l108 436q10 36 10 77v246q0 48 -32 81.5t-80 33.5q-46 0 -79 -33t-33 -79v-32h-32v125q0 40 -25 72.5t-64 40.5q-14 2 -23 2q-46 0 -79 -33t-33 -79v-128h-32v122q0 51 -32.5 89.5t-82.5 43.5q-5 1 -13 1zM768 1280q84 0 149 -50q57 34 123 34q59 0 111 -27 t86 -76q27 7 59 7q100 0 170 -71.5t70 -171.5v-246q0 -51 -13 -108l-109 -436q-6 -24 -6 -71q0 -80 -56 -136t-136 -56h-640q-84 0 -138 58.5t-54 142.5l-308 296q-76 73 -76 175v224q0 99 70.5 169.5t169.5 70.5q11 0 16 -1q6 95 75.5 160t164.5 65q52 0 98 -21 q72 69 174 69z" />
+<glyph unicode="&#xf256;" horiz-adv-x="1792" d="M880 1408q-46 0 -79 -33t-33 -79v-656h-32v528q0 46 -33 79t-79 33t-79 -33t-33 -79v-528v-256l-154 205q-38 51 -102 51q-53 0 -90.5 -37.5t-37.5 -90.5q0 -43 26 -77l384 -512q38 -51 102 -51h688q34 0 61 22t34 56l76 405q5 32 5 59v498q0 46 -33 79t-79 33t-79 -33 t-33 -79v-272h-32v528q0 46 -33 79t-79 33t-79 -33t-33 -79v-528h-32v656q0 46 -33 79t-79 33zM880 1536q68 0 125.5 -35.5t88.5 -96.5q19 4 42 4q99 0 169.5 -70.5t70.5 -169.5v-17q105 6 180.5 -64t75.5 -175v-498q0 -40 -8 -83l-76 -404q-14 -79 -76.5 -131t-143.5 -52 h-688q-60 0 -114.5 27.5t-90.5 74.5l-384 512q-51 68 -51 154q0 106 75 181t181 75q78 0 128 -34v434q0 99 70.5 169.5t169.5 70.5q23 0 42 -4q31 61 88.5 96.5t125.5 35.5z" />
+<glyph unicode="&#xf257;" horiz-adv-x="1792" d="M1073 -128h-177q-163 0 -226 141q-23 49 -23 102v5q-62 30 -98.5 88.5t-36.5 127.5q0 38 5 48h-261q-106 0 -181 75t-75 181t75 181t181 75h113l-44 17q-74 28 -119.5 93.5t-45.5 145.5q0 106 75 181t181 75q46 0 91 -17l628 -239h401q106 0 181 -75t75 -181v-668 q0 -88 -54 -157.5t-140 -90.5l-339 -85q-92 -23 -186 -23zM1024 583l-155 -71l-163 -74q-30 -14 -48 -41.5t-18 -60.5q0 -46 33 -79t79 -33q26 0 46 10l338 154q-49 10 -80.5 50t-31.5 90v55zM1344 272q0 46 -33 79t-79 33q-26 0 -46 -10l-290 -132q-28 -13 -37 -17 t-30.5 -17t-29.5 -23.5t-16 -29t-8 -40.5q0 -50 31.5 -82t81.5 -32q20 0 38 9l352 160q30 14 48 41.5t18 60.5zM1112 1024l-650 248q-24 8 -46 8q-53 0 -90.5 -37.5t-37.5 -90.5q0 -40 22.5 -73t59.5 -47l526 -200v-64h-640q-53 0 -90.5 -37.5t-37.5 -90.5t37.5 -90.5 t90.5 -37.5h535l233 106v198q0 63 46 106l111 102h-69zM1073 0q82 0 155 19l339 85q43 11 70 45.5t27 78.5v668q0 53 -37.5 90.5t-90.5 37.5h-308l-136 -126q-36 -33 -36 -82v-296q0 -46 33 -77t79 -31t79 35t33 81v208h32v-
 208q0 -70 -57 -114q52 -8 86.5 -48.5t34.5 -93.5 q0 -42 -23 -78t-61 -53l-310 -141h91z" />
+<glyph unicode="&#xf258;" horiz-adv-x="2048" d="M1151 1536q61 0 116 -28t91 -77l572 -781q118 -159 118 -359v-355q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v177l-286 143h-546q-80 0 -136 56t-56 136v32q0 119 84.5 203.5t203.5 84.5h420l42 128h-686q-100 0 -173.5 67.5t-81.5 166.5q-65 79 -65 182v32 q0 80 56 136t136 56h959zM1920 -64v355q0 157 -93 284l-573 781q-39 52 -103 52h-959q-26 0 -45 -19t-19 -45q0 -32 1.5 -49.5t9.5 -40.5t25 -43q10 31 35.5 50t56.5 19h832v-32h-832q-26 0 -45 -19t-19 -45q0 -44 3 -58q8 -44 44 -73t81 -29h640h91q40 0 68 -28t28 -68 q0 -15 -5 -30l-64 -192q-10 -29 -35 -47.5t-56 -18.5h-443q-66 0 -113 -47t-47 -113v-32q0 -26 19 -45t45 -19h561q16 0 29 -7l317 -158q24 -13 38.5 -36t14.5 -50v-197q0 -26 19 -45t45 -19h384q26 0 45 19t19 45z" />
+<glyph unicode="&#xf259;" horiz-adv-x="2048" d="M816 1408q-48 0 -79.5 -34t-31.5 -82q0 -14 3 -28l150 -624h-26l-116 482q-9 38 -39.5 62t-69.5 24q-47 0 -79 -34t-32 -81q0 -11 4 -29q3 -13 39 -161t68 -282t32 -138v-227l-307 230q-34 26 -77 26q-52 0 -89.5 -36.5t-37.5 -88.5q0 -67 56 -110l507 -379 q34 -26 76 -26h694q33 0 59 20.5t34 52.5l100 401q8 30 10 88t9 86l116 478q3 12 3 26q0 46 -33 79t-80 33q-38 0 -69 -25.5t-40 -62.5l-99 -408h-26l132 547q3 14 3 28q0 47 -32 80t-80 33q-38 0 -68.5 -24t-39.5 -62l-145 -602h-127l-164 682q-9 38 -39.5 62t-68.5 24z M1461 -256h-694q-85 0 -153 51l-507 380q-50 38 -78.5 94t-28.5 118q0 105 75 179t180 74q25 0 49.5 -5.5t41.5 -11t41 -20.5t35 -23t38.5 -29.5t37.5 -28.5l-123 512q-7 35 -7 59q0 93 60 162t152 79q14 87 80.5 144.5t155.5 57.5q83 0 148 -51.5t85 -132.5l103 -428 l83 348q20 81 85 132.5t148 51.5q87 0 152.5 -54t82.5 -139q93 -10 155 -78t62 -161q0 -30 -7 -57l-116 -477q-5 -22 -5 -67q0 -51 -13 -108l-101 -401q-19 -75 -79.5 -122.5t-137.5 -47.5z" />
+<glyph unicode="&#xf25a;" horiz-adv-x="1792" d="M640 1408q-53 0 -90.5 -37.5t-37.5 -90.5v-512v-384l-151 202q-41 54 -107 54q-52 0 -89 -38t-37 -90q0 -43 26 -77l384 -512q38 -51 102 -51h718q22 0 39.5 13.5t22.5 34.5l92 368q24 96 24 194v217q0 41 -28 71t-68 30t-68 -28t-28 -68h-32v61q0 48 -32 81.5t-80 33.5 q-46 0 -79 -33t-33 -79v-64h-32v90q0 55 -37 94.5t-91 39.5q-53 0 -90.5 -37.5t-37.5 -90.5v-96h-32v570q0 55 -37 94.5t-91 39.5zM640 1536q107 0 181.5 -77.5t74.5 -184.5v-220q22 2 32 2q99 0 173 -69q47 21 99 21q113 0 184 -87q27 7 56 7q94 0 159 -67.5t65 -161.5 v-217q0 -116 -28 -225l-92 -368q-16 -64 -68 -104.5t-118 -40.5h-718q-60 0 -114.5 27.5t-90.5 74.5l-384 512q-51 68 -51 154q0 105 74.5 180.5t179.5 75.5q71 0 130 -35v547q0 106 75 181t181 75zM768 128v384h-32v-384h32zM1024 128v384h-32v-384h32zM1280 128v384h-32 v-384h32z" />
+<glyph unicode="&#xf25b;" d="M1288 889q60 0 107 -23q141 -63 141 -226v-177q0 -94 -23 -186l-85 -339q-21 -86 -90.5 -140t-157.5 -54h-668q-106 0 -181 75t-75 181v401l-239 628q-17 45 -17 91q0 106 75 181t181 75q80 0 145.5 -45.5t93.5 -119.5l17 -44v113q0 106 75 181t181 75t181 -75t75 -181 v-261q27 5 48 5q69 0 127.5 -36.5t88.5 -98.5zM1072 896q-33 0 -60.5 -18t-41.5 -48l-74 -163l-71 -155h55q50 0 90 -31.5t50 -80.5l154 338q10 20 10 46q0 46 -33 79t-79 33zM1293 761q-22 0 -40.5 -8t-29 -16t-23.5 -29.5t-17 -30.5t-17 -37l-132 -290q-10 -20 -10 -46 q0 -46 33 -79t79 -33q33 0 60.5 18t41.5 48l160 352q9 18 9 38q0 50 -32 81.5t-82 31.5zM128 1120q0 -22 8 -46l248 -650v-69l102 111q43 46 106 46h198l106 233v535q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5v-640h-64l-200 526q-14 37 -47 59.5t-73 22.5 q-53 0 -90.5 -37.5t-37.5 -90.5zM1180 -128q44 0 78.5 27t45.5 70l85 339q19 73 19 155v91l-141 -310q-17 -38 -53 -61t-78 -23q-53 0 -93.5 34.5t-48.5 86.5q-44 -57 -114 -57h-208v32h208q46 0 81 33t35 79t-31 79t-77 33h-296q-49 
 0 -82 -36l-126 -136v-308 q0 -53 37.5 -90.5t90.5 -37.5h668z" />
+<glyph unicode="&#xf25c;" horiz-adv-x="1973" d="M857 992v-117q0 -13 -9.5 -22t-22.5 -9h-298v-812q0 -13 -9 -22.5t-22 -9.5h-135q-13 0 -22.5 9t-9.5 23v812h-297q-13 0 -22.5 9t-9.5 22v117q0 14 9 23t23 9h793q13 0 22.5 -9.5t9.5 -22.5zM1895 995l77 -961q1 -13 -8 -24q-10 -10 -23 -10h-134q-12 0 -21 8.5 t-10 20.5l-46 588l-189 -425q-8 -19 -29 -19h-120q-20 0 -29 19l-188 427l-45 -590q-1 -12 -10 -20.5t-21 -8.5h-135q-13 0 -23 10q-9 10 -9 24l78 961q1 12 10 20.5t21 8.5h142q20 0 29 -19l220 -520q10 -24 20 -51q3 7 9.5 24.5t10.5 26.5l221 520q9 19 29 19h141 q13 0 22 -8.5t10 -20.5z" />
+<glyph unicode="&#xf25d;" horiz-adv-x="1792" d="M1042 833q0 88 -60 121q-33 18 -117 18h-123v-281h162q66 0 102 37t36 105zM1094 548l205 -373q8 -17 -1 -31q-8 -16 -27 -16h-152q-20 0 -28 17l-194 365h-155v-350q0 -14 -9 -23t-23 -9h-134q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h294q128 0 190 -24q85 -31 134 -109 t49 -180q0 -92 -42.5 -165.5t-115.5 -109.5q6 -10 9 -16zM896 1376q-150 0 -286 -58.5t-234.5 -157t-157 -234.5t-58.5 -286t58.5 -286t157 -234.5t234.5 -157t286 -58.5t286 58.5t234.5 157t157 234.5t58.5 286t-58.5 286t-157 234.5t-234.5 157t-286 58.5zM1792 640 q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
+<glyph unicode="&#xf25e;" horiz-adv-x="1792" d="M605 303q153 0 257 104q14 18 3 36l-45 82q-6 13 -24 17q-16 2 -27 -11l-4 -3q-4 -4 -11.5 -10t-17.5 -13t-23.5 -14.5t-28.5 -13.5t-33.5 -9.5t-37.5 -3.5q-76 0 -125 50t-49 127q0 76 48 125.5t122 49.5q37 0 71.5 -14t50.5 -28l16 -14q11 -11 26 -10q16 2 24 14l53 78 q13 20 -2 39q-3 4 -11 12t-30 23.5t-48.5 28t-67.5 22.5t-86 10q-148 0 -246 -96.5t-98 -240.5q0 -146 97 -241.5t247 -95.5zM1235 303q153 0 257 104q14 18 4 36l-45 82q-8 14 -25 17q-16 2 -27 -11l-4 -3q-4 -4 -11.5 -10t-17.5 -13t-23.5 -14.5t-28.5 -13.5t-33.5 -9.5 t-37.5 -3.5q-76 0 -125 50t-49 127q0 76 48 125.5t122 49.5q37 0 71.5 -14t50.5 -28l16 -14q11 -11 26 -10q16 2 24 14l53 78q13 20 -2 39q-3 4 -11 12t-30 23.5t-48.5 28t-67.5 22.5t-86 10q-147 0 -245.5 -96.5t-98.5 -240.5q0 -146 97 -241.5t247 -95.5zM896 1376 q-150 0 -286 -58.5t-234.5 -157t-157 -234.5t-58.5 -286t58.5 -286t157 -234.5t234.5 -157t286 -58.5t286 58.5t234.5 157t157 234.5t58.5 286t-58.5 286t-157 234.5t-234.5 157t-286 58.5zM896 1536q182 0 348 
 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191 t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71z" />
+<glyph unicode="&#xf260;" horiz-adv-x="2048" d="M736 736l384 -384l-384 -384l-672 672l672 672l168 -168l-96 -96l-72 72l-480 -480l480 -480l193 193l-289 287zM1312 1312l672 -672l-672 -672l-168 168l96 96l72 -72l480 480l-480 480l-193 -193l289 -287l-96 -96l-384 384z" />
+<glyph unicode="&#xf261;" horiz-adv-x="1792" d="M717 182l271 271l-279 279l-88 -88l192 -191l-96 -96l-279 279l279 279l40 -40l87 87l-127 128l-454 -454zM1075 190l454 454l-454 454l-271 -271l279 -279l88 88l-192 191l96 96l279 -279l-279 -279l-40 40l-87 -88zM1792 640q0 -182 -71 -348t-191 -286t-286 -191 t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
+<glyph unicode="&#xf262;" horiz-adv-x="2304" d="M651 539q0 -39 -27.5 -66.5t-65.5 -27.5q-39 0 -66.5 27.5t-27.5 66.5q0 38 27.5 65.5t66.5 27.5q38 0 65.5 -27.5t27.5 -65.5zM1805 540q0 -39 -27.5 -66.5t-66.5 -27.5t-66.5 27.5t-27.5 66.5t27.5 66t66.5 27t66.5 -27t27.5 -66zM765 539q0 79 -56.5 136t-136.5 57 t-136.5 -56.5t-56.5 -136.5t56.5 -136.5t136.5 -56.5t136.5 56.5t56.5 136.5zM1918 540q0 80 -56.5 136.5t-136.5 56.5q-79 0 -136 -56.5t-57 -136.5t56.5 -136.5t136.5 -56.5t136.5 56.5t56.5 136.5zM850 539q0 -116 -81.5 -197.5t-196.5 -81.5q-116 0 -197.5 82t-81.5 197 t82 196.5t197 81.5t196.5 -81.5t81.5 -196.5zM2004 540q0 -115 -81.5 -196.5t-197.5 -81.5q-115 0 -196.5 81.5t-81.5 196.5t81.5 196.5t196.5 81.5q116 0 197.5 -81.5t81.5 -196.5zM1040 537q0 191 -135.5 326.5t-326.5 135.5q-125 0 -231 -62t-168 -168.5t-62 -231.5 t62 -231.5t168 -168.5t231 -62q191 0 326.5 135.5t135.5 326.5zM1708 1110q-254 111 -556 111q-319 0 -573 -110q117 0 223 -45.5t182.5 -122.5t122 -183t45.5 -223q0 115 43.5 219.5t118 180.5t177.5 123t217 
 50zM2187 537q0 191 -135 326.5t-326 135.5t-326.5 -135.5 t-135.5 -326.5t135.5 -326.5t326.5 -135.5t326 135.5t135 326.5zM1921 1103h383q-44 -51 -75 -114.5t-40 -114.5q110 -151 110 -337q0 -156 -77 -288t-209 -208.5t-287 -76.5q-133 0 -249 56t-196 155q-47 -56 -129 -179q-11 22 -53.5 82.5t-74.5 97.5 q-80 -99 -196.5 -155.5t-249.5 -56.5q-155 0 -287 76.5t-209 208.5t-77 288q0 186 110 337q-9 51 -40 114.5t-75 114.5h365q149 100 355 156.5t432 56.5q224 0 421 -56t348 -157z" />
+<glyph unicode="&#xf263;" horiz-adv-x="1280" d="M640 629q-188 0 -321 133t-133 320q0 188 133 321t321 133t321 -133t133 -321q0 -187 -133 -320t-321 -133zM640 1306q-92 0 -157.5 -65.5t-65.5 -158.5q0 -92 65.5 -157.5t157.5 -65.5t157.5 65.5t65.5 157.5q0 93 -65.5 158.5t-157.5 65.5zM1163 574q13 -27 15 -49.5 t-4.5 -40.5t-26.5 -38.5t-42.5 -37t-61.5 -41.5q-115 -73 -315 -94l73 -72l267 -267q30 -31 30 -74t-30 -73l-12 -13q-31 -30 -74 -30t-74 30q-67 68 -267 268l-267 -268q-31 -30 -74 -30t-73 30l-12 13q-31 30 -31 73t31 74l267 267l72 72q-203 21 -317 94 q-39 25 -61.5 41.5t-42.5 37t-26.5 38.5t-4.5 40.5t15 49.5q10 20 28 35t42 22t56 -2t65 -35q5 -4 15 -11t43 -24.5t69 -30.5t92 -24t113 -11q91 0 174 25.5t120 50.5l38 25q33 26 65 35t56 2t42 -22t28 -35z" />
+<glyph unicode="&#xf264;" d="M927 956q0 -66 -46.5 -112.5t-112.5 -46.5t-112.5 46.5t-46.5 112.5t46.5 112.5t112.5 46.5t112.5 -46.5t46.5 -112.5zM1141 593q-10 20 -28 32t-47.5 9.5t-60.5 -27.5q-10 -8 -29 -20t-81 -32t-127 -20t-124 18t-86 36l-27 18q-31 25 -60.5 27.5t-47.5 -9.5t-28 -32 q-22 -45 -2 -74.5t87 -73.5q83 -53 226 -67l-51 -52q-142 -142 -191 -190q-22 -22 -22 -52.5t22 -52.5l9 -9q22 -22 52.5 -22t52.5 22l191 191q114 -115 191 -191q22 -22 52.5 -22t52.5 22l9 9q22 22 22 52.5t-22 52.5l-191 190l-52 52q141 14 225 67q67 44 87 73.5t-2 74.5 zM1092 956q0 134 -95 229t-229 95t-229 -95t-95 -229t95 -229t229 -95t229 95t95 229zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+<glyph unicode="&#xf265;" horiz-adv-x="1720" d="M1565 1408q65 0 110 -45.5t45 -110.5v-519q0 -176 -68 -336t-182.5 -275t-274 -182.5t-334.5 -67.5q-176 0 -335.5 67.5t-274.5 182.5t-183 275t-68 336v519q0 64 46 110t110 46h1409zM861 344q47 0 82 33l404 388q37 35 37 85q0 49 -34.5 83.5t-83.5 34.5q-47 0 -82 -33 l-323 -310l-323 310q-35 33 -81 33q-49 0 -83.5 -34.5t-34.5 -83.5q0 -51 36 -85l405 -388q33 -33 81 -33z" />
+<glyph unicode="&#xf266;" horiz-adv-x="2304" d="M1494 -103l-295 695q-25 -49 -158.5 -305.5t-198.5 -389.5q-1 -1 -27.5 -0.5t-26.5 1.5q-82 193 -255.5 587t-259.5 596q-21 50 -66.5 107.5t-103.5 100.5t-102 43q0 5 -0.5 24t-0.5 27h583v-50q-39 -2 -79.5 -16t-66.5 -43t-10 -64q26 -59 216.5 -499t235.5 -540 q31 61 140 266.5t131 247.5q-19 39 -126 281t-136 295q-38 69 -201 71v50l513 -1v-47q-60 -2 -93.5 -25t-12.5 -69q33 -70 87 -189.5t86 -187.5q110 214 173 363q24 55 -10 79.5t-129 26.5q1 7 1 25v24q64 0 170.5 0.5t180 1t92.5 0.5v-49q-62 -2 -119 -33t-90 -81 l-213 -442q13 -33 127.5 -290t121.5 -274l441 1017q-14 38 -49.5 62.5t-65 31.5t-55.5 8v50l460 -4l1 -2l-1 -44q-139 -4 -201 -145q-526 -1216 -559 -1291h-49z" />
+<glyph unicode="&#xf267;" horiz-adv-x="1792" d="M949 643q0 -26 -16.5 -45t-41.5 -19q-26 0 -45 16.5t-19 41.5q0 26 17 45t42 19t44 -16.5t19 -41.5zM964 585l350 581q-9 -8 -67.5 -62.5t-125.5 -116.5t-136.5 -127t-117 -110.5t-50.5 -51.5l-349 -580q7 7 67 62t126 116.5t136 127t117 111t50 50.5zM1611 640 q0 -201 -104 -371q-3 2 -17 11t-26.5 16.5t-16.5 7.5q-13 0 -13 -13q0 -10 59 -44q-74 -112 -184.5 -190.5t-241.5 -110.5l-16 67q-1 10 -15 10q-5 0 -8 -5.5t-2 -9.5l16 -68q-72 -15 -146 -15q-199 0 -372 105q1 2 13 20.5t21.5 33.5t9.5 19q0 13 -13 13q-6 0 -17 -14.5 t-22.5 -34.5t-13.5 -23q-113 75 -192 187.5t-110 244.5l69 15q10 3 10 15q0 5 -5.5 8t-10.5 2l-68 -15q-14 72 -14 139q0 206 109 379q2 -1 18.5 -12t30 -19t17.5 -8q13 0 13 12q0 6 -12.5 15.5t-32.5 21.5l-20 12q77 112 189 189t244 107l15 -67q2 -10 15 -10q5 0 8 5.5 t2 10.5l-15 66q71 13 134 13q204 0 379 -109q-39 -56 -39 -65q0 -13 12 -13q11 0 48 64q111 -75 187.5 -186t107.5 -241l-56 -12q-10 -2 -10 -16q0 -5 5.5 -8t9.5 -2l57 13q14 -72 14 -140zM1696 640q0 163 -63.5 311t
 -170.5 255t-255 170.5t-311 63.5t-311 -63.5 t-255 -170.5t-170.5 -255t-63.5 -311t63.5 -311t170.5 -255t255 -170.5t311 -63.5t311 63.5t255 170.5t170.5 255t63.5 311zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191 t191 -286t71 -348z" />
+<glyph unicode="&#xf268;" horiz-adv-x="1792" d="M893 1536q240 2 451 -120q232 -134 352 -372l-742 39q-160 9 -294 -74.5t-185 -229.5l-276 424q128 159 311 245.5t383 87.5zM146 1131l337 -663q72 -143 211 -217t293 -45l-230 -451q-212 33 -385 157.5t-272.5 316t-99.5 411.5q0 267 146 491zM1732 962 q58 -150 59.5 -310.5t-48.5 -306t-153 -272t-246 -209.5q-230 -133 -498 -119l405 623q88 131 82.5 290.5t-106.5 277.5zM896 942q125 0 213.5 -88.5t88.5 -213.5t-88.5 -213.5t-213.5 -88.5t-213.5 88.5t-88.5 213.5t88.5 213.5t213.5 88.5z" />
+<glyph unicode="&#xf269;" horiz-adv-x="1792" d="M903 -256q-283 0 -504.5 150.5t-329.5 398.5q-58 131 -67 301t26 332.5t111 312t179 242.5l-11 -281q11 14 68 15.5t70 -15.5q42 81 160.5 138t234.5 59q-54 -45 -119.5 -148.5t-58.5 -163.5q25 -8 62.5 -13.5t63 -7.5t68 -4t50.5 -3q15 -5 9.5 -45.5t-30.5 -75.5 q-5 -7 -16.5 -18.5t-56.5 -35.5t-101 -34l15 -189l-139 67q-18 -43 -7.5 -81.5t36 -66.5t65.5 -41.5t81 -6.5q51 9 98 34.5t83.5 45t73.5 17.5q61 -4 89.5 -33t19.5 -65q-1 -2 -2.5 -5.5t-8.5 -12.5t-18 -15.5t-31.5 -10.5t-46.5 -1q-60 -95 -144.5 -135.5t-209.5 -29.5 q74 -61 162.5 -82.5t168.5 -6t154.5 52t128 87.5t80.5 104q43 91 39 192.5t-37.5 188.5t-78.5 125q87 -38 137 -79.5t77 -112.5q15 170 -57.5 343t-209.5 284q265 -77 412 -279.5t151 -517.5q2 -127 -40.5 -255t-123.5 -238t-189 -196t-247.5 -135.5t-288.5 -49.5z" />
+<glyph unicode="&#xf26a;" d="M768 -92q77 0 139.5 63t100.5 166t59 234.5t21 268.5t-21 268.5t-59 234.5t-100.5 166t-139.5 63t-139.5 -63t-100.5 -166t-59 -234.5t-21 -268.5t21 -268.5t59 -234.5t100.5 -166t139.5 -63zM768 -256q-184 0 -333 77t-240 203t-141 287t-50 329t50 329t141 287t240 203 t333 77q148 0 274 -50t214.5 -136t151.5 -201t92.5 -244t29.5 -265t-29.5 -265t-92.5 -244t-151.5 -201t-214.5 -136t-274 -50z" />
+<glyph unicode="&#xf26b;" horiz-adv-x="1792" d="M716 -69q-143 35 -261.5 114t-197.5 191q-139 -300 -17 -398q26 -21 85 -24.5t127.5 9.5t141 41.5t122.5 66.5zM693 762h452q0 108 -61.5 169t-168.5 61q-103 0 -162.5 -62.5t-59.5 -167.5zM1724 1137h-34q26 102 22.5 170t-25 110t-63.5 57t-93.5 11t-115 -26.5 t-128.5 -56.5t-134 -79q129 -37 238.5 -113.5t185 -179t110 -231.5t15.5 -262h-1005q0 -60 10 -106t34 -85t69.5 -60t112.5 -21q87 0 142.5 44t72.5 122h540q-71 -230 -281.5 -377t-477.5 -147q-83 0 -159 15q-35 -40 -151 -94t-248 -78t-219 35q-78 60 -100 159t7 214 t88 242t143.5 248t173.5 226.5t177.5 183.5t156.5 112v24q-120 -37 -258.5 -137.5t-240.5 -207t-159 -195.5q4 106 34 201t80 169t118 135.5t147.5 100.5t168 65.5t180.5 29.5t185 -8q310 186 503 189h7q57 0 103 -18q80 -30 98 -132.5t-30 -248.5z" />
+<glyph unicode="&#xf26c;" horiz-adv-x="2048" d="M1792 288v960q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5zM1920 1248v-960q0 -66 -47 -113t-113 -47h-736v-128h352q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23 v64q0 14 9 23t23 9h352v128h-736q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
+<glyph unicode="&#xf26d;" horiz-adv-x="1792" d="M138 1408h197q-70 -64 -126 -149q-36 -56 -59 -115t-30 -125.5t-8.5 -120t10.5 -132t21 -126t28 -136.5q4 -19 6 -28q51 -238 81 -329q57 -171 152 -275h-272q-48 0 -82 34t-34 82v1304q0 48 34 82t82 34zM1346 1408h308q48 0 82 -34t34 -82v-1304q0 -48 -34 -82t-82 -34 h-178q212 210 196 565l-469 -101q-2 -45 -12 -82t-31 -72t-59.5 -59.5t-93.5 -36.5q-123 -26 -199 40q-32 27 -53 61t-51.5 129t-64.5 258q-35 163 -45.5 263t-5.5 139t23 77q20 41 62.5 73t102.5 45q45 12 83.5 6.5t67 -17t54 -35t43 -48t34.5 -56.5l468 100 q-68 175 -180 287z" />
+<glyph unicode="&#xf26e;" horiz-adv-x="2304" d="M1391 390v0l-1 1q-15 18 -34.5 37.5t-

<TRUNCATED>
http://git-wip-us.apache.org/repos/asf/allura/blob/47743877/Allura/allura/public/nf/fonts/fontawesome-webfont.ttf
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/fonts/fontawesome-webfont.ttf b/Allura/allura/public/nf/fonts/fontawesome-webfont.ttf
index ed9372f..d7994e1 100644
Binary files a/Allura/allura/public/nf/fonts/fontawesome-webfont.ttf and b/Allura/allura/public/nf/fonts/fontawesome-webfont.ttf differ


[46/50] [abbrv] allura git commit: [#7924] ticket:836 Update other perm_* icons

Posted by je...@apache.org.
[#7924] ticket:836 Update other perm_* icons

Can be found on /p/test/admin/permissions/


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/939847bb
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/939847bb
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/939847bb

Branch: refs/heads/ib/7924
Commit: 939847bbd520c01bd3f905c63add6a2cec4609c2
Parents: 3197323
Author: Igor Bondarenko <je...@gmail.com>
Authored: Thu Aug 13 16:36:59 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Thu Oct 15 15:08:33 2015 +0000

----------------------------------------------------------------------
 Allura/allura/lib/app_globals.py | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/939847bb/Allura/allura/lib/app_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/app_globals.py b/Allura/allura/lib/app_globals.py
index cdcaf54..faf82b4 100644
--- a/Allura/allura/lib/app_globals.py
+++ b/Allura/allura/lib/app_globals.py
@@ -254,16 +254,16 @@ class Globals(object):
             unsecure=Icon('fa fa-unlock', 'Unlock'),
             star=Icon('fa fa-star', 'Star'),
             # Permissions
-            perm_read=Icon('E', 'ico-focus'),
-            perm_update=Icon('0', 'ico-sync'),
-            perm_create=Icon('e', 'ico-config'),
-            perm_register=Icon('e', 'ico-config'),
+            perm_read=Icon('fa fa-eye', 'Read'),
+            perm_update=Icon('fa fa-rotate-left', 'Update'),
+            perm_create=Icon('fa fa-flash', 'Create'),
+            perm_register=Icon('fa fa-gear', 'Config'),
             perm_delete=Icon('fa fa-minus-circle', 'Remove'),
-            perm_tool=Icon('x', 'ico-config'),
-            perm_admin=Icon('(', 'ico-lock'),
+            perm_tool=Icon('fa fa-gear', 'Tool'),
+            perm_admin=Icon('fa fa-gear', 'Admin'),
             perm_has_yes=Icon('fa fa-check', 'Check'),
             perm_has_no=Icon('fa fa-ban', 'No entry'),
-            perm_has_inherit=Icon('2', 'ico-checkcircle'),
+            perm_has_inherit=Icon('fa fa-check-circle', 'Has inherit'),
         )
 
         # Cache some loaded entry points


[06/50] [abbrv] allura git commit: [#7994] automatically merge multiple threads if that occurs

Posted by je...@apache.org.
[#7994] automatically merge multiple threads if that occurs


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/8142fb6f
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/8142fb6f
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/8142fb6f

Branch: refs/heads/ib/7924
Commit: 8142fb6ff2f2d0e26ed0d0a657c486e36e0cda72
Parents: e9a4eea
Author: Dave Brondsema <da...@brondsema.net>
Authored: Fri Sep 25 13:31:21 2015 -0400
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Fri Sep 25 13:36:12 2015 -0400

----------------------------------------------------------------------
 Allura/allura/model/artifact.py            | 23 +++++++++++++++++++++--
 Allura/allura/tests/model/test_artifact.py | 24 ++++++++++++++++++++++++
 2 files changed, 45 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/8142fb6f/Allura/allura/model/artifact.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/artifact.py b/Allura/allura/model/artifact.py
index 1d4e230..67cbf3b 100644
--- a/Allura/allura/model/artifact.py
+++ b/Allura/allura/model/artifact.py
@@ -346,19 +346,38 @@ class Artifact(MappedClass, SearchIndexable):
 
         """
         from .discuss import Thread
-        t = Thread.query.get(ref_id=self.index_id())
-        if t is None:
+        threads = Thread.query.find(dict(ref_id=self.index_id())).all()
+        if not threads:
             idx = self.index()
             t = Thread.new(
                 app_config_id=self.app_config_id,
                 discussion_id=self.app_config.discussion_id,
                 ref_id=idx['id'],
                 subject='%s discussion' % h.get_first(idx, 'title'))
+        elif len(threads) == 1:
+            t = threads[0]
+        else:
+            # there should not be multiple threads, we'll merge them
+            destination = threads.pop()
+            for thread in threads:
+                for post in thread.posts:
+                    post.thread_id = destination._id
+                    destination.num_replies += 1
+                    destination.last_post_date = max(destination.last_post_date, post.mod_date)
+                    session(post).flush(post)
+                    session(post).expunge(post)  # so thread.posts ref later in the code doesn't use stale posts
+                Thread.query.remove({'_id': thread._id})  # NOT thread.delete() since that would remove its posts too
+                thread.attachment_class().query.update({'thread_id': thread._id},
+                                                       {'$set': {'thread_id': destination._id}},
+                                                       multi=True)
+            t = destination
+
         parent_id = None
         if data:
             in_reply_to = data.get('in_reply_to', [])
             if in_reply_to:
                 parent_id = in_reply_to[0]
+
         return t, parent_id
 
     @LazyProperty

http://git-wip-us.apache.org/repos/asf/allura/blob/8142fb6f/Allura/allura/tests/model/test_artifact.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/model/test_artifact.py b/Allura/allura/tests/model/test_artifact.py
index adbae4e..b7e9dc0 100644
--- a/Allura/allura/tests/model/test_artifact.py
+++ b/Allura/allura/tests/model/test_artifact.py
@@ -222,3 +222,27 @@ def test_last_updated_disabled(_datetime):
         assert_equal(c.project.last_updated, datetime(2014, 1, 1))
     finally:
         M.artifact_orm_session._get().skip_last_updated = False
+
+
+@with_setup(setUp, tearDown)
+def test_get_discussion_thread_dupe():
+    artif = WM.Page(title='TestSomeArtifact')
+    thr1 = artif.get_discussion_thread()[0]
+    thr1.post('thr1-post1')
+    thr1.post('thr1-post2')
+    thr2 = M.Thread.new(ref_id=thr1.ref_id)
+    thr2.post('thr2-post1')
+    thr2.post('thr2-post2')
+    thr2.post('thr2-post3')
+    thr3 = M.Thread.new(ref_id=thr1.ref_id)
+    thr3.post('thr3-post1')
+    thr4 = M.Thread.new(ref_id=thr1.ref_id)
+
+    thread_q = M.Thread.query.find(dict(ref_id=artif.index_id()))
+    assert_equal(thread_q.count(), 4)
+
+    thread = artif.get_discussion_thread()[0]  # force cleanup
+    threads = thread_q.all()
+    assert_equal(len(threads), 1)
+    assert_equal(len(thread.posts), 6)
+    assert not any(p.deleted for p in thread.posts)  # normal thread deletion propagates to children, make sure that doesn't happen


[17/50] [abbrv] allura git commit: fix JS error when viewing ticket list page that has no tickets

Posted by je...@apache.org.
fix JS error when viewing ticket list page that has no tickets


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/70001e20
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/70001e20
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/70001e20

Branch: refs/heads/ib/7924
Commit: 70001e2016b993aa2863b2b2a3a53ef55d691dfc
Parents: cd63778
Author: Dave Brondsema <da...@brondsema.net>
Authored: Thu Oct 1 14:54:50 2015 -0400
Committer: Heith Seewald <hs...@hsmb.local>
Committed: Fri Oct 2 10:01:49 2015 -0400

----------------------------------------------------------------------
 ForgeTracker/forgetracker/widgets/resources/js/ticket-list.js | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/70001e20/ForgeTracker/forgetracker/widgets/resources/js/ticket-list.js
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/widgets/resources/js/ticket-list.js b/ForgeTracker/forgetracker/widgets/resources/js/ticket-list.js
index 9221389..9d060e6 100644
--- a/ForgeTracker/forgetracker/widgets/resources/js/ticket-list.js
+++ b/ForgeTracker/forgetracker/widgets/resources/js/ticket-list.js
@@ -150,7 +150,10 @@
     });
 
     function select_active_filter() {
-      /* this 'filter' var is set in HTML */
+      /* this 'filter' var is set in HTML on list pages (if there are tickets) */
+      if (typeof filter === 'undefined') {
+          return;
+      }
       for (var name in filter) {
         var fname = 'filter-' + name;
         var $select = $('select[name="' + fname + '"]');


[27/50] [abbrv] allura git commit: [#7980] Fix many pep8 / pyflakes and related issues

Posted by je...@apache.org.
http://git-wip-us.apache.org/repos/asf/allura/blob/9d39b9a7/Allura/setup.cfg
----------------------------------------------------------------------
diff --git a/Allura/setup.cfg b/Allura/setup.cfg
index a835b71..0298938 100644
--- a/Allura/setup.cfg
+++ b/Allura/setup.cfg
@@ -15,6 +15,12 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
+[pep8]
+max-line-length = 119
+
+[flake8]
+max-line-length = 119
+
 [egg_info]
 tag_build = dev0
 

http://git-wip-us.apache.org/repos/asf/allura/blob/9d39b9a7/ForgeActivity/forgeactivity/tests/functional/test_rest.py
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/tests/functional/test_rest.py b/ForgeActivity/forgeactivity/tests/functional/test_rest.py
index f85639a..8c9e0f5 100644
--- a/ForgeActivity/forgeactivity/tests/functional/test_rest.py
+++ b/ForgeActivity/forgeactivity/tests/functional/test_rest.py
@@ -33,9 +33,9 @@ class TestActivityHasAccessAPI(TestRestApiBase):
         config['activitystream.enabled'] = self._enabled
 
     def test_has_access_no_params(self):
-        r = self.api_get('/rest/p/test/activity/has_access', status=404)
-        r = self.api_get('/rest/p/test/activity/has_access?user=root', status=404)
-        r = self.api_get('/rest/p/test/activity/has_access?perm=read', status=404)
+        self.api_get('/rest/p/test/activity/has_access', status=404)
+        self.api_get('/rest/p/test/activity/has_access?user=root', status=404)
+        self.api_get('/rest/p/test/activity/has_access?perm=read', status=404)
 
     def test_has_access_unknown_params(self):
         """Unknown user and/or permission always False for has_access API"""

http://git-wip-us.apache.org/repos/asf/allura/blob/9d39b9a7/ForgeBlog/forgeblog/tests/functional/test_rest.py
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/tests/functional/test_rest.py b/ForgeBlog/forgeblog/tests/functional/test_rest.py
index 3df73da..e7a9d7b 100644
--- a/ForgeBlog/forgeblog/tests/functional/test_rest.py
+++ b/ForgeBlog/forgeblog/tests/functional/test_rest.py
@@ -214,9 +214,9 @@ class TestBlogApi(TestRestApiBase):
         assert_equal(r.json['page'], 2)
 
     def test_has_access_no_params(self):
-        r = self.api_get('/rest/p/test/blog/has_access', status=404)
-        r = self.api_get('/rest/p/test/blog/has_access?user=root', status=404)
-        r = self.api_get('/rest/p/test/blog/has_access?perm=read', status=404)
+        self.api_get('/rest/p/test/blog/has_access', status=404)
+        self.api_get('/rest/p/test/blog/has_access?user=root', status=404)
+        self.api_get('/rest/p/test/blog/has_access?perm=read', status=404)
 
     def test_has_access_unknown_params(self):
         """Unknown user and/or permission always False for has_access API"""

http://git-wip-us.apache.org/repos/asf/allura/blob/9d39b9a7/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
index caad619..c66d5f8 100644
--- a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
+++ b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
@@ -26,7 +26,7 @@ from email.mime.multipart import MIMEMultipart
 
 import pkg_resources
 from pylons import tmpl_context as c
-from nose.tools import assert_equal, assert_in, assert_not_in
+from nose.tools import assert_equal, assert_in, assert_not_in, assert_true, assert_false
 import feedparser
 
 from allura import model as M
@@ -147,9 +147,8 @@ class TestForumAsync(TestController):
         self.user = M.User.query.get(username='root')
 
     def test_has_access(self):
-        assert False == c.app.has_access(M.User.anonymous(), 'testforum')
-        assert True == c.app.has_access(
-            M.User.query.get(username='root'), 'testforum')
+        assert_false(c.app.has_access(M.User.anonymous(), 'testforum'))
+        assert_true(c.app.has_access(M.User.query.get(username='root'), 'testforum'))
 
     def test_post(self):
         self._post('testforum', 'Test Thread', 'Nothing here')
@@ -209,9 +208,8 @@ class TestForumAsync(TestController):
         params = dict()
         inputs = f.findAll('input')
         for field in inputs:
-            if field.has_key('name'):
-                params[field['name']] = field.has_key(
-                    'value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params['subject'] = 'New Subject'
         params['text'] = 'Asdf'
         r = self.app.post(url, params=params)
@@ -221,9 +219,8 @@ class TestForumAsync(TestController):
         params = dict()
         inputs = post_form.findAll('input')
         for field in inputs:
-            if field.has_key('name'):
-                params[field['name']] = field.has_key(
-                    'value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params[post_form.find('textarea')['name']] = 'text'
         r = self.app.post(url + 'reply', params=params)
         self._post('testforum', 'Test Reply', 'Nothing here, either',
@@ -317,7 +314,6 @@ class TestForum(TestController):
                 form[field.name] = 'Test_Description'
         return form
 
-
     def test_unicode_name(self):
         r = self.app.get('/admin/discussion/forums')
         form = r.forms[3]
@@ -375,9 +371,8 @@ class TestForum(TestController):
             params = dict()
             inputs = f.findAll('input')
             for field in inputs:
-                if field.has_key('name'):
-                    params[field['name']] = field.has_key(
-                        'value') and field['value'] or ''
+                if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                    params[field['name']] = field.get('value') or ''
             params[f.find('textarea')['name']] = '1st post in Zero Posts thread'
             params[f.find('select')['name']] = 'testforum'
             params[f.find('input', {'style': 'width: 90%'})['name']] = 'Test Zero Posts'
@@ -419,8 +414,8 @@ class TestForum(TestController):
         params = dict()
         inputs = f.findAll('input')
         for field in inputs:
-            if field.has_key('name'):
-                params[field['name']] = field.has_key('value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = 'This is a *test thread*'
         params[f.find('select')['name']] = 'testforum'
         params[f.find('input', {'style': 'width: 90%'})['name']] = 'Test Thread'
@@ -443,8 +438,8 @@ class TestForum(TestController):
         params = dict()
         inputs = f.findAll('input')
         for field in inputs:
-            if field.has_key('name'):
-                params[field['name']] = field.has_key('value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = 'Post text'
         params[f.find('select')['name']] = 'testforum'
         params[f.find('input', {'style': 'width: 90%'})['name']] = "this is <h2> o'clock"
@@ -477,8 +472,8 @@ class TestForum(TestController):
         params = dict()
         inputs = f.findAll('input')
         for field in inputs:
-            if field.has_key('name'):
-                params[field['name']] = field.has_key('value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = 'Post content'
         params[f.find('select')['name']] = 'testforum'
         params[f.find('input', {'style': 'width: 90%'})['name']] = 'Test Thread'
@@ -503,8 +498,7 @@ class TestForum(TestController):
         assert 'Post content' in r
         r = self.app.get('/discussion/testforum/moderate/')
         post = FM.ForumPost.query.get(text='Post content')
-        link = '<a href="%s">[%s]</a>' % (post.thread.url()
-                                          + '?limit=25#' + post.slug, post.shorthand_id())
+        link = '<a href="%s">[%s]</a>' % (post.thread.url() + '?limit=25#' + post.slug, post.shorthand_id())
         assert link in r, link
 
     def test_thread(self):
@@ -514,8 +508,8 @@ class TestForum(TestController):
         params = dict()
         inputs = f.findAll('input')
         for field in inputs:
-            if field.has_key('name'):
-                params[field['name']] = field.has_key('value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = 'aaa'
         params[f.find('select')['name']] = 'testforum'
         params[f.find('input', {'style': 'width: 90%'})['name']] = 'AAA'
@@ -528,8 +522,8 @@ class TestForum(TestController):
         params = dict()
         inputs = f.findAll('input')
         for field in inputs:
-            if field.has_key('name'):
-                params[field['name']] = field.has_key('value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = 'bbb'
         thread = self.app.post(str(rep_url), params=params)
         thread = self.app.get(url)
@@ -550,8 +544,8 @@ class TestForum(TestController):
         params = dict()
         inputs = reply_form.findAll('input')
         for field in inputs:
-            if field.has_key('name'):
-                params[field['name']] = field.has_key('value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params[reply_form.find('textarea')['name']] = 'zzz'
         self.app.post(post_link, params)
         r = self.app.get(thread_url)
@@ -565,8 +559,8 @@ class TestForum(TestController):
         params = dict()
         inputs = f.findAll('input')
         for field in inputs:
-            if field.has_key('name'):
-                params[field['name']] = field.has_key('value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = 'Post text'
         params[f.find('select')['name']] = 'testforum'
         params[f.find('input', {'style': 'width: 90%'})['name']] = 'Post subject'
@@ -579,8 +573,8 @@ class TestForum(TestController):
         params = dict()
         inputs = f.findAll('input')
         for field in inputs:
-            if field.has_key('name') and 'subscription' not in field['name']:
-                params[field['name']] = field.has_key('value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         self.app.post(str(subscribe_url), params=params)
         self.app.post('/discussion/general/subscribe_to_forum', {'subscribe': True})
         f = thread.html.find('div', {'class': 'row reply_post_form'}).find('form')
@@ -588,8 +582,8 @@ class TestForum(TestController):
         params = dict()
         inputs = f.findAll('input')
         for field in inputs:
-            if field.has_key('name'):
-                params[field['name']] = field.has_key('value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = 'Reply 2'
         self.app.post(str(rep_url), params=params)
         assert M.Notification.query.find(
@@ -613,8 +607,8 @@ class TestForum(TestController):
         params = dict()
         inputs = f.findAll('input')
         for field in inputs:
-            if field.has_key('name'):
-                params[field['name']] = field.has_key('value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = 'aaa aaa'
         params[f.find('select')['name']] = 'testforum'
         params[f.find('input', {'style': 'width: 90%'})['name']] = 'AAAA'
@@ -666,8 +660,8 @@ class TestForum(TestController):
         params = dict()
         inputs = f.findAll('input')
         for field in inputs:
-            if field.has_key('name'):
-                params[field['name']] = field.has_key('value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = 'aaa aaa'
         params[f.find('select')['name']] = 'testforum'
         params[f.find('input', {'style': 'width: 90%'})['name']] = 'topic1'
@@ -680,8 +674,8 @@ class TestForum(TestController):
         params = dict()
         inputs = f.findAll('input')
         for field in inputs:
-            if field.has_key('name'):
-                params[field['name']] = field.has_key('value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = 'aaa aaa'
         params[f.find('select')['name']] = 'testforum'
         params[f.find('input', {'style': 'width: 90%'})['name']] = 'topic2'
@@ -731,8 +725,8 @@ class TestForum(TestController):
         params = dict()
         inputs = f.findAll('input')
         for field in inputs:
-            if field.has_key('name'):
-                params[field['name']] = field.has_key('value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = 'aaa aaa'
         params[f.find('select')['name']] = 'testforum'
         params[f.find('input', {'style': 'width: 90%'})['name']] = 'topic1'
@@ -746,8 +740,8 @@ class TestForum(TestController):
         params = dict()
         inputs = f.findAll('input')
         for field in inputs:
-            if field.has_key('name'):
-                params[field['name']] = field.has_key('value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = 'bbb'
         thread = self.app.post(str(rep_url), params=params)
         thread = self.app.get(url)
@@ -779,8 +773,8 @@ class TestForum(TestController):
         params = dict()
         inputs = f.findAll('input')
         for field in inputs:
-            if field.has_key('name'):
-                params[field['name']] = field.has_key('value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = 'aaa'
         params[f.find('select')['name']] = 'testforum'
         params[f.find('input', {'style': 'width: 90%'})['name']] = 'AAA'
@@ -803,8 +797,8 @@ class TestForum(TestController):
         params = dict()
         inputs = f.findAll('input')
         for field in inputs:
-            if field.has_key('name'):
-                params[field['name']] = field.has_key('value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = 'aaa'
         params[f.find('select')['name']] = 'testforum'
         params[f.find('input', {'style': 'width: 90%'})['name']] = 'AAA'
@@ -847,7 +841,7 @@ class TestForum(TestController):
         timestamp_before = M.Project.query.get(shortname='test').last_updated
 
         # View the thread and make sure project last_updated is not updated
-        thread = self.app.get(url)
+        self.app.get(url)
         timestamp_after = M.Project.query.get(shortname='test').last_updated
         assert_equal(timestamp_before, timestamp_after)
 

http://git-wip-us.apache.org/repos/asf/allura/blob/9d39b9a7/ForgeDiscussion/forgediscussion/tests/functional/test_forum_admin.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/tests/functional/test_forum_admin.py b/ForgeDiscussion/forgediscussion/tests/functional/test_forum_admin.py
index 4597017..3e7f0d4 100644
--- a/ForgeDiscussion/forgediscussion/tests/functional/test_forum_admin.py
+++ b/ForgeDiscussion/forgediscussion/tests/functional/test_forum_admin.py
@@ -188,9 +188,8 @@ class TestForumAdmin(TestController):
         params = dict()
         inputs = f.findAll('input')
         for field in inputs:
-            if field.has_key('name'):
-                params[field['name']] = field.has_key(
-                    'value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = 'secret text'
         params[f.find('select')['name']] = 'secret'
         params[f.find('input', {'style': 'width: 90%'})
@@ -243,9 +242,8 @@ class TestForumAdmin(TestController):
         params = dict()
         inputs = f.findAll('input')
         for field in inputs:
-            if field.has_key('name'):
-                params[field['name']] = field.has_key(
-                    'value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = 'post text'
         params[f.find('select')['name']] = 'testforum'
         params[f.find('input', {'style': 'width: 90%'})['name']] = 'post topic'
@@ -269,9 +267,8 @@ class TestForumAdmin(TestController):
         params = dict()
         inputs = f.findAll('input')
         for field in inputs:
-            if field.has_key('name'):
-                params[field['name']] = field.has_key(
-                    'value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = 'post text'
         params[f.find('select')['name']] = 'testforum'
         params[f.find('input', {'style': 'width: 90%'})['name']] = 'post topic'
@@ -299,9 +296,8 @@ class TestForumAdmin(TestController):
         params = dict()
         inputs = f.findAll('input')
         for field in inputs:
-            if field.has_key('name'):
-                params[field['name']] = field.has_key(
-                    'value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = 'post text'
         params[f.find('select')['name']] = 'testforum'
         params[f.find('input', {'style': 'width: 90%'})['name']] = 'post topic'
@@ -309,7 +305,8 @@ class TestForumAdmin(TestController):
         M.MonQTask.run_ready()
         email_tasks = M.MonQTask.query.find(
             dict(task_name='allura.tasks.mail_tasks.sendsimplemail')).all()
-        assert 'Sent from localhost because email@monitoring.com is subscribed to http://localhost/p/test/discussion/testforum/' in email_tasks[
+        assert 'Sent from localhost because email@monitoring.com is subscribed '\
+               'to http://localhost/p/test/discussion/testforum/' in email_tasks[
             0].kwargs['text'], email_tasks[0].kwargs['text']
         assert 'a project admin can change settings at http://localhost/p/test/admin/discussion/forums' in email_tasks[
             0].kwargs['text']

http://git-wip-us.apache.org/repos/asf/allura/blob/9d39b9a7/ForgeDiscussion/forgediscussion/tests/functional/test_rest.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/tests/functional/test_rest.py b/ForgeDiscussion/forgediscussion/tests/functional/test_rest.py
index c7624a4..bf677e9 100644
--- a/ForgeDiscussion/forgediscussion/tests/functional/test_rest.py
+++ b/ForgeDiscussion/forgediscussion/tests/functional/test_rest.py
@@ -55,9 +55,8 @@ class TestDiscussionApiBase(TestRestApiBase):
         params = dict()
         inputs = f.findAll('input')
         for field in inputs:
-            if field.has_key('name'):
-                params[field['name']] = field.has_key(
-                    'value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = text
         params[f.find('select')['name']] = forum
         params[f.find('input', {'style': 'width: 90%'})['name']] = subject
@@ -250,9 +249,9 @@ class TestRootRestController(TestDiscussionApiBase):
         assert_equal(r.json['forums'][0]['shortname'], 'general')
 
     def test_has_access_no_params(self):
-        r = self.api_get('/rest/p/test/discussion/has_access', status=404)
-        r = self.api_get('/rest/p/test/discussion/has_access?user=root', status=404)
-        r = self.api_get('/rest/p/test/discussion/has_access?perm=read', status=404)
+        self.api_get('/rest/p/test/discussion/has_access', status=404)
+        self.api_get('/rest/p/test/discussion/has_access?user=root', status=404)
+        self.api_get('/rest/p/test/discussion/has_access?perm=read', status=404)
 
     def test_has_access_unknown_params(self):
         """Unknown user and/or permission always False for has_access API"""

http://git-wip-us.apache.org/repos/asf/allura/blob/9d39b9a7/ForgeDiscussion/forgediscussion/widgets/__init__.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/widgets/__init__.py b/ForgeDiscussion/forgediscussion/widgets/__init__.py
index f733ddb..53322a7 100644
--- a/ForgeDiscussion/forgediscussion/widgets/__init__.py
+++ b/ForgeDiscussion/forgediscussion/widgets/__init__.py
@@ -18,3 +18,7 @@
 from forum_widgets import ForumSubscriptionForm, ThreadSubscriptionForm, AnnouncementsTable
 from forum_widgets import ModerateThread, ForumHeader, ThreadHeader
 from forum_widgets import Post, Thread, Forum
+
+__all__ = [
+    'ForumSubscriptionForm', 'ThreadSubscriptionForm', 'AnnouncementsTable', 'ModerateThread', 'ForumHeader',
+    'ThreadHeader', 'Post', 'Thread', 'Forum']

http://git-wip-us.apache.org/repos/asf/allura/blob/9d39b9a7/ForgeGit/forgegit/tests/functional/test_controllers.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/tests/functional/test_controllers.py b/ForgeGit/forgegit/tests/functional/test_controllers.py
index cdff7c8..0e0928d 100644
--- a/ForgeGit/forgegit/tests/functional/test_controllers.py
+++ b/ForgeGit/forgegit/tests/functional/test_controllers.py
@@ -42,7 +42,6 @@ from forgegit import model as GM
 
 
 class _TestCase(TestController):
-
     def setUp(self):
         super(_TestCase, self).setUp()
         self.setup_with_tools()
@@ -50,8 +49,7 @@ class _TestCase(TestController):
     @with_git
     def setup_with_tools(self):
         h.set_context('test', 'src-git', neighborhood='Projects')
-        repo_dir = pkg_resources.resource_filename(
-            'forgegit', 'tests/data')
+        repo_dir = pkg_resources.resource_filename('forgegit', 'tests/data')
         c.app.repo.fs_path = repo_dir
         c.app.repo.status = 'ready'
         c.app.repo.name = 'testgit.git'
@@ -67,8 +65,7 @@ class _TestCase(TestController):
     @with_tool('test', 'Git', 'testgit-index', 'Git', type='git')
     def setup_testgit_index_repo(self):
         h.set_context('test', 'testgit-index', neighborhood='Projects')
-        repo_dir = pkg_resources.resource_filename(
-            'forgegit', 'tests/data')
+        repo_dir = pkg_resources.resource_filename('forgegit', 'tests/data')
         c.app.repo.fs_path = repo_dir
         c.app.repo.status = 'ready'
         c.app.repo.name = 'testgit_index.git'
@@ -79,13 +76,10 @@ class _TestCase(TestController):
 
 
 class TestRootController(_TestCase):
-
-
     @with_tool('test', 'Git', 'weird-chars', 'WeirdChars', type='git')
     def _setup_weird_chars_repo(self):
         h.set_context('test', 'weird-chars', neighborhood='Projects')
-        repo_dir = pkg_resources.resource_filename(
-            'forgegit', 'tests/data')
+        repo_dir = pkg_resources.resource_filename('forgegit', 'tests/data')
         c.app.repo.fs_path = repo_dir
         c.app.repo.status = 'ready'
         c.app.repo.name = 'weird-chars.git'
@@ -135,41 +129,34 @@ class TestRootController(_TestCase):
              u'message': u'Add README', u'row': 2})
 
     def test_log(self):
-        resp = self.app.get(
-            '/src-git/ci/1e146e67985dcd71c74de79613719bef7bddca4a/log/')
+        resp = self.app.get('/src-git/ci/1e146e67985dcd71c74de79613719bef7bddca4a/log/')
         assert 'Initial commit' in resp
         assert '<div class="markdown_content"><p>Change README</div>' in resp
         assert 'tree/README?format=raw">Download</a>' not in resp
-        assert 'Tree' in resp.html.findAll(
-            'td')[2].text, resp.html.findAll('td')[2].text
+        assert 'Tree' in resp.html.findAll('td')[2].text, resp.html.findAll('td')[2].text
         assert 'byRick Copeland' in resp.html.findAll('td')[0].text, resp.html.findAll('td')[0].text
-        resp = self.app.get(
-            '/src-git/ci/1e146e67985dcd71c74de79613719bef7bddca4a/log/?path=/README')
+        resp = self.app.get('/src-git/ci/1e146e67985dcd71c74de79613719bef7bddca4a/log/?path=/README')
         assert 'View' in resp.html.findAll('td')[2].text
         assert 'Change README' in resp
         assert 'tree/README?format=raw">Download</a>' in resp
         assert 'Add README' in resp
         assert "Initial commit " not in resp
-        resp = self.app.get(
-            '/src-git/ci/1e146e67985dcd71c74de79613719bef7bddca4a/log/?path=/a/b/c/')
+        resp = self.app.get('/src-git/ci/1e146e67985dcd71c74de79613719bef7bddca4a/log/?path=/a/b/c/')
         assert 'Remove file' in resp
         assert 'Initial commit' in resp
         assert 'Add README' not in resp
         assert 'Change README' not in resp
-        resp = self.app.get(
-            '/src-git/ci/1e146e67985dcd71c74de79613719bef7bddca4a/log/?path=/not/exist')
+        resp = self.app.get('/src-git/ci/1e146e67985dcd71c74de79613719bef7bddca4a/log/?path=/not/exist')
         assert 'No (more) commits' in resp
 
     def test_diff_ui(self):
-        r = self.app.get(
-            '/src-git/ci/1e146e67985dcd71c74de79613719bef7bddca4a/log/?path=/README')
+        r = self.app.get('/src-git/ci/1e146e67985dcd71c74de79613719bef7bddca4a/log/?path=/README')
         assert '<div class="grid-19"><input type="button" value="Compare" class="compare_revision"></div>' in r
         assert '<input type="checkbox" class="revision"' in r
         assert 'revision="1e146e67985dcd71c74de79613719bef7bddca4a"' in r
         assert 'url_commit="/p/test/src-git/ci/1e146e67985dcd71c74de79613719bef7bddca4a/">' in r
 
-        r = self.app.get(
-            '/src-git/ci/1e146e67985dcd71c74de79613719bef7bddca4a/log/')
+        r = self.app.get('/src-git/ci/1e146e67985dcd71c74de79613719bef7bddca4a/log/')
         assert '<div class="grid-19"><input type="button" value="Compare" class="compare_revision"></div>' not in r
         assert '<input type="checkbox" class="revision"' not in r
         assert 'revision="1e146e67985dcd71c74de79613719bef7bddca4a"' not in r
@@ -247,10 +234,8 @@ class TestRootController(_TestCase):
     def test_file(self):
         ci = self._get_ci()
         resp = self.app.get(ci + 'tree/README')
-        assert 'README' in resp.html.find(
-            'h2', {'class': 'dark title'}).contents[2]
-        content = str(
-            resp.html.find('div', {'class': 'clip grid-19 codebrowser'}))
+        assert 'README' in resp.html.find('h2', {'class': 'dark title'}).contents[2]
+        content = str(resp.html.find('div', {'class': 'clip grid-19 codebrowser'}))
         assert 'This is readme' in content, content
         assert '<span id="l1" class="code_block">' in resp
         assert 'var hash = window.location.hash.substring(1);' in resp
@@ -261,16 +246,14 @@ class TestRootController(_TestCase):
         url = ci + 'tree/' + h.urlquote(u'привіт.txt') + '?format=raw'
         resp = self.app.get(url)
         assert_in(u'Привіт!\nWhich means Hello!', resp.body.decode('utf-8'))
-        assert_equal(
-            resp.headers.get('Content-Disposition').decode('utf-8'),
-            u'attachment;filename="привіт.txt"')
+        assert_equal(resp.headers.get('Content-Disposition').decode('utf-8'),
+                     u'attachment;filename="привіт.txt"')
 
         url = ci + 'tree/' + h.urlquote(u'with space.txt') + '?format=raw'
         resp = self.app.get(url)
         assert_in(u'with space', resp.body.decode('utf-8'))
-        assert_equal(
-            resp.headers.get('Content-Disposition').decode('utf-8'),
-            u'attachment;filename="with space.txt"')
+        assert_equal(resp.headers.get('Content-Disposition').decode('utf-8'),
+                     u'attachment;filename="with space.txt"')
 
     def test_invalid_file(self):
         ci = self._get_ci()
@@ -278,8 +261,7 @@ class TestRootController(_TestCase):
 
     def test_diff(self):
         ci = self._get_ci()
-        resp = self.app.get(
-            ci + 'tree/README?diff=df30427c488aeab84b2352bdf88a3b19223f9d7a')
+        resp = self.app.get(ci + 'tree/README?diff=df30427c488aeab84b2352bdf88a3b19223f9d7a')
         assert 'readme' in resp, resp.showbrowser()
         assert '+++' in resp, resp.showbrowser()
 
@@ -287,8 +269,7 @@ class TestRootController(_TestCase):
         ci = self._get_ci()
         fn = 'tree/README?diff=df30427c488aeab84b2352bdf88a3b19223f9d7a'
         r = self.app.get(ci + fn + '&diformat=regular')
-        assert fn + \
-            '&amp;diformat=sidebyside">Switch to side-by-side view</a>' in r
+        assert fn + '&amp;diformat=sidebyside">Switch to side-by-side view</a>' in r
 
         r = self.app.get(ci + fn + '&diformat=sidebyside')
         assert fn + '&amp;diformat=regular">Switch to unified view</a>' in r
@@ -297,8 +278,7 @@ class TestRootController(_TestCase):
     def test_refresh(self):
         notification = M.Notification.query.find({'subject': '[test:src-git] 5 new commits to Git'}).first()
         assert notification
-        domain = '.'.join(
-            reversed(c.app.url[1:-1].split('/'))).replace('_', '-')
+        domain = '.'.join(reversed(c.app.url[1:-1].split('/'))).replace('_', '-')
         common_suffix = tg.config['forgemail.domain']
         email = 'noreply@%s%s' % (domain, common_suffix)
         assert_in(email, notification['reply_to_address'])
@@ -306,8 +286,7 @@ class TestRootController(_TestCase):
     def test_file_force_display(self):
         ci = self._get_ci()
         resp = self.app.get(ci + 'tree/README?force=True')
-        content = str(
-            resp.html.find('div', {'class': 'clip grid-19 codebrowser'}))
+        content = str(resp.html.find('div', {'class': 'clip grid-19 codebrowser'}))
         assert re.search(r'<pre>.*This is readme', content), content
         assert '</pre>' in content, content
 
@@ -320,8 +299,7 @@ class TestRootController(_TestCase):
         r = self.app.get(ci + 'tree/index.html')
         header = r.html.find('h2', {'class': 'dark title'}).contents[2]
         assert 'index.html' in header, header
-        content = str(
-            r.html.find('div', {'class': 'clip grid-19 codebrowser'}))
+        content = str(r.html.find('div', {'class': 'clip grid-19 codebrowser'}))
         assert ('<span class="nt">&lt;h1&gt;</span>'
                 'index.html'
                 '<span class="nt">&lt;/h1&gt;</span>') in content, content
@@ -335,8 +313,7 @@ class TestRootController(_TestCase):
         header = r.html.find('h2', {'class': 'dark title'})
         assert 'index' in header.contents[3], header.contents[3]
         assert 'index.htm' in header.contents[4], header.contents[4]
-        content = str(
-            r.html.find('div', {'class': 'clip grid-19 codebrowser'}))
+        content = str(r.html.find('div', {'class': 'clip grid-19 codebrowser'}))
         assert ('<span class="nt">&lt;h1&gt;</span>'
                 'index/index.htm'
                 '<span class="nt">&lt;/h1&gt;</span>') in content, content
@@ -387,9 +364,7 @@ class TestRootController(_TestCase):
         assert not '<div id="access_urls"' in r
         r = self.app.get('/src-git/fork')
         assert not '<div id="access_urls"' in r
-        r = self.app.get(
-            ci +
-            'tree/README?diff=df30427c488aeab84b2352bdf88a3b19223f9d7a')
+        r = self.app.get(ci + 'tree/README?diff=df30427c488aeab84b2352bdf88a3b19223f9d7a')
         assert not '<div id="access_urls"' in r
         r = self.app.get(ci + 'tree/README')
         assert not '<div id="access_urls"' in r
@@ -419,8 +394,7 @@ class TestRootController(_TestCase):
         self.setup_testgit_index_repo()
         r = self.app.get('/p/test/testgit-index/ci/master/tree/index/')
         form = r.html.find('form', 'tarball')
-        assert_equal(
-            form.get('action'), '/p/test/testgit-index/ci/master/tarball')
+        assert_equal(form.get('action'), '/p/test/testgit-index/ci/master/tarball')
         assert_equal(form.input.get('value'), '/index')
 
     def test_default_branch(self):
@@ -466,7 +440,6 @@ class TestRootController(_TestCase):
 
 
 class TestRestController(_TestCase):
-
     def test_index(self):
         self.app.get('/rest/p/test/src-git/', status=200)
 
@@ -475,7 +448,6 @@ class TestRestController(_TestCase):
 
 
 class TestHasAccessAPI(TestRestApiBase):
-
     def setUp(self):
         super(TestHasAccessAPI, self).setUp()
         self.setup_with_tools()
@@ -485,9 +457,9 @@ class TestHasAccessAPI(TestRestApiBase):
         pass
 
     def test_has_access_no_params(self):
-        r = self.api_get('/rest/p/test/src-git/has_access', status=404)
-        r = self.api_get('/rest/p/test/src-git/has_access?user=root', status=404)
-        r = self.api_get('/rest/p/test/src-git/has_access?perm=read', status=404)
+        self.api_get('/rest/p/test/src-git/has_access', status=404)
+        self.api_get('/rest/p/test/src-git/has_access?user=root', status=404)
+        self.api_get('/rest/p/test/src-git/has_access?perm=read', status=404)
 
     def test_has_access_unknown_params(self):
         """Unknown user and/or permission always False for has_access API"""
@@ -526,7 +498,6 @@ class TestHasAccessAPI(TestRestApiBase):
 
 
 class TestFork(_TestCase):
-
     def setUp(self):
         super(TestFork, self).setUp()
         to_project = M.Project.query.get(
@@ -575,7 +546,8 @@ class TestFork(_TestCase):
         return r
 
     def _find_request_merge_form(self, resp):
-        cond = lambda f: f.action == 'do_request_merge'
+        def cond(f):
+            return f.action == 'do_request_merge'
         return self.find_form(resp, cond)
 
     def _request_merge(self, **kw):
@@ -684,8 +656,7 @@ class TestFork(_TestCase):
         assert 'Merge Request #%s:  (rejected)' % mr_num in r, r
 
     def test_merge_request_default_branches(self):
-        _select_val = lambda r, n: r.html.find(
-            'select', {'name': n}).find(selected=True).string
+        _select_val = lambda r, n: r.html.find('select', {'name': n}).find(selected=True).string
         r = self.app.get('/p/test2/code/request_merge')
         assert_equal(_select_val(r, 'source_branch'), 'master')
         assert_equal(_select_val(r, 'target_branch'), 'master')
@@ -719,11 +690,12 @@ class TestFork(_TestCase):
 
     def test_merge_request_edit(self):
         r = self.app.post('/p/test2/code/do_request_merge',
-            params={
-                'source_branch': 'zz',
-                'target_branch': 'master',
-                'summary': 'summary',
-                'description': 'description'}).follow()
+                          params={
+                              'source_branch': 'zz',
+                              'target_branch': 'master',
+                              'summary': 'summary',
+                              'description': 'description',
+                          }).follow()
         assert '<a href="edit" title="Edit"><b data-icon="p" class="ico ico-pencil" title="Edit"></b></a>' in r
         r = self.app.get('/p/test/src-git/merge-requests/1/edit')
         assert 'value="summary"' in r
@@ -732,20 +704,24 @@ class TestFork(_TestCase):
         assert md_edit is not None, 'MarkdownEdit widget not found'
 
         r = self.app.post('/p/test/src-git/merge-requests/1/do_request_merge_edit',
-            params={
-                'source_branch': 'zz',
-                'target_branch': 'master',
-                'summary': 'changed summary',
-                'description': 'changed description'},
-                extra_environ=dict(username='*anonymous'), status=302).follow()
+                          params={
+                              'source_branch': 'zz',
+                              'target_branch': 'master',
+                              'summary': 'changed summary',
+                              'description': 'changed description'
+                          },
+                          extra_environ=dict(username='*anonymous'),
+                          status=302,
+                          ).follow()
         assert 'Login' in r
 
         r = self.app.post('/p/test/src-git/merge-requests/1/do_request_merge_edit',
-            params={
-                'source_branch': 'master',
-                'target_branch': 'master',
-                'summary': 'changed summary',
-                'description': 'changed description'}).follow()
+                          params={
+                              'source_branch': 'master',
+                              'target_branch': 'master',
+                              'summary': 'changed summary',
+                              'description': 'changed description',
+                          }).follow()
 
         assert '[5c4724]' not in r
         assert '<p>changed description</p' in r
@@ -786,7 +762,6 @@ class TestFork(_TestCase):
 
 
 class TestDiff(TestController):
-
     def setUp(self):
         super(TestDiff, self).setUp()
         self.setup_with_tools()
@@ -794,8 +769,7 @@ class TestDiff(TestController):
     @with_git
     def setup_with_tools(self):
         h.set_context('test', 'src-git', neighborhood='Projects')
-        repo_dir = pkg_resources.resource_filename(
-            'forgegit', 'tests/data')
+        repo_dir = pkg_resources.resource_filename('forgegit', 'tests/data')
         c.app.repo.fs_path = repo_dir
         c.app.repo.status = 'ready'
         c.app.repo.name = 'testmime.git'
@@ -805,19 +779,18 @@ class TestDiff(TestController):
         ThreadLocalORMSession.flush_all()
 
     def test_diff(self):
-        r = self.app.get(
-            '/src-git/ci/d961abbbf10341ee18a668c975842c35cfc0bef2/tree/1.png?barediff=2ce83a24e52c21e8d2146b1a04a20717c0bb08d7')
+        r = self.app.get('/src-git/ci/d961abbbf10341ee18a668c975842c35cfc0bef2/tree/1.png'
+                         '?barediff=2ce83a24e52c21e8d2146b1a04a20717c0bb08d7')
         assert 'alt="2ce83a2..."' in r
         assert 'alt="d961abb..."' in r
 
-        r = self.app.get(
-            '/src-git/ci/d961abbbf10341ee18a668c975842c35cfc0bef2/tree/1.png?diff=2ce83a24e52c21e8d2146b1a04a20717c0bb08d7')
+        r = self.app.get('/src-git/ci/d961abbbf10341ee18a668c975842c35cfc0bef2/tree/1.png'
+                         '?diff=2ce83a24e52c21e8d2146b1a04a20717c0bb08d7')
         assert 'alt="2ce83a2..."' in r
         assert 'alt="d961abb..."' in r
 
 
 class TestGitRename(TestController):
-
     def setUp(self):
         super(TestGitRename, self).setUp()
         self.setup_with_tools()
@@ -862,8 +835,9 @@ class TestGitRename(TestController):
 
         # the diff portion of the output
         resp_no_ws = re.sub(r'\s+', '', str(resp))
-        assert '<a href="/p/test/src-git/ci/fbb0644603bb6ecee3ebb62efe8c86efc9b84ee6/tree/f.txt">f.txt</a>to<a href="/p/test/src-git/ci/b120505a61225e6c14bee3e5b5862db81628c35c/tree/f2.txt">f2.txt</a>'.replace(' ','') \
-               in resp_no_ws
+        assert_in('<a href="/p/test/src-git/ci/fbb0644603bb6ecee3ebb62efe8c86efc9b84ee6/tree/f.txt">f.txt</a>'
+                  'to<a href="/p/test/src-git/ci/b120505a61225e6c14bee3e5b5862db81628c35c/tree/f2.txt">f2.txt</a>'
+                  .replace(' ', ''), resp_no_ws)
         assert '<span class="empty-diff">File was renamed.</span>' in resp
 
 
@@ -875,8 +849,7 @@ class TestGitBranch(TestController):
     @with_git
     def setup_with_tools(self):
         h.set_context('test', 'src-git', neighborhood='Projects')
-        repo_dir = pkg_resources.resource_filename(
-            'forgegit', 'tests/data')
+        repo_dir = pkg_resources.resource_filename('forgegit', 'tests/data')
         c.app.repo.fs_path = repo_dir
         c.app.repo.status = 'ready'
         c.app.repo.name = 'test_branch.git'
@@ -892,7 +865,6 @@ class TestGitBranch(TestController):
 
 
 class TestIncludeMacro(_TestCase):
-
     def setUp(self):
         super(TestIncludeMacro, self).setUp()
         setup_global_objects()

http://git-wip-us.apache.org/repos/asf/allura/blob/9d39b9a7/ForgeImporters/forgeimporters/tests/google/test_extractor.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/google/test_extractor.py b/ForgeImporters/forgeimporters/tests/google/test_extractor.py
index fe74f9c..72a7d6c 100644
--- a/ForgeImporters/forgeimporters/tests/google/test_extractor.py
+++ b/ForgeImporters/forgeimporters/tests/google/test_extractor.py
@@ -182,7 +182,8 @@ class TestGoogleCodeProjectExtractor(TestCase):
 
     @without_module('html2text')
     def test_get_issue_basic_fields(self):
-        test_issue = open(pkg_resources.resource_filename('forgeimporters', 'tests/data/google/test-issue.html')).read()
+        test_issue = open(pkg_resources.resource_filename(
+            'forgeimporters', 'tests/data/google/test-issue.html')).read()
         gpe = self._make_extractor(test_issue)
 
         self.assertEqual(gpe.get_issue_creator().name, 'john...@gmail.com')
@@ -222,7 +223,8 @@ class TestGoogleCodeProjectExtractor(TestCase):
 
     @skipif(module_not_available('html2text'))
     def test_get_issue_basic_fields_html2text(self):
-        test_issue = open(pkg_resources.resource_filename('forgeimporters', 'tests/data/google/test-issue.html')).read()
+        test_issue = open(pkg_resources.resource_filename(
+            'forgeimporters', 'tests/data/google/test-issue.html')).read()
         gpe = self._make_extractor(test_issue)
         self.assertEqual(gpe.get_issue_creator().name, 'john...@gmail.com')
         self.assertEqual(gpe.get_issue_creator().url,
@@ -303,8 +305,9 @@ class TestGoogleCodeProjectExtractor(TestCase):
         attachments = gpe.get_issue_attachments()
         self.assertEqual(len(attachments), 1)
         self.assertEqual(attachments[0].filename, 'at1.txt')
-        self.assertEqual(
-            attachments[0].url, 'http://allura-google-importer.googlecode.com/issues/attachment?aid=70000000&name=at1.txt&token=3REU1M3JUUMt0rJUg7ldcELt6LA%3A1376059941255')
+        self.assertEqual(attachments[0].url,
+                         'http://allura-google-importer.googlecode.com/issues/attachment?aid=70000000&name=at1.txt'
+                         '&token=3REU1M3JUUMt0rJUg7ldcELt6LA%3A1376059941255')
         self.assertEqual(attachments[0].type, 'text/plain')
 
     def test_get_issue_ids(self):
@@ -367,8 +370,10 @@ class TestWithSetupForComments(TestCase):
     # These tests use iter_comments and 2 HTML pages of comments.
 
     def _create_extractor(self):
-        test_issue = open(pkg_resources.resource_filename('forgeimporters', 'tests/data/google/test-issue-first-page.html')).read()
-        test_issue_older = open(pkg_resources.resource_filename('forgeimporters', 'tests/data/google/test-issue-prev-page.html')).read()
+        test_issue = open(pkg_resources.resource_filename(
+            'forgeimporters', 'tests/data/google/test-issue-first-page.html')).read()
+        test_issue_older = open(pkg_resources.resource_filename(
+            'forgeimporters', 'tests/data/google/test-issue-prev-page.html')).read()
 
         class LocalTestExtractor(google.GoogleCodeProjectExtractor):
             def urlopen(self, url, **kw):
@@ -442,7 +447,8 @@ class TestWithSetupForComments(TestCase):
                 'author.name': 'john...@gmail.com',
                 'author.url': 'http://code.google.com/u/101557263855536553789/',
                 'created_date': 'Thu Aug  8 15:36:57 2013',
-                'body': 'Oh, I forgot one \\(with an inter\\-project reference to [issue other\\-project:1](https://code.google.com/p/other-project/issues/detail?id=1)\\)',
+                'body': 'Oh, I forgot one \\(with an inter\\-project reference to '
+                        '[issue other\\-project:1](https://code.google.com/p/other-project/issues/detail?id=1)\\)',
                 'updates': {'Labels:': 'OpSys-OSX'},
                 'attachments': [],
             },
@@ -511,7 +517,8 @@ class TestWithSetupForComments(TestCase):
                 'author.name': 'john...@gmail.com',
                 'author.url': 'http://code.google.com/u/101557263855536553789/',
                 'created_date': 'Thu Aug  8 15:36:57 2013',
-                'body': 'Oh, I forgot one \\(with an inter-project reference to [issue other-project:1](https://code.google.com/p/other-project/issues/detail?id=1)\\)',
+                'body': 'Oh, I forgot one \\(with an inter-project reference to '
+                        '[issue other-project:1](https://code.google.com/p/other-project/issues/detail?id=1)\\)',
                 'updates': {'Labels:': 'OpSys-OSX'},
                 'attachments': [],
             },

http://git-wip-us.apache.org/repos/asf/allura/blob/9d39b9a7/ForgeLink/forgelink/tests/functional/test_rest.py
----------------------------------------------------------------------
diff --git a/ForgeLink/forgelink/tests/functional/test_rest.py b/ForgeLink/forgelink/tests/functional/test_rest.py
index 7fd6485..b2ac3b3 100644
--- a/ForgeLink/forgelink/tests/functional/test_rest.py
+++ b/ForgeLink/forgelink/tests/functional/test_rest.py
@@ -91,9 +91,9 @@ class TestLinkHasAccess(TestRestApiBase):
         h.set_context('test', 'link', neighborhood='Projects')
 
     def test_has_access_no_params(self):
-        r = self.api_get('/rest/p/test/link/has_access', status=404)
-        r = self.api_get('/rest/p/test/link/has_access?user=root', status=404)
-        r = self.api_get('/rest/p/test/link/has_access?perm=read', status=404)
+        self.api_get('/rest/p/test/link/has_access', status=404)
+        self.api_get('/rest/p/test/link/has_access?user=root', status=404)
+        self.api_get('/rest/p/test/link/has_access?perm=read', status=404)
 
     def test_has_access_unknown_params(self):
         """Unknown user and/or permission always False for has_access API"""

http://git-wip-us.apache.org/repos/asf/allura/blob/9d39b9a7/ForgeTracker/forgetracker/tests/functional/test_rest.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/functional/test_rest.py b/ForgeTracker/forgetracker/tests/functional/test_rest.py
index d2f42bf..a45477e 100644
--- a/ForgeTracker/forgetracker/tests/functional/test_rest.py
+++ b/ForgeTracker/forgetracker/tests/functional/test_rest.py
@@ -249,9 +249,9 @@ class TestRestSearch(TestTrackerApiBase):
 class TestRestHasAccess(TestTrackerApiBase):
 
     def test_has_access_no_params(self):
-        r = self.api_get('/rest/p/test/bugs/has_access', status=404)
-        r = self.api_get('/rest/p/test/bugs/has_access?user=root', status=404)
-        r = self.api_get('/rest/p/test/bugs/has_access?perm=read', status=404)
+        self.api_get('/rest/p/test/bugs/has_access', status=404)
+        self.api_get('/rest/p/test/bugs/has_access?user=root', status=404)
+        self.api_get('/rest/p/test/bugs/has_access?perm=read', status=404)
 
     def test_has_access_unknown_params(self):
         """Unknown user and/or permission always False for has_access API"""

http://git-wip-us.apache.org/repos/asf/allura/blob/9d39b9a7/ForgeTracker/forgetracker/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/functional/test_root.py b/ForgeTracker/forgetracker/tests/functional/test_root.py
index efcc59d..73ef421 100644
--- a/ForgeTracker/forgetracker/tests/functional/test_root.py
+++ b/ForgeTracker/forgetracker/tests/functional/test_root.py
@@ -67,11 +67,13 @@ class TrackerTestController(TestController):
         pass
 
     def _find_new_ticket_form(self, resp):
-        cond = lambda f: f.action.endswith('/save_ticket')
+        def cond(f):
+            return f.action.endswith('/save_ticket')
         return self.find_form(resp, cond)
 
     def _find_update_ticket_form(self, resp):
-        cond = lambda f: f.action.endswith('/update_ticket_from_widget')
+        def cond(f):
+            return f.action.endswith('/update_ticket_from_widget')
         return self.find_form(resp, cond)
 
     def new_ticket(self, mount_point='/bugs/', extra_environ=None, **kw):
@@ -363,8 +365,8 @@ class TestFunctionalController(TrackerTestController):
         assert 'test new ticket form description' in response
 
     def test_mass_edit(self):
-        ticket_view = self.new_ticket(summary='First Ticket').follow()
-        ticket_view = self.new_ticket(summary='Second Ticket').follow()
+        self.new_ticket(summary='First Ticket').follow()
+        self.new_ticket(summary='Second Ticket').follow()
         M.MonQTask.run_ready()
         first_ticket = tm.Ticket.query.find({'summary': 'First Ticket'}).first()
         second_ticket = tm.Ticket.query.find({'summary': 'Second Ticket'}).first()
@@ -627,7 +629,7 @@ class TestFunctionalController(TrackerTestController):
         r = self.app.get('/p/test/bugs/feed.atom', extra_environ=env)
         assert 'Private Ticket' not in r
         # ... or in the API ...
-        r = self.app.get('/rest/p/test/bugs/2/', extra_environ=env, status=401)
+        self.app.get('/rest/p/test/bugs/2/', extra_environ=env, status=401)
         r = self.app.get('/rest/p/test/bugs/', extra_environ=env)
         assert 'Private Ticket' not in r
 
@@ -870,8 +872,8 @@ class TestFunctionalController(TrackerTestController):
         params = dict()
         inputs = f.findAll('input')
         for field in inputs:
-            if field.has_key('name'):
-                params[field['name']] = field.has_key('value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = 'test comment'
         self.app.post(f['action'].encode('utf-8'), params=params,
                       headers={'Referer': '/bugs/1/'.encode("utf-8")})
@@ -881,7 +883,7 @@ class TestFunctionalController(TrackerTestController):
                       upload_files=[('file_info', 'test.txt', 'HiThere!')])
         r = self.app.get('/bugs/1/', dict(page=1))
         assert '<input class="submit delete_attachment file" type="submit" value="X"/>' in r
-        form = r.forms[5].submit()
+        r.forms[5].submit()
         r = self.app.get('/bugs/1/', dict(page=1))
         assert '<input class="submit delete_attachment" type="submit" value="X"/>' not in r
 
@@ -917,7 +919,7 @@ class TestFunctionalController(TrackerTestController):
         file_data = file(file_path).read()
         upload = ('attachment', file_name, file_data)
         self.new_ticket(summary='test new attachment')
-        ticket_editor = self.app.post('/bugs/1/update_ticket', {
+        self.app.post('/bugs/1/update_ticket', {
             'summary': 'zzz'
         }, upload_files=[upload]).follow()
         ticket = tm.Ticket.query.find({'ticket_num': 1}).first()
@@ -1116,8 +1118,8 @@ class TestFunctionalController(TrackerTestController):
             open_status_names='aa bb',
             closed_status_names='cc',
         )
-        r = self.app.post('/admin/bugs/set_custom_fields',
-                          params=variable_encode(params))
+        self.app.post('/admin/bugs/set_custom_fields',
+                      params=variable_encode(params))
         kw = {'custom_fields._number': ''}
         ticket_view = self.new_ticket(summary='test custom fields', **kw).follow()
         assert '<strong>Number</strong>:  --&gt;' not in ticket_view
@@ -1191,7 +1193,7 @@ class TestFunctionalController(TrackerTestController):
         assert 'Milestone' in ticket_view
         assert '1.0' in ticket_view
         assert 'zzzé' not in ticket_view
-        r = self.app.post('/bugs/update_milestones', {
+        self.app.post('/bugs/update_milestones', {
             'field_name': '_milestone',
             'milestones-0.old_name': '1.0',
             'milestones-0.new_name': 'zzzé',
@@ -1357,7 +1359,7 @@ class TestFunctionalController(TrackerTestController):
         self.new_ticket(summary='test first ticket')
         self.new_ticket(summary='test second ticket')
         p = M.Project.query.get(shortname='test')
-        tracker = p.app_instance('bugs')
+        p.app_instance('bugs')
         t = tm.Ticket.query.get(summary='test first ticket')
         t.reported_by_id = M.User.by_username('test-user-0')._id
         t = tm.Ticket.query.get(summary='test second ticket')
@@ -1422,8 +1424,8 @@ class TestFunctionalController(TrackerTestController):
             'sort': ''}).follow()
         r = self.app.get('/bugs/')
         assert sidebar_contains(r, 'This is not too long.')
-        r = self.app.post('/admin/bugs/bins/save_bin', {
-            'summary': 'This will be truncated because it is too long to show in the sidebar without being ridiculous.',
+        self.app.post('/admin/bugs/bins/save_bin', {
+            'summary': 'This will be truncated because it is too long to show in the sidebar without being ridiculous',
             'terms': 'aaa',
             'old_summary': '',
             'sort': ''}).follow()
@@ -1457,8 +1459,8 @@ class TestFunctionalController(TrackerTestController):
         params = dict()
         inputs = f.findAll('input')
         for field in inputs:
-            if field.has_key('name'):
-                params[field['name']] = field.has_key('value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = post_content
         r = self.app.post(f['action'].encode('utf-8'), params=params,
                           headers={'Referer': '/bugs/1/'.encode("utf-8")})
@@ -1473,8 +1475,8 @@ class TestFunctionalController(TrackerTestController):
         params = dict()
         inputs = f.findAll('input')
         for field in inputs:
-            if field.has_key('name'):
-                params[field['name']] = field.has_key('value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params['ticket_form.summary'] = new_summary
         r = self.app.post(f['action'].encode('utf-8'), params=params,
                           headers={'Referer': '/bugs/1/'.encode("utf-8")})
@@ -1492,8 +1494,8 @@ class TestFunctionalController(TrackerTestController):
         params = dict()
         inputs = f.findAll('input')
         for field in inputs:
-            if field.has_key('name'):
-                params[field['name']] = field.has_key('value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = post_content
         r = self.app.post(f['action'].encode('utf-8'), params=params,
                           headers={'Referer': '/bugs/1/'.encode("utf-8")})
@@ -1520,8 +1522,8 @@ class TestFunctionalController(TrackerTestController):
         params = dict()
         inputs = f.findAll('input')
         for field in inputs:
-            if field.has_key('name'):
-                params[field['name']] = field.has_key('value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = post_content
         self.app.post(f['action'].encode('utf-8'), params=params,
                       headers={'Referer': '/bugs/1/'.encode("utf-8")})
@@ -1534,8 +1536,8 @@ class TestFunctionalController(TrackerTestController):
         params = dict()
         inputs = post_form.findAll('input')
         for field in inputs:
-            if field.has_key('name'):
-                params[field['name']] = field.has_key('value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params[post_form.find('textarea')['name']] = 'Tis a reply'
         r = self.app.post(post_link + 'reply',
                           params=params,
@@ -1559,7 +1561,8 @@ class TestFunctionalController(TrackerTestController):
         assert_in('test first ticket', str(ticket_rows))
         assert_in('test second ticket', str(ticket_rows))
         edit_link = response.html.find('a', {'title': 'Bulk Edit'})
-        expected_link = "/p/test/bugs/edit/?q=%21status%3Awont-fix+%26%26+%21status%3Aclosed&sort=snippet_s+asc&limit=25&filter=&page=0"
+        expected_link = "/p/test/bugs/edit/?q=%21status%3Awont-fix+%26%26+%21status%3Aclosed"\
+                        "&sort=snippet_s+asc&limit=25&filter=&page=0"
         assert_equal(expected_link, edit_link['href'])
         response = self.app.get(edit_link['href'])
         ticket_rows = response.html.find('tbody', {'class': 'ticket-list'})
@@ -2139,8 +2142,8 @@ class TestFunctionalController(TrackerTestController):
         params = dict()
         inputs = f.findAll('input')
         for field in inputs:
-            if field.has_key('name'):
-                params[field['name']] = field.has_key('value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = post_content
         r = self.app.post(f['action'].encode('utf-8'), params=params,
                           headers={'Referer': '/p/test2/bugs2/1/'.encode("utf-8")})
@@ -2317,7 +2320,7 @@ class TestFunctionalController(TrackerTestController):
 
     def test_tags(self):
         p = M.Project.query.get(shortname='test')
-        tracker = p.app_instance('bugs')
+        p.app_instance('bugs')
         self.new_ticket(summary='a', labels='tag1,tag2')
         self.new_ticket(summary='b', labels='tag2')
         self.new_ticket(summary='c', labels='42cc,test')
@@ -2336,8 +2339,8 @@ class TestFunctionalController(TrackerTestController):
         params = dict()
         inputs = f.findAll('input')
         for field in inputs:
-            if field.has_key('name'):
-                params[field['name']] = field.has_key('value') and field['value'] or ''
+            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
+                params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = 'test comment'
         self.app.post(f['action'].encode('utf-8'), params=params,
                       headers={'Referer': '/bugs/1/'.encode("utf-8")})
@@ -2392,7 +2395,9 @@ class TestFunctionalController(TrackerTestController):
             return_path, rcpts, body = _client.sendmail.call_args[0]
             body = body.split('\n')
             assert 'Subject: [test:bugs] #1 test <h2> ticket' in body
-            assert_in('<p><strong> <a class="alink" href="http://localhost:8080/p/test/bugs/1/">[bugs:#1]</a> test &lt;h2&gt; ticket</strong></p>', body)
+            assert_in('<p><strong> <a class="alink" href="http://localhost:8080/p/test/bugs/1/">[bugs:#1]</a>'
+                      ' test &lt;h2&gt; ticket</strong></p>',
+                      body)
 
     @patch('forgetracker.search.query_filter_choices')
     def test_multiselect(self, query_filter_choices):
@@ -2623,7 +2628,7 @@ class TestEmailMonitoring(TrackerTestController):
             if (('thread' in f['action']) and ('post' in f['action'])):
                 params = {i['name']: i.get('value', '')
                           for i in f.findAll('input')
-                          if i.has_key('name')}
+                          if i.has_key('name')}  # nopep8 - beautifulsoup3 actually uses has_key
                 params[f.find('textarea')['name']] = 'foobar'
                 self.app.post(str(f['action']), params)
                 break  # Do it only once if many forms met
@@ -2869,7 +2874,7 @@ class TestBulkMove(TrackerTestController):
         original_p = M.Project.query.get(shortname='test')
         tracker = p.app_instance('bugs')
         original_tracker = original_p.app_instance('bugs')
-        r = self.app.post('/p/test/bugs/move_tickets', {
+        self.app.post('/p/test/bugs/move_tickets', {
             'tracker': str(tracker.config._id),
             '__ticket_ids': [t._id for t in tickets],
             '__search': '',
@@ -2907,7 +2912,7 @@ class TestBulkMove(TrackerTestController):
         tickets[0].subscribe(user=first_user)
         tickets[1].subscribe(user=second_user)
         M.MonQTask.query.remove()
-        r = self.app.post('/p/test/bugs/move_tickets', {
+        self.app.post('/p/test/bugs/move_tickets', {
             'tracker': str(tracker.config._id),
             '__ticket_ids': [t._id for t in tickets],
             '__search': '',
@@ -2970,7 +2975,7 @@ class TestBulkMove(TrackerTestController):
         p = M.Project.query.get(shortname='test2')
         tracker = p.app_instance('bugs2')
         M.MonQTask.query.remove()
-        r = self.app.post('/p/test/bugs/move_tickets', {
+        self.app.post('/p/test/bugs/move_tickets', {
             'tracker': str(tracker.config._id),
             '__ticket_ids': [t._id for t in tickets],
             '__search': '',

http://git-wip-us.apache.org/repos/asf/allura/blob/9d39b9a7/ForgeWiki/forgewiki/tests/functional/test_rest.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/tests/functional/test_rest.py b/ForgeWiki/forgewiki/tests/functional/test_rest.py
index 3bc61bb..4aba7f1 100644
--- a/ForgeWiki/forgewiki/tests/functional/test_rest.py
+++ b/ForgeWiki/forgewiki/tests/functional/test_rest.py
@@ -131,9 +131,9 @@ class TestWikiHasAccess(TestRestApiBase):
         h.set_context('test', 'wiki', neighborhood='Projects')
 
     def test_has_access_no_params(self):
-        r = self.api_get('/rest/p/test/wiki/has_access', status=404)
-        r = self.api_get('/rest/p/test/wiki/has_access?user=root', status=404)
-        r = self.api_get('/rest/p/test/wiki/has_access?perm=read', status=404)
+        self.api_get('/rest/p/test/wiki/has_access', status=404)
+        self.api_get('/rest/p/test/wiki/has_access?user=root', status=404)
+        self.api_get('/rest/p/test/wiki/has_access?perm=read', status=404)
 
     def test_has_access_unknown_params(self):
         """Unknown user and/or permission always False for has_access API"""

http://git-wip-us.apache.org/repos/asf/allura/blob/9d39b9a7/ForgeWiki/forgewiki/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/tests/functional/test_root.py b/ForgeWiki/forgewiki/tests/functional/test_root.py
index b716877..635e2b6 100644
--- a/ForgeWiki/forgewiki/tests/functional/test_root.py
+++ b/ForgeWiki/forgewiki/tests/functional/test_root.py
@@ -35,14 +35,6 @@ from alluratest.controller import TestController
 
 from forgewiki import model
 
-#---------x---------x---------x---------x---------x---------x---------x
-# RootController methods exposed:
-#     index, new_page, search
-# PageController methods exposed:
-#     index, edit, history, diff, raw, revert, update
-# CommentController methods exposed:
-#     reply, delete
-
 
 class TestRootController(TestController):
 
@@ -184,7 +176,8 @@ class TestRootController(TestController):
                 'text': 'sometext',
                 'labels': 'test label',
                 'viewable_by-0.id': 'all'}).follow()
-        assert '''<a href="/p/test/wiki/search/?q=labels_t:%22test label%22&parser=standard">test label (1)</a>''' in response
+        assert_in('<a href="/p/test/wiki/search/?q=labels_t:%22test label%22&parser=standard">test label (1)</a>',
+                  response)
 
     def test_title_slashes(self):
         # forward slash not allowed in wiki page title - converted to dash
@@ -335,9 +328,13 @@ class TestRootController(TestController):
                                             **Note:** The logo shown in the sidebar is no longer stored as an object in the wiki (as it was in the Hosted App installation). Rather save it as a regular file, then edit LocalSettings.php, adding""")
         self.app.post('/wiki/testdiff/update', params=d)
         response = self.app.get('/wiki/testdiff/diff?v1=1&v2=2')
-        assert '# Now fix <del> permissons. </del> <ins> permissions. </ins> Wrong permissions may cause <ins> a </ins> massive slowdown!' in response
+        assert_in('# Now fix <del> permissons. </del> <ins> permissions. </ins> '
+                  'Wrong permissions may cause <ins> a </ins> massive slowdown!',
+                  response)
         response = self.app.get('/wiki/testdiff/diff?v1=2&v2=1')
-        assert '# Now fix <del> permissions. </del> <ins> permissons. </ins> Wrong permissions may cause <del> a </del> massive slowdown!' in response
+        assert_in('# Now fix <del> permissions. </del> <ins> permissons. </ins> '
+                  'Wrong permissions may cause <del> a </del> massive slowdown!',
+                  response)
 
     def test_page_raw(self):
         self.app.post(
@@ -763,7 +760,7 @@ class TestRootController(TestController):
         assert inp is not None
         # subscribe
         self.app.post('/p/test/wiki/subscribe', {'subscribe': True},
-                     extra_environ={'username': str(user.username)}).follow()
+                      extra_environ={'username': str(user.username)}).follow()
         # user is subscribed
         assert M.Mailbox.subscribed(user_id=user._id)
         r = self.app.get('/p/test/wiki/Home/', extra_environ={'username': str(user.username)})
@@ -771,7 +768,7 @@ class TestRootController(TestController):
         assert inp is not None
         # unsubscribe
         self.app.post('/p/test/wiki/subscribe', {'unsubscribe': True},
-                     extra_environ={'username': str(user.username)}).follow()
+                      extra_environ={'username': str(user.username)}).follow()
         # user is not subscribed
         assert not M.Mailbox.subscribed(user_id=user._id)
         r = self.app.get('/p/test/wiki/Home/', extra_environ={'username': str(user.username)})

http://git-wip-us.apache.org/repos/asf/allura/blob/9d39b9a7/scripts/teamforge-import.py
----------------------------------------------------------------------
diff --git a/scripts/teamforge-import.py b/scripts/teamforge-import.py
index 9f601a0..b668128 100644
--- a/scripts/teamforge-import.py
+++ b/scripts/teamforge-import.py
@@ -305,18 +305,7 @@ def convert_project_shortname(teamforge_path):
 
 # FIXME hardcoded
 skip_perms_usernames = set([
-    'faisal_saeed', 'dsarkisian', 'debonairamit', 'nishanthiremath', 'Bhuvnesh', 'bluetooth', 'cnkurzke', 'makow2', 'jannes1', 'Joel_Hegberg', 'Farroc', 'brian_chen', 'eirikur',
-    'dmitry_flyorov', 'bipingm', 'MornayJo', 'ibv', 'b_weisshaar', 'k9srb', 'johnmmills', 'a_gomolitsky', 'filim', 'kapoor', 'ljzegers', 'jrukes', 'dwilson9', 'jlin', 'quickie',
-    'johnbell', 'nnikolenko', 'Gaetan', 'Giannetta', 'Katia', 'jackhan', 'jacobwangus', 'adwankar', 'dinobrusco', 'qbarnes', 'ilmojung', 'clifford_chan', 'nbaig', 'fhutchi1',
-    'rinofarina', 'baiyanbin', 'muralidhar', 'duanyiruo', 'bredding', 'mkolkey', 'manvith', 'nanduk', 'engyihan', 'deepsie', 'dabon', 'dino_jiang', 'mattrose', 'peter_j_wilhelm',
-    'emx2500', 'jmcguire', 'lfilimowski', 'guruppandit', 'abhilashisme', 'edwinhm', 'rabbi', 'ferrans', 'guna', 'kevin_robinson', 'adathiruthi', 'kochen', 'onehap', 'kalanithi',
-    'jamesn', 'obu001', 'chetanv', 'Avinash', 'HugoBoss', 'Han_Wei', 'mhooper', 'g16872', 'mfcarignano', 'jim_burke', 'kevin', 'arunkarra', 'adam_feng', 'pavan_scm', 'kostya_katz',
-    'ppazderka', 'eileenzhuang', 'pyammine', 'judyho', 'ashoykh', 'rdemento', 'ibrahim', 'min_wang', 'arvind_setlur', 'moorthy_karthik', 'daniel_nelson', 'dms', 'esnmurthy',
-    'rasa_bonyadlou', 'prashantjoshi', 'edkeating', 'billsaez', 'cambalindo', 'jims', 'bozkoyun', 'andry_deltsov', 'bpowers', 'manuel_milli', 'maryparsons', 'spriporov', 'yutianli',
-    'xiebin', 'tnemeth1', 'udayaps', 'zzzzuser', 'timberger', 'sbarve1', 'zarman', 'rwallace67', 'thangavelu_arum', 'yuhuaixie', 'tingup', 'sekchai', 'sasanplus', 'rupal', 'sebastien_hertz',
-    'sab8123', 'rony_lim', 'slava_kirillin', 'smwest', 'wendydu_yq', 'sco002', 'RonFred', 'spatnala', 'vd', 'Sunny', 'tthompson', 'sunijams', 'slaw', 'rodovich', 'zhangqingqi82', 'venki',
-    'yuntaom', 'xiaojin', 'walterciocosta', 'straus', 'Thomas', 'stupka', 'wangyu', 'yaowang', 'wisekb', 'tyler_louie', 'smartgarfield', 'shekar_mahalingam',
-    'venkata_akella', 'v_yellapragada', 'vavasthi', 'rpatel', 'zhengfang', 'sweetybala', 'vap', 'sergey', 'ymhuang', 'spatel78745'
+    'username1', 'username2', 'username3'
 ])
 
 
@@ -583,9 +572,9 @@ def import_discussion(project, pid, frs_mapping, sf_project_shortname, nbhd):
                                 parent=p.parent, timestamp=create_date)
                             p.slug = slug
                             p.full_slug = full_slug
-                            if oldest_post == None or oldest_post.timestamp > create_date:
+                            if oldest_post is None or oldest_post.timestamp > create_date:
                                 oldest_post = p
-                            if newest_post == None or newest_post.timestamp < create_date:
+                            if newest_post is None or newest_post.timestamp < create_date:
                                 newest_post = p
                             ThreadLocalORMSession.flush_all()
                     to.num_replies = to_num_replies
@@ -901,7 +890,8 @@ def _dir_sql(created_on, project, dir_name, rel_path):
       AND pfs_type = 'd'
       AND pfs_name = '%s'
       AND parent_directory = %s;
-    """ % (created_on, convert_project_shortname(project.path), options.neighborhood_shortname, dir_name, parent_directory)
+    """ % (created_on, convert_project_shortname(project.path), options.neighborhood_shortname,
+           dir_name, parent_directory)
     return sql
 
 


[14/50] [abbrv] allura git commit: [#7976] Use Broccoli to transpile es6 & jsx files

Posted by je...@apache.org.
[#7976] Use Broccoli to transpile es6 & jsx files


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/1dd78440
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/1dd78440
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/1dd78440

Branch: refs/heads/ib/7924
Commit: 1dd78440bde218d65065258a7bc988a37a596936
Parents: 34e5195
Author: Dave Brondsema <da...@brondsema.net>
Authored: Thu Sep 24 13:35:42 2015 -0400
Committer: Heith Seewald <hs...@hsmb.local>
Committed: Fri Oct 2 10:01:48 2015 -0400

----------------------------------------------------------------------
 .gitignore                                      |  2 ++
 .../allura/templates/jinja_master/master.html   |  1 +
 Allura/docs/development/contributing.rst        | 10 +++++-
 Allura/docs/getting_started/installation.rst    | 16 +++++++++
 Brocfile.js                                     | 35 ++++++++++++++++++++
 Dockerfile                                      |  8 +++--
 docker-compose.yml                              | 12 ++++++-
 package.json                                    | 23 +++++++++++++
 scripts/asf-release.sh                          | 12 +++++++
 9 files changed, 115 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/1dd78440/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index 44b29e3..0918813 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,11 +26,13 @@ var/
 .noseids
 env
 env-docker
+Allura/allura/public/nf/js/build/
 Allura/allura/templates/home
 Allura/allura/templates/var
 Allura/production.ini
 Allura/forced_upgrade.ini
 scripts/teamforge-export/
+/node_modules
 report.clonedigger
 .ropeproject
 .idea

http://git-wip-us.apache.org/repos/asf/allura/blob/1dd78440/Allura/allura/templates/jinja_master/master.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/jinja_master/master.html b/Allura/allura/templates/jinja_master/master.html
index 48b6911..b2d2418 100644
--- a/Allura/allura/templates/jinja_master/master.html
+++ b/Allura/allura/templates/jinja_master/master.html
@@ -29,6 +29,7 @@
 {% do g.register_forge_js('js/sylvester.js') %}
 {% do g.register_forge_js('js/pb.transformie.min.js') %}
 {% do g.register_forge_js('js/allura-base.js') %}
+{% do g.register_forge_js('js/build/transpiled.js') %}
 {% do g.register_forge_css('css/forge/hilite.css') %}
 {% do g.register_forge_css('css/forge/tooltipster.css') %}
 {% do g.register_forge_css('css/font-awesome.min.css', compress=False) %}

http://git-wip-us.apache.org/repos/asf/allura/blob/1dd78440/Allura/docs/development/contributing.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/development/contributing.rst b/Allura/docs/development/contributing.rst
index 56ee818..e161fdb 100644
--- a/Allura/docs/development/contributing.rst
+++ b/Allura/docs/development/contributing.rst
@@ -100,7 +100,15 @@ the Allura source already.
 `Jinja <http://jinja.pocoo.org/>`_ - HTML template library used by Allura.
 
 If you want to work on the front end of Allura, you'll also need some CSS and
-Javascript skills, and basic knowledge of JQuery.
+Javascript skills, and basic knowledge of JQuery.  We are also using React and ES6.
+To transpile those files as soon as you edit them:
+
+.. code-block:: bash
+
+    ~$ npm install -g broccoli-timepiece
+    ~$ cd ~/src/allura
+    ~$ broccoli-timepiece Allura/allura/public/nf/js/build/
+
 
 Finding Something to Work On
 ----------------------------

http://git-wip-us.apache.org/repos/asf/allura/blob/1dd78440/Allura/docs/getting_started/installation.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/getting_started/installation.rst b/Allura/docs/getting_started/installation.rst
index 36df424..b28fca3 100644
--- a/Allura/docs/getting_started/installation.rst
+++ b/Allura/docs/getting_started/installation.rst
@@ -178,6 +178,22 @@ Allura uses a background task service called "taskd" to do async tasks like send
     (env-allura)~$ cd ~/src/allura/Allura
     (env-allura)~/src/allura/Allura$ nohup paster taskd development.ini > /var/log/allura/taskd.log 2>&1 &
 
+
+A few more steps, if using git
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you're using a released version of Allura, these are already done for you.  This transpiles JS into a version all browsers support:
+
+.. code-block:: bash
+
+    (env-allura)~$ sudo aptitude install nodejs npm
+    (env-allura)~$ sudo ln -s /usr/bin/nodejs /usr/bin/node
+    (env-allura)~$ cd ~/src/allura
+    (env-allura)~$ npm install -g broccoli-cli
+    (env-allura)~$ npm install
+    (env-allura)~$ broccoli build Allura/allura/public/nf/js/build/
+
+
 The application server
 ~~~~~~~~~~~~~~~~~~~~~~
 

http://git-wip-us.apache.org/repos/asf/allura/blob/1dd78440/Brocfile.js
----------------------------------------------------------------------
diff --git a/Brocfile.js b/Brocfile.js
new file mode 100644
index 0000000..e16ee4c
--- /dev/null
+++ b/Brocfile.js
@@ -0,0 +1,35 @@
+var babelTranspiler = require("broccoli-babel-transpiler");
+var sourceMap = require('broccoli-source-map');
+var concat = require('broccoli-concat');
+var funnel = require('broccoli-funnel');
+var uglifyJavaScript = require('broccoli-uglify-js');
+
+var tree = funnel('Allura/allura/public/nf/js', {
+  include: ['*.es6.js'],
+});
+tree = babelTranspiler(tree, {
+    browserPolyfill: true,
+    //filterExtensions:['es6.js'],
+    sourceMaps: 'inline',  // external doesn't work, have to use extract below
+    comments: false,
+});
+tree = concat(tree, {
+  inputFiles: ['**/*.js'],
+  outputFile: '/transpiled.js'
+});
+tree = sourceMap.extract(tree);
+
+if (process.env.BROCCOLI_ENV === 'production') {
+    /* can't use this for dev mode, since it drops the sourcemap comment even if we set  output: {comments: true}
+     https://github.com/mishoo/UglifyJS2/issues/653
+     https://github.com/mishoo/UglifyJS2/issues/754
+     https://github.com/mishoo/UglifyJS2/issues/780
+     https://github.com/mishoo/UglifyJS2/issues/520
+     */
+    tree = uglifyJavaScript(tree, {
+        mangle: false,
+        compress: false
+    });
+}
+
+module.exports = tree;

http://git-wip-us.apache.org/repos/asf/allura/blob/1dd78440/Dockerfile
----------------------------------------------------------------------
diff --git a/Dockerfile b/Dockerfile
index 12170ef..f125d55 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -29,7 +29,10 @@ RUN apt-get update && apt-get install -y \
     python-pip \
     zip \
     subversion \
-    python-svn
+    python-svn \
+    npm
+RUN ln -s /usr/bin/nodejs /usr/bin/node
+RUN npm install -g broccoli-cli
 
 # Snapshot generation for SVN (and maybe other SCMs) might fail without this
 RUN locale-gen en_US.UTF-8
@@ -39,4 +42,5 @@ ENV LANG en_US.UTF-8
 # tests). If this is not set, it uses os.getlogin, which fails inside docker.
 ENV USER root
 
-WORKDIR /allura
+WORKDIR /allura/Allura
+CMD gunicorn --paste docker-dev.ini --reload

http://git-wip-us.apache.org/repos/asf/allura/blob/1dd78440/docker-compose.yml
----------------------------------------------------------------------
diff --git a/docker-compose.yml b/docker-compose.yml
index 6822677..86102ed 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -18,7 +18,17 @@
 web:
   build: .
   working_dir: /allura
-  command: bash -c 'cd Allura && gunicorn --paste docker-dev.ini --reload'
+  # specialized command (and working_dir) to run broccoli
+  # since it depends on files from the shared volume, it can't be run as part of the Dockerfile build :(
+  command: >
+    sh -c '
+    if [ ! -e Allura/allura/public/nf/js/build/transpiled.js ]; then
+      npm install &&
+      rm -rf Allura/allura/public/nf/js/build/ &&
+      broccoli build Allura/allura/public/nf/js/build/;
+    fi;
+    gunicorn --paste Allura/docker-dev.ini --reload
+    '
   ports:
     - "8080:8080"
   volumes:

http://git-wip-us.apache.org/repos/asf/allura/blob/1dd78440/package.json
----------------------------------------------------------------------
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..58dcc6b
--- /dev/null
+++ b/package.json
@@ -0,0 +1,23 @@
+{
+  "name": "allura",
+  "version": "0.0.0",
+  "description": "",
+  "main": "Brocfile.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "repository": {
+    "type": "git",
+    "url": "https://git-wip-us.apache.org/repos/asf/allura.git"
+  },
+  "author": "",
+  "license": "Apache-2.0",
+  "devDependencies": {
+    "broccoli": "^0.16.8",
+    "broccoli-babel-transpiler": "^5.4.5",
+    "broccoli-concat": "0.0.13",
+    "broccoli-funnel": "^0.2.8",
+    "broccoli-source-map": "^0.2.3",
+    "broccoli-uglify-js": "^0.1.3"
+  }
+}

http://git-wip-us.apache.org/repos/asf/allura/blob/1dd78440/scripts/asf-release.sh
----------------------------------------------------------------------
diff --git a/scripts/asf-release.sh b/scripts/asf-release.sh
index 9239dc2..8ee73a4 100755
--- a/scripts/asf-release.sh
+++ b/scripts/asf-release.sh
@@ -41,6 +41,7 @@ prompt VERSION "Version" "$VERSION"
 RELEASE_BASE=allura-$VERSION
 RELEASE_DIR=$RELEASE_DIR_BASE/$RELEASE_BASE
 RELEASE_FILENAME=$RELEASE_BASE.tar.gz
+RELEASE_FILE_EXTRACTED=$RELEASE_DIR/$RELEASE_BASE
 RELEASE_FILE=$RELEASE_DIR/$RELEASE_FILENAME
 RELEASE_TAG=asf_release_$VERSION
 CLOSE_DATE=`date -d '+72 hours' +%F`
@@ -68,6 +69,17 @@ COMMIT_SHA=`git rev-parse $RELEASE_TAG`
 mkdir -p $RELEASE_DIR
 git archive -o $RELEASE_FILE --prefix $RELEASE_BASE/ $RELEASE_TAG
 
+# expand archive, run broccoli in it, rebuild archive
+cd $RELEASE_DIR
+tar xzf $RELEASE_FILE
+cd $RELEASE_FILE_EXTRACTED
+npm install >/dev/null
+BROCCOLI_ENV=production broccoli build Allura/allura/public/nf/js/build/
+rm -rf node_modules
+cd ..
+tar czf $RELEASE_FILE $RELEASE_BASE
+rm -rf $RELEASE_FILE_EXTRACTED
+
 gpg --default-key $KEY --armor --output $RELEASE_FILE.asc --detach-sig $RELEASE_FILE
 MD5_CHECKSUM=`cd $RELEASE_DIR ; md5sum $RELEASE_FILENAME` ; echo "$MD5_CHECKSUM" > $RELEASE_FILE.md5
 SHA1_CHECKSUM=`cd $RELEASE_DIR ; shasum -a1 $RELEASE_FILENAME` ; echo "$SHA1_CHECKSUM" > $RELEASE_FILE.sha1


[47/50] [abbrv] allura git commit: [#7924] ticket:837 Add tests for Icon.render

Posted by je...@apache.org.
[#7924] ticket:837 Add tests for Icon.render


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/4e37a231
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/4e37a231
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/4e37a231

Branch: refs/heads/ib/7924
Commit: 4e37a23122c481343043bae364f3b5e3d7ddb9a7
Parents: 939847b
Author: Igor Bondarenko <je...@gmail.com>
Authored: Thu Oct 15 18:40:51 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Thu Oct 15 18:40:51 2015 +0300

----------------------------------------------------------------------
 Allura/allura/tests/test_globals.py | 37 ++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/4e37a231/Allura/allura/tests/test_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_globals.py b/Allura/allura/tests/test_globals.py
index bb5d80e..8b7c0c5 100644
--- a/Allura/allura/tests/test_globals.py
+++ b/Allura/allura/tests/test_globals.py
@@ -881,3 +881,40 @@ class TestNeighborhoodCache(object):
         cache = NeighborhoodCache(30)
         assert_equal(cache._expired({'ts': _now - dt.timedelta(seconds=29)}), False)
         assert_equal(cache._expired({'ts': _now - dt.timedelta(seconds=30)}), True)
+
+
+class TestIconRender(object):
+
+    def setUp(self):
+        self.i = g.icons['edit']
+
+    def test_default(self):
+        html = u'<a class="icon fa fa-edit" href="#" title="Edit"></a>'
+        assert_equal(html, self.i.render())
+
+    def test_show_title(self):
+        html = u'<a class="icon fa fa-edit" href="#" title="Edit"><span>&nbsp;Edit</span></a>'
+        assert_equal(html, self.i.render(show_title=True))
+
+        html = u'<a class="icon fa fa-edit" href="#" title="&lt;script&gt;"><span>&nbsp;&lt;script&gt;</span></a>'
+        assert_equal(html, self.i.render(show_title=True, title="<script>"))
+
+    def test_extra_css(self):
+        html = u'<a class="icon fa fa-edit reply btn" href="#" title="Edit"></a>'
+        assert_equal(html, self.i.render(extra_css='reply btn'))
+
+    def test_no_closing_tag(self):
+        html = u'<a class="icon fa fa-edit" href="#" title="Edit">'
+        assert_equal(html, self.i.render(closing_tag=False))
+
+    def test_tag(self):
+        html = u'<div class="icon fa fa-edit" href="#" title="Edit"></div>'
+        assert_equal(html, self.i.render(tag='div'))
+
+    def test_kwargs(self):
+        html = u'<a class="icon fa fa-edit" data-id="123" href="#" title="Edit"></a>'
+        assert_equal(html, self.i.render(**{'data-id': '123'}))
+
+    def test_escaping(self):
+        html = u'<a class="icon fa fa-edit &#34;" data-url="&gt;" href="#" title="Edit"></a>'
+        assert_equal(html, self.i.render(extra_css='"', **{'data-url': '>'}))


[02/50] [abbrv] allura git commit: [#7871] ticket:852 Added a test for sending notification on wiki page deletion

Posted by je...@apache.org.
[#7871] ticket:852 Added a test for sending notification on wiki page deletion


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/4cc456f5
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/4cc456f5
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/4cc456f5

Branch: refs/heads/ib/7924
Commit: 4cc456f5646ca6ec329aa1cf52bc13d15e01cb6b
Parents: 6ba5e06
Author: Aleksey 'LXj' Alekseyev <go...@gmail.com>
Authored: Mon Sep 21 15:41:54 2015 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Sep 23 16:09:43 2015 +0000

----------------------------------------------------------------------
 ForgeWiki/forgewiki/tests/functional/test_root.py | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/4cc456f5/ForgeWiki/forgewiki/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/tests/functional/test_root.py b/ForgeWiki/forgewiki/tests/functional/test_root.py
index 608045b..b716877 100644
--- a/ForgeWiki/forgewiki/tests/functional/test_root.py
+++ b/ForgeWiki/forgewiki/tests/functional/test_root.py
@@ -705,12 +705,12 @@ class TestRootController(TestController):
     def test_page_delete(self):
         self.app.post('/wiki/aaa/update', params={
             'title': 'aaa',
-            'text': '',
+            'text': '111',
             'labels': '',
             'viewable_by-0.id': 'all'})
         self.app.post('/wiki/bbb/update', params={
             'title': 'bbb',
-            'text': '',
+            'text': '222',
             'labels': '',
             'viewable_by-0.id': 'all'})
         response = self.app.get('/wiki/browse_pages/')
@@ -720,6 +720,8 @@ class TestRootController(TestController):
         response = self.app.get('/wiki/browse_pages/')
         assert 'aaa' in response
         assert '?deleted=True">bbb' in response
+        n = M.Notification.query.get(subject="[test:wiki] test-admin removed page bbb")
+        assert '222' in n.text
 
     def test_mailto_links(self):
         self.app.get('/wiki/test_mailto/')


[41/50] [abbrv] allura git commit: [#7924] ticket:830 Change some of the icons

Posted by je...@apache.org.
[#7924] ticket:830 Change some of the icons


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/aee6e44d
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/aee6e44d
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/aee6e44d

Branch: refs/heads/ib/7924
Commit: aee6e44db2576c93daa32d2967be3af186e36eb1
Parents: 4774387
Author: Igor Bondarenko <je...@gmail.com>
Authored: Fri Aug 7 18:38:09 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Thu Oct 15 15:06:12 2015 +0000

----------------------------------------------------------------------
 .../user_profile/templates/send_message.html    |  2 +-
 .../ext/user_profile/templates/user_index.html  |  2 +-
 Allura/allura/lib/app_globals.py                | 53 ++++++++++++++------
 .../lib/widgets/resources/js/subscriptions.js   | 13 ++---
 Allura/allura/nf/allura/css/allura.css          |  5 +-
 Allura/allura/nf/allura/css/site_style.css      |  4 ++
 Allura/allura/templates/discussion/index.html   |  7 ++-
 .../templates/jinja_master/sidebar_menu.html    | 11 ++--
 Allura/allura/templates/repo/merge_request.html |  2 +-
 .../templates/widgets/search_results.html       |  5 +-
 Allura/allura/templates/widgets/subscribe.html  |  1 -
 .../forgeactivity/templates/index.html          |  2 +-
 .../templates/widgets/profile_section.html      |  2 +-
 ForgeBlog/forgeblog/templates/blog/index.html   |  2 +-
 ForgeBlog/forgeblog/templates/blog/post.html    |  6 +--
 ForgeDiscussion/forgediscussion/forum_main.py   |  6 +--
 .../templates/discussionforums/index.html       |  2 +-
 .../templates/discussionforums/thread.html      |  6 +--
 .../forgeshorturl/templates/index.html          | 13 ++---
 .../forgetracker/templates/tracker/bin.html     | 18 +++++--
 .../forgetracker/templates/tracker/index.html   |  8 +--
 .../templates/tracker/mass_edit.html            |  3 +-
 .../templates/tracker/mass_move.html            |  3 +-
 .../templates/tracker/milestone.html            |  6 ++-
 .../templates/tracker/milestones.html           |  2 +-
 .../forgetracker/templates/tracker/search.html  | 15 ++++--
 .../forgetracker/templates/tracker/ticket.html  | 10 ++--
 .../tracker_widgets/ticket_search_results.html  |  2 +-
 ForgeTracker/forgetracker/tracker_main.py       |  2 +-
 .../forgewiki/templates/wiki/page_edit.html     |  4 +-
 .../forgewiki/templates/wiki/page_history.html  |  4 +-
 .../forgewiki/templates/wiki/page_view.html     | 10 ++--
 ForgeWiki/forgewiki/wiki_main.py                |  2 +-
 33 files changed, 140 insertions(+), 93 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/aee6e44d/Allura/allura/ext/user_profile/templates/send_message.html
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/user_profile/templates/send_message.html b/Allura/allura/ext/user_profile/templates/send_message.html
index eb99f41..82fc3a9 100644
--- a/Allura/allura/ext/user_profile/templates/send_message.html
+++ b/Allura/allura/ext/user_profile/templates/send_message.html
@@ -28,7 +28,7 @@
   <link rel="alternate" type="application/atom+xml" title="Atom" href="feed.atom">
 {% endblock %}
 {% block actions %}
-  <a href="{{c.app.url}}feed.rss" title="Follow"><b data-icon="{{g.icons['feed'].char}}" class="ico {{g.icons['feed'].css}}"></b></a>
+  {{ g.icons['feed'].render(href=c.app.url + 'feed.rss', title='Follow') }}
 {% endblock %}
 
 {% block content %}

http://git-wip-us.apache.org/repos/asf/allura/blob/aee6e44d/Allura/allura/ext/user_profile/templates/user_index.html
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/user_profile/templates/user_index.html b/Allura/allura/ext/user_profile/templates/user_index.html
index 3e4ed44..19cf1c1 100644
--- a/Allura/allura/ext/user_profile/templates/user_index.html
+++ b/Allura/allura/ext/user_profile/templates/user_index.html
@@ -29,7 +29,7 @@
 {% endblock %}
 
 {% block actions %}
-  <a href="{{c.app.url}}feed.rss" title="Follow"><b data-icon="{{g.icons['feed'].char}}" class="ico {{g.icons['feed'].css}}"></b></a>
+  {{ g.icons['feed'].render(href=c.app.url + 'feed.rss', title='Follow') }}
 {% endblock %}
 
 {% block nav_menu %}

http://git-wip-us.apache.org/repos/asf/allura/blob/aee6e44d/Allura/allura/lib/app_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/app_globals.py b/Allura/allura/lib/app_globals.py
index 1d88c9d..850938e 100644
--- a/Allura/allura/lib/app_globals.py
+++ b/Allura/allura/lib/app_globals.py
@@ -48,6 +48,7 @@ from pypeline.markup import markup as pypeline_markup
 import ew as ew_core
 import ew.jinja2_ew as ew
 from ming.utils import LazyProperty
+from jinja2 import Markup
 
 import allura.tasks.event_tasks
 from allura import model as M
@@ -221,27 +222,33 @@ class Globals(object):
         self.analytics = analytics.GoogleAnalytics(accounts=accounts)
 
         self.icons = dict(
-            admin=Icon('x', 'ico-admin'),
-            pencil=Icon('p', 'ico-pencil'),
-            help=Icon('h', 'ico-help'),
-            search=Icon('s', 'ico-search'),
-            history=Icon('N', 'ico-history'),
-            feed=Icon('f', 'ico-feed'),
-            mail=Icon('M', 'ico-mail'),
+            move=Icon('fa fa-arrows', 'Move'),
+            edit=Icon('fa fa-edit', 'Edit'),
+            admin=Icon('fa fa-gear', 'Admin'),
+            send=Icon('fa fa-send-o', 'Send'),
+            add=Icon('fa fa-plus-circle', 'Add'),
+            moderate=Icon('fa fa-hand-stop-o', 'Moderate'),
+            pencil=Icon('fa fa-pencil', 'Edit'),
+            help=Icon('fa fa-question-circle', 'Help'),
+            eye=Icon('fa fa-eye', 'View'),
+            search=Icon('fa fa-search', 'Search'),
+            history=Icon('fa fa-calendar', 'History'),
+            feed=Icon('fa fa-rss', 'Feed'),
+            mail=Icon('fa fa-envelope-o', 'Subscribe'),
             reply=Icon('w', 'ico-reply'),
-            tag=Icon('z', 'ico-tag'),
+            tag=Icon('fa fa-tag', 'Tag'),
             flag=Icon('^', 'ico-flag'),
-            undelete=Icon('+', 'ico-undelete'),
-            delete=Icon('#', 'ico-delete'),
+            undelete=Icon('fa fa-undo', 'Undelete'),
+            delete=Icon('fa fa-trash-o', 'Delete'),
             close=Icon('D', 'ico-close'),
             table=Icon('n', 'ico-table'),
-            stats=Icon('Y', 'ico-stats'),
+            stats=Icon('fa fa-line-chart', 'Stats'),
             pin=Icon('@', 'ico-pin'),
             folder=Icon('o', 'ico-folder'),
             fork=Icon('R', 'ico-fork'),
             merge=Icon('J', 'ico-merge'),
-            plus=Icon('+', 'ico-plus'),
-            conversation=Icon('q', 'ico-conversation'),
+            plus=Icon('fa fa-plus-circle', 'Add'),
+            conversation=Icon('fa fa-comments', 'Conversation'),
             group=Icon('g', 'ico-group'),
             user=Icon('U', 'ico-user'),
             secure=Icon('(', 'ico-lock'),
@@ -586,6 +593,22 @@ class Globals(object):
 
 class Icon(object):
 
-    def __init__(self, char, css):
-        self.char = char
+    def __init__(self, css, title=None):
         self.css = css
+        self.title = title or u''
+
+    def render(self, show_title=False, extra_css=None, closing_tag=True, **kw):
+        title = kw.get('title') or self.title
+        attrs = {
+            'href': '#',
+            'title': title,
+            'class': ' '.join(['icon', self.css, extra_css or '']).strip(),
+        }
+        attrs.update(kw)
+        attrs = ew._Jinja2Widget().j2_attrs(attrs)
+        visible_title = u''
+        if show_title:
+            visible_title = u'<span>&nbsp;{}</span>'.format(Markup.escape(title))
+        closing_tag = u'</a>' if closing_tag else u''
+        icon = u'<a {}>{}{}'.format(attrs, visible_title, closing_tag)
+        return Markup(icon)

http://git-wip-us.apache.org/repos/asf/allura/blob/aee6e44d/Allura/allura/lib/widgets/resources/js/subscriptions.js
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/resources/js/subscriptions.js b/Allura/allura/lib/widgets/resources/js/subscriptions.js
index d5a7648..47407d8 100644
--- a/Allura/allura/lib/widgets/resources/js/subscriptions.js
+++ b/Allura/allura/lib/widgets/resources/js/subscriptions.js
@@ -37,22 +37,17 @@ SubscriptionForm = React.createClass({
   render: function() {
     var action = this.props.subscribed ? "Unsubscribe from" : "Subscribe to";
     var title = action + ' this ' + this.props.thing;
-    var link_opts = {
+    var opts = {
       ref: 'link',
-      className: this.props.subscribed ? 'active' : '',
+      className: this.props.icon.css + (this.props.subscribed ? ' active' : ''),
       href: '#',
       title: title,
       onClick: this.handleClick
     };
     if (this.props.in_progress) {
-      link_opts.style = {cursor: 'wait'};
+      opts.style = {cursor: 'wait'};
     }
-    var icon_opts = {
-      'data-icon': this.props.icon.char,
-      className: 'ico ' + this.props.icon.css,
-      title: title
-    };
-    return dom('a', link_opts, dom('b', icon_opts));
+    return dom('a', opts);
   },
 
   handleClick: function() {

http://git-wip-us.apache.org/repos/asf/allura/blob/aee6e44d/Allura/allura/nf/allura/css/allura.css
----------------------------------------------------------------------
diff --git a/Allura/allura/nf/allura/css/allura.css b/Allura/allura/nf/allura/css/allura.css
index 4ddebc6..184ff58 100644
--- a/Allura/allura/nf/allura/css/allura.css
+++ b/Allura/allura/nf/allura/css/allura.css
@@ -30,6 +30,10 @@ b.ico {
     background-repeat: no-repeat;
     vertical-align: middle;
 }
+a.fa { color: rgb(85, 85, 85); }
+a.fa:hover { text-decoration: none; }
+a.btn.fa { font-family: FontAwesome; }
+a.fa > span { font-family: sans-serif; }
 h2.dark b.ico, .modal b.ico {background-image: url('../images/neo-icon-set-ffffff-256x350.png');}
 
 b.ico.ico-fork { background-position: -240px -16px; }
@@ -102,4 +106,3 @@ tr.rev div.markdown_content p {
 #sidebar-admin-header h3 {
     padding-left: 2px;
 }
-

http://git-wip-us.apache.org/repos/asf/allura/blob/aee6e44d/Allura/allura/nf/allura/css/site_style.css
----------------------------------------------------------------------
diff --git a/Allura/allura/nf/allura/css/site_style.css b/Allura/allura/nf/allura/css/site_style.css
index a3fbc09..342c8dc 100644
--- a/Allura/allura/nf/allura/css/site_style.css
+++ b/Allura/allura/nf/allura/css/site_style.css
@@ -1904,6 +1904,7 @@ nav .ico {
   -o-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4) inset,0 1px 0 rgba(255, 255, 255, 0.9);
   box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4) inset,0 1px 0 rgba(255, 255, 255, 0.9);
   border: medium none;
+  font-family: sans-serif;
   position: absolute;
   right: 5px;
   top: 4px;
@@ -1925,6 +1926,9 @@ nav .ico {
   display: block;
   padding: 5px 10px;
 }
+#sidebar li > a.fa {
+  padding: 8px 10px;
+}
 #sidebar li > a:hover {
   background: rgba(229, 229, 229, 0.9);
   text-decoration: none;

http://git-wip-us.apache.org/repos/asf/allura/blob/aee6e44d/Allura/allura/templates/discussion/index.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/discussion/index.html b/Allura/allura/templates/discussion/index.html
index 11c987a..8d05ccd 100644
--- a/Allura/allura/templates/discussion/index.html
+++ b/Allura/allura/templates/discussion/index.html
@@ -24,9 +24,12 @@
 
 {% block actions %}
   {% if discussion.email_address and c.app.config.options.get('AllowEmailPosting', True) %}
-    <a href="{{h.really_unicode(discussion.email_link(subject=None))}}" class="email" title="Send Email to Create a New Topic" ><b data-icon="{{g.icons['pencil'].char}}" class="ico {{g.icons['pencil'].css}}"></b></a>
+    {{ g.icons['send'].render(
+          extra_css='email',
+          title='Send Email to Create a New Topic',
+          href=h.really_unicode(discussion.email_link(subject=None))) }}
   {% endif %}
-  <a href="feed" title="Feed" ><b data-icon="{{g.icons['feed'].char}}" class="ico {{g.icons['feed'].css}}"></b></a>
+  {{ g.icons['feed'].render(href='feed.rss') }}
 {% endblock %}
 
 {% block edit_box %}

http://git-wip-us.apache.org/repos/asf/allura/blob/aee6e44d/Allura/allura/templates/jinja_master/sidebar_menu.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/jinja_master/sidebar_menu.html b/Allura/allura/templates/jinja_master/sidebar_menu.html
index 3d9ab06..f95ef86 100644
--- a/Allura/allura/templates/jinja_master/sidebar_menu.html
+++ b/Allura/allura/templates/jinja_master/sidebar_menu.html
@@ -24,10 +24,13 @@
       {% do ul_active.append(True) %}
     {% endif %}
   <li{% if request.path.find(s.url,-s.url.__len__()) != -1 %} class="active"{% endif %}>
-      <a href="{{ s.url }}" {{ s.extra_html_attrs|xmlattr }} {% if s.className %} class="{{ s.className or '' }}" {% endif %} >
-      {% if s.ui_icon %} <b data-icon="{{ s.ui_icon.char }}" class="ico {{ s.ui_icon.css }}"></b>{% endif %}
+      {% if s.ui_icon %}
+        {{ s.ui_icon.render(href=s.url, extra_css=s.className, closing_tag=False, **s.extra_html_attrs) }}
+      {% else %}
+        <a href="{{ s.url }}" {{ s.extra_html_attrs|xmlattr }} {% if s.className %}class="{{ s.className or '' }}"{% endif %}>
+      {% endif %}
       <span{% if s.small != None %} class="has_small"{% endif %}>{{ h.really_unicode(s.label) }}</span>
-      {% if s.small != None %}<small>{{ s.small }}</small>{% endif %} </a>
+      {% if s.small != None %}<small>{{ s.small }}</small>{% endif %}</a>
   </li>
   {% else %}
     {% if ul_active[-1] %}
@@ -35,7 +38,7 @@
       {% do ul_active.append(False) %}
     {% endif %}
     {% if s.label %}
-      <h3 class="{{s.className or ''}}">{% if s.ui_icon %}<b data-icon="{{s.ui_icon.char}}" class="ico {{s.ui_icon.css}}"></b>{% endif %}{{s.label}}</h3>
+      <h3 class="{{s.className or ''}}">{% if s.ui_icon %}{{ s.ui_icon.render() }}{% endif %}{{s.label}}</h3>
     {% endif %}
   {% endif %}
 {%- endmacro %}

http://git-wip-us.apache.org/repos/asf/allura/blob/aee6e44d/Allura/allura/templates/repo/merge_request.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/repo/merge_request.html b/Allura/allura/templates/repo/merge_request.html
index 3f5e894..a0fe3c5 100644
--- a/Allura/allura/templates/repo/merge_request.html
+++ b/Allura/allura/templates/repo/merge_request.html
@@ -28,7 +28,7 @@ Merge Request #{{req.request_number}}: {{req.summary}} ({{req.status}})
 
 {% block actions %}
   {% if h.has_access(req, 'write')() %}
-    <a href="edit" title="Edit"><b data-icon="{{g.icons['pencil'].char}}" class="ico {{g.icons['pencil'].css}}" title="Edit"></b></a>
+    {{ g.icons['edit'].render(href='edit', show_title=True) }}
   {% endif %}
 {% endblock %}
 

http://git-wip-us.apache.org/repos/asf/allura/blob/aee6e44d/Allura/allura/templates/widgets/search_results.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/search_results.html b/Allura/allura/templates/widgets/search_results.html
index 464dab4..51d1c5f 100644
--- a/Allura/allura/templates/widgets/search_results.html
+++ b/Allura/allura/templates/widgets/search_results.html
@@ -25,10 +25,7 @@
   </div>
   {% if c.help_modal %}
   <div class="grid-6">
-    <a href="#" class="btn search_help_modal">
-      <b data-icon="{{g.icons['help'].char}}" class="ico {{g.icons['help'].css}}"></b>
-      Help
-    </a>
+    {{ g.icons['help'].render(extra_css='btn search_help_modal', show_title=True) }}
   </div>
   {% endif %}
   <div style="clear:both"></div>

http://git-wip-us.apache.org/repos/asf/allura/blob/aee6e44d/Allura/allura/templates/widgets/subscribe.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/subscribe.html b/Allura/allura/templates/widgets/subscribe.html
index 2b61f71..2cfa681 100644
--- a/Allura/allura/templates/widgets/subscribe.html
+++ b/Allura/allura/templates/widgets/subscribe.html
@@ -34,7 +34,6 @@
     "subscribed_to_tool": {{"true" if tool_subscribed else "false"}},
     "url": "{{action}}",
     "icon": {
-      "char": "{{g.icons['mail'].char}}",
       "css": "{{g.icons['mail'].css}}"
     }
   };

http://git-wip-us.apache.org/repos/asf/allura/blob/aee6e44d/ForgeActivity/forgeactivity/templates/index.html
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/templates/index.html b/ForgeActivity/forgeactivity/templates/index.html
index 1cadb3f..c4a57a0 100644
--- a/ForgeActivity/forgeactivity/templates/index.html
+++ b/ForgeActivity/forgeactivity/templates/index.html
@@ -32,7 +32,7 @@
 {% endblock %}
 
 {% block actions %}
-    <a href="feed.rss" title="RSS"><b data-icon="{{g.icons['feed'].char}}" class="ico {{g.icons['feed'].css}}" title="Feed"></b></a>
+    {{ g.icons['feed'].render(href='feed.rss', title='RSS') }}
     {% if c.user and c.user != c.user.anonymous() and followee != c.user %}
         {{c.follow_toggle.display(following=following)}}
     {% endif %}

http://git-wip-us.apache.org/repos/asf/allura/blob/aee6e44d/ForgeActivity/forgeactivity/templates/widgets/profile_section.html
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/templates/widgets/profile_section.html b/ForgeActivity/forgeactivity/templates/widgets/profile_section.html
index 8d09ef3..5f6fbee 100644
--- a/ForgeActivity/forgeactivity/templates/widgets/profile_section.html
+++ b/ForgeActivity/forgeactivity/templates/widgets/profile_section.html
@@ -28,7 +28,7 @@
     {% if c.user and not c.user.is_anonymous() and c.user != user %}
         {{follow_toggle.display(following=following, action=activity_app.url+'follow')}}
     {% endif %}
-    <a href="feed.rss" title="RSS"><b data-icon="{{g.icons['feed'].char}}" class="ico {{g.icons['feed'].css}}" title="Feed"></b></a>
+    {{ g.icons['feed'].render(href='feed.rss', title='RSS') }}
 {% endblock %}
 
 {% block section_class %}activity{% endblock %}

http://git-wip-us.apache.org/repos/asf/allura/blob/aee6e44d/ForgeBlog/forgeblog/templates/blog/index.html
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/templates/blog/index.html b/ForgeBlog/forgeblog/templates/blog/index.html
index 9a90f7b..5589d39 100644
--- a/ForgeBlog/forgeblog/templates/blog/index.html
+++ b/ForgeBlog/forgeblog/templates/blog/index.html
@@ -28,7 +28,7 @@
 {% endblock %}
 
 {% block actions %}
-    <a href="feed" title="RSS"><b data-icon="{{g.icons['feed'].char}}" class="ico {{g.icons['feed'].css}}" title="Feed"></b></a>
+    {{ g.icons['feed'].render(href='feed.rss', title='RSS') }}
 {% endblock %}
 
 {% block content %}

http://git-wip-us.apache.org/repos/asf/allura/blob/aee6e44d/ForgeBlog/forgeblog/templates/blog/post.html
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/templates/blog/post.html b/ForgeBlog/forgeblog/templates/blog/post.html
index d0a3434..979b1f6 100644
--- a/ForgeBlog/forgeblog/templates/blog/post.html
+++ b/ForgeBlog/forgeblog/templates/blog/post.html
@@ -24,13 +24,13 @@
 
 {% block actions %}
   {% if h.has_access(post, 'write')() %}
-    <a href="edit" title="Edit"><b data-icon="{{g.icons['pencil'].char}}" class="ico {{g.icons['pencil'].css}}"></b></a>
+    {{ g.icons['edit'].render(href='edit') }}
   {% endif %}
-  <a href="history" title="History"><b data-icon="{{g.icons['history'].char}}" class="ico {{g.icons['history'].css}}"></b></a>
+  {{ g.icons['history'].render(href='history') }}
   {% if c.user and c.user != c.user.anonymous() %}
     {{c.subscribe_form.display(value=subscribed, action='subscribe', style='icon')}}
   {% endif %}
-  <a href="feed" title="RSS"><b data-icon="{{g.icons['feed'].char}}" class="ico {{g.icons['feed'].css}}"></b></a>
+  {{ g.icons['feed'].render(href='feed.rss', title='RSS') }}
 {% endblock %}
 
 {% block content %}

http://git-wip-us.apache.org/repos/asf/allura/blob/aee6e44d/ForgeDiscussion/forgediscussion/forum_main.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/forum_main.py b/ForgeDiscussion/forgediscussion/forum_main.py
index 542b3f0..96c2389 100644
--- a/ForgeDiscussion/forgediscussion/forum_main.py
+++ b/ForgeDiscussion/forgediscussion/forum_main.py
@@ -164,7 +164,7 @@ class ForgeDiscussionApp(Application):
                             'deleted': False,
                         }).count()
                         moderate_link = SitemapEntry(
-                            'Moderate', "%smoderate/" % f.url(), ui_icon=g.icons['pencil'],
+                            'Moderate', "%smoderate/" % f.url(), ui_icon=g.icons['moderate'],
                             small=num_moderate)
                     forum_links.append(
                         SitemapEntry(f.name, f.url(), small=f.num_topics))
@@ -172,12 +172,12 @@ class ForgeDiscussionApp(Application):
             url = h.urlquote(
                 url + c.forum.shortname if getattr(c, 'forum', None) and c.forum else url)
             l.append(
-                SitemapEntry('Create Topic', url, ui_icon=g.icons['plus']))
+                SitemapEntry('Create Topic', url, ui_icon=g.icons['add']))
             if has_access(c.app, 'configure')():
                 l.append(SitemapEntry('Add Forum', c.app.url +
                          'new_forum', ui_icon=g.icons['conversation']))
                 l.append(SitemapEntry('Admin Forums', c.project.url() + 'admin/' +
-                         self.config.options.mount_point + '/forums', ui_icon=g.icons['pencil']))
+                         self.config.options.mount_point + '/forums', ui_icon=g.icons['admin']))
             if moderate_link:
                 l.append(moderate_link)
             # if we are in a thread and not anonymous, provide placeholder

http://git-wip-us.apache.org/repos/asf/allura/blob/aee6e44d/ForgeDiscussion/forgediscussion/templates/discussionforums/index.html
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/templates/discussionforums/index.html b/ForgeDiscussion/forgediscussion/templates/discussionforums/index.html
index 941975a..4de5b94 100644
--- a/ForgeDiscussion/forgediscussion/templates/discussionforums/index.html
+++ b/ForgeDiscussion/forgediscussion/templates/discussionforums/index.html
@@ -24,7 +24,7 @@
 {% block header %}{{c.app.config.options.mount_label}}{% endblock %}
 
 {% block actions %}
-  <a href="feed" class="follow" title="Follow"><b data-icon="{{g.icons['feed'].char}}" class="ico {{g.icons['feed'].css}}"></b></a>
+  {{ g.icons['feed'].render(href='feed.rss', extra_css='follow', title='Follow') }}
 {% endblock %}
 
 {% if h.has_access(c.app, 'configure')() and (not hide_forum) %}

http://git-wip-us.apache.org/repos/asf/allura/blob/aee6e44d/ForgeDiscussion/forgediscussion/templates/discussionforums/thread.html
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/templates/discussionforums/thread.html b/ForgeDiscussion/forgediscussion/templates/discussionforums/thread.html
index 6bd6fec..076790a 100644
--- a/ForgeDiscussion/forgediscussion/templates/discussionforums/thread.html
+++ b/ForgeDiscussion/forgediscussion/templates/discussionforums/thread.html
@@ -27,10 +27,10 @@
 
 {% block actions %}
   {% if show_moderate and h.has_access(thread, 'moderate')() %}
-  <a href="#" title="Moderate" id="mod_thread_link"><b data-icon="{{g.icons['pencil'].char}}" class="ico {{g.icons['pencil'].css}}"></b></a>
+    {{ g.icons['moderate'].render(id='mod_thread_link') }}
   {% endif %}
-  <a href="#" title="Label This" class="thread_tag"><b data-icon="z" class="ico ico-tag"></b></a>
-  <a href="feed.rss" class="thread_feed0" title="Follow This"><b data-icon="{{g.icons['feed'].char}}" class="ico {{g.icons['feed'].css}}"></b></a>
+  {{ g.icons['tag'].render(title='Label This', extra_css='thread_tag') }}
+  {{ g.icons['feed'].render(href='feed.rss', title='Follow This', extra_css='thread_feed0') }}
 {% endblock %}
 
 {% block edit_box %}

http://git-wip-us.apache.org/repos/asf/allura/blob/aee6e44d/ForgeShortUrl/forgeshorturl/templates/index.html
----------------------------------------------------------------------
diff --git a/ForgeShortUrl/forgeshorturl/templates/index.html b/ForgeShortUrl/forgeshorturl/templates/index.html
index e370812..178345b 100644
--- a/ForgeShortUrl/forgeshorturl/templates/index.html
+++ b/ForgeShortUrl/forgeshorturl/templates/index.html
@@ -23,15 +23,12 @@
 
 {% block actions %}
   {% if can_create %}
-  <a href="{{ '{}admin/{}/add/'.format(c.project.url(), c.app.config.options.mount_point) }}"
-     title="Add Short URL"
-     class="add-short-url">
-    <b data-icon="{{g.icons['plus'].char}}" class="ico {{g.icons['plus'].css}}"></b>
-  </a>
+  {{ g.icons['plus'].render(
+      href='{}admin/{}/add/'.format(c.project.url(), c.app.config.options.mount_point),
+      title="Add Short URL",
+      extra_css="add-short-url") }}
   {% endif %}
-  <a href="search/" title="Search">
-    <b data-icon="{{g.icons['search'].char}}" class="ico {{g.icons['search'].css}}"></b>
-  </a>
+  {{ g.icons['search'].render(href='search/') }}
 {% endblock %}
 
 {% block content %}

http://git-wip-us.apache.org/repos/asf/allura/blob/aee6e44d/ForgeTracker/forgetracker/templates/tracker/bin.html
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/templates/tracker/bin.html b/ForgeTracker/forgetracker/templates/tracker/bin.html
index 07d320d..58dce0f 100644
--- a/ForgeTracker/forgetracker/templates/tracker/bin.html
+++ b/ForgeTracker/forgetracker/templates/tracker/bin.html
@@ -50,12 +50,17 @@
             <td class="edit" style="{% if not bin.error %}display:none{% else %}vertical-align:top{% endif %}"><input type="text" name="bins-{{loop.index0}}.summary" value="{{bin.summary}}"></td>
             <td class="edit" {% if not bin.error %}style="display:none"{% endif %}>
                 <input class="grid-8" type="text" name="bins-{{loop.index0}}.terms" value="{{bin.terms}}">
-                <span class="grid-3"><a href="{{tg.url(app.url + 'search_help/')}}" target="_blank" class="btn search_help_modal"><b data-icon="{{g.icons['help'].char}}" class="ico {{g.icons['help'].css}}"></b> Help</a></span>
+                <span class="grid-3">
+                  {{ g.icons['help'].render(
+                      show_title=True,
+                      target='_blank',
+                      href=tg.url(app.url + 'search_help/'),
+                      extra_css='btn search_help_modal') }}
                 {% if bin.error %}<br/><span style="color:red">{{bin.error}}</span>{% endif %}
             </td>
             <td style="width:40px;">
-              <a href="#" title="Delete" class="del_bin"><b data-icon="{{g.icons['delete'].char}}" class="ico {{g.icons['delete'].css}}"></b></a>
-              <a href="#" title="Edit" class="edit_bin"><b data-icon="{{g.icons['pencil'].char}}" class="ico {{g.icons['pencil'].css}}"></b></a>
+              {{ g.icons['delete'].render(extra_css='del_bin') }}
+              {{ g.icons['edit'].render(extra_css='edit_bin') }}
               <input type="hidden" name="bins-{{loop.index0}}.id" value="{{bin._id | string}}">
               <input type="hidden" name="bins-{{loop.index0}}.delete" value="False" class="delete_flag">
             </td>
@@ -70,7 +75,12 @@
           </td>
           <td>
             <input class="grid-8" type="text" name="bins-{{num_bins}}.terms" placeholder="Terms" {% if new_bin %}value="{{new_bin.terms}}"{% endif %}>
-            <span class="grid-3"><a href="{{tg.url(app.url + 'search_help/')}}" target="_blank" class="btn search_help_modal"><b data-icon="{{g.icons['help'].char}}" class="ico {{g.icons['help'].css}}"></b> Help</a></span>
+            <span class="grid-3">
+              {{ g.icons['help'].render(
+                  show_title=True,
+                  target='_blank',
+                  href=tg.url(app.url + 'search_help/'),
+                  extra_css='btn search_help_modal') }}
             {% if new_bin and new_bin.error %}<br/><span class="err" style="color:red">{{new_bin.error}}</span>{% endif %}
           </td>
           <td>&nbsp;</td>

http://git-wip-us.apache.org/repos/asf/allura/blob/aee6e44d/ForgeTracker/forgetracker/templates/tracker/index.html
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/templates/tracker/index.html b/ForgeTracker/forgetracker/templates/tracker/index.html
index 3d7c5d1..c759c15 100644
--- a/ForgeTracker/forgetracker/templates/tracker/index.html
+++ b/ForgeTracker/forgetracker/templates/tracker/index.html
@@ -31,15 +31,17 @@
 
 {% block actions %}
   {{ lib.maximize_content_button() }}
-  <a href="{{c.app.url}}feed.rss" title="Follow"><b data-icon="{{g.icons['feed'].char}}" class="ico {{g.icons['feed'].css}}"></b></a>
+    {{ g.icons['feed'].render(href=c.app.url + 'feed.rss', title='Follow') }}
   {% if c.user and c.user != c.user.anonymous() %}
     {{c.subscribe_form.display(value=subscribed, action='subscribe', style='icon')}}
   {% endif %}
   {% if allow_edit %}
-    <a href="{{tg.url(c.app.url+'edit/', dict(q=url_q, limit=limit, sort=url_sort, page=page, filter=filter))}}" title="Bulk Edit"><b data-icon="{{g.icons['pencil'].char}}" class="ico {{g.icons['pencil'].css}}"></b></a>
+    {% set bulk_edit_url = tg.url(c.app.url+'edit/', dict(q=url_q, limit=limit, sort=url_sort, page=page, filter=filter)) %}
+    {{ g.icons['edit'].render(href=bulk_edit_url, title='Bulk Edit') }}
   {% endif %}
   {% if allow_move %}
-    <a href="{{tg.url(c.app.url + 'move/', dict(q=url_q, limit=limit, sort=url_sort, page=page, filter=filter))}}" title="Bulk Move"><b data-icon="" class=""></b>Bulk Move</a>
+    {% set move_url = tg.url(c.app.url + 'move/', dict(q=url_q, limit=limit, sort=url_sort, page=page, filter=filter)) %}
+    {{ g.icons['move'].render(href=move_url, title='Bulk Move', show_title=True) }}
   {% endif %}
 {% endblock %}
 

http://git-wip-us.apache.org/repos/asf/allura/blob/aee6e44d/ForgeTracker/forgetracker/templates/tracker/mass_edit.html
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/templates/tracker/mass_edit.html b/ForgeTracker/forgetracker/templates/tracker/mass_edit.html
index e3a3ee2..b98862f 100644
--- a/ForgeTracker/forgetracker/templates/tracker/mass_edit.html
+++ b/ForgeTracker/forgetracker/templates/tracker/mass_edit.html
@@ -31,7 +31,8 @@
 {% block header %}ForgeTracker for {{c.project.shortname}}{% endblock %}
 
 {% block actions %}
-    <a href="{{tg.url(c.app.url+'edit/', dict(q=q, limit=limit, sort=sort, page=page))}}" title="Bulk Edit"><b data-icon="{{g.icons['pencil'].char}}" class="ico {{g.icons['pencil'].css}} active"></b></a>
+  {% set edit_url = tg.url(c.app.url+'edit/', dict(q=q, limit=limit, sort=sort, page=page)) %}
+  {{ g.icons['edit'].render(href=edit_url, title='Bulk Edit', extra_css='active') }}
 {% endblock %}
 
 {% block edit_box %}

http://git-wip-us.apache.org/repos/asf/allura/blob/aee6e44d/ForgeTracker/forgetracker/templates/tracker/mass_move.html
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/templates/tracker/mass_move.html b/ForgeTracker/forgetracker/templates/tracker/mass_move.html
index ac5c515..a4b24ca 100644
--- a/ForgeTracker/forgetracker/templates/tracker/mass_move.html
+++ b/ForgeTracker/forgetracker/templates/tracker/mass_move.html
@@ -19,7 +19,8 @@
 {% extends 'forgetracker:templates/tracker/mass_edit.html' %}
 
 {% block actions %}
-<a href="{{tg.url(c.app.url+'move/', dict(q=q, limit=limit, sort=sort, page=page))}}" title="Bulk Move" class="active"><b data-icon="" class=""></b>Bulk Move</a>
+{% set move_url = tg.url(c.app.url+'move/', dict(q=q, limit=limit, sort=sort, page=page)) %}
+{{ g.icons['move'].render(href=move_url, title='Bulk Move', extra_css='active', show_title=True) }}
 {% endblock %}
 
 {% block edit_box %}

http://git-wip-us.apache.org/repos/asf/allura/blob/aee6e44d/ForgeTracker/forgetracker/templates/tracker/milestone.html
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/templates/tracker/milestone.html b/ForgeTracker/forgetracker/templates/tracker/milestone.html
index 6107486..bb695f1 100644
--- a/ForgeTracker/forgetracker/templates/tracker/milestone.html
+++ b/ForgeTracker/forgetracker/templates/tracker/milestone.html
@@ -28,10 +28,12 @@
 {% block actions %}
 {{ lib.maximize_content_button() }}
 {% if allow_edit %}
-  <a href="{{tg.url(c.app.url+'edit/', dict(q=q, limit=limit, sort=url_sort, page=page, filter=filter))}}" title="Bulk Edit"><b data-icon="{{g.icons['pencil'].char}}" class="ico {{g.icons['pencil'].css}}"></b></a>
+  {% set bulk_edit_url = tg.url(c.app.url+'edit/', dict(q=q, limit=limit, sort=url_sort, page=page, filter=filter)) %}
+  {{ g.icons['edit'].render(href=bulk_edit_url, title='Bulk Edit') }}
 {% endif %}
 {% if allow_move %}
-  <a href="{{tg.url(c.app.url + 'move/', dict(q=q, limit=limit, sort=url_sort, page=page, filter=filter))}}" title="Bulk Move"><b data-icon="" class=""></b>Bulk Move</a>
+  {% set bulk_move_url = tg.url(c.app.url + 'move/', dict(q=q, limit=limit, sort=url_sort, page=page, filter=filter)) %}
+  {{ g.icons['move'].render(href=bulk_move_url, title='Bulk Move', show_title=True) }}
 {% endif %}
 {% endblock %}
 

http://git-wip-us.apache.org/repos/asf/allura/blob/aee6e44d/ForgeTracker/forgetracker/templates/tracker/milestones.html
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/templates/tracker/milestones.html b/ForgeTracker/forgetracker/templates/tracker/milestones.html
index a5e6db9..c8585b6 100644
--- a/ForgeTracker/forgetracker/templates/tracker/milestones.html
+++ b/ForgeTracker/forgetracker/templates/tracker/milestones.html
@@ -65,7 +65,7 @@
           {{c.date_field.display(value=m.due_date)}}
         </td>
         <td>{{m.closed}} / {{m.total}}</td>
-        <td style="width:20px;"><a href="#" title="Edit" class="edit_milestone"><b data-icon="{{g.icons['pencil'].char}}" class="ico {{g.icons['pencil'].css}}"></b></a></td>
+        <td style="width:20px;">{{ g.icons['edit'].render(extra_css='edit_milestone') }}</td>
       </tr>
       {% else %}
       <tr class="empty_message">

http://git-wip-us.apache.org/repos/asf/allura/blob/aee6e44d/ForgeTracker/forgetracker/templates/tracker/search.html
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/templates/tracker/search.html b/ForgeTracker/forgetracker/templates/tracker/search.html
index 8c651a7..f2b83ab 100644
--- a/ForgeTracker/forgetracker/templates/tracker/search.html
+++ b/ForgeTracker/forgetracker/templates/tracker/search.html
@@ -31,12 +31,15 @@
 
 {% block actions %}
   {{ lib.maximize_content_button() }}
-  <a href="{{tg.url(c.app.url+'search_feed/', dict(q=q, limit=limit, sort=sort))}}" title="Feed"><b data-icon="{{g.icons['feed'].char}}" class="ico {{g.icons['feed'].css}}"></b></a>
+  {% set feed_url = tg.url(c.app.url+'search_feed/', dict(q=q, limit=limit, sort=sort)) %}
+  {{ g.icons['feed'].render(href=feed_url) }}
 {% if allow_edit and count != 0 %}
-  <a href="{{tg.url(c.app.url+'edit/', dict(q=q, limit=limit, sort=sort, page=page, filter=filter))}}" title="Bulk Edit"><b data-icon="{{g.icons['pencil'].char}}" class="ico {{g.icons['pencil'].css}}"></b></a>
+  {% set bulk_edit_url = tg.url(c.app.url+'edit/', dict(q=q, limit=limit, sort=sort, page=page, filter=filter)) %}
+  {{ g.icons['edit'].render(href=bulk_edit_url, title='Bulk Edit') }}
 {% endif %}
 {% if allow_move and count != 0 %}
-  <a href="{{tg.url(c.app.url + 'move/', dict(q=q, limit=limit, sort=sort, page=page, filter=filter))}}" title="Bulk Move"><b data-icon="" class=""></b>Bulk Move</a>
+  {% set bulk_move_url = tg.url(c.app.url+'move/', dict(q=q, limit=limit, sort=sort, page=page, filter=filter)) %}
+  {{ g.icons['move'].render(href=bulk_move_url, title='Bulk Move', show_title=True) }}
 {% endif %}
 {% endblock %}
 
@@ -75,7 +78,11 @@
   {% endif %}
   <input type="submit" value="Search"/>
 </form>
-<a href="{{tg.url(c.app.url + 'search_help/')}}" target="_blank" class="btn search_help_modal"><b data-icon="{{g.icons['help'].char}}" class="ico {{g.icons['help'].css}}"></b> Help</a>
+{{ g.icons['help'].render(
+    show_title=True,
+    target='_blank',
+    href=tg.url(c.app.url + 'search_help/'),
+    extra_css='btn search_help_modal') }}
 
 </div>
 <div style="clear:both"></div>

http://git-wip-us.apache.org/repos/asf/allura/blob/aee6e44d/ForgeTracker/forgetracker/templates/tracker/ticket.html
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/templates/tracker/ticket.html b/ForgeTracker/forgetracker/templates/tracker/ticket.html
index a68e723..d3b0342 100644
--- a/ForgeTracker/forgetracker/templates/tracker/ticket.html
+++ b/ForgeTracker/forgetracker/templates/tracker/ticket.html
@@ -34,20 +34,20 @@
 {% set editable = h.has_access(ticket, 'update') and not ticket.deleted %}
 
 {% block actions %}
-<a href="{{ticket.url()}}feed.rss" title="Follow this Ticket"><b data-icon="{{g.icons['feed'].char}}" class="ico {{g.icons['feed'].css}}"></b></a>
+  {{ g.icons['feed'].render(href='feed.rss', title='Follow this Ticket') }}
 {% if c.user and c.user != c.user.anonymous() %}
   {{c.subscribe_form.display(value=subscribed, tool_subscribed=tool_subscribed, action='subscribe', style='icon')}}
 {% endif %}
 {% if h.has_access(ticket.app, 'admin') %}
-  <a href="move" title="Move"><b data-icon="{{g.icons['pencil'].char}}" class="ico {{g.icons['pencil'].css}}"></b> Move</a>
+  {{ g.icons['move'].render(show_title=True, href='move') }}
 {% endif %}
 {% if editable %}
-  <a href="#" title="Edit" class="edit_ticket"><b data-icon="{{g.icons['pencil'].char}}" class="ico {{g.icons['pencil'].css}}"></b> Edit</a>
+  {{ g.icons['edit'].render(show_title=True, extra_css='edit_ticket') }}
   {%if h.has_access(ticket, 'delete') and not ticket.deleted%}
-    <a class="post-link" href="./delete" title="Delete"><b data-icon="{{g.icons['delete'].char}}" class="ico {{g.icons['delete'].css}}" title="Delete"></b></a>
+    {{ g.icons['delete'].render(href='delete', extra_css='post-link') }}
   {% endif %}
 {%elif h.has_access(ticket, 'delete') and ticket.deleted%}
-  <a class="post-link" href="undelete" title="Undelete"><b data-icon="{{g.icons['undelete'].char}}" class="ico {{g.icons['undelete'].css}}" title="Undelete"></b></a>
+  {{ g.icons['undelete'].render(href='undelete', extra_css='post-link') }}
 {% endif %}
 {% endblock %}
 

http://git-wip-us.apache.org/repos/asf/allura/blob/aee6e44d/ForgeTracker/forgetracker/templates/tracker_widgets/ticket_search_results.html
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/templates/tracker_widgets/ticket_search_results.html b/ForgeTracker/forgetracker/templates/tracker_widgets/ticket_search_results.html
index 2634bbe..1266e08 100644
--- a/ForgeTracker/forgetracker/templates/tracker_widgets/ticket_search_results.html
+++ b/ForgeTracker/forgetracker/templates/tracker_widgets/ticket_search_results.html
@@ -51,7 +51,7 @@
             </th>
           {% endfor %}
           <th id="select_col_menu">
-            <a href="#" id="col_menu" title="Select Columns"><b data-icon="{{g.icons['admin'].char}}" class="ico {{g.icons['admin'].css}}"></b></a>
+            {{ g.icons['admin'].render(id='col_menu', title='Select Columns') }}
           </th>
         </tr>
       </thead>

http://git-wip-us.apache.org/repos/asf/allura/blob/aee6e44d/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index ad63b74..202ef82 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -370,7 +370,7 @@ class ForgeTrackerApp(Application):
         if pending_mod_count and has_access(discussion, 'moderate')():
             links.append(
                 SitemapEntry(
-                    'Moderate', discussion.url() + 'moderate', ui_icon=g.icons['pencil'],
+                    'Moderate', discussion.url() + 'moderate', ui_icon=g.icons['moderate'],
                     small=pending_mod_count))
 
         links += milestones

http://git-wip-us.apache.org/repos/asf/allura/blob/aee6e44d/ForgeWiki/forgewiki/templates/wiki/page_edit.html
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/templates/wiki/page_edit.html b/ForgeWiki/forgewiki/templates/wiki/page_edit.html
index 4e9584b..5b3bada 100644
--- a/ForgeWiki/forgewiki/templates/wiki/page_edit.html
+++ b/ForgeWiki/forgewiki/templates/wiki/page_edit.html
@@ -32,9 +32,9 @@
 {% endblock %}
 
 {% block actions %}
-  <a href="." title="View Page"><b data-icon="{{g.icons['search'].char}}" class="ico {{g.icons['search'].css}}" title="View Page"></b></a>
+  {{ g.icons['eye'].render(href='.', title='View Page') }}
   {% if page_exists and h.has_access(page, 'delete')() %}
-    <a class="post-link" href="#" title="Delete"><b data-icon="{{g.icons['delete'].char}}" class="ico {{g.icons['delete'].css}}" title="Delete"></b></a>
+    {{ g.icons['delete'].render(extra_css='post-link') }}
     <div class="confirmation_dialog" style="display:none">
         <b class="ico ico-close close" data-icon="D"></b>
 

http://git-wip-us.apache.org/repos/asf/allura/blob/aee6e44d/ForgeWiki/forgewiki/templates/wiki/page_history.html
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/templates/wiki/page_history.html b/ForgeWiki/forgewiki/templates/wiki/page_history.html
index 41ff4ba..d191337 100644
--- a/ForgeWiki/forgewiki/templates/wiki/page_history.html
+++ b/ForgeWiki/forgewiki/templates/wiki/page_history.html
@@ -24,7 +24,7 @@
 {% block header %}{{title}}{% endblock %}
 
 {% block actions %}
-  <a href="." title="View Page"><b data-icon="{{g.icons['search'].char}}" class="ico {{g.icons['search'].css}}" title="View Page"></b></a>
+  {{ g.icons['eye'].render(href='.', title='View Page') }}
 {% endblock %}
 
 {% block wiki_content %}
@@ -67,7 +67,7 @@
                 </p>
               </div>
             {% endif %}
-            <a href="./?version={{p.version}}"><b data-icon="{{g.icons['search'].char}}" class="ico {{g.icons['search'].css}}" title="View Revision"></b></a>
+            {{ g.icons['eye'].render(href='./?version={}'.format(p.version), title='View Revision') }}
           </td>
         </tr>
         {% set i = i+1 %}

http://git-wip-us.apache.org/repos/asf/allura/blob/aee6e44d/ForgeWiki/forgewiki/templates/wiki/page_view.html
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/templates/wiki/page_view.html b/ForgeWiki/forgewiki/templates/wiki/page_view.html
index 5762064..01bc09e 100644
--- a/ForgeWiki/forgewiki/templates/wiki/page_view.html
+++ b/ForgeWiki/forgewiki/templates/wiki/page_view.html
@@ -42,11 +42,11 @@
 {% block actions %}
   {% if not page['deleted'] %}
     {% if c.user and c.user != c.user.anonymous() %}
-      <a href="edit" title="Edit"><b data-icon="{{g.icons['pencil'].char}}" class="ico {{g.icons['pencil'].css}}" title="Edit"></b>&nbsp;Edit</a>
+      {{ g.icons['edit'].render(href='edit', show_title=True) }}
     {% endif %}
-    <a href="history" title="History"><b data-icon="{{g.icons['history'].char}}" class="ico {{g.icons['history'].css}}" title="History"></b></a>
+      {{ g.icons['history'].render(href='history') }}
   {% elif h.has_access(page, 'delete')() %}
-    <a class="post-link" href="#" title="Undelete"><b data-icon="{{g.icons['undelete'].char}}" class="ico {{g.icons['undelete'].css}}" title="Undelete"></b></a>
+    {{ g.icons['undelete'].render(extra_css='post-link') }}
     <div class="confirmation_dialog" style="display:none">
         <b class="ico ico-close close" data-icon="D"></b>
         <h1>Confirm page restoration</h1>
@@ -64,8 +64,8 @@
   {% if c.user and c.user != c.user.anonymous() %}
     {{c.subscribe_form.display(value=page_subscribed, action='subscribe', style='icon')}}
   {% endif %}
-	<a href="feed" title="RSS"><b data-icon="{{g.icons['feed'].char}}" class="ico {{g.icons['feed'].css}}" title="Feed"></b></a>
-  <a href="../search" title="Search"><b data-icon="{{g.icons['search'].char}}" class="ico {{g.icons['search'].css}}" title="Search"></b></a>
+  {{ g.icons['feed'].render(href='feed', title='RSS') }}
+  {{ g.icons['search'].render(href='../search') }}
 {% endblock %}
 
 {% block wiki_content %}

http://git-wip-us.apache.org/repos/asf/allura/blob/aee6e44d/ForgeWiki/forgewiki/wiki_main.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index f78a9b0..afdebec 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -241,7 +241,7 @@ The wiki uses [Markdown](%s) syntax.
         if pending_mod_count and h.has_access(discussion, 'moderate')():
             links.append(
                 SitemapEntry(
-                    'Moderate', discussion.url() + 'moderate', ui_icon=g.icons['pencil'],
+                    'Moderate', discussion.url() + 'moderate', ui_icon=g.icons['moderate'],
                     small=pending_mod_count))
         if not c.user.is_anonymous():
             subscribed = M.Mailbox.subscribed(app_config_id=self.config._id)


[31/50] [abbrv] allura git commit: Allow token auth over http when in debug mode

Posted by je...@apache.org.
Allow token auth over http when in debug mode


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/93be1519
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/93be1519
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/93be1519

Branch: refs/heads/ib/7924
Commit: 93be151997c74d269fd4ed0cd1081a1eb48e2b0a
Parents: 2bdcb95
Author: Heith Seewald <hs...@hsmb.local>
Authored: Fri Oct 9 12:25:38 2015 -0400
Committer: Heith Seewald <hs...@hsmb.local>
Committed: Fri Oct 9 12:25:38 2015 -0400

----------------------------------------------------------------------
 Allura/allura/controllers/rest.py | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/93be1519/Allura/allura/controllers/rest.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/rest.py b/Allura/allura/controllers/rest.py
index 2578fa2..30d28d9 100644
--- a/Allura/allura/controllers/rest.py
+++ b/Allura/allura/controllers/rest.py
@@ -21,8 +21,9 @@
 import logging
 
 import oauth2 as oauth
+from paste.util.converters import asbool
 from webob import exc
-from tg import expose, flash, redirect
+from tg import expose, flash, redirect, config
 from pylons import tmpl_context as c, app_globals as g
 from pylons import request, response
 
@@ -117,7 +118,8 @@ class OAuthNegotiator(object):
             # handle bearer tokens
             # skip https check if auth invoked from tests
             testing = request.environ.get('paste.testing', False)
-            if not testing and request.scheme != 'https':
+            debug = asbool(config.get('debug', False))
+            if not testing and request.scheme != 'https' and not debug:
                 request.environ['pylons.status_code_redirect'] = True
                 raise exc.HTTPForbidden
             access_token = M.OAuthAccessToken.query.get(api_key=access_token)


[03/50] [abbrv] allura git commit: [#7871] ticket:848 Added a notification after deleting a wiki page

Posted by je...@apache.org.
[#7871] ticket:848 Added a notification after deleting a wiki page


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/6ba5e061
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/6ba5e061
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/6ba5e061

Branch: refs/heads/ib/7924
Commit: 6ba5e0615bd91cf42bea8c3afe785123b7952bc1
Parents: 90fe547
Author: Aleksey 'LXj' Alekseyev <go...@gmail.com>
Authored: Sat Aug 29 15:09:01 2015 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Sep 23 16:09:43 2015 +0000

----------------------------------------------------------------------
 ForgeWiki/forgewiki/model/wiki.py | 5 +++++
 1 file changed, 5 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/6ba5e061/ForgeWiki/forgewiki/model/wiki.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/model/wiki.py b/ForgeWiki/forgewiki/model/wiki.py
index 2ca4f8f..9ddc7f2 100644
--- a/ForgeWiki/forgewiki/model/wiki.py
+++ b/ForgeWiki/forgewiki/model/wiki.py
@@ -245,6 +245,11 @@ class Page(VersionedArtifact, ActivityObject):
         }).all()
 
     def delete(self):
+        subject = '%s removed page %s' % (
+            context.user.username, self.title)
+        description = self.text
+        Notification.post(
+            artifact=self, topic='metadata', text=description, subject=subject)
         Shortlink.query.remove(dict(ref_id=self.index_id()))
         self.deleted = True
         suffix = " {:%Y-%m-%d %H:%M:%S.%f}".format(datetime.utcnow())


[49/50] [abbrv] allura git commit: [#7924] ticket:837 Update tests

Posted by je...@apache.org.
[#7924] ticket:837 Update tests


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/d72156ae
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/d72156ae
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/d72156ae

Branch: refs/heads/ib/7924
Commit: d72156aee7306e8d4504b62c020d8b21a4f1543e
Parents: 4dae87e
Author: Igor Bondarenko <je...@gmail.com>
Authored: Thu Oct 15 16:52:07 2015 +0000
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Thu Oct 15 16:52:07 2015 +0000

----------------------------------------------------------------------
 .../forgediscussion/tests/functional/test_forum.py        |  4 +++-
 ForgeGit/forgegit/tests/functional/test_controllers.py    |  2 +-
 ForgeTracker/forgetracker/tests/functional/test_root.py   | 10 +++++-----
 ForgeWiki/forgewiki/tests/functional/test_root.py         |  2 +-
 4 files changed, 10 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/d72156ae/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
index c66d5f8..d5bb39f 100644
--- a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
+++ b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
@@ -489,7 +489,9 @@ class TestForum(TestController):
 
         r = self.app.get(thread.request.url)
         assert '<div class="display_post moderate">' in r
-        assert '<a href="#" class="reply_post btn" style="display:none">' in r
+        assert '<a class="icon fa fa-reply reply_post btn" href="#" style="display:none;" title="Reply">'\
+               '<span>&nbsp;Reply</span></a>' in r
+
         assert r.html.find(
             'a', {'class': 'little_link shortlink', 'style': 'display:none'}) is not None
         assert 'name="delete"' in r

http://git-wip-us.apache.org/repos/asf/allura/blob/d72156ae/ForgeGit/forgegit/tests/functional/test_controllers.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/tests/functional/test_controllers.py b/ForgeGit/forgegit/tests/functional/test_controllers.py
index 0e0928d..9ef589d 100644
--- a/ForgeGit/forgegit/tests/functional/test_controllers.py
+++ b/ForgeGit/forgegit/tests/functional/test_controllers.py
@@ -696,7 +696,7 @@ class TestFork(_TestCase):
                               'summary': 'summary',
                               'description': 'description',
                           }).follow()
-        assert '<a href="edit" title="Edit"><b data-icon="p" class="ico ico-pencil" title="Edit"></b></a>' in r
+        assert '<a class="icon fa fa-edit" href="edit" title="Edit"><span>&nbsp;Edit</span></a>' in r
         r = self.app.get('/p/test/src-git/merge-requests/1/edit')
         assert 'value="summary"' in r
         assert '<option selected value="zz">zz</option>' in r

http://git-wip-us.apache.org/repos/asf/allura/blob/d72156ae/ForgeTracker/forgetracker/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/functional/test_root.py b/ForgeTracker/forgetracker/tests/functional/test_root.py
index 73ef421..8a1d8c4 100644
--- a/ForgeTracker/forgetracker/tests/functional/test_root.py
+++ b/ForgeTracker/forgetracker/tests/functional/test_root.py
@@ -736,7 +736,7 @@ class TestFunctionalController(TrackerTestController):
         # Make sure the 'Create Ticket' button is disabled for user without 'create' perm
         r = self.app.get('/bugs/', extra_environ=dict(username='*anonymous'))
         create_button = r.html.find('a', attrs={'href': u'/p/test/bugs/new/'})
-        assert_equal(create_button['class'], 'sidebar-disabled')
+        assert_equal(create_button['class'], 'icon fa fa-plus-circle sidebar-disabled')
 
     def test_render_markdown_syntax(self):
         r = self.app.get('/bugs/markdown_syntax')
@@ -853,7 +853,7 @@ class TestFunctionalController(TrackerTestController):
         assert file_name in ticket_editor, ticket_editor.showbrowser()
         req = self.app.get('/bugs/1/')
         form = self._find_update_ticket_form(req)
-        file_link = BeautifulSoup(form.text).findAll('a')[1]
+        file_link = BeautifulSoup(form.text).findAll('a')[2]
         assert_equal(file_link.string, file_name)
         self.app.post(str(file_link['href']), {
             'delete': 'True'
@@ -896,7 +896,7 @@ class TestFunctionalController(TrackerTestController):
             'summary': 'zzz'
         }, upload_files=[upload]).follow()
         form = self._find_update_ticket_form(ticket_editor)
-        download = self.app.get(str(BeautifulSoup(form.text).findAll('a')[1]['href']))
+        download = self.app.get(str(BeautifulSoup(form.text).findAll('a')[2]['href']))
         assert_equal(download.body, file_data)
 
     def test_two_attachments(self):
@@ -1986,8 +1986,8 @@ class TestFunctionalController(TrackerTestController):
                             extra_environ=dict(username='*anonymous'))
         ticket_url = r.headers['Location']
         r = self.app.get(ticket_url, extra_environ=dict(username='*anonymous'))
-        a = r.html.find('a', {'class': 'edit_ticket'})
-        assert a.text == 'Edit'
+        a = r.html.find('a', {'class': 'icon fa fa-edit edit_ticket'})
+        assert_equal(a.text, '&nbsp;Edit')
 
     def test_ticket_creator_cant_edit_private_ticket_without_update_perm(self):
         p = M.Project.query.get(shortname='test')

http://git-wip-us.apache.org/repos/asf/allura/blob/d72156ae/ForgeWiki/forgewiki/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/tests/functional/test_root.py b/ForgeWiki/forgewiki/tests/functional/test_root.py
index 635e2b6..eee2432 100644
--- a/ForgeWiki/forgewiki/tests/functional/test_root.py
+++ b/ForgeWiki/forgewiki/tests/functional/test_root.py
@@ -136,7 +136,7 @@ class TestRootController(TestController):
 
     def test_search_help(self):
         r = self.app.get('/wiki/search?q=test')
-        btn = r.html.find('a', attrs={'class': 'btn search_help_modal'})
+        btn = r.html.find('a', attrs={'class': 'icon fa fa-question-circle btn search_help_modal'})
         assert btn is not None, "Can't find a help button"
         div = r.html.find('div', attrs={'id': 'lightbox_search_help_modal'})
         assert div is not None, "Can't find help text"


[34/50] [abbrv] allura git commit: [#7984] force location of user subscriptions form elements

Posted by je...@apache.org.
[#7984] force location of user subscriptions form elements


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/151c63b6
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/151c63b6
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/151c63b6

Branch: refs/heads/ib/7924
Commit: 151c63b630a7373669cbd20ea8f8b37d7fed0439
Parents: 00110b1
Author: Dave Brondsema <da...@brondsema.net>
Authored: Mon Oct 12 10:27:55 2015 -0400
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Tue Oct 13 16:19:05 2015 -0400

----------------------------------------------------------------------
 Allura/allura/lib/widgets/subscriptions.py      | 24 +++++---
 .../templates/widgets/user_subs_form.html       | 61 ++++++++++++++++++++
 2 files changed, 76 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/151c63b6/Allura/allura/lib/widgets/subscriptions.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/subscriptions.py b/Allura/allura/lib/widgets/subscriptions.py
index 4e3324a..5d1ebea 100644
--- a/Allura/allura/lib/widgets/subscriptions.py
+++ b/Allura/allura/lib/widgets/subscriptions.py
@@ -58,17 +58,23 @@ class _SubscriptionTable(ew.TableField):
 class SubscriptionForm(CsrfForm):
     defaults = dict(
         ew.SimpleForm.defaults,
+        id='user-subs-form',
         submit_text='Save')
 
-    class fields(ew_core.NameList):
-        subscriptions = _SubscriptionTable()
-        email_format = ew.SingleSelectField(
-            name='email_format',
-            label='Email Format',
-            options=[
-                ew.Option(py_value='plain', label='Plain Text'),
-                ew.Option(py_value='html', label='HTML'),
-                ew.Option(py_value='both', label='Combined')])
+    template = 'jinja:allura:templates/widgets/user_subs_form.html'
+
+    @property
+    def fields(self):
+        return [
+            _SubscriptionTable(name='subscriptions'),
+            ew.SingleSelectField(
+                name='email_format',
+                show_label=False,
+                options=[
+                    ew.Option(py_value='plain', label='Plain Text'),
+                    ew.Option(py_value='html', label='HTML'),
+                    ew.Option(py_value='both', label='Combined')]),
+        ]
 
 
 class SubscribeForm(ew.SimpleForm):

http://git-wip-us.apache.org/repos/asf/allura/blob/151c63b6/Allura/allura/templates/widgets/user_subs_form.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/user_subs_form.html b/Allura/allura/templates/widgets/user_subs_form.html
new file mode 100644
index 0000000..39aecbc
--- /dev/null
+++ b/Allura/allura/templates/widgets/user_subs_form.html
@@ -0,0 +1,61 @@
+{#-
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+-#}
+
+<form {{widget.j2_attrs(dict(
+      name=rendered_name,
+      id=id,
+      method=method,
+      action=action,
+      enctype=enctype), attrs)}}>
+
+    {% set subs_table = widget.fields[0] %}
+    {{ subs_table.display(**widget.context_for(subs_table)) }}
+
+    {# use a table so it matches width and placement of big table above #}
+    <table class="user_subs_opts">
+    <tr><td>
+        <div class="user_sub_email_format">
+        Email Format:
+        {% set email_format = widget.fields[1] %}
+        {{ email_format.display(**widget.context_for(email_format)) }}
+        </div>
+        {% for hf in widget.hidden_fields %}
+            {{ hf.display(**widget.context_for(hf)) }}
+        {% endfor %}
+        {% for b in buttons %}
+            {{ b.display() }}
+        {% endfor %}
+    </td></tr>
+    </table>
+</form>
+
+<style type="text/css">
+    #user-subs-form table:first-child {
+        margin-bottom: 10px;
+    }
+    #user-subs-form table.user_subs_opts td {
+        border-bottom: none;
+    }
+    .user_sub_email_format {
+        float: left;
+    }
+    .user_subs_opts input[type=submit] {
+        float: right;
+    }
+</style>
\ No newline at end of file


[18/50] [abbrv] allura git commit: [#7976] add & use npm run cmds for build & watch; add license header

Posted by je...@apache.org.
[#7976] add & use npm run cmds for build & watch; add license header


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/d6a9114b
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/d6a9114b
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/d6a9114b

Branch: refs/heads/ib/7924
Commit: d6a9114b81ecc482e4216edcfd35f85eb5e397bb
Parents: 1dd7844
Author: Dave Brondsema <da...@brondsema.net>
Authored: Wed Sep 30 16:01:21 2015 -0400
Committer: Heith Seewald <hs...@hsmb.local>
Committed: Fri Oct 2 10:01:49 2015 -0400

----------------------------------------------------------------------
 Allura/docs/development/contributing.rst     |  2 +-
 Allura/docs/getting_started/installation.rst |  2 +-
 Brocfile.js                                  | 18 ++++++++++++++++++
 docker-compose.yml                           |  3 +--
 package.json                                 |  8 +++++---
 scripts/asf-release.sh                       |  2 +-
 6 files changed, 27 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/d6a9114b/Allura/docs/development/contributing.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/development/contributing.rst b/Allura/docs/development/contributing.rst
index e161fdb..73a9974 100644
--- a/Allura/docs/development/contributing.rst
+++ b/Allura/docs/development/contributing.rst
@@ -107,7 +107,7 @@ To transpile those files as soon as you edit them:
 
     ~$ npm install -g broccoli-timepiece
     ~$ cd ~/src/allura
-    ~$ broccoli-timepiece Allura/allura/public/nf/js/build/
+    ~$ npm run watch
 
 
 Finding Something to Work On

http://git-wip-us.apache.org/repos/asf/allura/blob/d6a9114b/Allura/docs/getting_started/installation.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/getting_started/installation.rst b/Allura/docs/getting_started/installation.rst
index b28fca3..026da99 100644
--- a/Allura/docs/getting_started/installation.rst
+++ b/Allura/docs/getting_started/installation.rst
@@ -191,7 +191,7 @@ If you're using a released version of Allura, these are already done for you.  T
     (env-allura)~$ cd ~/src/allura
     (env-allura)~$ npm install -g broccoli-cli
     (env-allura)~$ npm install
-    (env-allura)~$ broccoli build Allura/allura/public/nf/js/build/
+    (env-allura)~$ npm run build
 
 
 The application server

http://git-wip-us.apache.org/repos/asf/allura/blob/d6a9114b/Brocfile.js
----------------------------------------------------------------------
diff --git a/Brocfile.js b/Brocfile.js
index e16ee4c..93cab0b 100644
--- a/Brocfile.js
+++ b/Brocfile.js
@@ -1,3 +1,21 @@
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
 var babelTranspiler = require("broccoli-babel-transpiler");
 var sourceMap = require('broccoli-source-map');
 var concat = require('broccoli-concat');

http://git-wip-us.apache.org/repos/asf/allura/blob/d6a9114b/docker-compose.yml
----------------------------------------------------------------------
diff --git a/docker-compose.yml b/docker-compose.yml
index 86102ed..faac4a4 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -24,8 +24,7 @@ web:
     sh -c '
     if [ ! -e Allura/allura/public/nf/js/build/transpiled.js ]; then
       npm install &&
-      rm -rf Allura/allura/public/nf/js/build/ &&
-      broccoli build Allura/allura/public/nf/js/build/;
+      npm run build;
     fi;
     gunicorn --paste Allura/docker-dev.ini --reload
     '

http://git-wip-us.apache.org/repos/asf/allura/blob/d6a9114b/package.json
----------------------------------------------------------------------
diff --git a/package.json b/package.json
index 58dcc6b..95fa5ac 100644
--- a/package.json
+++ b/package.json
@@ -1,16 +1,18 @@
 {
   "name": "allura",
   "version": "0.0.0",
-  "description": "",
+  "description": "Apache Allura's JavaScript tooling",
   "main": "Brocfile.js",
   "scripts": {
-    "test": "echo \"Error: no test specified\" && exit 1"
+    "test": "echo \"Error: no test specified\" && exit 1",
+    "build": "rm -rf Allura/allura/public/nf/js/build/; broccoli build Allura/allura/public/nf/js/build/",
+    "watch": "broccoli-timepiece Allura/allura/public/nf/js/build/"
   },
   "repository": {
     "type": "git",
     "url": "https://git-wip-us.apache.org/repos/asf/allura.git"
   },
-  "author": "",
+  "author": "Apache Allura team",
   "license": "Apache-2.0",
   "devDependencies": {
     "broccoli": "^0.16.8",

http://git-wip-us.apache.org/repos/asf/allura/blob/d6a9114b/scripts/asf-release.sh
----------------------------------------------------------------------
diff --git a/scripts/asf-release.sh b/scripts/asf-release.sh
index 8ee73a4..cd1e347 100755
--- a/scripts/asf-release.sh
+++ b/scripts/asf-release.sh
@@ -74,7 +74,7 @@ cd $RELEASE_DIR
 tar xzf $RELEASE_FILE
 cd $RELEASE_FILE_EXTRACTED
 npm install >/dev/null
-BROCCOLI_ENV=production broccoli build Allura/allura/public/nf/js/build/
+BROCCOLI_ENV=production npm run build
 rm -rf node_modules
 cd ..
 tar czf $RELEASE_FILE $RELEASE_BASE


[20/50] [abbrv] allura git commit: [#7943] ticket:842 Rewrite tests

Posted by je...@apache.org.
[#7943] ticket:842 Rewrite tests


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/fc829503
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/fc829503
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/fc829503

Branch: refs/heads/ib/7924
Commit: fc82950385a94435677a2960ca5b4b1c0a95e768
Parents: dcec615
Author: Igor Bondarenko <je...@gmail.com>
Authored: Thu Oct 1 16:04:01 2015 +0000
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Fri Oct 2 10:06:07 2015 -0400

----------------------------------------------------------------------
 Allura/allura/tests/functional/test_discuss.py  | 85 +++++++++-----------
 .../forgetracker/tests/functional/test_rest.py  | 20 ++---
 2 files changed, 44 insertions(+), 61 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/fc829503/Allura/allura/tests/functional/test_discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_discuss.py b/Allura/allura/tests/functional/test_discuss.py
index 0063cb8..21b5d3b 100644
--- a/Allura/allura/tests/functional/test_discuss.py
+++ b/Allura/allura/tests/functional/test_discuss.py
@@ -17,48 +17,51 @@
 
 import os
 from mock import patch
-from nose.tools import assert_in, assert_not_in, assert_equal
+from nose.tools import assert_in, assert_not_in, assert_equal, assert_false, assert_true
 
 from ming.odm import session
 
 from allura.tests import TestController
 from allura import model as M
 
+class TestDiscussBase(TestController):
 
-class TestDiscuss(TestController):
+    def _thread_link(self):
+        home = self.app.get('/wiki/Home/')
+        new_post = home.html.find('div', {'id': 'new_post_holder'})
+        thread_link = new_post.find('form', {'id': 'edit_post'}).get('action')
+        return thread_link.rstrip('post')
+
+    def _thread_id(self):
+        home = self.app.get('/wiki/Home/')
+        new_post = home.html.find('div', {'id': 'new_post_holder'})
+        thread_link = new_post.find('form', {'id': 'edit_post'}).get('action')
+        return thread_link.split('/')[-2]
+
+
+class TestDiscuss(TestDiscussBase):
+
+    def _is_subscribed(self, username, thread_id):
+        user_id = str(M.User.by_username(username)._id)
+        thread = M.Thread.query.get(_id=thread_id)
+        return thread.subscriptions.get(user_id)
 
     def test_subscribe_unsubscribe(self):
-        home = self.app.get('/wiki/_discuss/')
-        subscribed = [i for i in home.html.findAll('input')
-                      if i.get('type') == 'checkbox'][0]
-        assert 'checked' not in subscribed.attrMap
-        link = [a for a in home.html.findAll('a')
-                if 'thread' in a['href']][0]
+        user = 'test-admin'
+        thread_id = self._thread_id()
+        assert_false(self._is_subscribed(user, thread_id))
+        link = self._thread_link()
         params = {
-            'threads-0._id': link['href'][len('/p/test/wiki/_discuss/thread/'):-1],
+            'threads-0._id': thread_id,
             'threads-0.subscription': 'on'}
-        r = self.app.post('/wiki/_discuss/subscribe',
-                          params=params,
-                          headers={'Referer': '/wiki/_discuss/'})
-        r = r.follow()
-        subscribed = [i for i in r.html.findAll('input')
-                      if i.get('type') == 'checkbox'][0]
-        assert 'checked' in subscribed.attrMap
-        params = {
-            'threads-0._id': link['href'][len('/p/test/wiki/_discuss/thread/'):-1]
-        }
-        r = self.app.post('/wiki/_discuss/subscribe',
-                          params=params,
-                          headers={'Referer': '/wiki/_discuss/'})
-        r = r.follow()
-        subscribed = [i for i in r.html.findAll('input')
-                      if i.get('type') == 'checkbox'][0]
-        assert 'checked' not in subscribed.attrMap
+        r = self.app.post('/wiki/_discuss/subscribe', params=params)
+        assert_true(self._is_subscribed(user, thread_id))
+        params = {'threads-0._id': thread_id}
+        r = self.app.post('/wiki/_discuss/subscribe', params=params)
+        assert_false(self._is_subscribed(user, thread_id))
 
     def _make_post(self, text):
-        home = self.app.get('/wiki/_discuss/')
-        thread_link = [a for a in home.html.findAll('a')
-                       if 'thread' in a['href']][0]['href']
+        thread_link = self._thread_link()
         thread = self.app.get(thread_link)
         for f in thread.html.findAll('form'):
             if f.get('action', '').endswith('/post'):
@@ -78,9 +81,7 @@ class TestDiscuss(TestController):
 
     @patch('allura.controllers.discuss.g.spam_checker.submit_spam')
     def test_post(self, submit_spam):
-        home = self.app.get('/wiki/_discuss/')
-        thread_link = [a for a in home.html.findAll('a')
-                       if 'thread' in a['href']][0]['href']
+        thread_link = self._thread_link()
         r = self._make_post('This is a post')
         assert 'This is a post' in r, r
         post_link = str(
@@ -124,9 +125,7 @@ class TestDiscuss(TestController):
             'This is a new post',), submit_spam.call_args[0]
 
     def test_permissions(self):
-        home = self.app.get('/wiki/_discuss/')
-        thread_url = [a for a in home.html.findAll('a')
-                      if 'thread' in a['href']][0]['href']
+        thread_url = self._thread_link()
         thread_id = thread_url.rstrip('/').split('/')[-1]
         thread = M.Thread.query.get(_id=thread_id)
 
@@ -154,8 +153,7 @@ class TestDiscuss(TestController):
     def test_spam_link(self):
         r = self._make_post('Test post')
         assert '<span>Spam</span>' in r
-        r = self.app.get('/wiki/_discuss/',
-                         extra_environ={'username': 'test-user-1'})
+        r = self.app.get('/wiki/Home/', extra_environ={'username': 'test-user-1'})
         assert '<span>Spam</span>' not in r, 'User without moderate perm must not see Spam link'
 
     @patch('allura.controllers.discuss.g.spam_checker.submit_spam')
@@ -195,9 +193,7 @@ class TestDiscuss(TestController):
         assert_in('Post needs moderation!', r)
 
     def test_post_paging(self):
-        home = self.app.get('/wiki/_discuss/')
-        thread_link = [a for a in home.html.findAll('a')
-                       if 'thread' in a['href']][0]['href']
+        thread_link = self._thread_link()
         # just make sure it doesn't 500
         self.app.get('%s?limit=50&page=0' % thread_link)
 
@@ -243,14 +239,11 @@ class TestDiscuss(TestController):
         r = self.app.get(post_link, status=404)
 
 
-class TestAttachment(TestController):
+class TestAttachment(TestDiscussBase):
 
     def setUp(self):
         super(TestAttachment, self).setUp()
-        home = self.app.get('/wiki/_discuss/')
-        self.thread_link = [a['href'].encode("utf-8")
-                            for a in home.html.findAll('a')
-                            if 'thread' in a['href']][0]
+        self.thread_link = self._thread_link()
         thread = self.app.get(self.thread_link)
         for f in thread.html.findAll('form'):
             if f.get('action', '').endswith('/post'):
@@ -264,7 +257,7 @@ class TestAttachment(TestController):
                     'value') and field['value'] or ''
         params[f.find('textarea')['name']] = 'Test Post'
         r = self.app.post(f['action'].encode('utf-8'), params=params,
-                          headers={'Referer': self.thread_link})
+                          headers={'Referer': self.thread_link.encode('utf-8')})
         r = r.follow()
         self.post_link = str(
             r.html.find('div', {'class': 'edit_post_form reply'}).find('form')['action'])

http://git-wip-us.apache.org/repos/asf/allura/blob/fc829503/ForgeTracker/forgetracker/tests/functional/test_rest.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/functional/test_rest.py b/ForgeTracker/forgetracker/tests/functional/test_rest.py
index 7d8d91a..d2f42bf 100644
--- a/ForgeTracker/forgetracker/tests/functional/test_rest.py
+++ b/ForgeTracker/forgetracker/tests/functional/test_rest.py
@@ -179,22 +179,13 @@ class TestRestDiscussion(TestTrackerApiBase):
         ticket_view = self.create_ticket()
         self.ticket_args = ticket_view.json['ticket']
 
-    def test_index(self):
-        r = self.api_get('/rest/p/test/bugs/_discuss/')
-        assert len(r.json['discussion']['threads']) == 1, r.json
-        for t in r.json['discussion']['threads']:
-            r = self.api_get('/rest/p/test/bugs/_discuss/thread/%s/' %
-                             t['_id'])
-            assert len(r.json['thread']['posts']) == 0, r.json
-
     def test_post(self):
-        discussion = self.api_get(
-            '/rest/p/test/bugs/_discuss/').json['discussion']
+        r = self.api_get('/rest/p/test/bugs/1/')
+        thread_id = r.json['ticket']['discussion_thread']['_id']
         post = self.api_post(
-            '/rest/p/test/bugs/_discuss/thread/%s/new' % discussion['threads'][0]['_id'],
+            '/rest/p/test/bugs/_discuss/thread/%s/new' % thread_id,
             text='This is a comment', wrap_args=None)
-        thread = self.api_get('/rest/p/test/bugs/_discuss/thread/%s/' %
-                              discussion['threads'][0]['_id'])
+        thread = self.api_get('/rest/p/test/bugs/_discuss/thread/%s/' % thread_id)
         assert len(thread.json['thread']['posts']) == 1, thread.json
         assert post.json['post']['text'] == 'This is a comment', post.json
         reply = self.api_post(
@@ -202,8 +193,7 @@ class TestRestDiscussion(TestTrackerApiBase):
                                                                ['_id'], post.json['post']['slug']),
             text='This is a reply', wrap_args=None)
         assert reply.json['post']['text'] == 'This is a reply', reply.json
-        thread = self.api_get('/rest/p/test/bugs/_discuss/thread/%s/' %
-                              discussion['threads'][0]['_id'])
+        thread = self.api_get('/rest/p/test/bugs/_discuss/thread/%s/' % thread_id)
         assert len(thread.json['thread']['posts']) == 2, thread.json
 
 


[19/50] [abbrv] allura git commit: [#7943] remove unused widget references

Posted by je...@apache.org.
[#7943] remove unused widget references


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/0b77e7e6
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/0b77e7e6
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/0b77e7e6

Branch: refs/heads/ib/7924
Commit: 0b77e7e6c053b76d32b2fc77718ee5ccad84ac23
Parents: fc82950
Author: Dave Brondsema <da...@brondsema.net>
Authored: Fri Oct 2 10:02:59 2015 -0400
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Fri Oct 2 10:06:07 2015 -0400

----------------------------------------------------------------------
 Allura/allura/controllers/discuss.py | 2 --
 1 file changed, 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/0b77e7e6/Allura/allura/controllers/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/discuss.py b/Allura/allura/controllers/discuss.py
index 36a9b97..459caf7 100644
--- a/Allura/allura/controllers/discuss.py
+++ b/Allura/allura/controllers/discuss.py
@@ -65,11 +65,9 @@ class WidgetConfig(object):
     post_filter = DW.PostFilter()
     moderate_posts = DW.ModeratePosts()
     # Other widgets
-    discussion = DW.Discussion()
     thread = DW.Thread()
     post = DW.Post()
     thread_header = DW.ThreadHeader()
-    discussion_header = DW.DiscussionHeader()
 
 # Controllers
 


[35/50] [abbrv] allura git commit: [#7984] remove unused columns

Posted by je...@apache.org.
[#7984] remove unused columns


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/68786d38
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/68786d38
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/68786d38

Branch: refs/heads/ib/7924
Commit: 68786d38cdf01b5138fbf30ee5ae65932733c88a
Parents: 151c63b
Author: Dave Brondsema <da...@brondsema.net>
Authored: Tue Oct 13 16:14:54 2015 -0400
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Tue Oct 13 16:19:05 2015 -0400

----------------------------------------------------------------------
 Allura/allura/lib/widgets/subscriptions.py | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/68786d38/Allura/allura/lib/widgets/subscriptions.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/subscriptions.py b/Allura/allura/lib/widgets/subscriptions.py
index 5d1ebea..db6c51d 100644
--- a/Allura/allura/lib/widgets/subscriptions.py
+++ b/Allura/allura/lib/widgets/subscriptions.py
@@ -42,13 +42,7 @@ class _SubscriptionTable(ew.TableField):
         project_name = ffw.DisplayOnlyField(
             label='Project', show_label=True, with_hidden_input=False)
         mount_point = ffw.DisplayOnlyField(
-            label='App', show_label=True, with_hidden_input=False)
-        topic = ffw.DisplayOnlyField(
-            label='Topic', show_label=True, with_hidden_input=False)
-        type = ffw.DisplayOnlyField(
-            label='Type', show_label=True, with_hidden_input=False)
-        frequency = ffw.DisplayOnlyField(
-            label='Frequency', show_label=True, with_hidden_input=False)
+            label='Tool', show_label=True, with_hidden_input=False)
         artifact_title = ew.LinkField(
             label='Artifact', show_label=True, plaintext_if_no_href=True)
         # unsubscribe = SubmitButton()


[04/50] [abbrv] allura git commit: [#7871] fix test failure (delete page before deleting its app)

Posted by je...@apache.org.
[#7871] fix test failure (delete page before deleting its app)


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/d2ebf892
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/d2ebf892
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/d2ebf892

Branch: refs/heads/ib/7924
Commit: d2ebf89259f7f1b1a29b670cd09b7002669a21e0
Parents: 4cc456f
Author: Dave Brondsema <da...@brondsema.net>
Authored: Wed Sep 23 17:46:02 2015 -0400
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Wed Sep 23 17:46:02 2015 -0400

----------------------------------------------------------------------
 Allura/allura/tests/model/test_artifact.py | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/d2ebf892/Allura/allura/tests/model/test_artifact.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/model/test_artifact.py b/Allura/allura/tests/model/test_artifact.py
index b6d6832..adbae4e 100644
--- a/Allura/allura/tests/model/test_artifact.py
+++ b/Allura/allura/tests/model/test_artifact.py
@@ -118,29 +118,28 @@ def test_artifact_index():
 @with_setup(setUp, tearDown)
 def test_artifactlink():
     pg = WM.Page(title='TestPage2')
-    q = M.Shortlink.query.find(dict(
+    q_shortlink = M.Shortlink.query.find(dict(
         project_id=c.project._id,
         app_config_id=c.app.config._id,
         link=pg.shorthand_id()))
-    assert q.count() == 0
+    assert q_shortlink.count() == 0
+
     ThreadLocalORMSession.flush_all()
     M.MonQTask.run_ready()
     ThreadLocalORMSession.flush_all()
-    assert q.count() == 1
+    assert q_shortlink.count() == 1
+
     assert M.Shortlink.lookup('[TestPage2]')
     assert M.Shortlink.lookup('[wiki:TestPage2]')
     assert M.Shortlink.lookup('[test:wiki:TestPage2]')
     assert not M.Shortlink.lookup('[test:wiki:TestPage2:foo]')
     assert not M.Shortlink.lookup('[Wiki:TestPage2]')
     assert not M.Shortlink.lookup('[TestPage2_no_such_page]')
+
+    pg.delete()
     c.project.uninstall_app('wiki')
-    ThreadLocalORMSession.flush_all()
     assert not M.Shortlink.lookup('[wiki:TestPage2]')
-    pg.delete()
-    ThreadLocalORMSession.flush_all()
-    M.MonQTask.run_ready()
-    ThreadLocalORMSession.flush_all()
-    assert q.count() == 0
+    assert q_shortlink.count() == 0
 
 
 @with_setup(setUp, tearDown)


[33/50] [abbrv] allura git commit: Merge remote-tracking branch 'dave/docker_npm_pwd'

Posted by je...@apache.org.
Merge remote-tracking branch 'dave/docker_npm_pwd'


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/00110b12
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/00110b12
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/00110b12

Branch: refs/heads/ib/7924
Commit: 00110b12ed58a44a95104d8579721bb6461bdada
Parents: 77c45da a1aab22
Author: Heith Seewald <hs...@hsmb.local>
Authored: Tue Oct 13 14:52:11 2015 -0400
Committer: Heith Seewald <hs...@hsmb.local>
Committed: Tue Oct 13 14:52:11 2015 -0400

----------------------------------------------------------------------
 Allura/allura/command/create_neighborhood.py   |  5 +++++
 Allura/docs/getting_started/administration.rst |  4 ++++
 Allura/docs/getting_started/installation.rst   | 20 +++++++++++++-------
 Dockerfile                                     | 13 +++++++++----
 docker-compose.yml                             |  8 ++++----
 5 files changed, 35 insertions(+), 15 deletions(-)
----------------------------------------------------------------------



[07/50] [abbrv] allura git commit: [#7995] move setup commands to start of docker section; easier to just copy and paste them

Posted by je...@apache.org.
[#7995] move setup commands to start of docker section; easier to just copy and paste them


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/f3bd36c6
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/f3bd36c6
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/f3bd36c6

Branch: refs/heads/ib/7924
Commit: f3bd36c6b3d818286c9a414a8e32d2f004c999c9
Parents: efc4642
Author: Dave Brondsema <da...@brondsema.net>
Authored: Thu Sep 24 13:10:43 2015 -0400
Committer: Heith Seewald <hs...@hsmb.local>
Committed: Fri Sep 25 16:07:28 2015 -0500

----------------------------------------------------------------------
 Allura/docs/getting_started/installation.rst | 109 +++++++++++-----------
 1 file changed, 55 insertions(+), 54 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/f3bd36c6/Allura/docs/getting_started/installation.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/getting_started/installation.rst b/Allura/docs/getting_started/installation.rst
index 029e21a..36df424 100644
--- a/Allura/docs/getting_started/installation.rst
+++ b/Allura/docs/getting_started/installation.rst
@@ -227,8 +227,52 @@ Extra
 Using Docker
 ------------
 
-General info
-^^^^^^^^^^^^
+First run
+^^^^^^^^^
+
+`Download the latest release <http://www.apache.org/dyn/closer.cgi/allura/>`_ of Allura, or `clone from git <https://forge-allura.apache.org/p/allura/git/ci/master/tree/>`_ for the bleeding edge.
+
+Install `Docker <http://docs.docker.com/installation/>`_ and `Docker Compose <https://docs.docker.com/compose/install/>`_.
+
+Build/fetch all required images (run these in allura source directory):
+
+.. code-block:: bash
+
+    docker-compose build
+
+Install requirements:
+
+.. code-block:: bash
+
+    docker-compose run web pip install -r requirements.txt
+
+Install Allura packages:
+
+.. code-block:: bash
+
+    docker-compose run web ./rebuild-all.bash
+
+Initialize database with test data:
+
+.. code-block:: bash
+
+    docker-compose run web bash -c 'cd Allura && paster setup-app docker-dev.ini'
+
+.. note::
+
+   If you want to skip test data creation you can instead run: :code:`docker-compose run web bash -c 'cd Allura && ALLURA_TEST_DATA=False paster setup-app docker-dev.ini'`
+
+Start containers in the background:
+
+.. code-block:: bash
+
+    docker-compose up -d
+
+You're up and running!  Visit localhost:8080 or on a Mac or Windows, whatever IP address Docker Toolbox is using.  Then
+see our :ref:`post-setup-instructions` and read more below about the Docker environment for Allura.
+
+Containers
+^^^^^^^^^^
 
 Allura runs on the following docker containers:
 
@@ -268,49 +312,6 @@ Ports, exposed to host system
 - 8825 - incoming mail listener
 - 27017 - mongodb
 
-First run
-^^^^^^^^^
-
-`Download the latest release <http://www.apache.org/dyn/closer.cgi/allura/>`_ of Allura, or `clone from git <https://forge-allura.apache.org/p/allura/git/ci/master/tree/>`_ for the bleeding edge.
-
-Install `Docker <http://docs.docker.com/installation/>`_ and `Docker Compose <https://docs.docker.com/compose/install/>`_.
-
-Build/fetch all required images (run these in allura source directory):
-
-.. code-block:: bash
-
-    ~$ docker-compose build
-
-Install requirements:
-
-.. code-block:: bash
-
-    ~$ docker-compose run web pip install -r requirements.txt
-
-Install Allura packages:
-
-.. code-block:: bash
-
-    ~$ docker-compose run web ./rebuild-all.bash
-
-Initialize database with test data:
-
-.. code-block:: bash
-
-    ~$ docker-compose run web bash -c 'cd Allura && paster setup-app docker-dev.ini'
-
-If you want to skip test data creation you can instead run:
-
-.. code-block:: bash
-
-    ~$ docker-compose run web bash -c 'cd Allura && ALLURA_TEST_DATA=False paster setup-app docker-dev.ini'
-
-Start containers in the background:
-
-.. code-block:: bash
-
-    ~$ docker-compose up -d
-
 Useful commands
 ^^^^^^^^^^^^^^^
 
@@ -318,48 +319,48 @@ Restarting all containers:
 
 .. code-block:: bash
 
-    ~$ docker-compose up -d
+    docker-compose up -d
 
 View logs from all services:
 
 .. code-block:: bash
 
-    ~$ docker-compose logs
+    docker-compose logs
 
 You can specify one or more services to view logs only from them, e.g. to see
 outgoing mail:
 
 .. code-block:: bash
 
-    ~$ docker-compose logs outmail
+    docker-compose logs outmail
 
 Update requirements and reinstall apps:
 
 .. code-block:: bash
 
-    ~$ docker-compose run web pip install -r requirements.txt
-    ~$ docker-compose run web ./rebuild-all.bash
+    docker-compose run web pip install -r requirements.txt
+    docker-compose run web ./rebuild-all.bash
 
 You may want to restart at least "taskd" container after that in order for it to
-pick up changes.
+pick up changes.  Run :code:`docker-compose restart taskd`
 
 Running all tests:
 
 .. code-block:: bash
 
-    ~$ docker-compose run web ./run_tests
+    docker-compose run web ./run_tests
 
 Running subset of tests:
 
 .. code-block:: bash
 
-    ~$ docker-compose run web bash -c 'cd ForgeGit && nosetests forgegit.tests.functional.test_controllers:TestFork'
+    docker-compose run web bash -c 'cd ForgeGit && nosetests forgegit.tests.functional.test_controllers:TestFork'
 
 Connecting to mongo using a container:
 
 .. code-block:: bash
 
-    ~$ docker-compose run mongo mongo --host mongo
+    docker-compose run mongo mongo --host mongo
 
 
 .. _post-setup-instructions:


[26/50] [abbrv] allura git commit: [#7991] Add sparse index for phone_verification.number_hash

Posted by je...@apache.org.
[#7991] Add sparse index for phone_verification.number_hash


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/c8300e12
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/c8300e12
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/c8300e12

Branch: refs/heads/ib/7924
Commit: c8300e128dd3b6c936ce9dacbe88da10b04c05d6
Parents: 0323078
Author: Dave Brondsema <da...@brondsema.net>
Authored: Mon Oct 5 12:05:40 2015 -0400
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Mon Oct 5 15:38:26 2015 -0400

----------------------------------------------------------------------
 Allura/allura/command/show_models.py | 10 ++++------
 Allura/allura/model/auth.py          |  3 +++
 Allura/allura/tests/test_commands.py | 13 ++++++++-----
 3 files changed, 15 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/c8300e12/Allura/allura/command/show_models.py
----------------------------------------------------------------------
diff --git a/Allura/allura/command/show_models.py b/Allura/allura/command/show_models.py
index 89a2a88..d651383 100644
--- a/Allura/allura/command/show_models.py
+++ b/Allura/allura/command/show_models.py
@@ -282,24 +282,22 @@ class EnsureIndexCommand(base.Command):
             base.log.info('...... ensure %s:%s', collection.name, idx)
             while True:
                 try:
-                    collection.ensure_index(idx.index_spec, unique=True)
+                    collection.ensure_index(idx.index_spec, **idx.index_options)
                     break
                 except DuplicateKeyError, err:
                     base.log.info('Found dupe key(%s), eliminating dupes', err)
                     self._remove_dupes(collection, idx.index_spec)
         for keys, idx in indexes.iteritems():
             base.log.info('...... ensure %s:%s', collection.name, idx)
-            collection.ensure_index(idx.index_spec, background=True)
+            collection.ensure_index(idx.index_spec, background=True, **idx.index_options)
         # Drop obsolete indexes
         for iname, keys in prev_indexes.iteritems():
             if keys not in indexes:
-                base.log.info('...... drop index %s:%s',
-                              collection.name, iname)
+                base.log.info('...... drop index %s:%s', collection.name, iname)
                 collection.drop_index(iname)
         for iname, keys in prev_uindexes.iteritems():
             if keys not in uindexes:
-                base.log.info('...... drop index %s:%s',
-                              collection.name, iname)
+                base.log.info('...... drop index %s:%s', collection.name, iname)
                 collection.drop_index(iname)
 
     def _recreate_index(self, collection, iname, keys, **creation_options):

http://git-wip-us.apache.org/repos/asf/allura/blob/c8300e12/Allura/allura/model/auth.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/auth.py b/Allura/allura/model/auth.py
index 163d5de..955c952 100644
--- a/Allura/allura/model/auth.py
+++ b/Allura/allura/model/auth.py
@@ -272,6 +272,9 @@ class User(MappedClass, ActivityNode, ActivityObject, SearchIndexable):
         session = main_orm_session
         indexes = ['tool_data.sfx.userid', 'tool_data.AuthPasswordReset.hash']
         unique_indexes = ['username']
+        custom_indexes = [
+            dict(fields=('tool_data.phone_verification.number_hash',), sparse=True),
+        ]
 
     type_s = 'User'
 

http://git-wip-us.apache.org/repos/asf/allura/blob/c8300e12/Allura/allura/tests/test_commands.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_commands.py b/Allura/allura/tests/test_commands.py
index f6800b7..fb5fb03 100644
--- a/Allura/allura/tests/test_commands.py
+++ b/Allura/allura/tests/test_commands.py
@@ -187,7 +187,8 @@ class TestEnsureIndexCommand(object):
             '_foo_bar': {'key': [('foo', 1), ('bar', 1)]},
         }
         indexes = [
-            Mock(unique=False, index_spec=[('foo', 1)]),
+            Mock(unique=False, index_spec=[('foo', 1)],
+                 index_options={'unique': False, 'sparse': False}),
         ]
         cmd = show_models.EnsureIndexCommand('ensure_index')
         cmd._update_indexes(collection, indexes)
@@ -216,8 +217,10 @@ class TestEnsureIndexCommand(object):
             '_foo_baz': {'key': [('foo', 1), ('baz', 1)]},
         }
         indexes = [
-            Mock(index_spec=[('foo', 1), ('bar', 1)], unique=False, ),
-            Mock(index_spec=[('foo', 1), ('baz', 1)], unique=True, ),
+            Mock(index_spec=[('foo', 1), ('bar', 1)], unique=False,
+                 index_options={'unique': False, 'sparse': False}),
+            Mock(index_spec=[('foo', 1), ('baz', 1)], unique=True,
+                 index_options={'unique': True, 'sparse': False}),
         ]
 
         cmd = show_models.EnsureIndexCommand('ensure_index')
@@ -235,8 +238,8 @@ class TestEnsureIndexCommand(object):
             call.drop_index('_foo_baz'),
             call.ensure_index([('foo', 1), ('baz', 1)], unique=True),
             call.drop_index('_foo_baz_temporary_extra_field_for_indexing'),
-            call.ensure_index([('foo', 1), ('baz', 1)], unique=True),
-            call.ensure_index([('foo', 1), ('bar', 1)], background=True)
+            call.ensure_index([('foo', 1), ('baz', 1)], unique=True, sparse=False),
+            call.ensure_index([('foo', 1), ('bar', 1)], unique=False, sparse=False, background=True)
         ])
 
 


[45/50] [abbrv] allura git commit: [#7924] ticket:836 Update another bunch of icons

Posted by je...@apache.org.
[#7924] ticket:836 Update another bunch of icons


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/dcc208e6
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/dcc208e6
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/dcc208e6

Branch: refs/heads/ib/7924
Commit: dcc208e64f01cec9808bf6caa33c8786b022e264
Parents: dc1a8a5
Author: Igor Bondarenko <je...@gmail.com>
Authored: Thu Aug 13 15:48:41 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Thu Oct 15 15:08:32 2015 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/project.py            |  2 +-
 Allura/allura/ext/admin/admin_main.py           |  2 +-
 .../templates/admin_widgets/card_field.html     |  9 ++-------
 .../ext/admin/templates/project_groups.html     | 15 +++------------
 .../templates/sections/projects.html            |  3 +--
 Allura/allura/lib/app_globals.py                | 20 ++++++++------------
 Allura/allura/nf/allura/css/allura.css          |  5 +++++
 Allura/allura/public/nf/css/forge/deck.css      |  2 +-
 Allura/allura/templates/jinja_master/lib.html   | 10 ++++++++--
 .../forgeactivity/templates/macros.html         |  5 ++++-
 .../forgeactivity/templates/widgets/follow.html | 13 ++++++++-----
 .../forgeshorturl/templates/index.html          |  2 +-
 ForgeTracker/forgetracker/tracker_main.py       |  4 ++--
 ForgeWiki/forgewiki/wiki_main.py                |  2 +-
 14 files changed, 46 insertions(+), 48 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/dcc208e6/Allura/allura/controllers/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/project.py b/Allura/allura/controllers/project.py
index 20d9f63..695e18a 100644
--- a/Allura/allura/controllers/project.py
+++ b/Allura/allura/controllers/project.py
@@ -169,7 +169,7 @@ class NeighborhoodController(object):
         if h.has_access(self.neighborhood, 'register')() and (nb_max_projects is None or count < nb_max_projects):
             c.custom_sidebar_menu += [
                 SitemapEntry('Add a Project', self.neighborhood.url()
-                             + 'add_project', ui_icon=g.icons['plus']),
+                             + 'add_project', ui_icon=g.icons['add']),
                 SitemapEntry('')
             ]
         c.custom_sidebar_menu = c.custom_sidebar_menu + [

http://git-wip-us.apache.org/repos/asf/allura/blob/dcc208e6/Allura/allura/ext/admin/admin_main.py
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/admin/admin_main.py b/Allura/allura/ext/admin/admin_main.py
index 7affa3c..43cdf55 100644
--- a/Allura/allura/ext/admin/admin_main.py
+++ b/Allura/allura/ext/admin/admin_main.py
@@ -136,7 +136,7 @@ class AdminApp(Application):
 
         if c.project.is_nbhd_project:
             links.append(SitemapEntry('Add Project', c.project.url()
-                                      + 'add_project', ui_icon=g.icons['plus']))
+                                      + 'add_project', ui_icon=g.icons['add']))
             nbhd_admin_url = c.project.neighborhood.url() + '_admin/'
             links = links + [
                 SitemapEntry('Neighborhood'),

http://git-wip-us.apache.org/repos/asf/allura/blob/dcc208e6/Allura/allura/ext/admin/templates/admin_widgets/card_field.html
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/admin/templates/admin_widgets/card_field.html b/Allura/allura/ext/admin/templates/admin_widgets/card_field.html
index e731290..47475fd 100644
--- a/Allura/allura/ext/admin/templates/admin_widgets/card_field.html
+++ b/Allura/allura/ext/admin/templates/admin_widgets/card_field.html
@@ -28,10 +28,7 @@
            class="ico-r admin_modal {{g.icons.perm_tool.css}}"></small>
       </a>
       {% endif %}
-      <p style="padding-bottom: 0"><b
-            data-icon="{{g.icons[icon_name].char}}"
-            class="ico x48 {{g.icons[icon_name].css}}"></b>
-      </p>
+      <p style="padding-bottom: 0">{{ g.icons[icon_name].render(tag='b', style='font-size:24px;') }}</p>
       {% if desc %}
       <p>{{ desc }}</p>
       {% endif %}
@@ -61,9 +58,7 @@
     <li>
       <a href="#"  class="adder">
         Add
-        <small data-icon="{{g.icons['plus'].char}}"
-               class="ico-r {{g.icons['plus'].css}}"
-               title="Add a user"></small>
+        {{ g.icons['add'].render(title="Add a user", tag="small") }}
       </a>
     </li>
     <li>

http://git-wip-us.apache.org/repos/asf/allura/blob/dcc208e6/Allura/allura/ext/admin/templates/project_groups.html
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/admin/templates/project_groups.html b/Allura/allura/ext/admin/templates/project_groups.html
index 54f7c26..57d37e2 100644
--- a/Allura/allura/ext/admin/templates/project_groups.html
+++ b/Allura/allura/ext/admin/templates/project_groups.html
@@ -38,10 +38,7 @@
   </ul>
 {% endmacro %}
 {% macro group_icon(icon) %}
-<p style="padding-bottom: 0"><b
-  data-icon="{{g.icons[icon].char}}"
-  class="ico x48 {{g.icons[icon].css}}"></b>
-</p>
+<p style="padding-bottom: 0">{{ g.icons[icon].render(tag='b', style='font-size:24px;') }}</p>
 {% endmacro %}
 
 {% block content %}
@@ -87,9 +84,7 @@
             </form>
           </li>
           <li class="adder">
-            <b data-icon="{{g.icons['plus'].char}}"
-               class="ico {{g.icons['plus'].css}}"></b>
-            Add
+            {{ g.icons['add'].render(show_title=True) }}
           </li>
         </ul>
       </td>
@@ -108,11 +103,7 @@
     </tr>
     <tr>
       <td colspan="3" class="new_group">
-        <a href="new" class="admin_modal" title="Add Group">
-          <b data-icon="{{g.icons['plus'].char}}"
-             class="ico x48 {{g.icons['plus'].css}}"></b>
-          Add a new group
-        </a>
+        {{ g.icons['add'].render(href="new", title="Add a new Group", show_title=True, extra_css='admin_modal') }}
       </td>
     </tr>
   </tbody>

http://git-wip-us.apache.org/repos/asf/allura/blob/dcc208e6/Allura/allura/ext/user_profile/templates/sections/projects.html
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/user_profile/templates/sections/projects.html b/Allura/allura/ext/user_profile/templates/sections/projects.html
index 9e1c632..246024c 100644
--- a/Allura/allura/ext/user_profile/templates/sections/projects.html
+++ b/Allura/allura/ext/user_profile/templates/sections/projects.html
@@ -57,8 +57,7 @@
     {% if projects|length > 5 %}
     <div class="show-more-projects">
         <button onclick="$(this).hide().closest('.section-body').find('li.hidden').show()">
-            Show More
-            <b data-icon="{{g.icons['plus'].char}}" class="ico {{g.icons['plus'].css}}"></b>
+          {{ g.icons['add'].render(title='Show More', show_title=True, tag='b') }}
         </button>
     </div>
     {% endif %}

http://git-wip-us.apache.org/repos/asf/allura/blob/dcc208e6/Allura/allura/lib/app_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/app_globals.py b/Allura/allura/lib/app_globals.py
index 0e22348..528423a 100644
--- a/Allura/allura/lib/app_globals.py
+++ b/Allura/allura/lib/app_globals.py
@@ -247,16 +247,12 @@ class Globals(object):
             folder=Icon('fa fa-folder', 'Folder'),
             fork=Icon('fa fa-code-fork', 'Fork'),
             merge=Icon('fa fa-code-fork', 'Merge'),  # TODO: use something else here
-            plus=Icon('fa fa-plus-circle', 'Add'),
             conversation=Icon('fa fa-comments', 'Conversation'),
-            group=Icon('g', 'ico-group'),
-            user=Icon('U', 'ico-user'),
-            secure=Icon('(', 'ico-lock'),
-            unsecure=Icon(')', 'ico-unlock'),
-            star=Icon('S', 'ico-star'),
-            watch=Icon('E', 'ico-watch'),
-            expand=Icon('`', 'ico-expand'),
-            restore=Icon('J', 'ico-restore'),
+            group=Icon('fa fa-group', 'Group'),
+            user=Icon('fa fa-user', 'User'),
+            secure=Icon('fa fa-lock', 'Lock'),
+            unsecure=Icon('fa fa-unlock', 'Unlock'),
+            star=Icon('fa fa-star', 'Star'),
             # Permissions
             perm_read=Icon('E', 'ico-focus'),
             perm_update=Icon('0', 'ico-sync'),
@@ -597,7 +593,7 @@ class Icon(object):
         self.css = css
         self.title = title or u''
 
-    def render(self, show_title=False, extra_css=None, closing_tag=True, **kw):
+    def render(self, show_title=False, extra_css=None, closing_tag=True, tag='a', **kw):
         title = kw.get('title') or self.title
         attrs = {
             'href': '#',
@@ -609,6 +605,6 @@ class Icon(object):
         visible_title = u''
         if show_title:
             visible_title = u'<span>&nbsp;{}</span>'.format(Markup.escape(title))
-        closing_tag = u'</a>' if closing_tag else u''
-        icon = u'<a {}>{}{}'.format(attrs, visible_title, closing_tag)
+        closing_tag = u'</{}>'.format(tag) if closing_tag else u''
+        icon = u'<{} {}>{}{}'.format(tag, attrs, visible_title, closing_tag)
         return Markup(icon)

http://git-wip-us.apache.org/repos/asf/allura/blob/dcc208e6/Allura/allura/nf/allura/css/allura.css
----------------------------------------------------------------------
diff --git a/Allura/allura/nf/allura/css/allura.css b/Allura/allura/nf/allura/css/allura.css
index e47065c..83232df 100644
--- a/Allura/allura/nf/allura/css/allura.css
+++ b/Allura/allura/nf/allura/css/allura.css
@@ -113,3 +113,8 @@ tr.rev div.markdown_content p {
 #sidebar-admin-header h3 {
     padding-left: 2px;
 }
+
+#usergroup_admin td.group {
+  text-align: center;
+  line-height: 3em;
+}

http://git-wip-us.apache.org/repos/asf/allura/blob/dcc208e6/Allura/allura/public/nf/css/forge/deck.css
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/css/forge/deck.css b/Allura/allura/public/nf/css/forge/deck.css
index 35a6b37..7bc7486 100644
--- a/Allura/allura/public/nf/css/forge/deck.css
+++ b/Allura/allura/public/nf/css/forge/deck.css
@@ -76,7 +76,7 @@ ul.deck li small {
     position: absolute;
     right: 5px;
     text-align: center;
-    top: 4px;
+    top: 6px;
     width: 26px;
 }
 

http://git-wip-us.apache.org/repos/asf/allura/blob/dcc208e6/Allura/allura/templates/jinja_master/lib.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/jinja_master/lib.html b/Allura/allura/templates/jinja_master/lib.html
index 75acb9e..83ea02e 100644
--- a/Allura/allura/templates/jinja_master/lib.html
+++ b/Allura/allura/templates/jinja_master/lib.html
@@ -60,7 +60,10 @@
          title="{{display_name}}"
          class="emboss{% if size %} x{{size}}{% endif %}{% if className %} {{className}}{% endif %}">
   {% else %}
-    <b data-icon="{{g.icons['user'].char}}" class="ico emboss {{g.icons['user'].css}}{% if size %} x{{size}}{% endif %}{% if className %} {{className}}{% endif %}"></b>
+    {{ g.icons['user'].render(
+        tag='b',
+        style='font-size:{}px;'.format(size) if size else '',
+        extra_css='emboss {}'.format(className or '')) }}
   {% endif %}
 {%- endmacro %}
 
@@ -78,7 +81,10 @@
          title="{{title or email}}"
          class="emboss {% if size %} x{{size}}{% endif %}">
   {% else %}
-    <b data-icon="{{g.icons['user'].char}}" class="ico emboss {{g.icons['user'].css}}{% if size %} x{{size}}{% endif %}"></b>
+    {{ g.icons['user'].render(
+        tag='b',
+        style='font-size:{}px;'.format(size) if size else '',
+        extra_css='emboss') }}
   {% endif %}
 {%- endmacro %}
 

http://git-wip-us.apache.org/repos/asf/allura/blob/dcc208e6/ForgeActivity/forgeactivity/templates/macros.html
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/templates/macros.html b/ForgeActivity/forgeactivity/templates/macros.html
index f3bac05..86897d7 100644
--- a/ForgeActivity/forgeactivity/templates/macros.html
+++ b/ForgeActivity/forgeactivity/templates/macros.html
@@ -32,6 +32,9 @@
          title="{{ o.activity_name }}"
          class="emboss{% if size %} x{{size}}{% endif %}{% if className %} {{className}}{% endif %}">
   {% else %}
-    <b data-icon="{{g.icons['user'].char}}" class="ico emboss {{g.icons['user'].css}}{% if size %} x{{size}}{% endif %}{% if className %} {{className}}{% endif %}"></b>
+    {{ g.icons['user'].render(
+        tag='b',
+        style='font-size:{}px;'.format(size) if size else '',
+        extra_css='emboss {}'.format(className or '')) }}
   {% endif %}
 {%- endmacro %}

http://git-wip-us.apache.org/repos/asf/allura/blob/dcc208e6/ForgeActivity/forgeactivity/templates/widgets/follow.html
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/templates/widgets/follow.html b/ForgeActivity/forgeactivity/templates/widgets/follow.html
index 34387e2..8fd8ea8 100644
--- a/ForgeActivity/forgeactivity/templates/widgets/follow.html
+++ b/ForgeActivity/forgeactivity/templates/widgets/follow.html
@@ -17,8 +17,11 @@
        under the License.
 -#}
 {% import 'allura:templates/jinja_master/lib.html' as lib with context %}
-<a  href="{{action}}" data-following="{{following|lower}}" data-csrf="{{lib.csrf()}}"
-    class="artifact_follow{{ ' active' if following }}"
-    title="{{'Stop %sing' % action_label if following else action_label|capitalize}} {{thing}}"><b
-        data-icon="{{g.icons[icon].char}}" class="ico {{g.icons[icon].css}}"
-        title="{{'Stop %sing' % action_label if following else action_label|capitalize}} {{thing}}"></b></a>
+{{ g.icons[icon].render(
+    href=action,
+    extra_css='artifact_follow{}'.format(' active' if following else ''),
+    title='{} {}'.format(
+      'Stop {}ing'.format(action_label) if following else action_label.capitalize(),
+      thing),
+    **{'data-following': h.really_unicode(following).lower(),
+       'data-csrf': lib.csrf()}) }}

http://git-wip-us.apache.org/repos/asf/allura/blob/dcc208e6/ForgeShortUrl/forgeshorturl/templates/index.html
----------------------------------------------------------------------
diff --git a/ForgeShortUrl/forgeshorturl/templates/index.html b/ForgeShortUrl/forgeshorturl/templates/index.html
index 178345b..8f51bf1 100644
--- a/ForgeShortUrl/forgeshorturl/templates/index.html
+++ b/ForgeShortUrl/forgeshorturl/templates/index.html
@@ -23,7 +23,7 @@
 
 {% block actions %}
   {% if can_create %}
-  {{ g.icons['plus'].render(
+  {{ g.icons['add'].render(
       href='{}admin/{}/add/'.format(c.project.url(), c.app.config.options.mount_point),
       title="Add Short URL",
       extra_css="add-short-url") }}

http://git-wip-us.apache.org/repos/asf/allura/blob/dcc208e6/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index 202ef82..edd5555 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -346,14 +346,14 @@ class ForgeTrackerApp(Application):
         links = []
         if has_access(self, 'create')():
             links.append(SitemapEntry('Create Ticket',
-                                      self.config.url() + 'new/', ui_icon=g.icons['plus']))
+                                      self.config.url() + 'new/', ui_icon=g.icons['add']))
         else:
             extra_attrs = {"title": "To create a new ticket, you must be authorized by the project admin."}
             links.append(SitemapEntry('Create Ticket',
                                       self.config.url() + 'new/',
                                       extra_html_attrs=extra_attrs,
                                       className='sidebar-disabled',
-                                      ui_icon=g.icons['plus']))
+                                      ui_icon=g.icons['add']))
         if has_access(self, 'configure')():
             links.append(SitemapEntry('Edit Milestones', self.config.url()
                          + 'milestones', ui_icon=g.icons['table']))

http://git-wip-us.apache.org/repos/asf/allura/blob/dcc208e6/ForgeWiki/forgewiki/wiki_main.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index afdebec..cf37ac0 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -225,7 +225,7 @@ The wiki uses [Markdown](%s) syntax.
         links = []
         if has_create_access:
             links += [SitemapEntry('Create Page', create_page_url,
-                                   ui_icon=g.icons['plus'],
+                                   ui_icon=g.icons['add'],
                                    className=create_page_class)]
         if not admin_menu:
             links += [SitemapEntry(''),


[42/50] [abbrv] allura git commit: [#7924] ticket:830 Update another bunch of icons

Posted by je...@apache.org.
[#7924] ticket:830 Update another bunch of icons


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/dc1a8a59
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/dc1a8a59
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/dc1a8a59

Branch: refs/heads/ib/7924
Commit: dc1a8a59a075f0ebbb7e9948113e1e9c251b677b
Parents: aee6e44
Author: Igor Bondarenko <je...@gmail.com>
Authored: Tue Aug 11 19:01:29 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Thu Oct 15 15:07:30 2015 +0000

----------------------------------------------------------------------
 .../ext/user_profile/templates/user_index.html      | 10 ++++++----
 Allura/allura/lib/app_globals.py                    | 16 ++++++++--------
 Allura/allura/nf/allura/css/allura.css              | 11 +++++++++--
 .../allura/templates/app_admin_webhooks_list.html   | 11 +++++------
 Allura/allura/templates/repo/diff.html              |  2 +-
 Allura/allura/templates/repo/file.html              |  2 +-
 Allura/allura/templates/widgets/flag_post.html      |  2 +-
 Allura/allura/templates/widgets/lightbox.html       |  2 +-
 Allura/allura/templates/widgets/markdown_edit.html  |  2 +-
 Allura/allura/templates/widgets/post_widget.html    |  7 +++++--
 Allura/allura/templates/widgets/threads_table.html  |  4 ++--
 .../templates/tracker_widgets/ticket_form.html      |  2 +-
 .../forgewiki/templates/wiki/page_history.html      |  6 ++++--
 13 files changed, 45 insertions(+), 32 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/dc1a8a59/Allura/allura/ext/user_profile/templates/user_index.html
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/user_profile/templates/user_index.html b/Allura/allura/ext/user_profile/templates/user_index.html
index 19cf1c1..5232a5a 100644
--- a/Allura/allura/ext/user_profile/templates/user_index.html
+++ b/Allura/allura/ext/user_profile/templates/user_index.html
@@ -34,10 +34,12 @@
 
 {% block nav_menu %}
     {% if user != c.user %}
-    <a id="user-message" href="send_message" class="btn">
-        <b data-icon="{{g.icons['mail'].char}}" class="ico {{g.icons['mail'].css}}"></b>
-        <span>Send Message</span>
-    </a>
+    {{ g.icons['mail'].render(
+        title='Send Message',
+        show_title=True,
+        href='send_message',
+        extra_css='btn',
+        id='user-message') }}
     {% endif %}
     {{super()}}
 {% endblock %}

http://git-wip-us.apache.org/repos/asf/allura/blob/dc1a8a59/Allura/allura/lib/app_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/app_globals.py b/Allura/allura/lib/app_globals.py
index 850938e..0e22348 100644
--- a/Allura/allura/lib/app_globals.py
+++ b/Allura/allura/lib/app_globals.py
@@ -235,18 +235,18 @@ class Globals(object):
             history=Icon('fa fa-calendar', 'History'),
             feed=Icon('fa fa-rss', 'Feed'),
             mail=Icon('fa fa-envelope-o', 'Subscribe'),
-            reply=Icon('w', 'ico-reply'),
+            reply=Icon('fa fa-reply', 'Reply'),
             tag=Icon('fa fa-tag', 'Tag'),
-            flag=Icon('^', 'ico-flag'),
+            flag=Icon('fa fa-flag-o', 'Flag'),
             undelete=Icon('fa fa-undo', 'Undelete'),
             delete=Icon('fa fa-trash-o', 'Delete'),
-            close=Icon('D', 'ico-close'),
-            table=Icon('n', 'ico-table'),
+            close=Icon('fa fa-close', 'Close'),
+            table=Icon('fa fa-table', 'Table'),
             stats=Icon('fa fa-line-chart', 'Stats'),
-            pin=Icon('@', 'ico-pin'),
-            folder=Icon('o', 'ico-folder'),
-            fork=Icon('R', 'ico-fork'),
-            merge=Icon('J', 'ico-merge'),
+            pin=Icon('fa fa-mail-pin', 'Pin'),
+            folder=Icon('fa fa-folder', 'Folder'),
+            fork=Icon('fa fa-code-fork', 'Fork'),
+            merge=Icon('fa fa-code-fork', 'Merge'),  # TODO: use something else here
             plus=Icon('fa fa-plus-circle', 'Add'),
             conversation=Icon('fa fa-comments', 'Conversation'),
             group=Icon('g', 'ico-group'),

http://git-wip-us.apache.org/repos/asf/allura/blob/dc1a8a59/Allura/allura/nf/allura/css/allura.css
----------------------------------------------------------------------
diff --git a/Allura/allura/nf/allura/css/allura.css b/Allura/allura/nf/allura/css/allura.css
index 184ff58..e47065c 100644
--- a/Allura/allura/nf/allura/css/allura.css
+++ b/Allura/allura/nf/allura/css/allura.css
@@ -30,8 +30,15 @@ b.ico {
     background-repeat: no-repeat;
     vertical-align: middle;
 }
-a.fa { color: rgb(85, 85, 85); }
-a.fa:hover { text-decoration: none; }
+a.fa,
+a.fa:hover {
+  text-decoration: none;
+  color: rgb(85, 85, 85);
+}
+.modal .fa {
+  color: white;
+  float: right;
+}
 a.btn.fa { font-family: FontAwesome; }
 a.fa > span { font-family: sans-serif; }
 h2.dark b.ico, .modal b.ico {background-image: url('../images/neo-icon-set-ffffff-256x350.png');}

http://git-wip-us.apache.org/repos/asf/allura/blob/dc1a8a59/Allura/allura/templates/app_admin_webhooks_list.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/app_admin_webhooks_list.html b/Allura/allura/templates/app_admin_webhooks_list.html
index a4efb97..f61feec 100644
--- a/Allura/allura/templates/app_admin_webhooks_list.html
+++ b/Allura/allura/templates/app_admin_webhooks_list.html
@@ -33,12 +33,11 @@
           <td>{{ wh.secret or '' }}</td>
           <td><a href="{{wh.url()}}">Edit</a></td>
           <td>
-            <a href="{{admin_url}}/{{hook.type}}/delete"
-               class="delete-link"
-               data-id="{{h.really_unicode(wh._id)}}"
-               title="Delete">
-              <b data-icon="{{g.icons['delete'].char}}" class="ico {{g.icons['delete'].css}}" title="Delete"></b>
-            </a>
+            {{ g.icons['delete'].render(
+                href='{}/{}/delete'.format(admin_url, hook.type),
+                extra_css='delete-link',
+                show_title=True,
+                **{'data-id': h.really_unicode(wh._id)}) }}
           </td>
         </tr>
         {% endfor %}

http://git-wip-us.apache.org/repos/asf/allura/blob/dc1a8a59/Allura/allura/templates/repo/diff.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/repo/diff.html b/Allura/allura/templates/repo/diff.html
index 217e48f..aa2f742 100644
--- a/Allura/allura/templates/repo/diff.html
+++ b/Allura/allura/templates/repo/diff.html
@@ -53,7 +53,7 @@
   {% else %}
   <div class="clip grid-19 diffbrowser">
     <h3>
-      <span class="ico-l"><b data-icon="{{g.icons['table'].char}}" class="ico {{g.icons['table'].css}}"></b> {{h.really_unicode(a.filename) or h.html.literal('&nbsp;')}}</span>
+      {{ g.icons['table'].render(title=h.really_unicode(a.filename) or ' ', show_title=True) }}
       <span class="fright">
         {% if session.diformat == 'sidebyside' %}
           {% set switch_url = request.url.replace('&diformat=sidebyside', '') + '&diformat=regular' %}

http://git-wip-us.apache.org/repos/asf/allura/blob/dc1a8a59/Allura/allura/templates/repo/file.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/repo/file.html b/Allura/allura/templates/repo/file.html
index 7221557..cad455b 100644
--- a/Allura/allura/templates/repo/file.html
+++ b/Allura/allura/templates/repo/file.html
@@ -82,7 +82,7 @@
     <p><a href="?format=raw">Download this file</a></p>
     <div class="clip grid-19 codebrowser">
       <h3>
-        <span class="ico-l"><b data-icon="{{g.icons['table'].char}}" class="ico {{g.icons['table'].css}}"></b> {{h.really_unicode(blob.name)}}</span>
+        {{ g.icons['table'].render(title=h.really_unicode(blob.name), show_title=True) }}
         &nbsp;&nbsp;
         {{ stats.line_count }} lines ({{ stats.data_line_count }} with data), {{ stats.code_size|filesizeformat }}
       </h3>

http://git-wip-us.apache.org/repos/asf/allura/blob/dc1a8a59/Allura/allura/templates/widgets/flag_post.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/flag_post.html b/Allura/allura/templates/widgets/flag_post.html
index bb77fa6..64a7d6e 100644
--- a/Allura/allura/templates/widgets/flag_post.html
+++ b/Allura/allura/templates/widgets/flag_post.html
@@ -19,6 +19,6 @@
 {% import 'allura:templates/jinja_master/lib.html' as lib with context %}
 <form method="POST" action="{{action}}">
     <input type="hidden" name="delete" value="True"/>
-    <a href="" title="Flag as inappropriate or spam" class="flag_post ico-l"><b data-icon="{{g.icons['flag'].char}}" class="ico {{g.icons['flag'].css}}"></b> <span>Flag</span></a>
+    {{ g.icons['flag'].render(show_title=True, extra_css='flag_post') }}
     {{lib.csrf_token()}}
 </form>

http://git-wip-us.apache.org/repos/asf/allura/blob/dc1a8a59/Allura/allura/templates/widgets/lightbox.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/lightbox.html b/Allura/allura/templates/widgets/lightbox.html
index 4c5210d..8297226 100644
--- a/Allura/allura/templates/widgets/lightbox.html
+++ b/Allura/allura/templates/widgets/lightbox.html
@@ -17,7 +17,7 @@
        under the License.
 -#}
 <div id="lightbox_{{name}}" class="modal" style="display:none">
-  <b data-icon="{{g.icons['close'].char}}" class="ico {{g.icons['close'].css}} close"></b>
+  {{ g.icons['close'].render(extra_css='close') }}
   {% if content_template %}
     {% include content_template with context %}
   {% else %}

http://git-wip-us.apache.org/repos/asf/allura/blob/dc1a8a59/Allura/allura/templates/widgets/markdown_edit.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/markdown_edit.html b/Allura/allura/templates/widgets/markdown_edit.html
index 773ea09..8ed865d 100644
--- a/Allura/allura/templates/widgets/markdown_edit.html
+++ b/Allura/allura/templates/widgets/markdown_edit.html
@@ -20,7 +20,7 @@
 <div class="markdown_edit">
   <textarea id="{{id or rendered_name}}" name="{{rendered_name}}" class="{{widget.css_class}}" {{widget.j2_attrs(attrs)}}>{{value or ''}}</textarea>
   <div class="modal markdown_help" style="display:none">
-    <b data-icon="{{g.icons['close'].char}}" class="ico {{g.icons['close'].css}} close"></b>
+    {{ g.icons['close'].render(extra_css='close') }}
     <div class="markdown_help_contents" data-url="{{c.app.url}}markdown_syntax_dialog"></div>
   </div>
   <input type="hidden" class="markdown_project" value="{{c.project.shortname}}">

http://git-wip-us.apache.org/repos/asf/allura/blob/dc1a8a59/Allura/allura/templates/widgets/post_widget.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/post_widget.html b/Allura/allura/templates/widgets/post_widget.html
index a0e4545..7e22dbf 100644
--- a/Allura/allura/templates/widgets/post_widget.html
+++ b/Allura/allura/templates/widgets/post_widget.html
@@ -97,7 +97,10 @@
         </div>
         <div class="options grid-3">
         {% if h.has_access(value.thread, 'post')() %}
-          <a href="#" class="reply_post btn"{%if value.status == 'pending'%} style="display:none"{%endif%}><b data-icon="{{g.icons['reply'].char}}" class="ico {{g.icons['reply'].css}}"></b>Reply</a>
+          {{ g.icons['reply'].render(
+              show_title=True,
+              extra_css='reply_post btn',
+              style='display:none;' if value.status == 'pending' else '') }}
         {% endif %}
         <div style="clear:both">
             <div class="little_link">
@@ -115,7 +118,7 @@
         </div>
       </div>
       <div class="shortlink_popup modal" style="display: none">
-        <b data-icon="{{g.icons['close'].char}}" class="ico {{g.icons['close'].css}} close"></b>
+        {{ g.icons['close'].render(extra_css='close') }}
         If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
         <input type="text" style="width:100%" value="{{shortlink_url}}">
       </div>

http://git-wip-us.apache.org/repos/asf/allura/blob/dc1a8a59/Allura/allura/templates/widgets/threads_table.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/threads_table.html b/Allura/allura/templates/widgets/threads_table.html
index 301b93b..dd85892 100644
--- a/Allura/allura/templates/widgets/threads_table.html
+++ b/Allura/allura/templates/widgets/threads_table.html
@@ -40,7 +40,7 @@
         {% if not thread.first_post %}
         <td class="topic">
           {% if 'flags' in thread and 'Sticky' in thread.flags %}
-                <a href="{{thread.url()}}" class="btn"><b data-icon="{{g.icons['pin'].char}}" class="ico {{g.icons['pin'].css}}"></b> <span>Sticky</span></a>
+            {{ g.icons['pin'].render(href=thread.url(), extra_css='btn', title='Sticky', show_title=True) }}
           {% endif %}
           <h3><a href="{{thread.url()}}">{{thread.subject and h.text.truncate(thread.subject, 72) or '(no subject)'}}</a></h3>
         </td>
@@ -48,7 +48,7 @@
         <td class="topic">
           {% set author = thread.first_post.author() %}
           {% if 'flags' in thread and 'Sticky' in thread.flags %}
-            <a href="{{thread.url()}}" class="btn ico"><b data-icon="{{g.icons['pin'].char}}" class="ico {{g.icons['pin'].css}}"></b> <span>Sticky</span></a>
+            {{ g.icons['pin'].render(href=thread.url(), extra_css='btn', title='Sticky', show_title=True) }}
           {% endif %}
           <h3><a href="{{thread.url()}}">{{thread.subject and h.text.truncate(thread.subject, 72) or '(no subject)'}}</a></h3>
           <span>By {{lib.user_link(author)}}</span> on {{thread.first_post.timestamp.strftime('%a %b %d, %Y %I:%M %p')}}

http://git-wip-us.apache.org/repos/asf/allura/blob/dc1a8a59/ForgeTracker/forgetracker/templates/tracker_widgets/ticket_form.html
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/templates/tracker_widgets/ticket_form.html b/ForgeTracker/forgetracker/templates/tracker_widgets/ticket_form.html
index 25f82a1..67323a6 100644
--- a/ForgeTracker/forgetracker/templates/tracker_widgets/ticket_form.html
+++ b/ForgeTracker/forgetracker/templates/tracker_widgets/ticket_form.html
@@ -100,7 +100,7 @@
               </a>
             {% endif %}
             <a href="{{att.url()}}">{{att.filename}}</a>
-            <a href="{{att.url()}}" class="btn delete_attachment"><b data-icon="{{g.icons['delete'].char}}" class="ico {{g.icons['delete'].css}}"></b></a>
+            {{ g.icons['delete'].render(href=att.url(), extra_css='btn delete_attachment') }}
           </div>
       {% endfor %}
       </div>

http://git-wip-us.apache.org/repos/asf/allura/blob/dc1a8a59/ForgeWiki/forgewiki/templates/wiki/page_history.html
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/templates/wiki/page_history.html b/ForgeWiki/forgewiki/templates/wiki/page_history.html
index d191337..0de9ef9 100644
--- a/ForgeWiki/forgewiki/templates/wiki/page_history.html
+++ b/ForgeWiki/forgewiki/templates/wiki/page_history.html
@@ -52,8 +52,10 @@
           <td><input name="v2" type="radio" value="{{p.version}}"/></td>
           <td class="tright">
             {% if i != 0 and h.has_access(p, 'edit')() %}
-              <a class="post-link" data-dialog-id="{{p.version}}" href="#"><b data-icon="{{g.icons['fork'].char}}" class="ico {{g.icons['fork'].css}}" title="Revert to version {{p.version}}"></b></a>
-
+              {{ g.icons['fork'].render(
+                  extra_css='post-link',
+                  title='Revert to version {}'.format(p.version),
+                  **{'data-dialog-id': p.version}) }}
               <div class="confirmation_dialog_{{p.version}}" style="display:none">
                 <b class="ico ico-close close" data-icon="D"></b>
                 <h1>Confirm revert to version {{p.version}}</h1>


[15/50] [abbrv] allura git commit: [#7976] no caching of resources during development - particularly needed since Chrome caches sourcemaps even if dev tools has caching off

Posted by je...@apache.org.
[#7976] no caching of resources during development - particularly needed since Chrome caches sourcemaps even if dev tools has caching off


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/34e5195c
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/34e5195c
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/34e5195c

Branch: refs/heads/ib/7924
Commit: 34e5195c9c6bb3c502b7c439354cb2742146ad87
Parents: 79b2b98
Author: Dave Brondsema <da...@brondsema.net>
Authored: Mon Sep 28 13:48:49 2015 -0400
Committer: Heith Seewald <hs...@hsmb.local>
Committed: Fri Oct 2 10:01:48 2015 -0400

----------------------------------------------------------------------
 Allura/allura/config/middleware.py | 4 +++-
 Allura/development.ini             | 4 ++++
 2 files changed, 7 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/34e5195c/Allura/allura/config/middleware.py
----------------------------------------------------------------------
diff --git a/Allura/allura/config/middleware.py b/Allura/allura/config/middleware.py
index 6c39d4b..5ce50a3 100644
--- a/Allura/allura/config/middleware.py
+++ b/Allura/allura/config/middleware.py
@@ -158,7 +158,9 @@ def _make_core_app(root, global_conf, full_stack=True, **app_conf):
         # compress=True,
         script_name=app_conf.get('ew.script_name', '/_ew_resources/'),
         url_base=app_conf.get('ew.url_base', '/_ew_resources/'),
-        extra_headers=eval(app_conf.get('ew.extra_headers', 'None')))
+        extra_headers=eval(app_conf.get('ew.extra_headers', 'None')),
+        cache_max_age=asint(app_conf.get('ew.cache_header_seconds', 60*60*24*365)),
+    )
     # Handle static files (by tool)
     app = StaticFilesMiddleware(app, app_conf.get('static.script_name'))
     # Handle setup and flushing of Ming ORM sessions

http://git-wip-us.apache.org/repos/asf/allura/blob/34e5195c/Allura/development.ini
----------------------------------------------------------------------
diff --git a/Allura/development.ini b/Allura/development.ini
index aee8bca..4c540d5 100644
--- a/Allura/development.ini
+++ b/Allura/development.ini
@@ -260,7 +260,11 @@ static.url_base = /nf/%(build_key)s/_static_/
 ; Expires header for "static" resources served through allura (e.g. icons, attachments, /nf/tool_icon_css)
 files_expires_header_secs = 1209600 ; 2 weeks
 
+; EasyWidgets settings
+; This CORS header is necessary if serving webfonts via a different domain
 ew.extra_headers = [ ('Access-Control-Allow-Origin', '*') ]
+; In production, comment this out and it will default to 1 year.  Update build_key whenever you deploy new code, instead.
+ew.cache_header_seconds = 0
 
 ; If your environment (e.g. behind a server-side proxy) needs to look at an http header to get the actual remote addr
 ;ip_address_header = X-Forwarded-For


[24/50] [abbrv] allura git commit: Docker & doc fixes for node, pwd, etc

Posted by je...@apache.org.
Docker & doc fixes for node, pwd, etc

Revert changes to WORKDIR in Allura/Dockerfile from recent broccoli/jsx setup
commits.  Its needed to have the 'web' container start in the root folder, so
`pip` command etc works.

Update docs to take advantage of the 'taskd' container starting in Allura
subdir so paster commands can run without "bash -c 'cd ...'" stuff.

Use newest version of node/npm to avoid symlink errors when installing
npm packages within a VM shared mount.

Add instructions for running administrative commands within docker.  Add
success logging at end of create-neighborhood so that some thread widget
errors don't make people think that command failed.


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/a1aab220
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/a1aab220
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/a1aab220

Branch: refs/heads/ib/7924
Commit: a1aab2208a37d3a32ed6639650eedcd5325dccaf
Parents: 0323078
Author: Dave Brondsema <da...@brondsema.net>
Authored: Mon Oct 5 13:38:39 2015 -0400
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Mon Oct 5 13:38:39 2015 -0400

----------------------------------------------------------------------
 Allura/allura/command/create_neighborhood.py   |  5 +++++
 Allura/docs/getting_started/administration.rst |  4 ++++
 Allura/docs/getting_started/installation.rst   | 20 +++++++++++++-------
 Dockerfile                                     | 13 +++++++++----
 docker-compose.yml                             |  8 ++++----
 5 files changed, 35 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/a1aab220/Allura/allura/command/create_neighborhood.py
----------------------------------------------------------------------
diff --git a/Allura/allura/command/create_neighborhood.py b/Allura/allura/command/create_neighborhood.py
index db79bb0..d099c46 100644
--- a/Allura/allura/command/create_neighborhood.py
+++ b/Allura/allura/command/create_neighborhood.py
@@ -15,6 +15,8 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
+import logging
+
 from . import base
 
 from ming.orm import session
@@ -23,6 +25,8 @@ from bson import ObjectId
 from allura import model as M
 from allura.lib import plugin, exceptions
 
+log = logging.getLogger(__name__)
+
 
 class CreateNeighborhoodCommand(base.Command):
     min_args = 3
@@ -44,6 +48,7 @@ class CreateNeighborhoodCommand(base.Command):
                           google_analytics=False))
         project_reg = plugin.ProjectRegistrationProvider.get()
         project_reg.register_neighborhood_project(n, admins)
+        log.info('Successfully created neighborhood "{}"'.format(shortname))
 
 
 class UpdateNeighborhoodCommand(base.Command):

http://git-wip-us.apache.org/repos/asf/allura/blob/a1aab220/Allura/docs/getting_started/administration.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/getting_started/administration.rst b/Allura/docs/getting_started/administration.rst
index 1571cb6..8673840 100644
--- a/Allura/docs/getting_started/administration.rst
+++ b/Allura/docs/getting_started/administration.rst
@@ -76,6 +76,10 @@ Scripts are in the `scripts/` directory and run slightly differently, via `paste
 
      paster script development.ini ../scripts/create-allura-sitemap.py -- -u 100
 
+To run these when using docker, prefix with :code:`docker-compose run web` and use :code:`docker-dev.ini` like::
+
+    docker-compose run taskd paster create-neighborhood docker-dev.ini myneighborhood myuser ...
+
 Tasks can be run via the web interface at http://MYSITE/nf/admin/task_manager  You must know
 the full task name, e.g. :code:`allura.tasks.admin_tasks.install_app`  You can
 optionally provide a username and project and app which will get set on the

http://git-wip-us.apache.org/repos/asf/allura/blob/a1aab220/Allura/docs/getting_started/installation.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/getting_started/installation.rst b/Allura/docs/getting_started/installation.rst
index 026da99..e180ac3 100644
--- a/Allura/docs/getting_started/installation.rst
+++ b/Allura/docs/getting_started/installation.rst
@@ -182,12 +182,12 @@ Allura uses a background task service called "taskd" to do async tasks like send
 A few more steps, if using git
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-If you're using a released version of Allura, these are already done for you.  This transpiles JS into a version all browsers support:
+If you're using a released version of Allura, these are already done for you.  This transpiles JS into a version all browsers support.
+For non-Ubuntu installations see https://nodejs.org/en/download/package-manager/ for other options to replace the first line here:
 
 .. code-block:: bash
 
-    (env-allura)~$ sudo aptitude install nodejs npm
-    (env-allura)~$ sudo ln -s /usr/bin/nodejs /usr/bin/node
+    (env-allura)~$ curl --silent --location https://deb.nodesource.com/setup_4.x | sudo bash -
     (env-allura)~$ cd ~/src/allura
     (env-allura)~$ npm install -g broccoli-cli
     (env-allura)~$ npm install
@@ -256,7 +256,7 @@ Build/fetch all required images (run these in allura source directory):
 
     docker-compose build
 
-Install requirements:
+Install requirements (and first containers started):
 
 .. code-block:: bash
 
@@ -272,11 +272,11 @@ Initialize database with test data:
 
 .. code-block:: bash
 
-    docker-compose run web bash -c 'cd Allura && paster setup-app docker-dev.ini'
+    docker-compose run taskd paster setup-app docker-dev.ini
 
 .. note::
 
-   If you want to skip test data creation you can instead run: :code:`docker-compose run web bash -c 'cd Allura && ALLURA_TEST_DATA=False paster setup-app docker-dev.ini'`
+   If you want to skip test data creation you can instead run: :code:`docker-compose run -e ALLURA_TEST_DATA=False taskd paster setup-app docker-dev.ini`
 
 Start containers in the background:
 
@@ -284,9 +284,15 @@ Start containers in the background:
 
     docker-compose up -d
 
-You're up and running!  Visit localhost:8080 or on a Mac or Windows, whatever IP address Docker Toolbox is using.  Then
+You're up and running!  Visit localhost:8080, or on a Mac or Windows whatever IP address Docker Toolbox is using.  Then
 see our :ref:`post-setup-instructions` and read more below about the Docker environment for Allura.
 
+.. note::
+
+   If running from git source, it will take a few minutes during the first time running "up", to set up JS build tools
+   before the webapp is actually running on port 8080.  Watch the progress with :code:`docker-compose logs web`.
+
+
 Containers
 ^^^^^^^^^^
 

http://git-wip-us.apache.org/repos/asf/allura/blob/a1aab220/Dockerfile
----------------------------------------------------------------------
diff --git a/Dockerfile b/Dockerfile
index f125d55..f91dd98 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -30,8 +30,13 @@ RUN apt-get update && apt-get install -y \
     zip \
     subversion \
     python-svn \
-    npm
-RUN ln -s /usr/bin/nodejs /usr/bin/node
+    curl
+
+# up-to-date version of node & npm
+RUN curl --silent --location https://deb.nodesource.com/setup_4.x | sudo bash - && \
+    apt-get install --yes nodejs
+
+# only do the global installation here.  All local packages are installed in the docker-compose.yml command, since they need the shared mount
 RUN npm install -g broccoli-cli
 
 # Snapshot generation for SVN (and maybe other SCMs) might fail without this
@@ -42,5 +47,5 @@ ENV LANG en_US.UTF-8
 # tests). If this is not set, it uses os.getlogin, which fails inside docker.
 ENV USER root
 
-WORKDIR /allura/Allura
-CMD gunicorn --paste docker-dev.ini --reload
+WORKDIR /allura
+CMD gunicorn --paste Allura/docker-dev.ini --reload

http://git-wip-us.apache.org/repos/asf/allura/blob/a1aab220/docker-compose.yml
----------------------------------------------------------------------
diff --git a/docker-compose.yml b/docker-compose.yml
index faac4a4..5eaaf4c 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -17,16 +17,16 @@
 
 web:
   build: .
-  working_dir: /allura
-  # specialized command (and working_dir) to run broccoli
+  # specialized command to run broccoli
   # since it depends on files from the shared volume, it can't be run as part of the Dockerfile build :(
+  # and --no-bin-links necessary when Virtualbox is used since shared mount can't handle symlinks
   command: >
     sh -c '
     if [ ! -e Allura/allura/public/nf/js/build/transpiled.js ]; then
-      npm install &&
+      npm install --no-bin-links --loglevel http &&
       npm run build;
     fi;
-    gunicorn --paste Allura/docker-dev.ini --reload
+    gunicorn --paste Allura/docker-dev.ini --reload;
     '
   ports:
     - "8080:8080"


[36/50] [abbrv] allura git commit: [#7984] skip tools that never have notications; better text within the table

Posted by je...@apache.org.
[#7984] skip tools that never have notications; better text within the table


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/e97c5ffe
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/e97c5ffe
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/e97c5ffe

Branch: refs/heads/ib/7924
Commit: e97c5ffe587b5e49a63fbee3800265df1db96a94
Parents: 68786d3
Author: Dave Brondsema <da...@brondsema.net>
Authored: Tue Oct 13 16:52:08 2015 -0400
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Wed Oct 14 10:01:15 2015 -0400

----------------------------------------------------------------------
 Allura/allura/app.py                        |  3 +++
 Allura/allura/controllers/auth.py           | 17 ++++++++++++-----
 Allura/allura/ext/admin/admin_main.py       |  1 +
 Allura/allura/ext/search/search_main.py     |  1 +
 Allura/allura/ext/user_profile/user_main.py |  1 +
 Allura/allura/lib/widgets/subscriptions.py  |  4 ++--
 Allura/allura/tests/functional/test_auth.py | 12 ++++++------
 ForgeActivity/forgeactivity/main.py         |  1 +
 ForgeChat/forgechat/main.py                 |  1 +
 ForgeLink/forgelink/link_main.py            |  1 +
 ForgeUserStats/forgeuserstats/main.py       |  1 +
 11 files changed, 30 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/e97c5ffe/Allura/allura/app.py
----------------------------------------------------------------------
diff --git a/Allura/allura/app.py b/Allura/allura/app.py
index bd6f36b..4cc47b1 100644
--- a/Allura/allura/app.py
+++ b/Allura/allura/app.py
@@ -216,6 +216,8 @@ class Application(object):
         can not be added to the project by the user. Default value is float("inf").
     :cvar bool hidden: Default is False, Application is not hidden from the
         list of a project's installed tools.
+    :cvar bool has_notifications: Default is True, if set to False then application will not
+        be listed on user subscriptions table.
     :cvar str tool_description: Text description of this Application.
     :cvar bool relaxed_mount_points: Set to True to relax the default mount point
         naming restrictions for this Application. Default is False. See
@@ -272,6 +274,7 @@ class Application(object):
     relaxed_mount_points = False
     ordinal = 0
     hidden = False
+    has_notifications = True
     icons = {
         24: 'images/admin_24.png',
         32: 'images/admin_32.png',

http://git-wip-us.apache.org/repos/asf/allura/blob/e97c5ffe/Allura/allura/controllers/auth.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/auth.py b/Allura/allura/controllers/auth.py
index e3c4d38..f2043af 100644
--- a/Allura/allura/controllers/auth.py
+++ b/Allura/allura/controllers/auth.py
@@ -868,15 +868,19 @@ class SubscriptionsController(BaseController):
                 continue
             if app_config is None:
                 continue
+            app = app_config.load()
+            if not app.has_notifications:
+                continue
 
             subscriptions.append(dict(
                 subscription_id=mb._id,
                 project_id=project._id,
                 app_config_id=mb.app_config_id,
                 project_name=project.name,
-                mount_point=app_config.options['mount_point'],
+                tool=app_config.options['mount_label'],
                 artifact_title=dict(
-                    text=mb.artifact_title, href=mb.artifact_url),
+                    text='Everything' if mb.artifact_title == 'All artifacts' else mb.artifact_title,
+                    href=mb.artifact_url),
                 topic=mb.topic,
                 type=mb.type,
                 frequency=mb.frequency.unit,
@@ -902,20 +906,23 @@ class SubscriptionsController(BaseController):
         for tool in my_tools:
             if tool['_id'] in my_tools_subscriptions:
                 continue  # We have already subscribed to this tool.
+            app = tool.load()
+            if not app.has_notifications:
+                continue
 
             subscriptions.append(
                 dict(tool_id=tool._id,
                      user_id=c.user._id,
                      project_id=tool.project_id,
                      project_name=my_projects[tool.project_id].name,
-                     mount_point=tool.options['mount_point'],
-                     artifact_title='No subscription',
+                     tool=tool.options['mount_label'],
+                     artifact_title='Everything',
                      topic=None,
                      type=None,
                      frequency=None,
                      artifact=None))
 
-        subscriptions.sort(key=lambda d: (d['project_name'], d['mount_point']))
+        subscriptions.sort(key=lambda d: (d['project_name'], d['tool']))
         provider = plugin.AuthenticationProvider.get(request)
         menu = provider.account_navigation()
         return dict(

http://git-wip-us.apache.org/repos/asf/allura/blob/e97c5ffe/Allura/allura/ext/admin/admin_main.py
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/admin/admin_main.py b/Allura/allura/ext/admin/admin_main.py
index dcda9be..7affa3c 100644
--- a/Allura/allura/ext/admin/admin_main.py
+++ b/Allura/allura/ext/admin/admin_main.py
@@ -86,6 +86,7 @@ class AdminApp(Application):
         48: 'images/admin_48.png'
     }
     exportable = True
+    has_notifications = False
 
     def __init__(self, project, config):
         Application.__init__(self, project, config)

http://git-wip-us.apache.org/repos/asf/allura/blob/e97c5ffe/Allura/allura/ext/search/search_main.py
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/search/search_main.py b/Allura/allura/ext/search/search_main.py
index 99c5dfc..9f8a92b 100644
--- a/Allura/allura/ext/search/search_main.py
+++ b/Allura/allura/ext/search/search_main.py
@@ -40,6 +40,7 @@ class SearchApp(Application):
     __version__ = version.__version__
     max_instances = 0
     hidden = True
+    has_notifications = False
     sitemap = []
 
     def __init__(self, project, config):

http://git-wip-us.apache.org/repos/asf/allura/blob/e97c5ffe/Allura/allura/ext/user_profile/user_main.py
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/user_profile/user_main.py b/Allura/allura/ext/user_profile/user_main.py
index f676bed..9be9276 100644
--- a/Allura/allura/ext/user_profile/user_main.py
+++ b/Allura/allura/ext/user_profile/user_main.py
@@ -59,6 +59,7 @@ class UserProfileApp(Application):
     __version__ = version.__version__
     tool_label = 'Profile'
     max_instances = 0
+    has_notifications = False
     icons = {
         24: 'images/home_24.png',
         32: 'images/home_32.png',

http://git-wip-us.apache.org/repos/asf/allura/blob/e97c5ffe/Allura/allura/lib/widgets/subscriptions.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/subscriptions.py b/Allura/allura/lib/widgets/subscriptions.py
index db6c51d..909a506 100644
--- a/Allura/allura/lib/widgets/subscriptions.py
+++ b/Allura/allura/lib/widgets/subscriptions.py
@@ -41,10 +41,10 @@ class _SubscriptionTable(ew.TableField):
     class fields(ew_core.NameList):
         project_name = ffw.DisplayOnlyField(
             label='Project', show_label=True, with_hidden_input=False)
-        mount_point = ffw.DisplayOnlyField(
+        tool = ffw.DisplayOnlyField(
             label='Tool', show_label=True, with_hidden_input=False)
         artifact_title = ew.LinkField(
-            label='Artifact', show_label=True, plaintext_if_no_href=True)
+            label='Item(s)', show_label=True, plaintext_if_no_href=True)
         # unsubscribe = SubmitButton()
         subscribed = ew.Checkbox(suppress_label=True)
 

http://git-wip-us.apache.org/repos/asf/allura/blob/e97c5ffe/Allura/allura/tests/functional/test_auth.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_auth.py b/Allura/allura/tests/functional/test_auth.py
index 5ad86ea..d74ebf0 100644
--- a/Allura/allura/tests/functional/test_auth.py
+++ b/Allura/allura/tests/functional/test_auth.py
@@ -582,20 +582,20 @@ class TestAuth(TestController):
         subscriptions = M.Mailbox.query.find(dict(
             user_id=c.user._id, is_flash=False)).all()
         # make sure page actually lists all the user's subscriptions
-        assert len(
-            subscriptions) > 0, 'Test user has no subscriptions, cannot verify that they are shown'
+        assert len(subscriptions) > 0, 'Test user has no subscriptions, cannot verify that they are shown'
         for m in subscriptions:
             assert m._id in r, "Page doesn't list subscription for Mailbox._id = %s" % m._id
 
         # make sure page lists all tools which user can subscribe
         user = M.User.query.get(username='test-admin')
-        tools = []
         for p in user.my_projects():
             for ac in p.app_configs:
                 if not M.Mailbox.subscribed(project_id=p._id, app_config_id=ac._id):
-                    tools.append(ac._id)
-        for tool_id in tools:
-            assert tool_id in r, "Page doesn't list tool with app_config_id = %s" % tool_id
+                    if ac.tool_name in ('activity', 'admin', 'search', 'userstats', 'profile'):
+                        # these have has_notifications=False
+                        assert ac._id not in r, "Page lists tool %s but it should not" % ac.tool_name
+                    else:
+                        assert ac._id in r, "Page doesn't list tool %s" % ac.tool_name
 
     def _find_subscriptions_form(self, r):
         form = None

http://git-wip-us.apache.org/repos/asf/allura/blob/e97c5ffe/ForgeActivity/forgeactivity/main.py
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/main.py b/ForgeActivity/forgeactivity/main.py
index 9bb6029..845eb9e 100644
--- a/ForgeActivity/forgeactivity/main.py
+++ b/ForgeActivity/forgeactivity/main.py
@@ -52,6 +52,7 @@ class ForgeActivityApp(Application):
     default_mount_point = 'activity'
     max_instances = 0
     searchable = False
+    has_notifications = False
 
     def __init__(self, project, config):
         Application.__init__(self, project, config)

http://git-wip-us.apache.org/repos/asf/allura/blob/e97c5ffe/ForgeChat/forgechat/main.py
----------------------------------------------------------------------
diff --git a/ForgeChat/forgechat/main.py b/ForgeChat/forgechat/main.py
index 39a6807..bdd373a 100644
--- a/ForgeChat/forgechat/main.py
+++ b/ForgeChat/forgechat/main.py
@@ -59,6 +59,7 @@ class ForgeChatApp(Application):
     config_options = Application.config_options + [
         ConfigOption('channel', str, ''),
     ]
+    has_notifications = False
     icons = {
         24: 'images/chat_24.png',
         32: 'images/chat_32.png',

http://git-wip-us.apache.org/repos/asf/allura/blob/e97c5ffe/ForgeLink/forgelink/link_main.py
----------------------------------------------------------------------
diff --git a/ForgeLink/forgelink/link_main.py b/ForgeLink/forgelink/link_main.py
index 735816d..dde7a02 100644
--- a/ForgeLink/forgelink/link_main.py
+++ b/ForgeLink/forgelink/link_main.py
@@ -59,6 +59,7 @@ class ForgeLinkApp(Application):
     config_on_install = ['url']
     searchable = True
     exportable = True
+    has_notifications = False
     tool_label = 'External Link'
     default_mount_label = 'Link name'
     default_mount_point = 'link'

http://git-wip-us.apache.org/repos/asf/allura/blob/e97c5ffe/ForgeUserStats/forgeuserstats/main.py
----------------------------------------------------------------------
diff --git a/ForgeUserStats/forgeuserstats/main.py b/ForgeUserStats/forgeuserstats/main.py
index eb25140..daa19ef 100644
--- a/ForgeUserStats/forgeuserstats/main.py
+++ b/ForgeUserStats/forgeuserstats/main.py
@@ -97,6 +97,7 @@ class ForgeUserStatsApp(Application):
         'admin': 'Toggle stats visibility.',
     }
     max_instances = 0
+    has_notifications = False
     ordinal = 15
     config_options = Application.config_options
     default_external_feeds = []


[50/50] [abbrv] allura git commit: [#7924] ticket:838 Fix group permissions change js

Posted by je...@apache.org.
[#7924] ticket:838 Fix group permissions change js


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/2505c075
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/2505c075
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/2505c075

Branch: refs/heads/ib/7924
Commit: 2505c075f056473512140600f78c291594dd3fbc
Parents: d72156a
Author: Igor Bondarenko <je...@gmail.com>
Authored: Mon Oct 19 10:37:39 2015 +0000
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Mon Oct 19 10:37:39 2015 +0000

----------------------------------------------------------------------
 Allura/allura/public/nf/js/project_groups.js | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/2505c075/Allura/allura/public/nf/js/project_groups.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/project_groups.js b/Allura/allura/public/nf/js/project_groups.js
index 858d1ac..ca4acb3 100644
--- a/Allura/allura/public/nf/js/project_groups.js
+++ b/Allura/allura/public/nf/js/project_groups.js
@@ -104,17 +104,16 @@ $(function() {
         var perm_link = perm_holder.find('a');
         if(!perm_holder.hasClass(item.has)){
           perm_holder.effect('highlight', {}, 2000);
-          var icon = perm_holder.find('b');
           perm_holder.attr('class',item.has);
           perm_link.attr('title',item.text);
           if(item.has=="yes"){
-            icon.attr('class','ico ico-check').attr('data-icon','3');
+            perm_link.attr('class','icon fa fa-check');
           }
           else if(item.has=="inherit"){
-            icon.attr('class','ico ico-checkcircle').attr('data-icon','2');
+            perm_link.attr('class','icon fa fa-check-circle');
           }
           else{
-            icon.attr('class','ico ico-noentry').attr('data-icon','d');
+            perm_link.attr('class','icon fa fa-ban');
           }
           perm_holder.find('span').remove();
           perm_link.show();


[43/50] [abbrv] allura git commit: [#7924] ticket:836 Update perm_delete

Posted by je...@apache.org.
[#7924] ticket:836 Update perm_delete


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/9068b7e0
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/9068b7e0
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/9068b7e0

Branch: refs/heads/ib/7924
Commit: 9068b7e0c7676aa67272865b42e12700d1e52ab3
Parents: dcc208e
Author: Igor Bondarenko <je...@gmail.com>
Authored: Thu Aug 13 16:13:19 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Thu Oct 15 15:08:32 2015 +0000

----------------------------------------------------------------------
 .../ext/admin/templates/admin_widgets/card_field.html | 13 +++++--------
 Allura/allura/ext/admin/templates/project_groups.html | 14 ++++++++++----
 Allura/allura/lib/app_globals.py                      |  2 +-
 Allura/allura/public/nf/js/project_groups.js          |  9 ++++++---
 4 files changed, 22 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/9068b7e0/Allura/allura/ext/admin/templates/admin_widgets/card_field.html
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/admin/templates/admin_widgets/card_field.html b/Allura/allura/ext/admin/templates/admin_widgets/card_field.html
index 47475fd..657f6a0 100644
--- a/Allura/allura/ext/admin/templates/admin_widgets/card_field.html
+++ b/Allura/allura/ext/admin/templates/admin_widgets/card_field.html
@@ -22,11 +22,10 @@
     <li class="tcenter">
       <h3>{{name}}</h3>
       {% if settings_href %}
-      <a href="{{settings_href}}" class="admin_modal" title="{{name}} Settings">
-        <small
-           data-icon="{{g.icons.perm_tool.char}}"
-           class="ico-r admin_modal {{g.icons.perm_tool.css}}"></small>
-      </a>
+      {{ g.icons['perm_tool'].render(
+          href=settings_href,
+          extra_css='admin_modal',
+          title='{} Settings'.format(name)) }}
       {% endif %}
       <p style="padding-bottom: 0">{{ g.icons[icon_name].render(tag='b', style='font-size:24px;') }}</p>
       {% if desc %}
@@ -46,9 +45,7 @@
           {{ widget.item_display(item) }}
           <input type="hidden" name="card-{{index}}.value"
                  {{ widget.j2_attrs(dict(value=widget.item_id(item))) }} />
-          <small data-icon="{{g.icons['perm_delete'].char}}"
-                 class="ico-r {{g.icons['perm_delete'].css}}"
-                 title="Remove"></small>
+          {{ g.icons['perm_delete'].render(tag='small') }}
         </a>
     </li>
     {% endfor %}

http://git-wip-us.apache.org/repos/asf/allura/blob/9068b7e0/Allura/allura/ext/admin/templates/project_groups.html
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/admin/templates/project_groups.html b/Allura/allura/ext/admin/templates/project_groups.html
index 57d37e2..7169b60 100644
--- a/Allura/allura/ext/admin/templates/project_groups.html
+++ b/Allura/allura/ext/admin/templates/project_groups.html
@@ -71,9 +71,11 @@
           {% endfor %}
           {% for r in role.users_with_role() %}
           <li class="deleter" data-user="{{r.user.username}}">
-            <b data-icon="{{g.icons['perm_delete'].char}}"
-               class="ico {{g.icons['perm_delete'].css}} deleter" data-user="{{r.user.username}}"></b>
-            {{ r.user.display_name }} ({{r.user.username}})
+            {{ g.icons['perm_delete'].render(
+                title='{} ({})'.format(r.user.display_name, r.user.username),
+                show_title=True,
+                extra_css='deleter',
+                **{'data-user': r.user.username}) }}
           </li>
           {% endfor %}
           <li class="new-item">
@@ -115,6 +117,10 @@
 <script type="text/javascript">
   // these icons are used in the js, so set them up now
   var spinner_img = '<img src="{{g.forge_static('images/spinner.gif')}}">';
-  var perm_delete_ico = '<b data-icon="{{g.icons['perm_delete'].char}}" class="ico {{g.icons['perm_delete'].css}}"></b>';
+  {% set perm_delete_ico = g.icons['perm_delete'].render(
+                title='',
+                show_title=True,
+                extra_css='deleter') %}
+  var perm_delete_ico = '{{perm_delete_ico}}';
 </script>
 {% endblock %}

http://git-wip-us.apache.org/repos/asf/allura/blob/9068b7e0/Allura/allura/lib/app_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/app_globals.py b/Allura/allura/lib/app_globals.py
index 528423a..49fa366 100644
--- a/Allura/allura/lib/app_globals.py
+++ b/Allura/allura/lib/app_globals.py
@@ -258,7 +258,7 @@ class Globals(object):
             perm_update=Icon('0', 'ico-sync'),
             perm_create=Icon('e', 'ico-config'),
             perm_register=Icon('e', 'ico-config'),
-            perm_delete=Icon('-', 'ico-minuscirc'),
+            perm_delete=Icon('fa fa-minus-circle', 'Remove'),
             perm_tool=Icon('x', 'ico-config'),
             perm_admin=Icon('(', 'ico-lock'),
             perm_has_yes=Icon('3', 'ico-check'),

http://git-wip-us.apache.org/repos/asf/allura/blob/9068b7e0/Allura/allura/public/nf/js/project_groups.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/project_groups.js b/Allura/allura/public/nf/js/project_groups.js
index 99ecd12..858d1ac 100644
--- a/Allura/allura/public/nf/js/project_groups.js
+++ b/Allura/allura/public/nf/js/project_groups.js
@@ -53,6 +53,7 @@ $(function() {
   });
   // remove user from group
   var delete_user = function(evt){
+    evt.preventDefault();
     var user_holder =  $(this).parent();
     if(confirm("Are you sure you want to remove the user "+user_holder.data('user')+"?")){
         var params = {'role_id': user_holder.closest('tr').data('group'),
@@ -70,7 +71,7 @@ $(function() {
       }
     });
   }};
-  $('#usergroup_admin b.deleter').click(delete_user);
+  $('#usergroup_admin a.deleter').click(delete_user);
   // add user to group
   $('#usergroup_admin tr').delegate("form.add_user", "submit", function(evt){
     evt.preventDefault();
@@ -87,8 +88,9 @@ $(function() {
       }
       else{
         holder.attr('data-user', data.username).addClass('deleter');
-        holder.html(perm_delete_ico+' '+data.displayname+' ('+data.username+')');
-        holder.children('b').click(delete_user);
+        holder.html(perm_delete_ico);
+        holder.find('span').html('&nbsp;' + data.displayname + ' (' + data.username + ')');
+        holder.children('a.deleter').click(delete_user);
       }
     });
   });
@@ -166,6 +168,7 @@ $(function() {
       newitem.remove();
       newitem.removeClass('new-item');
       adder.click(function(evt) {
+          evt.preventDefault();
           newitem.clone().insertBefore(adder.closest('li')).find('input:text').focus();
       });
   });


[11/50] [abbrv] allura git commit: [#7946] ticket:846 Add test for chat's configure

Posted by je...@apache.org.
[#7946] ticket:846 Add test for chat's configure

It actually passes, cause turns out problem is in js, but can be still
useful in the future.


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/367525f0
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/367525f0
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/367525f0

Branch: refs/heads/ib/7924
Commit: 367525f0eb942179dc7d728333a32fa5bde1564a
Parents: f3bd36c
Author: Igor Bondarenko <je...@gmail.com>
Authored: Tue Sep 22 16:21:16 2015 +0300
Committer: Heith Seewald <hs...@hsmb.local>
Committed: Mon Sep 28 14:33:47 2015 -0400

----------------------------------------------------------------------
 .../forgechat/tests/functional/test_root.py     | 22 ++++++++++++++++++++
 1 file changed, 22 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/367525f0/ForgeChat/forgechat/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/ForgeChat/forgechat/tests/functional/test_root.py b/ForgeChat/forgechat/tests/functional/test_root.py
index 013176c..49b824d 100644
--- a/ForgeChat/forgechat/tests/functional/test_root.py
+++ b/ForgeChat/forgechat/tests/functional/test_root.py
@@ -15,7 +15,16 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
+import json
+from datadiff.tools import assert_equal
+
 from alluratest.controller import TestController
+from allura.tests.decorators import with_tool
+
+from forgechat import model as CM
+
+
+with_chat = with_tool('test', 'Chat', 'chat', 'Chat')
 
 
 class TestRootController(TestController):
@@ -23,3 +32,16 @@ class TestRootController(TestController):
     def test_root_index(self):
         response = self.app.get('/chat/').follow()
         assert 'Log for' in response
+
+    @with_chat
+    def test_admin_configure(self):
+        self.app.get('/')  # establish session
+        data = {'channel': 'test channel',
+                '_session_id': self.app.cookies['_session_id']}
+        ch = CM.ChatChannel.query.get()
+        assert_equal(ch.channel, '')
+        resp = self.app.post('/p/test/admin/chat/configure', data)
+        expected = {'status': 'ok', 'message': 'Chat options updated'}
+        assert_equal(json.loads(self.webflash(resp)), expected)
+        ch = CM.ChatChannel.query.get()
+        assert_equal(ch.channel, 'test channel')


[08/50] [abbrv] allura git commit: [#7995] share python env in /allura-data not in local dir

Posted by je...@apache.org.
[#7995] share python env in /allura-data not in local dir

This is so it won't be shared to host machine if using docker-machine (e.g. Mac/Win
using Docker Toolbox).  No point in sharing there since the environment has
different system libs linked and can't be re-used.

Also fixes a warning about relative paths.


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/efc4642c
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/efc4642c
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/efc4642c

Branch: refs/heads/ib/7924
Commit: efc4642cff21ffad1294a2e07e0d4da16693601e
Parents: b036c1c
Author: Dave Brondsema <da...@brondsema.net>
Authored: Thu Sep 24 13:03:29 2015 -0400
Committer: Heith Seewald <hs...@hsmb.local>
Committed: Fri Sep 25 16:07:28 2015 -0500

----------------------------------------------------------------------
 Allura/docs/getting_started/installation.rst | 8 +++++---
 docker-compose.yml                           | 4 ++--
 2 files changed, 7 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/efc4642c/Allura/docs/getting_started/installation.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/getting_started/installation.rst b/Allura/docs/getting_started/installation.rst
index 203d6f5..029e21a 100644
--- a/Allura/docs/getting_started/installation.rst
+++ b/Allura/docs/getting_started/installation.rst
@@ -244,12 +244,14 @@ Host-mounted volumes
 
 These are created on first run.
 
-Current directory mounted as :file:`/allura` inside containers.
+Current directory mounted as :file:`/allura` inside containers.  This means your current source code in your host
+environment is shared with the containers.  You can edit Allura code directly, and the containers will reflect your
+changes.
 
 Python environment:
 
-- :file:`env-docker/python`
-- :file:`env-docker/bin`
+- :file:`/allura-data/env-docker/python`
+- :file:`/allura-data/env-docker/bin`
 
 Services data:
 

http://git-wip-us.apache.org/repos/asf/allura/blob/efc4642c/docker-compose.yml
----------------------------------------------------------------------
diff --git a/docker-compose.yml b/docker-compose.yml
index 155a421..6822677 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -24,8 +24,8 @@ web:
   volumes:
     - .:/allura
     # mount env to allow update and sharing with taskd container
-    - env-docker/python:/usr/local/lib/python2.7
-    - env-docker/bin:/usr/local/bin
+    - /allura-data/env-docker/python:/usr/local/lib/python2.7
+    - /allura-data/env-docker/bin:/usr/local/bin
     # mounting it separatelly to create git, svn, hg directories automatically
     - /allura-data/scm/git:/allura-data/scm/git
     - /allura-data/scm/hg:/allura-data/scm/hg


[16/50] [abbrv] allura git commit: [#7976] concat sourcemaps together properly

Posted by je...@apache.org.
[#7976] concat sourcemaps together properly


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/cd63778f
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/cd63778f
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/cd63778f

Branch: refs/heads/ib/7924
Commit: cd63778f4c93bf7a3503f41ffef9a88857058c01
Parents: d6a9114
Author: Dave Brondsema <da...@brondsema.net>
Authored: Thu Oct 1 14:54:33 2015 -0400
Committer: Heith Seewald <hs...@hsmb.local>
Committed: Fri Oct 2 10:01:49 2015 -0400

----------------------------------------------------------------------
 Brocfile.js  | 8 +++-----
 package.json | 3 +--
 2 files changed, 4 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/cd63778f/Brocfile.js
----------------------------------------------------------------------
diff --git a/Brocfile.js b/Brocfile.js
index 93cab0b..71a8f90 100644
--- a/Brocfile.js
+++ b/Brocfile.js
@@ -17,8 +17,7 @@
        under the License.
 */
 var babelTranspiler = require("broccoli-babel-transpiler");
-var sourceMap = require('broccoli-source-map');
-var concat = require('broccoli-concat');
+var sourceMapConcat = require('broccoli-sourcemap-concat');
 var funnel = require('broccoli-funnel');
 var uglifyJavaScript = require('broccoli-uglify-js');
 
@@ -31,11 +30,10 @@ tree = babelTranspiler(tree, {
     sourceMaps: 'inline',  // external doesn't work, have to use extract below
     comments: false,
 });
-tree = concat(tree, {
-  inputFiles: ['**/*.js'],
+tree = sourceMapConcat(tree, {
+  inputFiles: ['**/*'],
   outputFile: '/transpiled.js'
 });
-tree = sourceMap.extract(tree);
 
 if (process.env.BROCCOLI_ENV === 'production') {
     /* can't use this for dev mode, since it drops the sourcemap comment even if we set  output: {comments: true}

http://git-wip-us.apache.org/repos/asf/allura/blob/cd63778f/package.json
----------------------------------------------------------------------
diff --git a/package.json b/package.json
index 95fa5ac..f850f00 100644
--- a/package.json
+++ b/package.json
@@ -17,9 +17,8 @@
   "devDependencies": {
     "broccoli": "^0.16.8",
     "broccoli-babel-transpiler": "^5.4.5",
-    "broccoli-concat": "0.0.13",
     "broccoli-funnel": "^0.2.8",
-    "broccoli-source-map": "^0.2.3",
+    "broccoli-sourcemap-concat": "^2.0.1",
     "broccoli-uglify-js": "^0.1.3"
   }
 }


[22/50] [abbrv] allura git commit: [#7976] dummy es6.js file until we have actual ones, so that our JS build process doesn't error out

Posted by je...@apache.org.
[#7976] dummy es6.js file until we have actual ones, so that our JS build process doesn't error out


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/53ff3fe8
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/53ff3fe8
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/53ff3fe8

Branch: refs/heads/ib/7924
Commit: 53ff3fe8e38b4081d02b5c3b255e5fd7cc16efa0
Parents: 0b77e7e
Author: Dave Brondsema <da...@brondsema.net>
Authored: Fri Oct 2 10:30:46 2015 -0400
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Fri Oct 2 10:30:46 2015 -0400

----------------------------------------------------------------------
 Allura/allura/public/nf/js/dummy.es6.js | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/53ff3fe8/Allura/allura/public/nf/js/dummy.es6.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/dummy.es6.js b/Allura/allura/public/nf/js/dummy.es6.js
new file mode 100644
index 0000000..e69de29


[23/50] [abbrv] allura git commit: [#7971] remove hidden CSS non-loading message, hopefully fixed now

Posted by je...@apache.org.
[#7971] remove hidden CSS non-loading message, hopefully fixed now


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/03230782
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/03230782
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/03230782

Branch: refs/heads/ib/7924
Commit: 03230782a0b6d75a1abe7e51dee6552a4483939d
Parents: 53ff3fe
Author: Dave Brondsema <da...@brondsema.net>
Authored: Mon Oct 5 10:07:33 2015 -0400
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Mon Oct 5 10:07:33 2015 -0400

----------------------------------------------------------------------
 Allura/allura/templates/jinja_master/master.html | 6 ------
 1 file changed, 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/03230782/Allura/allura/templates/jinja_master/master.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/jinja_master/master.html b/Allura/allura/templates/jinja_master/master.html
index b2d2418..4fde7ab 100644
--- a/Allura/allura/templates/jinja_master/master.html
+++ b/Allura/allura/templates/jinja_master/master.html
@@ -78,12 +78,6 @@
 </head>
 
 <body{% block body_attrs %}{% endblock %} id="forge">
-<h2 class="hidden">
-    <span style="color:red">Error:</span> CSS did not load.<br>
-    This may happen on the first request due to CSS mimetype issues.
-    Try clearing your browser cache and refreshing.
-    <hr>
-</h2>
 {% block body_top_js %}
     {% for blob in g.resource_manager.emit('body_top_js') %}
         {{ blob }}


[44/50] [abbrv] allura git commit: [#7924] ticket:836 Update perm_has_(no|yes)

Posted by je...@apache.org.
[#7924] ticket:836 Update perm_has_(no|yes)


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/31973232
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/31973232
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/31973232

Branch: refs/heads/ib/7924
Commit: 319732328f984fce384ecc73d5b398645da91da5
Parents: 9068b7e
Author: Igor Bondarenko <je...@gmail.com>
Authored: Thu Aug 13 16:23:04 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Thu Oct 15 15:08:32 2015 +0000

----------------------------------------------------------------------
 Allura/allura/ext/admin/templates/project_groups.html | 7 +++----
 Allura/allura/lib/app_globals.py                      | 4 ++--
 2 files changed, 5 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/31973232/Allura/allura/ext/admin/templates/project_groups.html
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/admin/templates/project_groups.html b/Allura/allura/ext/admin/templates/project_groups.html
index 7169b60..e78c622 100644
--- a/Allura/allura/ext/admin/templates/project_groups.html
+++ b/Allura/allura/ext/admin/templates/project_groups.html
@@ -29,10 +29,9 @@
   <ul class="permissions">
     {% for perm in permissions_by_role[role._id.__str__()] %}
     <li class="{{perm['has']}}" data-permission="{{perm['name']}}">
-      <a href="#" title="{{perm['text']}}">
-        <b data-icon="{{g.icons['perm_has_%s'%perm['has']].char}}"
-           class="ico {{g.icons['perm_has_%s'%perm['has']].css}}">
-        </b> {{perm['name']}}</a>
+      {{ g.icons['perm_has_%s'%perm['has']].render(title=perm['text'], closing_tag=False) }}
+        {{perm['name']}}
+      </a> {# close tag, opened by render #}
     </li>
     {% endfor %}
   </ul>

http://git-wip-us.apache.org/repos/asf/allura/blob/31973232/Allura/allura/lib/app_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/app_globals.py b/Allura/allura/lib/app_globals.py
index 49fa366..cdcaf54 100644
--- a/Allura/allura/lib/app_globals.py
+++ b/Allura/allura/lib/app_globals.py
@@ -261,8 +261,8 @@ class Globals(object):
             perm_delete=Icon('fa fa-minus-circle', 'Remove'),
             perm_tool=Icon('x', 'ico-config'),
             perm_admin=Icon('(', 'ico-lock'),
-            perm_has_yes=Icon('3', 'ico-check'),
-            perm_has_no=Icon('d', 'ico-noentry'),
+            perm_has_yes=Icon('fa fa-check', 'Check'),
+            perm_has_no=Icon('fa fa-ban', 'No entry'),
             perm_has_inherit=Icon('2', 'ico-checkcircle'),
         )