From 615e24094aa596b0dc36ce2ff63afa95feb50640 Mon Sep 17 00:00:00 2001 From: ishanashastri Date: Sat, 3 Jun 2017 16:44:20 -0400 Subject: [PATCH] Updated sign in/sign out software for use in the front office of Poolesville High School. --- .classpath | 7 + .gitignore | 1 + .project | 17 + .settings/org.eclipse.jdt.core.prefs | 11 + doc/IDReader.html | 305 +++++ doc/allclasses-frame.html | 19 + doc/allclasses-noframe.html | 19 + doc/class-use/IDReader.html | 122 ++ doc/constant-values.html | 122 ++ doc/deprecated-list.html | 122 ++ doc/help-doc.html | 223 ++++ doc/index-files/index-1.html | 129 ++ doc/index-files/index-2.html | 127 ++ doc/index-files/index-3.html | 127 ++ doc/index-files/index-4.html | 127 ++ doc/index.html | 72 ++ doc/overview-tree.html | 131 ++ doc/package-frame.html | 20 + doc/package-list | 1 + doc/package-summary.html | 129 ++ doc/package-tree.html | 131 ++ doc/package-use.html | 122 ++ doc/script.js | 30 + doc/stylesheet.css | 574 +++++++++ src/JavaFXGUI/AnimatedAlertBox.java | 95 ++ src/JavaFXGUI/AnimatedGif.java | 37 + src/JavaFXGUI/AnimatedLabel.java | 50 + src/JavaFXGUI/Animation.java | 75 ++ src/JavaFXGUI/ButtonHandler.java | 94 ++ src/JavaFXGUI/CachedTimelineTransition.java | 89 ++ src/JavaFXGUI/EmailHandler.java | 168 +++ src/JavaFXGUI/EnterInfoTab.java | 314 +++++ src/JavaFXGUI/EnterStudentTab.java | 382 ++++++ src/JavaFXGUI/IDReader.java | 133 +++ src/JavaFXGUI/MenuTabPane.java | 35 + src/JavaFXGUI/OptionButton.java | 106 ++ src/JavaFXGUI/OptionHBox.java | 102 ++ src/JavaFXGUI/OptionSelect.java | 379 ++++++ src/JavaFXGUI/PasswordLock.java | 120 ++ src/JavaFXGUI/Playable.java | 12 + src/JavaFXGUI/SettingConfig.java | 61 + src/JavaFXGUI/SettingHBox.java | 809 +++++++++++++ src/JavaFXGUI/ShakeTransition.java | 58 + src/JavaFXGUI/StartApplication.java | 284 +++++ src/JavaFXGUI/StartTab.java | 394 ++++++ src/JavaFXGUI/StudentComparator.java | 18 + src/JavaFXGUI/TimeComparator.java | 19 + src/backend/GifDecoder.java | 768 ++++++++++++ src/backend/Student.java | 130 ++ src/backend/StudentList.java | 131 ++ src/backend/StudentProperty.java | 112 ++ src/backup/2017-05-06-IN.csv | 1 + src/backup/2017-05-06-OUT.csv | 1 + src/backup/2017-05-07-IN.csv | 1 + src/backup/2017-05-07-OUT.csv | 1 + src/backup/2017-05-08-IN.csv | 1 + src/backup/2017-05-08-OUT.csv | 1 + src/backup/2017-05-09-IN.csv | 2 + src/backup/2017-05-09-OUT.csv | 1 + src/backup/2017-05-10-IN.csv | 5 + src/backup/2017-05-10-OUT.csv | 8 + src/backup/2017-05-12-IN.csv | 9 + src/backup/2017-05-12-OUT.csv | 2 + src/backup/2017-05-14-IN.csv | 1 + src/backup/2017-05-14-OUT.csv | 1 + src/backup/2017-05-15-IN.csv | 1 + src/backup/2017-05-15-OUT.csv | 2 + src/backup/2017-05-16-IN.csv | 2 + src/backup/2017-05-16-OUT.csv | 3 + src/backup/2017-05-18-IN.csv | 1 + src/backup/2017-05-18-OUT.csv | 1 + src/backup/2017-05-19-IN.csv | 1 + src/backup/2017-05-19-OUT.csv | 1 + src/backup/2017-05-20-IN.csv | 1 + src/backup/2017-05-20-OUT.csv | 1 + src/backup/2017-05-21-IN.csv | 2 + src/backup/2017-05-21-OUT.csv | 2 + src/backup/2017-05-22-IN.csv | 5 + src/backup/2017-05-22-OUT.csv | 3 + src/backup/2017-05-23-IN.csv | 1 + src/backup/2017-05-23-OUT.csv | 1 + src/backup/2017-05-24-IN.csv | 1 + src/backup/2017-05-24-OUT.csv | 1 + src/backup/2017-05-25-IN.csv | 1 + src/backup/2017-05-25-OUT.csv | 1 + src/backup/2017-05-27-IN.csv | 2 + src/backup/2017-05-27-OUT.csv | 1 + src/backup/2017-05-29-IN.csv | 16 + src/backup/2017-05-29-OUT.csv | 1 + src/backup/2017-05-30-IN.csv | 7 + src/backup/2017-05-30-OUT.csv | 2 + src/backup/2017-05-31-IN.csv | 9 + src/backup/2017-05-31-OUT.csv | 5 + src/backup/2017-06-03-IN.csv | 2 + src/backup/2017-06-03-OUT.csv | 1 + src/css/application.css | 638 ++++++++++ src/css/fextile.css | 270 +++++ src/data/SchoolDatabase.mer | 1197 +++++++++++++++++++ src/data/email.config | 3 + src/data/options.sip | 21 + src/data/quartech.mer | 1171 ++++++++++++++++++ src/data/settings.config | 2 + src/img/gifCheckmark.gif | Bin 0 -> 20794 bytes src/img/gifCheckmarkReverse.gif | Bin 0 -> 20794 bytes src/img/image.png | Bin 0 -> 55223 bytes src/img/logo.png | Bin 0 -> 13644 bytes src/img/next-button-left.png | Bin 0 -> 12855 bytes src/img/next-button-right.png | Bin 0 -> 12416 bytes 108 files changed, 11078 insertions(+) create mode 100644 .classpath create mode 100644 .gitignore create mode 100644 .project create mode 100644 .settings/org.eclipse.jdt.core.prefs create mode 100644 doc/IDReader.html create mode 100644 doc/allclasses-frame.html create mode 100644 doc/allclasses-noframe.html create mode 100644 doc/class-use/IDReader.html create mode 100644 doc/constant-values.html create mode 100644 doc/deprecated-list.html create mode 100644 doc/help-doc.html create mode 100644 doc/index-files/index-1.html create mode 100644 doc/index-files/index-2.html create mode 100644 doc/index-files/index-3.html create mode 100644 doc/index-files/index-4.html create mode 100644 doc/index.html create mode 100644 doc/overview-tree.html create mode 100644 doc/package-frame.html create mode 100644 doc/package-list create mode 100644 doc/package-summary.html create mode 100644 doc/package-tree.html create mode 100644 doc/package-use.html create mode 100644 doc/script.js create mode 100644 doc/stylesheet.css create mode 100644 src/JavaFXGUI/AnimatedAlertBox.java create mode 100644 src/JavaFXGUI/AnimatedGif.java create mode 100644 src/JavaFXGUI/AnimatedLabel.java create mode 100644 src/JavaFXGUI/Animation.java create mode 100644 src/JavaFXGUI/ButtonHandler.java create mode 100644 src/JavaFXGUI/CachedTimelineTransition.java create mode 100644 src/JavaFXGUI/EmailHandler.java create mode 100644 src/JavaFXGUI/EnterInfoTab.java create mode 100644 src/JavaFXGUI/EnterStudentTab.java create mode 100644 src/JavaFXGUI/IDReader.java create mode 100644 src/JavaFXGUI/MenuTabPane.java create mode 100644 src/JavaFXGUI/OptionButton.java create mode 100644 src/JavaFXGUI/OptionHBox.java create mode 100644 src/JavaFXGUI/OptionSelect.java create mode 100644 src/JavaFXGUI/PasswordLock.java create mode 100644 src/JavaFXGUI/Playable.java create mode 100644 src/JavaFXGUI/SettingConfig.java create mode 100644 src/JavaFXGUI/SettingHBox.java create mode 100644 src/JavaFXGUI/ShakeTransition.java create mode 100644 src/JavaFXGUI/StartApplication.java create mode 100644 src/JavaFXGUI/StartTab.java create mode 100644 src/JavaFXGUI/StudentComparator.java create mode 100644 src/JavaFXGUI/TimeComparator.java create mode 100644 src/backend/GifDecoder.java create mode 100644 src/backend/Student.java create mode 100644 src/backend/StudentList.java create mode 100644 src/backend/StudentProperty.java create mode 100644 src/backup/2017-05-06-IN.csv create mode 100644 src/backup/2017-05-06-OUT.csv create mode 100644 src/backup/2017-05-07-IN.csv create mode 100644 src/backup/2017-05-07-OUT.csv create mode 100644 src/backup/2017-05-08-IN.csv create mode 100644 src/backup/2017-05-08-OUT.csv create mode 100644 src/backup/2017-05-09-IN.csv create mode 100644 src/backup/2017-05-09-OUT.csv create mode 100644 src/backup/2017-05-10-IN.csv create mode 100644 src/backup/2017-05-10-OUT.csv create mode 100644 src/backup/2017-05-12-IN.csv create mode 100644 src/backup/2017-05-12-OUT.csv create mode 100644 src/backup/2017-05-14-IN.csv create mode 100644 src/backup/2017-05-14-OUT.csv create mode 100644 src/backup/2017-05-15-IN.csv create mode 100644 src/backup/2017-05-15-OUT.csv create mode 100644 src/backup/2017-05-16-IN.csv create mode 100644 src/backup/2017-05-16-OUT.csv create mode 100644 src/backup/2017-05-18-IN.csv create mode 100644 src/backup/2017-05-18-OUT.csv create mode 100644 src/backup/2017-05-19-IN.csv create mode 100644 src/backup/2017-05-19-OUT.csv create mode 100644 src/backup/2017-05-20-IN.csv create mode 100644 src/backup/2017-05-20-OUT.csv create mode 100644 src/backup/2017-05-21-IN.csv create mode 100644 src/backup/2017-05-21-OUT.csv create mode 100644 src/backup/2017-05-22-IN.csv create mode 100644 src/backup/2017-05-22-OUT.csv create mode 100644 src/backup/2017-05-23-IN.csv create mode 100644 src/backup/2017-05-23-OUT.csv create mode 100644 src/backup/2017-05-24-IN.csv create mode 100644 src/backup/2017-05-24-OUT.csv create mode 100644 src/backup/2017-05-25-IN.csv create mode 100644 src/backup/2017-05-25-OUT.csv create mode 100644 src/backup/2017-05-27-IN.csv create mode 100644 src/backup/2017-05-27-OUT.csv create mode 100644 src/backup/2017-05-29-IN.csv create mode 100644 src/backup/2017-05-29-OUT.csv create mode 100644 src/backup/2017-05-30-IN.csv create mode 100644 src/backup/2017-05-30-OUT.csv create mode 100644 src/backup/2017-05-31-IN.csv create mode 100644 src/backup/2017-05-31-OUT.csv create mode 100644 src/backup/2017-06-03-IN.csv create mode 100644 src/backup/2017-06-03-OUT.csv create mode 100644 src/css/application.css create mode 100644 src/css/fextile.css create mode 100644 src/data/SchoolDatabase.mer create mode 100644 src/data/email.config create mode 100644 src/data/options.sip create mode 100644 src/data/quartech.mer create mode 100644 src/data/settings.config create mode 100644 src/img/gifCheckmark.gif create mode 100644 src/img/gifCheckmarkReverse.gif create mode 100644 src/img/image.png create mode 100644 src/img/logo.png create mode 100644 src/img/next-button-left.png create mode 100644 src/img/next-button-right.png diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..10d5f0a --- /dev/null +++ b/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ae3c172 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/.project b/.project new file mode 100644 index 0000000..3374c1f --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + Client Project + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..3a21537 --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/doc/IDReader.html b/doc/IDReader.html new file mode 100644 index 0000000..6795fd3 --- /dev/null +++ b/doc/IDReader.html @@ -0,0 +1,305 @@ + + + + + +IDReader + + + + + + + + +
+ + + + + + + +
+ + + +
+

Class IDReader

+
+
+ +
+
    +
  • +
    +
    All Implemented Interfaces:
    +
    java.lang.Runnable
    +
    +
    +
    +
    public class IDReader
    +extends java.lang.Object
    +implements java.lang.Runnable
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Constructor Summary

      + + + + + + + + +
      Constructors 
      Constructor and Description
      IDReader() 
      +
    • +
    + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + + + + + + + + + +
      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and TypeMethod and Description
      static voidmain(java.lang.String[] args) 
      voidrun() 
      voidserialEvent(SerialPortEvent event, + java.util.HashMap<java.lang.String,StudentList> data) 
      +
        +
      • + + +

        Methods inherited from class java.lang.Object

        +equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
      • +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IDReader

        +
        public IDReader()
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        run

        +
        public void run()
        +
        +
        Specified by:
        +
        run in interface java.lang.Runnable
        +
        +
      • +
      + + + +
        +
      • +

        serialEvent

        +
        public void serialEvent(SerialPortEvent event,
        +                        java.util.HashMap<java.lang.String,StudentList> data)
        +
      • +
      + + + +
        +
      • +

        main

        +
        public static void main(java.lang.String[] args)
        +
      • +
      +
    • +
    +
  • +
+
+
+ + +
+ + + + + + + +
+ + + + diff --git a/doc/allclasses-frame.html b/doc/allclasses-frame.html new file mode 100644 index 0000000..7960235 --- /dev/null +++ b/doc/allclasses-frame.html @@ -0,0 +1,19 @@ + + + + + +All Classes + + + + + +

All Classes

+
+ +
+ + diff --git a/doc/allclasses-noframe.html b/doc/allclasses-noframe.html new file mode 100644 index 0000000..5fcc03c --- /dev/null +++ b/doc/allclasses-noframe.html @@ -0,0 +1,19 @@ + + + + + +All Classes + + + + + +

All Classes

+
+ +
+ + diff --git a/doc/class-use/IDReader.html b/doc/class-use/IDReader.html new file mode 100644 index 0000000..c45a5ca --- /dev/null +++ b/doc/class-use/IDReader.html @@ -0,0 +1,122 @@ + + + + + +Uses of Class IDReader + + + + + + + + +
+ + + + + + + +
+ + +
+

Uses of Class
IDReader

+
+
No usage of IDReader
+ +
+ + + + + + + +
+ + + + diff --git a/doc/constant-values.html b/doc/constant-values.html new file mode 100644 index 0000000..db65f69 --- /dev/null +++ b/doc/constant-values.html @@ -0,0 +1,122 @@ + + + + + +Constant Field Values + + + + + + + + +
+ + + + + + + +
+ + +
+

Constant Field Values

+

Contents

+
+ +
+ + + + + + + +
+ + + + diff --git a/doc/deprecated-list.html b/doc/deprecated-list.html new file mode 100644 index 0000000..820109d --- /dev/null +++ b/doc/deprecated-list.html @@ -0,0 +1,122 @@ + + + + + +Deprecated List + + + + + + + + +
+ + + + + + + +
+ + +
+

Deprecated API

+

Contents

+
+ +
+ + + + + + + +
+ + + + diff --git a/doc/help-doc.html b/doc/help-doc.html new file mode 100644 index 0000000..9066c0d --- /dev/null +++ b/doc/help-doc.html @@ -0,0 +1,223 @@ + + + + + +API Help + + + + + + + + +
+ + + + + + + +
+ + +
+

How This API Document Is Organized

+
This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
+
+
+ +This help file applies to API documentation generated using the standard doclet.
+ +
+ + + + + + + +
+ + + + diff --git a/doc/index-files/index-1.html b/doc/index-files/index-1.html new file mode 100644 index 0000000..d5068ff --- /dev/null +++ b/doc/index-files/index-1.html @@ -0,0 +1,129 @@ + + + + + +I-Index + + + + + + + + +
+ + + + + + + +
+ + +
I M R S  + + +

I

+
+
IDReader - Class in <Unnamed>
+
 
+
IDReader() - Constructor for class IDReader
+
 
+
+I M R S 
+ +
+ + + + + + + +
+ + + + diff --git a/doc/index-files/index-2.html b/doc/index-files/index-2.html new file mode 100644 index 0000000..b7d4097 --- /dev/null +++ b/doc/index-files/index-2.html @@ -0,0 +1,127 @@ + + + + + +M-Index + + + + + + + + +
+ + + + + + + +
+ + +
I M R S  + + +

M

+
+
main(String[]) - Static method in class IDReader
+
 
+
+I M R S 
+ +
+ + + + + + + +
+ + + + diff --git a/doc/index-files/index-3.html b/doc/index-files/index-3.html new file mode 100644 index 0000000..4c7c5cb --- /dev/null +++ b/doc/index-files/index-3.html @@ -0,0 +1,127 @@ + + + + + +R-Index + + + + + + + + +
+ + + + + + + +
+ + +
I M R S  + + +

R

+
+
run() - Method in class IDReader
+
 
+
+I M R S 
+ +
+ + + + + + + +
+ + + + diff --git a/doc/index-files/index-4.html b/doc/index-files/index-4.html new file mode 100644 index 0000000..6fcf609 --- /dev/null +++ b/doc/index-files/index-4.html @@ -0,0 +1,127 @@ + + + + + +S-Index + + + + + + + + +
+ + + + + + + +
+ + +
I M R S  + + +

S

+
+
serialEvent(SerialPortEvent, HashMap<String, StudentList>) - Method in class IDReader
+
 
+
+I M R S 
+ +
+ + + + + + + +
+ + + + diff --git a/doc/index.html b/doc/index.html new file mode 100644 index 0000000..d43dc76 --- /dev/null +++ b/doc/index.html @@ -0,0 +1,72 @@ + + + + + +Generated Documentation (Untitled) + + + + + + +<noscript> +<div>JavaScript is disabled on your browser.</div> +</noscript> +<h2>Frame Alert</h2> +<p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="IDReader.html">Non-frame version</a>.</p> + + + diff --git a/doc/overview-tree.html b/doc/overview-tree.html new file mode 100644 index 0000000..976e5cb --- /dev/null +++ b/doc/overview-tree.html @@ -0,0 +1,131 @@ + + + + + +Class Hierarchy + + + + + + + + +
+ + + + + + + +
+ + +
+

Hierarchy For All Packages

+
+
+

Class Hierarchy

+ +
+ +
+ + + + + + + +
+ + + + diff --git a/doc/package-frame.html b/doc/package-frame.html new file mode 100644 index 0000000..01b423f --- /dev/null +++ b/doc/package-frame.html @@ -0,0 +1,20 @@ + + + + + +<Unnamed> + + + + + +

<Unnamed>

+
+

Classes

+ +
+ + diff --git a/doc/package-list b/doc/package-list new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/doc/package-list @@ -0,0 +1 @@ + diff --git a/doc/package-summary.html b/doc/package-summary.html new file mode 100644 index 0000000..9baf304 --- /dev/null +++ b/doc/package-summary.html @@ -0,0 +1,129 @@ + + + + + + + + + + + + +
+ + + + + + + +
+ + +
+

Package <Unnamed>

+
+
+ +
+ +
+ + + + + + + +
+ + + + diff --git a/doc/package-tree.html b/doc/package-tree.html new file mode 100644 index 0000000..5576a2d --- /dev/null +++ b/doc/package-tree.html @@ -0,0 +1,131 @@ + + + + + + Class Hierarchy + + + + + + + + +
+ + + + + + + +
+ + +
+

Hierarchy For Package <Unnamed>

+
+
+

Class Hierarchy

+ +
+ +
+ + + + + + + +
+ + + + diff --git a/doc/package-use.html b/doc/package-use.html new file mode 100644 index 0000000..503b8ef --- /dev/null +++ b/doc/package-use.html @@ -0,0 +1,122 @@ + + + + + +Uses of Package + + + + + + + + +
+ + + + + + + +
+ + +
+

Uses of Package

+
+
No usage of
+ +
+ + + + + + + +
+ + + + diff --git a/doc/script.js b/doc/script.js new file mode 100644 index 0000000..b346356 --- /dev/null +++ b/doc/script.js @@ -0,0 +1,30 @@ +function show(type) +{ + count = 0; + for (var key in methods) { + var row = document.getElementById(key); + if ((methods[key] & type) != 0) { + row.style.display = ''; + row.className = (count++ % 2) ? rowColor : altColor; + } + else + row.style.display = 'none'; + } + updateTabs(type); +} + +function updateTabs(type) +{ + for (var value in tabs) { + var sNode = document.getElementById(tabs[value][0]); + var spanNode = sNode.firstChild; + if (value == type) { + sNode.className = activeTableTab; + spanNode.innerHTML = tabs[value][1]; + } + else { + sNode.className = tableTab; + spanNode.innerHTML = "" + tabs[value][1] + ""; + } + } +} diff --git a/doc/stylesheet.css b/doc/stylesheet.css new file mode 100644 index 0000000..98055b2 --- /dev/null +++ b/doc/stylesheet.css @@ -0,0 +1,574 @@ +/* Javadoc style sheet */ +/* +Overall document style +*/ + +@import url('resources/fonts/dejavu.css'); + +body { + background-color:#ffffff; + color:#353833; + font-family:'DejaVu Sans', Arial, Helvetica, sans-serif; + font-size:14px; + margin:0; +} +a:link, a:visited { + text-decoration:none; + color:#4A6782; +} +a:hover, a:focus { + text-decoration:none; + color:#bb7a2a; +} +a:active { + text-decoration:none; + color:#4A6782; +} +a[name] { + color:#353833; +} +a[name]:hover { + text-decoration:none; + color:#353833; +} +pre { + font-family:'DejaVu Sans Mono', monospace; + font-size:14px; +} +h1 { + font-size:20px; +} +h2 { + font-size:18px; +} +h3 { + font-size:16px; + font-style:italic; +} +h4 { + font-size:13px; +} +h5 { + font-size:12px; +} +h6 { + font-size:11px; +} +ul { + list-style-type:disc; +} +code, tt { + font-family:'DejaVu Sans Mono', monospace; + font-size:14px; + padding-top:4px; + margin-top:8px; + line-height:1.4em; +} +dt code { + font-family:'DejaVu Sans Mono', monospace; + font-size:14px; + padding-top:4px; +} +table tr td dt code { + font-family:'DejaVu Sans Mono', monospace; + font-size:14px; + vertical-align:top; + padding-top:4px; +} +sup { + font-size:8px; +} +/* +Document title and Copyright styles +*/ +.clear { + clear:both; + height:0px; + overflow:hidden; +} +.aboutLanguage { + float:right; + padding:0px 21px; + font-size:11px; + z-index:200; + margin-top:-9px; +} +.legalCopy { + margin-left:.5em; +} +.bar a, .bar a:link, .bar a:visited, .bar a:active { + color:#FFFFFF; + text-decoration:none; +} +.bar a:hover, .bar a:focus { + color:#bb7a2a; +} +.tab { + background-color:#0066FF; + color:#ffffff; + padding:8px; + width:5em; + font-weight:bold; +} +/* +Navigation bar styles +*/ +.bar { + background-color:#4D7A97; + color:#FFFFFF; + padding:.8em .5em .4em .8em; + height:auto;/*height:1.8em;*/ + font-size:11px; + margin:0; +} +.topNav { + background-color:#4D7A97; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; + font-size:12px; +} +.bottomNav { + margin-top:10px; + background-color:#4D7A97; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; + font-size:12px; +} +.subNav { + background-color:#dee3e9; + float:left; + width:100%; + overflow:hidden; + font-size:12px; +} +.subNav div { + clear:left; + float:left; + padding:0 0 5px 6px; + text-transform:uppercase; +} +ul.navList, ul.subNavList { + float:left; + margin:0 25px 0 0; + padding:0; +} +ul.navList li{ + list-style:none; + float:left; + padding: 5px 6px; + text-transform:uppercase; +} +ul.subNavList li{ + list-style:none; + float:left; +} +.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { + color:#FFFFFF; + text-decoration:none; + text-transform:uppercase; +} +.topNav a:hover, .bottomNav a:hover { + text-decoration:none; + color:#bb7a2a; + text-transform:uppercase; +} +.navBarCell1Rev { + background-color:#F8981D; + color:#253441; + margin: auto 5px; +} +.skipNav { + position:absolute; + top:auto; + left:-9999px; + overflow:hidden; +} +/* +Page header and footer styles +*/ +.header, .footer { + clear:both; + margin:0 20px; + padding:5px 0 0 0; +} +.indexHeader { + margin:10px; + position:relative; +} +.indexHeader span{ + margin-right:15px; +} +.indexHeader h1 { + font-size:13px; +} +.title { + color:#2c4557; + margin:10px 0; +} +.subTitle { + margin:5px 0 0 0; +} +.header ul { + margin:0 0 15px 0; + padding:0; +} +.footer ul { + margin:20px 0 5px 0; +} +.header ul li, .footer ul li { + list-style:none; + font-size:13px; +} +/* +Heading styles +*/ +div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { + background-color:#dee3e9; + border:1px solid #d0d9e0; + margin:0 0 6px -8px; + padding:7px 5px; +} +ul.blockList ul.blockList ul.blockList li.blockList h3 { + background-color:#dee3e9; + border:1px solid #d0d9e0; + margin:0 0 6px -8px; + padding:7px 5px; +} +ul.blockList ul.blockList li.blockList h3 { + padding:0; + margin:15px 0; +} +ul.blockList li.blockList h2 { + padding:0px 0 20px 0; +} +/* +Page layout container styles +*/ +.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { + clear:both; + padding:10px 20px; + position:relative; +} +.indexContainer { + margin:10px; + position:relative; + font-size:12px; +} +.indexContainer h2 { + font-size:13px; + padding:0 0 3px 0; +} +.indexContainer ul { + margin:0; + padding:0; +} +.indexContainer ul li { + list-style:none; + padding-top:2px; +} +.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { + font-size:12px; + font-weight:bold; + margin:10px 0 0 0; + color:#4E4E4E; +} +.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { + margin:5px 0 10px 0px; + font-size:14px; + font-family:'DejaVu Sans Mono',monospace; +} +.serializedFormContainer dl.nameValue dt { + margin-left:1px; + font-size:1.1em; + display:inline; + font-weight:bold; +} +.serializedFormContainer dl.nameValue dd { + margin:0 0 0 1px; + font-size:1.1em; + display:inline; +} +/* +List styles +*/ +ul.horizontal li { + display:inline; + font-size:0.9em; +} +ul.inheritance { + margin:0; + padding:0; +} +ul.inheritance li { + display:inline; + list-style:none; +} +ul.inheritance li ul.inheritance { + margin-left:15px; + padding-left:15px; + padding-top:1px; +} +ul.blockList, ul.blockListLast { + margin:10px 0 10px 0; + padding:0; +} +ul.blockList li.blockList, ul.blockListLast li.blockList { + list-style:none; + margin-bottom:15px; + line-height:1.4; +} +ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { + padding:0px 20px 5px 10px; + border:1px solid #ededed; + background-color:#f8f8f8; +} +ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { + padding:0 0 5px 8px; + background-color:#ffffff; + border:none; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { + margin-left:0; + padding-left:0; + padding-bottom:15px; + border:none; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { + list-style:none; + border-bottom:none; + padding-bottom:0; +} +table tr td dl, table tr td dl dt, table tr td dl dd { + margin-top:0; + margin-bottom:1px; +} +/* +Table styles +*/ +.overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary { + width:100%; + border-left:1px solid #EEE; + border-right:1px solid #EEE; + border-bottom:1px solid #EEE; +} +.overviewSummary, .memberSummary { + padding:0px; +} +.overviewSummary caption, .memberSummary caption, .typeSummary caption, +.useSummary caption, .constantsSummary caption, .deprecatedSummary caption { + position:relative; + text-align:left; + background-repeat:no-repeat; + color:#253441; + font-weight:bold; + clear:none; + overflow:hidden; + padding:0px; + padding-top:10px; + padding-left:1px; + margin:0px; + white-space:pre; +} +.overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link, +.useSummary caption a:link, .constantsSummary caption a:link, .deprecatedSummary caption a:link, +.overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover, +.useSummary caption a:hover, .constantsSummary caption a:hover, .deprecatedSummary caption a:hover, +.overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active, +.useSummary caption a:active, .constantsSummary caption a:active, .deprecatedSummary caption a:active, +.overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited, +.useSummary caption a:visited, .constantsSummary caption a:visited, .deprecatedSummary caption a:visited { + color:#FFFFFF; +} +.overviewSummary caption span, .memberSummary caption span, .typeSummary caption span, +.useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span { + white-space:nowrap; + padding-top:5px; + padding-left:12px; + padding-right:12px; + padding-bottom:7px; + display:inline-block; + float:left; + background-color:#F8981D; + border: none; + height:16px; +} +.memberSummary caption span.activeTableTab span { + white-space:nowrap; + padding-top:5px; + padding-left:12px; + padding-right:12px; + margin-right:3px; + display:inline-block; + float:left; + background-color:#F8981D; + height:16px; +} +.memberSummary caption span.tableTab span { + white-space:nowrap; + padding-top:5px; + padding-left:12px; + padding-right:12px; + margin-right:3px; + display:inline-block; + float:left; + background-color:#4D7A97; + height:16px; +} +.memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab { + padding-top:0px; + padding-left:0px; + padding-right:0px; + background-image:none; + float:none; + display:inline; +} +.overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd, +.useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd { + display:none; + width:5px; + position:relative; + float:left; + background-color:#F8981D; +} +.memberSummary .activeTableTab .tabEnd { + display:none; + width:5px; + margin-right:3px; + position:relative; + float:left; + background-color:#F8981D; +} +.memberSummary .tableTab .tabEnd { + display:none; + width:5px; + margin-right:3px; + position:relative; + background-color:#4D7A97; + float:left; + +} +.overviewSummary td, .memberSummary td, .typeSummary td, +.useSummary td, .constantsSummary td, .deprecatedSummary td { + text-align:left; + padding:0px 0px 12px 10px; +} +th.colOne, th.colFirst, th.colLast, .useSummary th, .constantsSummary th, +td.colOne, td.colFirst, td.colLast, .useSummary td, .constantsSummary td{ + vertical-align:top; + padding-right:0px; + padding-top:8px; + padding-bottom:3px; +} +th.colFirst, th.colLast, th.colOne, .constantsSummary th { + background:#dee3e9; + text-align:left; + padding:8px 3px 3px 7px; +} +td.colFirst, th.colFirst { + white-space:nowrap; + font-size:13px; +} +td.colLast, th.colLast { + font-size:13px; +} +td.colOne, th.colOne { + font-size:13px; +} +.overviewSummary td.colFirst, .overviewSummary th.colFirst, +.useSummary td.colFirst, .useSummary th.colFirst, +.overviewSummary td.colOne, .overviewSummary th.colOne, +.memberSummary td.colFirst, .memberSummary th.colFirst, +.memberSummary td.colOne, .memberSummary th.colOne, +.typeSummary td.colFirst{ + width:25%; + vertical-align:top; +} +td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { + font-weight:bold; +} +.tableSubHeadingColor { + background-color:#EEEEFF; +} +.altColor { + background-color:#FFFFFF; +} +.rowColor { + background-color:#EEEEEF; +} +/* +Content styles +*/ +.description pre { + margin-top:0; +} +.deprecatedContent { + margin:0; + padding:10px 0; +} +.docSummary { + padding:0; +} + +ul.blockList ul.blockList ul.blockList li.blockList h3 { + font-style:normal; +} + +div.block { + font-size:14px; + font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; +} + +td.colLast div { + padding-top:0px; +} + + +td.colLast a { + padding-bottom:3px; +} +/* +Formatting effect styles +*/ +.sourceLineNo { + color:green; + padding:0 30px 0 0; +} +h1.hidden { + visibility:hidden; + overflow:hidden; + font-size:10px; +} +.block { + display:block; + margin:3px 10px 2px 0px; + color:#474747; +} +.deprecatedLabel, .descfrmTypeLabel, .memberNameLabel, .memberNameLink, +.overrideSpecifyLabel, .packageHierarchyLabel, .paramLabel, .returnLabel, +.seeLabel, .simpleTagLabel, .throwsLabel, .typeNameLabel, .typeNameLink { + font-weight:bold; +} +.deprecationComment, .emphasizedPhrase, .interfaceName { + font-style:italic; +} + +div.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase, +div.block div.block span.interfaceName { + font-style:normal; +} + +div.contentContainer ul.blockList li.blockList h2{ + padding-bottom:0px; +} diff --git a/src/JavaFXGUI/AnimatedAlertBox.java b/src/JavaFXGUI/AnimatedAlertBox.java new file mode 100644 index 0000000..b4c02c9 --- /dev/null +++ b/src/JavaFXGUI/AnimatedAlertBox.java @@ -0,0 +1,95 @@ +package JavaFXGUI; + +import javafx.animation.*; +import javafx.geometry.Pos; +import javafx.scene.control.Label; +import javafx.util.Duration; +import javafx.scene.layout.*; + + + +/** + * An Animated Alert box, either green or red, that fades in and out. Intended to be + * attached to the top of a BorderPane. + * @author Kevin + */ +@SuppressWarnings("restriction") +public class AnimatedAlertBox extends HBox{ + private SequentialTransition seqT; + private Label studentIDLabel; + private boolean warning; + /** + * Constructor + * @param defText The default text. + * @param warning Whether or not the Alert is a warning, red, or not, green. + */ + public AnimatedAlertBox(String defText, boolean w){ + warning = w; + setOpacity(0); + studentIDLabel = new Label(defText); + + if (warning){ + + getStyleClass().add("alertMessage"); + studentIDLabel.getStyleClass().add("alertText"); + + } + else{ + + getStyleClass().add("sucessMessage"); + studentIDLabel.getStyleClass().add("sucessText"); + + } + + getChildren().add(studentIDLabel); + setAlignment(Pos.CENTER); + setPrefHeight(40); + + + FadeTransition ftIn = new FadeTransition(Duration.millis(500), this); + ftIn.setFromValue(0); + ftIn.setToValue(1.0); + ftIn.setCycleCount(1); + PauseTransition pt = new PauseTransition(Duration.millis(2000)); + FadeTransition ftOut = new FadeTransition(Duration.millis(500), this); + ftOut.setFromValue(1.0); + ftOut.setToValue(0); + ftOut.setCycleCount(1); + + seqT = new SequentialTransition (ftIn, pt, ftOut); + } + + public void setStyle(){ + if (warning){ + getStyleClass().remove(getStyleClass().size()-1); + getStyleClass().add("alertMessage"); + studentIDLabel.getStyleClass().add("alertText"); + studentIDLabel.getStyleClass().remove(getStyleClass().size()-1); + } + else{ + getStyleClass().remove(getStyleClass().size()-1); + getStyleClass().add("sucessMessage"); + studentIDLabel.getStyleClass().add("sucessText"); + studentIDLabel.getStyleClass().remove(getStyleClass().size()-1); + } + } + /** + * Plays the animation (fades in and out) with a custom message. + * @param mes The Message of the alert. + */ + public void play(String mes){ + studentIDLabel.setText(mes); + seqT.play(); + } + /** + * Plays the animation (fades in and out) with the default message defined in the constructor. + */ + public void play(){ + seqT.play(); + } + public void setWarning(boolean w){ + warning = w; + setStyle(); + } + +} diff --git a/src/JavaFXGUI/AnimatedGif.java b/src/JavaFXGUI/AnimatedGif.java new file mode 100644 index 0000000..ed05fba --- /dev/null +++ b/src/JavaFXGUI/AnimatedGif.java @@ -0,0 +1,37 @@ +package JavaFXGUI; + +import java.awt.image.BufferedImage; + +import javafx.embed.swing.SwingFXUtils; +import javafx.scene.image.Image; +import javafx.scene.image.WritableImage; +import backend.GifDecoder; + +/** + * Wrapper class for Animation that reads a .gif file. + * @author Kevin + */ +public class AnimatedGif extends Animation { + /** + * Wrapper class for Animation that reads a .gif file. + * @param filename filepath of gif. + * @param durationMs the duration of the gif to be played + */ + public AnimatedGif( String filename, double durationMs) { + GifDecoder d = new GifDecoder(); + d.read( filename); + + Image[] sequence = new Image[ d.getFrameCount()]; + for( int i=0; i < d.getFrameCount(); i++) { + + WritableImage wimg = null; + BufferedImage bimg = d.getFrame(i); + sequence[i] = SwingFXUtils.toFXImage( bimg, wimg); + + } + + super.init( sequence, durationMs); + + } + +} \ No newline at end of file diff --git a/src/JavaFXGUI/AnimatedLabel.java b/src/JavaFXGUI/AnimatedLabel.java new file mode 100644 index 0000000..c456877 --- /dev/null +++ b/src/JavaFXGUI/AnimatedLabel.java @@ -0,0 +1,50 @@ +package JavaFXGUI; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.layout.*; +import javafx.scene.control.*; +import javafx.util.Duration; +import javafx.animation.*; +import javafx.event.*; +import javafx.geometry.*; + + +/** + * Extension of label class that flashes whenever the play() function is called. + * @author Kevin + */ +@SuppressWarnings("restriction") +public class AnimatedLabel extends Label{ + FadeTransition ftIn; + FadeTransition ftOut; + SequentialTransition seqBlink; + + + public AnimatedLabel(String text){ + super(text); + ftIn = new FadeTransition(Duration.millis(500), this); + ftIn.setFromValue(0); + ftIn.setToValue(1.0); + ftIn.setCycleCount(1); + + + ftOut = new FadeTransition(Duration.millis(500), this); + ftOut.setFromValue(1.0); + ftOut.setToValue(0); + ftOut.setCycleCount(1); + + seqBlink = new SequentialTransition(ftIn, ftOut); + seqBlink.setCycleCount(Timeline.INDEFINITE); + + } + + public void play(){ + seqBlink.play(); + getStyleClass().add("summaryLabel-active"); + } + + public void stop(){ + seqBlink.stop(); + getStyleClass().remove("summaryLabel-active"); + } +} diff --git a/src/JavaFXGUI/Animation.java b/src/JavaFXGUI/Animation.java new file mode 100644 index 0000000..b5585c1 --- /dev/null +++ b/src/JavaFXGUI/Animation.java @@ -0,0 +1,75 @@ +package JavaFXGUI; + +import javafx.animation.Interpolator; +import javafx.animation.Transition; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.util.Duration; + +/** + * Animation class that takes a sequence of images and plays it over a duration. + * Call getView() to get the ImageView that is to be included in the parent application, + * and call play() to play the animation. + * @author Kevin + */ +@SuppressWarnings("restriction") +public class Animation extends Transition { + private ImageView imageView; + private int count; + private int lastIndex; + private Image[] sequence; + + /** + * Empty constructor + */ + public Animation() { + + } + /** + * Constructor taking a sequence of images, and a duration to be played. + * @param sequence A sequence of images to be played + * @param durationMs The duration of the animation + */ + public Animation( Image[] sequence, double durationMs) { + init( sequence, durationMs); + } + + /** + * Initializes the animation. + * + * @param sequence An Array of images. + * @param durationMs The duration of the animation. + */ + public void init(Image[] sequence, double durationMs) { + this.imageView = new ImageView(sequence[0]); + this.imageView.setFitHeight(40); + this.imageView.setPreserveRatio(true); + this.sequence = sequence; + this.count = sequence.length; + + setCycleCount(1); + setCycleDuration(Duration.millis(durationMs)); + setInterpolator(Interpolator.LINEAR); + } + /** + * The interpolate class that is called every frame (a required method of Transition) + * @param k The fraction of the animation that is played through. + */ + protected void interpolate(double k) { + + final int index = Math.min((int) Math.floor(k * count), count - 1); + if (index != lastIndex) { + imageView.setImage(sequence[index]); + lastIndex = index; + } + + } + /** + * An method returning a ImageView to be used in the main application. + * @return imageView The imageView that is returned. + */ + public ImageView getView() { + return imageView; + } + +} \ No newline at end of file diff --git a/src/JavaFXGUI/ButtonHandler.java b/src/JavaFXGUI/ButtonHandler.java new file mode 100644 index 0000000..9af3242 --- /dev/null +++ b/src/JavaFXGUI/ButtonHandler.java @@ -0,0 +1,94 @@ +package JavaFXGUI; + +import java.util.ArrayList; + +import javafx.event.ActionEvent; +import javafx.event.EventHandler; +import javafx.scene.control.Button; + +/** + * A handler that handles the selection of elements in the OptionSelect Class. + * @author Kevin + */ +@SuppressWarnings("restriction") +public class ButtonHandler implements EventHandler { + public static ArrayList previous = new ArrayList ();; + private String val ; + private Playable button; + private OptionSelect parent; + private boolean otherText; + /** + * Constructor + * @param opt The value of the button. + * @param b A Playable node. + * @param p The Parent OptionSelect class + */ + public ButtonHandler(String opt, Playable b, OptionSelect p) { + this.val = opt ; + button = b; + parent = p; + otherText = false; + if (button.getPage() == previous.size()){ + previous.add(null); + } + } + + /** + * + * @param opt The value of the button. + * @param b A Playable node. + * @param p The Parent OptionSelect class + * @param oT Whether or not the Playable Node is an OptionHBox + */ + public ButtonHandler(String opt, Playable b, OptionSelect p, boolean oT) { + this.val = opt ; + button = b; + parent = p; + otherText = oT; + + if (button.getPage() == previous.size()){ + previous.add(null); + } + } + public ButtonHandler( Playable b, OptionSelect p, boolean oT) { + + button = b; + parent = p; + otherText = oT; + + if (button.getPage() == previous.size()){ + previous.add(null); + } + } + public void setVal(String v){ + val =v; + } + /** + * Handles the playing of the animation of buttons. Also calls addInfo() of + * optionSelect to add the information encoded in each button + */ + @Override + public void handle(ActionEvent event) { + if (previous.get(button.getPage())== null){ + button.play(); + previous.set(button.getPage(), button); + } + else if (button != previous.get(button.getPage())){ + button.play(); + previous.get(button.getPage()).reverse(); + previous.get(button.getPage()).clear(); + previous.set(button.getPage(), button); + } + if (otherText ==false){ + parent.addInfo(val); + } + else{ + parent.addInfo(((OptionHBox)(button)).getText()); + } + + + } + + + +} \ No newline at end of file diff --git a/src/JavaFXGUI/CachedTimelineTransition.java b/src/JavaFXGUI/CachedTimelineTransition.java new file mode 100644 index 0000000..3c8bf2c --- /dev/null +++ b/src/JavaFXGUI/CachedTimelineTransition.java @@ -0,0 +1,89 @@ +package JavaFXGUI; + +import javafx.animation.Interpolator; +import javafx.animation.Timeline; +import javafx.animation.Transition; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +import javafx.scene.CacheHint; +import javafx.scene.Node; +import javafx.util.Duration; + +/** + * A Transition that uses a Timeline internally and turns SPEED caching on for + * the animated node during the animation. + * + * @author Jasper Potts + */ +@SuppressWarnings("restriction") +public class CachedTimelineTransition extends Transition { + protected static final Interpolator WEB_EASE = Interpolator.SPLINE(0.25, 0.1, 0.25, 1); + protected final Node node; + protected Timeline timeline; + private boolean oldCache = false; + private CacheHint oldCacheHint = CacheHint.DEFAULT; + private final boolean useCache; + + /** + * Create new CachedTimelineTransition + * + * @param node The node that is being animated by the timeline + * @param timeline The timeline for the animation, it should be from 0 to 1 seconds + */ + public CachedTimelineTransition(final Node node, final Timeline timeline) { + this(node, timeline, true); + } + + /** + * Create new CachedTimelineTransition + * + * @param node The node that is being animated by the timeline + * @param timeline The timeline for the animation, it should be from 0 to 1 seconds + * @param useCache When true the node is cached as image during the animation + */ + public CachedTimelineTransition(final Node node, final Timeline timeline, final boolean useCache) { + this.node = node; + this.timeline = timeline; + this.useCache = useCache; + statusProperty().addListener(new ChangeListener() { + @Override public void changed(ObservableValue ov, Status t, Status newStatus) { + switch(newStatus) { + case RUNNING: + starting(); + break; + default: + stopping(); + break; + } + } + }); + } + + /** + * Called when the animation is starting + */ + protected void starting() { + if (useCache) { + oldCache = node.isCache(); + oldCacheHint = node.getCacheHint(); + node.setCache(true); + node.setCacheHint(CacheHint.SPEED); + } + } + + /** + * Called when the animation is stopping + */ + protected void stopping() { + if (useCache) { + node.setCache(oldCache); + node.setCacheHint(oldCacheHint); + } + } + + @Override protected void interpolate(double d) { + timeline.playFrom(Duration.seconds(d)); + timeline.stop(); + } + +} \ No newline at end of file diff --git a/src/JavaFXGUI/EmailHandler.java b/src/JavaFXGUI/EmailHandler.java new file mode 100644 index 0000000..242e6e7 --- /dev/null +++ b/src/JavaFXGUI/EmailHandler.java @@ -0,0 +1,168 @@ +package JavaFXGUI; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.PrintWriter; +import java.time.LocalDate; +import java.util.*; + +import javax.mail.*; +import javax.mail.internet.*; +import javax.activation.*; + +import com.sun.mail.smtp.SMTPAddressFailedException; +import com.sun.mail.util.MailConnectException; + +public class EmailHandler { + private String username; + private String password; + private String error = "none"; + ArrayList destination = new ArrayList(); + + public EmailHandler( String u, String p, ArrayList d){ + username = u; + password = p; + readEmailList(); + destination = d; + + } + public ArrayList getEmailList(){ + return destination; + } + + public static ArrayList readEmailList(){ + Scanner configScanner = null; + File configFile = new File("src//data//email.config"); + ArrayList d = new ArrayList(); + try { + configScanner = new Scanner(configFile); + int num = (int)Integer.parseInt(configScanner.nextLine()); + for (int i = 0; i < num; i++){ + d.add(configScanner.nextLine()); + } + + configScanner.close(); + + } catch (FileNotFoundException e1) { + d = new ArrayList(); + } + return d; + } + + public static void writeEmailList(ArrayList d){ + + File configFile = new File("src//data//email.config"); + try { + PrintWriter printWriter = new PrintWriter (configFile); + printWriter.println(d.size()); + + for (int i = 0; i < d.size(); i++){ + printWriter.println(d.get(i)); + } + printWriter.close(); + + } catch (FileNotFoundException e1) { + d = new ArrayList(); + } + + } + public static boolean isValidEmailAddress(String email) { + boolean result = true; + try { + InternetAddress emailAddr = new InternetAddress(email); + emailAddr.validate(); + } catch (AddressException ex) { + result = false; + } + return result; + } + + public void send(){ + LocalDate todayDate = LocalDate.now(); + String date = todayDate.toString(); + + Properties properties = System.getProperties(); + properties.setProperty("mail.smtp.host", "smtp.gmail.com"); + properties.put("mail.smtp.auth", "true"); + properties.put("mail.smtp.ssl.enable", true); + + + + + + Session session = Session.getDefaultInstance(properties, + new javax.mail.Authenticator(){ + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication( + username, password); + } + }); + Transport transport; + + + MimeMessage generateMailMessage = new MimeMessage(session); + + try { + transport = session.getTransport("smtp"); + + transport.connect("smtp.gmail.com", username, password); + generateMailMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(destination.get(0))); + for (int i = 1; i < destination.size(); i++){ + generateMailMessage.addRecipient(Message.RecipientType.BCC, new InternetAddress(destination.get(i))); + } + + generateMailMessage.setSubject(date + " Attendance Report"); + String emailBody = "Here is today's attendance report attached below:" + + "

" + + "Thanks," + + "
" + + "QuarTech."; + + Multipart multipart = new MimeMultipart(); + BodyPart messageBodyPart = new MimeBodyPart(); + + messageBodyPart.setContent(emailBody, "text/html"); + multipart.addBodyPart(messageBodyPart); + + messageBodyPart = new MimeBodyPart(); + + String filename = "src/backup/" + date+"-IN.csv"; + DataSource source = new FileDataSource(filename); + messageBodyPart.setDataHandler(new DataHandler(source)); + messageBodyPart.setFileName( date+"-IN.csv"); + multipart.addBodyPart(messageBodyPart); + + messageBodyPart = new MimeBodyPart(); + filename = "src/backup/" + date+"-OUT.csv"; + source = new FileDataSource(filename); + messageBodyPart.setDataHandler(new DataHandler(source)); + messageBodyPart.setFileName(date+"-OUT.csv"); + multipart.addBodyPart(messageBodyPart); + generateMailMessage.setContent(multipart); + Transport.send(generateMailMessage); + + error = "none"; + } catch (NoSuchProviderException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } catch (MailConnectException e) { + // TODO Auto-generated catch block + error = "This program cannot access the gmail server to send the email." + + "\nPlease check your firewall or internet connection."; + + } + catch(SendFailedException e){ + error = "An email is not in email format."; + } + catch(MessagingException e){ + error = "Unkown Error"; + + } + + } + + public String getError(){ + return error; + } + +} + diff --git a/src/JavaFXGUI/EnterInfoTab.java b/src/JavaFXGUI/EnterInfoTab.java new file mode 100644 index 0000000..c891822 --- /dev/null +++ b/src/JavaFXGUI/EnterInfoTab.java @@ -0,0 +1,314 @@ +package JavaFXGUI; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.PrintWriter; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Scanner; + +import backend.Student; +import backend.StudentList; +import javafx.scene.layout.*; +import javafx.scene.control.*; +import javafx.geometry.*; +/** + * The tab where the student enters specific information about why he/she is late. + * @author Kevin + * + */ +@SuppressWarnings("restriction") +public class EnterInfoTab extends Tab{ + + private boolean goingIn; + private MenuTabPane parent; + private EnterStudentTab previous; + private Student student; + private HashMap data; + private AnimatedAlertBox alert; + private VBox summaryLeftVBox; + private OptionSelect infoOptionSelect; + private ArrayList summariesOptions; + /** + * Initializes the Tab. The Tab reads from a file "src/data/options.sip" for a list + * of the options of the OptionSelect carousel. + * @param par The parent (tabPane) + * @param prev The previous tab + * @param title The Title of the tab. + * @param d The Data of which students Signed in, out and the student Database + * @param gIn Whether or not the student is signing in. + * @param st The Student that is signing in. + */ + public EnterInfoTab(MenuTabPane par, EnterStudentTab prev, String title, + HashMap d, boolean gIn, Student st){ + setText(title); + goingIn = gIn; + previous = prev; + parent = par; + student = st; + + data = d; + + BorderPane content = new BorderPane(); + + alert = new AnimatedAlertBox("Please select all options.", true); + + summaryLeftVBox = new VBox(); + summaryLeftVBox.getStyleClass().add("summaryVBox"); + summaryLeftVBox.setSpacing(20); + summaryLeftVBox.setMaxWidth(300); + summaryLeftVBox.setPrefWidth(300); + + + infoOptionSelect = new OptionSelect(770, 550, this, student); + + int version = 0; + if (goingIn){ + version = 0; + for (int i = 0; i < data.get("outin").getStudentList().size(); i++){ + if (student.equals(data.get("outin").getStudentList().get(i))){ + version = 2; + } + + } + } + else{ + version = 1; + } + Scanner file = null; + try { + file = new Scanner(new File("src/data/options.sip")); + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + + int v = -1; + int page = -1; + String stringData = ""; + while(file.hasNext()){ + + stringData = file.nextLine(); + if (stringData.equals("+++")){ + v ++; + + } + else if (stringData.equals("++")&& version == v){ + page++; + stringData = file.nextLine(); + if (stringData.contains("Submit Button")){ + String[] stringDatas = stringData.split(", "); + infoOptionSelect.addPage(stringDatas[1]); + } + else{ + infoOptionSelect.addPage(stringData); + } + + } + else if (stringData.equals("++++")){ + stringData=file.nextLine(); + if (stringData.contains("Submit Button")){ + String[] stringDatas = stringData.split(", "); + infoOptionSelect.addSubmitButton(page); + infoOptionSelect.addPage(stringDatas[1]); + + String title1 = stringDatas[1]; + ArrayList data1 = new ArrayList(); + stringData = file.nextLine(); + while(!stringData.equals("Title 2")){ + data1.add(stringData); + stringData = file.nextLine(); + } + String title2 = file.nextLine(); + stringData = file.nextLine(); + ArrayList data2 = new ArrayList(); + while(!stringData.equals("End")){ + data2.add(stringData); + stringData=file.nextLine(); + } + infoOptionSelect.splitScreen(page+1, title1, title2, data1, data2); + } + } + else if (version == v){ + infoOptionSelect.addButton(page, stringData, stringData); + } + } + file.close(); + + + Button backButton = new Button("Back to Start"); + backButton.setOnAction(e -> goBackToHome()); + backButton.setPrefSize(150, 20); +// backButton.getStylesheets().add(getClass().getResource("backButton").toString()); + + HBox navHBox = new HBox(); + navHBox.setPadding(new Insets(15, 12, 15, 12)); + navHBox.setSpacing(10); + + navHBox.getChildren().add(backButton); + + VBox contentVBox = new VBox(); + + contentVBox.setSpacing(40); + + VBox centerVBox = new VBox(); + centerVBox.getChildren().add(infoOptionSelect); + centerVBox.setAlignment(Pos.CENTER); + + contentVBox.getChildren().addAll(alert, centerVBox); + content.setCenter(contentVBox); + content.setBottom(navHBox); + + + // "T:/Pictures" for pictures + // TODO Implement scanner, pictures, styling for summary page. Also implement selection, + // then submit click thing, summary page for student name above Option select + + setContent(content); + } + + public void updateScrollPane(ArrayList option){ + + summaryLeftVBox.getChildren().clear(); + summariesOptions = new ArrayList(); + + Separator separator = new Separator(); + summaryLeftVBox.getChildren().add(separator); + ArrayList titleList = infoOptionSelect.getPageTitles(); + for (int i = 0; i < titleList.size(); i++){ + summariesOptions.add(new AnimatedLabel (titleList.get(i) +" "+option.get(i))); + } + + for (int i = 0; i < summariesOptions.size(); i++){ + summariesOptions.get(i).getStyleClass().add("summaryLabel"); + summariesOptions.get(i).setWrapText(true); + summaryLeftVBox.getChildren().add(summariesOptions.get(i)); + } + } + public void updateAnimation(int page){ + + for (int i = 0; i < summariesOptions.size(); i++){ + if ( page == i){ + summariesOptions.get(i).play(); + + } + else{ + summariesOptions.get(i).stop(); + } + } + } + /** + * Transfers focus to the previous tab. + */ + public void goBack(){ + previous.setDisable(false); + parent.getSelectionModel().select(previous); + die(); + } + /** + * Kills the current tab + */ + public void die(){ + parent.getTabs().remove(this); + } + /** + * Adds data to the program, and writes the data out to a backup file in case the program shuts down. + * It then closes the previous two tabs. + * @param option An ArrayList of Strings obtained from the OptionSelect that contains the data from that OptionSelect + */ + public void addData(ArrayList option){ + + if (option.get(0).isEmpty()){ + alert.play(); + } + else{ + if (!goingIn){ + student.setReason(option.get(0)); + student.setExcused(option.get(1)); + data.get("outin").add(student); + } + else{ + student.setReason(option.get(0)); + data.get("in").add(student); + } + + LocalDate todayDate = LocalDate.now(); + String date = todayDate.toString(); + File f = new File("src/backup/" + date+"-IN.csv"); + try { + f.createNewFile(); + } catch (IOException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + + try { + PrintWriter printWriter = new PrintWriter (f); + printWriter.println("DATE,ID,NAME,GR,TIME,REASON"); + for(Student st : data.get("in").getStudentList()){ + printWriter.print("\"" + st.getDate() + "\","); + printWriter.print("\"" + st.getStudentID() + "\","); + printWriter.print("\"" + st.getName() + "\","); + printWriter.print("\"" + st.getGrade() + "\","); + for(int i = 0;i nameEntries; + private ListView list; + private StudentList studentData; + private HashMap data; + private TextField searchTextField; + private AnimatedAlertBox alert; + private ObservableList subentries = FXCollections.observableArrayList(); + + /** + * Creates a Student Tab. On each element, a tooltip is present for information. + * Also creates an AnimatedAlertBox that plays an alert whenever the selected student + * does not exist. + * @param par The parent of this node. + * @param prev The previous tab + * @param title The title of the tab + * @param d The data of which students signed in or out. + * @param gIn Whether or not the student is signing in or out. + */ + public EnterStudentTab(MenuTabPane par, StartTab prev, String title, HashMap d, boolean gIn){ + + list = new ListView(); + + Tooltip toolList = new Tooltip("Double click to select student, \n" + + "or select student and then click submit."); + list.setTooltip(toolList); + + + + goingIn = gIn; + + parent = par; + previous = prev; + studentData = d.get("database"); + data = d; + + setText(title); + BorderPane content = new BorderPane(); + + VBox imageHBox = new VBox(); + imageHBox.setAlignment(Pos.CENTER); + imageHBox.setPadding(new Insets(15, 12, 15, 12)); + imageHBox.setSpacing(10); + + alert = new AnimatedAlertBox("The Student name does not exist.", true); + + + Image photoID = new Image("img//image.png"); + ImageView photoIDView = new ImageView(); + photoIDView.setImage(photoID); + photoIDView.setFitWidth(300); + photoIDView.setPreserveRatio(true); + photoIDView.setSmooth(true); + photoIDView.setCache(true); + + HBox labelHBox = new HBox(); + + + Label studentIDLabel = new Label("Enter student name: "); + studentIDLabel.getStyleClass().add("studentIDLabel"); + Button submitButton = new Button("Submit"); + submitButton.setDefaultButton(true); + submitButton.setPrefSize(100, 20); + submitButton.setOnAction(e -> submitButton()); + submitButton.getStyleClass().add("submitButton"); + + labelHBox.getChildren().addAll(studentIDLabel); + labelHBox.setAlignment(Pos.CENTER); + + HBox navHBox = new HBox(); + navHBox.setPadding(new Insets(15, 12, 15, 12)); + navHBox.setSpacing(10); + + Button backButton = new Button("Back"); + backButton.setOnAction(e -> goBack(false)); + backButton.setPrefSize(150, 20); + + navHBox.getChildren().add(backButton); + + + + nameEntries = FXCollections.observableArrayList(studentData.getInfoList()); + FXCollections.sort(nameEntries, new StudentComparator()); + searchTextField = new TextField(); + searchTextField.setPromptText("Search"); + searchTextField.textProperty().addListener( + new ChangeListener() { + public void changed(ObservableValue observable, + Object oldVal, Object newVal) { + searchStudent(nameEntries, (String)oldVal, (String)newVal); + } + }); + Platform.runLater(new Runnable() { + public void run() { + searchTextField.requestFocus(); + } + }); + + Tooltip toolTextField = new Tooltip(" Enter in keywords " + + "\n separated by a space. "); + searchTextField.setTooltip(toolTextField); + + list.setMaxHeight(400); + list.setItems(nameEntries); + list.getStyleClass().add("searchTextField"); + + VBox searchVBox = new VBox(); + searchVBox.setPadding(new Insets(15, 12, 15, 12)); + searchVBox.setSpacing(10); + searchVBox.setMaxSize(500, 300); + searchVBox.getChildren().addAll(searchTextField, list); + list.setOnMouseClicked(new EventHandler() { + public void handle(MouseEvent click) { + if (click.getClickCount() == 2) { + String currentItemSelected = list.getSelectionModel().getSelectedItem(); + list.getSelectionModel().select(-1); + moveOn(goingIn, data.get("database").getStudentByToString(currentItemSelected)); + } + } + }); + + imageHBox.getChildren().addAll(photoIDView, labelHBox, searchVBox, submitButton); + content.setCenter(imageHBox); + content.setBottom(navHBox); + content.setTop(alert); + setContent(content); + + } + /** + * Closes the current tab. Displays a displays a Success AlertAnimatedBox if there is a submission + * as opposed to just closing the tab (the back button is clicked, for example) + * @param sucess Whether or not the submission was a success + */ + public void goBack(boolean sucess){ + previous.setDisable(false); + parent.getSelectionModel().select(previous); + die(); + if (sucess){ + previous.displaySuccess(); + } + } + /** + * Kills this tab. + */ + public void die(){ + parent.getTabs().remove(this); + } + + /** + * Searches for a student within an ObservableList. Every time a key is pressed + * in a textField, this method is called. Updates the ListView list accordingly. + * The search functions uses every space-separated word as a keyword, and an + * element that is deemed part of the search must have EVERY keyword. + * @param entries The ObservableList of Entries + * @param oldVal The previous value of the search + * @param newVal The new value of the Search. + */ + public void searchStudent(ObservableList entries, String oldVal, String newVal) { + + if ( oldVal != null && (newVal.length() < oldVal.length()) ) { + list.setItems( entries ); + } + + String[] parts = newVal.toUpperCase().split(" "); + + subentries = FXCollections.observableArrayList(); + for ( Object entry: list.getItems() ) { + boolean match = true; + String entryText = (String)entry; + for ( String part: parts ) { + if ( ! entryText.toUpperCase().contains(part) ) { + match = false; + break; + } + } + + if ( match ) { + subentries.add(entryText); + } + } + list.setItems(subentries); + } + + /** + * Manages logic for the submit Button. Plays an alert if the student was not found, + * and calls moveOn otherwise + */ + private void submitButton(){ + searchTextField.requestFocus(); + String selected = list.getSelectionModel().getSelectedItem(); + String submittedText = ""; + if (selected == null){ + if (subentries.size() !=0){ + if (subentries.size() ==1){ + submittedText = subentries.get(0); + ArrayList toStringList = data.get("database").getInfoList(); + if (toStringList.contains(submittedText)){ + moveOn(goingIn, data.get("database").getStudentByToString(submittedText)); + } + } + else{ + alert.play("Please continue entering information until there is only one possible student."); + } + } + else{ + if (searchTextField.getText().isEmpty()){ + alert.play("Please submit your name."); + } + else{ + + alert.play("The student \"" + searchTextField.getText() + "\" was not found."); + } + } + + + + + } + + else{ + moveOn(goingIn, data.get("database").getStudentByToString(selected)); + } + } + + + /** + * Manages logic moving on. If the student is signing back into school (they are signing in + * and they have signed out), the arrival time of the Student data structure is updated, + * the backup file for the program is updated, and the user is transported to the starting Tab. + * Otherwise, the appropriate version (sign-in) or (sign-out) of the EnterInfoTab is created. + * @param signIn + * @param student + */ + private void moveOn(boolean signIn, Student student){ + EnterInfoTab tab3; + boolean outin = false; + int j = 0; + for (int i =0; i < data.get("outin").getStudentList().size(); i++){ + if (student.equals(data.get("outin").getStudentList().get(i))){ + j = i; + outin=true; + + } + } + + if (outin){ + if(student.getArrTime().size()==1){ + System.out.println("None"); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("hh:mm a", Locale.US); + LocalTime todayTime = LocalTime.now(); + String time = formatter.format(todayTime); + + data.get("outin").getStudentList().get(j).setArrTime(time); + LocalDate todayDate = LocalDate.now(); + String date = todayDate.toString(); + File f = new File("src/backup/" + date+"-OUT.csv"); + try { + f.createNewFile(); + } catch (IOException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + + try { + PrintWriter printWriter = new PrintWriter (f); + printWriter.println("DATE,ID,NAME,GR,REASON,EXCUSED,TIME,ARRTIME"); + for(Student st : data.get("outin").getStudentList()){ + printWriter.print("\"" + st.getDate() + "\","); + printWriter.print("\"" + st.getStudentID() + "\","); + printWriter.print("\"" + st.getName() + "\","); + printWriter.print("\"" + st.getGrade() + "\","); + printWriter.print("\"" + st.getReason() + "\","); + printWriter.print("\"" + st.getExcused() + "\","); + printWriter.print("\"" + st.getTime() + "\","); + printWriter.print("\"" + st.getArrTime() +"\","); + printWriter.println(); + } + printWriter.close(); + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + goBack(true); + }else{ + + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("hh:mm a", Locale.US); + LocalTime todayTime = LocalTime.now(); + LocalDate todayDate = LocalDate.now(); + String date = todayDate.toString(); + String time = formatter.format(todayTime); + student.setArrTime(student.getArrTime() + "\n" + time); + File f = new File("src/backup/" + date+"-OUT.csv"); + + try { + f.createNewFile(); + } catch (IOException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + + try { + PrintWriter printWriter = new PrintWriter (f); + printWriter.println("DATE,ID,NAME,GR,REASON,EXCUSED,TIME,ARRTIME"); + for(Student st : data.get("outin").getStudentList()){ + printWriter.print("\"" + st.getDate() + "\","); + printWriter.print("\"" + st.getStudentID() + "\","); + printWriter.print("\"" + st.getName() + "\","); + printWriter.print("\"" + st.getGrade() + "\","); + printWriter.print("\"" + st.getReason() + "\","); + printWriter.print("\"" + st.getExcused() + "\","); + printWriter.print("\"" + st.getTime() + "\","); + printWriter.print("\"" + st.getArrTime() +"\","); + printWriter.println(); + } + printWriter.close(); + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + else + { + if (signIn){ + tab3= new EnterInfoTab(parent, this, "Enter Information", data, signIn, student); + } + else{ + tab3 = new EnterInfoTab(parent, this, "Enter Information", data, signIn, student); + } + setDisable(true); + parent.getTabs().add(tab3); + parent.getSelectionModel().select(tab3); + } + + } + + + +} diff --git a/src/JavaFXGUI/IDReader.java b/src/JavaFXGUI/IDReader.java new file mode 100644 index 0000000..7e995a5 --- /dev/null +++ b/src/JavaFXGUI/IDReader.java @@ -0,0 +1,133 @@ +import java.awt.AWTException; +import java.awt.Robot; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.sql.Connection; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Properties; +import java.util.TooManyListenersException; +import javax.comm.CommPortIdentifier; +import javax.comm.PortInUseException; +import javax.comm.SerialPort; +import javax.comm.SerialPortEvent; +import javax.comm.SerialPortEventListener; +import javax.comm.UnsupportedCommOperationException; + +public class IDReader implements Runnable, SerialPortEventListener { + + private static CommPortIdentifier myCommPortIdentifier; + private static Enumeration portList; + private static String TimeStamp; + private static String driverClass; + private static String connectionString; + private static String comPort; + + private Connection myConnection; + private InputStream myInputStream; + private Robot myRobot; + private SerialPort mySerialPort; + private Thread myThread; + + + public IDReader() { + + // open serial port + try { + TimeStamp = new java.util.Date().toString(); + mySerialPort = (SerialPort) myCommPortIdentifier.open("ComControl", 2000); + //System.out.println(TimeStamp + ": " + myCommPortIdentifier.getName() + " opened for scanner input"); + } catch (PortInUseException e) { + e.printStackTrace(); + } + + // get serial input stream + try { + myInputStream = mySerialPort.getInputStream(); + } catch (IOException e) { + e.printStackTrace(); + } + + // add an event listener on the port + try { + mySerialPort.addEventListener(this); + } catch (TooManyListenersException e) { + e.printStackTrace(); + } + mySerialPort.notifyOnDataAvailable(true); + + // set up the serial port properties + try { + mySerialPort.setSerialPortParams(9600, + SerialPort.DATABITS_8, + SerialPort.STOPBITS_1, + SerialPort.PARITY_NONE); + mySerialPort.setDTR(false); + mySerialPort.setRTS(false); + + } catch (UnsupportedCommOperationException e) { + e.printStackTrace(); + } + + // make a robot to pass keyboard data + try { + myRobot = new Robot(); + } catch (AWTException e) { + e.printStackTrace(); + } + + // create the thread + myThread = new Thread(this); + myThread.start(); + } + + public void run() { + try { + Thread.sleep(100); + } catch (InterruptedException e) {} + } + + // on scan + public void serialEvent(SerialPortEvent event, HashMap data) { + + if (event.getEventType() == SerialPortEvent.DATA_AVAILABLE) { + + StringBuilder myStringBuilder = new StringBuilder(); + int c; + try { + + + // close the input stream + myInputStream.close(); + + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + public static void main(String[] args) { + + // read ScanHandler properties + Properties myProperties = new Properties(); + try { + myProperties.load(new FileInputStream("config.properties")); + comPort = myProperties.getProperty("ScanHandler.comPort"); + } catch (IOException e) { + e.printStackTrace(); + } + + try { + + // get our pre-defined COM port + myCommPortIdentifier = CommPortIdentifier.getPortIdentifier(comPort); + ScanHandler reader = new ScanHandler(); + + } catch (Exception e) { + TimeStamp = new java.util.Date().toString(); + System.out.println(TimeStamp + ": " + comPort + " " + myCommPortIdentifier); + System.out.println(TimeStamp + ": msg1 - " + e); + } + }; +} \ No newline at end of file diff --git a/src/JavaFXGUI/MenuTabPane.java b/src/JavaFXGUI/MenuTabPane.java new file mode 100644 index 0000000..a60051e --- /dev/null +++ b/src/JavaFXGUI/MenuTabPane.java @@ -0,0 +1,35 @@ +package JavaFXGUI; + +import java.util.HashMap; +import java.util.concurrent.atomic.AtomicBoolean; + +import backend.StudentList; +import javafx.scene.control.*; + +/** + * A Custom styled TabPane that can't close tabs. + * @author Kevin + */ +@SuppressWarnings("restriction") +public class MenuTabPane extends TabPane{ + + public StartTab init; + public StartApplication parent; + /** + * Initializes a StartTab. Holds the public variable parent so that the StartTab can + * call methods in StartApplication + * + * @param p The root node. + * @param data The data of the program. + */ + public MenuTabPane(StartApplication p, HashMap data, AtomicBoolean busMode){ + setTabClosingPolicy(TabClosingPolicy.UNAVAILABLE); + init = new StartTab(this, "Start", data, busMode); + getTabs().addAll(init); + parent = p; + } + + + + +} diff --git a/src/JavaFXGUI/OptionButton.java b/src/JavaFXGUI/OptionButton.java new file mode 100644 index 0000000..147541f --- /dev/null +++ b/src/JavaFXGUI/OptionButton.java @@ -0,0 +1,106 @@ +package JavaFXGUI; + +import javafx.scene.control.*; +/** + * An optionSelect block that implements Playable. Is a button and is handled by ButtonHandler + * @author Kevin + */ +@SuppressWarnings("restriction") +public class OptionButton extends Button implements Playable{ + private String valueText; + private AnimatedGif gfA1; + private AnimatedGif gfA2; + private int page; + /** + * Creates itself without any style. + * @param t The content displayed in the button + * @param value The value of the button + * @param p The page number + */ + public OptionButton(String t, String value, int p){ + setText(t); + valueText = value; + init(); + page = p; + } + /** + * Initializes the button with a specific style. + * @param t The content displayed in the button + * @param value The value of the button + * @param style The Style of the button ("top", "mid", or "bottom"); + * @param p the Page number + */ + public OptionButton(String t, String value, String style, int p){ + setText(t); + valueText = value; + setPosStyle(style); + init(); + page = p; + } + + /** + * Initializes the Button. Creates an AnimatedGif of a checkMark and an AnimatedGif of a checkMark closing. + */ + private void init(){ + gfA1 = new AnimatedGif("src/img/gifCheckmark.gif", 500); + gfA1.setCycleCount(1); + setGraphic(gfA1.getView()); + + gfA2 = new AnimatedGif("src/img/gifCheckmarkReverse.gif", 500); + gfA2.setCycleCount(1); + + } + + /** + * Gets the value of the button + * @return The value of the button + */ + public String getValue(){ + return valueText; + } + + /** + * Sets the style of the button. "top", "mid", and "bottom" correspond to where the button is in the OptionSelect. + * @param style The style of the button + */ + public void setPosStyle(String style){ + getStyleClass().clear(); + if (style == "top"){ + getStyleClass().add("optionButton-top"); + } + else if (style == "mid"){ + getStyleClass().add("optionButton-mid"); + } + + else if (style == "bottom"){ + getStyleClass().add("optionButton-bottom"); + } + } + + /** + * Plays the gif in the button + */ + public void play(){ + setGraphic(gfA1.getView()); + gfA1.play(); + } + /** + * Plays the gif in the button in reverse + */ + public void reverse(){ + setGraphic(gfA2.getView()); + gfA2.play(); + } + + public int getPage(){ + return page; + } + + public boolean equals(OptionButton other){ + return (valueText.equals(other.valueText)); + } + public void clear(){ + + } + +} diff --git a/src/JavaFXGUI/OptionHBox.java b/src/JavaFXGUI/OptionHBox.java new file mode 100644 index 0000000..4d71e96 --- /dev/null +++ b/src/JavaFXGUI/OptionHBox.java @@ -0,0 +1,102 @@ +package JavaFXGUI; + +import java.util.Observable; + +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.layout.*; +import javafx.scene.control.*; +import javafx.util.Duration; +import javafx.animation.FadeTransition; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +import javafx.event.*; +import javafx.geometry.*; +/** + * Creates a playable panel, inside which is a label, a textfield, and a button. + * @author Kevin + */ +@SuppressWarnings("restriction") +public class OptionHBox extends HBox implements Playable{ + private TextField textFieldOther; + private OptionSelect parent; + private AnimatedGif gfA1; + private AnimatedGif gfA2; + private int page; + /** + * Creates the playable panel. Creates two gifs. + * @param width The Width of the panel. + * @param p The parent of this node. + * @param pa The page number + */ + public OptionHBox(int width, OptionSelect p, int pa) { + page = pa; + parent = p; + OptionHBox ref = this; + Label textFieldOtherLabel = new Label("Other: "); + textFieldOther = new TextField(); + textFieldOther.setPrefWidth(width-300); + ButtonHandler handler = new ButtonHandler( (Playable)ref, parent, true); + textFieldOther.textProperty().addListener((observable, oldVal, newVal) + ->{ + if (oldVal != newVal){ + handler.setVal(newVal); + handler.handle(new ActionEvent()); + } + + } + ); + + + gfA1 = new AnimatedGif("src/img/gifCheckmark.gif", 500); + gfA1.setCycleCount(1); + + + gfA2 = new AnimatedGif("src/img/gifCheckmarkReverse.gif", 500); + gfA2.setCycleCount(1); + + getChildren().addAll(gfA1.getView(), textFieldOtherLabel, textFieldOther); + setSpacing(10); + setAlignment(Pos.CENTER_LEFT); + + } + /** + * Plays the animated check mark. + */ + @Override + public void play() { + getChildren().remove(0); + getChildren().add(0, gfA1.getView()); + gfA1.play(); + + } + /** + * Plays the animated check mark in reverse. + */ + @Override + public void reverse() { + getChildren().remove(0); + getChildren().add(0, gfA2.getView()); + gfA2.play(); + + } + + /** + * Clears the TextField inside this object + */ + public void clear(){ + textFieldOther.clear(); + } + + /** + * Gets the text of the TextField of this object + * @return The text of the textField of this object. + */ + public String getText(){ + return textFieldOther.getText(); + } + + public int getPage(){ + return page; + } +} diff --git a/src/JavaFXGUI/OptionSelect.java b/src/JavaFXGUI/OptionSelect.java new file mode 100644 index 0000000..eb0558c --- /dev/null +++ b/src/JavaFXGUI/OptionSelect.java @@ -0,0 +1,379 @@ +package JavaFXGUI; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.JSplitPane; + +import org.omg.CORBA.SystemException; + +import backend.Student; +import javafx.scene.layout.*; +import javafx.scene.Scene; +import javafx.scene.control.*; +import javafx.util.Duration; +import javafx.animation.FadeTransition; +import javafx.event.*; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyEvent; + +import java.awt.Component; +import java.awt.event.KeyListener; + +import javafx.geometry.Orientation; +import javafx.geometry.Pos; +/** + * Creates a carousel of options that the student uses to select his/her reasons for signing in/out. + * @author Kevin + */ +@SuppressWarnings("restriction") +public class OptionSelect extends VBox{ + private ArrayList> buttonList; + private ArrayList title = new ArrayList(); + private VBox buttonVBox; + private ArrayList option = new ArrayList(); + private int page; + private Label titleLabel; + private int height, width; + private HBox bottomHBox; + private Label pageNumberLabel; + private Button submitButton; + private EnterInfoTab tabToBeClosed; + private Student student; + private Button pageButtonLeft; + private Button pageButtonRight; + private FadeTransition ftIn; + private FadeTransition ftOut; + private ArrayList optionHBoxArray = new ArrayList(); + /** + * Constructor. The data of the optionSelect is represented by an ArrayList of Strings that indicates what options where selected. + * @param w Width of the optionSelect + * @param h Height of the optionSelect + * @param close The Tab to be closed when the options are submitted. + * @param st The Student selected + */ + public OptionSelect(int w, int h, EnterInfoTab close, Student st){ + buttonList = new ArrayList>(); + height = h; + width = w; + student = st; + tabToBeClosed = close; + + init(); + + + } + /** + * Initializes contents of the optionSelect. + */ + public void init(){ + + + ftIn = new FadeTransition(Duration.millis(250), buttonVBox); + ftIn.setFromValue(0); + ftIn.setToValue(1.0); + ftIn.setCycleCount(1); + + + ftOut = new FadeTransition(Duration.millis(250), buttonVBox); + ftOut.setFromValue(1.0); + ftOut.setToValue(0); + ftOut.setCycleCount(1); + + + setMaxHeight(height); + setMaxWidth(width); + + submitButton = new Button("Submit"); + submitButton.setAlignment(Pos.BOTTOM_CENTER); + submitButton.getStyleClass().add("submitButton"); + submitButton.setDefaultButton(true); + submitButton.setOnAction(e -> handle()); + + titleLabel= new Label(); + titleLabel.getStyleClass().add("optionTitle"); + + getChildren().add(titleLabel); + getStyleClass().add("optionSelect"); + HBox contentHBox = new HBox(); + + pageButtonLeft = new Button(); + pageButtonLeft.getStyleClass().add("pageButton-left"); + pageButtonLeft.setOnAction(new NextHandler(false)); + + pageButtonRight = new Button(); + pageButtonRight.getStyleClass().add("pageButton-right"); + pageButtonRight.setOnAction(new NextHandler(true)); + + contentHBox.getChildren().add(pageButtonLeft); + buttonVBox = new VBox(); + buttonVBox.getStyleClass().add("buttonVBox"); + + contentHBox.getChildren().addAll(buttonVBox, pageButtonRight); + getChildren().add(contentHBox); + + bottomHBox = new HBox(); + bottomHBox.getStyleClass().add("bottomHBox"); + getChildren().add(bottomHBox); + + } + /** + * Adds a button. + * @param page The page of the carousel of the button + * @param name The text displayed in the button. + * @param mes The value of the Button + */ + public void addButton(int page, String name, String mes){ + buttonList.get(page).add(new OptionButton(name, mes, page)); + updateState(0); + } + + + /** + * Adds a page in the carousel. + * @param t The title of the page (usually the question). + */ + public void addPage(String t){ + buttonList.add(new ArrayList()); + title.add(t); + option.add(""); + OptionHBox textFieldOtherHBox = new OptionHBox(width, this, buttonList.size()-1); + textFieldOtherHBox.getStyleClass().add("optionTextFieldOther"); + optionHBoxArray.add(textFieldOtherHBox); + updateState(0); + } + + + /** + * Updates the state of the carousel. This is called every time the arrow buttons are clicked, + * or when a button/page is added. This method scales every child of the OptionSelect + * to fit the OptionSelect. + * @param pg The page to be displayed + */ + private void updateState(int pg){ + if(pg == 0 && pg == buttonList.size()-1){ + pageButtonLeft.setDisable(true); + pageButtonRight.setDisable(true); + } + else if(pg == 0 && pg == buttonList.size()-2){ + pageButtonLeft.setDisable(true); + pageButtonRight.setDisable(true); + } + else if (pg == 0){ + pageButtonLeft.setDisable(true); + pageButtonRight.setDisable(false); + } + else if (pg == buttonList.size()-1){ + pageButtonLeft.setDisable(false); + pageButtonRight.setDisable(true); + } + else{ + pageButtonLeft.setDisable(false); + pageButtonRight.setDisable(false); + } + titleLabel.setText(title.get(pg)); + page = pg; + + buttonVBox.getChildren().clear(); + double buttonHeight = (double)(height-80)/ (buttonList.get(page).size()+1); + double buttonWidth = (double)(width-100); + + if (buttonList.get(page).size() >=3){ + buttonList.get(page).get(0).setPosStyle("top"); + buttonList.get(page).get(0).setOnAction(new ButtonHandler(buttonList.get(page).get(0).getValue(), buttonList.get(page).get(0),this)); + buttonList.get(page).get(0).setPrefHeight(buttonHeight); + buttonList.get(page).get(0).setPrefWidth(buttonWidth); + buttonVBox.getChildren().add(buttonList.get(page).get(0)); + for (int i = 1; i < buttonList.get(page).size()-1; i++){ + buttonList.get(page).get(i).setPosStyle("mid"); + buttonVBox.getChildren().add(buttonList.get(page).get(i)); + + buttonList.get(page).get(i).setPrefHeight(buttonHeight); + buttonList.get(page).get(i).setPrefWidth(buttonWidth); + + buttonList.get(page).get(i).setOnAction(new ButtonHandler(buttonList.get(page).get(i).getValue(), buttonList.get(page).get(i),this)); + } + buttonList.get(page).get(buttonList.get(page).size()-1).setPosStyle("mid"); + buttonList.get(page).get(buttonList.get(page).size()-1).setOnAction(new ButtonHandler(buttonList.get(page).get(buttonList.get(page).size()-1).getValue(),buttonList.get(page).get(buttonList.get(page).size()-1), this)); + buttonList.get(page).get(buttonList.get(page).size()-1).setPrefHeight(buttonHeight); + buttonList.get(page).get(buttonList.get(page).size()-1).setPrefWidth(buttonWidth); + buttonVBox.getChildren().add(buttonList.get(page).get(buttonList.get(page).size()-1)); + } + else if (buttonList.get(page).size() == 2){ + buttonList.get(page).get(0).setPosStyle("top"); + buttonList.get(page).get(0).setOnAction(new ButtonHandler(buttonList.get(page).get(0).getValue(), buttonList.get(page).get(0),this)); + buttonList.get(page).get(0).setPrefHeight(buttonHeight); + buttonList.get(page).get(0).setPrefWidth(buttonWidth); + buttonVBox.getChildren().add(buttonList.get(page).get(0)); + + buttonList.get(page).get(buttonList.get(page).size()-1).setPosStyle("mid"); + buttonList.get(page).get(buttonList.get(page).size()-1).setOnAction(new ButtonHandler(buttonList.get(page).get(buttonList.get(page).size()-1).getValue(), buttonList.get(page).get(buttonList.get(page).size()-1), this)); + buttonList.get(page).get(buttonList.get(page).size()-1).setPrefHeight(buttonHeight); + buttonList.get(page).get(buttonList.get(page).size()-1).setPrefWidth(buttonWidth); + buttonVBox.getChildren().add(buttonList.get(page).get(buttonList.get(page).size()-1)); + + } + else if (buttonList.get(page).size() == 1){ + buttonList.get(page).get(0).setPosStyle("mid"); + buttonList.get(page).get(0).setPrefHeight(buttonHeight); + buttonList.get(page).get(0).setPrefWidth(buttonWidth); + buttonList.get(page).get(0).setOnAction(new ButtonHandler(buttonList.get(page).get(0).getValue(), buttonList.get(page).get(0),this)); + buttonVBox.getChildren().add(buttonList.get(page).get(0)); + } + + + + optionHBoxArray.get(page).setPrefHeight(buttonHeight); + optionHBoxArray.get(page).setPrefWidth(buttonWidth); + + buttonVBox.getChildren().add(optionHBoxArray.get(page)); + tabToBeClosed.updateScrollPane(option); + tabToBeClosed.updateAnimation(pg); + } + public void splitScreen(int page, String title1, String title2, ArrayList data1, ArrayList data2){ + ArrayList left = new ArrayList(); + for(int i =0;i right = new ArrayList(); + VBox bV = new VBox(); + for(int i = 0; i< data2.size();i++){ + OptionButton opt = new OptionButton(data2.get(i), data2.get(i), page); + opt.setPrefWidth((double)width-100); + opt.setPrefHeight((double)(height-80)/(buttonList.get(page).size()+1)); + right.add(opt); + } + bV.getChildren().add(right.get(page)); + bV.getChildren().add(left.get(page)); + + SplitPane splitPane = new SplitPane(new TableView(), + new VBox(new Label("some other content"))); + +splitPane.setOrientation(Orientation.HORIZONTAL); + +// place splitPane as center +BorderPane borderPane = new BorderPane(splitPane); + +borderPane.setTop(new MenuBar(new Menu())); + +Scene scene = new Scene(borderPane, 600, 400); +//getChildren().show(); + +// Component leftt = new List(); +// sp.setLeftComponent(leftt); + + + buttonList.get(page).addAll(left) ; + buttonList.get(page).addAll(right); + option.add(""); + + OptionHBox textFieldOtherHBox = new OptionHBox(width, this, buttonList.size()-1); + textFieldOtherHBox.getStyleClass().add("optionTextFieldOther"); + optionHBoxArray.add(textFieldOtherHBox); + + updateState(0); + } + + /** + * This is called by the ButtonHandler to add information to the Data. + * @param mes The value of the button clicked to be added. + */ + public void addInfo(String mes){ + option.set(page, mes); + } + public void addSubmitButton(int page){ + if(!bottomHBox.getChildren().contains(submitButton)){ + bottomHBox.getChildren().add(submitButton); + } + } + + private void setPage(boolean next){ + + if (next == true && (page + 1 < buttonList.size()-1)){ + transitionPage(page+1); + } + else if ((next != true) && (page - 1 >= 0)){ + transitionPage(page-1); + } + else if ((next == true) && (page + 1 == buttonList.size()-1)){ + transitionPage(page+1); + } + } + + /** + * This is called when the arrow buttons are clicked. If the current page is equal to the amount of pages. + * the User is brought to a custom Page with a submit button. + * @param pg + */ + private void transitionPage(int pg){ + if (pg == buttonList.size()-1){ + ftOut.play(); + page = page + 1; + ftIn.play(); + pageButtonRight.setDisable(true); + pageButtonLeft.setDisable(false); + } + else{ + for(ArrayList e: buttonList){ + for(OptionButton d: e){ + System.out.println(d); + } + } + ftOut.play(); + updateState(pg); + ftIn.play(); + } + + } + + /** + * The class that handles going to the next page. + * @author Kevin + * + */ + private class NextHandler implements EventHandler { + private boolean next ; + public NextHandler(boolean n) { + this.next = n; + } + @Override + public void handle(ActionEvent event) { + setPage(next); + } + + } + + /** + * The method that handles submitting the Data. + * @author Ishana + * + */ + + public void handle() { + submitButton.defaultButtonProperty().bind(submitButton.focusedProperty()); + tabToBeClosed.addData(option); + } + + + public ArrayList getOption(){ + ArrayList returnArr = new ArrayList(); + for (String o : option){ + returnArr.add(o); + } + return returnArr; + } + + public ArrayList getPageTitles(){ + ArrayList titleArray = new ArrayList(); + + for (String t : title){ + titleArray.add(t); + } + return titleArray; + } + + public int getPage(){ + return page; + } + +} \ No newline at end of file diff --git a/src/JavaFXGUI/PasswordLock.java b/src/JavaFXGUI/PasswordLock.java new file mode 100644 index 0000000..b648755 --- /dev/null +++ b/src/JavaFXGUI/PasswordLock.java @@ -0,0 +1,120 @@ +package JavaFXGUI; +import java.io.File; +import java.io.FileNotFoundException; +import java.math.BigInteger; +import java.security.SecureRandom; +import java.util.HashMap; +import java.util.Scanner; +import java.util.concurrent.atomic.AtomicBoolean; +import javafx.scene.effect.*; +import javafx.geometry.Insets; +import javafx.scene.layout.*; +import javafx.scene.control.*; +import backend.StudentList; + +/** + * A pane that locks whatever is inside it from view unless the correct password is added. + * @author Kevin + */ +@SuppressWarnings("restriction") +public class PasswordLock extends StackPane{ + // Does not have to 100% secure, just so student's can't access this. + private String passwordHash; + private String salt; + private StartApplication parent; + private SettingHBox optionBorderContentHBox; + private PasswordField passwordField; + /** + * Creates the PasswordLock. Reads from a file for a salted hash of the current stored + * password. + * @param p The parent of this node. + * @param width The width of the child node. + * @param d The data of the program. + */ + public PasswordLock(StartApplication p, double width, HashMap d, + AtomicBoolean busMode){ + SecureRandom random = new SecureRandom(); + salt = new BigInteger(130, random).toString(32); + Scanner configScanner = null; + File configFile = new File("src/data/settings.config"); + try { + configScanner = new Scanner(configFile); + passwordHash = configScanner.nextLine(); + salt = configScanner.nextLine(); + + configScanner.close(); + } catch (FileNotFoundException e1) { + e1.printStackTrace(); + } + + + + parent = p; + VBox passwordPanel = new VBox(); + passwordPanel.getStyleClass().add("passwordLock"); + + Label optionLabel = new Label("Please enter the password: "); + + passwordPanel.setMaxHeight(150); + passwordPanel.setMaxWidth(400); + + + passwordField = new PasswordField(); + passwordField.getStyleClass().add("passwordTextField"); + + + HBox buttonHBox = new HBox(); + + buttonHBox.setPadding(new Insets(15, 12, 15, 12)); + buttonHBox.setSpacing(10); + buttonHBox.getStyleClass().add("center"); + + Button cancelButton = new Button("Cancel"); + cancelButton.getStyleClass().add("closeButton"); + cancelButton.setOnAction(e -> cancel()); + + Button submitButton = new Button("Submit"); + submitButton.setOnAction(e-> submit()); + submitButton.setDefaultButton(true); + submitButton.getStyleClass().add("saveButton"); + + buttonHBox.getChildren().addAll(cancelButton, submitButton); + passwordPanel.getChildren().addAll(optionLabel, passwordField, buttonHBox); + + optionBorderContentHBox = new SettingHBox(p, width, d, passwordHash, salt, busMode); + BoxBlur bb = new BoxBlur(); + bb.setIterations(3); + optionBorderContentHBox.setEffect(bb); + optionBorderContentHBox.setDisable(true); + getChildren().add(optionBorderContentHBox); + + getChildren().add(passwordPanel); + } + /** + * Hides this and the child node. + */ + private void cancel(){ + parent.hideOptionsPage(); + } + /** + * Sees whether or not the the submitted password is equal to the current password. + * If so, disables the blur effect and unlocks the childNode for use. + */ + private void submit(){ + String p = passwordField.getText(); + p = SettingConfig.generateHash(p, salt); + if (passwordHash.equals(p)){ + optionBorderContentHBox.setEffect(null); + getChildren().remove(1); + optionBorderContentHBox.setDisable(false); + } + else{ + passwordField.getStyleClass().add("passwordTextField-error"); + ShakeTransition anim = new ShakeTransition(passwordField); + anim.play(); + } + + } + + +} diff --git a/src/JavaFXGUI/Playable.java b/src/JavaFXGUI/Playable.java new file mode 100644 index 0000000..a3254aa --- /dev/null +++ b/src/JavaFXGUI/Playable.java @@ -0,0 +1,12 @@ +package JavaFXGUI; +/** + * An interface that defines the something that can play an animation. + * @author Kevin + * + */ +public interface Playable { + public void play(); + public void reverse(); + public int getPage(); + public void clear(); +} diff --git a/src/JavaFXGUI/SettingConfig.java b/src/JavaFXGUI/SettingConfig.java new file mode 100644 index 0000000..262188f --- /dev/null +++ b/src/JavaFXGUI/SettingConfig.java @@ -0,0 +1,61 @@ +package JavaFXGUI; + +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.PrintWriter; +import java.math.BigInteger; +import java.security.*; + +/** + * An utility class to generate salted hashes and write to the settings file. + * @author Kevin + * + */ +public class SettingConfig { + /** + * Generates a salted MD5 hash. + * @param password The submitted password + * @param salt The salt + * @return The hash of the two put together. + */ + public static String generateHash(String password, String salt){ + String p = password + salt; + MessageDigest md = null; + try { + md = MessageDigest.getInstance("MD5"); + } catch (NoSuchAlgorithmException e) { + + e.printStackTrace(); + } + md.update(p.getBytes()); + byte byteData[] = md.digest(); + + + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < byteData.length; i++) { + sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1)); + } + p = sb.toString(); + return p; + + } + /** + * Writes to the settings file a new password, and generates a random hash. + * @param path The path of the settings.config file. + * @param password The password to be saved. + */ + public static void writeSettingsFile(String path, String password){ + SecureRandom random = new SecureRandom(); + String salt = new BigInteger(130, random).toString(32); + String passwordHash = generateHash(password, salt); + + try { + PrintWriter writer = new PrintWriter(new FileOutputStream(path, false)); + writer.println(passwordHash); + writer.println(salt); + writer.close(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + } +} diff --git a/src/JavaFXGUI/SettingHBox.java b/src/JavaFXGUI/SettingHBox.java new file mode 100644 index 0000000..35d2d73 --- /dev/null +++ b/src/JavaFXGUI/SettingHBox.java @@ -0,0 +1,809 @@ +package JavaFXGUI; +import java.io.File; +import java.util.concurrent.atomic.*; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Optional; + +import javafx.concurrent.WorkerStateEvent; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +import javafx.concurrent.Task; +import javafx.print.*; +import javafx.util.*; +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import javafx.geometry.Side; +import javafx.scene.Node; +import javafx.scene.layout.*; +import javafx.scene.control.*; +import javafx.scene.control.TabPane.TabClosingPolicy; +import javafx.scene.control.cell.*; +import javafx.collections.*; +import javafx.event.EventHandler; +import backend.*; +import javafx.scene.text.Text; +import javafx.scene.text.TextAlignment; +import javafx.stage.*; +import javafx.stage.FileChooser.ExtensionFilter; +import javafx.scene.control.ButtonBar.ButtonData; +import javafx.scene.web.*; + +/** + * A Panel that contains all the information on settings. + * Inside are a print button, a loading file button, a save button, + * a changePassword button, and a TabPane with Two tables that displays the data so far. + * @author Kevin + */ +@SuppressWarnings("restriction") +public class SettingHBox extends HBox{ + private ObservableList goingIn = FXCollections.observableArrayList(); + private ObservableList goingOutIn =FXCollections.observableArrayList(); + private EmailHandler sendEmail; + private StartApplication parent; + private TableView tableSignOut; + private TableView tableSignIn; + private String passwordHash; + private String salt; + private HashMapdata; + private AtomicBoolean busMode; + private String[] headers = {"Date", "Student ID", "Student Name", "Grade", "Reason for Late Arrival", + "Time In"}; + private String[] headersOut = {"Date", "Student ID", "Student Name", "Grade", "Reason for leaving", + "Excused By", "Time of Departure", "Time of Return"}; + @SuppressWarnings({ "rawtypes", "unchecked" }) + + /** + * Initializes the elements of this class. + * @param p The parent class. + * @param width The width of this class. + * @param d The data of this class. + * @param pHash The password hash. + * @param s The salt of the password hash. + */ + public SettingHBox(StartApplication p, double width, + HashMapd, String pHash, String s, AtomicBoolean bmode){ + busMode = bmode; + passwordHash = pHash; + salt = s; + data = d; + parent = p; + for (Student st : data.get("in").getStudentList()) { + goingIn.add(new StudentProperty(st)); + } + + for (Student st : data.get("outin").getStudentList()) { + goingOutIn.add(new StudentProperty(st)); + } + + HBox contentHBox = new HBox(); + VBox buttonVBox = new VBox(); + AnchorPane buttonAnchorPane = new AnchorPane(); + buttonAnchorPane.getStyleClass().add("buttonAnchorPane"); + + HBox viewButtonHBox = new HBox(); + viewButtonHBox.setPadding(new Insets(15, 12, 15, 12)); + viewButtonHBox.setSpacing(10); + + Button printButton = new Button("Print"); + printButton.setPrefSize(150, 40); + printButton.setMinSize(150, 40); + printButton.setOnAction(e -> print()); + printButton.getStyleClass().add("printButton"); + + Button loadButton = new Button("Load"); + loadButton.setPrefSize(150, 40); + loadButton.setMinSize(150, 40); + loadButton.getStyleClass().add("loadButton"); + loadButton.setOnAction(e -> openFile()); + + Button saveButton = new Button("Save"); + saveButton.setPrefSize(150, 40); + saveButton.setMinSize(150, 40); + saveButton.getStyleClass().add("saveButton"); + saveButton.setOnAction(e -> saveFile()); + + Button changePasswordButton = new Button("Change Password"); + changePasswordButton.setPrefSize(150, 40); + changePasswordButton.setMinSize(150, 40); + changePasswordButton.getStyleClass().add("changePasswordButton"); + changePasswordButton.setOnAction(e -> changePassword()); + + Button sendEmailButton = new Button("Send Report"); + sendEmailButton.setPrefSize(150, 40); + sendEmailButton.setMinSize(150, 40); + sendEmailButton.setOnAction(e -> sendEmail()); + sendEmailButton.getStyleClass().add("emailButton"); + CheckBox checkBox = new CheckBox("Late Bus Mode"); + checkBox.setSelected(busMode.get()); + checkBox.selectedProperty().addListener((ov, old_val, new_val) -> + { + busMode.set(new_val); + } + ); + + Button closeButton = new Button("Close"); + closeButton.setPrefSize(100, 40); + closeButton.setMinSize(100, 40); + closeButton.setOnAction(e -> parent.hideOptionsPage()); + closeButton.getStyleClass().add("closeButton"); + + viewButtonHBox.getChildren().add(closeButton); + buttonVBox.getChildren().addAll(printButton, loadButton, saveButton, + changePasswordButton, sendEmailButton, checkBox); + + buttonVBox.setPadding(new Insets(15, 15, 15, 15)); + buttonVBox.setSpacing(20); + + AnchorPane.setTopAnchor(buttonVBox, 0.0); + AnchorPane.setLeftAnchor(buttonVBox, 0.0); + + AnchorPane.setBottomAnchor(closeButton, 15.0); + AnchorPane.setLeftAnchor(closeButton, 15.0); + + buttonAnchorPane.getChildren().addAll(buttonVBox, closeButton); + contentHBox.getChildren().addAll(buttonAnchorPane); + + getChildren().add(contentHBox); + + TabPane tableTabPane = new TabPane(); + tableTabPane.setSide(Side.LEFT); + tableTabPane.getStyleClass().add("tabTable"); + + tableSignIn = createTableIn(); + + tableSignOut = createTableInOut(); + + + tableSignOut.setPrefWidth(3000); + tableSignIn.setPrefWidth(3000); + Tab signInTableTab = new Tab("Sign In Table"); + signInTableTab.setContent(tableSignIn); + + Tab signOutTableTab = new Tab("Sign Out Table"); + signOutTableTab.setContent(tableSignOut); + tableTabPane.getTabs().addAll(signInTableTab, signOutTableTab); + tableTabPane.setTabClosingPolicy(TabClosingPolicy.UNAVAILABLE); + getChildren().add(tableTabPane); + } + /** + * Utility function for creating a TableColumn + * @param mes The title of the TableColumn + * @return The TableColumn + */ + @SuppressWarnings("rawtypes") + private TableColumn createTableColumn(String mes){ + return new TableColumn(mes); + } + + + /** + * Prints the two tables, with a page break in between. The data of the program is + * converted to HTML format, which is then printed. + */ + @SuppressWarnings("unchecked") + private void print(){ + String htmlIn = " " + + "" + + "" + +"

Sign In Data

" + + "" + + ""; + for (String t : headers){ + htmlIn = htmlIn + ""; + } + htmlIn = htmlIn + ""; + htmlIn = htmlIn + ""; + for (Student st: data.get("in").getStudentList()){ + htmlIn = htmlIn + ""; + htmlIn = htmlIn + ""; + htmlIn = htmlIn + ""; + htmlIn = htmlIn + ""; + htmlIn = htmlIn + ""; + for(int i = 0;i" + st.getTime().get(i) + ""; + } + for(int i = 0;i" + st.getReason().get(i) + ""; + } + } + + String htmlOut = " " + + "" + + "" + + "

Sign out Data

" + + "
"+t+"
" + st.getDate() + "" + st.getStudentID() + "" + st.getName() + "" + st.getGrade() + "
" + + ""; + htmlOut = htmlOut + "
" + + ""; + for (String t : headersOut){ + htmlOut = htmlOut + ""; + } + htmlOut = htmlOut + ""; + htmlOut = htmlOut + ""; + for (Student st: data.get("outin").getStudentList()){ + htmlOut = htmlOut + ""; + htmlOut = htmlOut + ""; + htmlOut = htmlOut + ""; + htmlOut = htmlOut + ""; + htmlOut = htmlOut + ""; + for(int i = 0;i" + st.getReason().get(i) + ""; + } + for(int i = 0;i" + st.getExcused().get(i) + ""; + } + for(int i = 0;i" + st.getTime().get(i) + ""; + } + for(int i = 0;i" + st.getArrTime().get(i) + ""; + } + } + htmlOut = htmlOut + "
"+t+"
" + st.getDate() + "" + st.getStudentID() + "" + st.getName() + "" + st.getGrade() + "
"; + + WebView browserIn = new WebView(); + + browserIn.getEngine().loadContent(htmlIn); + WebView browserOut = new WebView(); + + browserOut.getEngine().loadContent(htmlOut); + + PrinterJob job = PrinterJob.createPrinterJob(); + boolean print = job.showPrintDialog(null); + if (job != null && print) { + browserIn.getEngine().print(job); + browserOut.getEngine().print(job); + job.endJob(); + } + + } + + /** + * Opens a database mer file and updates the database stored by the program. + * If the file is in an incorrect format. + */ + private void openFile(){ + FileChooser fileChooser = new FileChooser(); + fileChooser.setTitle("Open Database File"); + fileChooser.getExtensionFilters().addAll( + new ExtensionFilter("Database Files", "*.mer")); + File selectedFile = fileChooser.showOpenDialog(parent.stage); + if (selectedFile != null){ + StudentList studentData = parent.readStudentDatabase(selectedFile.getPath(), "d"); + if (studentData != null){ + data.put("database", studentData); + String text = ""; + try { + text = new String(Files.readAllBytes(Paths.get(selectedFile.getPath())), StandardCharsets.UTF_8); + } catch (IOException e) { + + + e.printStackTrace(); + } + try { + PrintWriter writer = new PrintWriter(new FileOutputStream("src/data/quartech.mer", false)); + writer.print(text); + writer.close(); + } catch (FileNotFoundException e) { + + e.printStackTrace(); + } + } + + } + + + } + /** + * Saves the files into a .csv for later viewing, preferably with Excel. + */ + private void saveFile(){ + DirectoryChooser fileChooser = new DirectoryChooser(); + fileChooser.setTitle("Save Log File"); + File selectedFile = fileChooser.showDialog((parent.stage)); + PrintWriter writer = null; + LocalDate todayDate = LocalDate.now(); + String date = todayDate.toString(); + + if (selectedFile!=null){ + try { + writer = new PrintWriter(selectedFile.getPath() + "/" + date + "-Sign-In.csv"); + } catch (FileNotFoundException e) { + System.out.println("ERROR"); + e.printStackTrace(); + } + + + for (String i : headers){ + writer.print( i+ ", "); + } + writer.println(); + ArrayList temp = data.get("in").getStudentList(); + for (int i = 0; i < temp.size(); i++){ + writer.print (temp.get(i).getDate() + ", "); + writer.print (temp.get(i).getName() + ", "); + writer.print (temp.get(i).getStudentID() + ", "); + writer.print (temp.get(i).getGrade() + ", "); + for(int j = 0;j> dialog = new Dialog<>(); + dialog.setTitle("Change Password"); + dialog.setHeaderText("Please enter your old, then new password below"); + ButtonType loginButtonType = new ButtonType("Change", ButtonData.OK_DONE); + dialog.getDialogPane().getButtonTypes().addAll(loginButtonType, ButtonType.CANCEL); + GridPane grid = new GridPane(); + grid.setHgap(10); + grid.setVgap(10); + grid.setPadding(new Insets(20, 150, 10, 10)); + + PasswordField oldPasswordTextField = new PasswordField(); + oldPasswordTextField.setPromptText("Old Password"); + oldPasswordTextField.setPrefWidth(250); + oldPasswordTextField.getStyleClass().add("passwordTextField"); + + PasswordField newPasswordTextField = new PasswordField(); + newPasswordTextField.setPromptText("New Password"); + newPasswordTextField.setPrefWidth(250); + newPasswordTextField.getStyleClass().add("passwordTextField"); + + + PasswordField newRepeatPasswordTextField = new PasswordField(); + newRepeatPasswordTextField.setPromptText("Confirm New Password"); + newRepeatPasswordTextField.setPrefWidth(250); + newRepeatPasswordTextField.getStyleClass().add("passwordTextField"); + + grid.add(new Label("Enter Old Password:"), 0, 0); + grid.add(oldPasswordTextField, 1, 0); + grid.add(new Label("Enter New Password:"), 0, 1); + grid.add(newPasswordTextField, 1, 1); + grid.add(new Label("Confirm New Password:"), 0, 2); + grid.add(newRepeatPasswordTextField, 1, 2); + + dialog.getDialogPane().setContent(grid); + dialog.setResultConverter(dialogButton -> { + if (dialogButton == loginButtonType) { + return new Pair<>(oldPasswordTextField.getText(), newPasswordTextField.getText()); + } + return null; + }); + + Node loginButton = dialog.getDialogPane().lookupButton(loginButtonType); + loginButton.setDisable(true); + oldPasswordTextField.textProperty().addListener((observable, oldValue, newValue) -> { + loginButton.setDisable(newPasswordTextField.getText().isEmpty() || !(passwordHash.equals( SettingConfig.generateHash(newValue, salt))) + || !(newPasswordTextField.getText().equals(newRepeatPasswordTextField.getText()))); + if(passwordHash.equals( SettingConfig.generateHash(newValue, salt))){ + if (oldPasswordTextField.getStyleClass().size() == 4){ + oldPasswordTextField.getStyleClass().add("passwordTextField-success"); + } + else{ + oldPasswordTextField.getStyleClass().remove(4); + oldPasswordTextField.getStyleClass().add("passwordTextField-success"); + } + } + else{ + if (oldPasswordTextField.getStyleClass().size() == 4){ + oldPasswordTextField.getStyleClass().add("passwordTextField-error"); + } + else{ + oldPasswordTextField.getStyleClass().remove(4); + oldPasswordTextField.getStyleClass().add("passwordTextField-error"); + } + } + }); + + + + newPasswordTextField.textProperty().addListener((observable, oldValue, newValue) -> { + loginButton.setDisable(!(passwordHash.equals(SettingConfig.generateHash(oldPasswordTextField.getText(), salt))) + || !(newPasswordTextField.getText().equals(newRepeatPasswordTextField.getText()))); + + if(newPasswordTextField.getText().equals(newRepeatPasswordTextField.getText())){ + if (newPasswordTextField.getStyleClass().size() == 4 && + newRepeatPasswordTextField.getStyleClass().size() == 4){ + newPasswordTextField.getStyleClass().add("passwordTextField-success"); + newRepeatPasswordTextField.getStyleClass().add("passwordTextField-success"); + } + else if(newPasswordTextField.getStyleClass().size() != 4 && + newRepeatPasswordTextField.getStyleClass().size() == 4){ + newPasswordTextField.getStyleClass().remove(4); + newPasswordTextField.getStyleClass().add("passwordTextField-success"); + newRepeatPasswordTextField.getStyleClass().add("passwordTextField-success"); + } + else if(newPasswordTextField.getStyleClass().size() == 4 && + newRepeatPasswordTextField.getStyleClass().size() != 4){ + newRepeatPasswordTextField.getStyleClass().remove(4); + newRepeatPasswordTextField.getStyleClass().add("passwordTextField-success"); + newPasswordTextField.getStyleClass().add("passwordTextField-success"); + } + else{ + newPasswordTextField.getStyleClass().remove(4); + newPasswordTextField.getStyleClass().add("passwordTextField-success"); + newRepeatPasswordTextField.getStyleClass().remove(4); + newRepeatPasswordTextField.getStyleClass().add("passwordTextField-success"); + } + } + else{ + if (newPasswordTextField.getStyleClass().size() == 4 && + newRepeatPasswordTextField.getStyleClass().size() == 4){ + newPasswordTextField.getStyleClass().add("passwordTextField-error"); + newRepeatPasswordTextField.getStyleClass().add("passwordTextField-error"); + } + else if(newPasswordTextField.getStyleClass().size() != 4 && + newRepeatPasswordTextField.getStyleClass().size() == 4){ + newPasswordTextField.getStyleClass().remove(4); + newPasswordTextField.getStyleClass().add("passwordTextField-error"); + newRepeatPasswordTextField.getStyleClass().add("passwordTextField-error"); + } + else if(newPasswordTextField.getStyleClass().size() == 4 && + newRepeatPasswordTextField.getStyleClass().size() != 4){ + newRepeatPasswordTextField.getStyleClass().remove(4); + newRepeatPasswordTextField.getStyleClass().add("passwordTextField-error"); + newPasswordTextField.getStyleClass().add("passwordTextField-error"); + } + else{ + newPasswordTextField.getStyleClass().remove(4); + newPasswordTextField.getStyleClass().add("passwordTextField-error"); + newRepeatPasswordTextField.getStyleClass().remove(4); + newRepeatPasswordTextField.getStyleClass().add("passwordTextField-error"); + } + } + + }); + + + newRepeatPasswordTextField.textProperty().addListener((observable, oldValue, newValue) -> { + loginButton.setDisable(!(passwordHash.equals( SettingConfig.generateHash(oldPasswordTextField.getText(), salt))) + || !(newPasswordTextField.getText().equals(newRepeatPasswordTextField.getText()))); + if(newPasswordTextField.getText().equals(newRepeatPasswordTextField.getText())){ + if (newPasswordTextField.getStyleClass().size() == 4 && + newRepeatPasswordTextField.getStyleClass().size() == 4){ + newPasswordTextField.getStyleClass().add("passwordTextField-success"); + newRepeatPasswordTextField.getStyleClass().add("passwordTextField-success"); + } + else if(newPasswordTextField.getStyleClass().size() != 4 && + newRepeatPasswordTextField.getStyleClass().size() == 4){ + newPasswordTextField.getStyleClass().remove(4); + newPasswordTextField.getStyleClass().add("passwordTextField-success"); + newRepeatPasswordTextField.getStyleClass().add("passwordTextField-success"); + } + else if(newPasswordTextField.getStyleClass().size() == 4 && + newRepeatPasswordTextField.getStyleClass().size() != 4){ + newRepeatPasswordTextField.getStyleClass().remove(4); + newRepeatPasswordTextField.getStyleClass().add("passwordTextField-success"); + newPasswordTextField.getStyleClass().add("passwordTextField-success"); + } + else{ + newPasswordTextField.getStyleClass().remove(4); + newPasswordTextField.getStyleClass().add("passwordTextField-success"); + newRepeatPasswordTextField.getStyleClass().remove(4); + newRepeatPasswordTextField.getStyleClass().add("passwordTextField-success"); + } + } + else{ + if (newPasswordTextField.getStyleClass().size() == 4 && + newRepeatPasswordTextField.getStyleClass().size() == 4){ + newPasswordTextField.getStyleClass().add("passwordTextField-error"); + newRepeatPasswordTextField.getStyleClass().add("passwordTextField-error"); + } + else if(newPasswordTextField.getStyleClass().size() != 4 && + newRepeatPasswordTextField.getStyleClass().size() == 4){ + newPasswordTextField.getStyleClass().remove(4); + newPasswordTextField.getStyleClass().add("passwordTextField-error"); + newRepeatPasswordTextField.getStyleClass().add("passwordTextField-error"); + } + else if(newPasswordTextField.getStyleClass().size() == 4 && + newRepeatPasswordTextField.getStyleClass().size() != 4){ + newRepeatPasswordTextField.getStyleClass().remove(4); + newRepeatPasswordTextField.getStyleClass().add("passwordTextField-error"); + newPasswordTextField.getStyleClass().add("passwordTextField-error"); + } + else{ + newPasswordTextField.getStyleClass().remove(4); + newPasswordTextField.getStyleClass().add("passwordTextField-error"); + newRepeatPasswordTextField.getStyleClass().remove(4); + newRepeatPasswordTextField.getStyleClass().add("passwordTextField-error"); + } + } + }); + dialog.getDialogPane().getStylesheets().add("css/application.css"); + ButtonBar buttonBar = (ButtonBar)dialog.getDialogPane().lookup(".button-bar"); + buttonBar.getButtons().get(0).getStyleClass().add("saveButton"); + buttonBar.getButtons().get(1).getStyleClass().add("closeButton"); + + + Optional> result = dialog.showAndWait(); + + result.ifPresent(newOldPassword -> { + SettingConfig.writeSettingsFile("src/data/settings.config", newOldPassword.getValue()); + }); + + } + + @SuppressWarnings("unchecked") + /** + * Creates a TableView with the sign in data format. + * @return A TableView Sign In. + */ + public TableView createTableIn(){ + TableView tableSignIn = new TableView(); + + + ArrayList columnList = new ArrayList(); + + + double[] widths = {0.1, 0.15, 0.25, 0.1, 0.275, 0.125}; + + for(int i = 0; i < headers.length; i++){ + columnList.add(createTableColumn(headers[i])); + columnList.get(i).setResizable(false); + columnList.get(i).prefWidthProperty().bind(tableSignIn.widthProperty().multiply(widths[i])); + if (i != 3){ + columnList.get(i).setCellFactory(column -> { + return new TableCell() { + @Override + protected void updateItem(Object item, boolean empty) { + super.updateItem(item, empty); + Text text = new Text(item.toString()); + text.wrappingWidthProperty().bind(getTableColumn().widthProperty()); // Setting the wrapping width to the Text + text.setTextAlignment(TextAlignment.CENTER); + setGraphic(text); + } + }; + }); +// columnList.get(i).setSortable(true); +// TimeComparator c = new TimeComparator(); +// columnList.sort(c); +// tableSignIn.sort(); + } + tableSignIn.getColumns().add(columnList.get(i)); +// tableSignIn.getColumns().size(), columnList.get(i)); + + } + + columnList.get(0).setCellValueFactory(new PropertyValueFactory("date")); + columnList.get(1).setCellValueFactory(new PropertyValueFactory("studentID")); + columnList.get(2).setCellValueFactory(new PropertyValueFactory("name")); + columnList.get(3).setCellValueFactory(new PropertyValueFactory("grade")); + columnList.get(4).setCellValueFactory(new PropertyValueFactory>("reason")); + columnList.get(5).setCellValueFactory(new PropertyValueFactory>("time")); + + columnList.get(5).setSortable(true); +// columnList.get(5).setComparator(new TimeComparator()); + tableSignIn.setItems(goingIn); +// tableSignIn.sort(); + return tableSignIn; + + } + + /** + * Creates a TableView with a sign out format. + * @return A sign out TableView + */ + @SuppressWarnings("unchecked") + public TableView createTableInOut(){ + TableView tableSignOut = new TableView(); + + + ArrayList columnListOut = new ArrayList(); + + + double[] widthsOut = {0.1, 0.125, 0.115, 0.05, 0.175, 0.13, 0.15, 0.15}; + + for(int i = 0; i < headersOut.length; i++){ + columnListOut.add(createTableColumn(headersOut[i])); + columnListOut.get(i).setResizable(false); + columnListOut.get(i).prefWidthProperty().bind(tableSignOut.widthProperty().multiply(widthsOut[i])); + if (i != 3){ + columnListOut.get(i).setCellFactory(column -> { + return new TableCell() { + @Override + protected void updateItem(Object item, boolean empty) { + super.updateItem(item, empty); + Text text = new Text(item.toString()); + text.wrappingWidthProperty().bind(getTableColumn().widthProperty()); // Setting the wrapping width to the Text + text.setTextAlignment(TextAlignment.CENTER); + setGraphic(text); + } + }; + }); + columnListOut.get(i).setSortable(false); + } + tableSignOut.getColumns().add(columnListOut.get(i)); + } + + columnListOut.get(0).setCellValueFactory(new PropertyValueFactory("date")); + columnListOut.get(1).setCellValueFactory(new PropertyValueFactory("studentID")); + columnListOut.get(2).setCellValueFactory(new PropertyValueFactory("name")); + columnListOut.get(3).setCellValueFactory(new PropertyValueFactory("grade")); + columnListOut.get(4).setCellValueFactory(new PropertyValueFactory>("reason")); + columnListOut.get(5).setCellValueFactory(new PropertyValueFactory>("excused")); + columnListOut.get(6).setCellValueFactory(new PropertyValueFactory>("time")); + columnListOut.get(7).setCellValueFactory(new PropertyValueFactory>("arrTime")); + + tableSignOut.setItems(goingOutIn); + return tableSignOut; + } + + public void sendEmail(){ + Dialog> dialog = new Dialog<>(); + dialog.setTitle("Send Report"); + dialog.setHeaderText("Please enter emails, separated by commas"); + ButtonType loginButtonType = new ButtonType("Send", ButtonData.OK_DONE); + dialog.getDialogPane().getButtonTypes().addAll(loginButtonType, ButtonType.CANCEL); + + TextArea emailTextArea = new TextArea(); + emailTextArea.setWrapText(true); + ArrayList emailList = EmailHandler.readEmailList(); + + + + + + dialog.getDialogPane().setContent(emailTextArea); + dialog.setResultConverter(dialogButton -> { + if (dialogButton == loginButtonType) { + return new Pair<>(emailTextArea.getText(), ""); + } + return null; + }); + + Node sendEmailButton = dialog.getDialogPane().lookupButton(loginButtonType); + sendEmailButton.setDisable(true); + if (emailList.size() != 0){ + String temp = ""; + for (int i = 0; i < emailList.size(); i++){ + if (emailList.size() != 1 && i != emailList.size()-1){ + temp = temp + emailList.get(i) + ", "; + } + else{ + temp = temp + emailList.get(i); + } + } + emailTextArea.setText(temp); + String[] d = temp.split(","); + boolean valid = true; + for (int i =0; i < d.length; i++){ + d[i] = d[i].trim(); + if (!EmailHandler.isValidEmailAddress(d[i])){ + valid = false; + } + } + if (valid){ + sendEmailButton.setDisable(false); + } + else{ + sendEmailButton.setDisable(true); + } + } + + emailTextArea.textProperty().addListener((observable, oldValue, newValue) -> { + + String[] d = newValue.split(","); + boolean valid = true; + for (int i =0; i < d.length; i++){ + d[i] = d[i].trim(); + if (!EmailHandler.isValidEmailAddress(d[i])){ + valid = false; + } + } + if (valid){ + sendEmailButton.setDisable(false); + if (emailTextArea.getStyleClass().size() == 4){ + emailTextArea.getStyleClass().remove(3); + + } + + } + else{ + sendEmailButton.setDisable(true); + if (emailTextArea.getStyleClass().size() == 4){ + emailTextArea.getStyleClass().remove(3); + emailTextArea.getStyleClass().add("passwordTextField-error"); + } + else if (emailTextArea.getStyleClass().size() == 3){ + emailTextArea.getStyleClass().add("passwordTextField-error"); + } + } + }); + dialog.getDialogPane().getStylesheets().add("css/application.css"); + ButtonBar buttonBar = (ButtonBar)dialog.getDialogPane().lookup(".button-bar"); + buttonBar.getButtons().get(0).getStyleClass().add("saveButton"); + buttonBar.getButtons().get(1).getStyleClass().add("closeButton"); + Optional> result = dialog.showAndWait(); + + result.ifPresent(email -> { + + String[] d = email.getKey().split(","); + ArrayList destination = new ArrayList(); + for (String i : d){ + destination.add(i.trim()); + } + sendEmail = new EmailHandler("smcs2019.quartech@gmail.com", "quartech", destination); + sendEmail.send(); + + EmailHandler.writeEmailList(destination); + + + + + }); + } + + +} diff --git a/src/JavaFXGUI/ShakeTransition.java b/src/JavaFXGUI/ShakeTransition.java new file mode 100644 index 0000000..5f72219 --- /dev/null +++ b/src/JavaFXGUI/ShakeTransition.java @@ -0,0 +1,58 @@ +package JavaFXGUI; +import javafx.animation.*; +import javafx.scene.*; +import javafx.beans.property.SimpleDoubleProperty; +import javafx.beans.property.DoubleProperty; +import javafx.util.*; +import javafx.event.*; +import javafx.animation.KeyFrame; +import javafx.animation.KeyValue; +import javafx.animation.TimelineBuilder; +import javafx.scene.Node; +import javafx.util.Duration; + +/** + * Animate a shake effect on the given node + * + * Port of Shake from Animate.css http://daneden.me/animate by Dan Eden + * + * {@literal @}keyframes shake { + * 0%, 100% {transform: translateX(0);} + * 10%, 30%, 50%, 70%, 90% {transform: translateX(-10px);} + * 20%, 40%, 60%, 80% {transform: translateX(10px);} + * } + * + * @author Jasper Potts + */ +public class ShakeTransition extends CachedTimelineTransition { + /** + * Create new ShakeTransition + * + * @param node The node to affect + */ + + @SuppressWarnings({ "restriction", "deprecation" }) + public ShakeTransition(final Node node) { + + super( + node, + TimelineBuilder.create() + .keyFrames( + new KeyFrame(Duration.millis(0), new KeyValue(node.translateXProperty(), 0, WEB_EASE)), + new KeyFrame(Duration.millis(100), new KeyValue(node.translateXProperty(), -5, WEB_EASE)), + new KeyFrame(Duration.millis(200), new KeyValue(node.translateXProperty(), 5, WEB_EASE)), + new KeyFrame(Duration.millis(300), new KeyValue(node.translateXProperty(), -5, WEB_EASE)), + new KeyFrame(Duration.millis(400), new KeyValue(node.translateXProperty(), 5, WEB_EASE)), + new KeyFrame(Duration.millis(500), new KeyValue(node.translateXProperty(), -5, WEB_EASE)), + new KeyFrame(Duration.millis(600), new KeyValue(node.translateXProperty(), 5, WEB_EASE)), + new KeyFrame(Duration.millis(700), new KeyValue(node.translateXProperty(), -5, WEB_EASE)), + new KeyFrame(Duration.millis(800), new KeyValue(node.translateXProperty(), 5, WEB_EASE)), + new KeyFrame(Duration.millis(900), new KeyValue(node.translateXProperty(), -5, WEB_EASE)), + new KeyFrame(Duration.millis(1000), new KeyValue(node.translateXProperty(), 0, WEB_EASE)) + ) + .build() + ); + setCycleDuration(Duration.seconds(0.6)); + setDelay(Duration.seconds(0.2)); + } +} \ No newline at end of file diff --git a/src/JavaFXGUI/StartApplication.java b/src/JavaFXGUI/StartApplication.java new file mode 100644 index 0000000..3e98fcc --- /dev/null +++ b/src/JavaFXGUI/StartApplication.java @@ -0,0 +1,284 @@ +package JavaFXGUI; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.file.Files; +import java.nio.file.Path; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.Scanner; +import java.util.concurrent.atomic.AtomicBoolean; + +import javafx.animation.FadeTransition; +import javafx.application.Application; +import javafx.scene.Group; +import javafx.scene.Scene; +import javafx.scene.layout.*; +import javafx.scene.paint.Color; +import javafx.stage.Stage; +import javafx.util.Duration; +import backend.Student; +import backend.StudentList; +import javafx.scene.control.*; +import javafx.stage.Modality; +import javafx.scene.image.*; +@SuppressWarnings("restriction") +/** + * The Main class of the program. This class is run to initialize everything. + * @author Kevin + */ +public class StartApplication extends Application { + private StackPane content; + private MenuTabPane tabPane; + private FadeTransition brightenTransition; + private BorderPane optionBorderPane; + private HashMap data; + private HBox contentPane; + private AtomicBoolean busMode = new AtomicBoolean(false); + public Stage stage; + + public static void main(String[] args) { + launch(args); + } + /** + * Initializes all of the values. The School database is read from an internal + * file "src/data/SchoolDatabase.mer." The other two StudentLists are emtpy if the + * backup file does not exist, other they are populated with the backup file's data. + * The data itself is stored in a HashMap of Strings and StudentLists. + */ + @Override + public void start(Stage primaryStage) throws Exception { + stage = primaryStage; + StudentList studentData = readStudentDatabase("src//data//quartech.mer", "d"); + StudentList studentIn = new StudentList(); + StudentList studentOutIn = new StudentList(); + stage.getIcons().add(new Image("img//logo.png")); + + LocalDate todayDate = LocalDate.now(); + String date = todayDate.toString(); + File f = new File("src/backup/" + date+"-IN.csv"); + if(f.exists() && !f.isDirectory()) { + studentIn = readStudentDatabase(f.getPath(), "i"); + } + else{ + try { + f.createNewFile(); + } catch (IOException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + try { + PrintWriter printWriter = new PrintWriter (f); + printWriter.println("DATE,ID,NAME,GR,TIME,REASON"); + printWriter.close(); + } + catch(IOException e1){ + e1.printStackTrace(); + + } + } + + + f = new File("src/backup/" + date+"-OUT.csv"); + if(f.exists() && !f.isDirectory()) { + studentOutIn = readStudentDatabase(f.getPath(), "o"); + } + else{ + try { + f.createNewFile(); + } catch (IOException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + try { + PrintWriter printWriter = new PrintWriter (f); + printWriter.println("DATE,ID,NAME,GR,REASON,EXCUSED,TIME,ARRTIME"); + printWriter.close(); + } + catch(IOException e1){ + e1.printStackTrace(); + + } + } + for (int i = 0; i < 30; i ++){ + LocalDate pastDate = todayDate.minusDays(40 + i); + date = pastDate.toString(); + + f = new File("src/backup/" + date+"-IN.csv"); + + Files.deleteIfExists(f.toPath()); + f = new File("src/backup/" + date+"-OUT.csv"); + + Files.deleteIfExists(f.toPath()); + } + + + data = new HashMap(); + data.put("database", studentData); + data.put("in", studentIn); + data.put("outin", studentOutIn); + primaryStage.setTitle("Office Sign In"); //TODO Title + Group root = new Group(); + Scene scene = new Scene(root, 1200, 750, Color.WHITE); + tabPane = new MenuTabPane(this, data, busMode); + + content = new StackPane(); + BorderPane borderPane = new BorderPane(); + + scene.getStylesheets().add("css/application.css"); + + borderPane.prefHeightProperty().bind(scene.heightProperty()); + borderPane.prefWidthProperty().bind(scene.widthProperty()); + + borderPane.setCenter(tabPane); + content.getChildren().add(borderPane); + root.getChildren().add(content); + primaryStage.setScene(scene); + primaryStage.show(); + + optionBorderPane= new BorderPane(); + optionBorderPane.getStyleClass().add("optionContent"); + optionBorderPane.setOpacity(0); + contentPane = new HBox(); + + + contentPane.getStyleClass().add("ContentPane"); + + + contentPane.setPrefHeight(primaryStage.getHeight()-100); + contentPane.setMaxHeight(primaryStage.getHeight()-100); + + contentPane.setPrefWidth(primaryStage.getWidth()-100); + contentPane.setMaxWidth(primaryStage.getWidth()-100); + + optionBorderPane.setCenter(contentPane); + + brightenTransition = new FadeTransition(Duration.millis(100), optionBorderPane); + brightenTransition.setFromValue(0); + brightenTransition.setToValue(1.0); + brightenTransition.setCycleCount(1); + + } + /** + * Shows the settings page. + */ + + public void showOptionsPage(){ + content.getChildren().add(optionBorderPane); + PasswordLock optionBorderContentHBox = new PasswordLock(this, stage.getWidth() - 102, data, busMode); + contentPane.getChildren().clear(); + contentPane.getChildren().add(optionBorderContentHBox); + brightenTransition.play(); + } + + /** + * Hides the settings page. + */ + public void hideOptionsPage(){ + content.getChildren().remove(optionBorderPane); + tabPane.init.switchMode(); + } + /** + * Reads from a mer file. A Mer file is a .csv with an extra row on the top for headers. + * No spaces are in between elements of the .csv. If there is an error, a pop-up window that displays an error + * is displayed. + * @param fileName The file path of the mer. + * @param opt which type of data it is (database, sign in, or signout) + * @return Returns a StudentList of students in the data file. + */ + @SuppressWarnings("resource") + public StudentList readStudentDatabase(String fileName, String opt){ + try{ + StudentList list = new StudentList(); + Scanner file = null; + try { + file = new Scanner(new File(fileName)); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + //create Map of Fields (line 1) + Map field = new HashMap(); + int i = 0; + for(String fieldName: file.nextLine().split(",")){ + field.put(fieldName.trim(), i++); + } + + //Load in student data + ArrayList> studentData = new ArrayList>(); + while(file.hasNext()){ + ArrayList aStudent = new ArrayList(); + String line = file.nextLine(); + line = line.substring(1); + line = line.substring(0,line.length()-1); + for(String studentField: line.split("\",\"")){ + aStudent.add(studentField.trim()); + } + studentData.add(aStudent); + + } + + //eliminate duplicates + for(i = 0; i < studentData.size(); i++){ + String id = studentData.get(i).get(field.get("ID")); + for(int j = studentData.size() - 1; j > i; j--){ + String id2 = studentData.get(j).get(field.get("ID")); + if(id.equals(id2)){ + studentData.remove(j); + } + } + } + if (opt == "d"){ + for(ArrayList student: studentData){ + String id = (student.get(field.get("ID"))); + String name = student.get(field.get("FIRST"))+" "+student.get(field.get("LAST")); + int grade = Integer.parseInt(student.get(field.get("GR"))); + list.add(new Student (name,grade,id)); + } + } + else if (opt == "i"){ + for(ArrayList student: studentData){ + String id = student.get(field.get("ID")); + String name = student.get(field.get("NAME")); + int grade = Integer.parseInt(student.get(field.get("GR"))); + Student st = new Student (name,grade,id); + st.setTime(student.get(field.get("TIME"))); + st.setReason(student.get(field.get("REASON"))); + st.setDate(student.get(field.get("DATE"))); + list.add(st); + } + } + else if (opt == "o"){ + for(ArrayList student: studentData){ + String id = student.get(field.get("ID")); + String name = student.get(field.get("NAME")); + int grade = Integer.parseInt(student.get(field.get("GR"))); + Student st = new Student (name,grade,id); + st.setTime(student.get(field.get("TIME"))); + st.setReason(student.get(field.get("REASON"))); + st.setArrTime(student.get(field.get("ARRTIME"))); + st.setExcused(student.get(field.get("EXCUSED"))); + st.setDate(student.get(field.get("DATE"))); + list.add(st); + } + } + return list; + } catch (Exception e){ + Alert alert = new Alert(Alert.AlertType.ERROR); + alert.setTitle("Warning"); + alert.setHeaderText(null); + alert.setContentText("File format error"); + DialogPane dialogPane = alert.getDialogPane(); + dialogPane.getStylesheets().add("css/application.css"); + dialogPane.getStyleClass().add("alertBox"); + alert.initModality(Modality.APPLICATION_MODAL); + alert.show(); + return new StudentList(); + } + } + + +} diff --git a/src/JavaFXGUI/StartTab.java b/src/JavaFXGUI/StartTab.java new file mode 100644 index 0000000..1dd4151 --- /dev/null +++ b/src/JavaFXGUI/StartTab.java @@ -0,0 +1,394 @@ +package JavaFXGUI; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.PrintWriter; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.Scanner; +import java.util.concurrent.atomic.AtomicBoolean; + +import backend.Student; +import backend.StudentList; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.input.MouseEvent; +import javafx.scene.layout.*; +import javafx.scene.control.*; +import javafx.scene.effect.BoxBlur; +import javafx.application.Platform; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.event.EventHandler; +import javafx.geometry.*; + +/** + * The Starting tab of the program. + * @author Kevin + */ +@SuppressWarnings("restriction") +public class StartTab extends Tab { + private ObservableList subentries = FXCollections.observableArrayList(); + private MenuTabPane parent; + private HashMap data; + private AnimatedAlertBox alert; + private BorderPane content; + private AtomicBoolean busMode; + private ListView list; + private ObservableList nameEntries; + private TextField searchTextField; + /** + * Initializes two buttons in the middle and a third View Records button in the bottom + * left + * @param p The Parent of this node. + * @param title The title of this tab. + * @param data The data of the program. + */ + public StartTab(MenuTabPane p, String title, HashMap data, AtomicBoolean bMode){ + busMode = bMode; + + this.data = data; + parent = p; + setText(title); + content = new BorderPane(); + + HBox viewButtonHBox = new HBox(); + viewButtonHBox.setPadding(new Insets(15, 12, 15, 12)); + viewButtonHBox.setSpacing(10); + + MenuBar menuBar = new MenuBar(); + Menu settings = new Menu("Settings"); + settings.setGraphic(viewButtonHBox); + CheckMenuItem lateBus = new CheckMenuItem("Late Bus Mode"); + lateBus.setSelected(busMode.get()); + lateBus.selectedProperty().addListener((ov, old_val, new_val) -> + { + busMode.set(new_val); + } + ); +// if(lateBus.isSelected()){ +//// VBox passwordPanel = new VBox(); +//// passwordPanel.getStyleClass().add("passwordLock"); +//// +//// Label optionLabel = new Label("Please enter the password: "); +//// +//// passwordPanel.setMaxHeight(150); +//// passwordPanel.setMaxWidth(400); +//// +//// PasswordField passwordField = new PasswordField(); +//// passwordField.getStyleClass().add("passwordTextField"); +//// +//// +//// HBox buttonHBox = new HBox(); +//// +//// buttonHBox.setPadding(new Insets(15, 12, 15, 12)); +//// buttonHBox.setSpacing(10); +//// buttonHBox.getStyleClass().add("center"); +//// +//// Button cancelButton = new Button("Cancel"); +//// cancelButton.getStyleClass().add("closeButton"); +//// cancelButton.setOnAction(e -> cancel()); +//// +//// Button submitButton = new Button("Submit"); +//// submitButton.setOnAction(e-> submit()); +//// submitButton.setDefaultButton(true); +//// submitButton.getStyleClass().add("saveButton"); +//// +//// buttonHBox.getChildren().addAll(cancelButton, submitButton); +//// passwordPanel.getChildren().addAll(optionLabel, passwordField, buttonHBox); +//// +//// SettingHBox optionBorderContentHBox = new SettingHBox(this, 1000, new HashMap(), "ss", "salt", busMode); +//// BoxBlur bb = new BoxBlur(); +//// bb.setIterations(3); +//// optionBorderContentHBox.setEffect(bb); +//// optionBorderContentHBox.setDisable(true); +//// content.getChildren().add(optionBorderContentHBox); +//// +//// content.getChildren().add(passwordPanel); +// } + + + MenuItem viewButton = new MenuItem("View Records"); +// viewButton.setPrefSize(150, 20); + viewButton.setOnAction(e -> parent.parent.showOptionsPage()); +// viewButtonHBox.getChildren().add(viewButton); + settings.getItems().add(viewButton); + settings.getItems().add(lateBus); + menuBar.getMenus().add(settings); + content.setBottom(menuBar); + alert = new AnimatedAlertBox("Submission Sucessful!", false); + content.setTop(alert); + +// content.setBottom(viewButtonHBox); + setContent(content); + switchMode(); + + } + /** + * Goes to the next page by creating a EnterStudentTab. + * @param signIn + */ + private void moveOn(boolean signIn){ + EnterStudentTab tab2 = null; + if (signIn){ + tab2 = new EnterStudentTab(parent, this, "Sign In", data, signIn); + } + else{ + tab2 = new EnterStudentTab(parent, this, "Sign Out", data, signIn); + } + setDisable(true); + parent.getTabs().add(tab2); + parent.getSelectionModel().select(tab2); + + } + + public void switchMode(){ + + if (busMode.get()){ + list = new ListView(); + + + Tooltip toolList = new Tooltip("Double click to select student, \n" + + "or select student and then click submit"); + list.setTooltip(toolList); + + + + + + VBox imageHBox = new VBox(); + imageHBox.setAlignment(Pos.CENTER); + imageHBox.setPadding(new Insets(15, 12, 15, 12)); + imageHBox.setSpacing(10); + + + + + + Image photoID = new Image("img//image.png"); + ImageView photoIDView = new ImageView(); + photoIDView.setImage(photoID); + photoIDView.setFitWidth(300); + photoIDView.setPreserveRatio(true); + photoIDView.setSmooth(true); + photoIDView.setCache(true); + + HBox labelHBox = new HBox(); + imageHBox.setPadding(new Insets(15, 12, 15, 12)); + imageHBox.setSpacing(10); + + Label studentIDLabel = new Label("Enter student name for late bus: "); + studentIDLabel.getStyleClass().add("studentIDLabel"); + Button submitButton = new Button("Submit"); + submitButton.setDefaultButton(true); + submitButton.setPrefSize(100, 20); + submitButton.setOnAction(e -> submitButton()); + labelHBox.getChildren().addAll(studentIDLabel); + labelHBox.setAlignment(Pos.CENTER); + + + + + + nameEntries = FXCollections.observableArrayList(data.get("database").getInfoList()); + FXCollections.sort(nameEntries, new StudentComparator()); + searchTextField = new TextField(); + searchTextField.setPromptText("Search"); + searchTextField.textProperty().addListener( + new ChangeListener() { + public void changed(ObservableValue observable, + Object oldVal, Object newVal) { + searchStudent(nameEntries, (String)oldVal, (String)newVal); + } + }); + Platform.runLater(new Runnable() { + public void run() { + searchTextField.requestFocus(); + } + }); + + Tooltip toolTextField = new Tooltip(" Enter in keywords " + + "\n separated by a space. "); + searchTextField.setTooltip(toolTextField); + + list.setMaxHeight(400); + + list.setItems(nameEntries); + list.getStyleClass().add("searchTextField"); + + VBox searchVBox = new VBox(); + searchVBox.setPadding(new Insets(15, 12, 15, 12)); + searchVBox.setSpacing(10); + searchVBox.setMaxSize(500, 300); + searchVBox.getChildren().addAll(searchTextField, list); + list.setOnMouseClicked(new EventHandler() { + public void handle(MouseEvent click) { + if (click.getClickCount() == 2) { + String currentItemSelected = (String) list.getSelectionModel().getSelectedItem(); + list.getSelectionModel().select(-1); + submit(currentItemSelected); + } + } + }); + + + + imageHBox.getChildren().addAll(photoIDView, labelHBox, searchVBox, submitButton); + + content.setCenter(imageHBox); + + } + else{ + HBox contentHBox = new HBox(); + contentHBox.setAlignment(Pos.CENTER); + contentHBox.setPadding(new Insets(15, 12, 15, 12)); + contentHBox.setSpacing(10); + + + Button buttonSignIn = new Button("Student Sign In"); + buttonSignIn.setPrefSize(200, 40); + buttonSignIn.setOnAction(e -> moveOn(true)); + + + Button buttonSignOut = new Button("Student Sign Out"); + buttonSignOut.setPrefSize(200, 40); + buttonSignOut.setOnAction(e -> moveOn(false)); + + Image photoID = new Image("img//image.png"); + ImageView photoIDView = new ImageView(); + photoIDView.setImage(photoID); + photoIDView.setFitWidth(350); + photoIDView.setPreserveRatio(true); + photoIDView.setSmooth(true); + photoIDView.setCache(true); + VBox v = new VBox(); + v.getChildren().add(photoIDView); + + contentHBox.getChildren().addAll(buttonSignIn, buttonSignOut); + content.setCenter(contentHBox); + + } + + } + /** + * Displays a Success message when an entry is successfully submitted + */ + public void displaySuccess(){ + alert.setWarning(false); + alert.play(); + } + + + public void searchStudent(ObservableList entries, String oldVal, String newVal) { + + if ( oldVal != null && (newVal.length() < oldVal.length()) ) { + list.setItems( entries ); + } + + String[] parts = newVal.toUpperCase().split(" "); + + subentries = FXCollections.observableArrayList(); + for ( Object entry: list.getItems() ) { + boolean match = true; + String entryText = (String)entry; + for ( String part: parts ) { + if ( ! entryText.toUpperCase().contains(part) ) { + match = false; + break; + } + } + + if ( match ) { + subentries.add(entryText); + } + } + list.setItems(subentries); + } + + public void submitButton(){ + + searchTextField.requestFocus(); + String selected = (String) list.getSelectionModel().getSelectedItem(); + String submittedText = ""; + if (selected == null){ + if (subentries.size() !=0){ + if (subentries.size() ==1){ + submittedText = subentries.get(0); + ArrayList toStringList = data.get("database").getInfoList(); + if (toStringList.contains(submittedText)){ + submit(submittedText); + } + } + else{ + alert.setWarning(true); + alert.play("Please continue entering information until there is only one possible student."); + } + } + else{ + if (searchTextField.getText().isEmpty()){ + alert.setWarning(true); + + alert.play("Please submit your name."); + } + else{ + alert.setWarning(true); + alert.play("The student \"" + searchTextField.getText() + "\" was not found."); + } + } + } + else{ + submit(selected); + } + } + + public void submit(String txt){ + searchTextField.clear(); + LocalDate todayDate = LocalDate.now(); + String date = todayDate.toString(); + + + + Student newStudent = data.get("database").getStudentByToString(txt); + newStudent.setReason("Late Bus"); + data.get("in").add(newStudent); + + File f = new File("src/backup/" + date+"-IN.csv"); + try { + f.createNewFile(); + } catch (IOException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + + try { + PrintWriter printWriter = new PrintWriter (f); + printWriter.println("DATE,ID,NAME,GR,TIME,REASON"); + for(Student st : data.get("in").getStudentList()){ + printWriter.print("\"" + st.getDate() + "\","); + printWriter.print("\"" + st.getStudentID() + "\","); + printWriter.print("\"" + st.getName() + "\","); + printWriter.print("\"" + st.getGrade() + "\","); + for(int i = 0;i{ + + @Override + + public int compare(Student o1, Student o2) { + return o1.getTime().get(0).compareTo(o2.getTime().get(0)); + } + +} diff --git a/src/backend/GifDecoder.java b/src/backend/GifDecoder.java new file mode 100644 index 0000000..e7fc75a --- /dev/null +++ b/src/backend/GifDecoder.java @@ -0,0 +1,768 @@ +package backend; + +import java.net.*; +import java.io.*; +import java.net.URL; +import java.util.*; +import java.awt.*; +import java.awt.image.*; + +/** + * Class GifDecoder - Decodes a GIF file into one or more frames. + * + * No copyright asserted on the source code of this class. May be used for + * any purpose, however, refer to the Unisys LZW patent for any additional + * restrictions. Please forward any corrections to kweiner@fmsware.com. + * + * @author Kevin Weiner, FM Software; LZW decoder adapted from John Cristy's ImageMagick. + * @version 1.03 November 2003 + * + */ + +public class GifDecoder { + + /** + * File read status: No errors. + */ + public static final int STATUS_OK = 0; + + /** + * File read status: Error decoding file (may be partially decoded) + */ + public static final int STATUS_FORMAT_ERROR = 1; + + /** + * File read status: Unable to open source. + */ + public static final int STATUS_OPEN_ERROR = 2; + + protected BufferedInputStream in; + protected int status; + + protected int width; // full image width + protected int height; // full image height + protected boolean gctFlag; // global color table used + protected int gctSize; // size of global color table + protected int loopCount = 1; // iterations; 0 = repeat forever + + protected int[] gct; // global color table + protected int[] lct; // local color table + protected int[] act; // active color table + + protected int bgIndex; // background color index + protected int bgColor; // background color + protected int lastBgColor; // previous bg color + protected int pixelAspect; // pixel aspect ratio + + protected boolean lctFlag; // local color table flag + protected boolean interlace; // interlace flag + protected int lctSize; // local color table size + + protected int ix, iy, iw, ih; // current image rectangle + protected Rectangle lastRect; // last image rect + protected BufferedImage image; // current frame + protected BufferedImage lastImage; // previous frame + + protected byte[] block = new byte[256]; // current data block + protected int blockSize = 0; // block size + + // last graphic control extension info + protected int dispose = 0; + // 0=no action; 1=leave in place; 2=restore to bg; 3=restore to prev + protected int lastDispose = 0; + protected boolean transparency = false; // use transparent color + protected int delay = 0; // delay in milliseconds + protected int transIndex; // transparent color index + + protected static final int MaxStackSize = 4096; + // max decoder pixel stack size + + // LZW decoder working arrays + protected short[] prefix; + protected byte[] suffix; + protected byte[] pixelStack; + protected byte[] pixels; + + protected ArrayList frames; // frames read from current file + protected int frameCount; + + static class GifFrame { + public GifFrame(BufferedImage im, int del) { + image = im; + delay = del; + } + public BufferedImage image; + public int delay; + } + + /** + * Gets display duration for specified frame. + * + * @param n int index of frame + * @return delay in milliseconds + */ + public int getDelay(int n) { + // + delay = -1; + if ((n >= 0) && (n < frameCount)) { + delay = ((GifFrame) frames.get(n)).delay; + } + return delay; + } + + /** + * Gets the number of frames read from file. + * @return frame count + */ + public int getFrameCount() { + return frameCount; + } + + /** + * Gets the first (or only) image read. + * + * @return BufferedImage containing first frame, or null if none. + */ + public BufferedImage getImage() { + return getFrame(0); + } + + /** + * Gets the "Netscape" iteration count, if any. + * A count of 0 means repeat indefinitiely. + * + * @return iteration count if one was specified, else 1. + */ + public int getLoopCount() { + return loopCount; + } + + /** + * Creates new frame image from current data (and previous + * frames as specified by their disposition codes). + */ + protected void setPixels() { + // expose destination image's pixels as int array + int[] dest = + ((DataBufferInt) image.getRaster().getDataBuffer()).getData(); + + // fill in starting image contents based on last image's dispose code + if (lastDispose > 0) { + if (lastDispose == 3) { + // use image before last + int n = frameCount - 2; + if (n > 0) { + lastImage = getFrame(n - 1); + } else { + lastImage = null; + } + } + + if (lastImage != null) { + int[] prev = + ((DataBufferInt) lastImage.getRaster().getDataBuffer()).getData(); + System.arraycopy(prev, 0, dest, 0, width * height); + // copy pixels + + if (lastDispose == 2) { + // fill last image rect area with background color + Graphics2D g = image.createGraphics(); + Color c = null; + if (transparency) { + c = new Color(0, 0, 0, 0); // assume background is transparent + } else { + c = new Color(lastBgColor); // use given background color + } + g.setColor(c); + g.setComposite(AlphaComposite.Src); // replace area + g.fill(lastRect); + g.dispose(); + } + } + } + + // copy each source line to the appropriate place in the destination + int pass = 1; + int inc = 8; + int iline = 0; + for (int i = 0; i < ih; i++) { + int line = i; + if (interlace) { + if (iline >= ih) { + pass++; + switch (pass) { + case 2 : + iline = 4; + break; + case 3 : + iline = 2; + inc = 4; + break; + case 4 : + iline = 1; + inc = 2; + } + } + line = iline; + iline += inc; + } + line += iy; + if (line < height) { + int k = line * width; + int dx = k + ix; // start of line in dest + int dlim = dx + iw; // end of dest line + if ((k + width) < dlim) { + dlim = k + width; // past dest edge + } + int sx = i * iw; // start of line in source + while (dx < dlim) { + // map color and insert in destination + int index = ((int) pixels[sx++]) & 0xff; + int c = act[index]; + if (c != 0) { + dest[dx] = c; + } + dx++; + } + } + } + } + + /** + * Gets the image contents of frame n. + * @param n The frame number of the animation. + * @return BufferedImage representation of frame, or null if n is invalid. + */ + public BufferedImage getFrame(int n) { + BufferedImage im = null; + if ((n >= 0) && (n < frameCount)) { + im = ((GifFrame) frames.get(n)).image; + } + return im; + } + + /** + * Gets image size. + * + * @return GIF image dimensions + */ + public Dimension getFrameSize() { + return new Dimension(width, height); + } + + /** + * Reads GIF image from stream + * + * @param is BufferedInputStream containing GIF file. + * @return read status code (0 = no errors) + */ + public int read(BufferedInputStream is) { + init(); + if (is != null) { + in = is; + readHeader(); + if (!err()) { + readContents(); + if (frameCount < 0) { + status = STATUS_FORMAT_ERROR; + } + } + } else { + status = STATUS_OPEN_ERROR; + } + try { + is.close(); + } catch (IOException e) { + } + return status; + } + + /** + * Reads GIF image from stream + * + * @param is InputStream containing GIF file. + * @return read status code (0 = no errors) + */ + public int read(InputStream is) { + init(); + if (is != null) { + if (!(is instanceof BufferedInputStream)) + is = new BufferedInputStream(is); + in = (BufferedInputStream) is; + readHeader(); + if (!err()) { + readContents(); + if (frameCount < 0) { + status = STATUS_FORMAT_ERROR; + } + } + } else { + status = STATUS_OPEN_ERROR; + } + try { + is.close(); + } catch (IOException e) { + } + return status; + } + + /** + * Reads GIF file from specified file/URL source + * (URL assumed if name contains ":/" or "file:") + * + * @param name String containing source + * @return read status code (0 = no errors) + */ + public int read(String name) { + status = STATUS_OK; + try { + name = name.trim().toLowerCase(); + if ((name.indexOf("file:") >= 0) || + (name.indexOf(":/") > 0)) { + URL url = new URL(name); + in = new BufferedInputStream(url.openStream()); + } else { + in = new BufferedInputStream(new FileInputStream(name)); + } + status = read(in); + } catch (IOException e) { + status = STATUS_OPEN_ERROR; + } + + return status; + } + + /** + * Decodes LZW image data into pixel array. + * Adapted from John Cristy's ImageMagick. + */ + protected void decodeImageData() { + int NullCode = -1; + int npix = iw * ih; + int available, + clear, + code_mask, + code_size, + end_of_information, + in_code, + old_code, + bits, + code, + count, + i, + datum, + data_size, + first, + top, + bi, + pi; + + if ((pixels == null) || (pixels.length < npix)) { + pixels = new byte[npix]; // allocate new pixel array + } + if (prefix == null) prefix = new short[MaxStackSize]; + if (suffix == null) suffix = new byte[MaxStackSize]; + if (pixelStack == null) pixelStack = new byte[MaxStackSize + 1]; + + // Initialize GIF data stream decoder. + + data_size = read(); + clear = 1 << data_size; + end_of_information = clear + 1; + available = clear + 2; + old_code = NullCode; + code_size = data_size + 1; + code_mask = (1 << code_size) - 1; + for (code = 0; code < clear; code++) { + prefix[code] = 0; + suffix[code] = (byte) code; + } + + // Decode GIF pixel stream. + + datum = bits = count = first = top = pi = bi = 0; + + for (i = 0; i < npix;) { + if (top == 0) { + if (bits < code_size) { + // Load bytes until there are enough bits for a code. + if (count == 0) { + // Read a new data block. + count = readBlock(); + if (count <= 0) + break; + bi = 0; + } + datum += (((int) block[bi]) & 0xff) << bits; + bits += 8; + bi++; + count--; + continue; + } + + // Get the next code. + + code = datum & code_mask; + datum >>= code_size; + bits -= code_size; + + // Interpret the code + + if ((code > available) || (code == end_of_information)) + break; + if (code == clear) { + // Reset decoder. + code_size = data_size + 1; + code_mask = (1 << code_size) - 1; + available = clear + 2; + old_code = NullCode; + continue; + } + if (old_code == NullCode) { + pixelStack[top++] = suffix[code]; + old_code = code; + first = code; + continue; + } + in_code = code; + if (code == available) { + pixelStack[top++] = (byte) first; + code = old_code; + } + while (code > clear) { + pixelStack[top++] = suffix[code]; + code = prefix[code]; + } + first = ((int) suffix[code]) & 0xff; + + // Add a new string to the string table, + + if (available >= MaxStackSize) + break; + pixelStack[top++] = (byte) first; + prefix[available] = (short) old_code; + suffix[available] = (byte) first; + available++; + if (((available & code_mask) == 0) + && (available < MaxStackSize)) { + code_size++; + code_mask += available; + } + old_code = in_code; + } + + // Pop a pixel off the pixel stack. + + top--; + pixels[pi++] = pixelStack[top]; + i++; + } + + for (i = pi; i < npix; i++) { + pixels[i] = 0; // clear missing pixels + } + + } + + /** + * Returns true if an error was encountered during reading/decoding + */ + protected boolean err() { + return status != STATUS_OK; + } + + /** + * Initializes or re-initializes reader + */ + protected void init() { + status = STATUS_OK; + frameCount = 0; + frames = new ArrayList(); + gct = null; + lct = null; + } + + /** + * Reads a single byte from the input stream. + */ + protected int read() { + int curByte = 0; + try { + curByte = in.read(); + } catch (IOException e) { + status = STATUS_FORMAT_ERROR; + } + return curByte; + } + + /** + * Reads next variable length block from input. + * + * @return number of bytes stored in "buffer" + */ + protected int readBlock() { + blockSize = read(); + int n = 0; + if (blockSize > 0) { + try { + int count = 0; + while (n < blockSize) { + count = in.read(block, n, blockSize - n); + if (count == -1) + break; + n += count; + } + } catch (IOException e) { + } + + if (n < blockSize) { + status = STATUS_FORMAT_ERROR; + } + } + return n; + } + + /** + * Reads color table as 256 RGB integer values + * + * @param ncolors int number of colors to read + * @return int array containing 256 colors (packed ARGB with full alpha) + */ + protected int[] readColorTable(int ncolors) { + int nbytes = 3 * ncolors; + int[] tab = null; + byte[] c = new byte[nbytes]; + int n = 0; + try { + n = in.read(c); + } catch (IOException e) { + } + if (n < nbytes) { + status = STATUS_FORMAT_ERROR; + } else { + tab = new int[256]; // max size to avoid bounds checks + int i = 0; + int j = 0; + while (i < ncolors) { + int r = ((int) c[j++]) & 0xff; + int g = ((int) c[j++]) & 0xff; + int b = ((int) c[j++]) & 0xff; + tab[i++] = 0xff000000 | (r << 16) | (g << 8) | b; + } + } + return tab; + } + + /** + * Main file parser. Reads GIF content blocks. + */ + protected void readContents() { + // read GIF file content blocks + boolean done = false; + while (!(done || err())) { + int code = read(); + switch (code) { + + case 0x2C : // image separator + readImage(); + break; + + case 0x21 : // extension + code = read(); + switch (code) { + case 0xf9 : // graphics control extension + readGraphicControlExt(); + break; + + case 0xff : // application extension + readBlock(); + String app = ""; + for (int i = 0; i < 11; i++) { + app += (char) block[i]; + } + if (app.equals("NETSCAPE2.0")) { + readNetscapeExt(); + } + else + skip(); // don't care + break; + + default : // uninteresting extension + skip(); + } + break; + + case 0x3b : // terminator + done = true; + break; + + case 0x00 : // bad byte, but keep going and see what happens + break; + + default : + status = STATUS_FORMAT_ERROR; + } + } + } + + /** + * Reads Graphics Control Extension values + */ + protected void readGraphicControlExt() { + read(); // block size + int packed = read(); // packed fields + dispose = (packed & 0x1c) >> 2; // disposal method + if (dispose == 0) { + dispose = 1; // elect to keep old image if discretionary + } + transparency = (packed & 1) != 0; + delay = readShort() * 10; // delay in milliseconds + transIndex = read(); // transparent color index + read(); // block terminator + } + + /** + * Reads GIF file header information. + */ + protected void readHeader() { + String id = ""; + for (int i = 0; i < 6; i++) { + id += (char) read(); + } + if (!id.startsWith("GIF")) { + status = STATUS_FORMAT_ERROR; + return; + } + + readLSD(); + if (gctFlag && !err()) { + gct = readColorTable(gctSize); + bgColor = gct[bgIndex]; + } + } + + /** + * Reads next frame image + */ + protected void readImage() { + ix = readShort(); // (sub)image position & size + iy = readShort(); + iw = readShort(); + ih = readShort(); + + int packed = read(); + lctFlag = (packed & 0x80) != 0; // 1 - local color table flag + interlace = (packed & 0x40) != 0; // 2 - interlace flag + // 3 - sort flag + // 4-5 - reserved + lctSize = 2 << (packed & 7); // 6-8 - local color table size + + if (lctFlag) { + lct = readColorTable(lctSize); // read table + act = lct; // make local table active + } else { + act = gct; // make global table active + if (bgIndex == transIndex) + bgColor = 0; + } + int save = 0; + if (transparency) { + save = act[transIndex]; + act[transIndex] = 0; // set transparent color if specified + } + + if (act == null) { + status = STATUS_FORMAT_ERROR; // no color table defined + } + + if (err()) return; + + decodeImageData(); // decode pixel data + skip(); + + if (err()) return; + + frameCount++; + + // create new image to receive frame data + image = + new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB_PRE); + + setPixels(); // transfer pixel data to image + + frames.add(new GifFrame(image, delay)); // add image to frame list + + if (transparency) { + act[transIndex] = save; + } + resetFrame(); + + } + + /** + * Reads Logical Screen Descriptor + */ + protected void readLSD() { + + // logical screen size + width = readShort(); + height = readShort(); + + // packed fields + int packed = read(); + gctFlag = (packed & 0x80) != 0; // 1 : global color table flag + // 2-4 : color resolution + // 5 : gct sort flag + gctSize = 2 << (packed & 7); // 6-8 : gct size + + bgIndex = read(); // background color index + pixelAspect = read(); // pixel aspect ratio + } + + /** + * Reads Netscape extenstion to obtain iteration count + */ + protected void readNetscapeExt() { + do { + readBlock(); + if (block[0] == 1) { + // loop count sub-block + int b1 = ((int) block[1]) & 0xff; + int b2 = ((int) block[2]) & 0xff; + loopCount = (b2 << 8) | b1; + } + } while ((blockSize > 0) && !err()); + } + + /** + * Reads next 16-bit value, LSB first + */ + protected int readShort() { + // read 16-bit value, LSB first + return read() | (read() << 8); + } + + /** + * Resets frame state for reading next image. + */ + protected void resetFrame() { + lastDispose = dispose; + lastRect = new Rectangle(ix, iy, iw, ih); + lastImage = image; + lastBgColor = bgColor; + dispose = 0; + transparency = false; + delay = 0; + lct = null; + } + + /** + * Skips variable length blocks up to and including + * next zero length block. + */ + protected void skip() { + do { + readBlock(); + } while ((blockSize > 0) && !err()); + } +} \ No newline at end of file diff --git a/src/backend/Student.java b/src/backend/Student.java new file mode 100644 index 0000000..92b0b5f --- /dev/null +++ b/src/backend/Student.java @@ -0,0 +1,130 @@ +package backend; + +import java.time.*; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Locale; + + +/** + * Data class that holds information on each student. Holds name, studentID and grade. + * @author Kevin + */ +public class Student implements Comparable{ + + private String name; + private int grade; + private String studentID; + private ArrayList reason = new ArrayList(); + private String date; + private ArrayList time = new ArrayList(); + private ArrayList excused = new ArrayList(); + private ArrayList arrTime = new ArrayList(); + + /** + * Constructor. Initializes Date and Time at moment of creation + * + * @param n Name of student. + * @param g Grade of student. + * @param sID ID of student. + */ + + public Student(String n, int g, String sID){ + name = n; + grade = (Integer) g; + studentID = sID; + LocalDate todayDate = LocalDate.now(); + date = todayDate.toString(); + + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("hh:mm a", Locale.US); + LocalTime todayTime = LocalTime.now(); + time.add(formatter.format(todayTime)); + + } + + + + /** + * Copy Constructor. Applies current date and time, NOT date and time of different student. + * + * @param other Student to be copied. + */ + public Student(Student other) { + name = other.name; + grade = other.grade; + studentID = other.studentID; + LocalDate todayDate = LocalDate.now(); + date = todayDate.toString(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("hh:mm a", Locale.US); + LocalTime todayTime = LocalTime.now(); + time.add(formatter.format(todayTime)); + + } + + + + public String getName() { + return name; + } + + public int getGrade() { + return grade; + } + + public String getStudentID() { + return studentID; + } + + + public String toString(){ + return " " + String.format("%-37s", name) +grade; + } + + + + public ArrayList getReason() { + return reason; + } + + + + public void setReason(String reason) { + this.reason.add(reason); + } + + public ArrayList getTime(){ + return time; + } + + public void setTime(String t){ + time.add(t); + } + + public String getDate(){ + return date; + } + public void setDate(String d){ + date = d; + } + public ArrayList getExcused() { + return excused; + } + public void setExcused(String excused) { + this.excused.add(excused); + } + public void setArrTime(String arrTime) { + this.arrTime.add(arrTime); + } + public ArrayList getArrTime() { + return arrTime; + } + + public int compareTo(Student o) { + return toString().compareTo(o.toString()); + } + + public boolean equals(Student other){ + return this.toString().equals(other.toString()); + } + +} \ No newline at end of file diff --git a/src/backend/StudentList.java b/src/backend/StudentList.java new file mode 100644 index 0000000..a144b0b --- /dev/null +++ b/src/backend/StudentList.java @@ -0,0 +1,131 @@ + + +//TODO Start writing Javadoc +package backend; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +/** + * Container class for Student. + * Holds Students in two Hashmaps, one in <name, Student>, one in <studentID, Student> + * @author Kevin + */ +public class StudentList { + + private Map nameMap; + private Map studentIDMap; + + + /** + * No args- constructor. Creates empty StudentList + */ + public StudentList(){ + studentIDMap = new HashMap (); + nameMap = new HashMap (); + } + /** + * Adds a student to the StudentList. + * @param student The Student to add. + */ + public void add(Student student){ + studentIDMap.put(student.getStudentID(), student); + nameMap.put(student.getName(), student); + } + + + /** + * Searches for Student in the StudentList by ID. + * @param sID The Student ID to be searched. + * @return Returns the Student with that studentID + */ + public Student getStudentByID(String sID){ + return new Student(studentIDMap.get(sID)); + } + + /** + * Searches for Student in the StudentList by name. + * @param name The name to be searched. + * @return Returns the Student with that name. + */ + public Student getStudentByName(String name){ + return new Student(nameMap.get(name)); + } + /** + * Searches for Student in the StudentList by toString value. + * @param s The name to be searched. + * @return Returns the Student with that name. + */ + public Student getStudentByToString(String s){ + String result = ""; + for (int i= 2; i < s.length() - 1; i++){ + if (s.charAt(i) == ' ' && s.charAt(i + 1) == ' '){ + break; + } + else{ + result = result + s.substring(i, i+1); + } + } + return new Student(getStudentByName(result)); + } + /** + * Gets list of names. + * @return Returns ArrayList <String> in lexicographic order, all lowercase. + */ + public ArrayList getNameList(){ + ArrayList res = new ArrayList(); + res.addAll(nameMap.keySet()); + // sort(res, 0, res.size()); + return res; + } + + + /** + * Gets list of ID + name + grade. + * @return Returns ArrayList <String> in numerical order, + */ + public ArrayList getInfoList(){ + ArrayList res = new ArrayList(); + for (Student student: nameMap.values()){ + res.add(student.toString()); + } + // sort(res, 0, res.size()); + return res; + } + /** + * Gets list of IDs. + * @return Returns ArrayList <Integer> in numerical order, + */ + public ArrayList getIDList(){ + ArrayList res = new ArrayList(); + res.addAll(studentIDMap.keySet()); + // sort(res, 0, res.size()); + return res; + } + + /** + * Gets list of Students. + * @return Returns ArrayList <Integer> in numerical order, + */ + public ArrayList getStudentList(){ + return new ArrayList(nameMap.values()); + } + /** + * Gets size of the StudentList + * @param other Student to be checked + * @return Returns if Student is in the StudentList. + */ + public boolean contains(Student other){ + if (nameMap.values().contains(other)){ + return true; + } + return false; + } + /** + * Gets size of the StudentList + * @return Returns size. + */ + public int size(){ + return nameMap.values().size(); + } +} \ No newline at end of file diff --git a/src/backend/StudentProperty.java b/src/backend/StudentProperty.java new file mode 100644 index 0000000..4dae185 --- /dev/null +++ b/src/backend/StudentProperty.java @@ -0,0 +1,112 @@ +package backend; +import java.util.ArrayList; + +import javafx.beans.property.*; + +/** + * Wrapper Class of student for implementation in a TableView. + * @author Kevin + */ +@SuppressWarnings("restriction") +public class StudentProperty { + private SimpleStringProperty name; + private SimpleIntegerProperty grade; + private SimpleStringProperty studentID; + private ArrayList reason = new ArrayList(); + private SimpleStringProperty date; + private ArrayList time = new ArrayList(); + private ArrayList excused = new ArrayList(); + private ArrayList arrTime = new ArrayList(); + + /** + * Constructs StudentProperty from a Student and copies all the data. + * @param st the Student to be copied + */ + public StudentProperty(Student st){ + name = new SimpleStringProperty(st.getName()); + grade = new SimpleIntegerProperty(st.getGrade()); + studentID = new SimpleStringProperty(st.getStudentID()); + for(int i = 0; i getReason() { + return reason; + } + + public void setReason(String reason) { + SimpleStringProperty r = new SimpleStringProperty(reason); + this.reason.add(r); + } + + public String getDate() { + return date.get(); + } + + public void setDate(String date) { + this.date.set(date); + } + + public ArrayList getExcused() { + return excused; + } + + public void setExcused(String excused) { + SimpleStringProperty e = new SimpleStringProperty(excused); + this.excused.add(e); + } + + public ArrayList getArrTime() { + return arrTime; + } + + public void setArrTime(String arrTime) { + SimpleStringProperty a = new SimpleStringProperty(arrTime); + this.arrTime.add(a); + } + public ArrayList getTime() { + return time; + } + + public void setTime(String time) { + SimpleStringProperty t = new SimpleStringProperty(time); + this.time.add(t); + } + + +} \ No newline at end of file diff --git a/src/backup/2017-05-06-IN.csv b/src/backup/2017-05-06-IN.csv new file mode 100644 index 0000000..3e64306 --- /dev/null +++ b/src/backup/2017-05-06-IN.csv @@ -0,0 +1 @@ +DATE,ID,NAME,GR,TIME,REASON,NOTE diff --git a/src/backup/2017-05-06-OUT.csv b/src/backup/2017-05-06-OUT.csv new file mode 100644 index 0000000..f0bb21e --- /dev/null +++ b/src/backup/2017-05-06-OUT.csv @@ -0,0 +1 @@ +DATE,ID,NAME,GR,REASON,EXCUSED,TIME,ARRTIME,NOTE diff --git a/src/backup/2017-05-07-IN.csv b/src/backup/2017-05-07-IN.csv new file mode 100644 index 0000000..2b0bb45 --- /dev/null +++ b/src/backup/2017-05-07-IN.csv @@ -0,0 +1 @@ +DATE,ID,NAME,GR,TIME,REASON diff --git a/src/backup/2017-05-07-OUT.csv b/src/backup/2017-05-07-OUT.csv new file mode 100644 index 0000000..8be6953 --- /dev/null +++ b/src/backup/2017-05-07-OUT.csv @@ -0,0 +1 @@ +DATE,ID,NAME,GR,REASON,EXCUSED,TIME,ARRTIME diff --git a/src/backup/2017-05-08-IN.csv b/src/backup/2017-05-08-IN.csv new file mode 100644 index 0000000..2b0bb45 --- /dev/null +++ b/src/backup/2017-05-08-IN.csv @@ -0,0 +1 @@ +DATE,ID,NAME,GR,TIME,REASON diff --git a/src/backup/2017-05-08-OUT.csv b/src/backup/2017-05-08-OUT.csv new file mode 100644 index 0000000..8be6953 --- /dev/null +++ b/src/backup/2017-05-08-OUT.csv @@ -0,0 +1 @@ +DATE,ID,NAME,GR,REASON,EXCUSED,TIME,ARRTIME diff --git a/src/backup/2017-05-09-IN.csv b/src/backup/2017-05-09-IN.csv new file mode 100644 index 0000000..83604ce --- /dev/null +++ b/src/backup/2017-05-09-IN.csv @@ -0,0 +1,2 @@ +DATE,ID,NAME,GR,TIME,REASON +"2017-05-09","353851","Ishana Shastri","9","05:44 PM","Late Bus", diff --git a/src/backup/2017-05-09-OUT.csv b/src/backup/2017-05-09-OUT.csv new file mode 100644 index 0000000..8be6953 --- /dev/null +++ b/src/backup/2017-05-09-OUT.csv @@ -0,0 +1 @@ +DATE,ID,NAME,GR,REASON,EXCUSED,TIME,ARRTIME diff --git a/src/backup/2017-05-10-IN.csv b/src/backup/2017-05-10-IN.csv new file mode 100644 index 0000000..d841658 --- /dev/null +++ b/src/backup/2017-05-10-IN.csv @@ -0,0 +1,5 @@ +DATE,ID,NAME,GR,TIME,REASON +"2017-05-10","347989","Sruthi Ganesh","9","10:43 AM","Transportation""""""", +"2017-05-10","126042","Vaibhav Patil","9","02:03 PM","im stupid", +"2017-05-10","984751","Ryan Lentz","12","10:56 AM","College Visit""""", +"2017-05-10","347696","Joseph Lang","9","10:41 AM","Unexcused"""""""", diff --git a/src/backup/2017-05-10-OUT.csv b/src/backup/2017-05-10-OUT.csv new file mode 100644 index 0000000..7403531 --- /dev/null +++ b/src/backup/2017-05-10-OUT.csv @@ -0,0 +1,8 @@ +DATE,ID,NAME,GR,REASON,EXCUSED,TIME,ARRTIME +"2017-05-10","347493","Macy Palmer","9","College Visit","Parent","10:44 AM","02:02 PM""", +"2017-05-10","347818","Sridhar Ganti","9","Religious Reason","Parent","10:30 AM","02:04 PM"", +"2017-05-10","346344","Emma Moon","9","College Visit","","11:09 AM","None""""""", +"2017-05-10","370958","Michelle Gu","9","Religious Reason","Parent","10:29 AM","10:56 AM"""""""""", +"2017-05-10","372675","Daniel Fong","9","Religious Reason","Parent","12:02 AM","05:49 PM", +"2017-05-10","374267","Vincent Bian","9","Religious Reason","Health Room","01:59 PM","None"""", +"2017-05-10","349901","Justin Ma","9","Religious Reason","","11:08 AM","02:02 PM""", diff --git a/src/backup/2017-05-12-IN.csv b/src/backup/2017-05-12-IN.csv new file mode 100644 index 0000000..5ba94ae --- /dev/null +++ b/src/backup/2017-05-12-IN.csv @@ -0,0 +1,9 @@ +DATE,ID,NAME,GR,TIME,REASON +2017-05-12,229702,Edward Parker,9,02:26 PM,Religious Reason, +2017-05-12,976576,Sean Murphey,12,01:55 AM,Sick"""""", +2017-05-12,353851,Ishana Shastri,9,01:56 AM,Transportation"""""", +2017-05-12,191721,Spencer Chan,9,01:55 AM,Doctor/Dentist Appointment"""""", +2017-05-12,349387,Adiat Muyeen,9,08:00 AM,Sick""", +2017-05-12,349901,Justin Ma,9,01:56 AM,Religious Reason"""""", +2017-05-12,359307,Rao Li,10,01:35 PM,Unexcused"", +2017-05-12,331474,Grace Kim,9,07:53 AM,Religious Reason"""", diff --git a/src/backup/2017-05-12-OUT.csv b/src/backup/2017-05-12-OUT.csv new file mode 100644 index 0000000..78a5d26 --- /dev/null +++ b/src/backup/2017-05-12-OUT.csv @@ -0,0 +1,2 @@ +DATE,ID,NAME,GR,REASON,EXCUSED,TIME,ARRTIME +"2017-05-12","369393","Varshini Selvadurai","10","Religious Reason","","01:49 PM","02:24 PM"", diff --git a/src/backup/2017-05-14-IN.csv b/src/backup/2017-05-14-IN.csv new file mode 100644 index 0000000..2b0bb45 --- /dev/null +++ b/src/backup/2017-05-14-IN.csv @@ -0,0 +1 @@ +DATE,ID,NAME,GR,TIME,REASON diff --git a/src/backup/2017-05-14-OUT.csv b/src/backup/2017-05-14-OUT.csv new file mode 100644 index 0000000..8be6953 --- /dev/null +++ b/src/backup/2017-05-14-OUT.csv @@ -0,0 +1 @@ +DATE,ID,NAME,GR,REASON,EXCUSED,TIME,ARRTIME diff --git a/src/backup/2017-05-15-IN.csv b/src/backup/2017-05-15-IN.csv new file mode 100644 index 0000000..2b0bb45 --- /dev/null +++ b/src/backup/2017-05-15-IN.csv @@ -0,0 +1 @@ +DATE,ID,NAME,GR,TIME,REASON diff --git a/src/backup/2017-05-15-OUT.csv b/src/backup/2017-05-15-OUT.csv new file mode 100644 index 0000000..7084f4d --- /dev/null +++ b/src/backup/2017-05-15-OUT.csv @@ -0,0 +1,2 @@ +DATE,ID,NAME,GR,REASON,EXCUSED,TIME,ARRTIME +2017-05-15,327515,Jhasper Paul,11,Doctor/Dentist Appointment,Health Room,11:58 PM,None, diff --git a/src/backup/2017-05-16-IN.csv b/src/backup/2017-05-16-IN.csv new file mode 100644 index 0000000..79e9668 --- /dev/null +++ b/src/backup/2017-05-16-IN.csv @@ -0,0 +1,2 @@ +DATE,ID,NAME,GR,TIME,REASON +"2017-05-16","441161","Mariam Rahman","9","12:27 AM","Religious Reason"", diff --git a/src/backup/2017-05-16-OUT.csv b/src/backup/2017-05-16-OUT.csv new file mode 100644 index 0000000..d487ee5 --- /dev/null +++ b/src/backup/2017-05-16-OUT.csv @@ -0,0 +1,3 @@ +DATE,ID,NAME,GR,REASON,EXCUSED,TIME,ARRTIME +"2017-05-16","315824","Rachel Tievy","9","College Visit","Parent","12:25 AM","None""""", +"2017-05-16","350448","Rohit Chari","11","Sick","Parent","10:30 AM","11:06 AM", diff --git a/src/backup/2017-05-18-IN.csv b/src/backup/2017-05-18-IN.csv new file mode 100644 index 0000000..2b0bb45 --- /dev/null +++ b/src/backup/2017-05-18-IN.csv @@ -0,0 +1 @@ +DATE,ID,NAME,GR,TIME,REASON diff --git a/src/backup/2017-05-18-OUT.csv b/src/backup/2017-05-18-OUT.csv new file mode 100644 index 0000000..8be6953 --- /dev/null +++ b/src/backup/2017-05-18-OUT.csv @@ -0,0 +1 @@ +DATE,ID,NAME,GR,REASON,EXCUSED,TIME,ARRTIME diff --git a/src/backup/2017-05-19-IN.csv b/src/backup/2017-05-19-IN.csv new file mode 100644 index 0000000..2b0bb45 --- /dev/null +++ b/src/backup/2017-05-19-IN.csv @@ -0,0 +1 @@ +DATE,ID,NAME,GR,TIME,REASON diff --git a/src/backup/2017-05-19-OUT.csv b/src/backup/2017-05-19-OUT.csv new file mode 100644 index 0000000..8be6953 --- /dev/null +++ b/src/backup/2017-05-19-OUT.csv @@ -0,0 +1 @@ +DATE,ID,NAME,GR,REASON,EXCUSED,TIME,ARRTIME diff --git a/src/backup/2017-05-20-IN.csv b/src/backup/2017-05-20-IN.csv new file mode 100644 index 0000000..2b0bb45 --- /dev/null +++ b/src/backup/2017-05-20-IN.csv @@ -0,0 +1 @@ +DATE,ID,NAME,GR,TIME,REASON diff --git a/src/backup/2017-05-20-OUT.csv b/src/backup/2017-05-20-OUT.csv new file mode 100644 index 0000000..8be6953 --- /dev/null +++ b/src/backup/2017-05-20-OUT.csv @@ -0,0 +1 @@ +DATE,ID,NAME,GR,REASON,EXCUSED,TIME,ARRTIME diff --git a/src/backup/2017-05-21-IN.csv b/src/backup/2017-05-21-IN.csv new file mode 100644 index 0000000..803df00 --- /dev/null +++ b/src/backup/2017-05-21-IN.csv @@ -0,0 +1,2 @@ +DATE,ID,NAME,GR,TIME,REASON +"2017-05-21","348770","Bailey Smith","9","01:27 PM","Religious Reason", diff --git a/src/backup/2017-05-21-OUT.csv b/src/backup/2017-05-21-OUT.csv new file mode 100644 index 0000000..b11a06c --- /dev/null +++ b/src/backup/2017-05-21-OUT.csv @@ -0,0 +1,2 @@ +DATE,ID,NAME,GR,REASON,EXCUSED,TIME,ARRTIME +"2017-05-21","368746","Juan Barron","9","Doctor/Dentist Appointment","","01:15 PM","03:38 PM", diff --git a/src/backup/2017-05-22-IN.csv b/src/backup/2017-05-22-IN.csv new file mode 100644 index 0000000..5eae512 --- /dev/null +++ b/src/backup/2017-05-22-IN.csv @@ -0,0 +1,5 @@ +DATE,ID,NAME,GR,TIME,REASON +"2017-05-22","348770","Bailey Smith","9","01:06 PM","Late Bus""", +"2017-05-22","353851","Ishana Shastri","10","11:00 PM","Late Bus", +"2017-05-22","457331","William Hicks","9","01:07 PM","Late Bus"", +"2017-05-22","366517","Ann Dahlman","9","01:07 PM","Late Bus"", diff --git a/src/backup/2017-05-22-OUT.csv b/src/backup/2017-05-22-OUT.csv new file mode 100644 index 0000000..e899866 --- /dev/null +++ b/src/backup/2017-05-22-OUT.csv @@ -0,0 +1,3 @@ +DATE,ID,NAME,GR,REASON,EXCUSED,TIME,ARRTIME +"2017-05-22","229702","Edward Parker","9","Parent","","12:45 PM","05:38 PM"", +"2017-05-22","366517","Ann Dahlman","9","Health Room","","12:08 PM","10:59 PM", diff --git a/src/backup/2017-05-23-IN.csv b/src/backup/2017-05-23-IN.csv new file mode 100644 index 0000000..2b0bb45 --- /dev/null +++ b/src/backup/2017-05-23-IN.csv @@ -0,0 +1 @@ +DATE,ID,NAME,GR,TIME,REASON diff --git a/src/backup/2017-05-23-OUT.csv b/src/backup/2017-05-23-OUT.csv new file mode 100644 index 0000000..8be6953 --- /dev/null +++ b/src/backup/2017-05-23-OUT.csv @@ -0,0 +1 @@ +DATE,ID,NAME,GR,REASON,EXCUSED,TIME,ARRTIME diff --git a/src/backup/2017-05-24-IN.csv b/src/backup/2017-05-24-IN.csv new file mode 100644 index 0000000..2b0bb45 --- /dev/null +++ b/src/backup/2017-05-24-IN.csv @@ -0,0 +1 @@ +DATE,ID,NAME,GR,TIME,REASON diff --git a/src/backup/2017-05-24-OUT.csv b/src/backup/2017-05-24-OUT.csv new file mode 100644 index 0000000..8be6953 --- /dev/null +++ b/src/backup/2017-05-24-OUT.csv @@ -0,0 +1 @@ +DATE,ID,NAME,GR,REASON,EXCUSED,TIME,ARRTIME diff --git a/src/backup/2017-05-25-IN.csv b/src/backup/2017-05-25-IN.csv new file mode 100644 index 0000000..2b0bb45 --- /dev/null +++ b/src/backup/2017-05-25-IN.csv @@ -0,0 +1 @@ +DATE,ID,NAME,GR,TIME,REASON diff --git a/src/backup/2017-05-25-OUT.csv b/src/backup/2017-05-25-OUT.csv new file mode 100644 index 0000000..8be6953 --- /dev/null +++ b/src/backup/2017-05-25-OUT.csv @@ -0,0 +1 @@ +DATE,ID,NAME,GR,REASON,EXCUSED,TIME,ARRTIME diff --git a/src/backup/2017-05-27-IN.csv b/src/backup/2017-05-27-IN.csv new file mode 100644 index 0000000..33ccae3 --- /dev/null +++ b/src/backup/2017-05-27-IN.csv @@ -0,0 +1,2 @@ +DATE,ID,NAME,GR,TIME,REASON +"2017-05-27","366517","Ann Dahlman","9","12:25 AM","College Visit", diff --git a/src/backup/2017-05-27-OUT.csv b/src/backup/2017-05-27-OUT.csv new file mode 100644 index 0000000..8be6953 --- /dev/null +++ b/src/backup/2017-05-27-OUT.csv @@ -0,0 +1 @@ +DATE,ID,NAME,GR,REASON,EXCUSED,TIME,ARRTIME diff --git a/src/backup/2017-05-29-IN.csv b/src/backup/2017-05-29-IN.csv new file mode 100644 index 0000000..2c701ed --- /dev/null +++ b/src/backup/2017-05-29-IN.csv @@ -0,0 +1,16 @@ +DATE,ID,NAME,GR,TIME,REASON +"2017-05-29,"345433,"Shriya Singh,"10,"11:08 PM,"forgot her tofu"", +"2017-05-29,"348770,"Bailey Smith,"9,"11:42 PM,"Transportation, +"2017-05-29,"353851,"Ishana Shastri,"10,"11:08 PM,"amit:))))))))))"", +"2017-05-29,"457084,"Tejas Guha,"9,"11:01 PM,"Transportation""", +"2017-05-29,"369393,"Varshini Selvadurai,"10,"10:40 PM,"jason""""", +"2017-05-29,"346252,"Jason Lee,"10,"10:41 PM,"varshini""""", +"2017-05-29,"992124,"Seung Kyoon Bong,"12,"11:18 PM,"yale", +"2017-05-29,"998271,"Amogh Narendra,"11,"10:30 PM,"stoned""""""", +"2017-05-29,"991284,"Colin Fisher,"12,"11:13 PM,"his mophair made his car crash", +"2017-05-29,"371547,"Luckshika Arudchandran,"10,"11:06 PM,"carbs lifted his eyebrow"", +"2017-05-29,"347317,"Rachel Bupp,"10,"11:11 PM,"looking at carbs"", +"2017-05-29,"323685,"Aman Jaiman,"11,"11:09 PM,"in love w the robo"", +"2017-05-29,"181715,"Noah Lucas,"10,"11:10 PM,"stuck in britain"", +"2017-05-29,"364235,"Chase Hanscom,"9,"11:02 PM,"College Visit""", +"2017-05-29,"325836,"Amit Yavasani,"11,"10:50 PM,"ishana:))))))))))))))"""", diff --git a/src/backup/2017-05-29-OUT.csv b/src/backup/2017-05-29-OUT.csv new file mode 100644 index 0000000..8be6953 --- /dev/null +++ b/src/backup/2017-05-29-OUT.csv @@ -0,0 +1 @@ +DATE,ID,NAME,GR,REASON,EXCUSED,TIME,ARRTIME diff --git a/src/backup/2017-05-30-IN.csv b/src/backup/2017-05-30-IN.csv new file mode 100644 index 0000000..9eb4e1a --- /dev/null +++ b/src/backup/2017-05-30-IN.csv @@ -0,0 +1,7 @@ +DATE,ID,NAME,GR,TIME,REASON +"2017-05-30","441161","Mariam Rahman","9","11:53 PM","Religious Reason", +"2017-05-30","982046","Kellie Dahlin","11","09:20 PM","Transportation"""", +"2017-05-30","353851","Ishana Shastri","10","09:20 PM","Unexcused"""", +"2017-05-30","988419","Shirley Quito","12","09:21 PM","Religious Reason"""", +"2017-05-30","368746","Juan Barron","9","11:51 PM","Religious Reason"", +"2017-05-30","362556","Shaun Bolten","9","09:20 PM","Religious Reason"""", diff --git a/src/backup/2017-05-30-OUT.csv b/src/backup/2017-05-30-OUT.csv new file mode 100644 index 0000000..e25a7c2 --- /dev/null +++ b/src/backup/2017-05-30-OUT.csv @@ -0,0 +1,2 @@ +DATE,ID,NAME,GR,REASON,EXCUSED,TIME,ARRTIME +"2017-05-30","229702","Edward Parker","9","Doctor/Dentist Appointment","","11:48 PM","None""", diff --git a/src/backup/2017-05-31-IN.csv b/src/backup/2017-05-31-IN.csv new file mode 100644 index 0000000..54c0119 --- /dev/null +++ b/src/backup/2017-05-31-IN.csv @@ -0,0 +1,9 @@ +DATE,ID,NAME,GR,TIME,REASON +"2017-05-31","441161","Mariam Rahman","9","01:55 PM","10:59 AM","10:45 AM", +"2017-05-31","348770","Bailey Smith","9","01:55 PM","10:59 AM","10:45 AM", +"2017-05-31","229702","Edward Parker","9","01:55 PM","10:59 AM","10:45 AM", +"2017-05-31","353851","Ishana Shastri","10","01:55 PM","10:59 AM","10:45 AM", +"2017-05-31","457084","Tejas Guha","9","01:55 PM","10:59 AM","10:45 AM", +"2017-05-31","368746","Juan Barron","9","01:55 PM","10:59 AM","Religious Reason"", +"2017-05-31","369393","Varshini Selvadurai","10","01:55 PM","Unexcused", +"2017-05-31","366985","Aidan Olcott","9","01:55 PM","10:59 AM","10:45 AM", diff --git a/src/backup/2017-05-31-OUT.csv b/src/backup/2017-05-31-OUT.csv new file mode 100644 index 0000000..0c13f0f --- /dev/null +++ b/src/backup/2017-05-31-OUT.csv @@ -0,0 +1,5 @@ +DATE,ID,NAME,GR,REASON,EXCUSED,TIME,ARRTIME +"2017-05-31","353851","Ishana Shastri","10","[[[Religious Reason]]]","[[[]]]","01:55 PM","10:59 AM","[10:52 AM, [10:47 AM, [10:45 AM]]]", +"2017-05-31","457331","William Hicks","9","[[[Doctor/Dentist Appointment]]]","[[[]]]","01:55 PM","10:59 AM","[10:52 AM, [10:47 AM, [10:45 AM, 01:26 AM]]]", +"2017-05-31","366517","Ann Dahlman","9","[[[Religious Reason]]]","[[[]]]","01:55 PM","10:59 AM","[10:52 AM, [10:47 AM, [10:45 AM, 09:11 AM]]]", +"2017-05-31","376522","Malik Smith","9","[[[Doctor/Dentist Appointment]]]","[[[]]]","01:55 PM","10:59 AM","[10:52 AM, [10:47 AM, [10:45 AM, 09:15 AM]]]", diff --git a/src/backup/2017-06-03-IN.csv b/src/backup/2017-06-03-IN.csv new file mode 100644 index 0000000..da2a27d --- /dev/null +++ b/src/backup/2017-06-03-IN.csv @@ -0,0 +1,2 @@ +DATE,ID,NAME,GR,TIME,REASON +"2017-06-03","441161","Mariam Rahman","9","04:43 PM","Transportation", diff --git a/src/backup/2017-06-03-OUT.csv b/src/backup/2017-06-03-OUT.csv new file mode 100644 index 0000000..8be6953 --- /dev/null +++ b/src/backup/2017-06-03-OUT.csv @@ -0,0 +1 @@ +DATE,ID,NAME,GR,REASON,EXCUSED,TIME,ARRTIME diff --git a/src/css/application.css b/src/css/application.css new file mode 100644 index 0000000..7e31b8c --- /dev/null +++ b/src/css/application.css @@ -0,0 +1,638 @@ +.searchTextField{ + -fx-font-size: 13pt; + -fx-font-family: "Courier New"; +} + + +.root{ + -fx-font-family: "Avenir"; + +} + +.alertMessage{ + -fx-background-color: #b94a48; + -fx-border-color: #b94a48; + -fx-padding: 8px 35px 8px 14px; + -fx-margin-bottom: 18px; + -fx-pref-height: 40px; +} + +.alertText{ + -fx-text-fill: #f2dede; +} +.sucessMessage{ + -fx-background-color: #5cb85c; + -fx-border-color: #5cb85c; + -fx-padding: 8px 35px 8px 14px; + -fx-margin-bottom: 18px; + -fx-pref-height: 40px; +} + +.sucessText{ + -fx-text-fill: #fff; +} +.button { + -fx-border-radius: 4px; + -fx-background-radius: 4px; + -fx-padding: 3px 17px 3px 12px; + -fx-text-fill: #000000; + -fx-background-color: #FFD700; + -fx-border-color: #FFD700; + -fx-font-size: 21.5px; + width: 20px; + height: 10px; + } +.button:hover { + -fx-text-fill: #ffffff; + -fx-background-color: #3276b1; + -fx-border-color: #285e8e; + +} + +.button:armed { + -fx-text-fill: #ffffff !important; + -fx-background-color: #286090 !important; + -fx-border-color: #204d74 !important; +} + +.pageButton-left{ + -fx-pref-width: 50; + -fx-max-height: 100000; + -fx-border-color: transparent #ccc transparent transparent; + -fx-border-width: 1; + -fx-background-image: url('../img/next-button-left.png'); + -fx-background-color: transparent; + -fx-border-radius: 0 0 0 5; + -fx-background-size: 30px; + -fx-background-repeat: no-repeat; + -fx-background-position: 50%; + + +} + +.pageButton-right{ + -fx-pref-width: 50; + -fx-max-height: 100000; + -fx-border-width: 1; + -fx-border-color: transparent transparent transparent #ccc; + -fx-background-image: url('../img/next-button-right.png'); + -fx-background-color: transparent; + -fx-border-radius: 0 0 0 0; + -fx-background-size: 30px; + -fx-background-repeat: no-repeat; + -fx-background-position: 50%; + + +} + +.pageButton-left:hover { + -fx-background-color: #e6e6e6; + -fx-border-color: transparent #ccc transparent transparent; + -fx-background-radius: 0 0 0 0; + -fx-border-width: 1; + -fx-background-insets: 0.1 0.1; +} + +.pageButton-right:hover{ + -fx-background-color: #e6e6e6; + -fx-border-color: transparent transparent transparent #ccc; + -fx-background-radius: 0 0 0 0; + -fx-border-width: 1; + -fx-background-insets: 0.1 0.1; +} + +.pageButton-left:armed { + -fx-background-color: #c7ddef !important; + -fx-border-color: transparent #ccc transparent transparent !important; + -fx-background-radius: 0 0 0 0; + -fx-border-width: 1; + -fx-background-insets: 0.1 0.1; +} + +.pageButton-right:armed{ + -fx-background-color: #c7ddef !important; + -fx-border-color: transparent transparent transparent #ccc !important; + -fx-background-radius: 0 0 0 0; + -fx-border-width: 1; + -fx-background-insets: 0.1 0.1; + +} + + + +.optionSelect{ + -fx-alignment: center; + -fx-background-color: transparent; + -fx-border-color: #808080; + -fx-border-width: 1; + -fx-border-radius: 5; + + +} +.optionTitle{ + -fx-border-color: transparent; + -fx-max-width: 10000; + -fx-pref-height:50; + -fx-alignment:center; + -fx-background-color:#FFD700; + -fx-text-fill: #000000; + -fx-border-radius: 0; + -fx-background-radius: 5 5 0 0; + -fx-font-size: 12pt; + +} +.optionButton-top { + -fx-max-height: 10000; + -fx-max-width: 10000; + -fx-background-radius: 0 0 0 0; + -fx-border-radius: 0 0 0 0; + -fx-background-color: #fff; + -fx-border-color: #ccc; + -fx-text-fill: black; + -fx-border-width: 0 0 0.5 0; + -fx-font-size: 20px; +} +.optionButton-mid { + + -fx-max-height: 10000; + -fx-max-width: 10000; + -fx-background-radius: 0 0 0 0; + -fx-border-radius: 0 0 0 0; + -fx-background-color: #fff; + -fx-border-color: #ccc; + -fx-text-fill: black; + -fx-border-width: 0.5 0 0.5 0; + -fx-font-size: 20px; +} + +.optionButton-bottom{ + -fx-max-height: 10000; + -fx-max-width: 10000; + -fx-border-color: #ccc #ccc #337ab7 #ccc; + -fx-text-fill: black; + -fx-border-width: 0.5 0 0 0; + -fx-border-radius: 0 0 0 0; + -fx-background-radius: 0 0 0 0; + -fx-font-size: 20px; + +} + + + .optionButton-mid:hover, .optionButton-top:hover { + -fx-background-color: #e6e6e6; + -fx-border-color: #ccc; + +} +.optionButton-mid:armed, .optionButton-top:armed { + -fx-border-color: #ccc #ccc #337ab7 #ccc; + -fx-background-color: #c7ddef !important; +} + +.optionButton-bottom:hover{ + -fx-background-color: #e6e6e6; + -fx-border-color: #ccc #ccc #337ab7 #ccc; + -fx-border-width: 0.5 1 0 1; +} + +.optionButton-bottom:armed{ + -fx-background-color: #c7ddef !important; + -fx-border-color: #ccc #ccc #337ab7 #ccc !important; + -fx-border-width: 0.5 1 0 1; +} + + +.optionTextFieldOther{ + -fx-border-color: #ccc #ccc #337ab7 #ccc; + -fx-text-fill: black; + -fx-border-width: 0.5 0 0 0; + -fx-border-radius: 0 0 0 0; + -fx-background-radius: 0 0 0 0; + -fx-padding: 0; + +} + + +.textFieldOtherButton{ + -fx-font-size: 20pt; + -fx-background-color: #5cb85c; + -fx-border-color: #4cae4c; + +} +.textFieldOtherButton:hover { + -fx-color: #fff; + -fx-background-color: #449d44; + -fx-border-color: #398439; +} + +.textFieldOtherButton:armed{ + -fx-color: #fff; + -fx-background-color: #5cb85c !important; + -fx-border-color: #4cae4c !important; +} +.textFieldOther{ + -fx-min-height: 10; +} + +.submitButton{ + -fx-font-size: 20px; + -fx-background-color: #5cb85c; + -fx-border-color: #4cae4c; + -fx-font-color: #fff + +} +.submitButton:hover { + -fx-color: #fff; + -fx-background-color: #449d44; + -fx-border-color: #398439; +} + +.submitButton:armed{ + -fx-color: #fff; + -fx-background-color: #5cb85c !important; + -fx-border-color: #4cae4c !important; +} + +.backButton { + -fx-border-radius: 4px; + -fx-background-radius: 4px; + -fx-padding: 3px 17px 3px 12px; + -fx-text-fill: #000000; + -fx-background-color: #FFD700; + -fx-border-color: #FFD700; + -fx-font-size: 20px; +} + +.bottomHBox{ + -fx-max-height: 40; + -fx-pref-height: 40; + -fx-max-width: 10000; + -fx-border-color: #ccc #ccc #337ab7 #ccc; + -fx-text-fill: black; + -fx-border-width: 0.5 0 0 0; + -fx-border-radius: 0 0 0 0; + -fx-background-radius: 0 0 0 0; + -fx-alignment: center; +} + +.buttonVBox { + -fx-alignment: center; +} + +.tab{ + -fx-background-color: #FFF; + -fx-border-color: #eeeeee; + -fx-padding-left: 5; + -fx-padding-right: 4; + -fx-border-width: 1 1 1 1; + -fx-border-radius: 3 3 0 0; + -fx-focus-color: transparent; + -fx-faint-focus-color: transparent; +} + +.list-view { + -fx-background-color:transparent; +} + + + +.scroll-bar{ + -fx-background-color: rgb(96,96,96); + -fx-background-radius: 2em; +} +.scroll-bar:horizontal .track, +.scroll-bar:vertical .track { + -fx-background-color: transparent; + -fx-border-color:transparent; + -fx-background-radius: 2em; +} +.scroll-bar:vertical .track-background, +.scroll-bar:horizontal .track-background { + -fx-background-color: transparent; + -fx-background-insets: 0; + -fx-background-radius: 2em; +} +.scroll-bar:horizontal .thumb { + -fx-background-color: rgb(211,211,211); + -fx-background-insets: 4 0 4 0; + -fx-background-radius: 2em; +} +.scroll-bar:vertical .thumb { + -fx-background-color: rgb(211,211,211); + -fx-background-insets: 0 4 0 4; + -fx-background-radius: 2em; +} +.scroll-bar:horizontal .thumb:hover, +.scroll-bar:vertical .thumb:hover { + -fx-background-color: rgb(231,231,231); +} +.scroll-bar:horizontal .thumb:pressed, +.scroll-bar:vertical .thumb:pressed { + -fx-background-color: rgb(255,255,255); +} +.scroll-bar:vertical .increment-button, .scroll-bar:vertical .decrement-button { + -fx-background-color:transparent; + -fx-background-radius: 2em; + -fx-padding: 5; +} +.scroll-bar:horizontal .increment-button, .scroll-bar:horizontal .decrement-button { + -fx-background-color:transparent; + -fx-background-radius: 2em; + -fx-padding: 5; +} +.scroll-bar:horizontal .increment-arrow { + -fx-shape: "M 0 0 L 4 8 L 8 0 Z"; + -fx-background-color: rgb(211,211,211); + -fx-padding: 0.25em; + -fx-rotate: -90; +} +.scroll-bar:vertical .increment-arrow { + -fx-background-color: rgb(211,211,211); + -fx-shape: "M 0 0 L 4 8 L 8 0 Z"; + -fx-padding: 0.25em; + -fx-rotate: 0; +} +.scroll-bar:horizontal .decrement-arrow { + -fx-background-color: rgb(211,211,211); + -fx-shape: "M 0 0 L 4 8 L 8 0 Z"; + -fx-padding: 0.25em; + -fx-rotate: 90; +} +.scroll-bar:vertical .decrement-arrow { + -fx-background-color: rgb(211,211,211); + -fx-shape: "M 0 0 L 4 8 L 8 0 Z"; + -fx-padding: 0.25em; + -fx-rotate: -180; +} +.scroll-bar:vertical:focused, +.scroll-bar:horizontal:focused { + -fx-background-color: transparent,rgb(96,96,96),rgb(96,96,96); +} + +.scroll-bar:vertical .increment-arrow:hover, +.scroll-bar:vertical .decrement-arrow:hover, +.scroll-bar:horizontal .increment-arrow:hover, +.scroll-bar:horizontal .decrement-arrow:hover{ + -fx-background-color: rgb(231,231,231); +} + +.scroll-bar:vertical .increment-arrow:pressed, +.scroll-bar:vertical .decrement-arrow:pressed, +.scroll-bar:horizontal .increment-arrow:pressed, +.scroll-bar:horizontal .decrement-arrow:pressed{ + -fx-background-color: #FFF; +} + + +.tab-header-background{ + -fx-background-color: rgb(231,231,231); +} + +.tab-pane .tab:selected +{ + -fx-background-color: #FFF; +} +.tab:selected .tab-label { + -fx-alignment: CENTER; +} +.tab:left +{ + -fx-background-color: #ddd; + -fx-border-width: 0; +} + + +.optionContent{ + -fx-background-color: rgba(192,192,192, 0.5); +} + +.ContentPane{ + -fx-background-color: #fff; + -fx-background-radius: 0; + -fx-border-radius: 0; + -fx-border-color: #357ebd; + -fx-border-width: 1; + -fx-padding: 0; +} + +.ContentPane > .viewport{ + -fx-border-color: transparent; + -fx-background-radius: 0; + -fx-border-radius: 0; + -fx-background-color: #fff; + +} + + +.closeButton{ + -fx-border-radius: 4px; + -fx-background-radius: 4px; + -fx-padding: 6px 12px 6px 12px; + -fx-text-fill: #ffffff; + -fx-background-color: #d9534f; + -fx-border-color: #761c19; + -fx-font-size: 20px; +} +.closeButton:hover { + -fx-text-fill: #ffffff; + -fx-background-color: #c9302c; + -fx-border-color: #ac2925; +} +.closeButton:armed { + -fx-text-fill: #ffffff !important; + -fx-background-color: #c9302c !important; + -fx-border-color: #ac2925 !important; + +} + +.saveButton{ + -fx-font-size: 20px; + -fx-background-color: #5cb85c; + -fx-border-color: #4cae4c; + +} +.saveButton:hover { + -fx-color: #fff; + -fx-background-color: #449d44; + -fx-border-color: #398439; +} + +.saveButton:armed{ + -fx-color: #fff; + -fx-background-color: #5cb85c !important; + -fx-border-color: #4cae4c !important; +} + +.saveButton:disabled{ + -fx-color: #fff; + -fx-background-color: #5cb85c; + -fx-border-color: #4cae4c; +} + +.menu{ + -fx-font-size: 15px; +} + +.printButton{ + -fx-font-size: 20px; + -fx-background-color:#FFD700; + -fx-border-color: #FFD700; + +} + +.emailButton{ + -fx-font-size: 20px; + -fx-background-color:#FFD700; + -fx-border-color: #FFD700; + +} + +.loadButton{ + -fx-font-size: 20px; + -fx-background-color: #5bc0de; + -fx-border-color: #46b8da; + +} +.loadButton:hover { + -fx-color: #fff; + -fx-background-color: #31b0d5; + -fx-border-color: #269abc; +} + +.loadButton:armed{ + -fx-color: #fff; + -fx-background-color: #31b0d5 !important; + -fx-border-color: #269abc !important; +} + +.buttonAnchorPane{ + -fx-background-color: rgb(231,231,231); +} + + +.center{ + -fx-alignment: center; +} + +.passwordLock{ + -fx-background-color: #FFF !important; + -fx-alignment: center; + -fx-border-color: #357ebd; + -fx-border-width: 1; + -fx-padding: 20; + -fx-border-radius: 5; + -fx-font-size: 12pt; + -fx-background-radius: 10; + +} + + +.passwordTextField{ + -fx-font-size: 12; + -fx-pref-height: 10; +} +.passwordTextField-error{ + -fx-focus-color: #EF9A9A; + -fx-faint-focus-color: #d3524422; + + -fx-highlight-fill: -fx-accent; + -fx-highlight-text-fill: white; + -fx-background-color: + -fx-focus-color, + -fx-control-inner-background, + -fx-faint-focus-color, + linear-gradient(from 0px 0px to 0px 5px, derive(-fx-control-inner-background, -9%), -fx-control-inner-background); + -fx-background-insets: -0.2, 1, -1.4, 3; + -fx-background-radius: 3, 2, 4, 0; + -fx-prompt-text-fill: transparent; + -fx-pref-height: 10; + +} + +.passwordTextField-success{ + -fx-focus-color: #4CBB17; + -fx-faint-focus-color: rgb(131, 245, 44, 0.4); + + -fx-highlight-fill: -fx-accent; + -fx-highlight-text-fill: white; + -fx-background-color: + -fx-focus-color, + -fx-control-inner-background, + -fx-faint-focus-color, + linear-gradient(from 0px 0px to 0px 5px, derive(-fx-control-inner-background, -9%), -fx-control-inner-background); + -fx-background-insets: -0.2, 1, -1.4, 3; + -fx-background-radius: 3, 2, 4, 0; + -fx-prompt-text-fill: transparent; + -fx-pref-height: 10; +} + + + + +.alertBox{ + -fx-background-color: #fff; +} +.alertBox > *.button-bar > *.container{ + -fx-background-color: #fff; +} +.alertBox > *.label.content{ + -fx-font-size: 16; + -fx-alignment: center; +} +.alertBox:header *.header-panel{ + -fx-background-color: #fff; + -fx-alignment: center; +} +.alertBox:header *.header-panel *.label{ + -fx-font-size: 18px; + -fx-font-style: italic; + -fx-fill: #fff; +} + +.changePasswordButton { + -fx-border-radius: 4px; + -fx-background-radius: 4px; + -fx-padding: 6px 12px 6px 12px; + -fx-text-fill: #ffffff; + -fx-background-color: #f0ad4e; + -fx-border-color: #eea236; + -fx-font-size: 14px; +} +.changePasswordButton:hover { + -fx-text-fill: #ffffff; + -fx-background-color: #ec971f; + -fx-border-color: #d58512; + +} + +.changePasswordButton:armed { + -fx-text-fill: #ffffff !important; + -fx-background-color: #ec971f !important; + -fx-border-color: #d58512 !important; +} + +.tooltip { + -fx-background: #f0ad4e; + -fx-text-fill: white; + -fx-background-color: #f0ad4e; + -fx-background-radius: 6px; + -fx-background-insets: 0; + -fx-padding: 0.667em 0.75em 0.667em 0.75em; /* 10px */ + -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.5) , 10, 0.0 , 0 , 3 ); + -fx-font-size: 14; + -fx-font-family: "Avenir"; +} + +.summaryLabel{ + -fx-font-size: 14; + -fx-font-family: "Courier New"; +} +.summaryLabel-active{ + -fx-font-weight: bold; +} +.summaryVBox{ + -fx-padding: 20; + -fx-background-color: transparent; +} +.studentIDLabel{ + -fx-font-size: 15; +} \ No newline at end of file diff --git a/src/css/fextile.css b/src/css/fextile.css new file mode 100644 index 0000000..cbc1a5e --- /dev/null +++ b/src/css/fextile.css @@ -0,0 +1,270 @@ +/** + * Base + */ +.root { + -fx-background-color: #ffffff; +} + + + +.hbox, +.vbox, +.pane, +.scroll-pane { + -fx-font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + -fx-font-size: 14px; + -fx-background-color: transparent; +} + +.accordion, +.button, +.cell, +.check-box, +.choice-box, +.color-picker, +.combo-box, +.label, +.list-cell, +.text-area, +.text-field { + -fx-font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + -fx-font-size: 14px; + -fx-text-fill: #333333; +} + +/** + * Controls + */ +.hyperlink { + -fx-text-fill: #428bca; +} +.hyperlink:hover, +.hyperlink:focused { + -fx-text-fill: #2a6496; + -fx-underline: true; +} + +.button { + -fx-border-radius: 4px; + -fx-background-radius: 4px; + -fx-padding: 6px 12px 6px 12px; +} + +/** + * Style + */ +.small { + -fx-font-size: 85%; +} +.code, .kbd, .pre, .samp { + -fx-font-family: monospace, serif; + -fx-font-size: 14px; /* 1em; There are bugs on focus. size of 'em' copied and over wrote from other control. */ +} +.text-muted { + -fx-text-fill: #999999; +} +.text-primary { + -fx-text-fill: #428bca; +} +.text-primary:hover { + -fx-text-fill: #3071a9; +} +.text-warning { + -fx-text-fill: #c09853; +} +.text-warning:hover { + -fx-text-fill: #a47e3c; +} +.text-danger { + -fx-text-fill: #b94a48; +} +.text-danger:hover { + -fx-text-fill: #953b39; +} +.text-success { + -fx-text-fill: #468847; +} +.text-success:hover { + -fx-text-fill: #356635; +} +.text-info { + -fx-text-fill: #3a87ad; +} +.text-info:hover { + -fx-text-fill: #2d6987; +} +.text-left { + -fx-text-alignment: left; +} +.text-center { + -fx-text-alignment: center; +} +.text-right { + -fx-text-alignment: right; +} + +.h1, +.h2, +.h3, +.h4, +.h5, +.h6 { + -fx-font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + -fx-font-weight: 500; +} +.h1, +.h2, +.h3 { + -fx-padding: 20px 0 10px 0; +} +.h4, +.h5, +.h6 { + -fx-padding: 10px 0 10px 0; +} +.h1 { + -fx-font-size: 36px; +} +.h2 { + -fx-font-size: 30px; +} +.h3 { + -fx-font-size: 24px; +} +.h4 { + -fx-font-size: 18px; +} +.h5 { + -fx-font-size: 14px; +} +.h6 { + -fx-font-size: 12px; +} + +.page-header { + -fx-padding: 40px 0 29px 0; +} + +.container { + -fx-padding: 0 15px 0 15px; +} + +.alert { + /* margin-bottom: 20px; Cannot found way to configure margins via css */ + -fx-padding: 15px; + -fx-gap-start-and-end: true; + -fx-border-style: solid; + -fx-border-width: 1px; + -fx-border-radius: 4px; +} + +.alert-success { + -fx-background-color: #dff0d8; + -fx-border-color: #d6e9c6; + -fx-text-fill: #468847; +} +.alert-info { + -fx-background-color: #d9edf7; + -fx-border-color: #bce8f1; + -fx-text-fill: #3a87ad; +} +.alert-warning { + -fx-background-color: #fcf8e3; + -fx-border-color: #faebcc; + -fx-text-fill: #c09853; +} +.alert-danger { + -fx-background-color: #f2dede; + -fx-border-color: #ebccd1; + -fx-text-fill: #b94a48; +} + +.btn-default { + -fx-text-fill: #333333; + -fx-background-color: #ffffff; + -fx-border-color: #cccccc; +} +.btn-default:hover { + -fx-text-fill: #333333; + -fx-background-color: #ebebeb; + -fx-border-color: #adadad; +} +.btn-default:disabled { + -fx-background-color: #ffffff; + -fx-border-color: #cccccc; +} + +.btn-primary { + -fx-text-fill: #ffffff; + -fx-background-color: #428bca; + -fx-border-color: #357ebd; +} +.btn-primary:hover { + -fx-text-fill: #ffffff; + -fx-background-color: #3276b1; + -fx-border-color: #285e8e; +} +.btn-primary:disabled { + -fx-background-color: #428bca; + -fx-border-color: #357ebd; +} + +.btn-warning { + -fx-text-fill: #ffffff; + -fx-background-color: #f0ad4e; + -fx-border-color: #eea236; +} +.btn-warning:hover { + -fx-text-fill: #ffffff; + -fx-background-color: #ed9c28; + -fx-border-color: #d58512; +} +.btn-warning:disabled { + -fx-background-color: #f0ad4e; + -fx-border-color: #eea236; +} + +.btn-danger { + -fx-text-fill: #ffffff; + -fx-background-color: #d9534f; + -fx-border-color: #d43f3a; +} +.btn-danger:hover { + -fx-text-fill: #ffffff; + -fx-background-color: #d2322d; + -fx-border-color: #ac2925; +} +.btn-danger:disabled { + -fx-background-color: #d9534f; + -fx-border-color: #d43f3a; +} + +.btn-success { + -fx-text-fill: #ffffff; + -fx-background-color: #5cb85c; + -fx-border-color: #4cae4c; +} +.btn-success:hover { + -fx-text-fill: #ffffff; + -fx-background-color: #47a447; + -fx-border-color: #398439; +} +.btn-success:disabled { + -fx-background-color: #5cb85c; + -fx-border-color: #4cae4c; +} + +.btn-info { + -fx-text-fill: #ffffff; + -fx-background-color: #5bc0de; + -fx-border-color: #46b8da; +} +.btn-info:hover { + -fx-text-fill: #ffffff; + -fx-background-color: #39b3d7; + -fx-border-color: #269abc; +} +.btn-info:disabled { + -fx-background-color: #5bc0de; + -fx-border-color: #46b8da; +} \ No newline at end of file diff --git a/src/data/SchoolDatabase.mer b/src/data/SchoolDatabase.mer new file mode 100644 index 0000000..138eb54 --- /dev/null +++ b/src/data/SchoolDatabase.mer @@ -0,0 +1,1197 @@ +Mark,ID,LAST,FIRST,MI,GR,G +"","353116","Abrigo","Alexis","A","09","F" +"fralg","440892","Ainsworth","Damion","L","09","M" +"","420146","Akdag","Anna","M","09","F" +"","335165","Alvarez","Jocelyn","N","09","F" +"","400232","Anderson","Holly","E","09","F" +"","371547","Arudchandran","Luckshika","S","09","F" +"alg","330470","Atkins","Alivia","J","09","F" +"","347300","Auel","Aidan","A","09","M" +"","348521","Barber","Alexander","R","09","M" +"alg","346116","Barney","Kieran","M","09","M" +"","456491","Beaton","Nicholas","J","09","M" +"","353317","Beautz","Michael","R","09","M" +"","346020","Becker","Rachel","V","09","F" +"","438040","Behrens","Thomas","K","09","M" +"","340384","Benadon","Clara","M","09","F" +"","345206","Bentz","Timothy","D","09","M" +"","161058","Berger","Darian","E","09","M" +"","144508","Bevley","Dwight","J","09","M" +"","345210","Bian","Edward","H","09","M" +"","374267","Bian","Vincent","W","09","M" +"fralg","347304","Bledsoe","Jack","S","09","M" +"","347305","Bodmer","Grace","E","09","F" +"","358446","Boe","Gwendolyn","R","09","F" +"","363951","Bonagiri","Prasanthi","","09","F" +"","378619","Broadhurst","Rhyston","J","09","M" +"","347312","Brooks","Gabriella","L","09","F" +"","347317","Bupp","Rachel","J","09","F" +"","352716","Burdette","Madeline","L","09","F" +"","346849","Bzhilyanskaya","Sofia","A","09","F" +"","356867","Callaway","Jasmin","N","09","F" +"","370287","Carbonell","John","A","09","M" +"alg","342912","Carey","Jessica","L","09","F" +"fralg","357108","Carr","Arianna","E","09","F" +"alg","346360","Carter","Kaelyn","N","09","F" +"","347327","Cayzedo","Nicolas","A","09","M" +"","191721","Chan","Spencer","S","09","M" +"","158598","Chaudhry","Aliyaan","N","09","M" +"alg","196134","Chaves","Tatiana","V","09","F" +"","347982","Chen","Kevin","N","09","M" +"","350370","Chen","Peiqi","","09","F" +"","190795","Cherfan","Marilyn","M","09","F" +"","344406","Chilla","Lauren","M","09","F" +"","352718","Chim","Vincent","B","09","M" +"","338866","Chintagumpala","Hrishi","","09","M" +"","349370","Chinthalapale","Anusha","","09","F" +"","346200","Chu","Amanda","Y","09","F" +"","156197","Chu","Kristina","C","09","F" +"","412888","Clark","Grace","E","09","F" +"","326309","Connell","Ronan","A","09","M" +"alg","985766","Cooley","Jacob","C","09","M" +"","316761","Corfman","Julia","L","09","F" +"","346476","Cornejo","Julian","A","09","M" +"fralg","339880","Cox","Meghan","E","09","F" +"","344787","Crooks","Gabrielle","M","09","F" +"","364713","Crucillo","Josephine","R","09","F" +"","347330","Dacanay","Carla","R","09","F" +"","352714","Davis","Bryce","J","09","M" +"alg","353543","De Luna","Alec","C","09","M" +"","479260","Derenoncourt","Leeah","M","09","F" +"","334919","Dice","Lillian","C","09","F" +"","192548","Diller","Ashley","J","09","F" +"","155855","Dower","Meghan","E","09","F" +"","347511","Dwyer","Joseph","M","09","M" +"","159163","Earley","Joseph","A","09","M" +"","452704","Edwards","William","B","09","M" +"","336187","Edwards III","Michael","W","09","M" +"","375135","Elangovan","Kaushik","","09","M" +"fralg","357411","Essah","Antonio","U","09","M" +"","347827","Firestine","Alexander","T","09","M" +"","191730","Flitter","Alexander","P","09","M" +"","372675","Fong","Daniel","C","09","M" +"","346222","Foo","Bryan","C","09","M" +"","436378","Foppe","Allison","J","09","F" +"","345565","Foster","John","T","09","M" +"","352719","Fraley","Lita","M","09","F" +"","347336","Fraley","Travis","W","09","M" +"","347343","Fultz","Garrett","W","09","M" +"","349532","Fuster","Anthony","O","09","M" +"","362973","Gaddis","Ethan","J","09","M" +"","347989","Ganesh","Sruthi","S","09","F" +"","347818","Ganti","Sridhar","S","09","M" +"","437679","Garrett","Julianna","F","09","F" +"","347349","Geehreng","Daniel","P","09","M" +"","436435","Georgius","Thomas","R","09","M" +"","194459","Germer","Amy","C","09","F" +"","347137","Gibbs","Isabel","L","09","F" +"","356158","Gimbrere","Matthew","C","09","M" +"","370958","Gu","Michelle","","09","F" +"","349213","Guimaraes","Isabel","A","09","F" +"","345217","Guo","Maria","K","09","F" +"","347419","Haddaway","Allison","C","09","F" +"","430735","Hanidu","Bilikisu","O","09","F" +"","347426","Harris","Caitlin","F","09","F" +"","344737","Headley","Annabelle","M","09","F" +"alg","192017","Heemskerk","Isabella","M","09","F" +"","411936","Hegarty","John","M","09","M" +"","347089","Helfert","Hannah","L","09","F" +"","343508","Hinkson","Trent","A","09","M" +"","347342","Hoffman","Dominic","J","09","M" +"","300697","Hoffman","Sierra","M","09","F" +"","359671","Holmes","Stephen","M","09","M" +"","353004","Holmquist","Foster","O","09","M" +"","455630","Hong","Richard","L","09","M" +"","986977","Hoover","Devin","J","09","M" +"alg","477538","Houston","Paige","A","09","F" +"","347520","Hsiao","Carmie","C","09","F" +"","342921","Hsieh","Natalie","T","09","F" +"","343940","Hu","Amanda","S","09","F" +"","331565","Huaylinos","Jairo","E","09","M" +"","347450","Hueting","Maureen","E","09","F" +"","352721","Huff","Joseph","A","09","M" +"","138604","Hull","Elizabeth","R","09","F" +"","191327","Hull","Samuel","D","09","M" +"","347841","Huntley","Isabel","E","09","F" +"","338972","Islam","Aniq","","09","M" +"","338973","Islam","Aniqa","","09","F" +"","347949","Iyer","Varsha","","09","F" +"fralg","333061","Jackson","Demetreus","","09","M" +"","354441","Jamison","William","F","09","M" +"","349340","Jin","Alex","R","09","F" +"","349256","Job","Anna","","09","F" +"","365859","Johns","William","T","09","M" +"","996555","Johnson","Harrison","T","09","M" +"","344489","Jones","Alexander","R","09","M" +"","348759","Jones","William","R","09","M" +"","371383","Jung","Minjee","","09","F" +"","347435","Justin","Anjali","","09","F" +"","445100","Kantor","Noah","B","09","M" +"","352715","Karns","Garrett","J","09","M" +"","354600","Kaur","Saran","","09","F" +"","421393","Kavanagh","James","H","09","M" +"","354882","Kee","Brian","C","09","M" +"","348035","Kelly","Megan","","09","F" +"","190850","Kelsey","Mark","R","09","M" +"","345270","Ki","Julia","V","09","F" +"","331474","Kim","Grace","R","09","F" +"","347256","Kim","James","S","09","M" +"","437090","Kim","Jenny","M","09","F" +"","343606","Kim","Jisu","","09","M" +"","338761","Kindel","Andrew","R","09","M" +"alg","343506","Kirkpatrick","Noel","G","09","F" +"","353179","Knudson","Eve","M","09","F" +"","347439","Koert","Julianna","R","09","F" +"","347459","Kovach","Mackenzie","L","09","F" +"","349575","Kraekel","Cortney","E","09","F" +"","339044","Kramer","Pamela","S","09","F" +"","347623","Kundu","Sahana","","09","F" +"","167007","Lanasa","Dominic","J","09","M" +"","347696","Lang","Joseph","J","09","M" +"alg","325215","Lavanderos","Elena","L","09","F" +"","346252","Lee","Jason","J","09","M" +"alg","451381","Leitner","Stephanie","J","09","F" +"","365895","Levine","Shivani","S","09","F" +"fralg","360905","Lewis","Emily","P","09","F" +"","365897","Li","Daniel","X","09","M" +"","359307","Li","Rao","","09","F" +"","985548","Lightcap","Lukas","W","09","M" +"alg","452717","Little","Joseph","S","09","M" +"","346267","Liu","Miranda","","09","F" +"","198665","Lostoski","Christian","A","09","M" +"fralg","331347","Lowe","Travis","E","09","M" +"fralg","316880","Lowe, Jr.","Jake","L","09","M" +"alg","181715","Lucas","Noah","M","09","M" +"","344080","Luchytsky","Maria","A","09","F" +"","346826","Luckabaugh","Zachary","P","09","M" +"","349901","Ma","Justin","L","09","M" +"","352722","Maier","Casandra","W","09","F" +"","352723","Mallow","Josephine","M","09","F" +"","357699","Mamuad","Maxine Genevyv","A","09","F" +"","360482","Maniktala","Dhruv","","09","M" +"","442385","Mareddy","Srikar","R","09","M" +"","456648","Markoff","Alexandra","B","09","F" +"","375502","Marshall","Roshawna","D","09","F" +"","349180","McCue","Liam","P","09","M" +"","364193","Mehra","Kanika","A","09","F" +"","349434","Mehta","Vivek","N","09","M" +"","334198","Mejia","Diego","A","09","M" +"","330919","Meza","Anthony","B","09","M" +"","344707","Miller","Benjamin","M","09","M" +"","347254","Mnev","Pauline","","09","F" +"","345612","Moats","Ryan","M","09","M" +"","479379","Molnar","Benjamin","A","09","M" +"","346344","Moon","Emma","P","09","F" +"","347535","Mossman","Amanda","K","09","F" +"","353180","Mulcahy","Mary","G","09","F" +"","348756","Mullikin","Sarah","J","09","F" +"","343844","Mullin","Calley","B","09","F" +"","456680","Mullins","Andrew","J","09","M" +"","349387","Muyeen","Adiat","M","09","M" +"","192783","Nagahara","Elaine","A","09","F" +"","348030","Nambiar","Hirschel","M","09","M" +"","348028","Nambiar","Marshall","M","09","M" +"","348340","Ng","Clarissa","M","09","F" +"alg","348763","Norton","Guy","L","09","M" +"alg","195196","Orsini","Sara","M","09","F" +"alg","138988","Ouart","Julia","R","09","F" +"","159596","Pabba","Mani","K","09","M" +"","349220","Palmer","Eric","G","09","M" +"","347493","Palmer","Macy","A","09","F" +"","345622","Parikh","Esha","A","09","F" +"","126042","Patil","Vaibhav","V","09","M" +"","345915","Pavlick","Julia","J","09","F" +"","476863","Peek","Madison","G","09","F" +"","347585","Pelzman","Jacob","D","09","M" +"","453248","Pepper","Rachel","E","09","F" +"","371056","Pfeiffer","Andrew","M","09","M" +"","344961","Pham","Emily","Y","09","F" +"","330327","Portillo-Rivas","Nathaly","V","09","F" +"","334199","Prasada-Rao","Wilhelmina","S","09","F" +"","368924","Putta","Sanjana","","09","F" +"","352725","Quaranta","Marie","V","09","F" +"","347551","Ramazon","Patrick","F","09","M" +"","361786","Ramirez","Taylor","R","09","F" +"","436739","Ransom","Alison","F","09","F" +"alg","346225","Reyes","Rachel","","09","F" +"","348446","Richman","Jessica","B","09","F" +"","372512","Ringling","Brennah","E","09","F" +"","349175","Rivas","Franco","G","09","M" +"","348447","Robin","Rachel","E","09","F" +"","348450","Rodriguez","Patrick","L","09","M" +"","373073","Rondeau","Olivia","M","09","F" +"","352726","Roque","Jose","J","09","M" +"","371194","Rowe","Katrina","M","09","F" +"","156768","Ryan","Finn","L","09","M" +"","355862","Ryan","Rachel","G","09","F" +"fralg","464593","Santorocco","Giavanna","R","09","F" +"","349382","Satsangi","Nandini","M","09","F" +"","347900","Scott","Kile","A","09","M" +"","353112","Seely","Cade","M","09","M" +"","369393","Selvadurai","Varshini","","09","F" +"","349540","Sena","Alessandra","G","09","F" +"","348471","Shanbhag","Sayaka","K","09","F" +"","353851","Shastri","Ishana","A","09","F" +"","353006","Sier","Brandon","M","09","M" +"","345433","Singh","Shriya","","09","F" +"","347308","Sinha","Sahil","","09","M" +"alg","348767","Sofelkanik","Nikolas","W","09","M" +"","338835","Soriano","Beverly","K","09","F" +"alg","331885","Spano","Nicholas","A","09","M" +"","349094","Ssentongo","Racheal","","09","F" +"","349276","Starost","Joshua","E","09","M" +"","349280","Stevens-Donati","Kyle","M","09","M" +"","349259","Stewart","Samantha","E","09","F" +"","340793","Suggs","Adrian","I","09","M" +"","346769","Summers","Brandon","T","09","M" +"","479034","Sun","Andy","W","09","M" +"","347576","Sundaram","Sivani","","09","F" +"","342673","Suzich","Michael","J","09","M" +"","353541","Tabaa","Danny","M","09","M" +"","123438","Tammera","Sri Lahari","","09","F" +"","342696","Tang","Grace","W","09","F" +"","348496","Tang","Nina","","09","F" +"","347109","Taylor","Brandon","E","09","M" +"alg","322144","Tejada","Zed Mikhail","S","09","M" +"","348771","Terragno","Kalie","A","09","F" +"","349898","Thirukkonda","Ashwini","","09","F" +"","348772","Thomas","Samantha","F","09","F" +"","357200","Tiren","Joshua","N","09","M" +"","332367","Tkach","Oksana","N","09","F" +"","349153","Tom","Jalen","H","09","M" +"","349490","Treleven","Cathryn","A","09","F" +"","357176","Trone","Clark","E","09","M" +"fralg","355286","Trujillo-Duenas","Stephanie","","09","F" +"","304293","Turbyfill","Justin","C","09","M" +"","355369","Van Wert","Kasey","W","09","F" +"","437372","Vellala","Sourabh","S","09","M" +"","353182","Ventura","Tiara","S","09","F" +"","373412","Vidas","Justin","A","09","M" +"","459692","Villajuan","Joseph","B","09","M" +"alg","348773","Wade","Timothy","D","09","M" +"","203348","Walton","Cutler","J","09","M" +"","346786","Wang","Angela","J","09","F" +"","346790","Wang","Autumn","X","09","F" +"","353000","Wasilik","John","P","09","M" +"","343013","Wilbur","Thomas","B","09","M" +"alg","346798","Wilson","Clare","P","09","F" +"alg","167495","Wilson","Gregory","W","09","M" +"alg","348774","Winstead","Briona","A","09","F" +"","409338","Xu","April","R","09","F" +"","360428","Xu","Kenneth","X","09","M" +"","179131","Yamson","Vince Jay Marnell","O","09","M" +"","349312","Yang","Kaitlyn","Y","09","F" +"","347816","Yee","Kristen","R","09","F" +"","348863","Yih","Timothy","","09","M" +"","375405","Yim","Ashley","J","09","F" +"","331349","Zapata","Begonia","L","09","F" +"","346803","Zhang","Melody","Y","09","F" +"","350221","Zheng","Grace","C","09","F" +"","346824","Zheng","Michelle","X","09","F" +"","346808","Zhong","Eric","","09","M" +"","341741","Zhou","Edward","T","09","M" +"","338416","Zhou","Samuel","J","09","M" +"","411591","Zhu","Amy","Y","09","F" +"","349769","Zou","David","","09","M" +"","346085","Zou","Dylan","Y","09","M" +"","322507","Abbey","Bian","","10","F" +"","345932","Acquaye","Nicole","A","10","F" +"","350429","Adah","Alex","J","10","M" +"","440893","Ainsworth","Dewontay","L","10","M" +"","324849","Allentuck","Jordan","N","10","F" +"","993196","Andrade","Christian","M","10","M" +"","380266","Archampong","Victoria","N","10","F" +"","309386","Arias","Diana","M","10","F" +"","377046","Austin","Christian","T","10","M" +"","322757","Awono","Camille","I","10","F" +"","328663","Babbar","Anav","","10","M" +"","326086","Bagalkotkar","Sapna","P","10","F" +"","332990","Ballmann","Dorothy","M","10","F" +"","326090","Bang","Joon","","10","M" +"stat","327677","Barbosa","Andres","R","10","M" +"","327567","Barry","Peter","A","10","M" +"","425001","Basehore","Michael","J","10","M" +"","325482","Beaulieu","Alexander","J","10","M" +"","323807","Beltran","Stefanie","V","10","F" +"","307313","Benitez","Katherine","J","10","F" +"","996465","Berenzweig","Adam","J","10","M" +"","325591","Bernstein","Philip","L","10","M" +"","325592","Bhut","Yogi","N","10","M" +"","197660","Blackburn","Emma","E","10","F" +"","324856","Bliss","Morgan","K","10","F" +"","322396","Bolten","Emily","A","10","F" +"","354581","Bonhomme","Jacob","C","10","M" +"","147027","Boyle","Eleanor","H","10","F" +"","424991","Branton","Luc","J","10","M" +"","330231","Brenholtz","Quinlan","C","10","M" +"","324861","Briancon","Aidan","S","10","M" +"","327080","Brill","Charles","R","10","M" +"","360839","Broadhurst","Kadin","J","10","M" +"","326261","Brooks","Jared","E","10","M" +"","330232","Bush","Hannah","C","10","F" +"","322289","Byrd","Taylor","R","10","F" +"","357142","Caballero","Lydia","B","10","F" +"","350034","Cahill","Madison","W","10","F" +"","335294","Campbell","Cassandra","R","10","F" +"","322461","Capobianchi","Gabriella","A","10","F" +"","325362","Carin","Rebecca","D","10","F" +"","322349","Carney","Killian","K","10","F" +"","322608","Carpentier","Emma","C","10","F" +"","327712","Casay","Marisa","N","10","F" +"","323240","Castillo-Grynberg","Adan","","10","M" +"","350445","Chari","Rohan","R","10","M" +"","350448","Chari","Rohit","R","10","M" +"","301794","Chatterjee","Anshul","","10","M" +"","423399","Chen","Cindy","X","10","F" +"","314700","Chen","George","","10","M" +"","327203","Chernosky","Ryan","A","10","M" +"","318541","Cherubet","Nadjah","Y","10","F" +"","169829","Chintala","Navya","R","10","F" +"","169833","Chintala","Rohith","S","10","M" +"","123766","Choi","Alexander","W","10","M" +"","329668","Chung","Stephen","A","10","M" +"","318912","Collins","Michael","I","10","M" +"","316760","Convers","Matthew","J","10","M" +"","319648","Copeland","Paris","S","10","F" +"","328186","Corapcioglu","Darren","Y","10","M" +"","336009","Correa","Matthew","","10","M" +"","325781","Courbois","Caroline","A","10","F" +"","996703","Cubert","Noah","J","10","M" +"","982046","Dahlin","Kellie","S","10","F" +"","178020","Davis","Alexandra","A","10","F" +"","334922","Dice","Cassidy","L","10","F" +"","995071","Dockstader","Alayna","S","10","F" +"","326306","Dollar","Theresa","M","10","F" +"","306296","Dominici","Perry","C","10","M" +"","328706","Dou","Zachary","D","10","M" +"","325789","Draghici","Jonathan","M","10","M" +"","161815","Drain","Dylan","S","10","M" +"","987619","Duran","Nicole","A","10","F" +"","325791","Durmowicz","Madeline","N","10","F" +"","330238","Dutton","James","R","10","M" +"","144126","Elkoshairi","Youssef","W","10","M" +"","430947","Evans","Elise","F","10","F" +"","334272","Falls","Richard","Z","10","M" +"","319116","Fang","Steven","","10","M" +"","321643","Fein","Derek","C","10","M" +"","465713","Fernandes","Loren","R","10","F" +"","463730","Fessenden","Stefan","E","10","M" +"","997418","Field","William","J","10","M" +"","325626","Fisanich","Tabitha","J","10","F" +"","316549","Fitzgerald","Sean","P","10","M" +"","354119","Fogam","Edlia","K","10","F" +"","328714","Fream","Mitchell","R","10","M" +"","326604","Fry","Carter","H","10","M" +"","328716","Fuhrmann","Christian","B","10","M" +"","323189","Furr","Athena","C","10","F" +"","325569","Gana","Nahbuma","F","10","F" +"","340689","Gangineni","Sai","A","10","M" +"","353998","Gao","Catherine","X","10","F" +"","338460","Garcia","Elias","A","10","M" +"","437670","Garrett","Samuel","S","10","M" +"","327375","Getahun","Caleb","Z","10","M" +"","301387","Gherman","Benjamin","M","10","M" +"","305596","Glinsmann","Matthew","J","10","M" +"","454380","Graham","Paul","C","10","M" +"","325745","Green","Erin","K","10","F" +"","327453","Green","Justin","W","10","M" +"","326264","Groman","Alexander","W","10","M" +"","993198","Gruber","Victoria","A","10","F" +"","326607","Gupta","Kshitij","","10","M" +"","337161","Gupta","Shefali","","10","F" +"","328410","Guthrie","Sarah","L","10","F" +"","327749","Guzman","Gianmarco","M","10","M" +"","318219","Haddaway","Ryan","A","10","M" +"","336663","Hamm","Brooke","M","10","F" +"","324972","Hammett","Bridgette","M","10","F" +"","464978","Harkins","Haley","E","10","F" +"","170086","Harris","Adey","A","10","F" +"","334913","Hawkins","Jessica","G","10","F" +"","322447","Headley","Benedict","E","10","M" +"","306218","Hendricks","Michael","R","10","M" +"","457303","Heron","Marcus","A","10","M" +"","327804","Herron","Mark","R","10","M" +"","330243","Hill","Mathew","F","10","M" +"","310796","Hill, JR","Keith","A","10","M" +"","333994","Hinds","Ethan","J","10","M" +"","177350","Hobbs","Julia","E","10","F" +"stat","333457","Homsi","Rami","M","10","M" +"","309595","Hong","Sung Yun","","10","M" +"","309371","Hovor","Franklina","E","10","F" +"","326233","Hsu","Jason","S","10","M" +"","323175","Huang","Robert","B","10","M" +"","451221","Huynh","Dylan","N","10","M" +"","374967","In","Esther","","10","F" +"","323372","Insalaco","Chloe","C","10","F" +"","318622","Ipina","Katherine","A","10","F" +"","325074","Ismail","Feras","","10","M" +"","336870","Iyer","Sarayu","P","10","F" +"","330245","Jackson","Clara","A","10","F" +"","981993","Jackson","James","D","10","M" +"","320055","Jackson","Tania","L","10","F" +"","329170","Jacobs","Brian","D","10","M" +"","323685","Jaiman","Aman","","10","M" +"","455374","Jain","Ritvik","P","10","M" +"","409436","Jang","Jennifer","Y","10","F" +"","322458","Jaramillo","Juanita","","10","F" +"","328090","Johnson","Andrea","N","10","F" +"","327479","Johnson","Darby","B","10","M" +"","328091","Johnson","Rachel","M","10","F" +"","330247","Johnston","Ryan","B","10","M" +"","310312","Jones","Christian","M","10","M" +"","328651","Kabir","Mubrook","","10","M" +"","326029","Kalra","Anjali","S","10","F" +"","329080","Kang","Dahye","","10","F" +"","416210","Kasten","Ryan","J","10","M" +"","156440","Kasuske","Isaac","W","10","M" +"","355235","Katti","Divya","M","10","F" +"","319117","Keranahalli","Pooja","B","10","F" +"","323750","Kim","Caius","A","10","M" +"stat","311520","Kim","Na Hye","","10","F" +"stat","327348","Kim","Stephanie","S","10","F" +"","319552","Kinzie","Raymond","H","10","M" +"","327495","Kong","Joyce","J","10","F" +"","325078","Kovich","Yaniv","R","10","M" +"","376519","Krasche","Jackson","E","10","M" +"","977297","Lavanderos","Estephan","E","10","M" +"","370665","Lechner","Katarina","T","10","F" +"stat","418300","Lee","Carol","T","10","F" +"","333179","Lee","Daniel","D","10","M" +"","370017","Lee","Kelliann","R","10","F" +"","175217","Lehrman","Stephanie","A","10","F" +"","330237","Leibrand","Hannah","N","10","F" +"","326279","Li","William","J","10","M" +"","325361","Lin","Ching-Yuan","A","10","M" +"","337260","Lu","Amy","H","10","F" +"","415874","Lyons","Erin","R","10","F" +"","415881","Lyons","Sean","M","10","M" +"","326079","Ma","Joyce","I","10","F" +"","321102","Macairan","Rachel Alexandra","E","10","F" +"","330251","Magaha","Maddison","J","10","F" +"","321675","Mallow","Charlotte","Z","10","F" +"","430056","Mandere","Glenn","G","10","M" +"","344981","Manickavel","Sangavi","R","10","F" +"","329166","Manoharan","Shashidhar","S","10","M" +"","375499","Marshall","Darrell","R","10","M" +"","325093","Marshall","Jacob","A","10","M" +"","453044","Mason","Dylan","M","10","M" +"","433207","Mathews","Thomas","R","10","M" +"","325162","Mayer","Anna","I","10","F" +"","332605","McCutcheon","Brynn","E","10","F" +"","322979","McFall","Trevor","D","10","M" +"","327940","McLoughlin","Kelsey","Q","10","F" +"","332548","McMahan","Brendan","W","10","M" +"","318342","Metz","Colin","P","10","M" +"","176019","Miller","Daniel","J","10","M" +"","322710","Miller","Maureen","J","10","F" +"","327158","Modjarrad","Alessia","A","10","F" +"","170548","Molyneaux","NIcholas","R","10","M" +"","430059","Moraa","Michelle","H","10","F" +"","304551","Morningstar","Tyler","G","10","M" +"","355350","Morrison","Anna","R","10","F" +"","331039","Morrow","Katheryn","R","10","F" +"","326417","Mullett","Mackenzie","K","10","F" +"","356447","Murthy","Chandan","E","10","M" +"","415543","Nachod","Zachary","J","10","M" +"","998271","Narendra","Amogh","","10","M" +"","332090","Naumov","Victoria","","10","F" +"","331529","Neidhart","Kevin","D","10","M" +"","177343","Oberman","Connell","D","10","M" +"","313690","Oden","Sara","V","10","F" +"","992043","Oram","Thomas","B","10","M" +"","139000","Ouart","Jeremy","L","10","M" +"","328991","Oza","Parth","R","10","M" +"","161168","Paksima","Amirah","N","10","F" +"","347366","Pandalai","Bhuvana","S","10","F" +"","325748","Parise","Elizabeth","H","10","F" +"","183083","Park","Colin","","10","M" +"","324971","Park","Justin","S","10","M" +"","326638","Parker","Stephanie","E","10","F" +"","327515","Paul","Jhasper","G","10","F" +"","349010","Pavelle","Jessica","T","10","F" +"","409423","Pearre","Brady","A","10","M" +"","356056","Peck","Kira","E","10","F" +"","329031","Phelps","Maria","J","10","F" +"","325848","Poole","Thomas","E","10","M" +"","310348","Powell","Rani","O","10","F" +"","985471","Prebilic","Gavin","F","10","M" +"","370149","Prem","Jagan","R","10","M" +"stat","323123","Qian","Eric","S","10","M" +"","330253","Quaranta","Renee","G","10","F" +"","352948","Queen","Robert","A","10","M" +"","336015","Raghu","Apurva","K","10","F" +"","327046","Rakheja","Rhea","","10","F" +"","167548","Rauschenberg","Carson","G","10","M" +"","332939","Reyazuddin","Michelle","F","10","F" +"","325823","Rich","Julia","E","10","F" +"","372290","Rosenberg","Samuel","K","10","M" +"","327139","Roy","Tyler","J","10","M" +"","325094","Royal","James","M","10","M" +"","325946","Ruvinsky","Rebecca","J","10","F" +"","327362","Saar","Logan","M","10","M" +"stat","317905","Sabas","Hayden","A","10","M" +"","354220","Sabett","Michael","T","10","M" +"","325248","Sartschev","John","T","10","M" +"","330254","Schmidt","Susanna","B","10","F" +"","318633","Selvadoss","Andrew","S","10","M" +"","349754","Sesetty","Vaishnavi","S","10","F" +"","343999","Sheehi","Anthony","J","10","M" +"","327672","Shen","Kevin","","10","M" +"","330255","Sherman","Molly","E","10","F" +"","353561","Shields","Brigit","E","10","F" +"","330256","Siegrist","Robert","M","10","M" +"","329455","Simonson","Kelly","P","10","F" +"","327799","Sivarajan","Arjun","R","10","M" +"","324212","Skanchy","Sophie","K","10","F" +"","323088","Slebodnik","Nicole","A","10","F" +"","974034","Smith","Shelby","L","10","F" +"","157270","Solans","Paige","E","10","F" +"fralg","334658","Solomon","Azlyn","C","10","F" +"","329090","Song","Kevin","","10","M" +"","330257","Speck-McMorris","Liam Gareth","M","10","M" +"","326256","Srikanth","Sriya","","10","F" +"","325256","Staszewski","Melanie","Y","10","F" +"","326339","Stoughton","Jennifer","T","10","F" +"","334201","Stroud","Lucas","A","10","M" +"","323261","Su","Kevin","L","10","M" +"","319368","Szafranski, Jr.","Paul","J","10","M" +"","364884","Taggart","Ethan","S","10","M" +"","326469","Tash","Jonah","N","10","M" +"","325941","Tatum","Megan","R","10","F" +"","327102","Taylor","Bryce","R","10","M" +"","963062","Tetlow","Alivia","G","10","F" +"","323346","Thomas","Colin","C","10","M" +"","325251","Thompson","John","J","10","M" +"","325249","Thompson","Madeleine","C","10","F" +"","320324","Thota","Ishwarya","","10","F" +"","329104","Ting","John","","10","M" +"stat","329106","Todd","Nina","N","10","F" +"","310596","Torres","Ester Pauline","L","10","F" +"","330261","Trent","Dillon","M","10","M" +"","326082","Tripu","Deepika","R","10","F" +"","328128","Truland","Danielle","H","10","F" +"","327036","Tuzmen","Deniz","Z","10","F" +"","325270","Tyler","Jackson","L","10","M" +"stat","409792","Umansky","David","S","10","M" +"stat","326008","Urban","Michael","J","10","M" +"","411234","Van Houten","Kathleen","R","10","F" +"","326702","Vangara","Sreya","","10","F" +"","459691","Villajuan","Jirah","B","10","F" +"","352848","Vincent","Jorin","T","10","M" +"","327173","Vinh","Ryan","B","10","M" +"","405213","Vogel","Donald","E","10","M" +"","140526","Volkle","Cassandra","N","10","F" +"","326679","Walker","Alice","E","10","F" +"","326680","Walker","Zachary","J","10","M" +"","325796","Wallace","Triana","D","10","F" +"","322910","Walter","Christian","H","10","M" +"","343778","Wang","Alan","M","10","M" +"","327774","Wang","Andy","","10","M" +"","356457","Wang","Julia","X","10","F" +"","329128","Wang","Patrick","","10","M" +"","979875","Wang","Philip","Z","10","M" +"","325272","Wathen","Kira","N","10","F" +"","146453","Webber","Dalton","P","10","M" +"","372094","Welch","Zoe","J","10","F" +"","326476","Whelan","Tobias","D","10","M" +"","344222","Whitney-Blum","Avery","D","10","F" +"","344130","Widenhofer","Zachary","A","10","M" +"","310569","Williams","Amelia","A","10","F" +"","997019","Wilson","Jack","M","10","M" +"","306662","Wolitzky","Gage","A","10","M" +"","326687","Wrona","Thomas","D","10","M" +"","328575","Wu","Iris","L","10","F" +"","455139","Xiao","Manchun","","10","F" +"","349890","Ya","Alvin","L","10","M" +"","329603","Yan","Tracy","Z","10","F" +"","307294","Yates","Sarah","V","10","F" +"","325836","Yavasani","Amit","K","10","M" +"","333679","Yendluri","Avanish","C","10","M" +"","332136","Yerger","Roger","W","10","M" +"","375473","Young","Breanna","M","10","F" +"","333810","Yu","Iris","","10","F" +"","171182","Zeranski","Zachary","B","10","M" +"","326015","Zic","Sophia","M","10","F" +"","329182","Zinn","Travis","A","10","M" +"","328019","Zou","Claude","Y","10","M" +"","302444","Agrawal","Neil","C","11","M" +"","963542","Agrawal","Nina","","11","F" +"","306422","Ahrens","John","F","11","M" +"rl","987912","Alfaro","Keila","M","11","F" +"rl","155860","Andres","Catherine","J","11","F" +"1","447433","Arabia","Samuel","L","11","M" +"","462484","Arango","Simon","","11","M" +"","977045","Atkins","Antonnia","J","11","F" +"","303747","Azamati","Delali","H","11","F" +"","308469","Baigal","Arona","","11","F" +"","982184","Ballew","Daniel","W","11","M" +"1","306806","Bamfo","Tyrone","K","11","M" +"1","307323","Beautz","John","P","11","M" +"","331354","Belski","Jordan","A","11","M" +"","304107","Bentz","Emma","N","11","F" +"","305932","Bernard-Coogan","Rory","S","11","M" +"","371971","Bhagwat","Aden","A","11","M" +"","331191","Bharmal","Zoya","H","11","F" +"","304483","Bhaskaran","Aadya","","11","F" +"","305581","Bhattacharyya","Jessica","","11","F" +"","302462","Bleich","Jessica","W","11","F" +"","304985","Boby","Kevin","P","11","M" +"","992124","Bong","Seung-Kyoon","","11","M" +"","332502","Boocks","Heather","L","11","F" +"","307553","Bourque","Courtney","S","11","F" +"","304871","Brady","Kellie","V","11","F" +"","306255","Brashear","Joseph","O","11","M" +"","990311","Bricker, Jr.","Daniel","J","11","M" +"","966129","Budd","Keyon","T","11","M" +"","306257","Budd","Patrick","J","11","M" +"","311924","Burnett","Filip","G","11","M" +"","319668","Carmack","Coleman","K","11","M" +"","343523","Carr","Alona","M","11","F" +"","314833","Caruso-Dipaolo","Josephine","F","11","F" +"","409319","Cecco","Delaney","I","11","F" +"","312341","Chawla","Karanbir","S","11","M" +"1","319279","Chen","Chris","M","11","M" +"","308698","Chen","Chuan","","11","M" +"1","364491","Chen","Eamon","Z","11","M" +"","992716","Cheng","Raymond","","11","M" +"","305034","Cherian","Amelia","A","11","F" +"","305260","Chilla","Michael","J","11","M" +"","309023","Cho","Daniel","","11","M" +"","304051","Cho","Kathleen","M","11","F" +"","163574","Choudhry","Skindar","M","11","M" +"","965240","Christensen","Kathryn","K","11","F" +"","304143","Colby","Derek","A","11","M" +"","305262","Corral","Ava","M","11","F" +"","200297","Cowger","Kylie","M","11","F" +"","306288","Creedon","Danielle","E","11","F" +"","306289","Creedon","Kathryn","J","11","F" +"","335394","Cross","Kenydi","J","11","F" +"","304265","Danna","Christopher","F","11","M" +"","966560","Deitz","Robert","S","11","M" +"1","316106","Dinh","Alyssa","M","11","F" +"","362021","Dixit","Anusha","","11","F" +"","307262","Donovan","James","F","11","M" +"","165011","Dorn","Yannick","D","11","M" +"1","162035","Drain","Aja","S","11","F" +"","306417","Drissel","Jacob","W","11","M" +"","304440","Dunathan","Conner","R","11","M" +"","306579","Durkin","Olivia","R","11","F" +"","312560","Dwyer","Michela","G","11","F" +"1","331050","Edwards","Alexus","N","11","F" +"","205337","Emmerich","Helen","","11","F" +"","306672","Enriquez","Shane","J","11","M" +"","991851","Er","Sertac","","11","M" +"","474465","Esser","David","M","11","M" +"","334273","Falls","Isabelle","G","11","F" +"1","304916","Fatima","Jabeen","","11","F" +"","305429","Feng","Matthew","R","11","M" +"1","470158","Fernandez","Gabriel","T","11","M" +"1","470157","Fernandez","Nicolas","D","11","M" +"","310151","Field","Danielle","N","11","F" +"","991284","Fisher","Colin","T","11","M" +"","320877","Fisher","Destiny ","N","11","F" +"1","320878","Fisher","Kaley","N","11","F" +"","368130","Forrester, Jr.","Corland","D","11","M" +"","438266","Frendlich","Dylan","A","11","M" +"","304270","Fruth","Kyle","M","11","M" +"","992695","Gandla","Divya","M","11","F" +"","334295","Ganesh","Harini","","11","F" +"","461266","Gao","Henry","J","11","M" +"","303411","Geisler","Shane","S","11","M" +"","306006","Giffin","Addison","M","11","F" +"","310181","Gnanaravi","Gilda","F","11","F" +"","304569","Goldberg","Anastasia","L","11","F" +"","306412","Goldsborough","Samantha","C","11","F" +"","380252","Gordon","Alicia","N","11","F" +"","325469","Greene","Kahlil","J","11","M" +"","304457","Greer","John","E","11","M" +"","154667","Grenier","Winston","E","11","M" +"","131844","Grimsby","Dakota","J","11","M" +"","323195","Gross","Mackenzie","A","11","F" +"","302166","Gross","Michael","S","11","M" +"","306324","Grubb","Megan","E","11","F" +"","306325","Hall","Melissa","J","11","F" +"","983211","Hanscom","Lucas","R","11","M" +"","995073","Harney","Morgan","A","11","F" +"","155715","Harris","Baharu","N","11","M" +"","306765","Harris","Granville","T","11","M" +"","147217","Heemskerk","William","H","11","M" +"","306329","Heimbach","Katherine","M","11","F" +"1","305275","Hemingway","Keegan","R","11","M" +"","306368","Hepburn","Kristen","M","11","F" +"","361916","Hernandez","Julian","A","11","M" +"","306374","Himmelfarb","Sara","W","11","F" +"1","330111","Hong","Sara","J","11","F" +"","154668","Hoover","Samantha","M","11","F" +"","958363","Hough","Jake","P","11","M" +"1","303725","Howson","Sachi","N","11","F" +"","308708","Hu","Kevin","","11","M" +"","306376","Huber","Alison","K","11","F" +"","311037","Huff, Jr.","Michael","A","11","M" +"","306779","Huntley","Steven","R","11","M" +"","303442","Jackson","Taneka","M","11","F" +"","172172","Jagodits","Theodore","B","11","M" +"","457138","Jensen","Claire","E","11","F" +"","350015","Jin","Benjamin","W","11","M" +"","329411","Johns","Emily","G","11","F" +"1","310514","Johnson","Sabrina","","11","F" +"","315935","Kane","Zubin","A","11","M" +"1","306790","Kaplan","Benjamin","D","11","M" +"1","333456","Kaur","Meher","","11","F" +"","306377","Khalil","Hailey","N","11","F" +"","375192","Khanna","Shreya","","11","F" +"1","319387","Khare","Mitushi","","11","F" +"","190433","Kilian","Nicholas","J","11","M" +"","303582","Kim","Dennis","T","11","M" +"","310521","Kim","Justin","B","11","M" +"","369110","Kim","Seungmin","","11","M" +"","305276","King","Amelia","F","11","F" +"","306379","Kinzie","Calvin","E","11","M" +"","138982","Klimkiewicz","James","A","11","M" +"","305321","Kline","Rebekah","L","11","F" +"","306380","Kocur","Brandon","E","11","M" +"","313850","Kollipara","Parameshwar","S","11","M" +"","308325","Kovich","Micael","R","11","M" +"","141145","Krishnan","Kartik","S","11","M" +"","141147","Krishnan","Uma","S","11","F" +"","977504","Kwon","Nathan","Y","11","M" +"","307799","Lang","Stephen","E","11","M" +"","306383","Larkin","Erin","N","11","F" +"","300971","Lawbaugh","Isabella","M","11","F" +"1","313915","Lee","Matthew","J","11","M" +"","303732","Lee","Samuel","G","11","M" +"","349909","Leng","Caroline","P","11","F" +"","310915","Lent","Andrew","M","11","M" +"","996291","Li","Vincent","","11","M" +"","301580","Love","Asya","J","11","F" +"","340715","Madhu","Shraeya","P","11","F" +"","308694","Mahshigian","Anthony","","11","M" +"","307266","Maier","Kimora","W","11","F" +"","315251","Malinin","Lev","V","11","M" +"","330114","Malmgren","Jackson","C","11","M" +"","312038","Mamba","Lindelwa","S","11","F" +"","307165","Manakkunnel","Kevin","S","11","M" +"","992458","Manjunath","Thanushree","","11","F" +"","172180","Markoff","Isabel","I","11","F" +"","313873","Marsh","Gabrielle","A","11","F" +"","335253","Martinis","Coleman","P","11","M" +"","306423","Mason","Jacob","P","11","M" +"","319624","Mathew","Nidhi","E","11","F" +"","992447","Mayenkar","Sahil","","11","M" +"1","305008","Mazzanti","Anna","M","11","F" +"","304887","McCoy","Sean","D","11","M" +"","334949","McDonald","Michael","D","11","M" +"","304125","McElroy","Jessica","L","11","F" +"","306396","McIntyre","Timothy","I","11","M" +"","301604","McKenney","Cole","M","11","M" +"","301728","McMichael","Andrew","C","11","M" +"","986725","Melton","Jason","R","11","M" +"","301684","Mense","Sophia","A","11","F" +"","306606","Merrell","Kevin","L","11","M" +"","451465","Milby","Kaelyn","M","11","F" +"","306433","Miller","Connor","H","11","M" +"","154700","Miller","Madeline","E","11","F" +"","415826","Mohammed","Azeem","S","11","M" +"","438428","Molina","Alessandra","","11","F" +"","302340","Montone","Julia","E","11","F" +"","306435","Morgan","Michael","J","11","M" +"","306439","Mullikin","Samantha","A","11","F" +"","307378","Mundra","Ishan","S","11","M" +"","304362","Myers Mallinger","Cooper","T","11","M" +"","992878","Nardone","Theresa","J","11","F" +"","154672","Nichols","Alison","M","11","F" +"","307273","Nichols","Nelson","A","11","M" +"1","310959","Ning","Florence","C","11","F" +"","307922","Niu","Wally","L","11","M" +"","335867","Nocket","Parker","Q","11","M" +"","302502","O'Donnell","Alexander","L","11","M" +"","302233","Pach","Victoria","L","11","F" +"","437406","Pak","Alexis","Y","11","F" +"","992170","Papagjika","Daniel","H","11","M" +"","307280","Pappas","Michael","S","11","M" +"","305123","Patgiri","Anusha","","11","F" +"","972018","Paul","Hunter","C","11","M" +"","972019","Paul","Trevor","C","11","M" +"","307015","Paul","Viraj","","11","M" +"","305856","Pavlick","Samuel","V","11","M" +"","334941","Payne","Michael","J","11","M" +"","458399","Peng","Bo","","11","M" +"","308195","Peyton","Madison","L","11","F" +"","991285","Portillo","Natali","E","11","F" +"","304667","Pringle","Nicholas","J","11","M" +"","310994","Qian","Rachel","S","11","F" +"","988419","Quito","Shirley","","11","F" +"","441720","Rahman","Kashif","","11","M" +"","464950","Ralston","Jacob","A","11","M" +"","205550","Raman","Daven","L","11","M" +"","969688","Randall, Jr.","Ray","F","11","M" +"","364001","Reed","Elaine","K","11","F" +"","306669","Ren","Glenn","Y","11","M" +"","314827","Riegert","Thomas","H","11","M" +"","988421","Riggs","Siann","J","11","F" +"","328612","Roberts","Elizabeth","M","11","F" +"","463744","Romano","Olivia","G","11","F" +"","354284","Romero","Maristela","L","11","F" +"","981341","Ross","Tucker","W","11","M" +"","347712","Ryan","Liam","J","11","M" +"","156812","Ryan","Shay","C","11","F" +"","306233","Satsangi","Yamuna","E","11","F" +"","322980","Saud","Pahola","V","11","F" +"","307287","Savage","Catherine","T","11","F" +"","984333","Schneider","Cole","H","11","M" +"","333360","Sebastian","Ria","C","11","F" +"","318774","Shah","Harshal","A","11","M" +"","463317","Shao","David","","11","M" +"","311012","Shorb","Emily","C","11","F" +"","311202","Smedira","Devin","T","11","M" +"","306444","Smith","Austin","M","11","M" +"","457202","Sobrino","Carlos","A","11","M" +"","479687","Somaiya","Yash","","11","M" +"","336578","Stanoyevitch","William","V","11","M" +"","375451","Stephens","Seori","","11","F" +"","159058","Sun","Hannah","M","11","F" +"","995075","Terrell","Luke","R","11","M" +"","996244","Thaivalappil","Jeeva","R","11","F" +"","329197","Thaivalappil","Soorya","S","11","F" +"","320242","Thota","Praneeth","K","11","M" +"","306472","Tievy","Jacob","A","11","M" +"","305689","Tisaranni","Jordan","V","11","F" +"","306474","Trainor","Rebeckah","I","11","F" +"","306476","Truppo","Brian","J","11","M" +"","311747","Turbyfill","Joshua","A","11","M" +"","306876","Urban","Sophia","I","11","F" +"","996824","Valenta III","Thomas","M","11","M" +"","412735","Victoria","Emma","F","11","F" +"","306490","Wallace","Rebecca","L","11","F" +"","330985","Walter","Wilson","I","11","M" +"","311231","Wang","Crystal","Y","11","F" +"","996281","Wang","Lucy","","11","F" +"","331830","Wang","Lydia","","11","F" +"","307677","Wang","Richard","K","11","M" +"","307291","Wasilik","Carmela","N","11","F" +"","442790","Weaver","JaNae","N","11","F" +"","140704","Welch","Emma","K","11","F" +"","375478","Whitehouse","Emma","T","11","F" +"","375482","Whitehouse","Marc","A","11","M" +"","441536","Wilburn","James","R","11","M" +"","307937","Williams","Charles","L","11","M" +"","301500","Williams","Cole","J","11","M" +"","306660","Windall","Megan","C","11","F" +"","473646","Wink","Michael","H","11","M" +"","305643","Winston","Allison","A","11","F" +"","306661","Wolin","Camden","M","11","M" +"","311240","Wu","Fanny","","11","F" +"","304764","Xu","Daojun","J","11","F" +"","307909","Yang","Fiona","Y","11","F" +"","308335","Yang","Sheng Po","","11","M" +"","450372","Yin","Emily","L","11","F" +"","992415","Yin","Jessica","","11","F" +"","410139","Zhang","Christina","E","11","F" +"","411592","Zhang","Christine","Y","11","F" +"","305697","Zhang","Eric","Y","11","M" +"","306521","Zhang","Jacy","L","11","F" +"","439493","Zhao","Karl","","11","M" +"","333612","Zhou","Huile","","11","F" +"","305236","Zong","Kevin","","11","M" +"stat","420959","Abdelrahman","Eltayeb","A","12","M" +"","417699","Acosta","Luis","A","12","M" +"","968958","Agnihotri","Deepti","","12","F" +"","970350","Aho","Sylvana","M","12","F" +"","983110","Alvarez","Cynthia","M","12","F" +"","986700","Ambuehl","Olivia","P","12","F" +"","986522","Anthony","Benton","C","12","M" +"stat","353387","Aragon","Jovanna","","12","F" +"","980268","Armstrong","Jake","T","12","M" +"","982959","Arrington","Ayana","M","12","F" +"","333849","Arze","Daniel","P","12","M" +"","977600","Ashford","Erin","D","12","F" +"","311043","Ashley","Sirisha","M","12","F" +"","976721","Aurdos","Joshua","H","12","M" +"","986524","Bacas","Andrew","J","12","M" +"stat","985986","Badie","Kavon","","12","M" +"","419289","Baek","Gregorio","","12","M" +"","983095","Bannon","Ryan","M","12","M" +"stat","987070","Bano","Shaher","","12","F" +"","988316","Bao","Annie","J","12","F" +"","940228","Barner","Hayley","K","12","F" +"stat","983698","Beal","Grace","Y","12","F" +"","314399","Beeler","Abby","R","12","F" +"","126445","Beers","Elizabeth","M","12","F" +"","980502","Behrend","Geoffrey","H","12","M" +"","438148","Behrens","Taylor","L","12","F" +"stat","982386","Benedict","Emily","A","12","F" +"","939342","Berenzweig","Joshua","D","12","M" +"","160809","Berger","Kyle","E","12","M" +"","982309","Bernard","Emily","D","12","F" +"","420848","Bhatija","Sukalp","","12","F" +"","959498","Bilello","Lauren","E","12","F" +"1","473994","Blair","Erika","H","12","F" +"","955972","Blaker","Eli","A","12","M" +"","989223","Blankenship","Mercedes","A","12","F" +"","427659","Bodmer","Mollie","L","12","F" +"","988374","Bonilla","Yesenia","V","12","F" +"","983102","Bonnefond","Kaylee","D","12","F" +"","333295","Bourque","Liam","O","12","M" +"stat","981166","Bowe","Madison","K","12","F" +"","983024","Branscome","Adam","C","12","M" +"","984134","Brenchley","Cameron","M","12","M" +"1","983043","Brown","Cormac","C","12","M" +"","986344","Brown","Nicholas","J","12","M" +"","965308","Budd","Justin","B","12","M" +"","984255","Carrillo","Madison","J","12","F" +"stat","982088","Carroll","Ryan","C","12","M" +"","948825","Carter","William","F","12","M" +"stat","314835","Caruso-DiPaolo","Carissa","V","12","F" +"","984146","Chen","Candace","X","12","F" +"stat","990668","Choi","Erin","H","12","F" +"stat","981009","Chrisler","Ava","D","12","F" +"","949704","Cissel","Jordan","C","12","M" +"","984653","Coakley","Abigail","A","12","F" +"","983103","Comfort","Karyn","Q","12","F" +"stat","313510","Coombs","Rachel","P","12","F" +"","336007","Correa","Nicholas","J","12","M" +"","983108","Cross","Heather","M","12","F" +"","983195","D'Amelio","Jami","E","12","F" +"","983196","D'Amelio","Ryan","A","12","M" +"","983188","Dahlen","Alex","T","12","M" +"stat","983111","Dalrymple","Ryan","T","12","M" +"","983198","Darragh","Kristen","M","12","F" +"","983626","Dhingra","Opala","","12","F" +"","983187","Dibonge","Mina","S","12","F" +"","347152","Dillon ","Julio","A","12","M" +"stat","988321","Dixit","Rohan","S","12","M" +"","981770","Dodds","Lee","D","12","M" +"","971230","Dorsey","Jessica","A","12","F" +"stat","987040","Dunn","Jennifer","E","12","F" +"","985109","Durkin","Isabelle","M","12","F" +"","963115","Elerick","Riley","D","12","M" +"","970444","Er","Seray","","12","F" +"","993452","Essah","Breyonna","K","12","F" +"stat","983999","Evans","Nicholas","T","12","M" +"","165443","Falls","Taylor","L","12","F" +"","947742","Fan","Xiaotian","","12","M" +"","985631","Fisher","Destiny","N","12","F" +"","983202","Fisher","Destiny","S","12","F" +"","126444","Flitter","Joshua","W","12","M" +"stat","350381","Foster","Daniel","H","12","M" +"stat","334445","Franke","Ian","D","12","M" +"","963350","Frega","Guido","","12","M" +"","321674","Frost","Alex","R","12","F" +"stat","969107","Ganesan","Chandrashekar","","12","M" +"","984308","Garagiola","Jonathan","M","12","M" +"","986265","Getahun","Faven","W","12","F" +"","983030","Ghozati","Lia","M","12","F" +"","990998","Gill","Kyran","I","12","M" +"","984886","Goldman","Alexandra","L","12","F" +"","986525","Green","David","L","12","M" +"","313445","Green","Liesl","C","12","F" +"","989272","Grimes","Benjamin","C","12","M" +"stat","989318","Grimes","Matthew","E","12","M" +"stat","984467","Grinkemeyer","Austin","J","12","M" +"","983206","Gross","Stefan","M","12","M" +"","361721","Guggari","Megha","V","12","F" +"","419477","Guitart","Roger","I","12","M" +"stat","370097","Guo","Steven","H","12","M" +"stat","968669","Han","Khiem","B","12","M" +"stat","465573","Harkins","Casey","E","12","F" +"","984822","Haupt","Julia","R","12","F" +"","302956","Head","Katherine","M","12","F" +"","983232","Herbert","Makayla","C","12","F" +"","986528","Hetrick","Jonathan","T","12","M" +"","988656","Hinkson","Blake","A","12","M" +"","986529","Hinkson ","Christina","N","12","F" +"","984668","Hitchcock","David","J","12","M" +"","981231","Hitchcock","Robert","T","12","M" +"","177354","Hobbs","Ashley","M","12","F" +"","983039","Hockenbery","Gavin","T","12","M" +"","313735","Holmes","Rachel","E","12","F" +"stat","317742","Hong","Yoon Seo","","12","F" +"stat","353526","Horrigan","William","F","12","M" +"stat","983235","Howard","Grace","E","12","F" +"stat","984499","Hsu","Alex","S","12","M" +"stat","983214","Huang","Lily","S","12","F" +"stat","984504","Huang","Michelle","","12","F" +"","989953","Huff","Kara","A","12","F" +"","126470","Hundertmark","Anne","D","12","F" +"stat","438622","Hung","Erik","","12","M" +"","988325","Ives","Alexander","N","12","M" +"","983245","Jang","Jae Hee","","12","F" +"","333158","Jang","Jihoon","","12","M" +"","958773","Jansson","Colin","M","12","M" +"","986530","Jeffries","Declan","J","12","M" +"stat","982439","Jeong","Eunice","","12","F" +"","989273","Jia","Emily","","12","F" +"","428129","Jiang","Albert","S","12","M" +"stat","984021","Jiang","Kenneth","W","12","M" +"","312044","Jiau","Grace","W","12","F" +"","984023","Jofre","Kaitlyn","A","12","F" +"stat","983253","Johnson","Christopher","C","12","M" +"","960509","Johnson","Jake","M","12","M" +"","127386","Jordan","Julia","R","12","F" +"","211856","Joy","Melissa","A","12","F" +"stat","374245","Kandaswamy","Suriya","","12","F" +"","438149","Kang","Ellen","J","12","F" +"","981322","Karns","Analise","R","12","F" +"stat","421392","Kavanagh","Kathryn","J","12","F" +"","987035","Kenly","Carley","E","12","F" +"","430055","Kerubo","Ivy","S","12","F" +"","442990","Killsback","Konner","H","12","M" +"stat","981115","Kim","Chloe","I","12","F" +"","968996","Kim","Jean-Young","","12","F" +"","986088","King","Angeline","O","12","F" +"stat","985763","Kitchen","Rachel","C","12","F" +"1","138972","Klimkiewicz","Shirley","M","12","F" +"","983034","Kocur","Andrew","W","12","M" +"stat","982782","Koutsandreas","Megan","G","12","F" +"","965361","Kovach","Zachary","J","12","M" +"stat","955703","Kuhn","Michael","J","12","M" +"","955701","Kuhn","Nicholas","E","12","M" +"","983038","Kuldell","Jason","T","12","M" +"","982523","Lanciano","Katelyn","A","12","F" +"","311330","Land","Annika","J","12","F" +"","984614","Landis","Dylan","R","12","M" +"stat","949961","Lee","Hannah","S","12","F" +"","980951","LeMarr","Cody","M","12","M" +"","984751","Lentz","Ryan","A","12","M" +"stat","983539","Leung","Julia","M","12","F" +"stat","968888","Lew","Sonya","I","12","F" +"","984615","Lightcap","Lauren","L","12","F" +"","985876","Lingfu","Christina","W","12","F" +"","984622","Link","Julia","A","12","F" +"","990230","Liu","Amber","L","12","F" +"stat","983865","Lock","Oliver","M","12","M" +"","355363","Look","Christopher","W","12","M" +"","126442","Lostoski","Elena","M","12","F" +"stat","968930","Lum","Andrew","M","12","M" +"","984379","Ma","Kent","","12","M" +"","353253","Madan","Sanna","","12","F" +"stat","986532","Magaha","Trevor","W","12","M" +"","984537","Mandavia","Rohit","J","12","M" +"","984624","Martinez","Jessica","H","12","F" +"","346472","Martinez","Oscar","U","12","M" +"stat","970054","Matevosyan","Gayane","","12","F" +"","986533","McAleer","Julia","I","12","F" +"","985120","McCright","Kevin","N","12","M" +"","340184","Mehta","Anuj","N","12","M" +"","969559","Mendez","Julianna","S","12","F" +"","980975","Merchlinsky","Alexander","R","12","M" +"","984633","Micheals","Georgia","A","12","F" +"","430779","Milbrath","Daniel","O","12","M" +"","993633","Milisits","Kylin","M","12","F" +"","986467","Moran","Michael","C","12","M" +"1","314035","Mosunmade","Ruth","O","12","F" +"","984642","Mullett","Morgan","E","12","F" +"","456513","Mullins","Caroline","M","12","F" +"","976576","Murphey","Sean","W","12","M" +"","423972","Murphy","Rebecca","M","12","F" +"","984757","Mustafa","Anne","M","12","F" +"stat","968605","Nagenalli","Trishul","P","12","M" +"stat","409289","Nalesnik","Abigail","R","12","F" +"stat","409297","Nalesnik","Allison","M","12","F" +"","414801","Nathwani","Jaylen","J","12","M" +"","984758","Nevius","Allison","M","12","F" +"","988305","Ni","Jonathan","R","12","M" +"","307876","Nicholson, III","Howard","J","12","M" +"","960870","O'Donnell","John","W","12","M" +"","965687","Ofsthun","Ian","T","12","M" +"","983027","Onderko","Nathan","C","12","M" +"","969137","Ovetsky","Daniel","M","12","M" +"stat","431210","Palma, Jr","Charles","A","12","M" +"","989669","Patch","Rachel","M","12","F" +"","969142","Patel","Dhruv","T","12","M" +"","937736","Patton","Reid","G","12","M" +"","312988","Pedersen","Lillianna","D","12","F" +"","986341","Pera","Carley","A","12","F" +"stat","989326","Phelps","Xavier","J","12","M" +"","459331","Phillips","Briana","L","12","F" +"","984332","Posey","Tatum","R","12","F" +"","986534","Poss","Morgan","H","12","F" +"","980923","Potts","Louis","R","12","M" +"","969013","Powell","Raquel","E","12","F" +"stat","968607","Prabhakar","Supriya","","12","F" +"","985177","Prasanna","Anish","G","12","M" +"","979991","Purdy","William","J","12","M" +"","983461","Qian","Rolane","T","12","F" +"stat","986535","Quaranta","Michael","F","12","M" +"","308218","Quiroa","Diana","A","12","F" +"","970335","Quito","Elizabeth","","12","F" +"","987007","Raines","Jolee","","12","F" +"","986794","Ramazon","Devin","C","12","M" +"","141373","Ranero","Fabian","","12","M" +"","975656","Reddy","Anantha Sriya","V","12","F" +"","985033","Reyazuddin","Yusuf","","12","M" +"","135454","Robb","Dillon","K","12","M" +"","986024","Robinson","Faith","N","12","F" +"stat","420852","Roche","Brianna","C","12","F" +"","420851","Roche","Danielle","M","12","F" +"","987845","Rojas Pompa","Odalis","","12","F" +"","990383","Roque","Rosario","D","12","F" +"stat","945977","Rubin","Jeremy","S","12","M" +"","989282","Rumbaugh","Aleli","A","12","F" +"","310249","Rusak","Adam","Y","12","M" +"","974052","Sarakhman","Alesya","N","12","F" +"","984860","Schinosi","Jean-Luc","R","12","M" +"","983035","Selby, IV","Roy","L","12","M" +"","349608","Shah","Parthiv","K","12","M" +"","349607","Shah","Tanvi","K","12","F" +"","969149","Shah","Vineet","T","12","M" +"","985474","Shahzad","Maryam","","12","F" +"stat","335538","Sharma","Ankita","","12","F" +"","331352","Shea","John","A","12","M" +"stat","976304","Sheth","Ankit","","12","M" +"","981597","Shrestha","Kriti","D","12","F" +"","965405","Simmons, Jr.","Kevin","J","12","M" +"","334399","Singer","Noah","R","12","M" +"","457273","Slavoff","Anelia","G","12","F" +"","315968","Smith","Cameron","P","12","M" +"","984863","Soltis","Joseph","A","12","M" +"stat","984865","Souder","Justin","M","12","M" +"","984883","Sparrow","Erin","M","12","F" +"","126749","Strong","Jennifer","A","12","F" +"stat","987270","Sunil","Manisha","","12","F" +"stat","980482","Suzich","Renee","N","12","F" +"stat","983814","Tash","Mira","S","12","F" +"","984107","Tauqeer","Abdullah","B","12","M" +"","984891","Terragno","Renee","A","12","F" +"","127986","Therriault","Sydney","W","12","F" +"","951370","Thiaw","Aissatou","","12","F" +"","985505","Ting","Alexander","","12","M" +"","985004","Tivoli","Sarah","R","12","F" +"","969024","Tolstoy","Alexander","I","12","M" +"stat","983297","Tran","Tram-Anh","Q","12","F" +"","968611","Uppala","Amulya","","12","F" +"stat","983085","Van Meter","Kelly","M","12","F" +"","969157","Vaules","Sayaka","H","12","F" +"stat","980709","Vyas","Aradhana","","12","F" +"stat","311861","Wade","Nathan","M","12","M" +"","983952","Walker","Patrick","A","12","M" +"","311656","Wang","Emily","","12","F" +"","937560","Warfield","Amanda","L","12","F" +"","433527","Watson","Courtney","M","12","F" +"","146629","Webber","Alexis","K","12","F" +"","983585","Weishaar","Benjamin","O","12","M" +"","984779","Werner","Gabriella","M","12","F" +"stat","985910","Whitefield","Fiona","K","12","F" +"stat","981501","Whitford Jones","Declan","M","12","M" +"","982934","Whittaker","Lauren","N","12","F" +"","127051","Wilbur","Robert","W","12","M" +"","313558","Wilkins","Kyle","L","12","M" +"","983644","Williams","Courtney","D","12","F" +"","983031","Williams","Kirk","H","12","M" +"","987017","Willis","Trey","T","12","M" +"","984894","Wills","Hannah","R","12","F" +"","989204","Wilson","Megan","O","12","F" +"","186693","Witmer","Kayla","A","12","F" +"","980699","Wolz","Shirley","A","12","F" +"stat","983977","Wrona","Paul","D","12","M" +"","976982","Xie","Cathy","","12","F" +"","333331","Xu","Eric","E","12","M" +"","450642","Yin","Michael","S","12","M" +"","308934","Yoo","Seong Joon","","12","M" +"","986106","Yoon","Stephanie","N","12","F" +"stat","985952","Young","Autumn","K","12","F" +"","969028","Yuan","Ally","H","12","F" +"","984519","Zhang","Hansheng","","12","M" +"stat","401359","Zhou","Angela","","12","F" +"stat","988516","Zou","Cherry","Y","12","F" +"","356187","Zou","Kaylee","M","12","F" \ No newline at end of file diff --git a/src/data/email.config b/src/data/email.config new file mode 100644 index 0000000..4f4b3fb --- /dev/null +++ b/src/data/email.config @@ -0,0 +1,3 @@ +2 +sais9942@gmail.com +353851@mcpsmd.net diff --git a/src/data/options.sip b/src/data/options.sip new file mode 100644 index 0000000..b77e144 --- /dev/null +++ b/src/data/options.sip @@ -0,0 +1,21 @@ ++++ +++ +Submit Button, Enter Reason for Late Arrival: +Sick +Doctor/Dentist Appointment +Unexcused +Religious Reason +Transportation +College Visit ++++ +++++ +Submit Button, Enter reason for leaving and who you were excused by: +Sick +Doctor/Dentist Appointment +Religious Reason +College Visit +Title 2 +Enter who you were excused by: +Health Room +Parent +End \ No newline at end of file diff --git a/src/data/quartech.mer b/src/data/quartech.mer new file mode 100644 index 0000000..eeb8970 --- /dev/null +++ b/src/data/quartech.mer @@ -0,0 +1,1171 @@ +Alpha_name,FIRST,GR,ID,LAST,MI +"Abdulmalek, Islah I.","Islah","09","350523","Abdulmalek","I" +"Aben, Aaron J.","Aaron","09","366101","Aben","J" +"Acharya, Aneesh S.","Aneesh","09","411401","Acharya","S" +"Agrawal, Amol ","Amol","09","369072","Agrawal","" +"Ahmad, Hisham U.","Hisham","09","403552","Ahmad","U" +"Ahmed, Rida ","Rida","09","479223","Ahmed","" +"Allentuck, Sydney H.","Sydney","09","364234","Allentuck","H" +"Allgood, Samuel H.","Samuel","09","442500","Allgood","H" +"Allison, Sofia H.","Sofia","09","367118","Allison","H" +"Aluka, Rohan V.","Rohan","09","366054","Aluka","V" +"Amani, Aziza V.","Aziza","09","476331","Amani","V" +"Anderson, Remy L.","Remy","09","368703","Anderson","L" +"Antolli, Marcus P.","Marcus","09","409871","Antolli","P" +"Arambawela, Lahiru M.","Lahiru","09","362950","Arambawela","M" +"Arida, Joseph A.","Joseph","09","177914","Arida","A" +"Ballew, Michael P.","Michael","09","364223","Ballew","P" +"Barash, June M.","June","09","368000","Barash","M" +"Barkdoll, David O.","David","09","364264","Barkdoll","O" +"Barochia, Meera V.","Meera","09","404411","Barochia","V" +"Barron, Juan M.","Juan","09","368746","Barron","M" +"Batres, William M.","William","09","351634","Batres","M" +"Battina, Pallavi ","Pallavi","09","368987","Battina","" +"Behrend, Rachael A.","Rachael","09","403886","Behrend","A" +"Bergstrom, Hunter M.","Hunter","09","415588","Bergstrom","M" +"Bertolini, Kyra M.","Kyra","09","352398","Bertolini","M" +"Blair, Bradford Y.","Bradford","09","473931","Blair","Y" +"Bodmer, Samuel L.","Samuel","09","364265","Bodmer","L" +"Bolten, Shaun P.","Shaun","09","362556","Bolten","P" +"Borjigin, Moshelle S.","Moshelle","09","366705","Borjigin","S" +"Bowen, Cheyanne M.","Cheyanne","09","347309","Bowen","M" +"Brannman, Solomiya S.","Solomiya","09","203076","Brannman","S" +"Brill, Owen G.","Owen","09","366209","Brill","G" +"Brizhik, Luka A.","Luka","09","187703","Brizhik","A" +"Brode, Madeline G.","Madeline","09","364961","Brode","G" +"Burdick, Olivia J.","Olivia","09","368750","Burdick","J" +"Burns, Kyle M.","Kyle","09","365395","Burns","M" +"Cahill, Daniel W.","Daniel","09","367357","Cahill","W" +"Carin, Jacob R.","Jacob","09","368524","Carin","R" +"Carney, Cameron M.","Cameron","09","341976","Carney","M" +"Carranza, Fernando ","Fernando","09","347324","Carranza","" +"Carter, Grace T.","Grace","09","199006","Carter","T" +"Chatterjee, Ishita ","Ishita","09","366717","Chatterjee","" +"Chen, Daniel Z.","Daniel","09","369338","Chen","Z" +"Chen, Robert L.","Robert","09","421549","Chen","L" +"Chen, Sherry S.","Sherry","09","366096","Chen","S" +"Chen, Shirley Y.","Shirley","09","352480","Chen","Y" +"Cherfan, Catherine M.","Catherine","09","222197","Cherfan","M" +"Christ, Bradley G.","Bradley","09","364270","Christ","G" +"Christensen, Kelly J.","Kelly","09","368060","Christensen","J" +"Connell, Ajda S.","Ajda","09","375485","Connell","S" +"Convers, Jessica J.","Jessica","09","321710","Convers","J" +"Cross, Holly L.","Holly","09","364218","Cross","L" +"Dahlman, Ann M.","Ann","09","366517","Dahlman","M" +"Davenport, Kobey R.","Kobey","09","365758","Davenport","R" +"Deffinbaugh, Mary B.","Mary","09","364336","Deffinbaugh","B" +"Di Pietro, Marco E.","Marco","09","363864","Di Pietro","E" +"Dominici, Timothy O.","Timothy","09","364262","Dominici","O" +"Dorr, Caroline G.","Caroline","09","368598","Dorr","G" +"Dorsey, Connor R.","Connor","09","126550","Dorsey","R" +"Durmowicz, Sophia A.","Sophia","09","365780","Durmowicz","A" +"Edwards, Sabrina G.","Sabrina","09","364432","Edwards","G" +"Ehrentraut, Isabelle N.","Isabelle","09","212004","Ehrentraut","N" +"Eisenhardt, Adam H.","Adam","09","458652","Eisenhardt","H" +"Elamin, Lena M.","Lena","09","351692","Elamin","M" +"Elkoshairi, Yasmeen W.","Yasmeen","09","144128","Elkoshairi","W" +"Endlur, Rithik P.","Rithik","09","370926","Endlur","P" +"Ennis, William R.","William","09","364221","Ennis","R" +"Esser, Joseph M.","Joseph","09","473574","Esser","M" +"Fedders, Zachary M.","Zachary","09","325668","Fedders","M" +"Fedorov, Hannah A.","Hannah","09","149228","Fedorov","A" +"Ferguson, Nicholas A.","Nicholas","09","324037","Ferguson","A" +"Field, Caroline E.","Caroline","09","368752","Field","E" +"Fisher, Justin M.","Justin","09","337070","Fisher","M" +"Fisher, Maxwell P.","Maxwell","09","364257","Fisher","P" +"Foley, Aileen H.","Aileen","09","368514","Foley","H" +"Folk, Madison A.","Madison","09","376431","Folk","A" +"Fruth, Jacob R.","Jacob","09","324954","Fruth","R" +"Fry, William O.","William","09","319641","Fry","O" +"Fuentes, Jakelinne A.","Jakelinne","09","369844","Fuentes","A" +"Ganatra, Mahi K.","Mahi","09","367451","Ganatra","K" +"Gaunoux, Hendrick V.","Hendrick","09","447204","Gaunoux","V" +"Ghosh, Neil S.","Neil","09","367864","Ghosh","S" +"Goldstein, Zachary B.","Zachary","09","411190","Goldstein","B" +"Gong, Christine Q.","Christine","09","436379","Gong","Q" +"Gonzalez, Fabrizio G.","Fabrizio","09","368753","Gonzalez","G" +"Gordon, Abigail E.","Abigail","09","380253","Gordon","E" +"Gotlewski, Alyson E.","Alyson","09","365783","Gotlewski","E" +"Gowda, Nishanth ","Nishanth","09","364364","Gowda","" +"Graham, Mallary H.","Mallary","09","344362","Graham","H" +"Griffith, Kendall A.","Kendall","09","369046","Griffith","A" +"Groboski, Ethan M.","Ethan","09","461058","Groboski","M" +"Groeninger, Avery N.","Avery","09","203591","Groeninger","N" +"Grubb, Matthew A.","Matthew","09","363980","Grubb","A" +"Guan, Jeffrey ","Jeffrey","09","367457","Guan","" +"Guha, Tejas ","Tejas","09","457084","Guha","" +"Guillette, Leo W.","Leo","09","364268","Guillette","W" +"Gularson, Garrett B.","Garrett","09","364237","Gularson","B" +"Gunaratne, Dinal ","Dinal","09","366695","Gunaratne","" +"Gupta, Maansi ","Maansi","09","367176","Gupta","" +"Guzman, Geraldine T.","Geraldine","09","365784","Guzman","T" +"Hammett, Colin J.","Colin","09","364259","Hammett","J" +"Hanscom, Chase P.","Chase","09","364235","Hanscom","P" +"Hardaway, Brennan M.","Brennan","09","365882","Hardaway","M" +"Helfert, Joseph B.","Joseph","09","365883","Helfert","B" +"Hemingway, Colin H.","Colin","09","368831","Hemingway","H" +"Hicks, William A.","William","09","457331","Hicks","A" +"Hillegas, Chase T.","Chase","09","451378","Hillegas","T" +"Hitchcock, Julianna M.","Julianna","09","364241","Hitchcock","M" +"Hobbs, Brianna M.","Brianna","09","364229","Hobbs","M" +"Hobbs, Mary A.","Mary","09","177028","Hobbs","A" +"Hsu, Mandy ","Mandy","09","366218","Hsu","" +"Hui, Justin A.","Justin","09","328450","Hui","A" +"Inman, Jalen M.","Jalen","09","376850","Inman","M" +"Insalaco, Tess E.","Tess","09","363974","Insalaco","E" +"Izmirlian, Elias S.","Elias","09","369353","Izmirlian","S" +"Jamison, Benjamin P.","Benjamin","09","366722","Jamison","P" +"Jensen, Eleanor G.","Eleanor","09","455620","Jensen","G" +"Jha, Tanaya ","Tanaya","09","366285","Jha","" +"Johnson, Andrew J.","Andrew","09","160811","Johnson","J" +"Joshi, Rakshan ","Rakshan","09","366676","Joshi","" +"Kaligotla, Sreedatta ","Sreedatta","09","400768","Kaligotla","" +"Kalomiris, Alexander B.","Alexander","09","366912","Kalomiris","B" +"Kamineny, Pranay B.","Pranay","09","378400","Kamineny","B" +"Kandakumar, Akshay ","Akshay","09","137210","Kandakumar","" +"Kaplan, Hanne L.","Hanne","09","365722","Kaplan","L" +"Kasten, Jacob V.","Jacob","09","416207","Kasten","V" +"Kayo, Bryang W.","Bryang","09","351957","Kayo","W" +"Khozhainov, Alexander ","Alexander","09","172533","Khozhainov","" +"Kim, Christian H.","Christian","09","369373","Kim","H" +"Kim, Hannah ","Hannah","09","379737","Kim","" +"Kim, Hannah S.","Hannah","09","365419","Kim","S" +"Kim, Katherine Y.","Katherine","09","365888","Kim","Y" +"Kim, Minsu ","Minsu","09","362980","Kim","" +"King, Ariana L.","Ariana","09","371165","King","L" +"Kiviat, Jacob A.","Jacob","09","368677","Kiviat","A" +"Kolb, Josie V.","Josie","09","347456","Kolb","V" +"Kotti, Medha S.","Medha","09","362413","Kotti","S" +"Kovich, Benjamin C.","Benjamin","09","364240","Kovich","C" +"Kraekel, Ashley H.","Ashley","09","375225","Kraekel","H" +"Kresslein, Xavier M.","Xavier","09","219116","Kresslein","M" +"Krueger, Kenna F.","Kenna","09","364244","Krueger","F" +"Kuhlman, Kylie A.","Kylie","09","312462","Kuhlman","A" +"Kumar, Sanjana ","Sanjana","09","406627","Kumar","" +"Lanasa, Maria I.","Maria","09","167009","Lanasa","I" +"Lease, Zachary G.","Zachary","09","364137","Lease","G" +"Lee, Phillip S.","Phillip","09","367177","Lee","S" +"Leff, Alexander M.","Alexander","09","367597","Leff","M" +"Lemarr, Makayla E.","Makayla","09","363860","Lemarr","E" +"Lightcap, Lindsey T.","Lindsey","09","364263","Lightcap","T" +"Livingston, Catherine V.","Catherine","09","473782","Livingston","V" +"Lolla, Sadhana S.","Sadhana","09","367203","Lolla","S" +"Lowe, Travis E.","Travis","09","331347","Lowe","E" +"Lu, Michelle Y.","Michelle","09","367471","Lu","Y" +"Luu, Macawan S.","Macawan","09","366473","Luu","S" +"Macairan, Celine Anne E.","Celine Anne","09","323160","Macairan","E" +"Madhavan, Priyanka R.","Priyanka","09","376563","Madhavan","R" +"Magnani, Matthew A.","Matthew","09","367729","Magnani","A" +"Mallik, Bismita ","Bismita","09","440634","Mallik","" +"Mann, Gurshaan S.","Gurshaan","09","369731","Mann","S" +"Manoj, Esha ","Esha","09","366531","Manoj","" +"Mantz, Christopher R.","Christopher","09","364084","Mantz","R" +"Martinez, Andres J.","Andres","09","357429","Martinez","J" +"Maskey, Saloni ","Saloni","09","470367","Maskey","" +"Matlock, Elijah T.","Elijah","09","211358","Matlock","T" +"Mayenkar, Sanjana ","Sanjana","09","368359","Mayenkar","" +"Maytin, Hallie E.","Hallie","09","366407","Maytin","E" +"McCue, Fiona J.","Fiona","09","368905","McCue","J" +"McCutcheon, Molly C.","Molly","09","370268","McCutcheon","C" +"McHugh, Declan C.","Declan","09","369427","McHugh","C" +"Medina, Emilia F.","Emilia","09","368483","Medina","F" +"Merchan, Xenia V.","Xenia","09","351460","Merchan","V" +"Metcalf, Paul J.","Paul","09","364260","Metcalf","J" +"Morrison, Keegan M.","Keegan","09","372448","Morrison","M" +"Moss, Gordon D.","Gordon","09","363407","Moss","D" +"Murphy, Eamon J.","Eamon","09","156292","Murphy","J" +"Murthy, Anjali E.","Anjali","09","367499","Murthy","E" +"Nahid, Urjoshi ","Urjoshi","09","401210","Nahid","" +"Nair, Shabarish ","Shabarish","09","410769","Nair","" +"Narisu, Helena ","Helena","09","365677","Narisu","" +"Nathela Sudhakhar, Aditya Sudarsan ","Aditya Sudarsan","09","377255","Nathela Sudhakhar","" +"Nee, Megan L.","Megan","09","366699","Nee","L" +"Nichols, Ethan C.","Ethan","09","366804","Nichols","C" +"Nishida, Hina ","Hina","09","158069","Nishida","" +"Ntumsi, Clare M.","Clare","09","441874","Ntumsi","M" +"O'Connell, Patrick R.","Patrick","09","429084","O'Connell","R" +"Oberman, Aidan M.","Aidan","09","169897","Oberman","M" +"Okonkwo, Olisaneme O.","Olisaneme","09","213220","Okonkwo","O" +"Olcott, Aidan F.","Aidan","09","366985","Olcott","F" +"Onderko, Rachel A.","Rachel","09","363979","Onderko","A" +"Onderko, Zachary A.","Zachary","09","363978","Onderko","A" +"Oprandi, Isabella C.","Isabella","09","222829","Oprandi","C" +"Pacheco, Ashley S.","Ashley","09","351071","Pacheco","S" +"Padmanabhan, Surya ","Surya","09","370635","Padmanabhan","" +"Palatnik, Matthew D.","Matthew","09","213219","Palatnik","D" +"Parameswaran, Roshini ","Roshini","09","366825","Parameswaran","" +"Parker, Edward D.","Edward","09","229702","Parker","D" +"Parker, Emma E.","Emma","09","364224","Parker","E" +"Pechenov, Anthony S.","Anthony","09","184980","Pechenov","S" +"Penn, Lauren R.","Lauren","09","370641","Penn","R" +"Perelshteyn, Elizabeth R.","Elizabeth","09","366896","Perelshteyn","R" +"Pervez, Wasif A.","Wasif","09","367094","Pervez","A" +"Pham, Furelise V.","Furelise","09","415443","Pham","V" +"Phelps, Elizabeth L.","Elizabeth","09","368847","Phelps","L" +"Ponnapalli, Krishna D.","Krishna","09","162109","Ponnapalli","D" +"Poore, Andrew J.","Andrew","09","364228","Poore","J" +"Potts, Kaeli B.","Kaeli","09","364281","Potts","B" +"Prakash, Preethi ","Preethi","09","366640","Prakash","" +"Pustylnik, Miriam Z.","Miriam","09","366539","Pustylnik","Z" +"Puttaraju, Amulya N.","Amulya","09","367503","Puttaraju","N" +"Quigley, Alexander J.","Alexander","09","376606","Quigley","J" +"Rahman, Mariam ","Mariam","09","441161","Rahman","" +"Raines, Holly ","Holly","09","365631","Raines","" +"Ramaswamy, Tharakai V.","Tharakai","09","453179","Ramaswamy","V" +"Ratnam, Suraj ","Suraj","09","431627","Ratnam","" +"Rawool, Ria N.","Ria","09","367274","Rawool","N" +"Rendzio, Jordan E.","Jordan","09","341964","Rendzio","E" +"Rentel, Astrid C.","Astrid","09","204093","Rentel","C" +"Repass, Madison E.","Madison","09","364274","Repass","E" +"Rifai, Safiullah ","Safiullah","09","407297","Rifai","" +"Robinson, Heather E.","Heather","09","368166","Robinson","E" +"Roe, Jacob J.","Jacob","09","370578","Roe","J" +"Rohde, Logan K.","Logan","09","215279","Rohde","K" +"Rosenbaum, Maya M.","Maya","09","161488","Rosenbaum","M" +"Rosenberg, Jack H.","Jack","09","372292","Rosenberg","H" +"Roy, Cole L.","Cole","09","364217","Roy","L" +"Ruan, Lydia E.","Lydia","09","367493","Ruan","E" +"Ryan, Aidan M.","Aidan","09","369547","Ryan","M" +"Sabas, Skyler A.","Skyler","09","368287","Sabas","A" +"Savage, Colin M.","Colin","09","352729","Savage","M" +"Savage, James H.","James","09","368850","Savage","H" +"Scott, Katerina I.","Katerina","09","366629","Scott","I" +"Shanavas, Imaan ","Imaan","09","412562","Shanavas","" +"Shete, Shreya Y.","Shreya","09","367522","Shete","Y" +"Shields, Alaina M.","Alaina","09","411945","Shields","M" +"Shou, Charlie ","Charlie","09","367603","Shou","" +"Sinclair, Taylor K.","Taylor","09","366583","Sinclair","K" +"Singh, Udai B.","Udai","09","370209","Singh","B" +"Singleton, Emily E.","Emily","09","372482","Singleton","E" +"Sladic, Jason K.","Jason","09","369327","Sladic","K" +"Smith, Bailey J.","Bailey","09","348770","Smith","J" +"Smith, Malik J.","Malik","09","376522","Smith","J" +"Smith, Micah J.","Micah","09","366587","Smith","J" +"Smith, Penelope J.","Penelope","09","365740","Smith","J" +"Song, Kenny ","Kenny","09","370842","Song","" +"Sorrell, Connor J.","Connor","09","364267","Sorrell","J" +"Speck-McMorris, Anya O.","Anya","09","368851","Speck-McMorris","O" +"Sriram, Adhvayith ","Adhvayith","09","408903","Sriram","" +"Staszewski, Colin A.","Colin","09","364239","Staszewski","A" +"Stearns, Ashlynn R.","Ashlynn","09","197894","Stearns","R" +"Stempler, Madeline H.","Madeline","09","364261","Stempler","H" +"Stoughton, Thomas E.","Thomas","09","369575","Stoughton","E" +"Stratton, Alexander M.","Alexander","09","344391","Stratton","M" +"Stratton, Carlos M.","Carlos","09","344392","Stratton","M" +"Stroud, Jenna L.","Jenna","09","368852","Stroud","L" +"Surendra, Shreya ","Shreya","09","367414","Surendra","" +"Szafranski, Kelsey J.","Kelsey","09","362558","Szafranski","J" +"Tan, Steven S.","Steven","09","351225","Tan","S" +"Tauqeer, Abdurrahman B.","Abdurrahman","09","358267","Tauqeer","B" +"Taylor, Cole M.","Cole","09","371575","Taylor","M" +"Tievy, Ethan J.","Ethan","09","364277","Tievy","J" +"Tievy, Rachel P.","Rachel","09","315824","Tievy","P" +"Torshizi, Kasra Z.","Kasra","09","325609","Torshizi","Z" +"Trost, Avi S.","Avi","09","312446","Trost","S" +"Trythall, Lucas J.","Lucas","09","364256","Trythall","J" +"Tuan, Daniel ","Daniel","09","411293","Tuan","" +"Tummalapalli, Megha ","Megha","09","367403","Tummalapalli","" +"Turner, Ethan P.","Ethan","09","370003","Turner","P" +"Vaillancourt, Ian B.","Ian","09","236236","Vaillancourt","B" +"Vakkalanka, Bhavya L.","Bhavya","09","421523","Vakkalanka","L" +"Victory, Andrew R.","Andrew","09","367420","Victory","R" +"Volkle, Jessica M.","Jessica","09","139579","Volkle","M" +"Wang, Angie D.","Angie","09","368828","Wang","D" +"Wang, Isaac L.","Isaac","09","369688","Wang","L" +"Wang, James ","James","09","354201","Wang","" +"Weir, Lila E.","Lila","09","156456","Weir","E" +"Widenhofer, Joshua L.","Joshua","09","347057","Widenhofer","L" +"Willard, Frank C.","Frank","09","367469","Willard","C" +"Williams, Hailee C.","Hailee","09","364238","Williams","C" +"Wilson, Emily K.","Emily","09","369053","Wilson","K" +"Wittwer, Brennan L.","Brennan","09","476740","Wittwer","L" +"Xu, Angela R.","Angela","09","404511","Xu","R" +"Xu, William J.","William","09","358582","Xu","J" +"Yaddula, Tejasa ","Tejasa","09","369646","Yaddula","" +"Yan, Maxwell C.","Maxwell","09","364988","Yan","C" +"Yu, Joyce D.","Joyce","09","369795","Yu","D" +"Zehnle, Nicholas A.","Nicholas","09","369956","Zehnle","A" +"Zeranski, Jacob F.","Jacob","09","215088","Zeranski","F" +"Zhong, Andrew T.","Andrew","09","370869","Zhong","T" +"Zolt, Noah M.","Noah","09","321232","Zolt","M" +"Abrigo, Alexis A.","Alexis","10","353116","Abrigo","A" +"Ainsworth, Damion L.","Damion","10","440892","Ainsworth","L" +"Akdag, Anna M.","Anna","10","420146","Akdag","M" +"Alvarez, Jocelyn N.","Jocelyn","10","335165","Alvarez","N" +"Anderson, Holly E.","Holly","10","400232","Anderson","E" +"Arredondo, Matthew I.","Matthew","10","331052","Arredondo","I" +"Arudchandran, Luckshika S.","Luckshika","10","371547","Arudchandran","S" +"Atkins, Alivia J.","Alivia","10","330470","Atkins","J" +"Auel, Aidan A.","Aidan","10","347300","Auel","A" +"Barber, Alexander R.","Alexander","10","348521","Barber","R" +"Barney, Kieran M.","Kieran","10","346116","Barney","M" +"Beaton, Nicholas J.","Nicholas","10","456491","Beaton","J" +"Beautz, Michael R.","Michael","10","353317","Beautz","R" +"Becker, Rachel V.","Rachel","10","346020","Becker","V" +"Behrens, Thomas K.","Thomas","10","438040","Behrens","K" +"Benadon, Clara M.","Clara","10","340384","Benadon","M" +"Bentz, Timothy D.","Timothy","10","345206","Bentz","D" +"Berger, Darian E.","Darian","10","161058","Berger","E" +"Bevley, Dwight J.","Dwight","10","144508","Bevley","J" +"Bian, Edward H.","Edward","10","345210","Bian","H" +"Bian, Vincent W.","Vincent","10","374267","Bian","W" +"Bledsoe, Jack S.","Jack","10","347304","Bledsoe","S" +"Bodmer, Grace E.","Grace","10","347305","Bodmer","E" +"Boe, Gwendolyn R.","Gwendolyn","10","358446","Boe","R" +"Bonagiri, Prasanthi ","Prasanthi","10","363951","Bonagiri","" +"Broadhurst, Rhyston J.","Rhyston","10","378619","Broadhurst","J" +"Brooks, Gabriella L.","Gabriella","10","347312","Brooks","L" +"Bupp, Rachel J.","Rachel","10","347317","Bupp","J" +"Burdette, Madeline L.","Madeline","10","352716","Burdette","L" +"Bzhilyanskaya, Sofia A.","Sofia","10","346849","Bzhilyanskaya","A" +"Callaway, Jasmin N.","Jasmin","10","356867","Callaway","N" +"Carbonell, John A.","John","10","370287","Carbonell","A" +"Carey, Jessica L.","Jessica","10","342912","Carey","L" +"Carr, Arianna E.","Arianna","10","357108","Carr","E" +"Cayzedo, Nicolas A.","Nicolas","10","347327","Cayzedo","A" +"Chan, Spencer S.","Spencer","10","191721","Chan","S" +"Chaudhry, Aliyaan N.","Aliyaan","10","158598","Chaudhry","N" +"Chaves, Tatiana V.","Tatiana","10","196134","Chaves","V" +"Chen, Kevin N.","Kevin","10","347982","Chen","N" +"Chen, Peiqi ","Peiqi","10","350370","Chen","" +"Cherfan, Marilyn M.","Marilyn","10","190795","Cherfan","M" +"Chilla, Lauren M.","Lauren","10","344406","Chilla","M" +"Chim, Vincent B.","Vincent","10","352718","Chim","B" +"Chintagumpala, Hrishi ","Hrishi","10","338866","Chintagumpala","" +"Chinthalapale, Anusha ","Anusha","10","349370","Chinthalapale","" +"Chu, Amanda Y.","Amanda","10","346200","Chu","Y" +"Chu, Kristina C.","Kristina","10","156197","Chu","C" +"Clark, Grace E.","Grace","10","412888","Clark","E" +"Connell, Ronan A.","Ronan","10","326309","Connell","A" +"Cooley, Jacob C.","Jacob","10","985766","Cooley","C" +"Corfman, Julia L.","Julia","10","316761","Corfman","L" +"Cornejo, Julian A.","Julian","10","346476","Cornejo","A" +"Cox, Meghan E.","Meghan","10","339880","Cox","E" +"Crooks, Gabrielle M.","Gabrielle","10","344787","Crooks","M" +"Crucillo, Josephine R.","Josephine","10","364713","Crucillo","R" +"Dacanay, Carla R.","Carla","10","347330","Dacanay","R" +"Davis, Bryce J.","Bryce","10","352714","Davis","J" +"De Luna, Alec C.","Alec","10","353543","De Luna","C" +"Derenoncourt, Leeah M.","Leeah","10","479260","Derenoncourt","M" +"Diller, Ashley J.","Ashley","10","192548","Diller","J" +"Dower, Meghan E.","Meghan","10","155855","Dower","E" +"Dwyer, Joseph M.","Joseph","10","347511","Dwyer","M" +"Earley, Joseph A.","Joseph","10","159163","Earley","A" +"Edwards, William B.","William","10","452704","Edwards","B" +"Edwards III, Michael W.","Michael","10","336187","Edwards III","W" +"Elangovan, Kaushik ","Kaushik","10","375135","Elangovan","" +"Essah, Antonio U.","Antonio","10","357411","Essah","U" +"Firestine, Alexander T.","Alexander","10","347827","Firestine","T" +"Flitter, Alexander P.","Alexander","10","191730","Flitter","P" +"Fong, Daniel C.","Daniel","10","372675","Fong","C" +"Foo, Bryan C.","Bryan","10","346222","Foo","C" +"Foppe, Allison J.","Allison","10","436378","Foppe","J" +"Foster, John T.","John","10","345565","Foster","T" +"Fraley, Lita M.","Lita","10","352719","Fraley","M" +"Fraley, Travis W.","Travis","10","347336","Fraley","W" +"Fultz, Garrett W.","Garrett","10","347343","Fultz","W" +"Fuster, Anthony O.","Anthony","10","349532","Fuster","O" +"Gaddis, Ethan J.","Ethan","10","362973","Gaddis","J" +"Ganesh, Sruthi S.","Sruthi","10","347989","Ganesh","S" +"Ganti, Sridhar S.","Sridhar","10","347818","Ganti","S" +"Garcia, Elias A.","Elias","10","338460","Garcia","A" +"Garrett, Julianna F.","Julianna","10","437679","Garrett","F" +"Geehreng, Daniel P.","Daniel","10","347349","Geehreng","P" +"Georgius, Thomas R.","Thomas","10","436435","Georgius","R" +"Germer, Amy C.","Amy","10","194459","Germer","C" +"Gibbs, Isabel L.","Isabel","10","347137","Gibbs","L" +"Gimbrere, Matthew C.","Matthew","10","356158","Gimbrere","C" +"Gu, Michelle ","Michelle","10","370958","Gu","" +"Guimaraes, Isabel A.","Isabel","10","349213","Guimaraes","A" +"Guo, Maria K.","Maria","10","345217","Guo","K" +"Haddaway, Allison C.","Allison","10","347419","Haddaway","C" +"Hanidu, Bilikisu O.","Bilikisu","10","430735","Hanidu","O" +"Harris, Caitlin F.","Caitlin","10","347426","Harris","F" +"Headley, Annabelle M.","Annabelle","10","344737","Headley","M" +"Heemskerk, Isabella M.","Isabella","10","192017","Heemskerk","M" +"Hegarty, John M.","John","10","411936","Hegarty","M" +"Helfert, Hannah L.","Hannah","10","347089","Helfert","L" +"Hinkson, Trent A.","Trent","10","343508","Hinkson","A" +"Hoffman, Dominic J.","Dominic","10","347342","Hoffman","J" +"Hoffman, Sierra M.","Sierra","10","300697","Hoffman","M" +"Holmes, Stephen M.","Stephen","10","359671","Holmes","M" +"Holmquist, Foster O.","Foster","10","353004","Holmquist","O" +"Hong, Richard L.","Richard","10","455630","Hong","L" +"Hoover, Devin J.","Devin","10","986977","Hoover","J" +"Hsiao, Carmie C.","Carmie","10","347520","Hsiao","C" +"Hsieh, Natalie T.","Natalie","10","342921","Hsieh","T" +"Hu, Amanda S.","Amanda","10","343940","Hu","S" +"Huaylinos, Jairo E.","Jairo","10","331565","Huaylinos","E" +"Hueting, Maureen E.","Maureen","10","347450","Hueting","E" +"Huff, Joseph A.","Joseph","10","352721","Huff","A" +"Hull, Elizabeth R.","Elizabeth","10","138604","Hull","R" +"Hull, Samuel D.","Samuel","10","191327","Hull","D" +"Huntley, Isabel E.","Isabel","10","347841","Huntley","E" +"Islam, Aniq ","Aniq","10","338972","Islam","" +"Islam, Aniqa ","Aniqa","10","338973","Islam","" +"Iyer, Varsha ","Varsha","10","347949","Iyer","" +"Jackson, Demetreus ","Demetreus","10","333061","Jackson","" +"Jamison, William F.","William","10","354441","Jamison","F" +"Jin, Alex R.","Alex","10","349340","Jin","R" +"Job, Anna ","Anna","10","349256","Job","" +"Johns, William T.","William","10","365859","Johns","T" +"Johnson, Harrison T.","Harrison","10","996555","Johnson","T" +"Jones, Alexander R.","Alexander","10","344489","Jones","R" +"Jones, William R.","William","10","348759","Jones","R" +"Jung, Minjee ","Minjee","10","371383","Jung","" +"Justin, Anjali ","Anjali","10","347435","Justin","" +"Kantor, Noah B.","Noah","10","445100","Kantor","B" +"Karns, Garrett J.","Garrett","10","352715","Karns","J" +"Kaur, Saran ","Saran","10","354600","Kaur","" +"Kavanagh, James H.","James","10","421393","Kavanagh","H" +"Kee, Brian C.","Brian","10","354882","Kee","C" +"Kelly, Megan ","Megan","10","348035","Kelly","" +"Kelsey, Mark R.","Mark","10","190850","Kelsey","R" +"Ki, Julia V.","Julia","10","345270","Ki","V" +"Kim, Grace R.","Grace","10","331474","Kim","R" +"Kim, James S.","James","10","347256","Kim","S" +"Kim, Jenny M.","Jenny","10","437090","Kim","M" +"Kim, Jisu ","Jisu","10","343606","Kim","" +"Kindel, Andrew R.","Andrew","10","338761","Kindel","R" +"Kirkpatrick, Noel G.","Noel","10","343506","Kirkpatrick","G" +"Koert, Julianna R.","Julianna","10","347439","Koert","R" +"Kovach, Mackenzie L.","Mackenzie","10","347459","Kovach","L" +"Kraekel, Cortney E.","Cortney","10","349575","Kraekel","E" +"Kramer, Pamela S.","Pamela","10","339044","Kramer","S" +"Kundu, Sahana ","Sahana","10","347623","Kundu","" +"Lanasa, Dominic J.","Dominic","10","167007","Lanasa","J" +"Lang, Joseph J.","Joseph","10","347696","Lang","J" +"Lavanderos, Elena L.","Elena","10","325215","Lavanderos","L" +"Lee, Jason J.","Jason","10","346252","Lee","J" +"Leitner, Stephanie J.","Stephanie","10","451381","Leitner","J" +"Levine, Shivani S.","Shivani","10","365895","Levine","S" +"Li, Daniel X.","Daniel","10","365897","Li","X" +"Li, Rao ","Rao","10","359307","Li","" +"Lightcap, Lukas W.","Lukas","10","985548","Lightcap","W" +"Little, Joseph S.","Joseph","10","452717","Little","S" +"Liu, Miranda ","Miranda","10","346267","Liu","" +"Lostoski, Christian A.","Christian","10","198665","Lostoski","A" +"Lucas, Noah M.","Noah","10","181715","Lucas","M" +"Luckabaugh, Zachary P.","Zachary","10","346826","Luckabaugh","P" +"Ma, Justin L.","Justin","10","349901","Ma","L" +"Maier, Casandra W.","Casandra","10","352722","Maier","W" +"Mallow, Josephine M.","Josephine","10","352723","Mallow","M" +"Mamuad, Maxine Genevyv A.","Maxine Genevyv","10","357699","Mamuad","A" +"Maniktala, Dhruv ","Dhruv","10","360482","Maniktala","" +"Mareddy, Srikar R.","Srikar","10","442385","Mareddy","R" +"Marshall, Roshawna D.","Roshawna","10","375502","Marshall","D" +"McCue, Liam P.","Liam","10","349180","McCue","P" +"Mehra, Kanika A.","Kanika","10","364193","Mehra","A" +"Mehta, Vivek N.","Vivek","10","349434","Mehta","N" +"Mejia, Diego A.","Diego","10","334198","Mejia","A" +"Meza, Anthony B.","Anthony","10","330919","Meza","B" +"Miller, Benjamin M.","Benjamin","10","344707","Miller","M" +"Mnev, Pauline ","Pauline","10","347254","Mnev","" +"Moats, Ryan M.","Ryan","10","345612","Moats","M" +"Molnar, Benjamin A.","Benjamin","10","479379","Molnar","A" +"Moon, Emma P.","Emma","10","346344","Moon","P" +"Mossman, Amanda K.","Amanda","10","347535","Mossman","K" +"Mullikin, Sarah J.","Sarah","10","348756","Mullikin","J" +"Mullin, Calley B.","Calley","10","343844","Mullin","B" +"Mullins, Andrew J.","Andrew","10","456680","Mullins","J" +"Muyeen, Adiat M.","Adiat","10","349387","Muyeen","M" +"Nagahara, Elaine A.","Elaine","10","192783","Nagahara","A" +"Nambiar, Hirschel M.","Hirschel","10","348030","Nambiar","M" +"Nambiar, Marshall M.","Marshall","10","348028","Nambiar","M" +"Ng, Clarissa M.","Clarissa","10","348340","Ng","M" +"Norton, Guy L.","Guy","10","348763","Norton","L" +"Orsini, Sara M.","Sara","10","195196","Orsini","M" +"Ouart, Julia R.","Julia","10","138988","Ouart","R" +"Pabba, Mani K.","Mani","10","159596","Pabba","K" +"Palmer, Eric G.","Eric","10","349220","Palmer","G" +"Palmer, Macy A.","Macy","10","347493","Palmer","A" +"Parikh, Esha A.","Esha","10","345622","Parikh","A" +"Patil, Vaibhav V.","Vaibhav","10","126042","Patil","V" +"Pavlick, Julia J.","Julia","10","345915","Pavlick","J" +"Peek, Madison G.","Madison","10","476863","Peek","G" +"Pelzman, Jacob D.","Jacob","10","347585","Pelzman","D" +"Pepper, Rachel E.","Rachel","10","453248","Pepper","E" +"Pepperman, Destiny M.","Destiny","10","347063","Pepperman","M" +"Pfeiffer, Andrew M.","Andrew","10","371056","Pfeiffer","M" +"Pham, Emily Y.","Emily","10","344961","Pham","Y" +"Poole, Thomas E.","Thomas","10","325848","Poole","E" +"Portillo-Rivas, Nathaly V.","Nathaly","10","330327","Portillo-Rivas","V" +"Prasada-Rao, Wilhelmina S.","Wilhelmina","10","334199","Prasada-Rao","S" +"Putta, Sanjana ","Sanjana","10","368924","Putta","" +"Quaranta, Marie V.","Marie","10","352725","Quaranta","V" +"Ramazon, Patrick F.","Patrick","10","347551","Ramazon","F" +"Ramirez, Taylor R.","Taylor","10","361786","Ramirez","R" +"Ransom, Alison F.","Alison","10","436739","Ransom","F" +"Reed, Faith M.","Faith","10","204594","Reed","M" +"Reyes, Rachel ","Rachel","10","346225","Reyes","" +"Richman, Jessica B.","Jessica","10","348446","Richman","B" +"Ringling, Brennah E.","Brennah","10","372512","Ringling","E" +"Rivas, Franco G.","Franco","10","349175","Rivas","G" +"Robin, Rachel E.","Rachel","10","348447","Robin","E" +"Rodriguez, Patrick L.","Patrick","10","348450","Rodriguez","L" +"Rondeau, Olivia M.","Olivia","10","373073","Rondeau","M" +"Roque, Jose J.","Jose","10","352726","Roque","J" +"Rowe, Katrina M.","Katrina","10","371194","Rowe","M" +"Ryan, Finn L.","Finn","10","156768","Ryan","L" +"Ryan, Rachel G.","Rachel","10","355862","Ryan","G" +"Santorocco, Giavanna R.","Giavanna","10","464593","Santorocco","R" +"Satsangi, Nandini M.","Nandini","10","349382","Satsangi","M" +"Scott, Kile A.","Kile","10","347900","Scott","A" +"Seely, Cade M.","Cade","10","353112","Seely","M" +"Selvadurai, Varshini ","Varshini","10","369393","Selvadurai","" +"Sena, Alessandra G.","Alessandra","10","349540","Sena","G" +"Shanbhag, Sayaka K.","Sayaka","10","348471","Shanbhag","K" +"Shastri, Ishana A.","Ishana","10","353851","Shastri","A" +"Sier, Brandon M.","Brandon","10","353006","Sier","M" +"Simms, Asian J.","Asian","10","369495","Simms","J" +"Singh, Shriya ","Shriya","10","345433","Singh","" +"Sinha, Sahil ","Sahil","10","347308","Sinha","" +"Sofelkanik, Nikolas W.","Nikolas","10","348767","Sofelkanik","W" +"Soriano, Beverly K.","Beverly","10","338835","Soriano","K" +"Spano, Nicholas A.","Nicholas","10","331885","Spano","A" +"Ssentongo, Racheal ","Racheal","10","349094","Ssentongo","" +"Starost, Joshua E.","Joshua","10","349276","Starost","E" +"Stevens-Donati, Kyle M.","Kyle","10","349280","Stevens-Donati","M" +"Stewart, Samantha E.","Samantha","10","349259","Stewart","E" +"Suggs, Adrian I.","Adrian","10","340793","Suggs","I" +"Summers, Brandon T.","Brandon","10","346769","Summers","T" +"Sun, Andy W.","Andy","10","479034","Sun","W" +"Sundaram, Sivani ","Sivani","10","347576","Sundaram","" +"Suzich, Michael J.","Michael","10","342673","Suzich","J" +"Tabaa, Danny M.","Danny","10","353541","Tabaa","M" +"Tammera, Sri Lahari ","Sri Lahari","10","123438","Tammera","" +"Tang, Grace W.","Grace","10","342696","Tang","W" +"Tang, Nina ","Nina","10","348496","Tang","" +"Taylor, Brandon E.","Brandon","10","347109","Taylor","E" +"Tejada, Zed Mikhail S.","Zed Mikhail","10","322144","Tejada","S" +"Terragno, Kalie A.","Kalie","10","348771","Terragno","A" +"Thirukkonda, Ashwini ","Ashwini","10","349898","Thirukkonda","" +"Thomas, Samantha F.","Samantha","10","348772","Thomas","F" +"Tiren, Joshua N.","Joshua","10","357200","Tiren","N" +"Tkach, Oksana N.","Oksana","10","332367","Tkach","N" +"Tom, Jalen H.","Jalen","10","349153","Tom","H" +"Treleven, Cathryn A.","Cathryn","10","349490","Treleven","A" +"Trone, Clark E.","Clark","10","357176","Trone","E" +"Trujillo-Duenas, Stephanie ","Stephanie","10","355286","Trujillo-Duenas","" +"Turbyfill, Justin C.","Justin","10","304293","Turbyfill","C" +"Van Wert, Kasey W.","Kasey","10","355369","Van Wert","W" +"Vellala, Sourabh S.","Sourabh","10","437372","Vellala","S" +"Ventura, Tiara S.","Tiara","10","353182","Ventura","S" +"Vidas, Justin A.","Justin","10","373412","Vidas","A" +"Villajuan, Joseph B.","Joseph","10","459692","Villajuan","B" +"Wade, Timothy D.","Timothy","10","348773","Wade","D" +"Walton, Cutler J.","Cutler","10","203348","Walton","J" +"Wang, Angela J.","Angela","10","346786","Wang","J" +"Wang, Autumn X.","Autumn","10","346790","Wang","X" +"Wasilik, John P.","John","10","353000","Wasilik","P" +"Wheeler, Mollie R.","Mollie","10","352946","Wheeler","R" +"Wilbur, Thomas B.","Thomas","10","343013","Wilbur","B" +"Wilson, Clare P.","Clare","10","346798","Wilson","P" +"Wilson, Gregory W.","Gregory","10","167495","Wilson","W" +"Winstead, Briona A.","Briona","10","348774","Winstead","A" +"Xu, April R.","April","10","409338","Xu","R" +"Xu, Kenneth X.","Kenneth","10","360428","Xu","X" +"Yamson, Vince Jay Marnell O.","Vince Jay Marnell","10","179131","Yamson","O" +"Yang, Kaitlyn Y.","Kaitlyn","10","349312","Yang","Y" +"Yee, Kristen R.","Kristen","10","347816","Yee","R" +"Yih, Timothy ","Timothy","10","348863","Yih","" +"Yim, Ashley J.","Ashley","10","375405","Yim","J" +"Zapata, Begonia L.","Begonia","10","331349","Zapata","L" +"Zhang, Melody Y.","Melody","10","346803","Zhang","Y" +"Zheng, Grace C.","Grace","10","350221","Zheng","C" +"Zheng, Michelle X.","Michelle","10","346824","Zheng","X" +"Zhong, Eric ","Eric","10","346808","Zhong","" +"Zhou, Samuel J.","Samuel","10","338416","Zhou","J" +"Zhu, Amy Y.","Amy","10","411591","Zhu","Y" +"Zou, David ","David","10","349769","Zou","" +"Zou, Dylan Y.","Dylan","10","346085","Zou","Y" +"Abbey, Bian ","Bian","11","322507","Abbey","" +"Acquaye, Nicole A.","Nicole","11","345932","Acquaye","A" +"Adah, Alex J.","Alex","11","350429","Adah","J" +"Ainsworth, Dewontay L.","Dewontay","11","440893","Ainsworth","L" +"Allentuck, Jordan N.","Jordan","11","324849","Allentuck","N" +"Andrade, Christian M.","Christian","11","993196","Andrade","M" +"Archampong, Victoria N.","Victoria","11","380266","Archampong","N" +"Arias, Diana M.","Diana","11","309386","Arias","M" +"Austin, Christian T.","Christian","11","377046","Austin","T" +"Awono, Camille I.","Camille","11","322757","Awono","I" +"Babbar, Anav ","Anav","11","328663","Babbar","" +"Bagalkotkar, Sapna P.","Sapna","11","326086","Bagalkotkar","P" +"Ballmann, Dorothy M.","Dorothy","11","332990","Ballmann","M" +"Bang, Joon ","Joon","11","326090","Bang","" +"Barbosa, Andres R.","Andres","11","327677","Barbosa","R" +"Barillas Chacon, Alondra G.","Alondra","11","338209","Barillas Chacon","G" +"Barry, Peter A.","Peter","11","327567","Barry","A" +"Basehore, Michael J.","Michael","11","425001","Basehore","J" +"Beaulieu, Alexander J.","Alexander","11","325482","Beaulieu","J" +"Beltran, Stefanie V.","Stefanie","11","323807","Beltran","V" +"Berenzweig, Adam J.","Adam","11","996465","Berenzweig","J" +"Bhut, Yogi N.","Yogi","11","325592","Bhut","N" +"Bliss, Morgan K.","Morgan","11","324856","Bliss","K" +"Bonhomme, Jacob C.","Jacob","11","354581","Bonhomme","C" +"Boyle, Eleanor H.","Eleanor","11","147027","Boyle","H" +"Branton, Luc J.","Luc","11","424991","Branton","J" +"Brenholtz, Quinlan C.","Quinlan","11","330231","Brenholtz","C" +"Briancon, Aidan S.","Aidan","11","324861","Briancon","S" +"Bricker, Jr., Daniel J.","Daniel","11","990311","Bricker, Jr.","J" +"Brill, Charles R.","Charles","11","327080","Brill","R" +"Broadhurst, Kadin J.","Kadin","11","360839","Broadhurst","J" +"Brooks, Jared E.","Jared","11","326261","Brooks","E" +"Bush, Hannah C.","Hannah","11","330232","Bush","C" +"Byrd, Taylor R.","Taylor","11","322289","Byrd","R" +"Caballero, Lydia B.","Lydia","11","357142","Caballero","B" +"Cahill, Madison W.","Madison","11","350034","Cahill","W" +"Campbell, Cassandra R.","Cassandra","11","335294","Campbell","R" +"Capobianchi, Gabriella A.","Gabriella","11","322461","Capobianchi","A" +"Carin, Rebecca D.","Rebecca","11","325362","Carin","D" +"Carney, Killian K.","Killian","11","322349","Carney","K" +"Carpentier, Emma C.","Emma","11","322608","Carpentier","C" +"Casay, Marisa N.","Marisa","11","327712","Casay","N" +"Castillo-Grynberg, Adan ","Adan","11","323240","Castillo-Grynberg","" +"Chari, Rohan R.","Rohan","11","350445","Chari","R" +"Chari, Rohit R.","Rohit","11","350448","Chari","R" +"Chatterjee, Anshul ","Anshul","11","301794","Chatterjee","" +"Chen, Cindy X.","Cindy","11","423399","Chen","X" +"Chen, George ","George","11","314700","Chen","" +"Chernosky, Ryan A.","Ryan","11","327203","Chernosky","A" +"Cherubet, Nadjah Y.","Nadjah","11","318541","Cherubet","Y" +"Chintala, Navya R.","Navya","11","169829","Chintala","R" +"Chintala, Rohith S.","Rohith","11","169833","Chintala","S" +"Choi, Alexander W.","Alexander","11","123766","Choi","W" +"Chung, Stephen A.","Stephen","11","329668","Chung","A" +"Convers, Matthew J.","Matthew","11","316760","Convers","J" +"Copeland, Paris S.","Paris","11","319648","Copeland","S" +"Corapcioglu, Darren Y.","Darren","11","328186","Corapcioglu","Y" +"Courbois, Caroline A.","Caroline","11","325781","Courbois","A" +"Cubert, Noah J.","Noah","11","996703","Cubert","J" +"Dahlin, Kellie S.","Kellie","11","982046","Dahlin","S" +"Dice, Cassidy L.","Cassidy","11","334922","Dice","L" +"Dice, Lillian C.","Lillian","11","334919","Dice","C" +"Dollar, Theresa M.","Theresa","11","326306","Dollar","M" +"Dominici, Perry C.","Perry","11","306296","Dominici","C" +"Dou, Zachary D.","Zachary","11","328706","Dou","D" +"Draghici, Jonathan M.","Jonathan","11","325789","Draghici","M" +"Drain, Dylan S.","Dylan","11","161815","Drain","S" +"Duran, Nicole A.","Nicole","11","987619","Duran","A" +"Durmowicz, Madeline N.","Madeline","11","325791","Durmowicz","N" +"Dutton, James R.","James","11","330238","Dutton","R" +"Elkoshairi, Youssef W.","Youssef","11","144126","Elkoshairi","W" +"Evans, Elise F.","Elise","11","430947","Evans","F" +"Falls, Richard Z.","Richard","11","334272","Falls","Z" +"Fang, Steven ","Steven","11","319116","Fang","" +"Fein, Derek C.","Derek","11","321643","Fein","C" +"Fernandes, Loren R.","Loren","11","465713","Fernandes","R" +"Fessenden, Stefan E.","Stefan","11","463730","Fessenden","E" +"Field, William J.","William","11","997418","Field","J" +"Fisanich, Tabitha J.","Tabitha","11","325626","Fisanich","J" +"Fitzgerald, Sean P.","Sean","11","316549","Fitzgerald","P" +"Fogam, Edlia K.","Edlia","11","354119","Fogam","K" +"Foster Jr, Alexander T.","Alexander","11","302479","Foster Jr","T" +"Fream, Mitchell R.","Mitchell","11","328714","Fream","R" +"Fry, Carter H.","Carter","11","326604","Fry","H" +"Fuhrmann, Christian B.","Christian","11","328716","Fuhrmann","B" +"Furr, Athena C.","Athena","11","323189","Furr","C" +"Gana, Nahbuma F.","Nahbuma","11","325569","Gana","F" +"Gangineni, Sai A.","Sai","11","340689","Gangineni","A" +"Gao, Catherine X.","Catherine","11","353998","Gao","X" +"Garrett, Samuel S.","Samuel","11","437670","Garrett","S" +"Getahun, Caleb Z.","Caleb","11","327375","Getahun","Z" +"Gherman, Benjamin M.","Benjamin","11","301387","Gherman","M" +"Glinsmann, Matthew J.","Matthew","11","305596","Glinsmann","J" +"Graham, Paul C.","Paul","11","454380","Graham","C" +"Green, Erin K.","Erin","11","325745","Green","K" +"Green, Justin W.","Justin","11","327453","Green","W" +"Groman, Alexander W.","Alexander","11","326264","Groman","W" +"Gruber, Victoria A.","Victoria","11","993198","Gruber","A" +"Gupta, Kshitij ","Kshitij","11","326607","Gupta","" +"Gupta, Shefali ","Shefali","11","337161","Gupta","" +"Guthrie, Erica L.","Erica","11","328410","Guthrie","L" +"Guzman, Gianmarco M.","Gianmarco","11","327749","Guzman","M" +"Haddaway, Ryan A.","Ryan","11","318219","Haddaway","A" +"Hamm, Brooke M.","Brooke","11","336663","Hamm","M" +"Hammett, Bridgette M.","Bridgette","11","324972","Hammett","M" +"Harkins, Haley E.","Haley","11","464978","Harkins","E" +"Harris, Adey A.","Adey","11","170086","Harris","A" +"Hawkins, Jessica G.","Jessica","11","334913","Hawkins","G" +"Headley, Benedict E.","Benedict","11","322447","Headley","E" +"Hendricks, Michael R.","Michael","11","306218","Hendricks","R" +"Heron, Marcus A.","Marcus","11","457303","Heron","A" +"Herron, Mark R.","Mark","11","327804","Herron","R" +"Hill, Mathew F.","Mathew","11","330243","Hill","F" +"Hill, JR, Keith A.","Keith","11","310796","Hill, JR","A" +"Hinds, Ethan J.","Ethan","11","333994","Hinds","J" +"Hobbs, Julia E.","Julia","11","177350","Hobbs","E" +"Homsi, Rami M.","Rami","11","333457","Homsi","M" +"Hong, Sung Yun ","Sung Yun","11","309595","Hong","" +"Hsu, Jason S.","Jason","11","326233","Hsu","S" +"Huang, Robert B.","Robert","11","323175","Huang","B" +"Huynh, Dylan N.","Dylan","11","451221","Huynh","N" +"In, Esther ","Esther","11","374967","In","" +"Insalaco, Chloe C.","Chloe","11","323372","Insalaco","C" +"Ismail, Feras ","Feras","11","325074","Ismail","" +"Iyer, Sarayu P.","Sarayu","11","336870","Iyer","P" +"Jackson, Clara A.","Clara","11","330245","Jackson","A" +"Jackson, James D.","James","11","981993","Jackson","D" +"Jackson, Tania L.","Tania","11","320055","Jackson","L" +"Jacobs, Brian D.","Brian","11","329170","Jacobs","D" +"Jaiman, Aman ","Aman","11","323685","Jaiman","" +"Jain, Ritvik P.","Ritvik","11","455374","Jain","P" +"Jang, Jennifer Y.","Jennifer","11","409436","Jang","Y" +"Jaramillo, Juanita ","Juanita","11","322458","Jaramillo","" +"Johnson, Andrea N.","Andrea","11","328090","Johnson","N" +"Johnston, Ryan B.","Ryan","11","330247","Johnston","B" +"Kabir, Mubrook ","Mubrook","11","328651","Kabir","" +"Kalra, Anjali S.","Anjali","11","326029","Kalra","S" +"Kang, Dahye ","Dahye","11","329080","Kang","" +"Kasten, Ryan J.","Ryan","11","416210","Kasten","J" +"Kasuske, Isaac W.","Isaac","11","156440","Kasuske","W" +"Katti, Divya M.","Divya","11","355235","Katti","M" +"Kayo, Shany-Jo T.","Shany-Jo","11","309643","Kayo","T" +"Keranahalli, Pooja B.","Pooja","11","319117","Keranahalli","B" +"Kim, Caius A.","Caius","11","323750","Kim","A" +"Kim, Na Hye ","Na Hye","11","311520","Kim","" +"Kim, Stephanie S.","Stephanie","11","327348","Kim","S" +"Kinzie, Raymond H.","Raymond","11","319552","Kinzie","H" +"Kong, Joyce J.","Joyce","11","327495","Kong","J" +"Kovich, Yaniv R.","Yaniv","11","325078","Kovich","R" +"Krasche, Jackson E.","Jackson","11","376519","Krasche","E" +"Lavanderos, Estephan E.","Estephan","11","977297","Lavanderos","E" +"Lechner, Katarina T.","Katarina","11","370665","Lechner","T" +"Lee, Carol T.","Carol","11","418300","Lee","T" +"Lee, Daniel D.","Daniel","11","333179","Lee","D" +"Lee, Kelliann R.","Kelliann","11","370017","Lee","R" +"Lehrman, Stephanie A.","Stephanie","11","175217","Lehrman","A" +"Leibrand, Hannah N.","Hannah","11","330237","Leibrand","N" +"Li, William J.","William","11","326279","Li","J" +"Lin, Ching-Yuan A.","Ching-Yuan","11","325361","Lin","A" +"Lockett, Ryan C.","Ryan","11","330249","Lockett","C" +"Lu, Amy H.","Amy","11","337260","Lu","H" +"Lyons, Erin R.","Erin","11","415874","Lyons","R" +"Lyons, Sean M.","Sean","11","415881","Lyons","M" +"Ma, Joyce I.","Joyce","11","326079","Ma","I" +"Macairan, Rachel Alexandra E.","Rachel Alexandra","11","321102","Macairan","E" +"Magaha, Maddison J.","Maddison","11","330251","Magaha","J" +"Mallow, Charlotte Z.","Charlotte","11","321675","Mallow","Z" +"Mandere, Glenn G.","Glenn","11","430056","Mandere","G" +"Manickavel, Sangavi R.","Sangavi","11","344981","Manickavel","R" +"Manoharan, Shashidhar S.","Shashidhar","11","329166","Manoharan","S" +"Marshall, Darrell R.","Darrell","11","375499","Marshall","R" +"Marshall, Jacob A.","Jacob","11","325093","Marshall","A" +"Mason, Dylan M.","Dylan","11","453044","Mason","M" +"Mathews, Thomas R.","Thomas","11","433207","Mathews","R" +"Mayer, Anna I.","Anna","11","325162","Mayer","I" +"McCutcheon, Brynn E.","Brynn","11","332605","McCutcheon","E" +"McFall, Trevor D.","Trevor","11","322979","McFall","D" +"McMahan, Brendan W.","Brendan","11","332548","McMahan","W" +"Metz, Colin P.","Colin","11","318342","Metz","P" +"Miller, Daniel J.","Daniel","11","176019","Miller","J" +"Miller, Maureen J.","Maureen","11","322710","Miller","J" +"Modjarrad, Alessia A.","Alessia","11","327158","Modjarrad","A" +"Molyneaux, NIcholas R.","NIcholas","11","170548","Molyneaux","R" +"Moraa, Michelle H.","Michelle","11","430059","Moraa","H" +"Morningstar, Tyler G.","Tyler","11","304551","Morningstar","G" +"Morrison, Anna R.","Anna","11","355350","Morrison","R" +"Morrow, Katheryn R.","Katheryn","11","331039","Morrow","R" +"Mozolin, Alexei M.","Alexei","11","180431","Mozolin","M" +"Mullett, Mackenzie K.","Mackenzie","11","326417","Mullett","K" +"Murthy, Chandan E.","Chandan","11","356447","Murthy","E" +"Nachod, Zachary J.","Zachary","11","415543","Nachod","J" +"Narendra, Amogh ","Amogh","11","998271","Narendra","" +"Naumov, Victoria ","Victoria","11","332090","Naumov","" +"Neidhart, Kevin D.","Kevin","11","331529","Neidhart","D" +"Oberman, Connell D.","Connell","11","177343","Oberman","D" +"Oden, Sara V.","Sara","11","313690","Oden","V" +"Oram, Thomas B.","Thomas","11","992043","Oram","B" +"Ouart, Jeremy L.","Jeremy","11","139000","Ouart","L" +"Oza, Parth R.","Parth","11","328991","Oza","R" +"Paksima, Amirah N.","Amirah","11","161168","Paksima","N" +"Pandalai, Bhuvana S.","Bhuvana","11","347366","Pandalai","S" +"Parise, Elizabeth H.","Elizabeth","11","325748","Parise","H" +"Park, Colin ","Colin","11","183083","Park","" +"Park, Justin S.","Justin","11","324971","Park","S" +"Parker, Stephanie E.","Stephanie","11","326638","Parker","E" +"Paul, Jhasper G.","Jhasper","11","327515","Paul","G" +"Pavelle, Jessica T.","Jessica","11","349010","Pavelle","T" +"Pearre, Brady A.","Brady","11","409423","Pearre","A" +"Peck, Kira E.","Kira","11","356056","Peck","E" +"Phelps, Maria J.","Maria","11","329031","Phelps","J" +"Powell, Rani O.","Rani","11","310348","Powell","O" +"Prebilic, Gavin F.","Gavin","11","985471","Prebilic","F" +"Prem, Jagan R.","Jagan","11","370149","Prem","R" +"Qian, Eric S.","Eric","11","323123","Qian","S" +"Quaranta, Renee G.","Renee","11","330253","Quaranta","G" +"Queen, Robert A.","Robert","11","352948","Queen","A" +"Raghu, Apurva K.","Apurva","11","336015","Raghu","K" +"Rakheja, Rhea ","Rhea","11","327046","Rakheja","" +"Rauschenberg, Carson G.","Carson","11","167548","Rauschenberg","G" +"Reyazuddin, Michelle F.","Michelle","11","332939","Reyazuddin","F" +"Rich, Julia E.","Julia","11","325823","Rich","E" +"Rosenberg, Samuel K.","Samuel","11","372290","Rosenberg","K" +"Roy, Tyler J.","Tyler","11","327139","Roy","J" +"Royal, James M.","James","11","325094","Royal","M" +"Saar, Logan M.","Logan","11","327362","Saar","M" +"Sabas, Hayden A.","Hayden","11","317905","Sabas","A" +"Sabett, Michael T.","Michael","11","354220","Sabett","T" +"Sartschev, John T.","John","11","325248","Sartschev","T" +"Schmidt, Susanna B.","Susanna","11","330254","Schmidt","B" +"Selvadoss, Andrew S.","Andrew","11","318633","Selvadoss","S" +"Sesetty, Vaishnavi S.","Vaishnavi","11","349754","Sesetty","S" +"Sheehi, Anthony J.","Anthony","11","343999","Sheehi","J" +"Shen, Kevin ","Kevin","11","327672","Shen","" +"Sherman, Molly E.","Molly","11","330255","Sherman","E" +"Shields, Brigit E.","Brigit","11","353561","Shields","E" +"Siegrist, Robert M.","Robert","11","330256","Siegrist","M" +"Simonson, Kelly P.","Kelly","11","329455","Simonson","P" +"Sivarajan, Arjun R.","Arjun","11","327799","Sivarajan","R" +"Skanchy, Sophie K.","Sophie","11","324212","Skanchy","K" +"Slebodnik, Nicole A.","Nicole","11","323088","Slebodnik","A" +"Solans, Paige E.","Paige","11","157270","Solans","E" +"Solomon, Azlyn C.","Azlyn","11","334658","Solomon","C" +"Song, Kevin ","Kevin","11","329090","Song","" +"Speck-McMorris, Liam Gareth M.","Liam Gareth","11","330257","Speck-McMorris","M" +"Srikanth, Sriya ","Sriya","11","326256","Srikanth","" +"Staszewski, Melanie Y.","Melanie","11","325256","Staszewski","Y" +"Stoughton, Jennifer T.","Jennifer","11","326339","Stoughton","T" +"Stroud, Lucas A.","Lucas","11","334201","Stroud","A" +"Su, Kevin L.","Kevin","11","323261","Su","L" +"Szafranski, Jr., Paul J.","Paul","11","319368","Szafranski, Jr.","J" +"Taggart, Ethan S.","Ethan","11","364884","Taggart","S" +"Tash, Jonah N.","Jonah","11","326469","Tash","N" +"Tatum, Megan R.","Megan","11","325941","Tatum","R" +"Taylor, Bryce R.","Bryce","11","327102","Taylor","R" +"Tetlow, Alivia G.","Alivia","11","963062","Tetlow","G" +"Thomas, Colin C.","Colin","11","323346","Thomas","C" +"Thompson, John J.","John","11","325251","Thompson","J" +"Thompson, Madeleine C.","Madeleine","11","325249","Thompson","C" +"Thota, Ishwarya ","Ishwarya","11","320324","Thota","" +"Ting, John ","John","11","329104","Ting","" +"Todd, Nina N.","Nina","11","329106","Todd","N" +"Torres, Ester Pauline L.","Ester Pauline","11","310596","Torres","L" +"Trent, Dillon M.","Dillon","11","330261","Trent","M" +"Tripu, Deepika R.","Deepika","11","326082","Tripu","R" +"Truland, Danielle H.","Danielle","11","328128","Truland","H" +"Tuzmen, Deniz Z.","Deniz","11","327036","Tuzmen","Z" +"Tyler, Jackson L.","Jackson","11","325270","Tyler","L" +"Umansky, David S.","David","11","409792","Umansky","S" +"Urban, Michael J.","Michael","11","326008","Urban","J" +"Van Houten, Kathleen R.","Kathleen","11","411234","Van Houten","R" +"Vangara, Sreya ","Sreya","11","326702","Vangara","" +"Villajuan, Jirah B.","Jirah","11","459691","Villajuan","B" +"Vincent, Jorin T.","Jorin","11","352848","Vincent","T" +"Vinh, Ryan B.","Ryan","11","327173","Vinh","B" +"Vogel, Donald E.","Donald","11","405213","Vogel","E" +"Volkle, Cassandra N.","Cassandra","11","140526","Volkle","N" +"Walker, Alice E.","Alice","11","326679","Walker","E" +"Walker, Zachary J.","Zachary","11","326680","Walker","J" +"Wallace, Triana D.","Triana","11","325796","Wallace","D" +"Walter, Christian H.","Christian","11","322910","Walter","H" +"Wang, Alan M.","Alan","11","343778","Wang","M" +"Wang, Andy ","Andy","11","327774","Wang","" +"Wang, Julia X.","Julia","11","356457","Wang","X" +"Wang, Patrick ","Patrick","11","329128","Wang","" +"Wang, Philip Z.","Philip","11","979875","Wang","Z" +"Wathen, Kira N.","Kira","11","325272","Wathen","N" +"Webber, Dalton P.","Dalton","11","146453","Webber","P" +"Welch, Zoe J.","Zoe","11","372094","Welch","J" +"Whelan, Tobias D.","Tobias","11","326476","Whelan","D" +"Whitney-Blum, Avery D.","Avery","11","344222","Whitney-Blum","D" +"Widenhofer, Zachary A.","Zachary","11","344130","Widenhofer","A" +"Wiese, Jannika ","Jannika","11","230058","Wiese","" +"Williams, Amelia A.","Amelia","11","310569","Williams","A" +"Willis, Rachel A.","Rachel","11","337090","Willis","A" +"Wilson, Jack M.","Jack","11","997019","Wilson","M" +"Wolitzky, Gage A.","Gage","11","306662","Wolitzky","A" +"Wrona, Thomas D.","Thomas","11","326687","Wrona","D" +"Wu, Iris L.","Iris","11","328575","Wu","L" +"Xiao, Manchun ","Manchun","11","455139","Xiao","" +"Ya, Alvin L.","Alvin","11","349890","Ya","L" +"Yan, Tracy Z.","Tracy","11","329603","Yan","Z" +"Yavasani, Amit K.","Amit","11","325836","Yavasani","K" +"Yendluri, Avanish C.","Avanish","11","333679","Yendluri","C" +"Yerger, Roger W.","Roger","11","332136","Yerger","W" +"Young, Breanna M.","Breanna","11","375473","Young","M" +"Yu, Iris ","Iris","11","333810","Yu","" +"Zeranski, Zachary B.","Zachary","11","171182","Zeranski","B" +"Zic, Sophia M.","Sophia","11","326015","Zic","M" +"Zinn, Travis A.","Travis","11","329182","Zinn","A" +"Zou, Claude Y.","Claude","11","328019","Zou","Y" +"Agrawal, Neil C.","Neil","12","302444","Agrawal","C" +"Agrawal, Nina ","Nina","12","963542","Agrawal","" +"Ahrens, John F.","John","12","306422","Ahrens","F" +"Alfaro, Keila M.","Keila","12","987912","Alfaro","M" +"Andres, Catherine J.","Catherine","12","155860","Andres","J" +"Arabia, Samuel L.","Samuel","12","447433","Arabia","L" +"Arango Baquero, Simon ","Simon","12","462484","Arango Baquero","" +"Atkins, Antonnia J.","Antonnia","12","977045","Atkins","J" +"Azamati, Delali H.","Delali","12","303747","Azamati","H" +"Baigal, Arona ","Arona","12","308469","Baigal","" +"Ballew, Daniel W.","Daniel","12","982184","Ballew","W" +"Bamfo, Tyrone K.","Tyrone","12","306806","Bamfo","K" +"Beautz, John P.","John","12","307323","Beautz","P" +"Belski, Jordan A.","Jordan","12","331354","Belski","A" +"Benitez, Katherine J.","Katherine","12","307313","Benitez","J" +"Bentz, Emma N.","Emma","12","304107","Bentz","N" +"Bernard-Coogan, Rory S.","Rory","12","305932","Bernard-Coogan","S" +"Bhagwat, Aden A.","Aden","12","371971","Bhagwat","A" +"Bharmal, Zoya H.","Zoya","12","331191","Bharmal","H" +"Bhaskaran, Aadya ","Aadya","12","304483","Bhaskaran","" +"Bhattacharyya, Jessica ","Jessica","12","305581","Bhattacharyya","" +"Bleich, Jessica W.","Jessica","12","302462","Bleich","W" +"Boby, Kevin P.","Kevin","12","304985","Boby","P" +"Bong, Seung Kyoon ","Seung Kyoon","12","992124","Bong","" +"Boocks, Heather L.","Heather","12","332502","Boocks","L" +"Bourque, Courtney S.","Courtney","12","307553","Bourque","S" +"Brady, Kellie V.","Kellie","12","304871","Brady","V" +"Brashear, Joseph O.","Joseph","12","306255","Brashear","O" +"Budd, Keyon T.","Keyon","12","966129","Budd","T" +"Budd, Patrick J.","Patrick","12","306257","Budd","J" +"Burnett, Filip G.","Filip","12","311924","Burnett","G" +"Carmack, Coleman K.","Coleman","12","319668","Carmack","K" +"Carr, Alona M.","Alona","12","343523","Carr","M" +"Caruso-DiPaolo, Josephine F.","Josephine","12","314833","Caruso-DiPaolo","F" +"Cecco, Delaney I.","Delaney","12","409319","Cecco","I" +"Chawla, Karanbir S.","Karanbir","12","312341","Chawla","S" +"Chen, Chris M.","Chris","12","319279","Chen","M" +"Chen, Chuan ","Chuan","12","308698","Chen","" +"Chen, Eamon Z.","Eamon","12","364491","Chen","Z" +"Cheng, Raymond ","Raymond","12","992716","Cheng","" +"Cherian, Amelia A.","Amelia","12","305034","Cherian","A" +"Chilla, Michael J.","Michael","12","305260","Chilla","J" +"Cho, Daniel ","Daniel","12","309023","Cho","" +"Cho, Kathleen M.","Kathleen","12","304051","Cho","M" +"Choudhry, Skindar M.","Skindar","12","163574","Choudhry","M" +"Christensen, Kathryn K.","Kathryn","12","965240","Christensen","K" +"Colby, Derek A.","Derek","12","304143","Colby","A" +"Collins, Michael I.","Michael","12","318912","Collins","I" +"Corral, Ava M.","Ava","12","305262","Corral","M" +"Cowger, Kylie M.","Kylie","12","200297","Cowger","M" +"Creedon, Danielle E.","Danielle","12","306288","Creedon","E" +"Creedon, Kathryn J.","Kathryn","12","306289","Creedon","J" +"Cross, Kenydi J.","Kenydi","12","335394","Cross","J" +"Danna, Christopher F.","Christopher","12","304265","Danna","F" +"Deitz, Robert S.","Robert","12","966560","Deitz","S" +"Dinh, Alyssa M.","Alyssa","12","316106","Dinh","M" +"Dixit, Anusha ","Anusha","12","362021","Dixit","" +"Donovan, James F.","James","12","307262","Donovan","F" +"Dorn, Yannick D.","Yannick","12","165011","Dorn","D" +"Drain, Aja S.","Aja","12","162035","Drain","S" +"Drissel, Jacob W.","Jacob","12","306417","Drissel","W" +"Dunathan, Conner R.","Conner","12","304440","Dunathan","R" +"Durkin, Olivia R.","Olivia","12","306579","Durkin","R" +"Dwyer, Michela G.","Michela","12","312560","Dwyer","G" +"Edwards, Alexus N.","Alexus","12","331050","Edwards","N" +"Enriquez, Shane J.","Shane","12","306672","Enriquez","J" +"Er, Sertac ","Sertac","12","991851","Er","" +"Esser, David M.","David","12","474465","Esser","M" +"Falls, Isabelle G.","Isabelle","12","334273","Falls","G" +"Fatima, Jabeen ","Jabeen","12","304916","Fatima","" +"Feng, Matthew R.","Matthew","12","305429","Feng","R" +"Fernandez, Gabriel T.","Gabriel","12","470158","Fernandez","T" +"Fernandez, Nicolas D.","Nicolas","12","470157","Fernandez","D" +"Field, Danielle N.","Danielle","12","310151","Field","N" +"Fisher, Colin T.","Colin","12","991284","Fisher","T" +"Fisher, Julia N.","Julia","12","320877","Fisher","N" +"Fisher, Kaley N.","Kaley","12","320878","Fisher","N" +"Forrester, Jr., Corland D.","Corland","12","368130","Forrester, Jr.","D" +"Frendlich, Dylan A.","Dylan","12","438266","Frendlich","A" +"Fruth, Kyle M.","Kyle","12","304270","Fruth","M" +"Gandla, Divya M.","Divya","12","992695","Gandla","M" +"Ganesh, Harini ","Harini","12","334295","Ganesh","" +"Gao, Henry J.","Henry","12","461266","Gao","J" +"Geisler, Shane S.","Shane","12","303411","Geisler","S" +"Giffin, Addison M.","Addison","12","306006","Giffin","M" +"Gnanaravi, Gilda F.","Gilda","12","310181","Gnanaravi","F" +"Goldberg, Anastasia L.","Anastasia","12","304569","Goldberg","L" +"Goldsborough, Samantha C.","Samantha","12","306412","Goldsborough","C" +"Gordon, Alicia N.","Alicia","12","380252","Gordon","N" +"Greene, Kahlil J.","Kahlil","12","325469","Greene","J" +"Greer, John E.","John","12","304457","Greer","E" +"Grenier, Winston E.","Winston","12","154667","Grenier","E" +"Grimsby, Dakota J.","Dakota","12","131844","Grimsby","J" +"Gross, Mackenzie A.","Mackenzie","12","323195","Gross","A" +"Gross, Michael S.","Michael","12","302166","Gross","S" +"Grubb, Megan E.","Megan","12","306324","Grubb","E" +"Hall, Melissa J.","Melissa","12","306325","Hall","J" +"Hall, Nathan T.","Nathan","12","306327","Hall","T" +"Hanscom, Lucas R.","Lucas","12","983211","Hanscom","R" +"Harney, Morgan A.","Morgan","12","995073","Harney","A" +"Harris, Baharu N.","Baharu","12","155715","Harris","N" +"Harris, Granville T.","Granville","12","306765","Harris","T" +"Heemskerk, William H.","William","12","147217","Heemskerk","H" +"Heimbach, Katherine M.","Katherine","12","306329","Heimbach","M" +"Hemingway, Keegan R.","Keegan","12","305275","Hemingway","R" +"Hepburn, Kristen M.","Kristen","12","306368","Hepburn","M" +"Hernandez, Julian A.","Julian","12","361916","Hernandez","A" +"Himmelfarb, Sara W.","Sara","12","306374","Himmelfarb","W" +"Hong, Sara J.","Sara","12","330111","Hong","J" +"Hoover, Samantha M.","Samantha","12","154668","Hoover","M" +"Hough, Jake P.","Jake","12","958363","Hough","P" +"Howson, Sachi N.","Sachi","12","303725","Howson","N" +"Hu, Kevin ","Kevin","12","308708","Hu","" +"Huber, Alison K.","Alison","12","306376","Huber","K" +"Huff, Jr., Michael A.","Michael","12","311037","Huff, Jr.","A" +"Huntley, Steven R.","Steven","12","306779","Huntley","R" +"Jackson, Taneka M.","Taneka","12","303442","Jackson","M" +"Jagodits, Theodore B.","Theodore","12","172172","Jagodits","B" +"Jensen, Claire E.","Claire","12","457138","Jensen","E" +"Jin, Benjamin W.","Benjamin","12","350015","Jin","W" +"Johns, Emily G.","Emily","12","329411","Johns","G" +"Johnson, Sabrina ","Sabrina","12","310514","Johnson","" +"Jones, Christian M.","Christian","12","310312","Jones","M" +"Kane, Zubin A.","Zubin","12","315935","Kane","A" +"Kaplan, Benjamin D.","Benjamin","12","306790","Kaplan","D" +"Kaur, Meher ","Meher","12","333456","Kaur","" +"Khalil, Hailey N.","Hailey","12","306377","Khalil","N" +"Khanna, Shreya ","Shreya","12","375192","Khanna","" +"Khare, Mitushi ","Mitushi","12","319387","Khare","" +"Kilian, Nicholas J.","Nicholas","12","190433","Kilian","J" +"Kim, Dennis T.","Dennis","12","303582","Kim","T" +"Kim, Justin B.","Justin","12","310521","Kim","B" +"Kim, Seungmin ","Seungmin","12","369110","Kim","" +"King, Amelia F.","Amelia","12","305276","King","F" +"Kinzie, Calvin E.","Calvin","12","306379","Kinzie","E" +"Klimkiewicz, James A.","James","12","138982","Klimkiewicz","A" +"Kline, Rebekah L.","Rebekah","12","305321","Kline","L" +"Kocur, Brandon E.","Brandon","12","306380","Kocur","E" +"Kollipara, Parameshwar S.","Parameshwar","12","313850","Kollipara","S" +"Kovich, Micael R.","Micael","12","308325","Kovich","R" +"Krishnan, Kartik S.","Kartik","12","141145","Krishnan","S" +"Krishnan, Uma S.","Uma","12","141147","Krishnan","S" +"Kwon, Nathan Y.","Nathan","12","977504","Kwon","Y" +"Lang, Stephen E.","Stephen","12","307799","Lang","E" +"Larkin, Aaron A.","Aaron","12","306383","Larkin","A" +"Lawbaugh, Isabella M.","Isabella","12","300971","Lawbaugh","M" +"Lee, Matthew J.","Matthew","12","313915","Lee","J" +"Lee, Samuel G.","Samuel","12","303732","Lee","G" +"Leng, Caroline P.","Caroline","12","349909","Leng","P" +"Lent, Andrew M.","Andrew","12","310915","Lent","M" +"Li, Vincent ","Vincent","12","996291","Li","" +"Love, Asya J.","Asya","12","301580","Love","J" +"Madhu, Shraeya P.","Shraeya","12","340715","Madhu","P" +"Mahshigian, Anthony D.","Anthony","12","308694","Mahshigian","D" +"Maier, Kimora W.","Kimora","12","307266","Maier","W" +"Malinin, Lev V.","Lev","12","315251","Malinin","V" +"Malmgren, Jackson C.","Jackson","12","330114","Malmgren","C" +"Mamba, Lindelwa S.","Lindelwa","12","312038","Mamba","S" +"Manakkunnel, Kevin S.","Kevin","12","307165","Manakkunnel","S" +"Manjunath, Thanushree ","Thanushree","12","992458","Manjunath","" +"Marsh, Gabrielle A.","Gabrielle","12","313873","Marsh","A" +"Martinis, Coleman P.","Coleman","12","335253","Martinis","P" +"Mason, Jacob P.","Jacob","12","306423","Mason","P" +"Mathew, Nidhi E.","Nidhi","12","319624","Mathew","E" +"Mayenkar, Sahil ","Sahil","12","992447","Mayenkar","" +"Mazzanti, Anna M.","Anna","12","305008","Mazzanti","M" +"McCoy, Sean D.","Sean","12","304887","McCoy","D" +"McDonald, Michael D.","Michael","12","334949","McDonald","D" +"McElroy, Jessica L.","Jessica","12","304125","McElroy","L" +"McIntyre, Timothy I.","Timothy","12","306396","McIntyre","I" +"McKenney, Cole M.","Cole","12","301604","McKenney","M" +"McMichael, Andrew C.","Andrew","12","301728","McMichael","C" +"Melton, Jason R.","Jason","12","986725","Melton","R" +"Mense, Sophia A.","Sophia","12","301684","Mense","A" +"Merrell, Kevin L.","Kevin","12","306606","Merrell","L" +"Milby, Kaelyn M.","Kaelyn","12","451465","Milby","M" +"Miller, Connor H.","Connor","12","306433","Miller","H" +"Miller, Madeline E.","Madeline","12","154700","Miller","E" +"Mohammed, Azeem S.","Azeem","12","415826","Mohammed","S" +"Molina, Alessandra ","Alessandra","12","438428","Molina","" +"Montone, Julia E.","Julia","12","302340","Montone","E" +"Morgan, Michael J.","Michael","12","306435","Morgan","J" +"Mullikin, Samantha A.","Samantha","12","306439","Mullikin","A" +"Mundra, Ishan S.","Ishan","12","307378","Mundra","S" +"Myers-Mallinger, Cooper T.","Cooper","12","304362","Myers-Mallinger","T" +"Nardone, Theresa J.","Theresa","12","992878","Nardone","J" +"Nichols, Alison M.","Alison","12","154672","Nichols","M" +"Nichols, Nelson A.","Nelson","12","307273","Nichols","A" +"Ning, Florence C.","Florence","12","310959","Ning","C" +"Niu, Wally L.","Wally","12","307922","Niu","L" +"Nocket, Parker Q.","Parker","12","335867","Nocket","Q" +"O'Donnell, Alexander L.","Alexander","12","302502","O'Donnell","L" +"Oliver, Sean G.","Sean","12","336622","Oliver","G" +"Pach, Victoria L.","Victoria","12","302233","Pach","L" +"Pak, Alexis Y.","Alexis","12","437406","Pak","Y" +"Papagjika, Daniel H.","Daniel","12","992170","Papagjika","H" +"Pappas, Michael S.","Michael","12","307280","Pappas","S" +"Patgiri, Anusha ","Anusha","12","305123","Patgiri","" +"Paul, Hunter C.","Hunter","12","972018","Paul","C" +"Paul, Trevor C.","Trevor","12","972019","Paul","C" +"Paul, Viraj ","Viraj","12","307015","Paul","" +"Pavlick, Samuel V.","Samuel","12","305856","Pavlick","V" +"Payne, Michael J.","Michael","12","334941","Payne","J" +"Peng, Bo ","Bo","12","458399","Peng","" +"Peyton, Madison L.","Madison","12","308195","Peyton","L" +"Portillo, Natali E.","Natali","12","991285","Portillo","E" +"Pringle, Nicholas J.","Nicholas","12","304667","Pringle","J" +"Qian, Rachel S.","Rachel","12","310994","Qian","S" +"Quito, Shirley ","Shirley","12","988419","Quito","" +"Rahman, Kashif ","Kashif","12","441720","Rahman","" +"Raman, Daven L.","Daven","12","205550","Raman","L" +"Randall, Jr., Ray F.","Ray","12","969688","Randall, Jr.","F" +"Reed, Elaine K.","Elaine","12","364001","Reed","K" +"Ren, Glenn Y.","Glenn","12","306669","Ren","Y" +"Riegert, Thomas H.","Thomas","12","314827","Riegert","H" +"Riggs, Siann J.","Siann","12","988421","Riggs","J" +"Roberts, Elizabeth M.","Elizabeth","12","328612","Roberts","M" +"Rogers, Natalie A.","Natalie","12","137136","Rogers","A" +"Romano, Olivia G.","Olivia","12","463744","Romano","G" +"Romero, Maristela Louisse C.","Maristela Louisse","12","354284","Romero","C" +"Ross, Tucker W.","Tucker","12","981341","Ross","W" +"Ryan, Liam J.","Liam","12","347712","Ryan","J" +"Ryan, Shay C.","Shay","12","156812","Ryan","C" +"Satsangi, Yamuna E.","Yamuna","12","306233","Satsangi","E" +"Saud, Pahola V.","Pahola","12","322980","Saud","V" +"Savage, Catherine T.","Catherine","12","307287","Savage","T" +"Schneider, Cole H.","Cole","12","984333","Schneider","H" +"Sebastian, Ria C.","Ria","12","333360","Sebastian","C" +"Shah, Harshal A.","Harshal","12","318774","Shah","A" +"Shao, David ","David","12","463317","Shao","" +"Shorb, Emily C.","Emily","12","311012","Shorb","C" +"Smedira, Devin T.","Devin","12","311202","Smedira","T" +"Smith, Austin M.","Austin","12","306444","Smith","M" +"Sobrino, Carlos A.","Carlos","12","457202","Sobrino","A" +"Somaiya, Yash ","Yash","12","479687","Somaiya","" +"Stanoyevitch, William V.","William","12","336578","Stanoyevitch","V" +"Stephens, Seori ","Seori","12","375451","Stephens","" +"Sun, Hannah M.","Hannah","12","159058","Sun","M" +"Terrell, Luke R.","Luke","12","995075","Terrell","R" +"Thaivalappil, Jeeva R.","Jeeva","12","996244","Thaivalappil","R" +"Thaivalappil, Soorya S.","Soorya","12","329197","Thaivalappil","S" +"Thota, Praneeth K.","Praneeth","12","320242","Thota","K" +"Tievy, Jacob A.","Jacob","12","306472","Tievy","A" +"Tisaranni, Jordan V.","Jordan","12","305689","Tisaranni","V" +"Trainor, Rebeckah I.","Rebeckah","12","306474","Trainor","I" +"Truppo, Brian J.","Brian","12","306476","Truppo","J" +"Turbyfill, Joshua A.","Joshua","12","311747","Turbyfill","A" +"Urban, Sophia I.","Sophia","12","306876","Urban","I" +"Valenta III, Thomas M.","Thomas","12","996824","Valenta III","M" +"Victoria, Emma F.","Emma","12","412735","Victoria","F" +"Wallace, Rebecca L.","Rebecca","12","306490","Wallace","L" +"Walter, Wilson I.","Wilson","12","330985","Walter","I" +"Wang, Crystal Y.","Crystal","12","311231","Wang","Y" +"Wang, Lucy ","Lucy","12","996281","Wang","" +"Wang, Lydia ","Lydia","12","331830","Wang","" +"Wang, Richard K.","Richard","12","307677","Wang","K" +"Wasilik, Carmela N.","Carmela","12","307291","Wasilik","N" +"Welch, Emma K.","Emma","12","140704","Welch","K" +"Whitehouse, Emma T.","Emma","12","375478","Whitehouse","T" +"Whitehouse, Marc A.","Marc","12","375482","Whitehouse","A" +"Wilburn, James R.","James","12","441536","Wilburn","R" +"Williams, Charles L.","Charles","12","307937","Williams","L" +"Williams, Cole J.","Cole","12","301500","Williams","J" +"Windall, Megan C.","Megan","12","306660","Windall","C" +"Wink, Michael H.","Michael","12","473646","Wink","H" +"Winston, Allison A.","Allison","12","305643","Winston","A" +"Wolin, Camden M.","Camden","12","306661","Wolin","M" +"Wu, Fanny ","Fanny","12","311240","Wu","" +"Xu, Dao-Jun ","Dao-Jun","12","304764","Xu","" +"Yang, Fiona Y.","Fiona","12","307909","Yang","Y" +"Yang, Sheng Po ","Sheng Po","12","308335","Yang","" +"Yin, Emily L.","Emily","12","450372","Yin","L" +"Yin, Jessica ","Jessica","12","992415","Yin","" +"Zhang, Christina E.","Christina","12","410139","Zhang","E" +"Zhang, Christine Y.","Christine","12","411592","Zhang","Y" +"Zhang, Eric Y.","Eric","12","305697","Zhang","Y" +"Zhang, Jacy L.","Jacy","12","306521","Zhang","L" +"Zhao, Karl ","Karl","12","439493","Zhao","" +"Zhou, Huile ","Huile","12","333612","Zhou","" +"Zong, Kevin ","Kevin","12","305236","Zong","" diff --git a/src/data/settings.config b/src/data/settings.config new file mode 100644 index 0000000..733e530 --- /dev/null +++ b/src/data/settings.config @@ -0,0 +1,2 @@ +ffa94595ea45cf16c6a8c1bc7952b65e +pf5dg73jmhk7i4oopc5jer6dju \ No newline at end of file diff --git a/src/img/gifCheckmark.gif b/src/img/gifCheckmark.gif new file mode 100644 index 0000000000000000000000000000000000000000..c76d52198233e2f31a4a5aa6136ab2d2159dbf71 GIT binary patch literal 20794 zcmc$_2UwHM)-Ie1N$3zdXegog4uaApG=U&ZK)Qf}2#A2?4ZR~J^cH$oKtMpyP^I_Y zq<4@eBDSA*mv8U$o$osPKWBgE|C8%V@=Ru)S!?Eg)|$2Eo|_m=IeFW=04ur8@yqYsrb@-TLR=?{ z?~W1JTK$-bPc-}EvBPOmpPE$rUM8;)2ac8tHhRWS)_rGRzuq3M*cxm4=gRkrB2RlaWQq%8Q6g%gRd03ZW###HB^WBt<2~ge4>u zq{I}YBv5~QabEW3>ENVbq^|k5zAmqnIGw${JrqPmpFDXY@i-)(%LwD4lceJ&8_}E*C^HS2ks^I3Kr}rN> zcJ~tbi$Wsy58Xt4Z9PQAMZ`qi-2T+-FSWhAjU4|W#(!Dc%h=DuQPjxM>)~Thd&kS_ zTz_wTId=c+j{dB8DUHG{PnXL{v3;Qa(EhQTqq{doU5WGZ9}x!^2L(AhdpmhY8F^tR zM;S?BM+qqhVOzV)OIar=c_}G5c{xcZhri$FziKb7E}@WJ0vVBq}F z`=OWfLl2ai+FxcJ#b@f`?(p!57yqBr^jEFb9X(xq933=0AG)FbGR_Jv|Ah>avUZM= zGU9f^k`i{d!qW0ma>BOqvbMr9u{$6y6&p&_u z$AfWs@gI+tqxFzNPtHQ)9#1`nuXTHPuzGUsYC= zmz9QX($i8?l9TX>3Gs0+V`HMDA|t}XLPLUs0t0Y=ym##kdmgIoG~x;okzt(%$} z>T0Sg$~UenDPB{Mmy?x|mbyfVn5c-bke~oRA1@D@n~ReJb@d868!HPl6C(pXl8%;! znu?NwoD2bnk&-|mU=R=h;P?iCA^^q!p+C*wpB@1~8jdp#3@+aO^-}AQl@G z8XUy_Pc{CbR^0!$Y7Ge-{F7Q;0>6IE{(1!Neobf%g3$?BHi%IFLydn3`TPHpkip`d zWGta9WSrt7oQyOeN})g@N)Qbr=Li`MH5kl*Ml+mJ(~ym@fWSqtV1UXJ9tdjC@S+|j zv;!%Ns;icUbD`d2+Q&mBI+q6fr>(p1wym1~Y zv+Ap_oO?S2y2Rvv%8-EtQMFT*x&xIAzAh3+?hi`|CNOQtrJIJ0su@p^5S_M&Ss?p5=rap5UvcmW3Prgn17x&i7LOt6VsdE#Ah5*g;+0#DR7KJ249&zGfE{%!~Po0RA9M01m3x;qm2 z5=fzTf<07P`khoIipsLG&fh}^<~|Da+Ln;MR=7W1<22&GzH3-f^P280k2Ko^|LyYb zI3BB}NgiXn>xl@Sr&A?j=~0hdH@*oL>U9NE--`H_w%S`BUf?f;@i&DBBk1nxBOlpy zMiKSr$-0M5IB^%}G*Z*$^Nrr5#|jsRB8!R}%~dX|$>O83q|04aPbZ%z(75`KmERqD z-}3$I;c8#btq<>iem_6i{WSF9!{tJcgl`E4VQ?m(0{&w5{%S$~fw6yo1_^9jSIAh3 zSjet$vAyP^WT&EHMCG9vN7*U4USDAc!l6)lMgk-K3LMCO@3qVOks>lnr&jO(b2cE|Z4u?urhGirxi
)1UX(`2 zKLBvA+e+jvi2)M8+h;9%S3!9VaBtwQ%5My1gK79?UruX@!Ov8p0Vn|yw?RMtB_E`U z&~jzhEfMN!4BWG0>uZP$%9e)?2+7&Ft*iaP3j*N8feS-n$P#sf)J5Cz$m95N_&XZh zB$gUbvcKh{ve3-zmaTQIfn(ysBPwZqKJV6%!Zd8F?o+vzrC44O#$Z3hdM}Fy<1;0# zM~-w)^BFy_#}k(tu5z&MTo*O7NXVvI{z0F-_El}>`8b)$hA`)%`a3zOnQ>$RFG@sX zncIv@bAgi?<0}uk`>ftfcH~an{8z(Ad?T`*<_V`?&2(RTpN^X1sl($je3;<)+sS-# z@tRc-2QC#-bg;P^`Kx1nMdjI`mm1fV&rV(nF5#^D^ z)=9{VP8}^Q-AI2>zrB&+(Z#=+={@PPndQ4tx|#j#Y+%C3e*KBr_ASoL$DKc6crS76IckGqa8XwPt8`sM!h-#9nM3+cP7ABi>`u? zu<+hI(D?*^fzf#eCjlAm_NywyRm`L9y&*a26~JSgC1gm^C`CsDf8GsP*#QNl0kcE| zZWukUlIslSp%dD!l-PbrRMSS4#CWgMT!k_xI~Y`T$KUP@fD5%I@|E9fhT%D>3pMCI zkziPb5(*qu?==I_s3dCUmqcL|ROpJ%g|mwy;@)p~CfBNPOD6D;r9p= z$?W!6IbWD#sbiR#bTT_=8DLsHnW6w;Y6!QPr`})+p3o|Rg(T4@n^?yYP2c&0E;{&qoNH1N9S2$w7_)v60pNRFV<35o# zi1Th`!$#TetLC$v-Pc4C!M&;uhWmTfh5s#>O%_C>rCzk#=Ts#d;KRis29tfP8#?Gdbf9e5W9RROk$uj^uJru7fK4bgShd$F* z(4IoG4o*QO2<6w=ybnJM5L8R_my5km*%Iuu+?7kHpv7h=M~>AJKPXptWSsaS-wUW3 z4iRs7mp>57_^g-j5ZU<MuJCRYxIy zzT}Xbv3AtpF~q^C@Hi5JZj8wq{Gqq!C z!mM;5`F%2uaJRY9#>E_3!Y~1-0a{8kP*)2D$@5Ss!ks-{!2Kn*$A$TMiHc9r%N;RK z!|rc=J=biY*}wi826-@3TUjIO&>)jHk-ABhkg5BEbM(Y&l7%zFMJn6AP`vG~{Kgj( z8;Q8o30ByPMvF!_0R(6IA#zsaWt7(8;yQDfp- zs*OezR!&pnrB(!=Oz3;j*l8=rNrX_<@%}qRes+Tp3Mi9LIZJvYH@ZnXr26+G%P> zZ|d5#7o1|%xMM@$YICE$xNPUPc9D-YZM*oeP`fE%)Z0G-+kE&3`UMNT+}pRSdX#bdzn`pCV-*G zGZL}5_#(4dED-}7#G*gCu^iD&kjAg_Ip?81=hxt;X>GJ^jM#M_q?QIFbHMwKOiz>9lZ8bhpd&T1YdVACuL|?udf0dhizt|MpWNq6 zv|eG5g*+o@8wfh7;t5KJS+u!Qt}d!8a*U}G*eDrz!GJc%EfgM2G{z)o=FNxeC9=WS z@O)Z5Z-~53c3Rq+XXHc`UYjmHL<0JXu`&NGnV>oJ9~S0(=!-3=4x!s7p-rRe5I%#B zxPrYZwAVn_CuiLT%14`Ckt{KTVcryScWRy7vQLuO>K1O?OHg&^&*X|mS7iEU3e_%c z{1KWy;pd;`ns9~;QM;myLec89Wb%2r;fZU zntZS~k!rlIb0oZbnhHN%M?#zn1duFaD-&C`Db|fCwy|_cj3-!{Ihu3ETBB%M=k2*MM(4N0ZN87!l5+ov%rVM8`N-si}0Bit|mW(} zWlc2f1Qs4mvUIc-RnIJQoCC*-ts4Kl zLQuiu9eXv-VWZU^*k>_V3O)L)&ezc1)kDoIKQ!+?rz`BV?7FwV8IUys!Iw?ZbAo>u z_KG4SF5pSQY#m9o9Jimg%WAyAR((h-HOXBl;g0{(WLzbXSa+xCI{G_dd!qARFX3Gf zfpUGqOJD@p7C}cn-}l)&5Ew-F-EZ{MA3%52oag7;rUdk!UhdUr8^U}&ur&=Ws6VZ0 zTb6K$!=aTgGbd-3=r)b2wJ<}dTsTR$o;aOXyJE2&$@>7UaF6#M$+l5^0uolyv>@eF zVLrY<&;w|!Q`GP1@Iz-E*DjZh=-3G7r3_)}aDbJ=vf|3JWpZf|w@b7<1B=ZxY_dD9 zooQpr>ZH3KCcLdX%y?%&9$d&}f1x@hV|TeSHFv38*EaF8O(>RBP8!`5vo$fIzy9<^ z0@5{Iai>o<4nSh$eT7u>q&|Zq#aWf^)VXL%N|af)VA-Ofoq*GUBEHtOhkA_ zse5o-I^MEuQ~jouooWpkM=-pq-6PWYX3EmoR_?i3V40|#+Z)$XyinYrTv%4(VAji} zE%NGhCfi?4<0BwPB3y>=Xz_W}bJ+WX!Fk zq*S085b4K2(peDIWIywpWL8EBQsJc~L{rPupQ?|k{CU=tt$g4y>;Y&{`n7E(U!v(qxb zfdcrkJPa-T=DGqcj=A*0G${e!2ks$={#0&Xd0#z8HI3f*)3Ln!-0mZ4O3xm zdF9rm-wi%@S*ECirkA1}T}@?L=Yf5Gq`rq4r;8&6@iz>zpKDunI6ilsTQkAA?ZU|M zQ-kcj9;+Yeqi-qw5gE`vlvYR~o8iC(G-6ugx%)>dN7c+jW?x<=&teWD%ISCfp#@;) zF)fv)_O=g)6LcP$8~oNmITs3z?q&l;2%qWmQkhW$9H$$#IKl7bsdIw`4%(HY6w;?G z01Q7)B7Q^Zm6cWE%i@Xl_xKcSSisztBxoqLv5g8Jf*XfRHlU2d0oVCU(e!-?)v!DV=qKOu!&xk9%q4;ducdhLy&QAezH(<2f{txRN|9N^Fyt&C&+= z2R^ym3Xv@z7x+TRC~^kEphX%!3%@FbdFZ? zqMwl+_^PkCY{-0SnA!GOXe2|BUR7+OirU%PvXNO?!6-*4UH=lGmhHR*e6cjE-S(Tn zm2e*j-kue7Y=28w3Lwb|=YE}|x^u?~B*5rW)cAbG_!tDdar-`Dx+z?Fkc*SBSz-Mg zVAR9q>mdOUsNq)zK$p@VwUVhO4HMA!KiS2r|DZSz1BV*K4lCC4DG zfNVL_!y|C&O6pQpNvk@_WHGX<(KsK0+gb3q67B)o$iNc<=Dos9_hf-mzkJsysCTU< z1MeHO@zw+xoGvex!unV6)*(?ERDvDEZgH{1v|~->an1F?YOr z(b8wG6*XBtNsrUCB3fkkPde3yL>Zj!nBwzrRi~yxKpWJ{pN0%?)JFtdTD486%O)yy z3(F0iU6TxsjdxU~%UJXz?v%1X^ZGR_dz28#k>fLk*KK)iw&9@>IyVWpnJ(1;%(KX* z6y%NKS{)}{{al-bMC6&c^vIZ9z7SPPGbEB_p#-ouPcw`w=(=z147jPCzT7DY}7@Nr|lNoiVZrHlu zaAg#?m3SmzdC`vg(mKBac%<~6;{|TFvrH+Iveh)I-?^~Oh-@nsdD5dp{>?Li=7)yV z5v#84U?Nk2kmi+`9#X@LNB9DvLjG1Dg?2?CedRRdQ6wFiIa_(QPl2N_9stnfu8EJe zbmcZuiO@D%NeCdS^GH?0G0L>mS%(F+ac%%t-dw5|4(gb2vu_>yUl^r3yabhqYxM^AFOgh3Z>5f{q6y~JT}IqFZ(|y)3YE27RtEg< zuO1W0$g*A^>-8+I$BbfSUzf*j?J!Jxj^Zs z@uEn@bKu534VM$D+^l7btPIpOpkb1ImgAl7hUCgwIiRX8homN- zq`o4T0pLZ{jpW{C_7^&CqdIaXhjZ47Le z7&Yt>-yIP0jz1QD$%3Dc!@rA^9^b6It*k`~3%uqr91jlJV3V?}1#-TNh?q2Q4zC^# zcVQhc-{pfry5l%8f#G2Z>@A^!cP^ebe$LkoOe7U!A<{Yu`E>G`|%zluviswXf&vUOW+>JSn!Eel=rsi zi(tvS6G91@s?XOp|O>yAk&g0RNt=9q3WQ*RO0)$8WXk5R0 zlPBWrD(0(g(p5~5bMWow;WdxFx(oasC@g>{C&TlLDqp=UElqu0TNjv9jfK=VS8_L&a<{Z+600dX zdg8kpdj})v`m5=NCW0778yO}iW{C5Hi(N|{uoWU~tr@u41>C7+-|uHXe04I)b5_`J zPJH)WPUGZbv;|R@8s-$_VPFIeSrm|Z)&aXukt-m)>NaAt5-WSj044=An_H! zo{JTsymwZxeqsf>e{k=+HDiXknj;nI?YO^+@u^45)3VfcSIrU&87KsHNhdgow#Q|? z6>s$gho02+`>m%POqi8aR%L}WRgR6->HIEq3ViBA8+O-w2=UZAz}5P-DNXK0MoN6{ z`(QX}k%Zi%6$l$d+UE!3F{%T&5!pV z28Qdqx~$&6qy1IU!tS}GpiWelhmDP!qmp~XZq-Ps-q&vUEi;v4pkyHuX4;UtS#U|Y^D-?U@WTa z>XXuDFz;W~gn-}}LIG81givvu7aOM?n@Uees+PwI^*y`LUlp(j@Oc9h#(nXSC!dRI zgLXM4BHWAhWuI2!)wp8uH!SgS(LC%|6NI`ruO`OoGO*y|muk3^BC1ZglMVHI(A;e5 z^|w&}!ihm3f5!|Qi-rFcGs(%9PAoqsC%?EP4qBKDEqz@TNK=tRQ~kD}wy2>w9o&=y zZfTE8BIaDC7sEbQ^bG|K)DHK37%glYZ{eP*?U}6xEi{3as#l2{ueUz#6i@Ee&KzWx z9}!=jrZasVV7f@;K278Sq6)y^*X&}`S}JYs2&OB&haQ$B5y1dsby5HqJ(6`MHx4FI zpcTZT*R`wlGOzb3p&b)GL$1{=F_G2NTgd zuOL4z&`Zh&HmyEzs+}ma`xYuOA7si{(|D}aJp?~wlDSlFyl}rN{)_E%HTURGO+U>_ z!PBCV3iGrBb!nN(@~Q{dR_mH-c1`ipcQ??dUL%f5g5Z$QH%IzzlF&J+O{0gpPxx1B z#!Zj+v_co^UZkWd?f67b#9M#WLN^UvaMxH|t=xIF(ip;8Q`eE_WU_0)r9+^Cg0d8MAj)4k3j8lcj z#tK&}jhsE_*t{HuU%|gqBrRUoPn?>1!JD>gpO>(%!v$-xfzCwto!E>a5G@9xUj4S3KAb8|j3N zzlTrt!DkzQ3nRd#D$wc_XrqL5dx3P1fcU(MI8LMN{W1cfJWn)WT9O?EAaHTI%3RZK zICyZ(bs>l8LvV*08IM7QtZl1?DzohI?s>enRy>!Is-+DDS_L9-l;w?yD`-xWy5BW^ zreZ%BLnq{lJ*O*FbLHbg4^p7hJ@=`PX!JHX`bKyrj6)#!YUsxH7i_glFt}-+}kyRT{G5#*1 zX`VR0JhBt%8r94+Z|s~gW${$sU+_&$vo=-6uE23+JK>@zQi%VcXgvJY_1>|2n}j_N znR@0=N_H2rFTaNP8NR>s1NQAJJx*{&c1a(N!A}BIlhnigjjA_oI6xT3;o$HsEdB-) zkLu7Z%g5p2K75aOIXUekf)^qp)IU-`7LsXWyD`+c75-wC@7^j`8xT7m8;d6)_fS?y z7*x~H9~}^Z3UK>jq-f+KdLGnG^Q?2fYV<7Rq5Ik3$j!y4MugpUO;ABIOPM?IL{*qO z{VSvLpV>5tfd9KZTVXe0&Th zXFW?$wk%nCkfR8q7Xdu0C8&UcsEfIst8A9@C`b|N(Pm4;8&P2Z*luHsE}v++9<>VNtAH-p22xqACfQwpt7r8@**IF|9sL16}NyO@HW zgz6Ol0SO9>oTIf_qI7j=0`E9V*q%u&z|)8QO!^Ou8b;##ZmaIk7|Be=w-^R4_$S!R zMwV;1;^@EHAi7ad++K!A03eQ1nePg7;Eo1>sn+2-6A+A#)buVH&hWp3pjW_aci0w^ z^(_ujdeFR~%R2@Q7Jux&9`sawwsGk9l^4xY<2m5%~^ z3zv`@OHW+K*og5AgRTADrl*>y9}N_)0iU$gnBZXVlXT4~^y88xtXs6Q%syF4e=^xu zTwgHetd&$Xq-iS}hyF^F47_C>TQo+gg)_!x#cy}q))qAMW7ahsU?1Er({T#dd8sAJ|qVXBf4OknIK84nCZ@bV&no!z5gCPZs20yg?5 z84nAaoC>4*w6VEJwHm}ovi13}i-d6%e)RPa-a2yra|2xV1FjzCN>K4Cq7*pQjQrFV z)&&TyA+636f1V>^HZK>F&HIE+kmb-=q(I|wrVOo^4UVX(k6@rxre11=0$61L4TmTI zCR(a37bn6qcMYA{4rY| z_BF1txNReV*^^a^ZHNMxRoBhq`@TBQ?q=2f&4YpOp5B9c8aHod(H?nq-Q>7Y{KLrJ z{kob60ygF$51eB+o{}Xqho2PuQX7^tP1pnC% z|Bt{;(m}JaRI;$4OKOZ+Dae8FMtUHSz7Y;2r(k_UU;tzPWRdoR89LK|1LG6pz>!4g zvJ`SN>ray-lm~dDG2EfwLsT!QQ zYL46n?9a3w*_Psvk_>EUj{J}Ozg4Yi-dr_f_n3o6`2|sw2v1TbtU@k zr+7KoTN#d7h$mc5cNAC6x?!GPd3#taOH8`FhG;=Xv`QfPJV4B+y&Lo6bZ7omU$3>> zcW#cpa%s`C`8yzX{Myv5N5k7D`cm&lG-KULmNa8+Ue;<3-Y@Cc7Sh~s{ zJ1glVjXyU@k_DZTtC}O7qByDNP@rp~@0iTSkZiXr<%F>*Aeid$JdH4#y_0&bHDF1Y z?&NBVbE%xb-1)c>om9?VN<^f@h=4m_9;3rO4+ zY#Y@v{9VZ5+a)nKhFLP=ynmQH3Us4uiqG_k9yM`!^1RcLf#IQv=X0)g2Zq#n8 zE^lTj?#r0^jU7#xkc~Pxv5vX{QW_2AsJE4o&ual}K#FZCq4D~qk-KhS?E=9^W-R2N zmIA3n2lpECXJ_3v7qcqA=1*1MyP?n`B;7bMYa!W0oj$+ypiuhW>VtukTFiXdZ3eb% zqqTcqIm91Mx*gSYCH#;Xc-C#%rE7cUl0PN7*>W%9kB}??n6Cw7o z;;Gih_k;p`6nX^PhdFn6$%ufU$HnzKJLOef0=pHpldku<|78I6zp}c)0s=*4v20|_ z2vQmvQUo)ZTzNSaHTIIb|ACsSF_($>vHJs4M>+`7Gdv6d_2Ypf)6>9-m$WmVrfKJ+ zNR~E+Nmj$AHurnxb^?(Hr`^b-FWLCGEZkk&zXLI(Ax5l1 z4mL{&lCrtcK5vW%ABc!Qr*qMEs&$$%-mqhiVJW&d4Y1>i<7b_)G)c6TU`W1G@0k3% zKUU|RsQaB4Pk5Dx^sKYGf1V`ympQ00@PHgN$bGwg9hU-bqmwY6-BKF8*jH{wNd9`D zFUDhpd=nEfvQ!`OeAssy9{wx9ez4Ot7H+ zw}>spN&kRfN$n;2E{~5iQB&3CGQDeSZ({mziN21$J_zU|9@sxN1{{7#J3c!`I~55a znOo^2SqvLp-R_v&Fh(JFj@pqMfa9<2Q;72)?>@30lOU@Af*J@D1_XKB&HHy1U~%q+ z*Bo!n<1Xo{LdbjCnE~Kb%HTOoM7E4i`mkX>qc-}DXO5-``1T_fkRhx#Afd4WPzoBi z@$8iuxW`YJS1^3%C$K4{FA@e<>hxmL)*UA}4shFSRF|}6+Zt&O-kGq1Na%t6_K9OU zt-q5goZrT$itCJB^4kyVjqZB=fmX61sb;5-=y+zRnmJU3YI~6;|3WB@_Dy5ru1s<* zF3s?xR>VL8J|Hcm$5=?LPppSSygqh81S^J-5uZ)8q6(sj_*{c5!HSKs_Q;AaC5DJ{ zQTCjP&Bs0_Tm7kZA+ocPNfty|dRjAEx}u!L^8d|ti-+JYFK zYxR7QnDGW@Ov1Y=?#P?8nw+#Z3&sluG?=A**Z3w4!79&VPmAdU0G(XaDhQ_FI92kW zMou@5ELYLle(7Lz&Wf1}WfD$7o>?x$I(!x-%~Pfm8%3+SrDUWjpe6B4!QO@IQP0Uz zQS39DKA9F=WQ0J)pD1NZ{U;0gCv(u^{=XMf;Z^F8`` zYQ4m0*T4V-)Pn~OPD}ttU(!y_PteXpku0nZkSv9bukCbAZw4ZFk2;YD$7h{OMrFhs2H}O<>DO*K!WZwsT6um z>KE1}XIE&jqKPbgK?4e@I|c)m#cqR6>1Eq{ti|_RO;}b7@Mb*@ycw;{#=<$0j)RI$ z;2GT#v{RRn6DuZKxv2c0git5dpW0E2{2jybrdGyn0rO;NJ>-;N9#|X1#sb#lPpJ;U zl}b62yxk&T;P3bs8wiL(33!;IinYtDCC?NzQ)%v z{KA;FWbpdWA9TaY&`$8Ol1EbzI@6@+F?UucH#|1Rm!aL>QTdBYv|#~-XR)F`Lz8aK zFmkp#;7Dp~i>tx=q^}@_uUcF1b;l@sQCbNBR8o-ax>H(GRJK!Aap}YP|1HmLEFe%^ zT2v7&@K4U0t+MhGnwO{U+Ni0TbD7$E``Va3UPANIY(hXoc;NWl9B}$2?fl9d?WZV` z)$K8ojj-9B!~VtnK;+TaKIG|F2ng`>ZLEonTO073y574;|IOzjS&@$GWa3qvEH7l zv(vKo)or;iTqm!k|7?H0&qv3urC<8qbi0ENXAGmSs|{W*{H#gW>*w4Fvz|%lGhuJL zB)%eY`%I-GU5A7<(h;ZRA4!>k(es7TF85nxLnL2_2QA5hj2<&cx{iz`iy=)omCa7$ z>Y~k4y(eO$(#+_i{XP<8`*l3@g6st)%DON{GVEhW$y<*kR>ai5sq4jsU(yY@qq9$$ z`i=6)8*lRoZ}UasiT&KY82(BrZ7r@O2(2uO?Pz>jrTX|)H3t81Lj{Dm11e+aaFt3K zM1$nTPdh{m5v=Rm*9i*JKHPaaAX4u9aU^^`H|PMCi5gKxL`$cLa4st``Rs&?t|GZy z(emRcGU3Z$sIT;%ibaz53IZj#HW(amTK>Ky0rdOHoPlJdMQJ zsgX%_P{To+R0Y#)b?5Ima|xNHeN>S9CIhQ;igs{$(iOmgPA8L?c4PP#?q_4BX#4Ll zY^j);kz-qzyRL;t$?uAZ8g+o=-xn|zJ@iA&1 z>#gRQHT7g~>~-fW%B*<-@v+48oW$&Kf0^Ad)b}DwOQRL*sP8h1P!2JlJE4Nl#dz3+ zKU+IRP3%WKDJ`r&!+b2X(A|}QA><3EpZBgILfjMV;j z9C!4e(M{+-Be1;e>ZOIeJef?q3~vYkrq-TbB2(w3iR>F4g@6X}z_Hm`;M7anx#d~f z#VC@Mtx=Nou$k@8eG7Ym$Zaq+`6WU0k}pb5O;V6Ac8d+@7YkA+GZnD}>A;y3=0Xn> z-nn$v(jOWt&k4NDRZd6`#UVk_`8&c-%>-5?0&_)p%C)qe#L_bhmMi!v#^oJ_q8fGU zU(v}qqFb_zHAOaS0&mIA{E)t7(5%-dW3peeXFgtLoNV4+d&py^f-R=*KK=6Gj&}F& z1gO$A{7m6n_jeXX^=Cr4HAEpLgZekF7It`l^vQiK=3s4Km4GVcv|}K1G^gwe;em2# zPZF~tZ7O+60W=m9P&5xnSg|4FaWvqu7~h$VW8&)*!vxfT>jecb1D_cWOlM+UvToyc z0m%nm4FjKm#*m#P5xyu?)sTWhH7H&MboQVh{bKw=iX+}9!1?|v}5YG$CJxo!@~BH zbnnuDx@<$DtV(9M9zi7;%^v?8?YCkM{KCmCaA7np?UL&p0l4N=pzABglRr_ZXjzwv zvA}L=rDEmvjSIMMq7%oZb&1LPu1Dy1Dl?<`Tz{QoGV)3wcz%apphQ0I zwBS*#r!P2-_*ovE7V{%r@-`wH&N`Znx{mvS!|=r)SC zQ+v#k3qnuUL$ZrlcFczhSahY?C1_WRWhXCSqATS2yXaR$&PxkAez;rxmt<(a%>VPmV?ol_fu$a(NyBoI7*86VBj;pyh45fcJ7Wd;=Hr1vw2#mk{_%pe0; zdRFhp{yThbWIFPabrnpdPdZ2lWjFV%`9hk{CU$P>TJuJ>t8;S6lN&eKLf$`KyFHkA z)2ma+9WhI3KcL6=Sn0t{^om$Y$_t4?&MyhLWGoat0Hqikv@$29>5GU+B~}^3uGDcq z5Vo-U_*;ku8O$=Wp}x1C{$h(r4aAVzJV{_r3+A>X z<%|r7pNA^mxC9Qi^7V&e}^`5u8J4xeDorIpG z?w>6R_oV24xc++be7y)x3hz&Wi_06VO!F|PPv)RgZW~RDgt>VFAiNHFW+GIYE2b~Z zX(Uqv+r4p2w^7$6810_qnquyN-b?FR{@V96F>^fv;Y<&0B~5rtmFOoOt&%3V#BN)8 z&eR$0%XN|&`%!QqWi&feF-am9TK)L+`3^Gkk!OWEw?yf&%UT#7V{)tF+6FRwCJsrL zj*bDfX%>d3Ir53Q@gtH=B0U$ybbVIV;x=n=(xnYlMoxRkGvXT3c*H!7 z=%~0(rzMl}ccR<*WUP}FVu9Btp(SMl9_EatRU4kJR=wj*eUiK)Ap26Ov)OLp`E$-a zbb0Nuwh-XTUlF`tJ8p9S&#dUv|886Se~@X~fIyjmwB$f0=+MTWDW^}+_82O}vwVUm zYaj`p1=TG>$qLuwuDTr+N*q&l?kI?83VT3b8<{WSBLo$`%J0Laain%OG#=ytQOkvd zikSvE@F=10r|mlS>aWMHbIXjGHt8?M2C(rSr^xAd!?x%;ju?ycT8b!DWyWc13b7d% zu4h<53D?xJGyjsu2I@9Ozr~Z>u9+r?+t|z*(Oh#(o3fYwf@t#FGqP$55&ZV!wz3CD z0MS=-g?>gnxAQ&9SmDQZP{0s@X33(%k0xw1Q!(h5P!mnfNIU~u)HUrdJCiZv`sQN% z?bTg%rf)(AV8?$3T5Kn*y*|z>(Febb#I|t;hJ!b54O7E+128nPO8Y|dL>~<14-J6m z6=R>1`H`!4M0*sfUZpMOtSymC zqB>||!dcA5bYqdoQ>GMM9w*0TZiUr`CC$d>#4(qSxtwgN%q^Cg6BRlfw-a`xi>K4s zIi2VHe4eNO;eEc(`+mO9^KlN01{(^4xnX{#mDlQ(4q+L}Ik*EWs1R4jbnEsJ5a+6K zo6_rNCArX1mZUcYZgQ7{DDmGvvYBn#$Pg#SIsNGh9q^!oEmiISdn91*DlhGotFX-G z%nq^P^laOBZfvpi{YOo0RR4;*CHH6w&grr$ohiEDWf?8xU5U{-nAXg{=kMp73 z0}5zgw%(vxrZ<$)H3$Y+;dC$<9h?;atnMA9z`MbPa|-yVLRbHmzOJHAuFHE5o<|do zRq4tp;Dg9*vW{SxakiJJhiwNGrA}GDU1!lj0WwrZs_nx*AzLFPYiy$mhdhZ#*u$vx zocn=K&yt)DI1D=lN)h)HeG`L8p}*@*(OEckfBfEpj~XtU>_>ZKFS{JlWNOFZh?1<% zoj0rumy}WS=CV1$JjQ2;tmb?C(J{|I1VJg}m0D$Jqis|6?7JTcEmuhKrmZoxf|g42 z(sOJM9(~wdIWjS*}aw>|-^* zesB4Ge6}^7{V%%PdDgXLyMPb;e=x6AUQ~CFusKVT8W0lL?1EF zIa094ARwK~!nvpJuFd0Fo!#l=-V$UEr3bB^I5l2}0#{i^}@e z$56vjO67A;=g-gR$`4dBsD-^{{7P%8b`{!94Vyimw?;?K`^O_)%7^($;pl`B_gIPl zlN`Z;{GkgCwmof|+*>?O%LK-3&+lHMKW>m{55Hiwkxq+Kx5NG2?AHc>;EuGM7|Nw= zfJtGN75AJvk-yP4xtK~B>tK;Ot?d`%eIMllg|LtZ`R$w}Qrm4j9q_Yy#p^X5cfHSQ z&`7A9fHmyf^=|fKR$b~VyG1h}9fSB~V0dygNgMTvjjlYjKzf0jlD9|1qrvF>ur%X0 zh1?SfX8S!dZ+YnPQQyr5LG;lYCLhy@aA6%a4`O=xPYjOq9JA0c%kt?{KS5G+?UPuq z47>xEk767&X($^T(-BBG1lfr*iFRcyt@n~Ka<`=+9h&3$wIKUkmSYn#K2&-FQjwwSS|&G90(q O{(kz09awFncmE4Z^G=cg literal 0 HcmV?d00001 diff --git a/src/img/gifCheckmarkReverse.gif b/src/img/gifCheckmarkReverse.gif new file mode 100644 index 0000000000000000000000000000000000000000..c7b10f7d1f89242a1cdf4280540ed94c786dd7df GIT binary patch literal 20794 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 SQgzVRd+)HPOM`F)25SI`;!aKg literal 0 HcmV?d00001 diff --git a/src/img/image.png b/src/img/image.png new file mode 100644 index 0000000000000000000000000000000000000000..0e12fd7bc7c2727ae4b2aa310ebcd230bb70d2d8 GIT binary patch literal 55223 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 literal 0 HcmV?d00001 diff --git a/src/img/next-button-right.png b/src/img/next-button-right.png new file mode 100644 index 0000000000000000000000000000000000000000..ea211b1e5ccbe7038be79306afeaf216b7477f6f GIT binary patch literal 12416 zcmY*=2{_bU*thxn%S^VJQOZ8{r)*^>%UH4`RQ6=cmaN$|VMaZc3WJbc4`p8}ON9_+ z3K7Y^FBP(tl=VF`J@50qU)R+YXU?2+?(KK~?)#i#&l&5n9OODkM@PqEps#a*jt)Tv ze|L}vz{q~=?{DBAg#QISExL;LJYT`j*6wCj0aiw5Rh)dhq#T`nF1tvDc=>`^babjA zD&R*imjFjxh?l3gze;U_?bE^Er_E{3Gh%8v@$w})AsRm!O2U>Nu3Z>KZwKO zRQ;S?RW9i0{`+66OJ%F-ufq-A6z!3;_NQ11Z8 z5J_);p+AfK?>agz{!V`Gz5(t&-Z<*Ij+cD`1JncssT=+G=g&C<++F|QPTv0iiUkCe zrhX!QQtE{Ce`|xUs!~T)O#Iwkz|Pe5)laI@X8wO;|L&tIP2K$e9OjRtv{4|c`axCc z|J0^_@a!uwYdSiqeghp%vk=6$vC>*$gVgagPZsPU-jE`P^O_%SnJ1k1jqFP}LC;Xn z{~$_1;`m?32dk&fY5q=2&*A)Rb!k*+=W<$Z`Qh|yJD0tGPRuVdeg8%n$yE>A`jPha zd&iISXndaVYQ!U>h#d8O>*Xg5q{pb8zK^^6YGLXox%(;#2OIS!kCP&DYUjr(VgKNW z%?u5-`q$4(w~et%e}7T z@zPR#c~cQ;#oT8Q=I!oU`?;IkbQng5nBWB0>%Jyi*GD$5!cq*vCjNaokQa% zc}c&t)|JEs|G}M5B_%*f_7<4LedREv{%C$ax=RA+!t3D<*GlY3PJLFe`a%8c{BDjp z-*x|-$(dt)b0ycWQWD9mHJL#ySbVO$E-tQkJCY6(A+;I1a0sdwI6HOVU~iQEi`+~h zMT1962O(sG7+J63xyIgo^{j=Jp_E_WW;HEv&_g6W2z&He(Pw2JyA^Y)ZpnJqSqmaZY*fUmbnub5V>~ct zkowVp6%iv^8b3TM6Nw zYUq$1Ki|~a%n>E?TVk-9Q6@qGmkr@hNc}AlN|ngs)kRKN#;`j~(0_&Vhwb-skOzZs z9J_N!QS7BMO(=9qIN^rNvR6+?MnhI}z7m-rZ~b@gZT^Wzzk1zskYkU7b+gd_K!Zwg@|gjRF#cHdH-Z>q6J$e(p6 z<6OVG!l+GnwRYQa|!)@n8 z(<8iGGQnpWsM$S=_-Z6`gv?sGCPYB$pO~Gelr~z(Ftad_HsNWrv_HG)J4hp9HH2j` z=>%?`Lm4-ah;#y5%aR}gJ7|dSoj=>H+`n0!^TI|9=kK$~!PBryIH=$AZuHbIy1w0L z*m*fDhJvWU4$833+VQ(AH|n*&{D5+<1q%C;pVzXtqDG&dNEtnqys80-fRznJYvu5h ze<9M-T6ah3*o|~1nIW0Y9L+I#dqLlO#Dc_YMIEEtNzb!JmBH*&ioQN$r!L@MNf{jZ zzDH08u6qw?HubD$@xA5`5SBTXE%A9>FXDl9Av^i`W&rz@<_nM;lCs2xaenskOgwj7 zbHmH{IbXe}H=K6WwDFPpWJf3Z)BbE?Cq5^2+_lxrI|I3)^c|2gWq$fs%uWMw$|*-P zE?|{R@x2*s(Ueh};ny6nEAU}i)V`(Oq$dJ}PA8Odb8wkq!1=^wq8>Gfox4fwOeaKy zO~^$E5SxR6JX{COu|=AANYr@amySdFp{&N zPk8sHKB}a%(c_A8kQ`Vb-gWKvwoM~`|(9;Yn^)o8$S=;)Y#=p{=AAhPFyI89QWV4Xy zH#lX3CF9bb*Cmq*x$Dv7=fOwHjyImplSd>z-%J(p(wpQa{nB24n`wOzs>fb2!b95g z0?BM^gYBKKGqUJ|QAFHJw=@El?3?sFxckFD%X~=Rl1+!#XSRAWiLgf`v#E@& zB^4=~i|u3{&!Hf-gZd}h__2t$m68ky_zVyW__eh`o+a>)bb=-8foQhVVA%(qjV5jc z4zjYpbm5k|lV15Zb_%l^e>!2LZtj@c7i&Cp&vf^m@!SkJs&rM<|c{d%r>h!SW(L>Lb!)=+~u7Ny*W8FX+EVDC^qG4Suxw(pGxm93_ z*n$$KoY;(=^JU~m8otoTAl^b1ZY3p7-A_bWu?9OYR({!zfv~E-15@lT3ifMjYvu`~ zF;iyJ&jZH zN9FKaWi2ppacem^BMkN>qqz?rgz8X~Q9@?dDna)MnVGI*iZz0pZk0%!^W~@G3RFb= zcKxloIA_McA=R@Y0%MDF3hqQQr}c2n9);GsdO+TpAJ;ta(z`;`L3y;FvZX;H?o>bS zY}By+71b;c0AQeqxgn0&ptzS6C)XE9vlzhMWXC!*x%bCfv<@ENlBcI84)%+f?H}(P zP9dSt$ZNm6e@i$I1YK&h=^-A?zLkQ5oy_F_KFW1eLhyLheyJkLUE zD{tpA?EJiC#;jYca`QM6q%#1I%b1R-RL>WqTKG@t@``V=*sqMG$Ll&UL%&HWmXlA- zB72n)(3A0I49FJ){{C;2U_l@R{UBjh#LNDqkE;OK@$Wo;0?4;9bH1nQo^Vq959IVU zeeRN==?tX&Xpr*HtBBz7If_d=cNJHf#i@G(By;ZV=YZBTlx2-fRHBt1wtCbkbCdRv zR;+aznR{O_h~K2?uhJNd@kZgA@-;dr{h`>`%Y3`Xd4Vn}x&40vxZYMVl>cGi5Wb-X zbV(f_IchpT?xj@n&>onOcQ}>k>1LKrsBC*YMC=&4^w~A&T9FNFou&|$>~xo- z@Va_vqopPtDG49R?4JPiQQ&e)nH_X#YK5^CcXZ$4J^a-n8%x5L6%;5T;G3d69|SQ;tc=@B^jjH zASueO>A7q3ydnR=Rmq4J{=KZhqpzv0Y6(r^118|$DI+n&ERVbxVEyhIQt5yZ?&%L< z+s=IZhcXa6d+BE99>}2GH8)EK48iP;;dyq1@`MuL06z4RMVWMk*B|~Azy%)FogY_O z$~(M)oiwZLQGg5h@sG~Ag8eLMnn4RV!Jfk>PLLkFC{BJy_XD3o6O=nx1P0NnKyW=nE}M4U9-}6afEX6 z-Zu~bk_lHQHb?*+0gi9N#{|zh(~mw^E!^T&3KBShnKaV~JxX0*b#fh(C~RBJvrK<3 zh|Pd#y6gOu{m=Nd5(L>i_f&mW4-eJ8&9{Q@dGxGsJfLsnU;Dma|lYOD43q!92GE7r|s3?9#VYj^sg zD>d@(;IhXh|5Oj*t)tTK-or@Bd!k~6y5eb9K@8?Uj2Z*`jP)#AT+3N|^El@Zb)?ae zdQSmdy~9{zZ>N?-bp0vUBUkPN$YDFdhfta;%<)$1%vl>u+72O2W>v z_o6N3sHsnlr;$lP%OMCze2*82CiCX;Sv~A*WPBA=EQ$gky%D(Xn)>7AYT>?MX| z$1~WDW7JrmG?PyEeDXKZGji?6nQ68uGmSB3u5%~BnSxKSB8CtP2Ijgt>sKp*4P=NN z7Dgb0#ZdVB^vF}Xj|6etq_Vt>(L+=RK6v*5${b5cC{=wwZ8kwsg`I`SDQ2z3cCi9- z`4>URb7w>mJ&{k7N&vHKLuZ_qL>Ow~K zreVtBdhrH0K|s3BjIfhanz__f1=mBj+WrM_|9Ly(jm=BTd#CZs(_gQC&e~H0l_H2r zS{l~TvBndL62y-m0Jwak+<)~J8ac$ zCj`o;w1JW@+n%!Im){7L!C4ENUk0O_>o{rE>BLbMc=o`3O@;36kngMwREMECm5V zFo&Vsqj_Dxud_?=L3L-GRzsW}jOuHl!B5Vn?Hhx|!$4)?GOYw`|V_v7U7Z|9Gm}G@HnLgHiR1O5qkgK8Vf4A-pq_ z-$t7Qk|`KE5*-*ZstJ^3ZSXRve6`KEtHvKGW0lmqmkR+WAfg*+1$SSTcz zTWFFM{ig`u7W_&CN16jiT49WAs$i!WC1%bHEY^FSb_n?wvZ9W`&PPp~Mn5R^e=k!6 zX^k2{6bWIMqlGGf)cEd82{jkLyqlc=Mg-(9*xBy*0}m`*;PHLASGi+qInw+gFGe4| z3_us9ub2NbuL1zD@y1PJ{aJr1%Nsk@kJ9&ddV2eSo{kKAY|LNOcc{Q>QYCwZ4c+pa)IbXemP zicL{SF>Soidc{H>ei2y0PQLoa>M2Y5u7J#@f`=B%M0)d**@~3EG-4=pmiaO5alv?M_TTWyK zgJa#+HP~ zSjukVc7Z|RR_<2Kog8y5TsI*iSN*p=Efu>i+CMV!7rcDn0#{$E7ZpM5tw3T=Egjwx z06mTLho8I39vwuuzq{0>pwLvdF5cnytSjSOYq02vcH=quU#{S@H)dUm_e>i@*%zAM z!_#bU!;(zc|0c>gKJw;zTRa|jEYMjDGExRUWt@+%QAFwJfF_pnU!V~)sYdH$q-+;# z=?6mV;~{&)xy?L)`Oz9+=;-V0#(_YM-Ko1&S|0JHqDO($skOdt(BCnICD$@qca(R> zC1yH@Zx_tHymAU6pebjfLdC^3o|Qzcgl-cQQ%>A_1@?PKyD%@TyL1NvZvZs$Y59Y1O{YC=@qo*$@Xnq*FkfI#r z)yboj55sSZlA-hJuxeAlG(C!Uwfu?6bucZ zbX3DL)y-pKI4OZbL)TeJ)Jg$ll<20?PbMHYSw7~GLKH_d-~IGz=gG7gf7ilReH5PW zyK8Ou3lP#}Co`QAK&88KzQDH795R=P?qKX)Smn$gTZ;~n^-6G2uG!dPZ(#Da)ECIvxU#b13cwo!q0qJ2jt$#w zZ+ZHmw8~+7G2r3qp^SD^M`?Da3EP^wg#Q-pDvgB?xuWG*)%(?vjF-h3RD=vR!MrXPn!9RgkNmZ0FLjM zJNx~@6n!WvH(8uo_}z}ncQ*&5epUn{fHNOFFBF6W7PFA)+@~4ZE~tcX%UrAGAsggh zu=QE}Mg9?_r!jD{{cl4VD9Y2>tO1DB@IA-g8c_X~i^CxYsNQH8ar{CyG0RbAKs5>f zkB|S&wrij`!y8Px0|Yfi?E zzU-!7$$%TTWXVl@)P?|C z`e}jeBy&(p7`%0w_yLO?gFM`7GC=fyOL^3*E*tCpNu8#s_Sz4i z2ux6ie(YmNmBxXxWWD=K{E5w3d%NFbvIpE?4)m`DpeQDNWoLcJVD~-0Ou^T{>jI>R zJ!vMkfTK`8Mt}9*z;(T+FZL<~R##wW7OD1lEu3sZ1oy+ITd~dT@Sc;(XALBUeKxCC zjTED&qeDv(M+-8UQ0XA>3{AittOpKkCg!Wqh%7qYRRNJCTp zxvlH5VCDzZRCgb z?B+91GABiZWr83KK1#6YFO)=$-j$08z(DIUH2v4tkLQ$$lUNF=|_&}wR3@h?c#L;{wdk=VeWm3+k z>*_E;m=q0mkc*=2kb&~e81UrvDkU|Gh9`8yqsfL`FYC_YqsCIp3%?QAW1584_%b=5 zC&!FavUR|4a&x_>EX?6HXxk?QJpp>~5MEV~zdez!+i}HI5|;V??774@@i<{zWsm>z z5Inv4t79n6Hw->5T2h@|0{_rRaSS#R>%@QR@$&>#;b8e|?C^PUQlacp#aA@K8gyml(Lkpy?shjtsvlTD zv2qbAz(B?rvV1iUL4l;)s|s#o0Nd1$8dG}Db_||HcS=3MkUCYvhl-^7aXs9mE}<@d zgdi>fIb_d-;0*G3d@JaqzQa@IdJh#n>b^_Xu*_l%5pY)D>}FTapi0Y#Fmc55_pd)) zM|K)u7u^$6ap#VZY;Q8G1g6k5%>u(rpBxyxic*@V!V?V9G!L!8Ov+Vu2@adGlVNb;WGVHo;xKDR zRs8`ZP0<8Uvjnr1EG)(1v*x2+25sr%Y5t>zTqP`NnrAnnWBPU~Yl5PPAFrmL98M8& zpVc|bOlZE$-ug9}B!J2KArn()gK43lcSCr}6ilN^1P% zWiZ#f^m+Rv#%(Ha6KaLPjzJRrANffoGD{UL9tWsCo-42_-DlAIR73l{vJm?IE}zlQ z6r!Aatt%IAVJJ*R+(r0Ft)47E5?dUOKlT?v9P&?UD_<~WgBmec-n;L8po3?@Eu4=g zvF`@c?S(Jt_!@9_ycqTDLB|l`383SzC`fV@?BeHax3L2L*p!NwS-QPxW!SZrkB(`Y zsr%YjHZjwC&J~v?cOxRDdBhB{7LxMMcY-LoN$rZ3d<8}#F^AR4nXS?%AakqWXDYaqSPx}=K9cpep>{&G`_J6d^6AmE7$4NQQPk#_JK8 zc&zaJT0i-3BD4F?*V*xXs;cZ<9CF?^8fTMJ|{!mMO$QuTK*;j+KbuuRC$zi~e zADrB5cjrU=DUjSkEybBqZ7h6*+uy7Rs1b5&`%Ar$%m7?jWB`PN;dfOdg|-`4 zxj}jlR>G1``5qV)XjUXKF@$Z-0LuDe66rBnT~{1;E#uDS6W6tWhiRmC4e(=EZr)QFci0{y2|c8 z8Vf6RDc&-{E8McyG{?jvY1tesYbYuW=1NbMF3kQq1#;UvVJ=fnFs`V8L<}AMV$gpr zBNrZb$rJ#hv4WoDDZJW)cdE5#D#U3{cP*o%%Em7=lnD{aIra50l0$V21`STY#P%;< z+s^RLz`uIbwYgzFHZigs`AMjX8!R2Hy=dWcGO3~^eQ@i53~n!R863k@lw^uEuUsReP!!EP#RlfW-%%&b z`+32_Y;wmC%IKd5(%uP)w?uLi%}%Gm^ZEc_c|h-whb}bVkP6DQ<^^40=v(Ijkj*U{ zGA*R6d`+{CFWv=gKR=??Ai8D*N_rgG*xN?#Zx(TZ5yTTHU>hv{=7 znXa`Vw`vlKU7Om~Yf2B3YEe3Jd#YhEdLuzUkRD>&D2`E7+0}X+&Z>$@7F1=Y1{3>k zFcy_8MFCTf-A^KVdYx&Bv|%^5Hv!7|_BO-R9>#jR^(b`#?~X6b*b)TalqQ6KV-ed@ z(2eU;y`w!BK?}C5d6DFKKw-SjQdSRO+v>0|Awz&l9k`rs~~*GvrrtfauGSXvfHBI z06yE{-*^$B?#wh{iii9SJZ?R}*svcp>0PZh*>yqmu)`LMzfiDyu%cC=8lyL#4J5z|Xo z{aPXo4V1lgs8gyPqud1^{lT1&7%IaLKUDtrngD5N&)$U5wBU zs+;BeLHi#(jDPU|RS}Mn2swNw4tWFAL(7x&B;qI^T_l6g)5nYe7~&8<6Runhp*BN5pC_Y5r!Hi#@&swClLO7N!I)?s$Fi>gU zhup90-~qyin2=S1s_f;gzEeN}gu2zJUG6oE#SUMaQ>$h{Nd+~4Qj|BpbzXszT-+I$ zmQOwUI4%XIj?|1DljJwRVa&SoYEP8z{RfJ*61Wq$iB{IWEe^gE zGVo>I-ldU%>o5W%@vO`0ykRcYz56Pnf0P7+p%BUmzeHW2JI{~4HFEWzmB@9dCk`za zbu)rK>f);$yg1ye)EW=QIJ6vK%opX?1&VJyw;A@pjzL&9p`jMsPJ>2LoqMuyEO>lp zf&KDBdpuIjl|#yQhXTiEZux&G)a(9P|QU>(l4mU;Cm^&uWceWnDG= z;E|&kI~9WI)a+iSaZ-5PbN2r{T5O374S0yFI!3aCZ%sJ$IX-yuo~od9O^>g}Y>=Q; zRqBTVUU}@V#g9cG-q3?t_(gScU9A2NmEzumlN<-~OOx(Ma$~N99+25qQ_yg_wG| z)?@$#@PFo#=AQsT56da1|GOg-~|JwjqLAAN_tx*8IE<_hu zgTtF}Vx@+WfaAm+E&1&F={PQufxs6C8X91z5*x553SVUwJ|yuh*4@1K7#Pdus(tO< z5BfM%LTkfgG~A#FMhWZ|`^TXg>gkVvR}MJ=y{+nSSHJ(kW7*q?s{Z-Jf4tnNrW=7O z?9oN98P^qRI^RY99qNgn6bEGEHQ^|8Kc>i$s{E3h`I<;GJkWEQM+NR2FNq7*sd5Nx z)w+3H0K_O(`^uX@$c+hE_&czE@HQS)jz<~I*}+3Nn8`v-PHx#5lyD{r#10Kn-&A(n zs!692rOTJVSbI&FshWn<0hv=>3``30W^zAqP(*G;^6LkO;1V(4DB>!?OhZC$RR^-* zP{q77tQ7LC2CBd0#;=!f8aGXCpy1iz_(Q;NVp13~k8*H@LI~sU?0NOG9&kLC40=Wv zJ+kBQxgf3nbRSqI1b(!!ib&Vr>s2%2)p1ZG!AyG!VZsKNy5Dn(u`69Z@X9^>Nuuq` ztH6B1eCC<@Gv1g%8z9BFpwB62!tc^90*1=5gQj@U{TQ%lxuOW2Vvq6FPkJWn+`nQ7 zUPIDsuvwEkJR(fC41DP3(-(9xOcQ(n`eVc;aZub(uK)x?v<(EImIQ!hM|jyTzSIDo zy6LubkP$O@5kLMYh>1g$5+c>d1I*Z!e)i@HX7Bev z^L?ui;he)Dsti%5K$eMQ(5v1ehK1{b5HOBpVC0c_(GUX=`}BRDkMyJ(@Yqf5`j>ij zT$Mbihs$G2Dz8Ew^e6@<3oqliQ;A?A;59##;ZL2w`@0_}mey*5=;IFReaC{5pzgx0 zWoaG^Ps<&V7|gZ~{DL8gfU~b+PH*dpk{w!<-XDgegjV(cMDJ8o6st67B)p_c(%upQ zqrcR)Y8rDI0U%C#>|~80NCc|j^z@6=m$ppQm$v2TXCgQsQ%0Dn_VVd(su|!w`LXqO zDR2b}#BR}(7OuaW-@?DtjDZUeXir|mJ#c8bzLYN#hyj!crS)oKn;!yal@mrkGXkmvErjYcdkOr3KMcs5xE4BZmc##g~9+N=b7Y mfyY4PJ*{{S5&}PRCqnkBgk9=n=@sh#6)-q$tW%-o5cxm8Qtm