diff --git a/.gitignore b/.gitignore
index dabf315..dc97b1c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,4 +2,5 @@
/nizika_nizika
/nml
/nizika_nml
+/log.txt
diff --git a/broadcast/.gitignore b/broadcast/.gitignore
new file mode 100644
index 0000000..686adb2
--- /dev/null
+++ b/broadcast/.gitignore
@@ -0,0 +1,3 @@
+/log.txt
+/log2.txt
+
diff --git a/broadcast/favicon.ico b/broadcast/favicon.ico
new file mode 100644
index 0000000..64f57c4
Binary files /dev/null and b/broadcast/favicon.ico differ
diff --git a/broadcast/index.frm.php b/broadcast/index.frm.php
new file mode 100644
index 0000000..8b3720f
--- /dev/null
+++ b/broadcast/index.frm.php
@@ -0,0 +1,138 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ 伊地知ニジカ放送局 - ニジカ返答ログ
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0): ?>
+
+
+
+
+
+
+
+
+ = $record['date_time'] ?>
+
+
+
+
+ = $record['chat_name'] ?>
+
+
+
+ > = $record['chat_message'] ?>
+
+
+
+ = $record['answer'] ?>
+
+
+
+
+
+
+
+
+
+ 何も見つかりませんでしたぬ゛ぅ゛ぅ゛ぅ゛ぅ゛ん゛
+
+
+
+
+
+
+
+
diff --git a/broadcast/index.php b/broadcast/index.php
new file mode 100644
index 0000000..67438a0
--- /dev/null
+++ b/broadcast/index.php
@@ -0,0 +1,65 @@
+ $dt[0],
+ 'chat_icon' => $chat_info -> author -> imageUrl,
+ 'chat_name' => $escaped ? htmlspecialchars ($chat_info -> author -> name) : $chat_info -> author -> name,
+ 'chat_message' => $escaped ? htmlspecialchars ($chat_info -> message) : $chat_info -> message,
+ 'answer' => $escaped ? htmlspecialchars ($dt[2]) : $dt[2]];
+ }
+ }
+
+fclose ($f);
+
+unset ($f);
+
+if ($keyword != '')
+ {
+ $log_data = array_filter ($log_data, fn ($row) => (
+ strpos ($row['chat_name'] . "\n" . $row['chat_message'] . "\n" . $row['answer'],
+ $keyword)
+ !== false));
+ }
+
+if ($date_start)
+ {
+ $log_data = array_filter ($log_data, fn ($row) => (
+ substr ($row['date_time'], 0, 10) >= $date_start));
+ }
+
+if ($date_end)
+ {
+ $log_data = array_filter ($log_data, fn ($row) => (
+ substr ($row['date_time'], 0, 10) <= $date_end));
+ }
+
+$pages_max = (int) ((count ($log_data) - 1) / $length) + 1;
+
+if (!($asc))
+ $log_data = array_reverse ($log_data);
+
+require_once './index.frm.php';
+
diff --git a/broadcast/modules/jquery.cookie-1.4.1.min.js b/broadcast/modules/jquery.cookie-1.4.1.min.js
new file mode 100644
index 0000000..c0f19d8
--- /dev/null
+++ b/broadcast/modules/jquery.cookie-1.4.1.min.js
@@ -0,0 +1,2 @@
+/*! jquery.cookie v1.4.1 | MIT */
+!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof exports?a(require("jquery")):a(jQuery)}(function(a){function b(a){return h.raw?a:encodeURIComponent(a)}function c(a){return h.raw?a:decodeURIComponent(a)}function d(a){return b(h.json?JSON.stringify(a):String(a))}function e(a){0===a.indexOf('"')&&(a=a.slice(1,-1).replace(/\\"/g,'"').replace(/\\\\/g,"\\"));try{return a=decodeURIComponent(a.replace(g," ")),h.json?JSON.parse(a):a}catch(b){}}function f(b,c){var d=h.raw?b:e(b);return a.isFunction(c)?c(d):d}var g=/\+/g,h=a.cookie=function(e,g,i){if(void 0!==g&&!a.isFunction(g)){if(i=a.extend({},h.defaults,i),"number"==typeof i.expires){var j=i.expires,k=i.expires=new Date;k.setTime(+k+864e5*j)}return document.cookie=[b(e),"=",d(g),i.expires?"; expires="+i.expires.toUTCString():"",i.path?"; path="+i.path:"",i.domain?"; domain="+i.domain:"",i.secure?"; secure":""].join("")}for(var l=e?void 0:{},m=document.cookie?document.cookie.split("; "):[],n=0,o=m.length;o>n;n++){var p=m[n].split("="),q=c(p.shift()),r=p.join("=");if(e&&e===q){l=f(r,g);break}e||void 0===(r=f(r))||(l[q]=r)}return l};h.defaults={},a.removeCookie=function(b,c){return void 0===a.cookie(b)?!1:(a.cookie(b,"",a.extend({},c,{expires:-1})),!a.cookie(b))}});
\ No newline at end of file
diff --git a/broadcast/pagination.cmp.php b/broadcast/pagination.cmp.php
new file mode 100644
index 0000000..4c88f00
--- /dev/null
+++ b/broadcast/pagination.cmp.php
@@ -0,0 +1,40 @@
+
+
diff --git a/broadcast/script.js b/broadcast/script.js
new file mode 100644
index 0000000..a75ddc3
--- /dev/null
+++ b/broadcast/script.js
@@ -0,0 +1,118 @@
+class
+Script
+{
+ static
+ main ()
+ {
+ const dateOptions = {dateFormat: 'yy-mm-dd',
+ firstDay: 6};
+
+ $ ('#filter-date-start').datepicker (dateOptions);
+ $ ('#filter-date-end').datepicker (dateOptions);
+
+ const url = new URL (window.location.href);
+
+ const orderAsc = document.getElementById ('order-asc');
+ const filterKeyword = document.getElementById ('filter-keyword');
+
+ const btnFilter = document.getElementById ('btn-filter');
+
+ const filter = (
+ function (e)
+ {
+ let dateStart = $ ('#filter-date-start').val ();
+ let dateEnd = $ ('#filter-date-end').val ();
+
+ if ((dateStart !== '')
+ && (dateEnd !== '')
+ && (dateStart > dateEnd))
+ [dateStart, dateEnd] = [dateEnd, dateStart];
+
+ url.searchParams.delete ('p');
+
+ url.searchParams.delete ('asc');
+ url.searchParams.append ('asc', orderAsc.checked ? '1' : '0');
+
+ url.searchParams.delete ('q');
+ url.searchParams.append ('q', filterKeyword.value);
+
+ url.searchParams.delete ('start');
+ url.searchParams.delete ('end');
+
+ if (dateStart !== '')
+ url.searchParams.append ('start', dateStart);
+
+ if (dateEnd !== '')
+ url.searchParams.append ('end', dateEnd);
+
+ window.location.href = url;
+ });
+
+ const resetFilter = (
+ function ()
+ {
+ window.location.href = '/';
+ });
+
+ filterKeyword.addEventListener ('keydown',
+ function (e)
+ {
+ if (e.key === 'Enter')
+ filter (e);
+ });
+
+ btnFilter.addEventListener ('click', filter);
+ $ ('#btn-reset').on ('click', resetFilter);
+
+ $ (window).resize (this.setPagination);
+ this.setPagination ();
+ $ ('.pagination').removeClass ('opacity-0');
+
+ $ ('#accordion-filter').on ('shown.bs.collapse', function ()
+ {
+ $.cookie ('expand-filter', '1');
+ });
+
+ $ ('#accordion-filter').on ('hidden.bs.collapse', function ()
+ {
+ $.cookie ('expand-filter', '0');
+ });
+
+ if ($.cookie ('expand-filter') === '0')
+ {
+ $ ('#collapse-filter').removeClass ('show');
+ $ ('#accordion-filter .accordion-button').addClass ('collapsed');
+ }
+ }
+
+ static
+ jumpTo (page)
+ {
+ const url = new URL (window.location.href);
+
+ url.searchParams.delete ('p');
+ url.searchParams.append ('p', page);
+
+ window.location.href = url;
+ }
+
+ static
+ setPagination ()
+ {
+ for (let i = 1; i <= 20; ++i)
+ $ (`.page-${i}`).removeClass ('d-none');
+
+ for (let i = 20; i > 1; --i)
+ {
+ if (($ ('.pagination').width () < $ ('body').width () * .8)
+ && ($ ('.page-item:not(.d-none)').length / 2 % 2 != 0))
+ break;
+
+ $ (`.page-${i}`).addClass ('d-none');
+ }
+ }
+}
+
+
+Script.main ();
+
diff --git a/broadcast/style.css b/broadcast/style.css
new file mode 100644
index 0000000..79b3a46
--- /dev/null
+++ b/broadcast/style.css
@@ -0,0 +1,26 @@
+.container-max-width
+{
+ max-width: 1600px;
+}
+
+.no-wrap
+{
+ white-space: nowrap;
+}
+
+.custom-width
+{
+ max-width: 1ex;
+}
+
+.row-width
+{
+ max-width: 6px;
+}
+
+.page-item
+{
+ width: 3.5em;
+ text-align: center;
+}
+