[Bps-public-commit] RT-BugTracker-Public branch, master, updated. 1.05-44-g7a6035d

? sunnavy sunnavy at bestpractical.com
Mon Mar 1 15:40:29 EST 2021


The branch, master has been updated
       via  7a6035d92328a711c2fe50afcdfd5456dc9387ea (commit)
       via  afdcd7b6596cdd76a011e7f641841d064532c0bf (commit)
       via  b72305dcf5c66cb3da9254bd3e224b7449682157 (commit)
       via  d924e8212762ea8ec190dfafd2e3ffa3675e9a12 (commit)
       via  5559846e537528835b48a92a866e1dce4294f9f1 (commit)
       via  a5be552e7afb1599a0051d5f51d22176b76e694f (commit)
       via  087236f6c7cdb20f9a9a32729755c4439cfbedad (commit)
       via  782d189a206947a5a432ec9ae2ac9a191da707ab (commit)
       via  b152e0721a6fd46e68184d845e1f74e1c3911ec4 (commit)
       via  9cd4e4b2c15df9fdacb413e4a8a212edcbd02b26 (commit)
       via  33cb6aaa9ee138d7d84676ad1e87793bd47f0d2b (commit)
       via  92628277df651dc77b2e470e3a65c3cb74f7f63c (commit)
       via  5408fe4071d55fdb83411e5c43b466c4658ab916 (commit)
       via  68c4804eb4bd2589d7cef8a78845727879a4bb19 (commit)
       via  cf7299a0ac9896a17bc9c639438001819efcbbdb (commit)
       via  01237cfb49970f484b9d5c937badb782e7ab29fd (commit)
       via  a99cb670ef2aba8eb04778b58f1ec2e6876837f5 (commit)
       via  e90c8c838c2db9f893dd7f38bee470ac498ab41e (commit)
       via  f3d40f6a66af167219a7024b511999b5662fe362 (commit)
       via  88851d27364eca44876dbfce4768c5034650d7cc (commit)
       via  7e579d6b04f7b5610e88d910d8b33f2547f71f85 (commit)
       via  b6f12897051db37a88b2d6d7290363444a8a9595 (commit)
       via  20e195b45c78515ed37619c693c92276711a4053 (commit)
       via  da3b708a32fc80acd287e6eb7ccc29cb159f376f (commit)
       via  a580f15ff1a73a0d083e1a124ebeef92c120a220 (commit)
       via  4e5d6a489321932b5c39783dbf0c3b7386b6640a (commit)
       via  5151a228d1b613c2e251e9cac13987ccdf7452ff (commit)
       via  3d5126b8819cb31a2a303848e6c96661d6690a2e (commit)
       via  ef9ed2c5775893fd7d3d94c0ca7ef039d4ff6653 (commit)
       via  35499ed99bba887f544c63579b985c6c346a727b (commit)
       via  e3ae54942c13c9167a9969125403a9f66516e5c4 (commit)
       via  bb8dbfeabf87f29d8e9667015c6f6f8ef4fbff5e (commit)
       via  8cd3dd13e208d6909c88b5b643d0263ad40289b2 (commit)
       via  ab5c6a137e91574a22159f0150dbc367706cc2bc (commit)
       via  f4404d95883a7772f380bd83440057aba165207b (commit)
       via  f30ab832dae496d8083e79f06652e41beaba53c5 (commit)
       via  5218a0a3610e87253a8ea5a26993af9a68f7c82d (commit)
       via  fabb4c9a9eac5f9fe00beacb398c021c60960013 (commit)
       via  ec9e02f563cc465070a8ff60b4b276ba03b8bf9b (commit)
       via  13e7c169b5587d42a848a4c00f521219d08f25ec (commit)
       via  618af1ee2d8da7cee04b98c71e169205ba593295 (commit)
       via  c903ba961307e5f187c78ab46f7990cfe0b0f9ce (commit)
       via  ec6ef0c017442cd47854fef723a50c4308fe0d21 (commit)
       via  fee5b48defd5d045e198434ea4eb6efed03ffa0c (commit)
      from  66987baace6f3884b19b18f96b5cc38aca86da10 (commit)

Summary of changes:
 Changes                                            |  14 ++
 MANIFEST                                           |   8 +-
 META.yml                                           |  15 +-
 Makefile.PL                                        |   6 +-
 README                                             | 104 ++++++++++--
 etc/BugTrackerPublic_Config.pm                     |   7 +
 etc/RT_SiteConfig.pm                               |   4 -
 etc/initialdata                                    |  25 +++
 .../BugTracker-Public/Elements/Login/Default       |  14 +-
 .../BugTracker-Public/Elements/Tabs/Privileged     |  58 ++++---
 .../NoAuth/Logout.html/AfterSessionDelete          |   2 +-
 .../BugTracker-Public/NoAuth/Logout.html/Default   |   2 +-
 .../BugTracker-Public/Search/Results.html/Initial  |   2 +-
 .../Ticket/Elements/ShowMessageHeaders/Default     |   2 +-
 html/Callbacks/BugTracker-Public/autohandler/Auth  |   2 +-
 .../BugTracker-Public/autohandler/Default          |   2 +-
 html/Callbacks/BugTracker-Public/autohandler/Final |   2 +-
 html/Elements/ShowUserPublic                       |  68 --------
 html/NoAuth/css/bugtracker-public.css              |  79 ---------
 html/NoAuth/js/bugtracker-public.js                |  55 ------
 html/Public/Browse.html                            |   2 +-
 html/Public/Bug/Display.html                       |  46 +++--
 html/Public/Bug/Elements/ShowSummary               |  52 +++---
 html/Public/Bug/Report.html                        | 141 +++++++--------
 html/Public/Bug/Update.html                        |   7 +-
 html/Public/Dist/BeginsWith.html                   |   2 +-
 html/Public/Dist/Browse.html                       |   2 +-
 html/Public/Dist/ByMaintainer.html                 |   2 +-
 html/Public/Dist/Display.html                      |  20 ++-
 html/Public/Dist/bugs.tsv                          |   5 +-
 html/Public/Elements/DistributionList              |  25 +--
 html/Public/Elements/ErrorNoDist                   |   4 +-
 html/Public/Elements/ErrorNoUser                   |   4 +-
 html/Public/Elements/Tabs                          |   2 +-
 html/Public/Search/Results.html                    |   4 +-
 html/Public/Search/Simple.html                     |   2 +-
 html/Public/Ticket/Attachment/WithHeaders/dhandler |   2 +-
 html/Public/Ticket/Attachment/dhandler             |   2 +-
 html/Public/autohandler                            |   2 +-
 html/Public/index.html                             |  57 +++++--
 inc/Module/Install.pm                              |  35 +---
 inc/Module/Install/Base.pm                         |   2 +-
 inc/Module/Install/Can.pm                          |  13 +-
 inc/Module/Install/Fetch.pm                        |   2 +-
 inc/Module/Install/Include.pm                      |   2 +-
 inc/Module/Install/Makefile.pm                     |   2 +-
 inc/Module/Install/Metadata.pm                     |   2 +-
 inc/Module/Install/RTx.pm                          |  54 ++++--
 inc/Module/Install/RTx/Runtime.pm                  |   1 +
 inc/Module/Install/ReadmeFromPod.pm                |   2 +-
 inc/Module/Install/Win32.pm                        |   2 +-
 inc/Module/Install/WriteAll.pm                     |   2 +-
 inc/YAML/Tiny.pm                                   |  14 +-
 lib/RT/BugTracker/Public.pm                        | 189 ++++++++++++++++++---
 static/css/bugtracker-public.css                   |  22 +++
 static/js/bugtracker-public.js                     |   8 +
 56 files changed, 684 insertions(+), 522 deletions(-)
 create mode 100644 etc/BugTrackerPublic_Config.pm
 delete mode 100644 etc/RT_SiteConfig.pm
 create mode 100644 etc/initialdata
 delete mode 100644 html/Elements/ShowUserPublic
 delete mode 100644 html/NoAuth/css/bugtracker-public.css
 delete mode 100644 html/NoAuth/js/bugtracker-public.js
 create mode 100644 static/css/bugtracker-public.css
 create mode 100644 static/js/bugtracker-public.js

- Log -----------------------------------------------------------------
commit fee5b48defd5d045e198434ea4eb6efed03ffa0c
Author: Brian C. Duggan <brian at bestpractical.com>
Date:   Thu Feb 23 14:59:07 2017 -0500

    Update BPS copyright

diff --git a/html/Callbacks/BugTracker-Public/Elements/Login/Default b/html/Callbacks/BugTracker-Public/Elements/Login/Default
index 2b7d87d..9f94e71 100644
--- a/html/Callbacks/BugTracker-Public/Elements/Login/Default
+++ b/html/Callbacks/BugTracker-Public/Elements/Login/Default
@@ -2,7 +2,7 @@
 %#
 %# COPYRIGHT:
 %#
-%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
 %#                                          <sales at bestpractical.com>
 %#
 %# (Except where explicitly superseded by other copyright notices)
diff --git a/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged b/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged
index a0dfa88..7fd8e02 100644
--- a/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged
+++ b/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged
@@ -2,7 +2,7 @@
 %#
 %# COPYRIGHT:
 %#
-%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
 %#                                          <sales at bestpractical.com>
 %#
 %# (Except where explicitly superseded by other copyright notices)
diff --git a/html/Callbacks/BugTracker-Public/NoAuth/Logout.html/AfterSessionDelete b/html/Callbacks/BugTracker-Public/NoAuth/Logout.html/AfterSessionDelete
index 339ef0b..5b3118d 100644
--- a/html/Callbacks/BugTracker-Public/NoAuth/Logout.html/AfterSessionDelete
+++ b/html/Callbacks/BugTracker-Public/NoAuth/Logout.html/AfterSessionDelete
@@ -2,7 +2,7 @@
 %#
 %# COPYRIGHT:
 %#
-%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
 %#                                          <sales at bestpractical.com>
 %#
 %# (Except where explicitly superseded by other copyright notices)
diff --git a/html/Callbacks/BugTracker-Public/NoAuth/Logout.html/Default b/html/Callbacks/BugTracker-Public/NoAuth/Logout.html/Default
index fbe87cc..5df12e9 100644
--- a/html/Callbacks/BugTracker-Public/NoAuth/Logout.html/Default
+++ b/html/Callbacks/BugTracker-Public/NoAuth/Logout.html/Default
@@ -2,7 +2,7 @@
 %#
 %# COPYRIGHT:
 %#
-%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
 %#                                          <sales at bestpractical.com>
 %#
 %# (Except where explicitly superseded by other copyright notices)
diff --git a/html/Callbacks/BugTracker-Public/Search/Results.html/Initial b/html/Callbacks/BugTracker-Public/Search/Results.html/Initial
index 3f7c8c2..aec36a3 100644
--- a/html/Callbacks/BugTracker-Public/Search/Results.html/Initial
+++ b/html/Callbacks/BugTracker-Public/Search/Results.html/Initial
@@ -2,7 +2,7 @@
 %#
 %# COPYRIGHT:
 %#
-%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
 %#                                          <sales at bestpractical.com>
 %#
 %# (Except where explicitly superseded by other copyright notices)
diff --git a/html/Callbacks/BugTracker-Public/Ticket/Elements/ShowMessageHeaders/Default b/html/Callbacks/BugTracker-Public/Ticket/Elements/ShowMessageHeaders/Default
index c281dfe..8ab0370 100644
--- a/html/Callbacks/BugTracker-Public/Ticket/Elements/ShowMessageHeaders/Default
+++ b/html/Callbacks/BugTracker-Public/Ticket/Elements/ShowMessageHeaders/Default
@@ -2,7 +2,7 @@
 %#
 %# COPYRIGHT:
 %#
-%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
 %#                                          <sales at bestpractical.com>
 %#
 %# (Except where explicitly superseded by other copyright notices)
diff --git a/html/Callbacks/BugTracker-Public/autohandler/Auth b/html/Callbacks/BugTracker-Public/autohandler/Auth
index b5d6ca6..26a30e5 100644
--- a/html/Callbacks/BugTracker-Public/autohandler/Auth
+++ b/html/Callbacks/BugTracker-Public/autohandler/Auth
@@ -2,7 +2,7 @@
 %#
 %# COPYRIGHT:
 %#
-%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
 %#                                          <sales at bestpractical.com>
 %#
 %# (Except where explicitly superseded by other copyright notices)
diff --git a/html/Callbacks/BugTracker-Public/autohandler/Default b/html/Callbacks/BugTracker-Public/autohandler/Default
index 0532814..bd40643 100644
--- a/html/Callbacks/BugTracker-Public/autohandler/Default
+++ b/html/Callbacks/BugTracker-Public/autohandler/Default
@@ -2,7 +2,7 @@
 %#
 %# COPYRIGHT:
 %#
-%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
 %#                                          <sales at bestpractical.com>
 %#
 %# (Except where explicitly superseded by other copyright notices)
diff --git a/html/Callbacks/BugTracker-Public/autohandler/Final b/html/Callbacks/BugTracker-Public/autohandler/Final
index a56f3d1..bc15ead 100644
--- a/html/Callbacks/BugTracker-Public/autohandler/Final
+++ b/html/Callbacks/BugTracker-Public/autohandler/Final
@@ -2,7 +2,7 @@
 %#
 %# COPYRIGHT:
 %#
-%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
 %#                                          <sales at bestpractical.com>
 %#
 %# (Except where explicitly superseded by other copyright notices)
diff --git a/html/Elements/ShowUserPublic b/html/Elements/ShowUserPublic
index e84021e..437a8b7 100644
--- a/html/Elements/ShowUserPublic
+++ b/html/Elements/ShowUserPublic
@@ -2,7 +2,7 @@
 %#
 %# COPYRIGHT:
 %#
-%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
 %#                                          <sales at bestpractical.com>
 %#
 %# (Except where explicitly superseded by other copyright notices)
diff --git a/html/NoAuth/css/bugtracker-public.css b/html/NoAuth/css/bugtracker-public.css
index 43480a0..f5f529d 100644
--- a/html/NoAuth/css/bugtracker-public.css
+++ b/html/NoAuth/css/bugtracker-public.css
@@ -2,7 +2,7 @@
 %#
 %# COPYRIGHT:
 %#
-%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
 %#                                          <sales at bestpractical.com>
 %#
 %# (Except where explicitly superseded by other copyright notices)
diff --git a/html/NoAuth/js/bugtracker-public.js b/html/NoAuth/js/bugtracker-public.js
index ce0eea1..98cd4f7 100644
--- a/html/NoAuth/js/bugtracker-public.js
+++ b/html/NoAuth/js/bugtracker-public.js
@@ -2,7 +2,7 @@
 %#
 %# COPYRIGHT:
 %#
-%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
 %#                                          <sales at bestpractical.com>
 %#
 %# (Except where explicitly superseded by other copyright notices)
diff --git a/html/Public/Browse.html b/html/Public/Browse.html
index bb00f6a..afd11e5 100755
--- a/html/Public/Browse.html
+++ b/html/Public/Browse.html
@@ -2,7 +2,7 @@
 %#
 %# COPYRIGHT:
 %#
-%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
 %#                                          <sales at bestpractical.com>
 %#
 %# (Except where explicitly superseded by other copyright notices)
diff --git a/html/Public/Bug/Display.html b/html/Public/Bug/Display.html
index 68838ac..545ae85 100755
--- a/html/Public/Bug/Display.html
+++ b/html/Public/Bug/Display.html
@@ -2,7 +2,7 @@
 %#
 %# COPYRIGHT:
 %#
-%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
 %#                                          <sales at bestpractical.com>
 %#
 %# (Except where explicitly superseded by other copyright notices)
diff --git a/html/Public/Bug/Elements/ShowSummary b/html/Public/Bug/Elements/ShowSummary
index eff225b..62192c1 100755
--- a/html/Public/Bug/Elements/ShowSummary
+++ b/html/Public/Bug/Elements/ShowSummary
@@ -2,7 +2,7 @@
 %#
 %# COPYRIGHT:
 %#
-%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
 %#                                          <sales at bestpractical.com>
 %#
 %# (Except where explicitly superseded by other copyright notices)
diff --git a/html/Public/Bug/Report.html b/html/Public/Bug/Report.html
index d508072..b24f54b 100755
--- a/html/Public/Bug/Report.html
+++ b/html/Public/Bug/Report.html
@@ -2,7 +2,7 @@
 %#
 %# COPYRIGHT:
 %#
-%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
 %#                                          <sales at bestpractical.com>
 %#
 %# (Except where explicitly superseded by other copyright notices)
diff --git a/html/Public/Bug/Update.html b/html/Public/Bug/Update.html
index 7aebdb2..e63a87c 100755
--- a/html/Public/Bug/Update.html
+++ b/html/Public/Bug/Update.html
@@ -2,7 +2,7 @@
 %#
 %# COPYRIGHT:
 %#
-%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
 %#                                          <sales at bestpractical.com>
 %#
 %# (Except where explicitly superseded by other copyright notices)
diff --git a/html/Public/Dist/BeginsWith.html b/html/Public/Dist/BeginsWith.html
index bb00f6a..afd11e5 100755
--- a/html/Public/Dist/BeginsWith.html
+++ b/html/Public/Dist/BeginsWith.html
@@ -2,7 +2,7 @@
 %#
 %# COPYRIGHT:
 %#
-%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
 %#                                          <sales at bestpractical.com>
 %#
 %# (Except where explicitly superseded by other copyright notices)
diff --git a/html/Public/Dist/Browse.html b/html/Public/Dist/Browse.html
index 55d2c55..4ab6825 100755
--- a/html/Public/Dist/Browse.html
+++ b/html/Public/Dist/Browse.html
@@ -2,7 +2,7 @@
 %#
 %# COPYRIGHT:
 %#
-%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
 %#                                          <sales at bestpractical.com>
 %#
 %# (Except where explicitly superseded by other copyright notices)
diff --git a/html/Public/Dist/ByMaintainer.html b/html/Public/Dist/ByMaintainer.html
index c2fa0ca..680d6e9 100755
--- a/html/Public/Dist/ByMaintainer.html
+++ b/html/Public/Dist/ByMaintainer.html
@@ -2,7 +2,7 @@
 %#
 %# COPYRIGHT:
 %#
-%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
 %#                                          <sales at bestpractical.com>
 %#
 %# (Except where explicitly superseded by other copyright notices)
diff --git a/html/Public/Dist/Display.html b/html/Public/Dist/Display.html
index 808c67c..d9fc932 100755
--- a/html/Public/Dist/Display.html
+++ b/html/Public/Dist/Display.html
@@ -2,7 +2,7 @@
 %#
 %# COPYRIGHT:
 %#
-%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
 %#                                          <sales at bestpractical.com>
 %#
 %# (Except where explicitly superseded by other copyright notices)
diff --git a/html/Public/Dist/bugs.tsv b/html/Public/Dist/bugs.tsv
index 62c0c6a..e585f89 100755
--- a/html/Public/Dist/bugs.tsv
+++ b/html/Public/Dist/bugs.tsv
@@ -2,7 +2,7 @@
 %#
 %# COPYRIGHT:
 %#
-%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
 %#                                          <sales at bestpractical.com>
 %#
 %# (Except where explicitly superseded by other copyright notices)
diff --git a/html/Public/Elements/DistributionList b/html/Public/Elements/DistributionList
index 3888b86..108e2ff 100644
--- a/html/Public/Elements/DistributionList
+++ b/html/Public/Elements/DistributionList
@@ -2,7 +2,7 @@
 %#
 %# COPYRIGHT:
 %#
-%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
 %#                                          <sales at bestpractical.com>
 %#
 %# (Except where explicitly superseded by other copyright notices)
diff --git a/html/Public/Elements/ErrorNoDist b/html/Public/Elements/ErrorNoDist
index 650ea29..dcad339 100644
--- a/html/Public/Elements/ErrorNoDist
+++ b/html/Public/Elements/ErrorNoDist
@@ -2,7 +2,7 @@
 %#
 %# COPYRIGHT:
 %#
-%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
 %#                                          <sales at bestpractical.com>
 %#
 %# (Except where explicitly superseded by other copyright notices)
diff --git a/html/Public/Elements/ErrorNoUser b/html/Public/Elements/ErrorNoUser
index b41826d..8c94954 100644
--- a/html/Public/Elements/ErrorNoUser
+++ b/html/Public/Elements/ErrorNoUser
@@ -2,7 +2,7 @@
 %#
 %# COPYRIGHT:
 %#
-%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
 %#                                          <sales at bestpractical.com>
 %#
 %# (Except where explicitly superseded by other copyright notices)
diff --git a/html/Public/Elements/Tabs b/html/Public/Elements/Tabs
index 6faac4c..b122cf1 100755
--- a/html/Public/Elements/Tabs
+++ b/html/Public/Elements/Tabs
@@ -2,7 +2,7 @@
 %#
 %# COPYRIGHT:
 %#
-%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
 %#                                          <sales at bestpractical.com>
 %#
 %# (Except where explicitly superseded by other copyright notices)
