diff --git a/README.md b/README.md
index b726fd6..7b4adac 100644
--- a/README.md
+++ b/README.md
@@ -250,12 +250,28 @@ GET http[s]://your-server/path-to-file/mdcountdata.php?id=BLAH
]
```
-## Potential Enhancements
+## Counter Reports
-* Check the IP address of the viewer, if found in a configurable *known IP list* the count is not incremented.
- * **NOTE**: When a markdown file with this hit counter is viewed *through* GitHub the IP address will always be within a specific range owned by GitHub.
- * One of my other utilites, [getfqdnip](https://github.com/jxmot/getfqdnip) could be part of the solution.
-
+The following files are used in report generation and viewing:
+
+* `mdreport.php` - Retrieves the counter data and renders a Bootstrap 4.x table.
+ * `mdreport.css` - Additional required CSS for the table
+ * `mdreport-th.txt` - Column heading text
+ * `stddefines.php` - A collection of `define()` that make a number of PHP variables available to the application. It contains components used for creating URLs to resources.
+* `report.html` - The minimum required HTML/CSS and JavaScript/jQuery to render and display the table.
+ * **Other Dependencies** : The "tool tips" used on the column headings are created with [tippy.js]().
+
+**Report Screen Shot :**
+
+
+
+The "Hit Count", "Repository" and "Last Counted" headings can be clicked to select sorting criteria and direction (*ascending vs descending*). When a column heading is clicked the report caption will change to reflect the choice.
+
+**NOTES :**
+* The links in the "Repository" column and built from the IDs found in `counters.json`. The ID text I used there is the *name of the repository* that the counter is intended for. The corresponding counter data files are named `repo-name`**`_counter.json`**.
+* When the report is viewed the data shown is *current*.
+* If the "Last Counted" column date and time seem to be incorrect then the time zone may need to be changed. Edit the `timezone.json` file to match your time zone.
+
## Other Uses
You could count just about anything. All you need is to do a GET of `mdcount.php` with a proper query and you got it!
diff --git a/mdimg/report_sshot.png b/mdimg/report_sshot.png
new file mode 100644
index 0000000..7946670
Binary files /dev/null and b/mdimg/report_sshot.png differ
diff --git a/mdreport-th.txt b/mdreport-th.txt
new file mode 100644
index 0000000..ac948d5
--- /dev/null
+++ b/mdreport-th.txt
@@ -0,0 +1 @@
+Rank,Hit Count,Repository,Last Counted
\ No newline at end of file
diff --git a/mdreport.css b/mdreport.css
new file mode 100644
index 0000000..3b80c4d
--- /dev/null
+++ b/mdreport.css
@@ -0,0 +1,35 @@
+div.table-container {
+ width:80%;
+ margin:auto;
+}
+
+tr th {
+ text-align:center;
+}
+
+tr td {
+ text-align:center;
+}
+
+table caption {
+ caption-side:top;
+ text-align:center;
+ color:black;
+ font-weight:bold;
+}
+
+.sort-arrow-up:after {
+ font-weight:bold;
+ content: "\25B2"!important;
+}
+
+.sort-arrow-dn:after {
+ font-weight:bold;
+ content: "\25BC"!important;
+}
+
+.orderhover:hover {
+ cursor:pointer!important;
+ background-color: rgba(189, 183, 137, 1);
+ border-radius: 15px 50px;
+}
diff --git a/mdreport.php b/mdreport.php
new file mode 100644
index 0000000..c039b37
--- /dev/null
+++ b/mdreport.php
@@ -0,0 +1,144 @@
+
+define('_DEBUGDEF', false);
+require_once './stddefines.php';
+
+// get the configured time zone
+function tzone() {
+ $tmp = json_decode(file_get_contents('./tzone.json'));
+ return $tmp->tz;
+}
+
+// check for debug/test mode
+if(!defined('_DEBUG') || _DEBUG === false) {
+
+ $mdcountdata = (isset($queries['mdcdata']) ? strtolower($queries['mdcdata']) : THISSRVR.'/mdcountdata.php');
+
+ // MUST be done like this for PHP files that are 'linked'
+ $queries = array();
+ parse_str($_SERVER['QUERY_STRING'], $queries);
+ // return all counters, ordered by count
+ $csort = (isset($queries['csort']) ? strtolower($queries['csort']) : null);
+ // return all counters, ordered by time of last count
+ $tsort = (isset($queries['tsort']) ? strtolower($queries['tsort']) : null);
+ // return all counters, ordered by ID
+ $isort = (isset($queries['isort']) ? strtolower($queries['isort']) : null);
+ // for sorts, limit number of counters returned
+ $limit = (isset($queries['limit']) ? $queries['limit'] : null);
+} else {
+ if(isset($_SERVER['QUERY_STRING'])) {
+ $q = $_SERVER['QUERY_STRING'];
+ echo "