"dev": true 459
+      "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
503 460
     },
504 461
     "node_modules/function-bind": {
505 462
       "version": "1.1.1",
506 463
       "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
507
-      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
508
-      "dev": true
464
+      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
509 465
     },
510 466
     "node_modules/glob": {
511 467
       "version": "7.1.6",
512 468
       "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
513 469
       "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
514
-      "dev": true,
515 470
       "dependencies": {
516 471
         "fs.realpath": "^1.0.0",
517 472
         "inflight": "^1.0.4",
@@ -531,7 +486,6 @@
531 486
       "version": "6.0.2",
532 487
       "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
533 488
       "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
534
-      "dev": true,
535 489
       "dependencies": {
536 490
         "is-glob": "^4.0.3"
537 491
       },
@@ -543,7 +497,6 @@
543 497
       "version": "1.0.3",
544 498
       "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
545 499
       "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
546
-      "dev": true,
547 500
       "dependencies": {
548 501
         "function-bind": "^1.1.1"
549 502
       },
@@ -555,7 +508,6 @@
555 508
       "version": "1.0.6",
556 509
       "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
557 510
       "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
558
-      "dev": true,
559 511
       "dependencies": {
560 512
         "once": "^1.3.0",
561 513
         "wrappy": "1"
@@ -564,20 +516,17 @@
564 516
     "node_modules/inherits": {
565 517
       "version": "2.0.4",
566 518
       "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
567
-      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
568
-      "dev": true
519
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
569 520
     },
570 521
     "node_modules/is-arrayish": {
571 522
       "version": "0.3.2",
572 523
       "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
573
-      "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==",
574
-      "dev": true
524
+      "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
575 525
     },
576 526
     "node_modules/is-binary-path": {
577 527
       "version": "2.1.0",
578 528
       "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
579 529
       "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
580
-      "dev": true,
581 530
       "dependencies": {
582 531
         "binary-extensions": "^2.0.0"
583 532
       },
@@ -589,7 +538,6 @@
589 538
       "version": "2.12.0",
590 539
       "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.0.tgz",
591 540
       "integrity": "sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ==",
592
-      "dev": true,
593 541
       "dependencies": {
594 542
         "has": "^1.0.3"
595 543
       },
@@ -601,7 +549,6 @@
601 549
       "version": "2.1.1",
602 550
       "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
603 551
       "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
604
-      "dev": true,
605 552
       "engines": {
606 553
         "node": ">=0.10.0"
607 554
       }
@@ -610,7 +557,6 @@
610 557
       "version": "4.0.3",
611 558
       "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
612 559
       "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
613
-      "dev": true,
614 560
       "dependencies": {
615 561
         "is-extglob": "^2.1.1"
616 562
       },
@@ -622,7 +568,6 @@
622 568
       "version": "7.0.0",
623 569
       "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
624 570
       "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
625
-      "dev": true,
626 571
       "engines": {
627 572
         "node": ">=0.12.0"
628 573
       }
@@ -631,7 +576,6 @@
631 576
       "version": "1.18.2",
632 577
       "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.18.2.tgz",
633 578
       "integrity": "sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==",
634
-      "dev": true,
635 579
       "bin": {
636 580
         "jiti": "bin/jiti.js"
637 581
       }
@@ -640,7 +584,6 @@
640 584
       "version": "2.1.0",
641 585
       "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
642 586
       "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==",
643
-      "dev": true,
644 587
       "engines": {
645 588
         "node": ">=10"
646 589
       }
@@ -648,14 +591,12 @@
648 591
     "node_modules/lines-and-columns": {
649 592
       "version": "1.2.4",
650 593
       "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
651
-      "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
652
-      "dev": true
594
+      "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
653 595
     },
654 596
     "node_modules/merge2": {
655 597
       "version": "1.4.1",
656 598
       "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
657 599
       "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
658
-      "dev": true,
659 600
       "engines": {
660 601
         "node": ">= 8"
661 602
       }
@@ -664,7 +605,6 @@
664 605
       "version": "4.0.5",
665 606
       "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
666 607
       "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
667
-      "dev": true,
668 608
       "dependencies": {
669 609
         "braces": "^3.0.2",
670 610
         "picomatch": "^2.3.1"
@@ -677,7 +617,6 @@
677 617
       "version": "3.1.2",
678 618
       "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
679 619
       "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
680
-      "dev": true,
681 620
       "dependencies": {
682 621
         "brace-expansion": "^1.1.7"
683 622
       },
@@ -689,7 +628,6 @@
689 628
       "version": "2.7.0",
690 629
       "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
691 630
       "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
692
-      "dev": true,
693 631
       "dependencies": {
694 632
         "any-promise": "^1.0.0",
695 633
         "object-assign": "^4.0.1",
@@ -700,7 +638,6 @@
700 638
       "version": "3.3.6",
701 639
       "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
702 640
       "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
703
-      "dev": true,
704 641
       "funding": [
705 642
         {
706 643
           "type": "github",
@@ -718,14 +655,12 @@
718 655
       "version": "2.0.10",
719 656
       "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz",
720 657
       "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==",
721
-      "dev": true,
722 658
       "peer": true
723 659
     },
724 660
     "node_modules/normalize-path": {
725 661
       "version": "3.0.0",
726 662
       "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
727 663
       "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
728
-      "dev": true,
729 664
       "engines": {
730 665
         "node": ">=0.10.0"
731 666
       }
@@ -734,7 +669,6 @@
734 669
       "version": "0.1.2",
735 670
       "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
736 671
       "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
737
-      "dev": true,
738 672
       "peer": true,
739 673
       "engines": {
740 674
         "node": ">=0.10.0"
@@ -744,7 +678,6 @@
744 678
       "version": "4.1.1",
745 679
       "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
746 680
       "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
747
-      "dev": true,
748 681
       "engines": {
749 682
         "node": ">=0.10.0"
750 683
       }
@@ -753,7 +686,6 @@
753 686
       "version": "3.0.0",
754 687
       "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
755 688
       "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
756
-      "dev": true,
757 689
       "engines": {
758 690
         "node": ">= 6"
759 691
       }
@@ -762,7 +694,6 @@
762 694
       "version": "1.4.0",
763 695
       "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
764 696
       "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
765
-      "dev": true,
766 697
       "dependencies": {
767 698
         "wrappy": "1"
768 699
       }
@@ -771,7 +702,6 @@
771 702
       "version": "1.0.1",
772 703
       "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
773 704
       "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
774
-      "dev": true,
775 705
       "engines": {
776 706
         "node": ">=0.10.0"
777 707
       }
@@ -779,20 +709,17 @@
779 709
     "node_modules/path-parse": {
780 710
       "version": "1.0.7",
781 711
       "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
782
-      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
783
-      "dev": true
712
+      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
784 713
     },
785 714
     "node_modules/picocolors": {
786 715
       "version": "1.0.0",
787 716
       "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
788
-      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
789
-      "dev": true
717
+      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
790 718
     },
791 719
     "node_modules/picomatch": {
792 720
       "version": "2.3.1",
793 721
       "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
794 722
       "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
795
-      "dev": true,
796 723
       "engines": {
797 724
         "node": ">=8.6"
798 725
       },
@@ -804,7 +731,6 @@
804 731
       "version": "2.3.0",
805 732
       "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
806 733
       "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
807
-      "dev": true,
808 734
       "engines": {
809 735
         "node": ">=0.10.0"
810 736
       }
@@ -813,7 +739,6 @@
813 739
       "version": "4.0.5",
814 740
       "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz",
815 741
       "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==",
816
-      "dev": true,
817 742
       "engines": {
818 743
         "node": ">= 6"
819 744
       }
@@ -822,7 +747,6 @@
822 747
       "version": "8.4.23",
823 748
       "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz",
824 749
       "integrity": "sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==",
825
-      "dev": true,
826 750
       "funding": [
827 751
         {
828 752
           "type": "opencollective",
@@ -850,7 +774,6 @@
850 774
       "version": "15.1.0",
851 775
       "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz",
852 776
       "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
853
-      "dev": true,
854 777
       "dependencies": {
855 778
         "postcss-value-parser": "^4.0.0",
856 779
         "read-cache": "^1.0.0",
@@ -867,7 +790,6 @@
867 790
       "version": "4.0.1",
868 791
       "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz",
869 792
       "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==",
870
-      "dev": true,
871 793
       "dependencies": {
872 794
         "camelcase-css": "^2.0.1"
873 795
       },
@@ -886,7 +808,6 @@
886 808
       "version": "4.0.1",
887 809
       "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.1.tgz",
888 810
       "integrity": "sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==",
889
-      "dev": true,
890 811
       "dependencies": {
891 812
         "lilconfig": "^2.0.5",
892 813
         "yaml": "^2.1.1"
@@ -915,7 +836,6 @@
915 836
       "version": "6.0.1",
916 837
       "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz",
917 838
       "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==",
918
-      "dev": true,
919 839
       "dependencies": {
920 840
         "postcss-selector-parser": "^6.0.11"
921 841
       },
@@ -934,7 +854,6 @@
934 854
       "version": "6.0.12",
935 855
       "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.12.tgz",
936 856
       "integrity": "sha512-NdxGCAZdRrwVI1sy59+Wzrh+pMMHxapGnpfenDVlMEXoOcvt4pGE0JLK9YY2F5dLxcFYA/YbVQKhcGU+FtSYQg==",
937
-      "dev": true,
938 857
       "dependencies": {
939 858
         "cssesc": "^3.0.0",
940 859
         "util-deprecate": "^1.0.2"
@@ -946,14 +865,12 @@
946 865
     "node_modules/postcss-value-parser": {
947 866
       "version": "4.2.0",
948 867
       "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
949
-      "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
950
-      "dev": true
868
+      "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
951 869
     },
952 870
     "node_modules/queue-microtask": {
953 871
       "version": "1.2.3",
954 872
       "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
955 873
       "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
956
-      "dev": true,
957 874
       "funding": [
958 875
         {
959 876
           "type": "github",
@@ -973,7 +890,6 @@
973 890
       "version": "1.0.0",
974 891
       "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
975 892
       "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
976
-      "dev": true,
977 893
       "dependencies": {
978 894
         "pify": "^2.3.0"
979 895
       }
@@ -982,7 +898,6 @@
982 898
       "version": "3.6.0",
983 899
       "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
984 900
       "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
985
-      "dev": true,
986 901
       "dependencies": {
987 902
         "picomatch": "^2.2.1"
988 903
       },
@@ -994,7 +909,6 @@
994 909
       "version": "1.22.2",
995 910
       "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz",
996 911
       "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==",
997
-      "dev": true,
998 912
       "dependencies": {
999 913
         "is-core-module": "^2.11.0",
1000 914
         "path-parse": "^1.0.7",
@@ -1011,7 +925,6 @@
1011 925
       "version": "1.0.4",
1012 926
       "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
1013 927
       "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
1014
-      "dev": true,
1015 928
       "engines": {
1016 929
         "iojs": ">=1.0.0",
1017 930
         "node": ">=0.10.0"
@@ -1021,7 +934,6 @@
1021 934
       "version": "1.2.0",
1022 935
       "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
1023 936
       "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
1024
-      "dev": true,
1025 937
       "funding": [
1026 938
         {
1027 939
           "type": "github",
@@ -1044,7 +956,6 @@
1044 956
       "version": "0.2.2",
1045 957
       "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
1046 958
       "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
1047
-      "dev": true,
1048 959
       "dependencies": {
1049 960
         "is-arrayish": "^0.3.1"
1050 961
       }
@@ -1053,7 +964,6 @@
1053 964
       "version": "1.0.2",
1054 965
       "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
1055 966
       "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
1056
-      "dev": true,
1057 967
       "engines": {
1058 968
         "node": ">=0.10.0"
1059 969
       }
@@ -1062,7 +972,6 @@
1062 972
       "version": "3.32.0",
1063 973
       "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.32.0.tgz",
1064 974
       "integrity": "sha512-ydQOU34rpSyj2TGyz4D2p8rbktIOZ8QY9s+DGLvFU1i5pWJE8vkpruCjGCMHsdXwnD7JDcS+noSwM/a7zyNFDQ==",
1065
-      "dev": true,
1066 975
       "dependencies": {
1067 976
         "@jridgewell/gen-mapping": "^0.3.2",
1068 977
         "commander": "^4.0.0",
@@ -1084,7 +993,6 @@
1084 993
       "version": "1.0.0",
1085 994
       "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
1086 995
       "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
1087
-      "dev": true,
1088 996
       "engines": {
1089 997
         "node": ">= 0.4"
1090 998
       },
@@ -1096,7 +1004,6 @@
1096 1004
       "version": "3.3.2",
1097 1005
       "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.2.tgz",
1098 1006
       "integrity": "sha512-9jPkMiIBXvPc2KywkraqsUfbfj+dHDb+JPWtSJa9MLFdrPyazI7q6WX2sUrm7R9eVR7qqv3Pas7EvQFzxKnI6w==",
1099
-      "dev": true,
1100 1007
       "dependencies": {
1101 1008
         "@alloc/quick-lru": "^5.2.0",
1102 1009
         "arg": "^5.0.2",
@@ -1134,7 +1041,6 @@
1134 1041
       "version": "3.3.1",
1135 1042
       "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
1136 1043
       "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
1137
-      "dev": true,
1138 1044
       "dependencies": {
1139 1045
         "any-promise": "^1.0.0"
1140 1046
       }
@@ -1143,7 +1049,6 @@
1143 1049
       "version": "1.6.0",
1144 1050
       "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
1145 1051
       "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
1146
-      "dev": true,
1147 1052
       "dependencies": {
1148 1053
         "thenify": ">= 3.1.0 < 4"
1149 1054
       },
@@ -1155,7 +1060,6 @@
1155 1060
       "version": "5.0.1",
1156 1061
       "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
1157 1062
       "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
1158
-      "dev": true,
1159 1063
       "dependencies": {
1160 1064
         "is-number": "^7.0.0"
1161 1065
       },
@@ -1166,14 +1070,12 @@
1166 1070
     "node_modules/ts-interface-checker": {
1167 1071
       "version": "0.1.13",
1168 1072
       "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
1169
-      "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
1170
-      "dev": true
1073
+      "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="
1171 1074
     },
1172 1075
     "node_modules/update-browserslist-db": {
1173 1076
       "version": "1.0.11",
1174 1077
       "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz",
1175 1078
       "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==",
1176
-      "dev": true,
1177 1079
       "funding": [
1178 1080
         {
1179 1081
           "type": "opencollective",
@@ -1203,20 +1105,17 @@
1203 1105
     "node_modules/util-deprecate": {
1204 1106
       "version": "1.0.2",
1205 1107
       "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
1206
-      "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
1207
-      "dev": true
1108
+      "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
1208 1109
     },
1209 1110
     "node_modules/wrappy": {
1210 1111
       "version": "1.0.2",
1211 1112
       "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
1212
-      "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
1213
-      "dev": true
1113
+      "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
1214 1114
     },
1215 1115
     "node_modules/yaml": {
1216 1116
       "version": "2.2.2",
1217 1117
       "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.2.2.tgz",
1218 1118
       "integrity": "sha512-CBKFWExMn46Foo4cldiChEzn7S7SRV+wqiluAb6xmueD/fGyRHIhX8m14vVGgeFWjN540nKCNVj6P21eQjgTuA==",
1219
-      "dev": true,
1220 1119
       "engines": {
1221 1120
         "node": ">= 14"
1222 1121
       }

+ 24 - 127
app/package-lock.json

@@ -5,11 +5,10 @@
5 5
   "requires": true,
6 6
   "packages": {
7 7
     "": {
8
-      "name": "app",
9
-      "version": "1.0.0",
10
-      "license": "ISC",
8
+      "dependencies": {
9
+        "daisyui": "^2.51.6"
10
+      },
11 11
       "devDependencies": {
12
-        "daisyui": "^2.51.6",
13 12
         "tailwindcss": "^3.3.2"
14 13
       }
15 14
     },
@@ -17,7 +16,6 @@
17 16
       "version": "5.2.0",
18 17
       "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
19 18
       "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
20
-      "dev": true,
21 19
       "engines": {
22 20
         "node": ">=10"
23 21
       },
@@ -29,7 +27,6 @@
29 27
       "version": "0.3.3",
30 28
       "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
31 29
       "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
32
-      "dev": true,
33 30
       "dependencies": {
34 31
         "@jridgewell/set-array": "^1.0.1",
35 32
         "@jridgewell/sourcemap-codec": "^1.4.10",
@@ -43,7 +40,6 @@
43 40
       "version": "3.1.0",
44 41
       "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
45 42
       "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
46
-      "dev": true,
47 43
       "engines": {
48 44
         "node": ">=6.0.0"
49 45
       }
@@ -52,7 +48,6 @@
52 48
       "version": "1.1.2",
53 49
       "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
54 50
       "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
55
-      "dev": true,
56 51
       "engines": {
57 52
         "node": ">=6.0.0"
58 53
       }
@@ -60,14 +55,12 @@
60 55
     "node_modules/@jridgewell/sourcemap-codec": {
61 56
       "version": "1.4.15",
62 57
       "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
63
-      "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
64
-      "dev": true
58
+      "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
65 59
     },
66 60
     "node_modules/@jridgewell/trace-mapping": {
67 61
       "version": "0.3.18",
68 62
       "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz",
69 63
       "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==",
70
-      "dev": true,
71 64
       "dependencies": {
72 65
         "@jridgewell/resolve-uri": "3.1.0",
73 66
         "@jridgewell/sourcemap-codec": "1.4.14"
@@ -76,14 +69,12 @@
76 69
     "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": {
77 70
       "version": "1.4.14",
78 71
       "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
79
-      "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
80
-      "dev": true
72
+      "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw=="
81 73
     },
82 74
     "node_modules/@nodelib/fs.scandir": {
83 75
       "version": "2.1.5",
84 76
       "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
85 77
       "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
86
-      "dev": true,
87 78
       "dependencies": {
88 79
         "@nodelib/fs.stat": "2.0.5",
89 80
         "run-parallel": "^1.1.9"
@@ -96,7 +87,6 @@
96 87
       "version": "2.0.5",
97 88
       "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
98 89
       "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
99
-      "dev": true,
100 90
       "engines": {
101 91
         "node": ">= 8"
102 92
       }
@@ -105,7 +95,6 @@
105 95
       "version": "1.2.8",
106 96
       "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
107 97
       "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
108
-      "dev": true,
109 98
       "dependencies": {
110 99
         "@nodelib/fs.scandir": "2.1.5",
111 100
         "fastq": "^1.6.0"
@@ -117,14 +106,12 @@
117 106
     "node_modules/any-promise": {
118 107
       "version": "1.3.0",
119 108
       "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
120
-      "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
121
-      "dev": true
109
+      "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="
122 110
     },
123 111
     "node_modules/anymatch": {
124 112
       "version": "3.1.3",
125 113
       "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
126 114
       "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
127
-      "dev": true,
128 115
       "dependencies": {
129 116
         "normalize-path": "^3.0.0",
130 117
         "picomatch": "^2.0.4"
@@ -136,14 +123,12 @@
136 123
     "node_modules/arg": {
137 124
       "version": "5.0.2",
138 125
       "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
139
-      "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
140
-      "dev": true
126
+      "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="
141 127
     },
142 128
     "node_modules/autoprefixer": {
143 129
       "version": "10.4.14",
144 130
       "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz",
145 131
       "integrity": "sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==",
146
-      "dev": true,
147 132
       "funding": [
148 133
         {
149 134
           "type": "opencollective",
@@ -176,14 +161,12 @@
176 161
     "node_modules/balanced-match": {
177 162
       "version": "1.0.2",
178 163
       "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
179
-      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
180
-      "dev": true
164
+      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
181 165
     },
182 166
     "node_modules/binary-extensions": {
183 167
       "version": "2.2.0",
184 168
       "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
185 169
       "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
186
-      "dev": true,
187 170
       "engines": {
188 171
         "node": ">=8"
189 172
       }
@@ -192,7 +175,6 @@
192 175
       "version": "1.1.11",
193 176
       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
194 177
       "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
195
-      "dev": true,
196 178
       "dependencies": {
197 179
         "balanced-match": "^1.0.0",
198 180
         "concat-map": "0.0.1"
@@ -202,7 +184,6 @@
202 184
       "version": "3.0.2",
203 185
       "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
204 186
       "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
205
-      "dev": true,
206 187
       "dependencies": {
207 188
         "fill-range": "^7.0.1"
208 189
       },
@@ -214,7 +195,6 @@
214 195
       "version": "4.21.5",
215 196
       "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz",
216 197
       "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==",
217
-      "dev": true,
218 198
       "funding": [
219 199
         {
220 200
           "type": "opencollective",
@@ -243,7 +223,6 @@
243 223
       "version": "2.0.1",
244 224
       "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
245 225
       "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
246
-      "dev": true,
247 226
       "engines": {
248 227
         "node": ">= 6"
249 228
       }
@@ -252,7 +231,6 @@
252 231
       "version": "1.0.30001486",
253 232
       "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001486.tgz",
254 233
       "integrity": "sha512-uv7/gXuHi10Whlj0pp5q/tsK/32J2QSqVRKQhs2j8VsDCjgyruAh/eEXHF822VqO9yT6iZKw3nRwZRSPBE9OQg==",
255
-      "dev": true,
256 234
       "funding": [
257 235
         {
258 236
           "type": "opencollective",
@@ -273,7 +251,6 @@
273 251
       "version": "3.5.3",
274 252
       "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
275 253
       "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
276
-      "dev": true,
277 254
       "funding": [
278 255
         {
279 256
           "type": "individual",
@@ -300,7 +277,6 @@
300 277
       "version": "5.1.2",
301 278
       "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
302 279
       "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
303
-      "dev": true,
304 280
       "dependencies": {
305 281
         "is-glob": "^4.0.1"
306 282
       },
@@ -312,7 +288,6 @@
312 288
       "version": "4.2.3",
313 289
       "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
314 290
       "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
315
-      "dev": true,
316 291
       "dependencies": {
317 292
         "color-convert": "^2.0.1",
318 293
         "color-string": "^1.9.0"
@@ -325,7 +300,6 @@
325 300
       "version": "2.0.1",
326 301
       "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
327 302
       "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
328
-      "dev": true,
329 303
       "dependencies": {
330 304
         "color-name": "~1.1.4"
331 305
       },
@@ -336,14 +310,12 @@
336 310
     "node_modules/color-name": {
337 311
       "version": "1.1.4",
338 312
       "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
339
-      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
340
-      "dev": true
313
+      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
341 314
     },
342 315
     "node_modules/color-string": {
343 316
       "version": "1.9.1",
344 317
       "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
345 318
       "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
346
-      "dev": true,
347 319
       "dependencies": {
348 320
         "color-name": "^1.0.0",
349 321
         "simple-swizzle": "^0.2.2"
@@ -353,7 +325,6 @@
353 325
       "version": "4.1.1",
354 326
       "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
355 327
       "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
356
-      "dev": true,
357 328
       "engines": {
358 329
         "node": ">= 6"
359 330
       }
@@ -361,14 +332,12 @@
361 332
     "node_modules/concat-map": {
362 333
       "version": "0.0.1",
363 334
       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
364
-      "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
365
-      "dev": true
335
+      "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
366 336
     },
367 337
     "node_modules/css-selector-tokenizer": {
368 338
       "version": "0.8.0",
369 339
       "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.8.0.tgz",
370 340
       "integrity": "sha512-Jd6Ig3/pe62/qe5SBPTN8h8LeUg/pT4lLgtavPf7updwwHpvFzxvOQBHYj2LZDMjUnBzgvIUSjRcf6oT5HzHFg==",
371
-      "dev": true,
372 341
       "dependencies": {
373 342
         "cssesc": "^3.0.0",
374 343
         "fastparse": "^1.1.2"
@@ -378,7 +347,6 @@
378 347
       "version": "3.0.0",
379 348
       "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
380 349
       "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
381
-      "dev": true,
382 350
       "bin": {
383 351
         "cssesc": "bin/cssesc"
384 352
       },
@@ -390,7 +358,6 @@
390 358
       "version": "2.51.6",
391 359
       "resolved": "https://registry.npmjs.org/daisyui/-/daisyui-2.51.6.tgz",
392 360
       "integrity": "sha512-JRqOKayuFCmWe4X4k6Qvx1y7V/VNao8U5eTSOhusOKIzCsYqf56+TCSe4d7zmqGE0V6JiLDYAT8JeoWUeRKFCw==",
393
-      "dev": true,
394 361
       "dependencies": {
395 362
         "color": "^4.2",
396 363
         "css-selector-tokenizer": "^0.8.0",
@@ -409,27 +376,23 @@
409 376
     "node_modules/didyoumean": {
410 377
       "version": "1.2.2",
411 378
       "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
412
-      "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
413
-      "dev": true
379
+      "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw=="
414 380
     },
415 381
     "node_modules/dlv": {
416 382
       "version": "1.1.3",
417 383
       "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
418
-      "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
419
-      "dev": true
384
+      "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="
420 385
     },
421 386
     "node_modules/electron-to-chromium": {
422 387
       "version": "1.4.388",
423 388
       "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.388.tgz",
424 389
       "integrity": "sha512-xZ0y4zjWZgp65okzwwt00f2rYibkFPHUv9qBz+Vzn8cB9UXIo9Zc6Dw81LJYhhNt0G/vR1OJEfStZ49NKl0YxQ==",
425
-      "dev": true,
426 390
       "peer": true
427 391
     },
428 392
     "node_modules/escalade": {
429 393
       "version": "3.1.1",
430 394
       "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
431 395
       "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
432
-      "dev": true,
433 396
       "peer": true,
434 397
       "engines": {
435 398
         "node": ">=6"
@@ -439,7 +402,6 @@
439 402
       "version": "3.2.12",
440 403
       "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz",
441 404
       "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==",
442
-      "dev": true,
443 405
       "dependencies": {
444 406
         "@nodelib/fs.stat": "^2.0.2",
445 407
         "@nodelib/fs.walk": "^1.2.3",
@@ -455,7 +417,6 @@
455 417
       "version": "5.1.2",
456 418
       "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
457 419
       "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
458
-      "dev": true,
459 420
       "dependencies": {
460 421
         "is-glob": "^4.0.1"
461 422
       },
@@ -466,14 +427,12 @@
466 427
     "node_modules/fastparse": {
467 428
       "version": "1.1.2",
468 429
       "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz",
469
-      "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==",
470
-      "dev": true
430
+      "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ=="
471 431
     },
472 432
     "node_modules/fastq": {
473 433
       "version": "1.15.0",
474 434
       "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
475 435
       "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==",
476
-      "dev": true,
477 436
       "dependencies": {
478 437
         "reusify": "^1.0.4"
479 438
       }
@@ -482,7 +441,6 @@
482 441
       "version": "7.0.1",
483 442
       "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
484 443
       "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
485
-      "dev": true,
486 444
       "dependencies": {
487 445
         "to-regex-range": "^5.0.1"
488 446
       },
@@ -494,7 +452,6 @@
494 452
       "version": "4.2.0",
495 453
       "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz",
496 454
       "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==",
497
-      "dev": true,
498 455
       "peer": true,
499 456
       "engines": {
500 457
         "node": "*"
@@ -507,14 +464,12 @@
507 464
     "node_modules/fs.realpath": {
508 465
       "version": "1.0.0",
509 466
       "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
510
-      "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
511
-      "dev": true
467
+      "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
512 468
     },
513 469
     "node_modules/fsevents": {
514 470
       "version": "2.3.2",
515 471
       "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
516 472
       "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
517
-      "dev": true,
518 473
       "hasInstallScript": true,
519 474
       "optional": true,
520 475
       "os": [
@@ -527,14 +482,12 @@
527 482
     "node_modules/function-bind": {
528 483
       "version": "1.1.1",
529 484
       "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
530
-      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
531
-      "dev": true
485
+      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
532 486
     },
533 487
     "node_modules/glob": {
534 488
       "version": "7.1.6",
535 489
       "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
536 490
       "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
537
-      "dev": true,
538 491
       "dependencies": {
539 492
         "fs.realpath": "^1.0.0",
540 493
         "inflight": "^1.0.4",
@@ -554,7 +507,6 @@
554 507
       "version": "6.0.2",
555 508
       "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
556 509
       "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
557
-      "dev": true,
558 510
       "dependencies": {
559 511
         "is-glob": "^4.0.3"
560 512
       },
@@ -566,7 +518,6 @@
566 518
       "version": "1.0.3",
567 519
       "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
568 520
       "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
569
-      "dev": true,
570 521
       "dependencies": {
571 522
         "function-bind": "^1.1.1"
572 523
       },
@@ -578,7 +529,6 @@
578 529
       "version": "1.0.6",
579 530
       "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
580 531
       "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
581
-      "dev": true,
582 532
       "dependencies": {
583 533
         "once": "^1.3.0",
584 534
         "wrappy": "1"
@@ -587,20 +537,17 @@
587 537
     "node_modules/inherits": {
588 538
       "version": "2.0.4",
589 539
       "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
590
-      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
591
-      "dev": true
540
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
592 541
     },
593 542
     "node_modules/is-arrayish": {
594 543
       "version": "0.3.2",
595 544
       "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
596
-      "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==",
597
-      "dev": true
545
+      "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
598 546
     },
599 547
     "node_modules/is-binary-path": {
600 548
       "version": "2.1.0",
601 549
       "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
602 550
       "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
603
-      "dev": true,
604 551
       "dependencies": {
605 552
         "binary-extensions": "^2.0.0"
606 553
       },
@@ -612,7 +559,6 @@
612 559
       "version": "2.12.0",
613 560
       "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.0.tgz",
614 561
       "integrity": "sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ==",
615
-      "dev": true,
616 562
       "dependencies": {
617 563
         "has": "^1.0.3"
618 564
       },
@@ -624,7 +570,6 @@
624 570
       "version": "2.1.1",
625 571
       "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
626 572
       "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
627
-      "dev": true,
628 573
       "engines": {
629 574
         "node": ">=0.10.0"
630 575
       }
@@ -633,7 +578,6 @@
633 578
       "version": "4.0.3",
634 579
       "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
635 580
       "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
636
-      "dev": true,
637 581
       "dependencies": {
638 582
         "is-extglob": "^2.1.1"
639 583
       },
@@ -645,7 +589,6 @@
645 589
       "version": "7.0.0",
646 590
       "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
647 591
       "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
648
-      "dev": true,
649 592
       "engines": {
650 593
         "node": ">=0.12.0"
651 594
       }
@@ -654,7 +597,6 @@
654 597
       "version": "1.18.2",
655 598
       "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.18.2.tgz",
656 599
       "integrity": "sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==",
657
-      "dev": true,
658 600
       "bin": {
659 601
         "jiti": "bin/jiti.js"
660 602
       }
@@ -663,7 +605,6 @@
663 605
       "version": "2.1.0",
664 606
       "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
665 607
       "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==",
666
-      "dev": true,
667 608
       "engines": {
668 609
         "node": ">=10"
669 610
       }
@@ -671,14 +612,12 @@
671 612
     "node_modules/lines-and-columns": {
672 613
       "version": "1.2.4",
673 614
       "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
674
-      "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
675
-      "dev": true
615
+      "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
676 616
     },
677 617
     "node_modules/merge2": {
678 618
       "version": "1.4.1",
679 619
       "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
680 620
       "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
681
-      "dev": true,
682 621
       "engines": {
683 622
         "node": ">= 8"
684 623
       }
@@ -687,7 +626,6 @@
687 626
       "version": "4.0.5",
688 627
       "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
689 628
       "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
690
-      "dev": true,
691 629
       "dependencies": {
692 630
         "braces": "^3.0.2",
693 631
         "picomatch": "^2.3.1"
@@ -700,7 +638,6 @@
700 638
       "version": "3.1.2",
701 639
       "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
702 640
       "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
703
-      "dev": true,
704 641
       "dependencies": {
705 642
         "brace-expansion": "^1.1.7"
706 643
       },
@@ -712,7 +649,6 @@
712 649
       "version": "2.7.0",
713 650
       "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
714 651
       "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
715
-      "dev": true,
716 652
       "dependencies": {
717 653
         "any-promise": "^1.0.0",
718 654
         "object-assign": "^4.0.1",
@@ -723,7 +659,6 @@
723 659
       "version": "3.3.6",
724 660
       "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
725 661
       "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
726
-      "dev": true,
727 662
       "funding": [
728 663
         {
729 664
           "type": "github",
@@ -741,14 +676,12 @@
741 676
       "version": "2.0.10",
742 677
       "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz",
743 678
       "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==",
744
-      "dev": true,
745 679
       "peer": true
746 680
     },
747 681
     "node_modules/normalize-path": {
748 682
       "version": "3.0.0",
749 683
       "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
750 684
       "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
751
-      "dev": true,
752 685
       "engines": {
753 686
         "node": ">=0.10.0"
754 687
       }
@@ -757,7 +690,6 @@
757 690
       "version": "0.1.2",
758 691
       "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
759 692
       "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
760
-      "dev": true,
761 693
       "peer": true,
762 694
       "engines": {
763 695
         "node": ">=0.10.0"
@@ -767,7 +699,6 @@
767 699
       "version": "4.1.1",
768 700
       "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
769 701
       "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
770
-      "dev": true,
771 702
       "engines": {
772 703
         "node": ">=0.10.0"
773 704
       }
@@ -776,7 +707,6 @@
776 707
       "version": "3.0.0",
777 708
       "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
778 709
       "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
779
-      "dev": true,
780 710
       "engines": {
781 711
         "node": ">= 6"
782 712
       }
@@ -785,7 +715,6 @@
785 715
       "version": "1.4.0",
786 716
       "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
787 717
       "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
788
-      "dev": true,
789 718
       "dependencies": {
790 719
         "wrappy": "1"
791 720
       }
@@ -794,7 +723,6 @@
794 723
       "version": "1.0.1",
795 724
       "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
796 725
       "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
797
-      "dev": true,
798 726
       "engines": {
799 727
         "node": ">=0.10.0"
800 728
       }
@@ -802,20 +730,17 @@
802 730
     "node_modules/path-parse": {
803 731
       "version": "1.0.7",
804 732
       "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
805
-      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
806
-      "dev": true
733
+      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
807 734
     },
808 735
     "node_modules/picocolors": {
809 736
       "version": "1.0.0",
810 737
       "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
811
-      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
812
-      "dev": true
738
+      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
813 739
     },
814 740
     "node_modules/picomatch": {
815 741
       "version": "2.3.1",
816 742
       "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
817 743
       "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
818
-      "dev": true,
819 744
       "engines": {
820 745
         "node": ">=8.6"
821 746
       },
@@ -827,7 +752,6 @@
827 752
       "version": "2.3.0",
828 753
       "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
829 754
       "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
830
-      "dev": true,
831 755
       "engines": {
832 756
         "node": ">=0.10.0"
833 757
       }
@@ -836,7 +760,6 @@
836 760
       "version": "4.0.5",
837 761
       "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz",
838 762
       "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==",
839
-      "dev": true,
840 763
       "engines": {
841 764
         "node": ">= 6"
842 765
       }
@@ -845,7 +768,6 @@
845 768
       "version": "8.4.23",
846 769
       "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz",
847 770
       "integrity": "sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==",
848
-      "dev": true,
849 771
       "funding": [
850 772
         {
851 773
           "type": "opencollective",
@@ -873,7 +795,6 @@
873 795
       "version": "15.1.0",
874 796
       "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz",
875 797
       "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
876
-      "dev": true,
877 798
       "dependencies": {
878 799
         "postcss-value-parser": "^4.0.0",
879 800
         "read-cache": "^1.0.0",
@@ -890,7 +811,6 @@
890 811
       "version": "4.0.1",
891 812
       "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz",
892 813
       "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==",
893
-      "dev": true,
894 814
       "dependencies": {
895 815
         "camelcase-css": "^2.0.1"
896 816
       },
@@ -909,7 +829,6 @@
909 829
       "version": "4.0.1",
910 830
       "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.1.tgz",
911 831
       "integrity": "sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==",
912
-      "dev": true,
913 832
       "dependencies": {
914 833
         "lilconfig": "^2.0.5",
915 834
         "yaml": "^2.1.1"
@@ -938,7 +857,6 @@
938 857
       "version": "6.0.1",
939 858
       "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz",
940 859
       "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==",
941
-      "dev": true,
942 860
       "dependencies": {
943 861
         "postcss-selector-parser": "^6.0.11"
944 862
       },
@@ -957,7 +875,6 @@
957 875
       "version": "6.0.12",
958 876
       "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.12.tgz",
959 877
       "integrity": "sha512-NdxGCAZdRrwVI1sy59+Wzrh+pMMHxapGnpfenDVlMEXoOcvt4pGE0JLK9YY2F5dLxcFYA/YbVQKhcGU+FtSYQg==",
960
-      "dev": true,
961 878
       "dependencies": {
962 879
         "cssesc": "^3.0.0",
963 880
         "util-deprecate": "^1.0.2"
@@ -969,14 +886,12 @@
969 886
     "node_modules/postcss-value-parser": {
970 887
       "version": "4.2.0",
971 888
       "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
972
-      "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
973
-      "dev": true
889
+      "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
974 890
     },
975 891
     "node_modules/queue-microtask": {
976 892
       "version": "1.2.3",
977 893
       "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
978 894
       "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
979
-      "dev": true,
980 895
       "funding": [
981 896
         {
982 897
           "type": "github",
@@ -996,7 +911,6 @@
996 911
       "version": "1.0.0",
997 912
       "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
998 913
       "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
999
-      "dev": true,
1000 914
       "dependencies": {
1001 915
         "pify": "^2.3.0"
1002 916
       }
@@ -1005,7 +919,6 @@
1005 919
       "version": "3.6.0",
1006 920
       "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
1007 921
       "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
1008
-      "dev": true,
1009 922
       "dependencies": {
1010 923
         "picomatch": "^2.2.1"
1011 924
       },
@@ -1017,7 +930,6 @@
1017 930
       "version": "1.22.2",
1018 931
       "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz",
1019 932
       "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==",
1020
-      "dev": true,
1021 933
       "dependencies": {
1022 934
         "is-core-module": "^2.11.0",
1023 935
         "path-parse": "^1.0.7",
@@ -1034,7 +946,6 @@
1034 946
       "version": "1.0.4",
1035 947
       "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
1036 948
       "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
1037
-      "dev": true,
1038 949
       "engines": {
1039 950
         "iojs": ">=1.0.0",
1040 951
         "node": ">=0.10.0"
@@ -1044,7 +955,6 @@
1044 955
       "version": "1.2.0",
1045 956
       "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
1046 957
       "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
1047
-      "dev": true,
1048 958
       "funding": [
1049 959
         {
1050 960
           "type": "github",
@@ -1067,7 +977,6 @@
1067 977
       "version": "0.2.2",
1068 978
       "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
1069 979
       "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
1070
-      "dev": true,
1071 980
       "dependencies": {
1072 981
         "is-arrayish": "^0.3.1"
1073 982
       }
@@ -1076,7 +985,6 @@
1076 985
       "version": "1.0.2",
1077 986
       "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
1078 987
       "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
1079
-      "dev": true,
1080 988
       "engines": {
1081 989
         "node": ">=0.10.0"
1082 990
       }
@@ -1085,7 +993,6 @@
1085 993
       "version": "3.32.0",
1086 994
       "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.32.0.tgz",
1087 995
       "integrity": "sha512-ydQOU34rpSyj2TGyz4D2p8rbktIOZ8QY9s+DGLvFU1i5pWJE8vkpruCjGCMHsdXwnD7JDcS+noSwM/a7zyNFDQ==",
1088
-      "dev": true,
1089 996
       "dependencies": {
1090 997
         "@jridgewell/gen-mapping": "^0.3.2",
1091 998
         "commander": "^4.0.0",
@@ -1107,7 +1014,6 @@
1107 1014
       "version": "1.0.0",
1108 1015
       "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
1109 1016
       "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
1110
-      "dev": true,
1111 1017
       "engines": {
1112 1018
         "node": ">= 0.4"
1113 1019
       },
@@ -1119,7 +1025,6 @@
1119 1025
       "version": "3.3.2",
1120 1026
       "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.2.tgz",
1121 1027
       "integrity": "sha512-9jPkMiIBXvPc2KywkraqsUfbfj+dHDb+JPWtSJa9MLFdrPyazI7q6WX2sUrm7R9eVR7qqv3Pas7EvQFzxKnI6w==",
1122
-      "dev": true,
1123 1028
       "dependencies": {
1124 1029
         "@alloc/quick-lru": "^5.2.0",
1125 1030
         "arg": "^5.0.2",
@@ -1157,7 +1062,6 @@
1157 1062
       "version": "3.3.1",
1158 1063
       "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
1159 1064
       "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
1160
-      "dev": true,
1161 1065
       "dependencies": {
1162 1066
         "any-promise": "^1.0.0"
1163 1067
       }
@@ -1166,7 +1070,6 @@
1166 1070
       "version": "1.6.0",
1167 1071
       "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
1168 1072
       "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
1169
-      "dev": true,
1170 1073
       "dependencies": {
1171 1074
         "thenify": ">= 3.1.0 < 4"
1172 1075
       },
@@ -1178,7 +1081,6 @@
1178 1081
       "version": "5.0.1",
1179 1082
       "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
1180 1083
       "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
1181
-      "dev": true,
1182 1084
       "dependencies": {
1183 1085
         "is-number": "^7.0.0"
1184 1086
       },
@@ -1189,14 +1091,12 @@
1189 1091
     "node_modules/ts-interface-checker": {
1190 1092
       "version": "0.1.13",
1191 1093
       "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
1192
-      "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
1193
-      "dev": true
1094
+      "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="
1194 1095
     },
1195 1096
     "node_modules/update-browserslist-db": {
1196 1097
       "version": "1.0.11",
1197 1098
       "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz",
1198 1099
       "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==",
1199
-      "dev": true,
1200 1100
       "funding": [
1201 1101
         {
1202 1102
           "type": "opencollective",
@@ -1226,20 +1126,17 @@
1226 1126
     "node_modules/util-deprecate": {
1227 1127
       "version": "1.0.2",
1228 1128
       "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
1229
-      "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
1230
-      "dev": true
1129
+      "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
1231 1130
     },
1232 1131
     "node_modules/wrappy": {
1233 1132
       "version": "1.0.2",
1234 1133
       "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
1235
-      "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
1236
-      "dev": true
1134
+      "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
1237 1135
     },
1238 1136
     "node_modules/yaml": {
1239 1137
       "version": "2.2.2",
1240 1138
       "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.2.2.tgz",
1241 1139
       "integrity": "sha512-CBKFWExMn46Foo4cldiChEzn7S7SRV+wqiluAb6xmueD/fGyRHIhX8m14vVGgeFWjN540nKCNVj6P21eQjgTuA==",
1242
-      "dev": true,
1243 1140
       "engines": {
1244 1141
         "node": ">= 14"
1245 1142
       }

+ 1 - 1
app/package.json

@@ -1,6 +1,6 @@
1 1
 {
2 2
   "scripts": {
3
-    "build": "tailwindcss -i ./static/css/input.css -o ./static/css/main.css ",
3
+    "build": "tailwindcss -i ./static/css/input.css -o ./static/css/main.css  --minify",
4 4
     "watch": "tailwindcss -i ./static/css/input.css -o ./static/css/main.css --watch"
5 5
   },
6 6
   "devDependencies": {

+ 1 - 1
app/tailwind.config.js

@@ -1,6 +1,6 @@
1 1
 /** @type {import('tailwindcss').Config} */
2 2
 module.exports = {
3
-  content: ["./*.{html,js}"],
3
+  content: ["./templates/**/*.{html,js}"],
4 4
   theme: {
5 5
     extend: {
6 6
       fontFamily: {

+ 19 - 0
app/templates/base.html

@@ -0,0 +1,19 @@
1
+{% load static %}
2
+<!DOCTYPE html>
3
+<html lang="en">
4
+<head>
5
+  <meta charset="UTF-8">
6
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+  <meta http-equiv="X-UA-Compatible" content="ie=edge">
8
+  <title>Tailwind + Django</title>
9
+	<link rel="stylesheet" href="{% static 'css/main.css' %}">
10
+</head>
11
+<body class="bg-grey-lightest font-serif leading-normal tracking-normal">
12
+<div class="container mx-auto ">
13
+<section class="flex items-center justify-center h-screen">
14
+	<h1 class="text-5xl font-sans">Django + Tailwind = ❤️</h1>
15
+</section>
16
+</div>
17
+</body>
18
+</html>
19
+

+ 5 - 1
app/tmt_learning/settings.py

@@ -42,6 +42,7 @@ INSTALLED_APPS = [
42 42
     'django.contrib.sessions',
43 43
     'django.contrib.messages',
44 44
     'django.contrib.staticfiles',
45
+    'course',
45 46
 ]
46 47
 
47 48
 MIDDLEWARE = [
@@ -59,7 +60,7 @@ ROOT_URLCONF = 'tmt_learning.urls'
59 60
 TEMPLATES = [
60 61
     {
61 62
         'BACKEND': 'django.template.backends.django.DjangoTemplates',
62
-        'DIRS': [],
63
+        'DIRS': [os.path.join(BASE_DIR, 'templates')],
63 64
         'APP_DIRS': True,
64 65
         'OPTIONS': {
65 66
             'context_processors': [
@@ -124,6 +125,9 @@ USE_TZ = True
124 125
 
125 126
 # Static files (CSS, JavaScript, Images)
126 127
 # https://docs.djangoproject.com/en/4.1/howto/static-files/
128
+STATICFILES_DIRS = [
129
+    BASE_DIR / "static",
130
+]
127 131
 
128 132
 STATIC_URL = 'static/'
129 133
 

+ 2 - 1
app/tmt_learning/urls.py

@@ -14,8 +14,9 @@ Including another URLconf
14 14
     2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
15 15
 """
16 16
 from django.contrib import admin
17
-from django.urls import path
17
+from django.urls import path, include
18 18
 
19 19
 urlpatterns = [
20 20
     path('admin/', admin.site.urls),
21
+    path('', include('course.urls')),
21 22
 ]

+ 11 - 2
docker-compose.yml

@@ -19,10 +19,10 @@ services:
19 19
   web:
20 20
     build: .
21 21
     command: >
22
-     sh -c "npm run watch &&
23
-            python manage.py migrate &&
22
+     sh -c "python manage.py migrate &&
24 23
             python manage.py runserver 0.0.0.0:8000"
25 24
     #entrypoint: ./server-entrypoint.sh
25
+    tty: true
26 26
     volumes:
27 27
       - ./app:/code
28 28
       - ./media:/code/media
@@ -38,6 +38,15 @@ services:
38 38
       - db
39 39
       - redis
40 40
       #- rabbitmq
41
+
42
+  tailwind:
43
+    build: .
44
+    #image: web
45
+    command: npm run watch
46
+    tty: true
47
+    volumes:
48
+      - ./app:/code
49
+
41 50
   websocket:
42 51
     build: .
43 52
     #image: web

tum/whitesports - Gogs: Simplico Git Service

Nav apraksta

feed.php 22KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838
  1. <?php
  2. /**
  3. * WordPress Feed API
  4. *
  5. * Many of the functions used in here belong in The Loop, or The Loop for the
  6. * Feeds.
  7. *
  8. * @package WordPress
  9. * @subpackage Feed
  10. * @since 2.1.0
  11. */
  12. /**
  13. * RSS container for the bloginfo function.
  14. *
  15. * You can retrieve anything that you can using the get_bloginfo() function.
  16. * Everything will be stripped of tags and characters converted, when the values
  17. * are retrieved for use in the feeds.
  18. *
  19. * @since 1.5.1
  20. *
  21. * @see get_bloginfo() For the list of possible values to display.
  22. *
  23. * @param string $show See get_bloginfo() for possible values.
  24. * @return string
  25. */
  26. function get_bloginfo_rss( $show = '' ) {
  27. $info = strip_tags( get_bloginfo( $show ) );
  28. /**
  29. * Filters the bloginfo for use in RSS feeds.
  30. *
  31. * @since 2.2.0
  32. *
  33. * @see convert_chars()
  34. * @see get_bloginfo()
  35. *
  36. * @param string $info Converted string value of the blog information.
  37. * @param string $show The type of blog information to retrieve.
  38. */
  39. return apply_filters( 'get_bloginfo_rss', convert_chars( $info ), $show );
  40. }
  41. /**
  42. * Display RSS container for the bloginfo function.
  43. *
  44. * You can retrieve anything that you can using the get_bloginfo() function.
  45. * Everything will be stripped of tags and characters converted, when the values
  46. * are retrieved for use in the feeds.
  47. *
  48. * @since 0.71
  49. *
  50. * @see get_bloginfo() For the list of possible values to display.
  51. *
  52. * @param string $show See get_bloginfo() for possible values.
  53. */
  54. function bloginfo_rss( $show = '' ) {
  55. /**
  56. * Filters the bloginfo for display in RSS feeds.
  57. *
  58. * @since 2.1.0
  59. *
  60. * @see get_bloginfo()
  61. *
  62. * @param string $rss_container RSS container for the blog information.
  63. * @param string $show The type of blog information to retrieve.
  64. */
  65. echo apply_filters( 'bloginfo_rss', get_bloginfo_rss( $show ), $show );
  66. }
  67. /**
  68. * Retrieve the default feed.
  69. *
  70. * The default feed is 'rss2', unless a plugin changes it through the
  71. * {@see 'default_feed'} filter.
  72. *
  73. * @since 2.5.0
  74. *
  75. * @return string Default feed, or for example 'rss2', 'atom', etc.
  76. */
  77. function get_default_feed() {
  78. /**
  79. * Filters the default feed type.
  80. *
  81. * @since 2.5.0
  82. *
  83. * @param string $feed_type Type of default feed. Possible values include 'rss2', 'atom'.
  84. * Default 'rss2'.
  85. */
  86. $default_feed = apply_filters( 'default_feed', 'rss2' );
  87. return ( 'rss' === $default_feed ) ? 'rss2' : $default_feed;
  88. }
  89. /**
  90. * Retrieve the blog title for the feed title.
  91. *
  92. * @since 2.2.0
  93. * @since 4.4.0 The optional `$sep` parameter was deprecated and renamed to `$deprecated`.
  94. *
  95. * @param string $deprecated Unused..
  96. * @return string The document title.
  97. */
  98. function get_wp_title_rss( $deprecated = '&#8211;' ) {
  99. if ( '&#8211;' !== $deprecated ) {
  100. /* translators: %s: 'document_title_separator' filter name. */
  101. _deprecated_argument( __FUNCTION__, '4.4.0', sprintf( __( 'Use the %s filter instead.' ), '<code>document_title_separator</code>' ) );
  102. }
  103. /**
  104. * Filters the blog title for use as the feed title.
  105. *
  106. * @since 2.2.0
  107. * @since 4.4.0 The `$sep` parameter was deprecated and renamed to `$deprecated`.
  108. *
  109. * @param string $title The current blog title.
  110. * @param string $deprecated Unused.
  111. */
  112. return apply_filters( 'get_wp_title_rss', wp_get_document_title(), $deprecated );
  113. }
  114. /**
  115. * Display the blog title for display of the feed title.
  116. *
  117. * @since 2.2.0
  118. * @since 4.4.0 The optional `$sep` parameter was deprecated and renamed to `$deprecated`.
  119. *
  120. * @param string $deprecated Unused.
  121. */
  122. function wp_title_rss( $deprecated = '&#8211;' ) {
  123. if ( '&#8211;' !== $deprecated ) {
  124. /* translators: %s: 'document_title_separator' filter name. */
  125. _deprecated_argument( __FUNCTION__, '4.4.0', sprintf( __( 'Use the %s filter instead.' ), '<code>document_title_separator</code>' ) );
  126. }
  127. /**
  128. * Filters the blog title for display of the feed title.
  129. *
  130. * @since 2.2.0
  131. * @since 4.4.0 The `$sep` parameter was deprecated and renamed to `$deprecated`.
  132. *
  133. * @see get_wp_title_rss()
  134. *
  135. * @param string $wp_title_rss The current blog title.
  136. * @param string $deprecated Unused.
  137. */
  138. echo apply_filters( 'wp_title_rss', get_wp_title_rss(), $deprecated );
  139. }
  140. /**
  141. * Retrieve the current post title for the feed.
  142. *
  143. * @since 2.0.0
  144. *
  145. * @return string Current post title.
  146. */
  147. function get_the_title_rss() {
  148. $title = get_the_title();
  149. /**
  150. * Filters the post title for use in a feed.
  151. *
  152. * @since 1.2.0
  153. *
  154. * @param string $title The current post title.
  155. */
  156. return apply_filters( 'the_title_rss', $title );
  157. }
  158. /**
  159. * Display the post title in the feed.
  160. *
  161. * @since 0.71
  162. */
  163. function the_title_rss() {
  164. echo get_the_title_rss();
  165. }
  166. /**
  167. * Retrieve the post content for feeds.
  168. *
  169. * @since 2.9.0
  170. *
  171. * @see get_the_content()
  172. *
  173. * @param string $feed_type The type of feed. rss2 | atom | rss | rdf
  174. * @return string The filtered content.
  175. */
  176. function get_the_content_feed( $feed_type = null ) {
  177. if ( ! $feed_type ) {
  178. $feed_type = get_default_feed();
  179. }
  180. /** This filter is documented in wp-includes/post-template.php */
  181. $content = apply_filters( 'the_content', get_the_content() );
  182. $content = str_replace( ']]>', ']]&gt;', $content );
  183. /**
  184. * Filters the post content for use in feeds.
  185. *
  186. * @since 2.9.0
  187. *
  188. * @param string $content The current post content.
  189. * @param string $feed_type Type of feed. Possible values include 'rss2', 'atom'.
  190. * Default 'rss2'.
  191. */
  192. return apply_filters( 'the_content_feed', $content, $feed_type );
  193. }
  194. /**
  195. * Display the post content for feeds.
  196. *
  197. * @since 2.9.0
  198. *
  199. * @param string $feed_type The type of feed. rss2 | atom | rss | rdf
  200. */
  201. function the_content_feed( $feed_type = null ) {
  202. echo get_the_content_feed( $feed_type );
  203. }
  204. /**
  205. * Display the post excerpt for the feed.
  206. *
  207. * @since 0.71
  208. */
  209. function the_excerpt_rss() {
  210. $output = get_the_excerpt();
  211. /**
  212. * Filters the post excerpt for a feed.
  213. *
  214. * @since 1.2.0
  215. *
  216. * @param string $output The current post excerpt.
  217. */
  218. echo apply_filters( 'the_excerpt_rss', $output );
  219. }
  220. /**
  221. * Display the permalink to the post for use in feeds.
  222. *
  223. * @since 2.3.0
  224. */
  225. function the_permalink_rss() {
  226. /**
  227. * Filters the permalink to the post for use in feeds.
  228. *
  229. * @since 2.3.0
  230. *
  231. * @param string $post_permalink The current post permalink.
  232. */
  233. echo esc_url( apply_filters( 'the_permalink_rss', get_permalink() ) );
  234. }
  235. /**
  236. * Outputs the link to the comments for the current post in an xml safe way
  237. *
  238. * @since 3.0.0
  239. */
  240. function comments_link_feed() {
  241. /**
  242. * Filters the comments permalink for the current post.
  243. *
  244. * @since 3.6.0
  245. *
  246. * @param string $comment_permalink The current comment permalink with
  247. * '#comments' appended.
  248. */
  249. echo esc_url( apply_filters( 'comments_link_feed', get_comments_link() ) );
  250. }
  251. /**
  252. * Display the feed GUID for the current comment.
  253. *
  254. * @since 2.5.0
  255. *
  256. * @param int|WP_Comment $comment_id Optional comment object or ID. Defaults to global comment object.
  257. */
  258. function comment_guid( $comment_id = null ) {
  259. echo esc_url( get_comment_guid( $comment_id ) );
  260. }
  261. /**
  262. * Retrieve the feed GUID for the current comment.
  263. *
  264. * @since 2.5.0
  265. *
  266. * @param int|WP_Comment $comment_id Optional comment object or ID. Defaults to global comment object.
  267. * @return string|false GUID for comment on success, false on failure.
  268. */
  269. function get_comment_guid( $comment_id = null ) {
  270. $comment = get_comment( $comment_id );
  271. if ( ! is_object( $comment ) ) {
  272. return false;
  273. }
  274. return get_the_guid( $comment->comment_post_ID ) . '#comment-' . $comment->comment_ID;
  275. }
  276. /**
  277. * Display the link to the comments.
  278. *
  279. * @since 1.5.0
  280. * @since 4.4.0 Introduced the `$comment` argument.
  281. *
  282. * @param int|WP_Comment $comment Optional. Comment object or ID. Defaults to global comment object.
  283. */
  284. function comment_link( $comment = null ) {
  285. /**
  286. * Filters the current comment's permalink.
  287. *
  288. * @since 3.6.0
  289. *
  290. * @see get_comment_link()
  291. *
  292. * @param string $comment_permalink The current comment permalink.
  293. */
  294. echo esc_url( apply_filters( 'comment_link', get_comment_link( $comment ) ) );
  295. }
  296. /**
  297. * Retrieve the current comment author for use in the feeds.
  298. *
  299. * @since 2.0.0
  300. *
  301. * @return string Comment Author
  302. */
  303. function get_comment_author_rss() {
  304. /**
  305. * Filters the current comment author for use in a feed.
  306. *
  307. * @since 1.5.0
  308. *
  309. * @see get_comment_author()
  310. *
  311. * @param string $comment_author The current comment author.
  312. */
  313. return apply_filters( 'comment_author_rss', get_comment_author() );
  314. }
  315. /**
  316. * Display the current comment author in the feed.
  317. *
  318. * @since 1.0.0
  319. */
  320. function comment_author_rss() {
  321. echo get_comment_author_rss();
  322. }
  323. /**
  324. * Display the current comment content for use in the feeds.
  325. *
  326. * @since 1.0.0
  327. */
  328. function comment_text_rss() {
  329. $comment_text = get_comment_text();
  330. /**
  331. * Filters the current comment content for use in a feed.
  332. *
  333. * @since 1.5.0
  334. *
  335. * @param string $comment_text The content of the current comment.
  336. */
  337. $comment_text = apply_filters( 'comment_text_rss', $comment_text );
  338. echo $comment_text;
  339. }
  340. /**
  341. * Retrieve all of the post categories, formatted for use in feeds.
  342. *
  343. * All of the categories for the current post in the feed loop, will be
  344. * retrieved and have feed markup added, so that they can easily be added to the
  345. * RSS2, Atom, or RSS1 and RSS0.91 RDF feeds.
  346. *
  347. * @since 2.1.0
  348. *
  349. * @param string $type Optional, default is the type returned by get_default_feed().
  350. * @return string All of the post categories for displaying in the feed.
  351. */
  352. function get_the_category_rss( $type = null ) {
  353. if ( empty( $type ) ) {
  354. $type = get_default_feed();
  355. }
  356. $categories = get_the_category();
  357. $tags = get_the_tags();
  358. $the_list = '';
  359. $cat_names = array();
  360. $filter = 'rss';
  361. if ( 'atom' === $type ) {
  362. $filter = 'raw';
  363. }
  364. if ( ! empty( $categories ) ) {
  365. foreach ( (array) $categories as $category ) {
  366. $cat_names[] = sanitize_term_field( 'name', $category->name, $category->term_id, 'category', $filter );
  367. }
  368. }
  369. if ( ! empty( $tags ) ) {
  370. foreach ( (array) $tags as $tag ) {
  371. $cat_names[] = sanitize_term_field( 'name', $tag->name, $tag->term_id, 'post_tag', $filter );
  372. }
  373. }
  374. $cat_names = array_unique( $cat_names );
  375. foreach ( $cat_names as $cat_name ) {
  376. if ( 'rdf' === $type ) {
  377. $the_list .= "\t\t<dc:subject><![CDATA[$cat_name]]></dc:subject>\n";
  378. } elseif ( 'atom' === $type ) {
  379. $the_list .= sprintf( '<category scheme="%1$s" term="%2$s" />', esc_attr( get_bloginfo_rss( 'url' ) ), esc_attr( $cat_name ) );
  380. } else {
  381. $the_list .= "\t\t<category><![CDATA[" . html_entity_decode( $cat_name, ENT_COMPAT, get_option( 'blog_charset' ) ) . "]]></category>\n";
  382. }
  383. }
  384. /**
  385. * Filters all of the post categories for display in a feed.
  386. *
  387. * @since 1.2.0
  388. *
  389. * @param string $the_list All of the RSS post categories.
  390. * @param string $type Type of feed. Possible values include 'rss2', 'atom'.
  391. * Default 'rss2'.
  392. */
  393. return apply_filters( 'the_category_rss', $the_list, $type );
  394. }
  395. /**
  396. * Display the post categories in the feed.
  397. *
  398. * @since 0.71
  399. *
  400. * @see get_the_category_rss() For better explanation.
  401. *
  402. * @param string $type Optional, default is the type returned by get_default_feed().
  403. */
  404. function the_category_rss( $type = null ) {
  405. echo get_the_category_rss( $type );
  406. }
  407. /**
  408. * Display the HTML type based on the blog setting.
  409. *
  410. * The two possible values are either 'xhtml' or 'html'.
  411. *
  412. * @since 2.2.0
  413. */
  414. function html_type_rss() {
  415. $type = get_bloginfo( 'html_type' );
  416. if ( strpos( $type, 'xhtml' ) !== false ) {
  417. $type = 'xhtml';
  418. } else {
  419. $type = 'html';
  420. }
  421. echo $type;
  422. }
  423. /**
  424. * Display the rss enclosure for the current post.
  425. *
  426. * Uses the global $post to check whether the post requires a password and if
  427. * the user has the password for the post. If not then it will return before
  428. * displaying.
  429. *
  430. * Also uses the function get_post_custom() to get the post's 'enclosure'
  431. * metadata field and parses the value to display the enclosure(s). The
  432. * enclosure(s) consist of enclosure HTML tag(s) with a URI and other
  433. * attributes.
  434. *
  435. * @since 1.5.0
  436. */
  437. function rss_enclosure() {
  438. if ( post_password_required() ) {
  439. return;
  440. }
  441. foreach ( (array) get_post_custom() as $key => $val ) {
  442. if ( 'enclosure' === $key ) {
  443. foreach ( (array) $val as $enc ) {
  444. $enclosure = explode( "\n", $enc );
  445. // Only get the first element, e.g. 'audio/mpeg' from 'audio/mpeg mpga mp2 mp3'.
  446. $t = preg_split( '/[ \t]/', trim( $enclosure[2] ) );
  447. $type = $t[0];
  448. /**
  449. * Filters the RSS enclosure HTML link tag for the current post.
  450. *
  451. * @since 2.2.0
  452. *
  453. * @param string $html_link_tag The HTML link tag with a URI and other attributes.
  454. */
  455. echo apply_filters( 'rss_enclosure', '<enclosure url="' . esc_url( trim( $enclosure[0] ) ) . '" length="' . absint( trim( $enclosure[1] ) ) . '" type="' . esc_attr( $type ) . '" />' . "\n" );
  456. }
  457. }
  458. }
  459. }
  460. /**
  461. * Display the atom enclosure for the current post.
  462. *
  463. * Uses the global $post to check whether the post requires a password and if
  464. * the user has the password for the post. If not then it will return before
  465. * displaying.
  466. *
  467. * Also uses the function get_post_custom() to get the post's 'enclosure'
  468. * metadata field and parses the value to display the enclosure(s). The
  469. * enclosure(s) consist of link HTML tag(s) with a URI and other attributes.
  470. *
  471. * @since 2.2.0
  472. */
  473. function atom_enclosure() {
  474. if ( post_password_required() ) {
  475. return;
  476. }
  477. foreach ( (array) get_post_custom() as $key => $val ) {
  478. if ( 'enclosure' === $key ) {
  479. foreach ( (array) $val as $enc ) {
  480. $enclosure = explode( "\n", $enc );
  481. $url = '';
  482. $type = '';
  483. $length = 0;
  484. $mimes = get_allowed_mime_types();
  485. // Parse URL.
  486. if ( isset( $enclosure[0] ) && is_string( $enclosure[0] ) ) {
  487. $url = trim( $enclosure[0] );
  488. }
  489. // Parse length and type.
  490. for ( $i = 1; $i <= 2; $i++ ) {
  491. if ( isset( $enclosure[ $i ] ) ) {
  492. if ( is_numeric( $enclosure[ $i ] ) ) {
  493. $length = trim( $enclosure[ $i ] );
  494. } elseif ( in_array( $enclosure[ $i ], $mimes, true ) ) {
  495. $type = trim( $enclosure[ $i ] );
  496. }
  497. }
  498. }
  499. $html_link_tag = sprintf(
  500. "<link href=\"%s\" rel=\"enclosure\" length=\"%d\" type=\"%s\" />\n",
  501. esc_url( $url ),
  502. esc_attr( $length ),
  503. esc_attr( $type )
  504. );
  505. /**
  506. * Filters the atom enclosure HTML link tag for the current post.
  507. *
  508. * @since 2.2.0
  509. *
  510. * @param string $html_link_tag The HTML link tag with a URI and other attributes.
  511. */
  512. echo apply_filters( 'atom_enclosure', $html_link_tag );
  513. }
  514. }
  515. }
  516. }
  517. /**
  518. * Determine the type of a string of data with the data formatted.
  519. *
  520. * Tell whether the type is text, HTML, or XHTML, per RFC 4287 section 3.1.
  521. *
  522. * In the case of WordPress, text is defined as containing no markup,
  523. * XHTML is defined as "well formed", and HTML as tag soup (i.e., the rest).
  524. *
  525. * Container div tags are added to XHTML values, per section 3.1.1.3.
  526. *
  527. * @link http://www.atomenabled.org/developers/syndication/atom-format-spec.php#rfc.section.3.1
  528. *
  529. * @since 2.5.0
  530. *
  531. * @param string $data Input string
  532. * @return array array(type, value)
  533. */
  534. function prep_atom_text_construct( $data ) {
  535. if ( strpos( $data, '<' ) === false && strpos( $data, '&' ) === false ) {
  536. return array( 'text', $data );
  537. }
  538. if ( ! function_exists( 'xml_parser_create' ) ) {
  539. trigger_error( __( "PHP's XML extension is not available. Please contact your hosting provider to enable PHP's XML extension." ) );
  540. return array( 'html', "<![CDATA[$data]]>" );
  541. }
  542. $parser = xml_parser_create();
  543. xml_parse( $parser, '<div>' . $data . '</div>', true );
  544. $code = xml_get_error_code( $parser );
  545. xml_parser_free( $parser );
  546. unset( $parser );
  547. if ( ! $code ) {
  548. if ( strpos( $data, '<' ) === false ) {
  549. return array( 'text', $data );
  550. } else {
  551. $data = "<div xmlns='http://www.w3.org/1999/xhtml'>$data</div>";
  552. return array( 'xhtml', $data );
  553. }
  554. }
  555. if ( strpos( $data, ']]>' ) === false ) {
  556. return array( 'html', "<![CDATA[$data]]>" );
  557. } else {
  558. return array( 'html', htmlspecialchars( $data ) );
  559. }
  560. }
  561. /**
  562. * Displays Site Icon in atom feeds.
  563. *
  564. * @since 4.3.0
  565. *
  566. * @see get_site_icon_url()
  567. */
  568. function atom_site_icon() {
  569. $url = get_site_icon_url( 32 );
  570. if ( $url ) {
  571. echo '<icon>' . convert_chars( $url ) . "</icon>\n";
  572. }
  573. }
  574. /**
  575. * Displays Site Icon in RSS2.
  576. *
  577. * @since 4.3.0
  578. */
  579. function rss2_site_icon() {
  580. $rss_title = get_wp_title_rss();
  581. if ( empty( $rss_title ) ) {
  582. $rss_title = get_bloginfo_rss( 'name' );
  583. }
  584. $url = get_site_icon_url( 32 );
  585. if ( $url ) {
  586. echo '
  587. <image>
  588. <url>' . convert_chars( $url ) . '</url>
  589. <title>' . $rss_title . '</title>
  590. <link>' . get_bloginfo_rss( 'url' ) . '</link>
  591. <width>32</width>
  592. <height>32</height>
  593. </image> ' . "\n";
  594. }
  595. }
  596. /**
  597. * Returns the link for the currently displayed feed.
  598. *
  599. * @since 5.3.0
  600. *
  601. * @return string Correct link for the atom:self element.
  602. */
  603. function get_self_link() {
  604. $host = parse_url( home_url() );
  605. return set_url_scheme( 'http://' . $host['host'] . wp_unslash( $_SERVER['REQUEST_URI'] ) );
  606. }
  607. /**
  608. * Display the link for the currently displayed feed in a XSS safe way.
  609. *
  610. * Generate a correct link for the atom:self element.
  611. *
  612. * @since 2.5.0
  613. */
  614. function self_link() {
  615. /**
  616. * Filters the current feed URL.
  617. *
  618. * @since 3.6.0
  619. *
  620. * @see set_url_scheme()
  621. * @see wp_unslash()
  622. *
  623. * @param string $feed_link The link for the feed with set URL scheme.
  624. */
  625. echo esc_url( apply_filters( 'self_link', get_self_link() ) );
  626. }
  627. /**
  628. * Get the UTC time of the most recently modified post from WP_Query.
  629. *
  630. * If viewing a comment feed, the time of the most recently modified
  631. * comment will be returned.
  632. *
  633. * @global WP_Query $wp_query WordPress Query object.
  634. *
  635. * @since 5.2.0
  636. *
  637. * @param string $format Date format string to return the time in.
  638. * @return string|false The time in requested format, or false on failure.
  639. */
  640. function get_feed_build_date( $format ) {
  641. global $wp_query;
  642. $datetime = false;
  643. $max_modified_time = false;
  644. $utc = new DateTimeZone( 'UTC' );
  645. if ( ! empty( $wp_query ) && $wp_query->have_posts() ) {
  646. // Extract the post modified times from the posts.
  647. $modified_times = wp_list_pluck( $wp_query->posts, 'post_modified_gmt' );
  648. // If this is a comment feed, check those objects too.
  649. if ( $wp_query->is_comment_feed() && $wp_query->comment_count ) {
  650. // Extract the comment modified times from the comments.
  651. $comment_times = wp_list_pluck( $wp_query->comments, 'comment_date_gmt' );
  652. // Add the comment times to the post times for comparison.
  653. $modified_times = array_merge( $modified_times, $comment_times );
  654. }
  655. // Determine the maximum modified time.
  656. $datetime = date_create_immutable_from_format( 'Y-m-d H:i:s', max( $modified_times ), $utc );
  657. }
  658. if ( false === $datetime ) {
  659. // Fall back to last time any post was modified or published.
  660. $datetime = date_create_immutable_from_format( 'Y-m-d H:i:s', get_lastpostmodified( 'GMT' ), $utc );
  661. }
  662. if ( false !== $datetime ) {
  663. $max_modified_time = $datetime->format( $format );
  664. }
  665. /**
  666. * Filters the date the last post or comment in the query was modified.
  667. *
  668. * @since 5.2.0
  669. *
  670. * @param string|false $max_modified_time Date the last post or comment was modified in the query, in UTC.
  671. * False on failure.
  672. * @param string $format The date format requested in get_feed_build_date().
  673. */
  674. return apply_filters( 'get_feed_build_date', $max_modified_time, $format );
  675. }
  676. /**
  677. * Return the content type for specified feed type.
  678. *
  679. * @since 2.8.0
  680. *
  681. * @param string $type Type of feed. Possible values include 'rss', rss2', 'atom', and 'rdf'.
  682. */
  683. function feed_content_type( $type = '' ) {
  684. if ( empty( $type ) ) {
  685. $type = get_default_feed();
  686. }
  687. $types = array(
  688. 'rss' => 'application/rss+xml',
  689. 'rss2' => 'application/rss+xml',
  690. 'rss-http' => 'text/xml',
  691. 'atom' => 'application/atom+xml',
  692. 'rdf' => 'application/rdf+xml',
  693. );
  694. $content_type = ( ! empty( $types[ $type ] ) ) ? $types[ $type ] : 'application/octet-stream';
  695. /**
  696. * Filters the content type for a specific feed type.
  697. *
  698. * @since 2.8.0
  699. *
  700. * @param string $content_type Content type indicating the type of data that a feed contains.
  701. * @param string $type Type of feed. Possible values include 'rss', rss2', 'atom', and 'rdf'.
  702. */
  703. return apply_filters( 'feed_content_type', $content_type, $type );
  704. }
  705. /**
  706. * Build SimplePie object based on RSS or Atom feed from URL.
  707. *
  708. * @since 2.8.0
  709. *
  710. * @param string|string[] $url URL of feed to retrieve. If an array of URLs, the feeds are merged
  711. * using SimplePie's multifeed feature.
  712. * See also {@link http://simplepie.org/wiki/faq/typical_multifeed_gotchas}
  713. * @return SimplePie|WP_Error SimplePie object on success or WP_Error object on failure.
  714. */
  715. function fetch_feed( $url ) {
  716. if ( ! class_exists( 'SimplePie', false ) ) {
  717. require_once ABSPATH . WPINC . '/class-simplepie.php';
  718. }
  719. require_once ABSPATH . WPINC . '/class-wp-feed-cache-transient.php';
  720. require_once ABSPATH . WPINC . '/class-wp-simplepie-file.php';
  721. require_once ABSPATH . WPINC . '/class-wp-simplepie-sanitize-kses.php';
  722. $feed = new SimplePie();
  723. $feed->set_sanitize_class( 'WP_SimplePie_Sanitize_KSES' );
  724. // We must manually overwrite $feed->sanitize because SimplePie's constructor
  725. // sets it before we have a chance to set the sanitization class.
  726. $feed->sanitize = new WP_SimplePie_Sanitize_KSES();
  727. // Register the cache handler using the recommended method for SimplePie 1.3 or later.
  728. if ( method_exists( 'SimplePie_Cache', 'register' ) ) {
  729. SimplePie_Cache::register( 'wp_transient', 'WP_Feed_Cache_Transient' );
  730. $feed->set_cache_location( 'wp_transient' );
  731. } else {
  732. // Back-compat for SimplePie 1.2.x.
  733. require_once ABSPATH . WPINC . '/class-wp-feed-cache.php';
  734. $feed->set_cache_class( 'WP_Feed_Cache' );
  735. }
  736. $feed->set_file_class( 'WP_SimplePie_File' );
  737. $feed->set_feed_url( $url );
  738. /** This filter is documented in wp-includes/class-wp-feed-cache-transient.php */
  739. $feed->set_cache_duration( apply_filters( 'wp_feed_cache_transient_lifetime', 12 * HOUR_IN_SECONDS, $url ) );
  740. /**
  741. * Fires just before processing the SimplePie feed object.
  742. *
  743. * @since 3.0.0
  744. *
  745. * @param SimplePie $feed SimplePie feed object (passed by reference).
  746. * @param string|string[] $url URL of feed or array of URLs of feeds to retrieve.
  747. */
  748. do_action_ref_array( 'wp_feed_options', array( &$feed, $url ) );
  749. $feed->init();
  750. $feed->set_output_encoding( get_option( 'blog_charset' ) );
  751. if ( $feed->error() ) {
  752. return new WP_Error( 'simplepie-error', $feed->error() );
  753. }
  754. return $feed;
  755. }