diff --git a/html/Public/Search/Results.html b/html/Public/Search/Results.html
index bcbd9a8..525e922 100644
--- a/html/Public/Search/Results.html
+++ b/html/Public/Search/Results.html
@@ -2,7 +2,7 @@
 %#
 %# COPYRIGHT:
 %#
-%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
 %#                                          <sales at bestpractical.com>
 %#
 %# (Except where explicitly superseded by other copyright notices)
diff --git a/html/Public/Search/Simple.html b/html/Public/Search/Simple.html
index 1180fad..3d3203a 100644
--- a/html/Public/Search/Simple.html
+++ b/html/Public/Search/Simple.html
@@ -2,7 +2,7 @@
 %#
 %# COPYRIGHT:
 %#
-%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
 %#                                          <sales at bestpractical.com>
 %#
 %# (Except where explicitly superseded by other copyright notices)
diff --git a/html/Public/Ticket/Attachment/WithHeaders/dhandler b/html/Public/Ticket/Attachment/WithHeaders/dhandler
index 2ebe24a..d8e1f45 100644
--- a/html/Public/Ticket/Attachment/WithHeaders/dhandler
+++ b/html/Public/Ticket/Attachment/WithHeaders/dhandler
@@ -2,7 +2,7 @@
 %#
 %# COPYRIGHT:
 %#
-%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
 %#                                          <sales at bestpractical.com>
 %#
 %# (Except where explicitly superseded by other copyright notices)
diff --git a/html/Public/Ticket/Attachment/dhandler b/html/Public/Ticket/Attachment/dhandler
index 917916e..dcc6111 100644
--- a/html/Public/Ticket/Attachment/dhandler
+++ b/html/Public/Ticket/Attachment/dhandler
@@ -2,7 +2,7 @@
 %#
 %# COPYRIGHT:
 %#
-%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
 %#                                          <sales at bestpractical.com>
 %#
 %# (Except where explicitly superseded by other copyright notices)
diff --git a/html/Public/autohandler b/html/Public/autohandler
index 07e03ae..01dd567 100644
--- a/html/Public/autohandler
+++ b/html/Public/autohandler
@@ -2,7 +2,7 @@
 %#
 %# COPYRIGHT:
 %#
-%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
 %#                                          <sales at bestpractical.com>
 %#
 %# (Except where explicitly superseded by other copyright notices)
diff --git a/html/Public/index.html b/html/Public/index.html
index 228a773..006dd6f 100755
--- a/html/Public/index.html
+++ b/html/Public/index.html
@@ -2,7 +2,7 @@
 %#
 %# COPYRIGHT:
 %#
-%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
 %#                                          <sales at bestpractical.com>
 %#
 %# (Except where explicitly superseded by other copyright notices)
diff --git a/lib/RT/BugTracker/Public.pm b/lib/RT/BugTracker/Public.pm
index 1857ddb..7fdaada 100644
--- a/lib/RT/BugTracker/Public.pm
+++ b/lib/RT/BugTracker/Public.pm
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
 #                                          <sales at bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -195,7 +195,7 @@ or via the web at
 
 =head1 LICENSE AND COPYRIGHT
 
-This software is Copyright (c) 2014 by Best Practical Solutions
+This software is Copyright (c) 2017 by Best Practical Solutions
 
 This is free software, licensed under:
 

commit ec6ef0c017442cd47854fef723a50c4308fe0d21
Author: Brian C. Duggan <brian at bestpractical.com>
Date:   Thu Feb 23 15:09:07 2017 -0500

    Update Makefile and POD for 4.2 and 4.4
    
    The subsequent changes in this branch break compatibility with RT
    <=4.0. The required version in Makefile.PL reflects this. POD includes
    configuration instructions for >=4.2, only.
    
    This change sets RT too new to 4.6.

diff --git a/Makefile.PL b/Makefile.PL
index e9d76fa..937f700 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -2,8 +2,8 @@ use inc::Module::Install;
 
 RTx('RT-BugTracker-Public');
 
-requires_rt('4.0.0');
-rt_too_new('4.2.0');
+requires_rt('4.2.0');
+rt_too_new('4.6.0');
 
 sign();
 WriteAll();
diff --git a/lib/RT/BugTracker/Public.pm b/lib/RT/BugTracker/Public.pm
index 7fdaada..f51895f 100644
--- a/lib/RT/BugTracker/Public.pm
+++ b/lib/RT/BugTracker/Public.pm
@@ -78,9 +78,7 @@ May need root permissions
 
 Add this line:
 
-    Set(@Plugins, qw(RT::BugTracker::Public));
-
-or add C<RT::BugTracker::Public> to your existing C<@Plugins> line.
+    Plugin('RT::BugTracker::Public');
 
 =item Clear your mason cache
 

commit c903ba961307e5f187c78ab46f7990cfe0b0f9ce
Author: Brian C. Duggan <brian at bestpractical.com>
Date:   Thu Feb 23 16:16:33 2017 -0500

    Enable optional public bug reporting through web UI
    
    Add the WebPublicUserReporting config variable, initialized to 0.
    
    When set, this variable allows the WebPublicUser to create bugs
    through the web UI.

diff --git a/etc/RT_SiteConfig.pm b/etc/RT_SiteConfig.pm
index 3fae53c..67f690e 100644
--- a/etc/RT_SiteConfig.pm
+++ b/etc/RT_SiteConfig.pm
@@ -1,4 +1,4 @@
 # Read more about options in lib/RT/BugTracker/Public.pm
 
 Set($WebPublicUser, 'public');
-
+Set($WebPublicUserReporting, 0);
diff --git a/html/Public/Bug/Report.html b/html/Public/Bug/Report.html
index b24f54b..5ca0411 100755
--- a/html/Public/Bug/Report.html
+++ b/html/Public/Bug/Report.html
@@ -81,7 +81,7 @@ public and indexed by search engines.
 <& /Dist/Elements/ShowBugtracker, Queue => $QueueObj &>
 <& /Dist/Elements/ShowNotes, Queue => $QueueObj &>
 
-% if ( $session{'CurrentUser'}->Name eq $RT::WebPublicUser ) {
+% if ( $session{'CurrentUser'}->Name eq $RT::WebPublicUser && !RT->Config->Get("WebPublicUserReporting") ) {
 
 <p style="font-weight: bold">
   The quickest way to report a bug in <% $QueueObj->Name %> is by sending email to
diff --git a/lib/RT/BugTracker/Public.pm b/lib/RT/BugTracker/Public.pm
index f51895f..57ff637 100644
--- a/lib/RT/BugTracker/Public.pm
+++ b/lib/RT/BugTracker/Public.pm
@@ -115,6 +115,13 @@ The public user should probably be unprivileged and have the following rights
 If you want the public UI to do anything useful. It should NOT have the
 ModifySelf right.
 
+=head2 WebPublicUserReporting
+
+By default, the web public user cannot create bug reports through the
+web UI. To allow this, add this line:
+
+    Set($WebPublicUserReporting, 1);
+
 =cut
 
 sub IsPublicUser {

commit 618af1ee2d8da7cee04b98c71e169205ba593295
Author: Brian C. Duggan <brian at bestpractical.com>
Date:   Thu Feb 23 15:23:51 2017 -0500

    Remove trailing whitespace in html/Public/Bug/Display.html

diff --git a/html/Public/Bug/Display.html b/html/Public/Bug/Display.html
index 545ae85..182d282 100755
--- a/html/Public/Bug/Display.html
+++ b/html/Public/Bug/Display.html
@@ -45,7 +45,7 @@
 %# those contributions and any derivatives thereof.
 %#
 %# END BPS TAGGED BLOCK }}}
-<& /Elements/Header, 
+<& /Elements/Header,
     Title => $title &>
 <& /Elements/Tabs &>
 
@@ -93,12 +93,12 @@ unless ($id || $TicketObj) {
 
 if ($ARGS{'id'} eq 'new') {
     # {{{ Create a new ticket
-    
-    my $Queue = new RT::Queue($session{'CurrentUser'});	
+
+    my $Queue = new RT::Queue($session{'CurrentUser'});
     unless ($Queue->Load($ARGS{'Queue'})) {
 	Abort('Queue not found');
     }
-    
+
     unless ($Queue->CurrentUserHasRight('CreateTicket')) {
 	Abort('You have no permission to create tickets in that queue.');
     }
@@ -109,7 +109,7 @@ if ($ARGS{'id'} eq 'new') {
 	Abort("No permission to view newly created ticket #".$TicketObj->id.".");
 	}
     # }}}
-} else { 
+} else {
     if (!$TicketObj) {
 
 	$TicketObj = RT::Ticket->new($session{'CurrentUser'});
@@ -130,7 +130,7 @@ if ($ARGS{'id'} eq 'new') {
 
     $ARGS{'UpdateContent'} =~ s/\r\n/\n/g if defined $ARGS{'UpdateContent'};
     if ( $ARGS{'UpdateTimeWorked'} ||
-	 $session{'Attachments'} || 
+	 $session{'Attachments'} ||
 	 (   defined $ARGS{'UpdateContent'}
              && $ARGS{'UpdateContent'} ne ''
 	     && $ARGS{'UpdateContent'} ne "-- \n"
@@ -148,13 +148,13 @@ if ($ARGS{'id'} eq 'new') {
     push (@Actions, @BasicActions, @results);
 }
 
-# This code does automatic redirection if any updates happen. 
+# This code does automatic redirection if any updates happen.
 # It doesn't work for the client.
 
 
 
 if (@Actions) {
-    # We've done something, so we need to clear the decks to avoid 
+    # We've done something, so we need to clear the decks to avoid
     # resubmission on refresh.
     # But we need to store Actions somewhere too, so we don't lose them.
     $session{"Actions"} = \@Actions;
@@ -206,7 +206,7 @@ sub _UpdateMessage {
 
         my $Message = MakeMIMEEntity(%mime);
 
-        $Message->head->add( 'Message-ID' => 
+        $Message->head->add( 'Message-ID' =>
               "<rt-"
               . $RT::VERSION . "-"
               . $$ . "-"
@@ -226,10 +226,10 @@ sub _UpdateMessage {
         }
 
         if ( $old_txn->Message && $old_txn->Message->First ) {
-            my @in_reply_to = split(/\s+/m, $old_txn->Message->First->GetHeader('In-Reply-To') || '');  
-            my @references = split(/\s+/m, $old_txn->Message->First->GetHeader('References') || '' );  
-            my @msgid = split(/\s+/m,$old_txn->Message->First->GetHeader('Message-ID') || ''); 
-            my @rtmsgid = split(/\s+/m,$old_txn->Message->First->GetHeader('RT-Message-ID') || ''); 
+            my @in_reply_to = split(/\s+/m, $old_txn->Message->First->GetHeader('In-Reply-To') || '');
+            my @references = split(/\s+/m, $old_txn->Message->First->GetHeader('References') || '' );
+            my @msgid = split(/\s+/m,$old_txn->Message->First->GetHeader('Message-ID') || '');
+            my @rtmsgid = split(/\s+/m,$old_txn->Message->First->GetHeader('RT-Message-ID') || '');
 
             $Message->head->replace( 'In-Reply-To', join (' ', @rtmsgid ? @rtmsgid : @msgid));
             $Message->head->replace( 'References', join(' ', @references, @msgid, @rtmsgid));

commit 13e7c169b5587d42a848a4c00f521219d08f25ec
Author: Brian C. Duggan <brian at bestpractical.com>
Date:   Thu Feb 23 15:24:59 2017 -0500

    Move CSS and JS from html/NoAuth to static

diff --git a/html/NoAuth/css/bugtracker-public.css b/html/NoAuth/css/bugtracker-public.css
deleted file mode 100644
index f5f529d..0000000
--- a/html/NoAuth/css/bugtracker-public.css
+++ /dev/null
@@ -1,79 +0,0 @@
-%# BEGIN BPS TAGGED BLOCK {{{
-%#
-%# COPYRIGHT:
-%#
-%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
-%#                                          <sales at bestpractical.com>
-%#
-%# (Except where explicitly superseded by other copyright notices)
-%#
-%#
-%# LICENSE:
-%#
-%# This work is made available to you under the terms of Version 2 of
-%# the GNU General Public License. A copy of that license should have
-%# been provided with this software, but in any event can be snarfed
-%# from www.gnu.org.
-%#
-%# This work is distributed in the hope that it will be useful, but
-%# WITHOUT ANY WARRANTY; without even the implied warranty of
-%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-%# General Public License for more details.
-%#
-%# You should have received a copy of the GNU General Public License
-%# along with this program; if not, write to the Free Software
-%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-%# 02110-1301 or visit their web page on the internet at
-%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
-%#
-%#
-%# CONTRIBUTION SUBMISSION POLICY:
-%#
-%# (The following paragraph is not intended to limit the rights granted
-%# to you to modify and distribute this software under the terms of
-%# the GNU General Public License and is only of importance to you if
-%# you choose to contribute your changes and enhancements to the
-%# community by submitting them to Best Practical Solutions, LLC.)
-%#
-%# By intentionally submitting any modifications, corrections or
-%# derivatives to this work, or any other work intended for use with
-%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
-%# you are the copyright holder for those contributions and you grant
-%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
-%# royalty-free, perpetual, license to use, copy, create derivative
-%# works based on those contributions, and sublicense and distribute
-%# those contributions and any derivatives thereof.
-%#
-%# END BPS TAGGED BLOCK }}}
-/* Similar to core RT's "sidebyside" styles */
-
-#reporting-a-bug {
-    float: right;
-    width: 58%;
-    clear: right;
-}
-
-.reporting-a-bug-instructions {
-    float: left;
-    width: 40%;
-    clear: left;
-}
-
- at media (max-width: 950px) {
-    /* Revert to a single column when we're less than 1000px wide */
-    #reporting-a-bug, .reporting-a-bug-instructions {
-        float: none;
-        width: auto;
-        clear: both;
-    }
-}
-
-#reporting-a-bug .edit-custom-field {
-    /* we're in a thinner column most of the time, make room for the default margin */
-    width: 45%;
-}
-
-#reporting-a-bug .edit-custom-field:first-child {
-    display: block;
-    float: none;
-}
diff --git a/html/NoAuth/js/bugtracker-public.js b/html/NoAuth/js/bugtracker-public.js
deleted file mode 100644
index 98cd4f7..0000000
--- a/html/NoAuth/js/bugtracker-public.js
+++ /dev/null
@@ -1,55 +0,0 @@
-%# BEGIN BPS TAGGED BLOCK {{{
-%#
-%# COPYRIGHT:
-%#
-%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
-%#                                          <sales at bestpractical.com>
-%#
-%# (Except where explicitly superseded by other copyright notices)
-%#
-%#
-%# LICENSE:
-%#
-%# This work is made available to you under the terms of Version 2 of
-%# the GNU General Public License. A copy of that license should have
-%# been provided with this software, but in any event can be snarfed
-%# from www.gnu.org.
-%#
-%# This work is distributed in the hope that it will be useful, but
-%# WITHOUT ANY WARRANTY; without even the implied warranty of
-%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-%# General Public License for more details.
-%#
-%# You should have received a copy of the GNU General Public License
-%# along with this program; if not, write to the Free Software
-%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-%# 02110-1301 or visit their web page on the internet at
-%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
-%#
-%#
-%# CONTRIBUTION SUBMISSION POLICY:
-%#
-%# (The following paragraph is not intended to limit the rights granted
-%# to you to modify and distribute this software under the terms of
-%# the GNU General Public License and is only of importance to you if
-%# you choose to contribute your changes and enhancements to the
-%# community by submitting them to Best Practical Solutions, LLC.)
-%#
-%# By intentionally submitting any modifications, corrections or
-%# derivatives to this work, or any other work intended for use with
-%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
-%# you are the copyright holder for those contributions and you grant
-%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
-%# royalty-free, perpetual, license to use, copy, create derivative
-%# works based on those contributions, and sublicense and distribute
-%# those contributions and any derivatives thereof.
-%#
-%# END BPS TAGGED BLOCK }}}
-jQuery(function() {
-    jQuery("a[data-bug-email]").each(function() {
-        var a = jQuery(this);
-        a.attr("href", "mailto:bug-"
-                       + encodeURIComponent(a.attr("data-bug-email"))
-                       + "@rt.cpan.org");
-    });
-});
diff --git a/static/css/bugtracker-public.css b/static/css/bugtracker-public.css
new file mode 100644
index 0000000..3962274
--- /dev/null
+++ b/static/css/bugtracker-public.css
@@ -0,0 +1,32 @@
+/* Similar to core RT's "sidebyside" styles */
+
+#reporting-a-bug {
+    float: right;
+    width: 58%;
+    clear: right;
+}
+
+.reporting-a-bug-instructions {
+    float: left;
+    width: 40%;
+    clear: left;
+}
+
+ at media (max-width: 950px) {
+    /* Revert to a single column when we're less than 1000px wide */
+    #reporting-a-bug, .reporting-a-bug-instructions {
+        float: none;
+        width: auto;
+        clear: both;
+    }
+}
+
+#reporting-a-bug .edit-custom-field {
+    /* we're in a thinner column most of the time, make room for the default margin */
+    width: 45%;
+}
+
+#reporting-a-bug .edit-custom-field:first-child {
+    display: block;
+    float: none;
+}
diff --git a/static/js/bugtracker-public.js b/static/js/bugtracker-public.js
new file mode 100644
index 0000000..93ab5a7
--- /dev/null
+++ b/static/js/bugtracker-public.js
@@ -0,0 +1,8 @@
+jQuery(function() {
+    jQuery("a[data-bug-email]").each(function() {
+        var a = jQuery(this);
+        a.attr("href", "mailto:bug-"
+                       + encodeURIComponent(a.attr("data-bug-email"))
+                       + "@rt.cpan.org");
+    });
+});

commit ec9e02f563cc465070a8ff60b4b276ba03b8bf9b
Author: Brian C. Duggan <brian at bestpractical.com>
Date:   Thu Feb 23 23:44:40 2017 -0500

    Use WebDomain instead of hardcoded rt.cpan.org
    
    RT::BugTracker and RT::BugTracker::Public both hardcode 'rt.cpan.org'
    in several places. This change replaces it with the value of the RT
    config variable, WebDomain.

diff --git a/html/Public/Bug/Report.html b/html/Public/Bug/Report.html
index 5ca0411..c2309e5 100755
--- a/html/Public/Bug/Report.html
+++ b/html/Public/Bug/Report.html
@@ -85,7 +85,7 @@ public and indexed by search engines.
 
 <p style="font-weight: bold">
   The quickest way to report a bug in <% $QueueObj->Name %> is by sending email to
-  <a style="font-size: 1.2em" href="#" data-bug-email="<% $QueueObj->Name %>">bug-<% $QueueObj->Name %> <i>[at]</i> rt.cpan.org</a>.
+  <a style="font-size: 1.2em" href="#" data-bug-email="<% $QueueObj->Name %>">bug-<% $QueueObj->Name %> <i>[at]</i> <% RT->Config->Get("WebDomain") %></a>.
 </p>
 
 <p>
diff --git a/static/js/bugtracker-public.js b/static/js/bugtracker-public.js
index 93ab5a7..427e7d8 100644
--- a/static/js/bugtracker-public.js
+++ b/static/js/bugtracker-public.js
@@ -3,6 +3,6 @@ jQuery(function() {
         var a = jQuery(this);
         a.attr("href", "mailto:bug-"
                        + encodeURIComponent(a.attr("data-bug-email"))
-                       + "@rt.cpan.org");
+                       + "@" + RT.Config.WebDomain);
     });
 });

commit fabb4c9a9eac5f9fe00beacb398c021c60960013
Author: Brian C. Duggan <brian at bestpractical.com>
Date:   Fri Feb 24 09:09:18 2017 -0500

    Fix Ticket CF editing in public bug report page
    
    Updated use of /Elements/EditCustomFields in /Public/Bug/Report.html
    to mirror use in /Ticket/Create.html. Pass TicketObj instead of
    QueueObj.

diff --git a/html/Public/Bug/Report.html b/html/Public/Bug/Report.html
index c2309e5..72fc71b 100755
--- a/html/Public/Bug/Report.html
+++ b/html/Public/Bug/Report.html
@@ -96,7 +96,7 @@ public and indexed by search engines.
 </p>
 
 % } else {
-<form action="<%$RT::WebPath%>/Public/Bug/Report.html" method="POST" enctype="multipart/form-data" name="TicketCreate">
+<form action="<% RT->Config->Get('WebPath') %>/Public/Bug/Report.html" method="POST" enctype="multipart/form-data" name="TicketCreate">
 <input type="hidden" class="hidden" name="id" value="new" />
 <input type="hidden" class="hidden" name="Status" value="new" />
 <div id="Ticket-Create-basics">
@@ -124,7 +124,12 @@ public and indexed by search engines.
 </tr>
 <tr>
 <td colspan="6">
-<& /Ticket/Elements/EditCustomFields, QueueObj => $QueueObj &>
+  <& /Elements/EditCustomFields,
+     Object => $ticket,
+     CustomFields => $CFs,
+     InTable => 1,
+     KeepValue => 1,
+  &>
 </td>
 </tr>
 % if ($TxnCFs->Count) {
@@ -204,9 +209,11 @@ Other things that are often helpful:
 </div>
 
 <%INIT>
+my $current_user = $session{'CurrentUser'};
+
 $Queue =~ s/::/-/g;
 
-my $QueueObj = new RT::Queue($session{'CurrentUser'});
+my $QueueObj = RT::Queue->new($current_user);
 $QueueObj->Load($Queue);
 
 if (not $QueueObj->Id) {
@@ -223,6 +230,8 @@ my $ValidCFs = $m->comp(
     ARGSRef => \%ARGS
 );
 
+my $ticket = RT::Ticket->new($current_user); # empty ticket object
+
 # if no due date has been set explicitly, then use the
 # queue's default if it exists
 if ($QueueObj->DefaultDueIn && !$ARGS{'Due'}) {

commit 5218a0a3610e87253a8ea5a26993af9a68f7c82d
Author: Brian C. Duggan <brian at bestpractical.com>
Date:   Fri Feb 24 12:27:49 2017 -0500

    Use DistributionToQueueRegex instead of perl-specific substitution
    
    Replace instances of the perl-module-specific substitution regex,
    s/::/-/g, with a substitution regex constructed from the new
    DistributionToQueueRegex config variable in RT::BugTracker.

diff --git a/html/Public/Bug/Report.html b/html/Public/Bug/Report.html
index 72fc71b..55c3e7f 100755
--- a/html/Public/Bug/Report.html
+++ b/html/Public/Bug/Report.html
@@ -211,7 +211,8 @@ Other things that are often helpful:
 <%INIT>
 my $current_user = $session{'CurrentUser'};
 
-$Queue =~ s/::/-/g;
+my %NameRegex = RT->Config->Get("DistributionToQueueRegex");
+$Queue =~ s/$NameRegex{Pattern}/$NameRegex{Substitution}/g;
 
 my $QueueObj = RT::Queue->new($current_user);
 $QueueObj->Load($Queue);
diff --git a/html/Public/Dist/Display.html b/html/Public/Dist/Display.html
index d9fc932..ea5342e 100755
--- a/html/Public/Dist/Display.html
+++ b/html/Public/Dist/Display.html
@@ -67,7 +67,8 @@
 
 <%INIT>
 $Name = $Queue unless $Name;
-$Name =~ s/::/-/g;
+my %NameRegex = RT->Config->Get("DistributionToQueueRegex");
+$Name =~ s/$NameRegex{Pattern}/$NameRegex{Substitution}/g;
 my $QueueObj = RT::Queue->new( $session{CurrentUser} );
 $QueueObj->Load( $Name );
 unless ( $QueueObj->id ) {
diff --git a/html/Public/Dist/bugs.tsv b/html/Public/Dist/bugs.tsv
index e585f89..9f5d947 100755
--- a/html/Public/Dist/bugs.tsv
+++ b/html/Public/Dist/bugs.tsv
@@ -50,7 +50,8 @@
 % }
 % $m->abort();
 <%INIT>
-$Dist =~ s/::/-/g;
+my %NameRegex = RT->Config->Get("DistributionToQueueRegex");
+$Dist =~ s/$NameRegex{Pattern}/$NameRegex{Substitution}/g;
 
 $r->content_type('text/plain');
 
diff --git a/html/Public/index.html b/html/Public/index.html
index 006dd6f..2c81f2b 100755
--- a/html/Public/index.html
+++ b/html/Public/index.html
@@ -105,7 +105,8 @@ if ( defined $Maintainer && length $Maintainer ) {
 
 if ( defined $Distribution && length $Distribution ) {
     my $queue = RT::Queue->new( $session{'CurrentUser'} );
-    $Distribution =~ s/::/-/g;
+    my %NameRegex = RT->Config->Get("DistributionToQueueRegex");
+    $Distribution =~ s/$NameRegex{Pattern}/$NameRegex{Substitution}/g;
     $queue->Load( $Distribution );
     unless ( $queue->id ) {
         push @results, loc("No distribution '[_1]' in the system", $Distribution);

commit f30ab832dae496d8083e79f06652e41beaba53c5
Author: Brian C. Duggan <brian at bestpractical.com>
Date:   Thu Feb 23 15:13:32 2017 -0500

    Update deprecated templates and functions
    
    html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged:
    Use LifecycleObj instead of Lifecycle
    
    html/Public/Bug/Display.html:
    Use /Elements/ShowHistory instead of /Ticket/ElementsShowHistory
    Use $TicketObj->Attachments instead of /Ticket/Elements/FindAttachments
    Use $TicketObj->TextAttachments instead of /Ticket/Elements/LoadTextAttachments
    
    html/Public/Bug/Report.html:
    Use /Elements/EditCustomFields instead of /Ticket/Elements/EditCustomFields
    Use RT::QueueObj::DefaultValue('Due') in >4.2, RT::QueueObj::DefaultDueIn in <=4.2
    
    Pass "Timezone => 'user' to $default_due->ISO. Fixes latent bug in
    Default Due for calculation for 4.2 where Due was set to UTC instead
    of server local.

diff --git a/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged b/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged
index 7fd8e02..bcb704d 100644
--- a/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged
+++ b/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged
@@ -138,7 +138,7 @@ if ( $queue and $queue->id ) {
     );
 
     if ($ticket and $ticket->id
-        and $queue->Lifecycle->IsInactive($ticket->Status)
+        and $queue->LifecycleObj->IsInactive($ticket->Status)
         and $ticket->CurrentUserHasRight("OpenTicket")) {
 
         PageMenu->child(
diff --git a/html/Public/Bug/Display.html b/html/Public/Bug/Display.html
index 182d282..fc8e8d5 100755
--- a/html/Public/Bug/Display.html
+++ b/html/Public/Bug/Display.html
@@ -62,17 +62,13 @@
 
 % $m->callback(%ARGS, CallbackName => 'BeforeShowHistory', Ticket => $TicketObj);
 
-<& /Ticket/Elements/ShowHistory , 
-      Ticket => $TicketObj, 
-      Tickets => $Tickets, 
-      Collapsed => $ARGS{'Collapsed'}, 
+<& /Elements/ShowHistory ,
+      Object => $TicketObj,
+      Transactions => $TicketObj->Transactions,
       ShowHeaders => $ARGS{'ShowHeaders'},
       Attachments => $attachments,
-      AttachmentContent => $attachment_content,
-      URIFile     => RT->Config->Get('WebPath') . '/Public/Bug/Display.html',
-      DisplayPath => RT->Config->Get('WebPath') . '/Public/Bug/Display.html?id='. $TicketObj->id,
-      UpdatePath  => RT->Config->Get('WebPath') . '/Public/Bug/Update.html',
-&> 
+      AttachmentContent => $attachment_content
+&>
 
 <%ARGS>
 $id => undef
@@ -166,9 +162,8 @@ if (@Actions) {
 $m->callback(CallbackName => 'BeforeDisplay',
 	 TicketObj => \$TicketObj, Tickets => \$Tickets, ARGSRef => \%ARGS);
 
-
-my $attachments = $m->comp('/Ticket/Elements/FindAttachments', Ticket => $TicketObj, Tickets => $Tickets);
-my $attachment_content = $m->comp('/Ticket/Elements/LoadTextAttachments', Ticket => $TicketObj);
+my $attachments = $TicketObj->Attachments;
+my $attachment_content = $TicketObj->TextAttachments;
 
 my $title = loc(
     "Bug #[_1] for [_2]: [_3]",
diff --git a/html/Public/Bug/Report.html b/html/Public/Bug/Report.html
index 55c3e7f..535581a 100755
--- a/html/Public/Bug/Report.html
+++ b/html/Public/Bug/Report.html
@@ -235,11 +235,12 @@ my $ticket = RT::Ticket->new($current_user); # empty ticket object
 
 # if no due date has been set explicitly, then use the
 # queue's default if it exists
-if ($QueueObj->DefaultDueIn && !$ARGS{'Due'}) {
+if ($RT::MAJOR_VERSION <= 4 && $RT::MINOR_VERSION <= 2
+    && $QueueObj->DefaultDueIn && !$ARGS{'Due'}) {
     my $default_due = RT::Date->new($session{'CurrentUser'});
     $default_due->SetToNow();
     $default_due->AddDays($QueueObj->DefaultDueIn);
-    $ARGS{'Due'} = $default_due->ISO();
+    $ARGS{'Due'} = $default_due->ISO(Timezone => 'user');
 }
 
 # {{{ deal with deleting uploaded attachments

commit f4404d95883a7772f380bd83440057aba165207b
Author: Brian C. Duggan <brian at bestpractical.com>
Date:   Wed Mar 8 14:19:20 2017 -0500

    Add functionality and configuration documentation.
    
    Describe general RT::BugTracker::Public functionality.
    Correct and clarify existing WebPublicUser documentation.

diff --git a/lib/RT/BugTracker/Public.pm b/lib/RT/BugTracker/Public.pm
index 57ff637..9643e8b 100644
--- a/lib/RT/BugTracker/Public.pm
+++ b/lib/RT/BugTracker/Public.pm
@@ -60,7 +60,33 @@ RT->AddStyleSheets("bugtracker-public.css");
 
 =head1 NAME
 
-RT::BugTracker::Public - Adds a public, (hopefully) userfriendly bug tracking UI to RT
+RT::BugTracker::Public - Adds a public, user-friendly bug tracking and
+reporting UI to RT
+
+=head1 DESCRIPTION
+
+RT::BugTracker::Public depends on RT::BugTracker.
+
+RT::BugTracker::Public depends on RT::Authen::Bitcard and
+Authen::Bitcard for external authentication through Bitcard.
+
+NB: External authentication through Bitcard is broken in RT 4.2 and
+4.4. The authors may eventually deprecate this functionality.
+
+This extension adds a public interface for searching and reporting
+bugs through an RT with RT::BugTracker installed. The public reporting
+UI is disabled, by default.
+
+The public interface entrypoint is on the RT login page. Click the
+C<public interface> link to access the public bug search page. The
+public search functionality is identical to the private interface in
+RT::BugTracker.
+
+To enable public bug reporting, follow the documentation for
+C<WebPublicUserReporting>, in the C<CONFIGURATION> section, below. To
+report bugs, public users must create a new ticket using the C<New
+ticket in> button, or click C<Report a new bug> from the bug list page
+for a distribution.
 
 =head1 INSTALLATION
 
@@ -96,24 +122,29 @@ define options there.
 
 =head2 WebPublicUser
 
-Make sure to create the public user in your RT system and add the line below
-to your F<RT_SiteConfig.pm>.
+Create the public user in your RT system through F<Admin \> Users \>
+Create> in RT. The public user must be able to access RT, and it must
+be privileged so it can have rights. Do not enter an email address for
+the public user.
 
-    Set( $WebPublicUser, 'guest' );
+Add the line below to F<RT_SiteConfig.pm> and replace 'guest' with the
+name of the RT user you just created.
 
-If you didn't name your public user 'guest', then change accordingly.
+    Set( $WebPublicUser, 'guest' );
 
-The public user should probably be unprivileged and have the following rights
+The public user needs the following rights on public distribution
+queues to search bugs:
 
-    CreateTicket
-    ModifyCustomField
-    ReplyToTicket
     SeeCustomField
     SeeQueue
     ShowTicket
 
-If you want the public UI to do anything useful. It should NOT have the
-ModifySelf right.
+The pubic user needs the following rights on public distribution
+queues to report bugs:
+
+    CreateTicket
+    ModifyCustomField
+    ReplyToTicket
 
 =head2 WebPublicUserReporting
 

commit ab5c6a137e91574a22159f0150dbc367706cc2bc
Author: Brian C. Duggan <brian at bestpractical.com>
Date:   Tue Feb 28 15:19:34 2017 -0500

    Update distribution files
    
    Update distribution files without signing

diff --git a/Changes b/Changes
index 3387741..bec7942 100644
--- a/Changes
+++ b/Changes
@@ -1,3 +1,7 @@
+1.06 2017-02-28
+ - RT 4.2 and 4.4 compatibility
+ - Drop 4.0 compatibility
+
 1.05 2016-07-19
  - Packaging updates
  - Whitelist all query endpoints from CSRF protection
diff --git a/MANIFEST b/MANIFEST
index 40c120d..8539a23 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -10,8 +10,6 @@ html/Callbacks/BugTracker-Public/NoAuth/Logout.html/Default
 html/Callbacks/BugTracker-Public/Search/Results.html/Initial
 html/Callbacks/BugTracker-Public/Ticket/Elements/ShowMessageHeaders/Default
 html/Elements/ShowUserPublic
-html/NoAuth/css/bugtracker-public.css
-html/NoAuth/js/bugtracker-public.js
 html/Public/autohandler
 html/Public/Browse.html
 html/Public/Bug/Display.html
@@ -50,3 +48,5 @@ Makefile.PL
 MANIFEST			This list of files
 META.yml
 README
+static/css/bugtracker-public.css
+static/js/bugtracker-public.js
diff --git a/META.yml b/META.yml
index dd4d8c7..e6d3212 100644
--- a/META.yml
+++ b/META.yml
@@ -1,5 +1,5 @@
 ---
-abstract: 'Adds a public, (hopefully) userfriendly bug tracking UI to RT'
+abstract: 'Adds a public, user-friendly bug tracking and reporting UI to RT'
 author:
   - 'Best Practical Solutions, LLC <modules at bestpractical.com>'
 build_requires:
@@ -8,7 +8,7 @@ configure_requires:
   ExtUtils::MakeMaker: 6.59
 distribution_type: module
 dynamic_config: 1
-generated_by: 'Module::Install version 1.16'
+generated_by: 'Module::Install version 1.17'
 license: gpl
 meta-spec:
   url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -19,11 +19,12 @@ no_index:
     - etc
     - html
     - inc
+    - static
 requires:
-  perl: 5.8.3
+  perl: 5.10.1
 resources:
   license: http://opensource.org/licenses/gpl-license.php
-version: '1.05'
+version: '1.06'
 x_module_install_rtx_version: '0.38'
-x_requires_rt: 4.0.0
-x_rt_too_new: 4.2.0
+x_requires_rt: 4.2.0
+x_rt_too_new: 4.6.0
diff --git a/README b/README
index 8437711..755a974 100644
--- a/README
+++ b/README
@@ -1,6 +1,30 @@
 NAME
-    RT::BugTracker::Public - Adds a public, (hopefully) userfriendly bug
-    tracking UI to RT
+    RT::BugTracker::Public - Adds a public, user-friendly bug tracking and
+    reporting UI to RT
+
+DESCRIPTION
+    RT::BugTracker::Public depends on RT::BugTracker.
+
+    RT::BugTracker::Public depends on RT::Authen::Bitcard and
+    Authen::Bitcard for external authentication through Bitcard.
+
+    NB: External authentication through Bitcard is broken in RT 4.2 and 4.4.
+    The authors may eventually deprecate this functionality.
+
+    This extension adds a public interface for searching and reporting bugs
+    through an RT with RT::BugTracker installed. The public reporting UI is
+    disabled, by default.
+
+    The public interface entrypoint is on the RT login page. Click the
+    public interface link to access the public bug search page. The public
+    search functionality is identical to the private interface in
+    RT::BugTracker.
+
+    To enable public bug reporting, follow the documentation for
+    WebPublicUserReporting, in the CONFIGURATION section, below. To report
+    bugs, public users must create a new ticket using the New ticket in
+    button, or click Report a new bug from the bug list page for a
+    distribution.
 
 INSTALLATION
     perl Makefile.PL
@@ -11,9 +35,7 @@ INSTALLATION
     Edit your /opt/rt4/etc/RT_SiteConfig.pm
         Add this line:
 
-            Set(@Plugins, qw(RT::BugTracker::Public));
-
-        or add RT::BugTracker::Public to your existing @Plugins line.
+            Plugin('RT::BugTracker::Public');
 
     Clear your mason cache
             rm -rf /opt/rt4/var/mason_data/obj
@@ -26,25 +48,35 @@ CONFIGURATION
     RT_SiteConfig.pm or define options there.
 
   WebPublicUser
-    Make sure to create the public user in your RT system and add the line
-    below to your RT_SiteConfig.pm.
+    Create the public user in your RT system through Admin \ Users \>
+    Create> in RT. The public user must be able to access RT, and it must be
+    privileged so it can have rights. Do not enter an email address for the
+    public user.
+
+    Add the line below to RT_SiteConfig.pm and replace 'guest' with the name
+    of the RT user you just created.
 
         Set( $WebPublicUser, 'guest' );
 
-    If you didn't name your public user 'guest', then change accordingly.
+    The public user needs the following rights on public distribution queues
+    to search bugs:
 
-    The public user should probably be unprivileged and have the following
-    rights
+        SeeCustomField
+        SeeQueue
+        ShowTicket
+
+    The pubic user needs the following rights on public distribution queues
+    to report bugs:
 
         CreateTicket
         ModifyCustomField
         ReplyToTicket
-        SeeCustomField
-        SeeQueue
-        ShowTicket
 
-    If you want the public UI to do anything useful. It should NOT have the
-    ModifySelf right.
+  WebPublicUserReporting
+    By default, the web public user cannot create bug reports through the
+    web UI. To allow this, add this line:
+
+        Set($WebPublicUserReporting, 1);
 
 AUTHOR
     Best Practical Solutions, LLC <modules at bestpractical.com>
@@ -59,7 +91,7 @@ BUGS
         L<rt.cpan.org|http://rt.cpan.org/Public/Dist/Display.html?Name=RT-BugTracker-Public>.
 
 LICENSE AND COPYRIGHT
-    This software is Copyright (c) 2014 by Best Practical Solutions
+    This software is Copyright (c) 2017 by Best Practical Solutions
 
     This is free software, licensed under:
 
diff --git a/inc/Module/Install.pm b/inc/Module/Install.pm
index f44ab4d..dbe10ca 100644
--- a/inc/Module/Install.pm
+++ b/inc/Module/Install.pm
@@ -31,7 +31,7 @@ BEGIN {
 	# This is not enforced yet, but will be some time in the next few
 	# releases once we can make sure it won't clash with custom
 	# Module::Install extensions.
-	$VERSION = '1.16';
+	$VERSION = '1.17';
 
 	# Storage for the pseudo-singleton
 	$MAIN    = undef;
@@ -244,6 +244,8 @@ sub new {
 	}
 	return $args{_self} if $args{_self};
 
+	$base_path = VMS::Filespec::unixify($base_path) if $^O eq 'VMS';
+
 	$args{dispatch} ||= 'Admin';
 	$args{prefix}   ||= 'inc';
 	$args{author}   ||= ($^O eq 'VMS' ? '_author' : '.author');
@@ -322,7 +324,7 @@ sub find_extensions {
 	my ($self, $path) = @_;
 
 	my @found;
-	File::Find::find( sub {
+	File::Find::find( {no_chdir => 1, wanted => sub {
 		my $file = $File::Find::name;
 		return unless $file =~ m!^\Q$path\E/(.+)\.pm\Z!is;
 		my $subpath = $1;
@@ -336,7 +338,7 @@ sub find_extensions {
 		# correctly.  Otherwise, root through the file to locate the case-preserved
 		# version of the package name.
 		if ( $subpath eq lc($subpath) || $subpath eq uc($subpath) ) {
-			my $content = Module::Install::_read($subpath . '.pm');
+			my $content = Module::Install::_read($File::Find::name);
 			my $in_pod  = 0;
 			foreach ( split /\n/, $content ) {
 				$in_pod = 1 if /^=\w/;
@@ -351,7 +353,7 @@ sub find_extensions {
 		}
 
 		push @found, [ $file, $pkg ];
-	}, $path ) if -d $path;
+	}}, $path ) if -d $path;
 
 	@found;
 }
@@ -373,8 +375,6 @@ sub _caller {
 	return $call;
 }
 
-# Done in evals to avoid confusing Perl::MinimumVersion
-eval( $] >= 5.006 ? <<'END_NEW' : <<'END_OLD' ); die $@ if $@;
 sub _read {
 	local *FH;
 	open( FH, '<', $_[0] ) or die "open($_[0]): $!";
@@ -383,16 +383,6 @@ sub _read {
 	close FH or die "close($_[0]): $!";
 	return $string;
 }
-END_NEW
-sub _read {
-	local *FH;
-	open( FH, "< $_[0]"  ) or die "open($_[0]): $!";
-	binmode FH;
-	my $string = do { local $/; <FH> };
-	close FH or die "close($_[0]): $!";
-	return $string;
-}
-END_OLD
 
 sub _readperl {
 	my $string = Module::Install::_read($_[0]);
@@ -413,8 +403,6 @@ sub _readpod {
 	return $string;
 }
 
-# Done in evals to avoid confusing Perl::MinimumVersion
-eval( $] >= 5.006 ? <<'END_NEW' : <<'END_OLD' ); die $@ if $@;
 sub _write {
 	local *FH;
 	open( FH, '>', $_[0] ) or die "open($_[0]): $!";
@@ -424,17 +412,6 @@ sub _write {
 	}
 	close FH or die "close($_[0]): $!";
 }
-END_NEW
-sub _write {
-	local *FH;
-	open( FH, "> $_[0]"  ) or die "open($_[0]): $!";
-	binmode FH;
-	foreach ( 1 .. $#_ ) {
-		print FH $_[$_] or die "print($_[0]): $!";
-	}
-	close FH or die "close($_[0]): $!";
-}
-END_OLD
 
 # _version is for processing module versions (eg, 1.03_05) not
 # Perl versions (eg, 5.8.1).
diff --git a/inc/Module/Install/Base.pm b/inc/Module/Install/Base.pm
index 5762a74..3d89918 100644
--- a/inc/Module/Install/Base.pm
+++ b/inc/Module/Install/Base.pm
@@ -4,7 +4,7 @@ package Module::Install::Base;
 use strict 'vars';
 use vars qw{$VERSION};
 BEGIN {
-	$VERSION = '1.16';
+	$VERSION = '1.17';
 }
 
 # Suspend handler for "redefined" warnings
diff --git a/inc/Module/Install/Can.pm b/inc/Module/Install/Can.pm
index d859276..fc699b3 100644
--- a/inc/Module/Install/Can.pm
+++ b/inc/Module/Install/Can.pm
@@ -8,7 +8,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '1.16';
+	$VERSION = '1.17';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
@@ -121,6 +121,15 @@ END_C
 # Can we locate a (the) C compiler
 sub can_cc {
 	my $self   = shift;
+
+	if ($^O eq 'VMS') {
+		require ExtUtils::CBuilder;
+		my $builder = ExtUtils::CBuilder->new(
+		quiet => 1,
+		);
+		return $builder->have_compiler;
+	}
+
 	my @chunks = split(/ /, $Config::Config{cc}) or return;
 
 	# $Config{cc} may contain args; try to find out the program part
@@ -151,4 +160,4 @@ if ( $^O eq 'cygwin' ) {
 
 __END__
 
-#line 236
+#line 245
diff --git a/inc/Module/Install/Fetch.pm b/inc/Module/Install/Fetch.pm
index 41d3517..3ee0aa1 100644
--- a/inc/Module/Install/Fetch.pm
+++ b/inc/Module/Install/Fetch.pm
@@ -6,7 +6,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '1.16';
+	$VERSION = '1.17';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
diff --git a/inc/Module/Install/Include.pm b/inc/Module/Install/Include.pm
index 2eb1d1f..e8a73b8 100644
--- a/inc/Module/Install/Include.pm
+++ b/inc/Module/Install/Include.pm
@@ -6,7 +6,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '1.16';
+	$VERSION = '1.17';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
diff --git a/inc/Module/Install/Makefile.pm b/inc/Module/Install/Makefile.pm
index e9918d2..bc81e06 100644
--- a/inc/Module/Install/Makefile.pm
+++ b/inc/Module/Install/Makefile.pm
@@ -8,7 +8,7 @@ use Fcntl qw/:flock :seek/;
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '1.16';
+	$VERSION = '1.17';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
diff --git a/inc/Module/Install/Metadata.pm b/inc/Module/Install/Metadata.pm
index 9792685..29934cf 100644
--- a/inc/Module/Install/Metadata.pm
+++ b/inc/Module/Install/Metadata.pm
@@ -6,7 +6,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '1.16';
+	$VERSION = '1.17';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
diff --git a/inc/Module/Install/Win32.pm b/inc/Module/Install/Win32.pm
index 218a66b..dba25f9 100644
--- a/inc/Module/Install/Win32.pm
+++ b/inc/Module/Install/Win32.pm
@@ -6,7 +6,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '1.16';
+	$VERSION = '1.17';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
diff --git a/inc/Module/Install/WriteAll.pm b/inc/Module/Install/WriteAll.pm
index 530749b..d553bd7 100644
--- a/inc/Module/Install/WriteAll.pm
+++ b/inc/Module/Install/WriteAll.pm
@@ -6,7 +6,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '1.16';
+	$VERSION = '1.17';
 	@ISA     = qw{Module::Install::Base};
 	$ISCORE  = 1;
 }
diff --git a/inc/YAML/Tiny.pm b/inc/YAML/Tiny.pm
index aa539f7..4fd023d 100644
--- a/inc/YAML/Tiny.pm
+++ b/inc/YAML/Tiny.pm
@@ -2,12 +2,12 @@
 use 5.008001; # sane UTF-8 support
 use strict;
 use warnings;
-package YAML::Tiny; # git description: v1.68-2-gcc5324e
+package YAML::Tiny; # git description: v1.69-8-g2c1e266
 # XXX-INGY is 5.8.1 too old/broken for utf8?
 # XXX-XDG Lancaster consensus was that it was sufficient until
 # proven otherwise
 
-our $VERSION = '1.69';
+our $VERSION = '1.70';
 
 #####################################################################
 # The YAML::Tiny API.
@@ -570,10 +570,8 @@ sub _dump_file {
     if ( _can_flock() ) {
         # Open without truncation (truncate comes after lock)
         my $flags = Fcntl::O_WRONLY()|Fcntl::O_CREAT();
-        sysopen( $fh, $file, $flags );
-        unless ( $fh ) {
-            $self->_error("Failed to open file '$file' for writing: $!");
-        }
+        sysopen( $fh, $file, $flags )
+            or $self->_error("Failed to open file '$file' for writing: $!");
 
         # Use no translation and strict UTF-8
         binmode( $fh, ":raw:encoding(UTF-8)");
@@ -871,4 +869,4 @@ delete $YAML::Tiny::{refaddr};
 
 __END__
 
-#line 1489
+#line 1487
diff --git a/lib/RT/BugTracker/Public.pm b/lib/RT/BugTracker/Public.pm
index 9643e8b..2c6af37 100644
--- a/lib/RT/BugTracker/Public.pm
+++ b/lib/RT/BugTracker/Public.pm
@@ -53,7 +53,7 @@ use warnings;
 package RT::BugTracker::Public;
 use URI::Escape qw/ uri_escape /;
 
-our $VERSION = '1.05';
+our $VERSION = '1.06';
 
 RT->AddJavaScript("bugtracker-public.js");
 RT->AddStyleSheets("bugtracker-public.css");

commit 8cd3dd13e208d6909c88b5b643d0263ad40289b2
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Wed Mar 8 21:58:25 2017 +0000

    Have WebPublicUserReporting permit ticket reply too

diff --git a/html/Public/Bug/Update.html b/html/Public/Bug/Update.html
index e63a87c..d51ce47 100755
--- a/html/Public/Bug/Update.html
+++ b/html/Public/Bug/Update.html
@@ -89,7 +89,7 @@
 <tr><td align="right"><&|/l&>Attach</&>:</td><td><input name="Attach" type="file" /><input type="submit" class="button" name="AddMoreAttach" value="<&|/l&>Add More Files</&>" /><input type="hidden" class="hidden" name="UpdateAttach" value="1" />
 </td></tr>
 <tr><td align="right" valign="top"><&|/l&>Message</&>:</td><td>
-<& /Elements/Callback, _CallbackName => 'BeforeMessageBox', %ARGS &>
+% $m->callback( CallbackName => 'BeforeMessageBox', %ARGS );
 % if (exists $ARGS{UpdateContent}) {
 % # preserve QuoteTransaction so we can use it to set up sane references/in/reply to
 % my $temp = $ARGS{'QuoteTransaction'};
@@ -111,7 +111,8 @@
 % }
 </form>
 <%INIT>
-return if $session{'CurrentUser'}->Name eq $RT::WebPublicUser;
+return if $session{'CurrentUser'}->Name eq $RT::WebPublicUser
+       && !RT->Config->Get("WebPublicUserReporting");
 
 my $TicketObj = LoadTicket($id);
 

commit bb8dbfeabf87f29d8e9667015c6f6f8ef4fbff5e
Author: Jim Brandt <jbrandt at bestpractical.com>
Date:   Tue Mar 28 11:22:29 2017 -0400

    Only add an about menu if it's defined
    
    RT::Extension::rt_cpan_org creates an about menu with some pages
    that describe the purpose of the RT system set up for cpan. Only show
    the About menu if another extension like that one has defined it.

diff --git a/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged b/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged
index bcb704d..d0ba881 100644
--- a/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged
+++ b/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged
@@ -75,7 +75,7 @@ Menu()->child(
     path        => '/Public/Dist/Browse.html',
 );
 
-Menu->child( "about", menu => $about );
+Menu->child( "about", menu => $about ) if $about;
 
 if ($session{CurrentUser}->Name eq RT->Config->Get("WebPublicUser")) {
     Menu->child(

commit e3ae54942c13c9167a9969125403a9f66516e5c4
Author: Jim Brandt <jbrandt at bestpractical.com>
Date:   Tue Mar 28 11:47:15 2017 -0400

    Remove the welcome message since the dead-end link is confusing
    
    Remove the 'welcome guest' menu option. It is intended as a reminder to
    the current user that they are logged in as a guest. It is confusing,
    however, because it renders as a link and the link has no target.
    
    Leave the commented code in place until RT's menus support a no-link option
    or a sensible target page is created.

diff --git a/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged b/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged
index d0ba881..cda5eb5 100644
--- a/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged
+++ b/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged
@@ -78,11 +78,16 @@ Menu()->child(
 Menu->child( "about", menu => $about ) if $about;
 
 if ($session{CurrentUser}->Name eq RT->Config->Get("WebPublicUser")) {
-    Menu->child(
-        'preferences' => title => loc( 'Welcome [_1]anonymous guest[_2].', '<span class="current-user">', '</span>' ),
-        escape_title  => 0,
-        sort_order    => 1000,
-    );
+
+    # This creates a welcome message that reminds the current user they are logged
+    # in as a guest. However, it renders as a link with no target
+    # because RT doesn't currently support menu items that don't link somewhere.
+    # Comment out until RT's menus support a 'no-link' option.
+#    Menu->child(
+#        'preferences' => title => loc( 'Welcome [_1]anonymous guest[_2].', '<span class="current-user">', '</span>' ),
+#        escape_title  => 0,
+#        sort_order    => 1000,
+#    );
 
     # Public user must logout to login
     Menu->child(

commit 35499ed99bba887f544c63579b985c6c346a727b
Author: Jim Brandt <jbrandt at bestpractical.com>
Date:   Tue Mar 28 12:03:20 2017 -0400

    Relabel log out link

diff --git a/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged b/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged
index cda5eb5..4d55447 100644
--- a/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged
+++ b/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged
@@ -92,7 +92,7 @@ if ($session{CurrentUser}->Name eq RT->Config->Get("WebPublicUser")) {
     # Public user must logout to login
     Menu->child(
         "login",
-        title       => loc('Login as another user'),
+        title       => loc('Log out guest user'),
         path        => '/NoAuth/Logout.html',
         sort_order  => 1001,
     );

commit ef9ed2c5775893fd7d3d94c0ca7ef039d4ff6653
Author: Jim Brandt <jbrandt at bestpractical.com>
Date:   Tue Mar 28 14:34:44 2017 -0400

    Add method to return content from articles in select UI locations
    
    Allow customization of select parts of the UI using articles in
    the BugTracker Pages class.

diff --git a/html/Callbacks/BugTracker-Public/Elements/Login/Default b/html/Callbacks/BugTracker-Public/Elements/Login/Default
index 9f94e71..4df861a 100644
--- a/html/Callbacks/BugTracker-Public/Elements/Login/Default
+++ b/html/Callbacks/BugTracker-Public/Elements/Login/Default
@@ -45,8 +45,6 @@
 %# those contributions and any derivatives thereof.
 %#
 %# END BPS TAGGED BLOCK }}}
-<h3><% loc("Don't have an account but want to browse bugs?") %></h3>
-<p>
-<% loc('Use the <a href="[_1]">public interface</a>.', RT->Config->Get('WebBaseURL') .'/Public/' ) |n %>
-<% loc('Want to report a bug? Send it in via e-mail.') %>
-</p>
+
+<% $m->comp( '/Elements/ScrubHTML',
+    Content => RT::BugTracker::Public::GetArticleContent('AfterLoginForm')) |n %>
diff --git a/lib/RT/BugTracker/Public.pm b/lib/RT/BugTracker/Public.pm
index 2c6af37..536a0af 100644
--- a/lib/RT/BugTracker/Public.pm
+++ b/lib/RT/BugTracker/Public.pm
@@ -215,6 +215,54 @@ require RT::Interface::Web;
     "/Public/index.html"             => 1,
 );
 
+=head2 GetArticleContent
+
+Searches in articles for content for various configurable pages in the BugTracker
+interface. The article names are available for adding custom
+content in the listed locations. To customize, create or edit the article with the
+listed name.
+
+=over
+
+=item * AfterLoginForm
+
+Location: Login page, below username/password fields
+
+=back
+
+=cut
+
+sub GetArticleContent {
+    my $article_name = shift;
+
+    my $Class = RT::Class->new( RT->SystemUser );
+    my ($ret, $msg) = $Class->Load('BugTracker Pages');
+
+    unless ( $ret and $Class->Id ){
+        RT::Logger->warning('Unable to load BugTracker Pages class for articles');
+        return '';
+    }
+
+    my $Article = RT::Article->new( RT->SystemUser );
+    ($ret, $msg) = $Article->LoadByCols( Name => $article_name, Class => $Class->Id );
+
+    unless ($ret and $Article->id){
+        RT::Logger->debug("No article found for " . $article_name);
+        return '';
+    }
+
+    RT::Logger->debug("Found article id: " . $Article->Id);
+    my $class = $Article->ClassObj;
+    my $cfs = $class->ArticleCustomFields;
+
+    while (my $cf = $cfs->Next) {
+        my $values = $Article->CustomFieldValues($cf->Id);
+        my $value = $values->First;
+        return $value->Content;
+    }
+    return;
+}
+
 =head1 AUTHOR
 
 Best Practical Solutions, LLC E<lt>modules at bestpractical.comE<gt>

commit 3d5126b8819cb31a2a303848e6c96661d6690a2e
Author: Jim Brandt <jbrandt at bestpractical.com>
Date:   Wed Mar 29 16:40:53 2017 -0400

    Add initialdata for default content articles

diff --git a/etc/initialdata b/etc/initialdata
new file mode 100644
index 0000000..4c4baac
--- /dev/null
+++ b/etc/initialdata
@@ -0,0 +1,25 @@
+ at Classes = (
+    {
+        Name              => 'BugTracker Pages',
+        Description       => 'Class to hold articles for customizing BugTracker extension pages',
+    },
+);
+
+our @Final = (
+    sub {
+        my %articles = (
+        'AfterLoginForm' => q{<h3>Don't have an account but want to browse bugs?</h3>
+<p>Use the <a href="/Public/">public interface</a></p>
+<p>Want to report a bug? Send it in via e-mail.</p>},
+        );
+
+        foreach my $article_name ( keys %articles ){
+            my $article = RT::Article->new(RT->SystemUser);
+            my ($ret, $msg) = $article->Create(
+                'Name' => $article_name,
+                'Class' => 'BugTracker Pages',
+                'CustomField-Content' => $articles{$article_name} );
+            RT::Logger->error("Unable to create new article $article_name: $msg") unless $ret;
+        }
+    },
+);

commit 5151a228d1b613c2e251e9cac13987ccdf7452ff
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Wed Mar 29 21:18:37 2017 +0000

    Respect RT::BugTracker's BugTracker_ShowAllDistributions

diff --git a/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged b/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged
index 4d55447..8b37d2c 100644
--- a/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged
+++ b/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged
@@ -70,10 +70,12 @@ Menu()->child(
     path        => '/Public/',
 );
 
-Menu()->child(
-    browse_dist => title => loc('Browse Distributions'),
-    path        => '/Public/Dist/Browse.html',
-);
+unless (RT->Config->Get('BugTracker_ShowAllDistributions')) {
+    Menu()->child(
+        browse_dist => title => loc('Browse Distributions'),
+        path        => '/Public/Dist/Browse.html',
+    );
+}
 
 Menu->child( "about", menu => $about ) if $about;
 
diff --git a/html/Public/index.html b/html/Public/index.html
index 2c81f2b..a1110f7 100755
--- a/html/Public/index.html
+++ b/html/Public/index.html
@@ -50,6 +50,7 @@
 
 <& /Elements/ListActions, actions => \@results &>
 
+% unless (RT->Config->Get('BugTracker_ShowAllDistributions')) {
 <p>
   <form action="<% RT->Config->Get('WebPath') %><% $m->request_path %>" method="get">
     <label for="form-dist-name"><&|/l&>Find a distribution by full name:</&></label>
@@ -65,6 +66,7 @@
     <input type="submit" class="button" value="<&|/l&>Search</&>" />
   </form>
 </p>
+% }
 
 <p>
   <form action="/Public/Search/Simple.html" method="get">
@@ -75,6 +77,14 @@
 
   <&|/l&>This search looks for bug report IDs, distribution names, usernames, and bug report descriptions among other fields.</&>
 </p>
+
+% if (RT->Config->Get('BugTracker_ShowAllDistributions')) {
+<h2><&|/l&>Distributions</&></h2>
+
+% my $queues = RT::Queues->new($session{CurrentUser});
+% $queues->UnLimit;
+    <& /Public/Elements/DistributionList, queues => $queues &>
+% }
 <%ARGS>
 $Distribution => ''
 $Maintainer   => ''

commit 4e5d6a489321932b5c39783dbf0c3b7386b6640a
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Wed Mar 29 21:22:04 2017 +0000

    Respect WebPublicUserReporting to suppress new ticket UI

diff --git a/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged b/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged
index 8b37d2c..07de3e7 100644
--- a/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged
+++ b/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged
@@ -62,8 +62,10 @@ RT::Interface::Web::InitializeMenu();
 PageWidgets()->child( simple_search => raw_html => $m->scomp(
     '/Elements/SimpleSearch', SendTo => '/Public/Search/Simple.html' ));
 
-PageWidgets()->child( create_ticket => raw_html => $m->scomp(
-    '/Elements/CreateTicket', SendTo => '/Public/Bug/Report.html' ));
+if (RT->Config->Get('WebPublicUserReporting')) {
+    PageWidgets()->child( create_ticket => raw_html => $m->scomp(
+        '/Elements/CreateTicket', SendTo => '/Public/Bug/Report.html' ));
+}
 
 Menu()->child(
     search_dist => title => loc('Search Distributions'),
@@ -139,10 +141,12 @@ if ( $queue and $queue->id ) {
             path  => "/Public/Dist/Display.html?Status=Rejected;Name=". $escaped,
     );
 
-    PageMenu()->child( report => 
-            title => loc("Report a new bug"),
-            path  => '/Public/Bug/Report.html?Queue='. $escaped,
-    );
+    if (RT->Config->Get('WebPublicUserReporting')) {
+        PageMenu()->child( report =>
+                title => loc("Report a new bug"),
+                path  => '/Public/Bug/Report.html?Queue='. $escaped,
+        );
+    }
 
     if ($ticket and $ticket->id
         and $queue->LifecycleObj->IsInactive($ticket->Status)

commit a580f15ff1a73a0d083e1a124ebeef92c120a220
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Wed Mar 29 21:36:14 2017 +0000

    Add support for WebPublicUserQueryBuilder
    
    Fixes: T#182770

diff --git a/lib/RT/BugTracker/Public.pm b/lib/RT/BugTracker/Public.pm
index 536a0af..af53750 100644
--- a/lib/RT/BugTracker/Public.pm
+++ b/lib/RT/BugTracker/Public.pm
@@ -192,8 +192,13 @@ sub RedirectToPublic {
         return "/Public$path";
     }
 
+    elsif ( RT->Config->Get('WebPublicUserQueryBuilder')) {
+        return undef if $path =~ '^/+Search/Build.html'
+                     || $path =~ '^/+Search/Results.html'
+    }
+
     # otherwise, drop the user at the Public default page
-    elsif (    $path !~ '^(/+)Public/'
+    if (       $path !~ '^(/+)Public/'
            and $path !~ RT->Config->Get('WebNoAuthRegex')
            and $path !~ '^/+Helpers/Autocomplete/Queues' ) {
         return "/Public/";

commit da3b708a32fc80acd287e6eb7ccc29cb159f376f
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Wed Mar 29 21:45:00 2017 +0000

    Finish support for WebPublicUserQueryBuilder

diff --git a/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged b/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged
index 07de3e7..e337e22 100644
--- a/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged
+++ b/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged
@@ -72,6 +72,13 @@ Menu()->child(
     path        => '/Public/',
 );
 
+if (RT->Config->Get('WebPublicUserQueryBuilder')) {
+    Menu()->child(
+        query_builder => title => loc('Advanced Search'),
+        path        => '/Search/Build.html?NewQuery=1',
+    );
+}
+
 unless (RT->Config->Get('BugTracker_ShowAllDistributions')) {
     Menu()->child(
         browse_dist => title => loc('Browse Distributions'),
diff --git a/lib/RT/BugTracker/Public.pm b/lib/RT/BugTracker/Public.pm
index af53750..556da46 100644
--- a/lib/RT/BugTracker/Public.pm
+++ b/lib/RT/BugTracker/Public.pm
@@ -153,6 +153,14 @@ web UI. To allow this, add this line:
 
     Set($WebPublicUserReporting, 1);
 
+=head2 WebPublicUserQueryBuilder
+
+By default, the web public user cannot use RT's fully-featured query builder
+and is limited instead to simple search. To allow access to the query
+builder, add this line:
+
+    Set($WebPublicUserQueryBuilder, 1);
+
 =cut
 
 sub IsPublicUser {

commit 20e195b45c78515ed37619c693c92276711a4053
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Wed Mar 29 21:45:20 2017 +0000

    Respect WebPublicUserReporting to suppress "Report a bug" in queue listing

diff --git a/html/Public/Elements/DistributionList b/html/Public/Elements/DistributionList
index 108e2ff..3d1f29b 100644
--- a/html/Public/Elements/DistributionList
+++ b/html/Public/Elements/DistributionList
@@ -64,8 +64,10 @@
   <li>
     <span class="dist-actions">
       <a href="<% $RT::WebPath %>/Public/Dist/Display.html?Name=<% $queue->Name |u %>">Bug list</a>
+% if (RT->Config->Get('WebPublicUserReporting')) {
       •
       <a href="<% $RT::WebPath %>/Public/Bug/Report.html?Queue=<% $queue->Name |u %>">Report a bug</a>
+% }
     </span>
     <strong><% $queue->Name %></strong>
   </li>

commit b6f12897051db37a88b2d6d7290363444a8a9595
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Wed Mar 29 22:02:27 2017 +0000

    Document make initdb now that we have an initialdata

diff --git a/lib/RT/BugTracker/Public.pm b/lib/RT/BugTracker/Public.pm
index 556da46..f7934d3 100644
--- a/lib/RT/BugTracker/Public.pm
+++ b/lib/RT/BugTracker/Public.pm
@@ -100,6 +100,8 @@ for a distribution.
 
 May need root permissions
 
+=item C<make initdb>
+
 =item Edit your F</opt/rt4/etc/RT_SiteConfig.pm>
 
 Add this line:

commit 7e579d6b04f7b5610e88d910d8b33f2547f71f85
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Wed Mar 29 22:05:56 2017 +0000

    1.07 releng

diff --git a/Changes b/Changes
index bec7942..f9e9a92 100644
--- a/Changes
+++ b/Changes
@@ -1,3 +1,13 @@
+1.07 2017-03-29
+ - Add WebPublicUserQueryBuilder config setting
+ - Have WebPublicUserReporting hide create/reply UI more consistently
+ - Support RT::BugTracker BugTracker_ShowAllDistributions
+ - Only add an about menu if it's defined
+ - Remove the welcome message since the dead-end link is confusing
+ - Remove the 'welcome guest' menu option
+ - Relabel log out link
+ - Allow customization of select parts of the UI using articles
+
 1.06 2017-02-28
  - RT 4.2 and 4.4 compatibility
  - Drop 4.0 compatibility
diff --git a/MANIFEST b/MANIFEST
index 8539a23..4a4aa75 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1,4 +1,5 @@
 Changes
+etc/initialdata
 etc/RT_SiteConfig.pm
 html/Callbacks/BugTracker-Public/autohandler/Auth
 html/Callbacks/BugTracker-Public/autohandler/Default
diff --git a/META.yml b/META.yml
index e6d3212..64dbca4 100644
--- a/META.yml
+++ b/META.yml
@@ -24,7 +24,7 @@ requires:
   perl: 5.10.1
 resources:
   license: http://opensource.org/licenses/gpl-license.php
-version: '1.06'
+version: '1.07'
 x_module_install_rtx_version: '0.38'
 x_requires_rt: 4.2.0
 x_rt_too_new: 4.6.0
diff --git a/Makefile.PL b/Makefile.PL
index 937f700..6081b5b 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -5,5 +5,4 @@ RTx('RT-BugTracker-Public');
 requires_rt('4.2.0');
 rt_too_new('4.6.0');
 
-sign();
 WriteAll();
diff --git a/README b/README
index 755a974..a466e4d 100644
--- a/README
+++ b/README
@@ -32,6 +32,7 @@ INSTALLATION
     make install
         May need root permissions
 
+    make initdb
     Edit your /opt/rt4/etc/RT_SiteConfig.pm
         Add this line:
 
@@ -78,6 +79,23 @@ CONFIGURATION
 
         Set($WebPublicUserReporting, 1);
 
+  WebPublicUserQueryBuilder
+    By default, the web public user cannot use RT's fully-featured query
+    builder and is limited instead to simple search. To allow access to the
+    query builder, add this line:
+
+        Set($WebPublicUserQueryBuilder, 1);
+
+  GetArticleContent
+    Searches in articles for content for various configurable pages in the
+    BugTracker interface. The article names are available for adding custom
+    content in the listed locations. To customize, create or edit the
+    article with the listed name.
+
+    *   AfterLoginForm
+
+        Location: Login page, below username/password fields
+
 AUTHOR
     Best Practical Solutions, LLC <modules at bestpractical.com>
 
diff --git a/lib/RT/BugTracker/Public.pm b/lib/RT/BugTracker/Public.pm
index f7934d3..eb00687 100644
--- a/lib/RT/BugTracker/Public.pm
+++ b/lib/RT/BugTracker/Public.pm
@@ -53,7 +53,7 @@ use warnings;
 package RT::BugTracker::Public;
 use URI::Escape qw/ uri_escape /;
 
-our $VERSION = '1.06';
+our $VERSION = '1.07';
 
 RT->AddJavaScript("bugtracker-public.js");
 RT->AddStyleSheets("bugtracker-public.css");

commit 88851d27364eca44876dbfce4768c5034650d7cc
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Thu Jun 8 14:24:20 2017 -0400

    Add config option WebPublicUserSortResults

diff --git a/etc/RT_SiteConfig.pm b/etc/RT_SiteConfig.pm
index 67f690e..a9d89ef 100644
--- a/etc/RT_SiteConfig.pm
+++ b/etc/RT_SiteConfig.pm
@@ -2,3 +2,5 @@
 
 Set($WebPublicUser, 'public');
 Set($WebPublicUserReporting, 0);
+Set($WebPublicUserSortResults, 0);
+
diff --git a/html/Public/Search/Results.html b/html/Public/Search/Results.html
index 525e922..1d2ba46 100644
--- a/html/Public/Search/Results.html
+++ b/html/Public/Search/Results.html
@@ -49,7 +49,7 @@
 <& /Elements/Tabs &>
 <& /Elements/CollectionList,
     Query           => $ARGS{Query},
-    AllowSorting    => 0,
+    AllowSorting    => RT->Config->Get('WebPublicUserSortResults'),
     OrderBy         => 'id',
     Order           => 'ASC',
     Rows            => 50,
diff --git a/lib/RT/BugTracker/Public.pm b/lib/RT/BugTracker/Public.pm
index eb00687..575d7ef 100644
--- a/lib/RT/BugTracker/Public.pm
+++ b/lib/RT/BugTracker/Public.pm
@@ -163,6 +163,13 @@ builder, add this line:
 
     Set($WebPublicUserQueryBuilder, 1);
 
+=head2 WebPublicUserSortResults
+
+By default, the web public user cannot click column headers to re-sort search
+results due to performance implications. To permit this, add this line:
+
+    Set($WebPublicUserSortResults, 1);
+
 =cut
 
 sub IsPublicUser {

commit f3d40f6a66af167219a7024b511999b5662fe362
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Tue Jun 27 15:58:10 2017 +0000

    Packager updates

diff --git a/MANIFEST b/MANIFEST
index 4a4aa75..da7c16b 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -43,6 +43,7 @@ inc/Module/Install/RTx.pm
 inc/Module/Install/RTx/Runtime.pm
 inc/Module/Install/Win32.pm
 inc/Module/Install/WriteAll.pm
+inc/unicore/Name.pm
 inc/YAML/Tiny.pm
 lib/RT/BugTracker/Public.pm
 Makefile.PL
diff --git a/META.yml b/META.yml
index 64dbca4..0b2d0cb 100644
--- a/META.yml
+++ b/META.yml
@@ -8,7 +8,7 @@ configure_requires:
   ExtUtils::MakeMaker: 6.59
 distribution_type: module
 dynamic_config: 1
-generated_by: 'Module::Install version 1.17'
+generated_by: 'Module::Install version 1.18'
 license: gpl
 meta-spec:
   url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -25,6 +25,6 @@ requires:
 resources:
   license: http://opensource.org/licenses/gpl-license.php
 version: '1.07'
-x_module_install_rtx_version: '0.38'
+x_module_install_rtx_version: '0.39'
 x_requires_rt: 4.2.0
 x_rt_too_new: 4.6.0
diff --git a/inc/Module/Install.pm b/inc/Module/Install.pm
index dbe10ca..07525c5 100644
--- a/inc/Module/Install.pm
+++ b/inc/Module/Install.pm
@@ -31,7 +31,7 @@ BEGIN {
 	# This is not enforced yet, but will be some time in the next few
 	# releases once we can make sure it won't clash with custom
 	# Module::Install extensions.
-	$VERSION = '1.17';
+	$VERSION = '1.18';
 
 	# Storage for the pseudo-singleton
 	$MAIN    = undef;
diff --git a/inc/Module/Install/Base.pm b/inc/Module/Install/Base.pm
index 3d89918..b61d424 100644
--- a/inc/Module/Install/Base.pm
+++ b/inc/Module/Install/Base.pm
@@ -4,7 +4,7 @@ package Module::Install::Base;
 use strict 'vars';
 use vars qw{$VERSION};
 BEGIN {
-	$VERSION = '1.17';
+	$VERSION = '1.18';
 }
 
 # Suspend handler for "redefined" warnings
diff --git a/inc/Module/Install/Can.pm b/inc/Module/Install/Can.pm
index fc699b3..1de368c 100644
--- a/inc/Module/Install/Can.pm
+++ b/inc/Module/Install/Can.pm
@@ -8,7 +8,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '1.17';
+	$VERSION = '1.18';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
diff --git a/inc/Module/Install/Fetch.pm b/inc/Module/Install/Fetch.pm
index 3ee0aa1..54b52cb 100644
--- a/inc/Module/Install/Fetch.pm
+++ b/inc/Module/Install/Fetch.pm
@@ -6,7 +6,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '1.17';
+	$VERSION = '1.18';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
diff --git a/inc/Module/Install/Include.pm b/inc/Module/Install/Include.pm
index e8a73b8..087da8d 100644
--- a/inc/Module/Install/Include.pm
+++ b/inc/Module/Install/Include.pm
@@ -6,7 +6,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '1.17';
+	$VERSION = '1.18';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
diff --git a/inc/Module/Install/Makefile.pm b/inc/Module/Install/Makefile.pm
index bc81e06..8ba3d88 100644
--- a/inc/Module/Install/Makefile.pm
+++ b/inc/Module/Install/Makefile.pm
@@ -8,7 +8,7 @@ use Fcntl qw/:flock :seek/;
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '1.17';
+	$VERSION = '1.18';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
diff --git a/inc/Module/Install/Metadata.pm b/inc/Module/Install/Metadata.pm
index 29934cf..692ce71 100644
--- a/inc/Module/Install/Metadata.pm
+++ b/inc/Module/Install/Metadata.pm
@@ -6,7 +6,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '1.17';
+	$VERSION = '1.18';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
diff --git a/inc/Module/Install/RTx.pm b/inc/Module/Install/RTx.pm
index 80538d3..3268e7e 100644
--- a/inc/Module/Install/RTx.pm
+++ b/inc/Module/Install/RTx.pm
@@ -8,7 +8,7 @@ no warnings 'once';
 
 use Module::Install::Base;
 use base 'Module::Install::Base';
-our $VERSION = '0.38';
+our $VERSION = '0.39';
 
 use FindBin;
 use File::Glob     ();
@@ -113,11 +113,29 @@ lexicons ::
 .
     }
 
+    my $remove_files;
+    if( $extra_args->{'remove_files'} ){
+        $self->include('Module::Install::RTx::Remove');
+        our @remove_files;
+        eval { require "etc/upgrade/remove_files" }
+          or print "No remove file located, no files to remove\n";
+        $remove_files = join ",", map {"q(\$(DESTDIR)$plugin_path/$name/$_)"} @remove_files;
+    }
+
     $self->include('Module::Install::RTx::Runtime') if $self->admin;
     $self->include_deps( 'YAML::Tiny', 0 ) if $self->admin;
     my $postamble = << ".";
 install ::
 \t\$(NOECHO) \$(PERL) -Ilib -I"$local_lib_path" -I"$lib_path" -Iinc -MModule::Install::RTx::Runtime -e"RTxPlugin()"
+.
+
+    if( $remove_files ){
+        $postamble .= << ".";
+\t\$(NOECHO) \$(PERL) -MModule::Install::RTx::Remove -e \"RTxRemove([$remove_files])\"
+.
+    }
+
+    $postamble .= << ".";
 \t\$(NOECHO) \$(PERL) -MExtUtils::Install -e \"install({$args})\"
 .
 
@@ -279,4 +297,4 @@ sub _load_rt_handle {
 
 __END__
 
-#line 428
+#line 468
diff --git a/inc/Module/Install/ReadmeFromPod.pm b/inc/Module/Install/ReadmeFromPod.pm
index 3634ee0..3738232 100644
--- a/inc/Module/Install/ReadmeFromPod.pm
+++ b/inc/Module/Install/ReadmeFromPod.pm
@@ -7,7 +7,7 @@ use warnings;
 use base qw(Module::Install::Base);
 use vars qw($VERSION);
 
-$VERSION = '0.26';
+$VERSION = '0.30';
 
 {
 
diff --git a/inc/Module/Install/Win32.pm b/inc/Module/Install/Win32.pm
index dba25f9..b80c900 100644
--- a/inc/Module/Install/Win32.pm
+++ b/inc/Module/Install/Win32.pm
@@ -6,7 +6,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '1.17';
+	$VERSION = '1.18';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
diff --git a/inc/Module/Install/WriteAll.pm b/inc/Module/Install/WriteAll.pm
index d553bd7..da279c7 100644
--- a/inc/Module/Install/WriteAll.pm
+++ b/inc/Module/Install/WriteAll.pm
@@ -6,7 +6,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '1.17';
+	$VERSION = '1.18';
 	@ISA     = qw{Module::Install::Base};
 	$ISCORE  = 1;
 }
diff --git a/inc/unicore/Name.pm b/inc/unicore/Name.pm
new file mode 100644
index 0000000..15e729b
--- /dev/null
+++ b/inc/unicore/Name.pm
@@ -0,0 +1,416 @@
+#line 1
+# !!!!!!!   DO NOT EDIT THIS FILE   !!!!!!!
+# This file is machine-generated by lib/unicore/mktables from the Unicode
+# database, Version 6.2.0.  Any changes made here will be lost!
+
+
+# !!!!!!!   INTERNAL PERL USE ONLY   !!!!!!!
+# This file is for internal use by core Perl only.  The format and even the
+# name or existence of this file are subject to change without notice.  Don't
+# use it directly.
+
+
+package charnames;
+
+# This module contains machine-generated tables and code for the
+# algorithmically-determinable Unicode character names.  The following
+# routines can be used to translate between name and code point and vice versa
+
+{ # Closure
+
+    # Matches legal code point.  4-6 hex numbers, If there are 6, the first
+    # two must be 10; if there are 5, the first must not be a 0.  Written this
+    # way to decrease backtracking.  The first regex allows the code point to
+    # be at the end of a word, but to work properly, the word shouldn't end
+    # with a valid hex character.  The second one won't match a code point at
+    # the end of a word, and doesn't have the run-on issue
+    my $run_on_code_point_re = qr/(?^aax: (?: 10[0-9A-F]{4} | [1-9A-F][0-9A-F]{4} | [0-9A-F]{4} ) \b)/;
+    my $code_point_re = qr/(?^aa:\b(?^aax: (?: 10[0-9A-F]{4} | [1-9A-F][0-9A-F]{4} | [0-9A-F]{4} ) \b))/;
+
+    # In the following hash, the keys are the bases of names which include
+    # the code point in the name, like CJK UNIFIED IDEOGRAPH-4E01.  The value
+    # of each key is another hash which is used to get the low and high ends
+    # for each range of code points that apply to the name.
+    my %names_ending_in_code_point = (
+'CJK COMPATIBILITY IDEOGRAPH' => 
+{
+'high' => 
+[
+64109,
+64217,
+195101,
+],
+'low' => 
+[
+63744,
+64112,
+194560,
+],
+},
+'CJK UNIFIED IDEOGRAPH' => 
+{
+'high' => 
+[
+19893,
+40908,
+173782,
+177972,
+178205,
+],
+'low' => 
+[
+13312,
+19968,
+131072,
+173824,
+177984,
+],
+},
+
+    );
+
+    # The following hash is a copy of the previous one, except is for loose
+    # matching, so each name has blanks and dashes squeezed out
+    my %loose_names_ending_in_code_point = (
+'CJKCOMPATIBILITYIDEOGRAPH' => 
+{
+'high' => 
+[
+64109,
+64217,
+195101,
+],
+'low' => 
+[
+63744,
+64112,
+194560,
+],
+},
+'CJKUNIFIEDIDEOGRAPH' => 
+{
+'high' => 
+[
+19893,
+40908,
+173782,
+177972,
+178205,
+],
+'low' => 
+[
+13312,
+19968,
+131072,
+173824,
+177984,
+],
+},
+
+    );
+
+    # And the following array gives the inverse mapping from code points to
+    # names.  Lowest code points are first
+    my @code_points_ending_in_code_point = (
+
+{
+'high' => 19893,
+'low' => 13312,
+'name' => 'CJK UNIFIED IDEOGRAPH',
+},
+{
+'high' => 40908,
+'low' => 19968,
+'name' => 'CJK UNIFIED IDEOGRAPH',
+},
+{
+'high' => 64109,
+'low' => 63744,
+'name' => 'CJK COMPATIBILITY IDEOGRAPH',
+},
+{
+'high' => 64217,
+'low' => 64112,
+'name' => 'CJK COMPATIBILITY IDEOGRAPH',
+},
+{
+'high' => 173782,
+'low' => 131072,
+'name' => 'CJK UNIFIED IDEOGRAPH',
+},
+{
+'high' => 177972,
+'low' => 173824,
+'name' => 'CJK UNIFIED IDEOGRAPH',
+},
+{
+'high' => 178205,
+'low' => 177984,
+'name' => 'CJK UNIFIED IDEOGRAPH',
+},
+{
+'high' => 195101,
+'low' => 194560,
+'name' => 'CJK COMPATIBILITY IDEOGRAPH',
+},
+,
+
+    );
+
+    # Convert from code point to Jamo short name for use in composing Hangul
+    # syllable names
+    my %Jamo = (
+4352 => 'G',
+4353 => 'GG',
+4354 => 'N',
+4355 => 'D',
+4356 => 'DD',
+4357 => 'R',
+4358 => 'M',
+4359 => 'B',
+4360 => 'BB',
+4361 => 'S',
+4362 => 'SS',
+4363 => '',
+4364 => 'J',
+4365 => 'JJ',
+4366 => 'C',
+4367 => 'K',
+4368 => 'T',
+4369 => 'P',
+4370 => 'H',
+4449 => 'A',
+4450 => 'AE',
+4451 => 'YA',
+4452 => 'YAE',
+4453 => 'EO',
+4454 => 'E',
+4455 => 'YEO',
+4456 => 'YE',
+4457 => 'O',
+4458 => 'WA',
+4459 => 'WAE',
+4460 => 'OE',
+4461 => 'YO',
+4462 => 'U',
+4463 => 'WEO',
+4464 => 'WE',
+4465 => 'WI',
+4466 => 'YU',
+4467 => 'EU',
+4468 => 'YI',
+4469 => 'I',
+4520 => 'G',
+4521 => 'GG',
+4522 => 'GS',
+4523 => 'N',
+4524 => 'NJ',
+4525 => 'NH',
+4526 => 'D',
+4527 => 'L',
+4528 => 'LG',
+4529 => 'LM',
+4530 => 'LB',
+4531 => 'LS',
+4532 => 'LT',
+4533 => 'LP',
+4534 => 'LH',
+4535 => 'M',
+4536 => 'B',
+4537 => 'BS',
+4538 => 'S',
+4539 => 'SS',
+4540 => 'NG',
+4541 => 'J',
+4542 => 'C',
+4543 => 'K',
+4544 => 'T',
+4545 => 'P',
+4546 => 'H',
+
+    );
+
+    # Leading consonant (can be null)
+    my %Jamo_L = (
+'' => 11,
+'B' => 7,
+'BB' => 8,
+'C' => 14,
+'D' => 3,
+'DD' => 4,
+'G' => 0,
+'GG' => 1,
+'H' => 18,
+'J' => 12,
+'JJ' => 13,
+'K' => 15,
+'M' => 6,
+'N' => 2,
+'P' => 17,
+'R' => 5,
+'S' => 9,
+'SS' => 10,
+'T' => 16,
+
+    );
+
+    # Vowel
+    my %Jamo_V = (
+'A' => 0,
+'AE' => 1,
+'E' => 5,
+'EO' => 4,
+'EU' => 18,
+'I' => 20,
+'O' => 8,
+'OE' => 11,
+'U' => 13,
+'WA' => 9,
+'WAE' => 10,
+'WE' => 15,
+'WEO' => 14,
+'WI' => 16,
+'YA' => 2,
+'YAE' => 3,
+'YE' => 7,
+'YEO' => 6,
+'YI' => 19,
+'YO' => 12,
+'YU' => 17,
+
+    );
+
+    # Optional trailing consonant
+    my %Jamo_T = (
+'B' => 17,
+'BS' => 18,
+'C' => 23,
+'D' => 7,
+'G' => 1,
+'GG' => 2,
+'GS' => 3,
+'H' => 27,
+'J' => 22,
+'K' => 24,
+'L' => 8,
+'LB' => 11,
+'LG' => 9,
+'LH' => 15,
+'LM' => 10,
+'LP' => 14,
+'LS' => 12,
+'LT' => 13,
+'M' => 16,
+'N' => 4,
+'NG' => 21,
+'NH' => 6,
+'NJ' => 5,
+'P' => 26,
+'S' => 19,
+'SS' => 20,
+'T' => 25,
+
+    );
+
+    # Computed re that splits up a Hangul name into LVT or LV syllables
+    my $syllable_re = qr/(|B|BB|C|D|DD|G|GG|H|J|JJ|K|M|N|P|R|S|SS|T)(A|AE|E|EO|EU|I|O|OE|U|WA|WAE|WE|WEO|WI|YA|YAE|YE|YEO|YI|YO|YU)(B|BS|C|D|G|GG|GS|H|J|K|L|LB|LG|LH|LM|LP|LS|LT|M|N|NG|NH|NJ|P|S|SS|T)?/;
+
+    my $HANGUL_SYLLABLE = "HANGUL SYLLABLE ";
+    my $loose_HANGUL_SYLLABLE = "HANGULSYLLABLE";
+
+    # These constants names and values were taken from the Unicode standard,
+    # version 5.1, section 3.12.  They are used in conjunction with Hangul
+    # syllables
+    my $SBase = 0xAC00;
+    my $LBase = 0x1100;
+    my $VBase = 0x1161;
+    my $TBase = 0x11A7;
+    my $SCount = 11172;
+    my $LCount = 19;
+    my $VCount = 21;
+    my $TCount = 28;
+    my $NCount = $VCount * $TCount;
+
+    sub name_to_code_point_special {
+        my ($name, $loose) = @_;
+
+        # Returns undef if not one of the specially handled names; otherwise
+        # returns the code point equivalent to the input name
+        # $loose is non-zero if to use loose matching, 'name' in that case
+        # must be input as upper case with all blanks and dashes squeezed out.
+
+        if ((! $loose && $name =~ s/$HANGUL_SYLLABLE//)
+            || ($loose && $name =~ s/$loose_HANGUL_SYLLABLE//))
+        {
+            return if $name !~ qr/^$syllable_re$/;
+            my $L = $Jamo_L{$1};
+            my $V = $Jamo_V{$2};
+            my $T = (defined $3) ? $Jamo_T{$3} : 0;
+            return ($L * $VCount + $V) * $TCount + $T + $SBase;
+        }
+
+        # Name must end in 'code_point' for this to handle.
+        return if (($loose && $name !~ /^ (.*?) ($run_on_code_point_re) $/x)
+                   || (! $loose && $name !~ /^ (.*) ($code_point_re) $/x));
+
+        my $base = $1;
+        my $code_point = CORE::hex $2;
+        my $names_ref;
+
+        if ($loose) {
+            $names_ref = \%loose_names_ending_in_code_point;
+        }
+        else {
+            return if $base !~ s/-$//;
+            $names_ref = \%names_ending_in_code_point;
+        }
+
+        # Name must be one of the ones which has the code point in it.
+        return if ! $names_ref->{$base};
+
+        # Look through the list of ranges that apply to this name to see if
+        # the code point is in one of them.
+        for (my $i = 0; $i < scalar @{$names_ref->{$base}{'low'}}; $i++) {
+            return if $names_ref->{$base}{'low'}->[$i] > $code_point;
+            next if $names_ref->{$base}{'high'}->[$i] < $code_point;
+
+            # Here, the code point is in the range.
+            return $code_point;
+        }
+
+        # Here, looked like the name had a code point number in it, but
+        # did not match one of the valid ones.
+        return;
+    }
+
+    sub code_point_to_name_special {
+        my $code_point = shift;
+
+        # Returns the name of a code point if algorithmically determinable;
+        # undef if not
+
+        # If in the Hangul range, calculate the name based on Unicode's
+        # algorithm
+        if ($code_point >= $SBase && $code_point <= $SBase + $SCount -1) {
+            use integer;
+            my $SIndex = $code_point - $SBase;
+            my $L = $LBase + $SIndex / $NCount;
+            my $V = $VBase + ($SIndex % $NCount) / $TCount;
+            my $T = $TBase + $SIndex % $TCount;
+            $name = "$HANGUL_SYLLABLE$Jamo{$L}$Jamo{$V}";
+            $name .= $Jamo{$T} if $T != $TBase;
+            return $name;
+        }
+
+        # Look through list of these code points for one in range.
+        foreach my $hash (@code_points_ending_in_code_point) {
+            return if $code_point < $hash->{'low'};
+            if ($code_point <= $hash->{'high'}) {
+                return sprintf("%s-%04X", $hash->{'name'}, $code_point);
+            }
+        }
+        return;            # None found
+    }
+} # End closure
+
+1;

commit e90c8c838c2db9f893dd7f38bee470ac498ab41e
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Tue Jun 27 15:58:25 2017 +0000

    Rename plugin config file away from RT_SiteConfig
    
    I believe RT's plugin loader was avoiding loading this
    plugin's config file because Perl had already required a
    file named RT_SiteConfig.pm

diff --git a/MANIFEST b/MANIFEST
index da7c16b..5c0002b 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1,6 +1,6 @@
 Changes
+etc/BugTrackerPublic_Config.pm
 etc/initialdata
-etc/RT_SiteConfig.pm
 html/Callbacks/BugTracker-Public/autohandler/Auth
 html/Callbacks/BugTracker-Public/autohandler/Default
 html/Callbacks/BugTracker-Public/autohandler/Final
diff --git a/etc/RT_SiteConfig.pm b/etc/BugTrackerPublic_Config.pm
similarity index 100%
rename from etc/RT_SiteConfig.pm
rename to etc/BugTrackerPublic_Config.pm

commit a99cb670ef2aba8eb04778b58f1ec2e6876837f5
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Tue Jun 27 16:05:54 2017 +0000

    Avoid re-set-by-plugin-config warnings

diff --git a/etc/BugTrackerPublic_Config.pm b/etc/BugTrackerPublic_Config.pm
index a9d89ef..693b061 100644
--- a/etc/BugTrackerPublic_Config.pm
+++ b/etc/BugTrackerPublic_Config.pm
@@ -1,6 +1,6 @@
 # Read more about options in lib/RT/BugTracker/Public.pm
 
-Set($WebPublicUser, 'public');
-Set($WebPublicUserReporting, 0);
-Set($WebPublicUserSortResults, 0);
+Set($WebPublicUser, 'public') unless RT->Config->Meta('WebPublicUser');
+Set($WebPublicUserReporting, 0) unless RT->Config->Meta('WebPublicUserReporting');
+Set($WebPublicUserSortResults, 0) unless RT->Config->Meta('WebPublicUserSortResults');
 

commit 01237cfb49970f484b9d5c937badb782e7ab29fd
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Tue Jun 27 16:06:18 2017 +0000

    ScrubInlineArticleContent config

diff --git a/README b/README
index a466e4d..6c9fb1b 100644
--- a/README
+++ b/README
@@ -86,6 +86,24 @@ CONFIGURATION
 
         Set($WebPublicUserQueryBuilder, 1);
 
+  WebPublicUserSortResults
+    By default, the web public user cannot click column headers to re-sort
+    search results due to performance implications. To permit this, add this
+    line:
+
+        Set($WebPublicUserSortResults, 1);
+
+  ScrubInlineArticleContent
+    By default, inline articles such as AfterLoginForm are scrubbed for
+    unsafe HTML tags just like ticket correspondence. If your articles are
+    modifiable only by trusted users, you may set this to 0 to pass through
+    article content unscrubbed.
+
+    See the documentation below for "GetArticleContent" for more
+    information.
+
+        Set($ScrubInlineArticleContent, 0);
+
   GetArticleContent
     Searches in articles for content for various configurable pages in the
     BugTracker interface. The article names are available for adding custom
diff --git a/etc/BugTrackerPublic_Config.pm b/etc/BugTrackerPublic_Config.pm
index 693b061..f886646 100644
--- a/etc/BugTrackerPublic_Config.pm
+++ b/etc/BugTrackerPublic_Config.pm
@@ -3,4 +3,5 @@
 Set($WebPublicUser, 'public') unless RT->Config->Meta('WebPublicUser');
 Set($WebPublicUserReporting, 0) unless RT->Config->Meta('WebPublicUserReporting');
 Set($WebPublicUserSortResults, 0) unless RT->Config->Meta('WebPublicUserSortResults');
+Set($ScrubInlineArticleContent, 1) unless RT->Config->Meta('ScrubInlineArticleContent');
 
diff --git a/html/Callbacks/BugTracker-Public/Elements/Login/Default b/html/Callbacks/BugTracker-Public/Elements/Login/Default
index 4df861a..a720e33 100644
--- a/html/Callbacks/BugTracker-Public/Elements/Login/Default
+++ b/html/Callbacks/BugTracker-Public/Elements/Login/Default
@@ -46,5 +46,9 @@
 %#
 %# END BPS TAGGED BLOCK }}}
 
-<% $m->comp( '/Elements/ScrubHTML',
+% if (RT->Config->Get('ScrubInlineArticleContent')) {
+  <% $m->comp( '/Elements/ScrubHTML',
     Content => RT::BugTracker::Public::GetArticleContent('AfterLoginForm')) |n %>
+% } else {
+  <% RT::BugTracker::Public::GetArticleContent('AfterLoginForm') |n %>
+% }
diff --git a/lib/RT/BugTracker/Public.pm b/lib/RT/BugTracker/Public.pm
index 575d7ef..9ab2a75 100644
--- a/lib/RT/BugTracker/Public.pm
+++ b/lib/RT/BugTracker/Public.pm
@@ -170,6 +170,17 @@ results due to performance implications. To permit this, add this line:
 
     Set($WebPublicUserSortResults, 1);
 
+=head2 ScrubInlineArticleContent
+
+By default, inline articles such as AfterLoginForm are scrubbed for unsafe
+HTML tags just like ticket correspondence. If your articles are modifiable
+only by trusted users, you may set this to 0 to pass through article content
+unscrubbed.
+
+See the documentation below for L</GetArticleContent> for more information.
+
+    Set($ScrubInlineArticleContent, 0);
+
 =cut
 
 sub IsPublicUser {

commit cf7299a0ac9896a17bc9c639438001819efcbbdb
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Tue Jun 27 16:06:44 2017 +0000

    1.08 releng

diff --git a/META.yml b/META.yml
index 0b2d0cb..e5d5998 100644
--- a/META.yml
+++ b/META.yml
@@ -24,7 +24,7 @@ requires:
   perl: 5.10.1
 resources:
   license: http://opensource.org/licenses/gpl-license.php
-version: '1.07'
+version: '1.08'
 x_module_install_rtx_version: '0.39'
 x_requires_rt: 4.2.0
 x_rt_too_new: 4.6.0
diff --git a/lib/RT/BugTracker/Public.pm b/lib/RT/BugTracker/Public.pm
index 9ab2a75..a206d6d 100644
--- a/lib/RT/BugTracker/Public.pm
+++ b/lib/RT/BugTracker/Public.pm
@@ -53,7 +53,7 @@ use warnings;
 package RT::BugTracker::Public;
 use URI::Escape qw/ uri_escape /;
 
-our $VERSION = '1.07';
+our $VERSION = '1.08';
 
 RT->AddJavaScript("bugtracker-public.js");
 RT->AddStyleSheets("bugtracker-public.css");

commit 68c4804eb4bd2589d7cef8a78845727879a4bb19
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Mon Jul 10 13:37:26 2017 +0000

    Fix attachment links

diff --git a/html/Public/Bug/Display.html b/html/Public/Bug/Display.html
index fc8e8d5..955ba13 100755
--- a/html/Public/Bug/Display.html
+++ b/html/Public/Bug/Display.html
@@ -67,7 +67,8 @@
       Transactions => $TicketObj->Transactions,
       ShowHeaders => $ARGS{'ShowHeaders'},
       Attachments => $attachments,
-      AttachmentContent => $attachment_content
+      AttachmentContent => $attachment_content,
+      AttachmentPath => RT->Config->Get('WebPath')."/Ticket/Attachment",
 &>
 
 <%ARGS>

commit 5408fe4071d55fdb83411e5c43b466c4658ab916
Author: Jim Brandt <jbrandt at bestpractical.com>
Date:   Wed Feb 24 16:31:48 2021 -0500

    Remove tables for bootstrap div layout

diff --git a/html/Public/Bug/Elements/ShowSummary b/html/Public/Bug/Elements/ShowSummary
index 62192c1..b252e55 100755
--- a/html/Public/Bug/Elements/ShowSummary
+++ b/html/Public/Bug/Elements/ShowSummary
@@ -45,42 +45,44 @@
 %# those contributions and any derivatives thereof.
 %#
 %# END BPS TAGGED BLOCK }}}
-<table width="100%" class="ticket-summary">
-<tr>
-  <td valign="top" class="boxcontainer">
-    <&| /Widgets/TitleBox, title => loc('The Basics'), 
+<div class="row ticket-summary">
+  <div class="boxcontainer col-md-6">
+% $m->callback( %ARGS, CallbackName => 'LeftColumnTop' );
+    <&| /Widgets/TitleBox, title => loc('The Basics'),
         class => 'ticket-info-basics',
     &>
-        <& /Ticket/Elements/ShowBasics, Ticket => $Ticket &>
+            <div class="inline-edit-display">
+                <& /Ticket/Elements/ShowBasics, Ticket => $Ticket &>
+            </div>
     </&>
+% $m->callback( %ARGS, CallbackName => 'AfterBasics' );
 
-    <&| /Widgets/TitleBox, title => loc('People'), 
+    <&| /Widgets/TitleBox, title => loc('People'),
         class => 'ticket-info-people',
     &>
-        <& /Ticket/Elements/ShowPeople, Ticket => $Ticket &>
-    </&>
+            <div class="inline-edit-display">
+                <& /Ticket/Elements/ShowPeople, Ticket => $Ticket &>
+            </div>
+</&>
 
+% $m->callback( %ARGS, CallbackName => 'AfterPeople' );
 % $m->callback( %ARGS, CallbackName => 'LeftColumn' );
+  </div>
+  <div class="boxcontainer col-md-6">
+% $m->callback( %ARGS, CallbackName => 'RightColumnTop' );
 
-  </td>
-  <td valign="top" class="boxcontainer">
-    
-% if ($Ticket->CustomFields->First) {
-    <&| /Widgets/TitleBox, title => loc('Bug Information'),
-        class => 'ticket-info-cfs',
-    &> 
-        <& /Ticket/Elements/ShowCustomFields, Ticket => $Ticket &>
-    </&>
-% }
-
-    <& /Ticket/Elements/ShowAttachments, Ticket => $Ticket, Attachments => $Attachments &>
+<& /Elements/ShowCustomFieldCustomGroupings,
+    Object       => $Ticket,
+    InlineEdit   => 0,
+    &>
 
+    <& /Ticket/Elements/ShowAttachments, Ticket => $Ticket, Attachments => $Attachments, Count => RT->Config->Get('AttachmentListCount') &>
+% $m->callback( %ARGS, CallbackName => 'AfterAttachments' );
 % $m->callback( %ARGS, CallbackName => 'RightColumn' );
-
-  </td>
-</tr>
-</table>
+  </div>
+</div>
 <%ARGS>
 $Ticket => undef
 $Attachments => undef
+$InlineEdit => 0
 </%ARGS>

commit 92628277df651dc77b2e470e3a65c3cb74f7f63c
Author: Jim Brandt <jbrandt at bestpractical.com>
Date:   Thu Feb 25 10:23:24 2021 -0500

    Remove tables from custom Report page

diff --git a/html/Public/Bug/Report.html b/html/Public/Bug/Report.html
index 535581a..a9f0275 100755
--- a/html/Public/Bug/Report.html
+++ b/html/Public/Bug/Report.html
@@ -99,86 +99,60 @@ public and indexed by search engines.
 <form action="<% RT->Config->Get('WebPath') %>/Public/Bug/Report.html" method="POST" enctype="multipart/form-data" name="TicketCreate">
 <input type="hidden" class="hidden" name="id" value="new" />
 <input type="hidden" class="hidden" name="Status" value="new" />
-<div id="Ticket-Create-basics">
+
+<div id="Ticket-Create-basics" class="form-group">
 <a name="basics"></a>
-<table border="0" cellpadding="0" cellspacing="0">
-<tr><td class="label"><&|/l&>Distribution</&>:</td>
-<td class="value"><% $QueueObj->Name %>
+
+<div class="form-row">
+  <div class="label form-group col-3"><&|/l&>Distribution</&>:</div>
+  <div class="value form-group col-9"><% $QueueObj->Name %></div>
+</div>
 <input type="hidden" class="hidden" name="Queue" Value="<%$QueueObj->Name%>">
-</td>
-<tr>
-<td class="label">
-<&|/l&>Your email address</&>:
-</td>
-<td class="value" colspan="5">
-<input name="Requestors" Value="<% ($ARGS{Requestors}) || $session{CurrentUser}->EmailAddress %>" size="40">
-</td>
-</tr>
-<tr>
-<td class="label">
-<&|/l&>Subject</&>:
-</td>
-<td class="value" colspan="5">
-<input name="Subject" size="60" maxsize="100" value="<%$ARGS{Subject} || ''%>">
-</td>
-</tr>
-<tr>
-<td colspan="6">
-  <& /Elements/EditCustomFields,
-     Object => $ticket,
-     CustomFields => $CFs,
-     InTable => 1,
-     KeepValue => 1,
-  &>
-</td>
-</tr>
-% if ($TxnCFs->Count) {
-% while (my $CF = $TxnCFs->Next()) {
-<tr>
-<td align="RIGHT"><% $CF->Name %>:</td>
-<td><& /Elements/EditCustomField, CustomField => $CF, NamePrefix =>
-    "Object-RT::Transaction--CustomField-" &><em><% $CF->FriendlyType %></em></td>
-</td></tr>
-% }
-% }
-<tr>
-% if (exists $session{'Attachments'}) {
-<td class="label">
-<&|/l&>Attached file</&>:
-</td>
-<td colspan="5">
-<&|/l&>Check box to delete</&><br/>
-% foreach my $attach_name (keys %{$session{'Attachments'}}) {
-<input type="checkbox" class="checkbox" name="DeleteAttach-<%$attach_name%>" value="1"><%$attach_name%><br />
-% } # end of foreach
-</td>
-</tr>
-<tr>
-% } # end of if
-<td>
-<&|/l&>Attach file</&>:
-</td>
-<td class="value" colspan="5">
-<input type="FILE" name="Attach">
-<input type="SUBMIT" class="button" name="AddMoreAttach" value="<&|/l&>Add More Files</&>">
-</td>
-</tr>
-<tr>
-<td colspan="6">
-<&|/l&>Describe the issue below</&>:<br/>
+
+<div class="form-row">
+  <div class="label form-group col-3"><&|/l&>Your email address</&>:</div>
+  <div class="value form-group col-9"><input class="form-control" name="Requestors" Value="<% ($ARGS{Requestors}) || $session{CurrentUser}->EmailAddress %>" size="80" maxsize="200"></div>
+</div>
+
+<div class="form-row">
+  <div class="form-group label col-3">
+    <&|/l&>Subject</&>:
+  </div>
+  <div class="form-group value col-9">
+    <input class="form-control" type="text" name="Subject" size="80" maxsize="200" value="<%$ARGS{Subject} || ''%>" />
+% $m->callback( %ARGS, CallbackName => 'AfterSubject' );
+  </div>
+</div>
+
+<& /Elements/EditCustomFields,
+    Object => $ticket,
+    CustomFields => $CFs,
+    InTable => 1,
+    KeepValue => 1,
+    ForCreation => 1,
+&>
+
+<& /Ticket/Elements/EditTransactionCustomFields, %ARGS, QueueObj => $QueueObj, InTable => 1 &>
+<p></p>
+<div class="form-group">
+% $m->callback( %ARGS, QueueObj => $QueueObj, CallbackName => 'BeforeMessageBox' );
 % if (exists $ARGS{Content}) {
-<& /Elements/MessageBox, Default => $ARGS{Content}, IncludeSignature => 0 &>
+  <& /Elements/MessageBox, QueueObj => $QueueObj, Default => $ARGS{Content}, IncludeSignature => 0, IncludeDefaultArticle => 0 &>
+% } elsif ( $QuoteTransaction ) {
+  <& /Elements/MessageBox, QueueObj => $QueueObj, QuoteTransaction => $QuoteTransaction, IncludeDefaultArticle => 0 &>
 % } else {
-<& /Elements/MessageBox, QuoteTransaction => $QuoteTransaction &>
+  <& /Elements/MessageBox, QueueObj => $QueueObj, IncludeDefaultArticle => 1 &>
 %}
-</td>
-</tr>
-<tr>
-<td align="RIGHT" colspan="2">
-</td>
-</tr>
-</table>
-<& /Elements/Submit, Label => loc("Create")&>
+% $m->callback( %ARGS, QueueObj => $QueueObj, CallbackName => 'AfterMessageBox' );
+</div>
+
+<& /Ticket/Elements/AddAttachments, %ARGS, QueueObj => $QueueObj &>
+<div class="form-row">
+  <div class="col-12">
+    <& /Elements/Submit, Label => loc("Create"), Name => 'SubmitTicket', id => 'SubmitTicket' &>
+  </div>
+</div>
+
 </div>
 
 </form>
diff --git a/static/css/bugtracker-public.css b/static/css/bugtracker-public.css
index 3962274..48b9bd6 100644
--- a/static/css/bugtracker-public.css
+++ b/static/css/bugtracker-public.css
@@ -20,13 +20,3 @@
         clear: both;
     }
 }
-
-#reporting-a-bug .edit-custom-field {
-    /* we're in a thinner column most of the time, make room for the default margin */
-    width: 45%;
-}
-
-#reporting-a-bug .edit-custom-field:first-child {
-    display: block;
-    float: none;
-}

commit 33cb6aaa9ee138d7d84676ad1e87793bd47f0d2b
Author: Dianne Skoll <dianne at bestpractical.com>
Date:   Tue Feb 23 15:18:14 2021 -0500

    Update variable name - it changed case to upper-case

diff --git a/lib/RT/BugTracker/Public.pm b/lib/RT/BugTracker/Public.pm
index a206d6d..95b1383 100644
--- a/lib/RT/BugTracker/Public.pm
+++ b/lib/RT/BugTracker/Public.pm
@@ -235,8 +235,8 @@ sub RedirectToPublic {
 }
 
 require RT::Interface::Web;
-%RT::Interface::Web::is_whitelisted_component = (
-    %RT::Interface::Web::is_whitelisted_component,
+%RT::Interface::Web::IS_WHITELISTED_COMPONENT = (
+    %RT::Interface::Web::IS_WHITELISTED_COMPONENT,
     "/Public/Browse.html"            => 1,
     "/Public/Dist/BeginsWith.html"   => 1,
     "/Public/Dist/Browse.html"       => 1,

commit 9cd4e4b2c15df9fdacb413e4a8a212edcbd02b26
Author: Dianne Skoll <dianne at bestpractical.com>
Date:   Tue Feb 23 15:18:56 2021 -0500

    Update Makefile for modern Perl and RT 5.0

diff --git a/Makefile.PL b/Makefile.PL
index 6081b5b..4091cc8 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -1,8 +1,9 @@
+use lib ".";
 use inc::Module::Install;
 
 RTx('RT-BugTracker-Public');
 
 requires_rt('4.2.0');
-rt_too_new('4.6.0');
+rt_too_new('5.2.0');
 
 WriteAll();

commit b152e0721a6fd46e68184d845e1f74e1c3911ec4
Author: Dianne Skoll <dianne at bestpractical.com>
Date:   Tue Feb 23 16:25:05 2021 -0500

    Move custom public user format out of Mason and into RT::User
    
    In core RT, ac4a4a38f6 moved username format methods from
    Mason into lib/RT/User.pm. Update the custom public format
    to align with that change.

diff --git a/html/Elements/ShowUserPublic b/html/Elements/ShowUserPublic
deleted file mode 100644
index 437a8b7..0000000
--- a/html/Elements/ShowUserPublic
+++ /dev/null
@@ -1,68 +0,0 @@
-%# BEGIN BPS TAGGED BLOCK {{{
-%#
-%# COPYRIGHT:
-%#
-%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
-%#                                          <sales at bestpractical.com>
-%#
-%# (Except where explicitly superseded by other copyright notices)
-%#
-%#
-%# LICENSE:
-%#
-%# This work is made available to you under the terms of Version 2 of
-%# the GNU General Public License. A copy of that license should have
-%# been provided with this software, but in any event can be snarfed
-%# from www.gnu.org.
-%#
-%# This work is distributed in the hope that it will be useful, but
-%# WITHOUT ANY WARRANTY; without even the implied warranty of
-%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-%# General Public License for more details.
-%#
-%# You should have received a copy of the GNU General Public License
-%# along with this program; if not, write to the Free Software
-%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-%# 02110-1301 or visit their web page on the internet at
-%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
-%#
-%#
-%# CONTRIBUTION SUBMISSION POLICY:
-%#
-%# (The following paragraph is not intended to limit the rights granted
-%# to you to modify and distribute this software under the terms of
-%# the GNU General Public License and is only of importance to you if
-%# you choose to contribute your changes and enhancements to the
-%# community by submitting them to Best Practical Solutions, LLC.)
-%#
-%# By intentionally submitting any modifications, corrections or
-%# derivatives to this work, or any other work intended for use with
-%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
-%# you are the copyright holder for those contributions and you grant
-%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
-%# royalty-free, perpetual, license to use, copy, create derivative
-%# works based on those contributions, and sublicense and distribute
-%# those contributions and any derivatives thereof.
-%#
-%# END BPS TAGGED BLOCK }}}
-<% $Address || $User->RealName || $User->Name %>\
-<%ARGS>
-$User => undef
-$Address => undef
-</%ARGS>
-<%INIT>
-if ( !$User && $Address ) {
-    $User = RT::User->new( $session{'CurrentUser'} );
-    $User->LoadByEmail( $Address->address );
-    if ( $User->Id ) {
-        $Address = '';
-    } else {
-        $Address = $Address->address;
-    }
-} else {
-    $Address = $User->EmailAddress;
-}
-if ( $Address && RT::BugTracker::Public->IsPublicUser ) {
-    $Address =~ s/@/ [...] /;
-}
-</%INIT>
diff --git a/lib/RT/BugTracker/Public.pm b/lib/RT/BugTracker/Public.pm
index 95b1383..b043220 100644
--- a/lib/RT/BugTracker/Public.pm
+++ b/lib/RT/BugTracker/Public.pm
@@ -296,6 +296,36 @@ sub GetArticleContent {
     return;
 }
 
+# "public" UsernameFormat
+package RT::User;
+
+sub _FormatUserPublic
+{
+    my $self = shift;
+    my %args = @_;
+    my $session = \%HTML::Mason::Commands::session;
+
+    if (!$args{User} && $args{Address}) {
+        $args{User} = RT::User->new( $session->{'CurrentUser'} );
+        $args{User}->LoadByEmail($args{Address}->address);
+        if ($args{User}->Id) {
+            $args{Address} = '';
+        } else {
+            $args{Address} = $args{Address}->address;
+        }
+    } else {
+        $args{Address} = $args{User}->EmailAddress;
+    }
+    if ( $args{Address} && RT::BugTracker::Public->IsPublicUser ) {
+        $args{Address} =~ s/@/ [...] /;
+    }
+
+    return $args{Address} || $args{User}->RealName || $args{User}->Name;
+}
+
+# Switch back to original package
+package RT::BugTracker::Public;
+
 =head1 AUTHOR
 
 Best Practical Solutions, LLC E<lt>modules at bestpractical.comE<gt>

commit 782d189a206947a5a432ec9ae2ac9a191da707ab
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Fri Feb 26 02:48:05 2021 +0800

    Switch to "__Active__" to be consistent with RT core

diff --git a/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged b/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged
index e337e22..e1a0df0 100644
--- a/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged
+++ b/html/Callbacks/BugTracker-Public/Elements/Tabs/Privileged
@@ -135,7 +135,7 @@ if ( $queue and $queue->id ) {
     my $escaped = $m->interp->apply_escapes($queue->Name, 'u');
     PageMenu()->child(
         active_bugs => title => loc("Active bugs"),
-        path => "/Public/Dist/Display.html?Status=Active;Name=" . $escaped,
+        path => "/Public/Dist/Display.html?Status=__Active__;Name=" . $escaped,
     );
 
     PageMenu()->child( resolved_bugs =>
diff --git a/html/Public/Dist/Display.html b/html/Public/Dist/Display.html
index ea5342e..8fe8645 100755
--- a/html/Public/Dist/Display.html
+++ b/html/Public/Dist/Display.html
@@ -77,7 +77,18 @@ unless ( $QueueObj->id ) {
 }
 $ARGS{'Name'} = $Name = $QueueObj->Name;
 
-my $title = loc( "$Status bugs for [_1]", $Name );
+my $status_text;
+if ( $Status =~ /__active__/i ) {
+    $status_text = loc('Active');
+}
+elsif ( $Status =~ /__inactive__/i ) {
+    $status_text = loc('Inactive');
+}
+else {
+    $status_text = $Status;
+}
+
+my $title = loc( "[_1] bugs for [_2]", $status_text, $Name );
 
 my $current_tab = "Public/Dist/Display.html"
     ."?Status=". $m->interp->apply_escapes($Status, 'u')
@@ -91,5 +102,5 @@ $base_url .= '&';
 $Name   => undef
 # Queue is an alias for Name, Name has higher precendance
 $Queue  => undef
-$Status => 'Active'
+$Status => '__Active__'
 </%ARGS>

commit 087236f6c7cdb20f9a9a32729755c4439cfbedad
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Fri Feb 26 02:54:26 2021 +0800

    Sync UI changes from rt-bugtracker

diff --git a/html/Public/Elements/DistributionList b/html/Public/Elements/DistributionList
index 3d1f29b..c145c9f 100644
--- a/html/Public/Elements/DistributionList
+++ b/html/Public/Elements/DistributionList
@@ -45,23 +45,25 @@
 %# those contributions and any derivatives thereof.
 %#
 %# END BPS TAGGED BLOCK }}}
-<div class="dist-list">
-<ul>
+<div class="dist-list row mt-2">
+  <div class="col-6">
+    <ul class="list-group">
 % my $count  = $queues->Count;
 % my $broken = 0;
 %
 % while (my $queue = $queues->Next) {
-% 
+%
 %     if ($count > 10
 %           and not $broken
 %           and $queues->_ItemsCounter >= $count / 2)
 %     {
 %         $broken = 1;
-</ul>
-
-<ul>
+    </ul>
+  </div>
+  <div class="col-6">
+    <ul class="list-group">
 %     }
-  <li>
+  <li class="list-group-item">
     <span class="dist-actions">
       <a href="<% $RT::WebPath %>/Public/Dist/Display.html?Name=<% $queue->Name |u %>">Bug list</a>
 % if (RT->Config->Get('WebPublicUserReporting')) {
@@ -72,7 +74,8 @@
     <strong><% $queue->Name %></strong>
   </li>
 % }
-</ul>
+    </ul>
+  </div>
 </div>
 
 <%args>
diff --git a/html/Public/Elements/ErrorNoDist b/html/Public/Elements/ErrorNoDist
index dcad339..8aa0916 100644
--- a/html/Public/Elements/ErrorNoDist
+++ b/html/Public/Elements/ErrorNoDist
@@ -48,7 +48,7 @@
 <& /Elements/Header, Title => loc("Unable to find distribution") &>
 <& /Elements/Tabs &>
 
-<p>
+<p class="mt-2">
 % if ($Queue) {
   The distribution you specified, <strong><% $Queue %></strong>, could not be found.
 % }
diff --git a/html/Public/Elements/ErrorNoUser b/html/Public/Elements/ErrorNoUser
index 8c94954..c71a323 100644
--- a/html/Public/Elements/ErrorNoUser
+++ b/html/Public/Elements/ErrorNoUser
@@ -48,7 +48,7 @@
 <& /Elements/Header, Title => loc("Unable to find user") &>
 <& /Elements/Tabs &>
 
-<p>
+<p class="mt-2">
   The user you specified, <strong><% $Name %></strong>, could not be found.
 </p>
 
diff --git a/html/Public/index.html b/html/Public/index.html
index a1110f7..29b0e9c 100755
--- a/html/Public/index.html
+++ b/html/Public/index.html
@@ -53,26 +53,50 @@
 % unless (RT->Config->Get('BugTracker_ShowAllDistributions')) {
 <p>
   <form action="<% RT->Config->Get('WebPath') %><% $m->request_path %>" method="get">
-    <label for="form-dist-name"><&|/l&>Find a distribution by full name:</&></label>
-    <input type="text" name="Distribution" id="form-dist-name" data-autocomplete="Queues" data-autocomplete-autosubmit=1 />
-    <input type="submit" class="button" value="<&|/l&>Search</&>" />
+    <div class="form-row">
+      <div class="col-auto label">
+        <&|/l&>Find a distribution by full name:</&>
+      </div>
+      <div class="col-auto">
+        <input type="text" name="Distribution" data-autocomplete="Queues" data-autocomplete-autosubmit=1 autocomplete="off" />
+      </div>
+      <div class="col-auto">
+        <input type="submit" class="button btn btn-primary form-control" value="<&|/l&>Search</&>" />
+      </div>
+    </div>
   </form>
 </p>
 
 <p>
   <form action="<% RT->Config->Get('WebPath') %><% $m->request_path %>" method="get">
-    <label for="form-dist-maint"><&|/l&>Find distributions by maintainer:</&></label>
-    <input type="text" name="Maintainer" id="form-dist-maint" data-autocomplete="Users" data-autocomplete-autosubmit=1 />
-    <input type="submit" class="button" value="<&|/l&>Search</&>" />
+    <div class="form-row">
+      <div class="col-auto label">
+        <&|/l&>Find distributions by maintainer:</&>
+      </div>
+      <div class="col-auto">
+        <input class="form-control" type="text" name="Maintainer" id="form-dist-maint" data-autocomplete="Users" data-autocomplete-autosubmit=1 autocomplete="off" />
+      </div>
+      <div class="col-auto">
+        <input type="submit" class="button btn btn-primary form-control" value="<&|/l&>Search</&>" />
+      </div>
+    </div>
   </form>
 </p>
 % }
 
 <p>
   <form action="/Public/Search/Simple.html" method="get">
-    <label for="form-simple-query"><&|/l&>General search:</&></label>
-    <input type="text" name="q" id="form-simple-query" />
-    <input type="submit" class="button" value="<&|/l&>Search</&>" />
+    <div class="form-row">
+      <div class="col-auto label">
+        <&|/l&>General search:</&>
+      </div>
+      <div class="col-auto">
+        <input class="form-control" type="text" name="q" id="form-simple-query" />
+      </div>
+      <div class="col-auto">
+        <input type="submit" class="button btn btn-primary form-control" value="<&|/l&>Search</&>" />
+      </div>
+    </div>
   </form>
 
   <&|/l&>This search looks for bug report IDs, distribution names, usernames, and bug report descriptions among other fields.</&>

commit a5be552e7afb1599a0051d5f51d22176b76e694f
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Sat Feb 27 06:18:56 2021 +0800

    Fix the one-off issue in DistributionList
    
    Previously the right side had 2 more items than the left side.

diff --git a/html/Public/Elements/DistributionList b/html/Public/Elements/DistributionList
index c145c9f..c621847 100644
--- a/html/Public/Elements/DistributionList
+++ b/html/Public/Elements/DistributionList
@@ -55,7 +55,7 @@
 %
 %     if ($count > 10
 %           and not $broken
-%           and $queues->_ItemsCounter >= $count / 2)
+%           and $queues->_ItemsCounter > $count / 2)
 %     {
 %         $broken = 1;
     </ul>

commit 5559846e537528835b48a92a866e1dce4294f9f1
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Tue Mar 2 04:35:08 2021 +0800

    Update M:I

diff --git a/META.yml b/META.yml
index e5d5998..7d78e6b 100644
--- a/META.yml
+++ b/META.yml
@@ -8,7 +8,7 @@ configure_requires:
   ExtUtils::MakeMaker: 6.59
 distribution_type: module
 dynamic_config: 1
-generated_by: 'Module::Install version 1.18'
+generated_by: 'Module::Install version 1.19'
 license: gpl
 meta-spec:
   url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -25,6 +25,6 @@ requires:
 resources:
   license: http://opensource.org/licenses/gpl-license.php
 version: '1.08'
-x_module_install_rtx_version: '0.39'
+x_module_install_rtx_version: '0.42'
 x_requires_rt: 4.2.0
 x_rt_too_new: 4.6.0
diff --git a/inc/Module/Install.pm b/inc/Module/Install.pm
index 07525c5..7ba98c2 100644
--- a/inc/Module/Install.pm
+++ b/inc/Module/Install.pm
@@ -31,7 +31,7 @@ BEGIN {
 	# This is not enforced yet, but will be some time in the next few
 	# releases once we can make sure it won't clash with custom
 	# Module::Install extensions.
-	$VERSION = '1.18';
+	$VERSION = '1.19';
 
 	# Storage for the pseudo-singleton
 	$MAIN    = undef;
diff --git a/inc/Module/Install/Base.pm b/inc/Module/Install/Base.pm
index b61d424..9fa42c2 100644
--- a/inc/Module/Install/Base.pm
+++ b/inc/Module/Install/Base.pm
@@ -4,7 +4,7 @@ package Module::Install::Base;
 use strict 'vars';
 use vars qw{$VERSION};
 BEGIN {
-	$VERSION = '1.18';
+	$VERSION = '1.19';
 }
 
 # Suspend handler for "redefined" warnings
diff --git a/inc/Module/Install/Can.pm b/inc/Module/Install/Can.pm
index 1de368c..d65c753 100644
--- a/inc/Module/Install/Can.pm
+++ b/inc/Module/Install/Can.pm
@@ -8,7 +8,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '1.18';
+	$VERSION = '1.19';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
diff --git a/inc/Module/Install/Fetch.pm b/inc/Module/Install/Fetch.pm
index 54b52cb..3072b08 100644
--- a/inc/Module/Install/Fetch.pm
+++ b/inc/Module/Install/Fetch.pm
@@ -6,7 +6,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '1.18';
+	$VERSION = '1.19';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
diff --git a/inc/Module/Install/Include.pm b/inc/Module/Install/Include.pm
index 087da8d..13fdcd0 100644
--- a/inc/Module/Install/Include.pm
+++ b/inc/Module/Install/Include.pm
@@ -6,7 +6,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '1.18';
+	$VERSION = '1.19';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
diff --git a/inc/Module/Install/Makefile.pm b/inc/Module/Install/Makefile.pm
index 8ba3d88..13a4464 100644
--- a/inc/Module/Install/Makefile.pm
+++ b/inc/Module/Install/Makefile.pm
@@ -8,7 +8,7 @@ use Fcntl qw/:flock :seek/;
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '1.18';
+	$VERSION = '1.19';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
diff --git a/inc/Module/Install/Metadata.pm b/inc/Module/Install/Metadata.pm
index 692ce71..11bf971 100644
--- a/inc/Module/Install/Metadata.pm
+++ b/inc/Module/Install/Metadata.pm
@@ -6,7 +6,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '1.18';
+	$VERSION = '1.19';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
diff --git a/inc/Module/Install/RTx.pm b/inc/Module/Install/RTx.pm
index 3268e7e..2dd9489 100644
--- a/inc/Module/Install/RTx.pm
+++ b/inc/Module/Install/RTx.pm
@@ -6,9 +6,10 @@ use strict;
 use warnings;
 no warnings 'once';
 
+use Term::ANSIColor qw(:constants);
 use Module::Install::Base;
 use base 'Module::Install::Base';
-our $VERSION = '0.39';
+our $VERSION = '0.42';
 
 use FindBin;
 use File::Glob     ();
@@ -53,7 +54,7 @@ sub RTx {
         my @look = @INC;
         unshift @look, grep {defined and -d $_} @try;
         push @look, grep {defined and -d $_}
-            map { ( "$_/rt4/lib", "$_/lib/rt4", "$_/lib" ) } @prefixes;
+            map { ( "$_/rt5/lib", "$_/lib/rt5", "$_/rt4/lib", "$_/lib/rt4", "$_/lib" ) } @prefixes;
         last if eval {local @INC = @look; require RT; $RT::LocalLibPath};
 
         warn
@@ -76,6 +77,22 @@ sub RTx {
         $self->requires_rt('4.0.0');
     }
 
+    my $package = $name;
+    $package =~ s/-/::/g;
+    if ( $RT::CORED_PLUGINS{$package} ) {
+        my ($base_version) = $RT::VERSION =~ /(\d+\.\d+\.\d+)/;
+        die RED, <<"EOT";
+
+**** Error: Your installed version of RT ($RT::VERSION) already
+            contains this extension in core, so you don't need to
+            install it.
+
+            Check https://docs.bestpractical.com/rt/$base_version/RT_Config.html
+            to configure it.
+
+EOT
+    }
+
     # Installation locations
     my %path;
     my $plugin_path;
@@ -223,7 +240,7 @@ sub requires_rt {
     my @sorted = sort RT::Handle::cmp_version $version,$RT::VERSION;
 
     if ($sorted[-1] eq $version) {
-        die <<"EOT";
+        die RED, <<"EOT";
 
 **** Error: This extension requires RT $version. Your installed version
             of RT ($RT::VERSION) is too old.
@@ -249,12 +266,12 @@ sub requires_rt_plugin {
         unshift @INC, $path;
     } else {
         my $name = $self->name;
-        warn <<"EOT";
+        my $msg = <<"EOT";
 
 **** Warning: $name requires that the $plugin plugin be installed and
               enabled; it does not appear to be installed.
-
 EOT
+        warn RED, $msg, RESET, "\n";
     }
     $self->requires(@_);
 }
@@ -264,9 +281,8 @@ sub rt_too_new {
     my $name = $self->name;
     $msg ||= <<EOT;
 
-**** Error: Your installed version of RT (%s) is too new; this extension
-            only works with versions older than %s.
-
+**** Warning: Your installed version of RT (%s) is too new; this extension
+              has not been tested on your version of RT and may not work as expected.
 EOT
     $self->add_metadata("x_rt_too_new", $version) if $self->is_admin;
 
@@ -274,7 +290,7 @@ EOT
     my @sorted = sort RT::Handle::cmp_version $version,$RT::VERSION;
 
     if ($sorted[0] eq $version) {
-        die sprintf($msg,$RT::VERSION,$version);
+        warn RED, sprintf($msg,$RT::VERSION), RESET, "\n";
     }
 }
 
@@ -297,4 +313,4 @@ sub _load_rt_handle {
 
 __END__
 
-#line 468
+#line 484
diff --git a/inc/Module/Install/RTx/Runtime.pm b/inc/Module/Install/RTx/Runtime.pm
index 937949f..ae07502 100644
--- a/inc/Module/Install/RTx/Runtime.pm
+++ b/inc/Module/Install/RTx/Runtime.pm
@@ -33,6 +33,7 @@ sub RTxDatabase {
 
     my $lib_path = File::Basename::dirname($INC{'RT.pm'});
     my @args = (
+        "-I.",
         "-Ilib",
         "-I$RT::LocalLibPath",
         "-I$lib_path",
diff --git a/inc/Module/Install/Win32.pm b/inc/Module/Install/Win32.pm
index b80c900..f7aa615 100644
--- a/inc/Module/Install/Win32.pm
+++ b/inc/Module/Install/Win32.pm
@@ -6,7 +6,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '1.18';
+	$VERSION = '1.19';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
diff --git a/inc/Module/Install/WriteAll.pm b/inc/Module/Install/WriteAll.pm
index da279c7..2db861a 100644
--- a/inc/Module/Install/WriteAll.pm
+++ b/inc/Module/Install/WriteAll.pm
@@ -6,7 +6,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '1.18';
+	$VERSION = '1.19';
 	@ISA     = qw{Module::Install::Base};
 	$ISCORE  = 1;
 }
diff --git a/inc/YAML/Tiny.pm b/inc/YAML/Tiny.pm
index 4fd023d..fb157a6 100644
--- a/inc/YAML/Tiny.pm
+++ b/inc/YAML/Tiny.pm
@@ -2,12 +2,12 @@
 use 5.008001; # sane UTF-8 support
 use strict;
 use warnings;
-package YAML::Tiny; # git description: v1.69-8-g2c1e266
+package YAML::Tiny; # git description: v1.72-7-g8682f63
 # XXX-INGY is 5.8.1 too old/broken for utf8?
 # XXX-XDG Lancaster consensus was that it was sufficient until
 # proven otherwise
 
-our $VERSION = '1.70';
+our $VERSION = '1.73';
 
 #####################################################################
 # The YAML::Tiny API.
@@ -374,7 +374,7 @@ sub _load_scalar {
     while ( @$lines ) {
         $lines->[0] =~ /^(\s*)/;
         last unless length($1) >= $indent->[-1];
-        push @multiline, substr(shift(@$lines), length($1));
+        push @multiline, substr(shift(@$lines), $indent->[-1]);
     }
 
     my $j = (substr($string, 0, 1) eq '>') ? ' ' : "\n";
diff --git a/inc/unicore/Name.pm b/inc/unicore/Name.pm
deleted file mode 100644
index 15e729b..0000000
--- a/inc/unicore/Name.pm
+++ /dev/null
@@ -1,416 +0,0 @@
-#line 1
-# !!!!!!!   DO NOT EDIT THIS FILE   !!!!!!!
-# This file is machine-generated by lib/unicore/mktables from the Unicode
-# database, Version 6.2.0.  Any changes made here will be lost!
-
-
-# !!!!!!!   INTERNAL PERL USE ONLY   !!!!!!!
-# This file is for internal use by core Perl only.  The format and even the
-# name or existence of this file are subject to change without notice.  Don't
-# use it directly.
-
-
-package charnames;
-
-# This module contains machine-generated tables and code for the
-# algorithmically-determinable Unicode character names.  The following
-# routines can be used to translate between name and code point and vice versa
-
-{ # Closure
-
-    # Matches legal code point.  4-6 hex numbers, If there are 6, the first
-    # two must be 10; if there are 5, the first must not be a 0.  Written this
-    # way to decrease backtracking.  The first regex allows the code point to
-    # be at the end of a word, but to work properly, the word shouldn't end
-    # with a valid hex character.  The second one won't match a code point at
-    # the end of a word, and doesn't have the run-on issue
-    my $run_on_code_point_re = qr/(?^aax: (?: 10[0-9A-F]{4} | [1-9A-F][0-9A-F]{4} | [0-9A-F]{4} ) \b)/;
-    my $code_point_re = qr/(?^aa:\b(?^aax: (?: 10[0-9A-F]{4} | [1-9A-F][0-9A-F]{4} | [0-9A-F]{4} ) \b))/;
-
-    # In the following hash, the keys are the bases of names which include
-    # the code point in the name, like CJK UNIFIED IDEOGRAPH-4E01.  The value
-    # of each key is another hash which is used to get the low and high ends
-    # for each range of code points that apply to the name.
-    my %names_ending_in_code_point = (
-'CJK COMPATIBILITY IDEOGRAPH' => 
-{
-'high' => 
-[
-64109,
-64217,
-195101,
-],
-'low' => 
-[
-63744,
-64112,
-194560,
-],
-},
-'CJK UNIFIED IDEOGRAPH' => 
-{
-'high' => 
-[
-19893,
-40908,
-173782,
-177972,
-178205,
-],
-'low' => 
-[
-13312,
-19968,
-131072,
-173824,
-177984,
-],
-},
-
-    );
-
-    # The following hash is a copy of the previous one, except is for loose
-    # matching, so each name has blanks and dashes squeezed out
-    my %loose_names_ending_in_code_point = (
-'CJKCOMPATIBILITYIDEOGRAPH' => 
-{
-'high' => 
-[
-64109,
-64217,
-195101,
-],
-'low' => 
-[
-63744,
-64112,
-194560,
-],
-},
-'CJKUNIFIEDIDEOGRAPH' => 
-{
-'high' => 
-[
-19893,
-40908,
-173782,
-177972,
-178205,
-],
-'low' => 
-[
-13312,
-19968,
-131072,
-173824,
-177984,
-],
-},
-
-    );
-
-    # And the following array gives the inverse mapping from code points to
-    # names.  Lowest code points are first
-    my @code_points_ending_in_code_point = (
-
-{
-'high' => 19893,
-'low' => 13312,
-'name' => 'CJK UNIFIED IDEOGRAPH',
-},
-{
-'high' => 40908,
-'low' => 19968,
-'name' => 'CJK UNIFIED IDEOGRAPH',
-},
-{
-'high' => 64109,
-'low' => 63744,
-'name' => 'CJK COMPATIBILITY IDEOGRAPH',
-},
-{
-'high' => 64217,
-'low' => 64112,
-'name' => 'CJK COMPATIBILITY IDEOGRAPH',
-},
-{
-'high' => 173782,
-'low' => 131072,
-'name' => 'CJK UNIFIED IDEOGRAPH',
-},
-{
-'high' => 177972,
-'low' => 173824,
-'name' => 'CJK UNIFIED IDEOGRAPH',
-},
-{
-'high' => 178205,
-'low' => 177984,
-'name' => 'CJK UNIFIED IDEOGRAPH',
-},
-{
-'high' => 195101,
-'low' => 194560,
-'name' => 'CJK COMPATIBILITY IDEOGRAPH',
-},
-,
-
-    );
-
-    # Convert from code point to Jamo short name for use in composing Hangul
-    # syllable names
-    my %Jamo = (
-4352 => 'G',
-4353 => 'GG',
-4354 => 'N',
-4355 => 'D',
-4356 => 'DD',
-4357 => 'R',
-4358 => 'M',
-4359 => 'B',
-4360 => 'BB',
-4361 => 'S',
-4362 => 'SS',
-4363 => '',
-4364 => 'J',
-4365 => 'JJ',
-4366 => 'C',
-4367 => 'K',
-4368 => 'T',
-4369 => 'P',
-4370 => 'H',
-4449 => 'A',
-4450 => 'AE',
-4451 => 'YA',
-4452 => 'YAE',
-4453 => 'EO',
-4454 => 'E',
-4455 => 'YEO',
-4456 => 'YE',
-4457 => 'O',
-4458 => 'WA',
-4459 => 'WAE',
-4460 => 'OE',
-4461 => 'YO',
-4462 => 'U',
-4463 => 'WEO',
-4464 => 'WE',
-4465 => 'WI',
-4466 => 'YU',
-4467 => 'EU',
-4468 => 'YI',
-4469 => 'I',
-4520 => 'G',
-4521 => 'GG',
-4522 => 'GS',
-4523 => 'N',
-4524 => 'NJ',
-4525 => 'NH',
-4526 => 'D',
-4527 => 'L',
-4528 => 'LG',
-4529 => 'LM',
-4530 => 'LB',
-4531 => 'LS',
-4532 => 'LT',
-4533 => 'LP',
-4534 => 'LH',
-4535 => 'M',
-4536 => 'B',
-4537 => 'BS',
-4538 => 'S',
-4539 => 'SS',
-4540 => 'NG',
-4541 => 'J',
-4542 => 'C',
-4543 => 'K',
-4544 => 'T',
-4545 => 'P',
-4546 => 'H',
-
-    );
-
-    # Leading consonant (can be null)
-    my %Jamo_L = (
-'' => 11,
-'B' => 7,
-'BB' => 8,
-'C' => 14,
-'D' => 3,
-'DD' => 4,
-'G' => 0,
-'GG' => 1,
-'H' => 18,
-'J' => 12,
-'JJ' => 13,
-'K' => 15,
-'M' => 6,
-'N' => 2,
-'P' => 17,
-'R' => 5,
-'S' => 9,
-'SS' => 10,
-'T' => 16,
-
-    );
-
-    # Vowel
-    my %Jamo_V = (
-'A' => 0,
-'AE' => 1,
-'E' => 5,
-'EO' => 4,
-'EU' => 18,
-'I' => 20,
-'O' => 8,
-'OE' => 11,
-'U' => 13,
-'WA' => 9,
-'WAE' => 10,
-'WE' => 15,
-'WEO' => 14,
-'WI' => 16,
-'YA' => 2,
-'YAE' => 3,
-'YE' => 7,
-'YEO' => 6,
-'YI' => 19,
-'YO' => 12,
-'YU' => 17,
-
-    );
-
-    # Optional trailing consonant
-    my %Jamo_T = (
-'B' => 17,
-'BS' => 18,
-'C' => 23,
-'D' => 7,
-'G' => 1,
-'GG' => 2,
-'GS' => 3,
-'H' => 27,
-'J' => 22,
-'K' => 24,
-'L' => 8,
-'LB' => 11,
-'LG' => 9,
-'LH' => 15,
-'LM' => 10,
-'LP' => 14,
-'LS' => 12,
-'LT' => 13,
-'M' => 16,
-'N' => 4,
-'NG' => 21,
-'NH' => 6,
-'NJ' => 5,
-'P' => 26,
-'S' => 19,
-'SS' => 20,
-'T' => 25,
-
-    );
-
-    # Computed re that splits up a Hangul name into LVT or LV syllables
-    my $syllable_re = qr/(|B|BB|C|D|DD|G|GG|H|J|JJ|K|M|N|P|R|S|SS|T)(A|AE|E|EO|EU|I|O|OE|U|WA|WAE|WE|WEO|WI|YA|YAE|YE|YEO|YI|YO|YU)(B|BS|C|D|G|GG|GS|H|J|K|L|LB|LG|LH|LM|LP|LS|LT|M|N|NG|NH|NJ|P|S|SS|T)?/;
-
-    my $HANGUL_SYLLABLE = "HANGUL SYLLABLE ";
-    my $loose_HANGUL_SYLLABLE = "HANGULSYLLABLE";
-
-    # These constants names and values were taken from the Unicode standard,
-    # version 5.1, section 3.12.  They are used in conjunction with Hangul
-    # syllables
-    my $SBase = 0xAC00;
-    my $LBase = 0x1100;
-    my $VBase = 0x1161;
-    my $TBase = 0x11A7;
-    my $SCount = 11172;
-    my $LCount = 19;
-    my $VCount = 21;
-    my $TCount = 28;
-    my $NCount = $VCount * $TCount;
-
-    sub name_to_code_point_special {
-        my ($name, $loose) = @_;
-
-        # Returns undef if not one of the specially handled names; otherwise
-        # returns the code point equivalent to the input name
-        # $loose is non-zero if to use loose matching, 'name' in that case
-        # must be input as upper case with all blanks and dashes squeezed out.
-
-        if ((! $loose && $name =~ s/$HANGUL_SYLLABLE//)
-            || ($loose && $name =~ s/$loose_HANGUL_SYLLABLE//))
-        {
-            return if $name !~ qr/^$syllable_re$/;
-            my $L = $Jamo_L{$1};
-            my $V = $Jamo_V{$2};
-            my $T = (defined $3) ? $Jamo_T{$3} : 0;
-            return ($L * $VCount + $V) * $TCount + $T + $SBase;
-        }
-
-        # Name must end in 'code_point' for this to handle.
-        return if (($loose && $name !~ /^ (.*?) ($run_on_code_point_re) $/x)
-                   || (! $loose && $name !~ /^ (.*) ($code_point_re) $/x));
-
-        my $base = $1;
-        my $code_point = CORE::hex $2;
-        my $names_ref;
-
-        if ($loose) {
-            $names_ref = \%loose_names_ending_in_code_point;
-        }
-        else {
-            return if $base !~ s/-$//;
-            $names_ref = \%names_ending_in_code_point;
-        }
-
-        # Name must be one of the ones which has the code point in it.
-        return if ! $names_ref->{$base};
-
-        # Look through the list of ranges that apply to this name to see if
-        # the code point is in one of them.
-        for (my $i = 0; $i < scalar @{$names_ref->{$base}{'low'}}; $i++) {
-            return if $names_ref->{$base}{'low'}->[$i] > $code_point;
-            next if $names_ref->{$base}{'high'}->[$i] < $code_point;
-
-            # Here, the code point is in the range.
-            return $code_point;
-        }
-
-        # Here, looked like the name had a code point number in it, but
-        # did not match one of the valid ones.
-        return;
-    }
-
-    sub code_point_to_name_special {
-        my $code_point = shift;
-
-        # Returns the name of a code point if algorithmically determinable;
-        # undef if not
-
-        # If in the Hangul range, calculate the name based on Unicode's
-        # algorithm
-        if ($code_point >= $SBase && $code_point <= $SBase + $SCount -1) {
-            use integer;
-            my $SIndex = $code_point - $SBase;
-            my $L = $LBase + $SIndex / $NCount;
-            my $V = $VBase + ($SIndex % $NCount) / $TCount;
-            my $T = $TBase + $SIndex % $TCount;
-            $name = "$HANGUL_SYLLABLE$Jamo{$L}$Jamo{$V}";
-            $name .= $Jamo{$T} if $T != $TBase;
-            return $name;
-        }
-
-        # Look through list of these code points for one in range.
-        foreach my $hash (@code_points_ending_in_code_point) {
-            return if $code_point < $hash->{'low'};
-            if ($code_point <= $hash->{'high'}) {
-                return sprintf("%s-%04X", $hash->{'name'}, $code_point);
-            }
-        }
-        return;            # None found
-    }
-} # End closure
-
-1;

commit d924e8212762ea8ec190dfafd2e3ffa3675e9a12
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Tue Mar 2 04:36:32 2021 +0800

    Update package info

diff --git a/MANIFEST b/MANIFEST
index 5c0002b..305c900 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -10,7 +10,6 @@ html/Callbacks/BugTracker-Public/NoAuth/Logout.html/AfterSessionDelete
 html/Callbacks/BugTracker-Public/NoAuth/Logout.html/Default
 html/Callbacks/BugTracker-Public/Search/Results.html/Initial
 html/Callbacks/BugTracker-Public/Ticket/Elements/ShowMessageHeaders/Default
-html/Elements/ShowUserPublic
 html/Public/autohandler
 html/Public/Browse.html
 html/Public/Bug/Display.html
@@ -43,7 +42,6 @@ inc/Module/Install/RTx.pm
 inc/Module/Install/RTx/Runtime.pm
 inc/Module/Install/Win32.pm
 inc/Module/Install/WriteAll.pm
-inc/unicore/Name.pm
 inc/YAML/Tiny.pm
 lib/RT/BugTracker/Public.pm
 Makefile.PL
diff --git a/META.yml b/META.yml
index 7d78e6b..fed50a9 100644
--- a/META.yml
+++ b/META.yml
@@ -27,4 +27,4 @@ resources:
 version: '1.08'
 x_module_install_rtx_version: '0.42'
 x_requires_rt: 4.2.0
-x_rt_too_new: 4.6.0
+x_rt_too_new: 5.2.0

commit b72305dcf5c66cb3da9254bd3e224b7449682157
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Tue Mar 2 04:37:32 2021 +0800

    Update doc for rt4 => rt5

diff --git a/README b/README
index 6c9fb1b..a8c796d 100644
--- a/README
+++ b/README
@@ -33,13 +33,13 @@ INSTALLATION
         May need root permissions
 
     make initdb
-    Edit your /opt/rt4/etc/RT_SiteConfig.pm
+    Edit your /opt/rt5/etc/RT_SiteConfig.pm
         Add this line:
 
             Plugin('RT::BugTracker::Public');
 
     Clear your mason cache
-            rm -rf /opt/rt4/var/mason_data/obj
+            rm -rf /opt/rt5/var/mason_data/obj
 
     Restart your webserver
 
diff --git a/lib/RT/BugTracker/Public.pm b/lib/RT/BugTracker/Public.pm
index b043220..64e460f 100644
--- a/lib/RT/BugTracker/Public.pm
+++ b/lib/RT/BugTracker/Public.pm
@@ -102,7 +102,7 @@ May need root permissions
 
 =item C<make initdb>
 
-=item Edit your F</opt/rt4/etc/RT_SiteConfig.pm>
+=item Edit your F</opt/rt5/etc/RT_SiteConfig.pm>
 
 Add this line:
 
@@ -110,7 +110,7 @@ Add this line:
 
 =item Clear your mason cache
 
-    rm -rf /opt/rt4/var/mason_data/obj
+    rm -rf /opt/rt5/var/mason_data/obj
 
 =item Restart your webserver
 

commit afdcd7b6596cdd76a011e7f641841d064532c0bf
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Tue Mar 2 04:38:28 2021 +0800

    Bump minimal RT version to 5.0

diff --git a/META.yml b/META.yml
index fed50a9..de03ace 100644
--- a/META.yml
+++ b/META.yml
@@ -26,5 +26,5 @@ resources:
   license: http://opensource.org/licenses/gpl-license.php
 version: '1.08'
 x_module_install_rtx_version: '0.42'
-x_requires_rt: 4.2.0
+x_requires_rt: 5.0.0
 x_rt_too_new: 5.2.0
diff --git a/Makefile.PL b/Makefile.PL
index 4091cc8..a8da22d 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -3,7 +3,7 @@ use inc::Module::Install;
 
 RTx('RT-BugTracker-Public');
 
-requires_rt('4.2.0');
+requires_rt('5.0.0');
 rt_too_new('5.2.0');
 
 WriteAll();

commit 7a6035d92328a711c2fe50afcdfd5456dc9387ea
Merge: 66987ba afdcd7b
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Tue Mar 2 04:39:13 2021 +0800

    Merge branch '5.0-updates'


-----------------------------------------------------------------------


More information about the Bps-public-commit mailing list