PK72META-INF/MANIFEST.MFMLK-. K-*ϳR03PKPK :1|<%experiments/SimilarityExperiment.java/** * Created on Dec 5, 2004 * * TODO To change the template for this generated file go to * Window - Preferences - Java - Code Style - Code Templates */ package experiments; import java.io.BufferedWriter; import java.io.*; import java.util.*; import keystats.KeyDataUtilities; /** * @author Edmond Lau [edmond@mit.edu] * * TODO To change the template for this generated type comment go to * Window - Preferences - Java - Code Style - Code Templates */ public class SimilarityExperiment { private TreeMap _userToFiles; private TreeMap _userToDigraphSequences; public SimilarityExperiment() { // get all the files _userToFiles = new TreeMap(UserDatabase.getUserToFileMap()); _userToDigraphSequences = new TreeMap(); // sort all the digraphs for each user and add to _userToDigraphSequenceMap Set users = _userToFiles.keySet(); DigraphComparator comp = new DigraphComparator(); for (Iterator i = users.iterator(); i.hasNext();) { // get the user's digraph lists over all samples String user = (String)i.next(); List userDigraphList = getDigraphListsForUser(user); for (Iterator j = userDigraphList.iterator(); j.hasNext();) { DigraphSequence sample = (DigraphSequence)j.next(); Collections.sort(sample, comp); } _userToDigraphSequences.put(user, userDigraphList); } } public void computeDistanceBetweenSameUser() { PrintWriter output = null; try { output = new PrintWriter(new BufferedWriter(new FileWriter(new File("analysis/same_user_latency.mat")))); } catch(IOException ioe) { ioe.printStackTrace(); } //Set keySet = _userToFiles.keySet(); Set users = _userToDigraphSequences.keySet(); for (Iterator i = users.iterator(); i.hasNext();) { // get the user's digraph lists over all samples //List userDigraphList = getDigraphListsForUser((String)i.next()); List userDigraphList = (List)_userToDigraphSequences.get(i.next()); for (int j = 0; j < userDigraphList.size(); j++) { for (int k = j+1; k < userDigraphList.size(); k++) { DigraphSequence d1 = (DigraphSequence)userDigraphList.get(j); DigraphSequence d2 = (DigraphSequence)userDigraphList.get(k); // System.out.print(sortAndComputeNormalizedDistance(d1, d2) + " "); output.print(normalizedDistance(d1, d2) + " "); } } output.flush(); } output.close(); } public void computeDistanceBetweenDifferentUsers() { PrintWriter output = null; try { output = new PrintWriter(new BufferedWriter(new FileWriter(new File("analysis/diff_users_latency.mat")))); } catch(IOException ioe) { ioe.printStackTrace(); } //Set users = _userToFiles.keySet(); Set users = _userToDigraphSequences.keySet(); while (users.size() > 1) { String currUser = (String)users.iterator().next(); //List currSeq = getDigraphListsForUser(currUser); List currSeq = (List)_userToDigraphSequences.get(currUser); for (Iterator i = users.iterator(); i.hasNext();) { // skip over current user String otherUser = (String)i.next(); if (otherUser.equals(currUser)) { continue; } //List otherSeq = getDigraphListsForUser(otherUser); List otherSeq = (List)_userToDigraphSequences.get(otherUser); //output.print(''); for (int j = 0; j < currSeq.size(); j++) { for (int k = 0; k < otherSeq.size(); k++) { DigraphSequence d1 = (DigraphSequence)currSeq.get(j); DigraphSequence d2 = (DigraphSequence)otherSeq.get(k); //System.out.print(sortAndComputeNormalizedDistance(d1, d2) + " "); output.print(normalizedDistance(d1, d2) + " "); } } //output.print('\n'); output.flush(); } users.remove(currUser); } output.close(); } /** * Returns a list of DigraphLists for user_ * @param user_ * @return List[DigraphSequence] */ private List getDigraphListsForUser(String user_) { // build the List of digraph lists for the user String userFile = (String)_userToFiles.get(user_); List userKeyLists = KeyDataUtilities.readFile(userFile); List userDigraphLists = DigraphWrapper.keyListsToDigraphLists(userKeyLists); return userDigraphLists; } private double sortAndComputeNormalizedDistance(DigraphSequence digraphs1_, DigraphSequence digraphs2_) { DigraphSequence digraphs1 = new DigraphSequence(digraphs1_); DigraphSequence digraphs2 = new DigraphSequence(digraphs2_); DigraphComparator comp = new DigraphComparator(); Collections.sort(digraphs1, comp); Collections.sort(digraphs2, comp); return normalizedDistance(digraphs1, digraphs2); } /** * Computes the normalized distance between two sequences of digraphs. * The distance is only tabulated based on common digraphs between the two sequences. * @param digraphs1_ * @param digraphs2_ * @return double between 0 and 1, inclusive, representing normalized distance. */ private double normalizedDistance(DigraphSequence digraphs1_, DigraphSequence digraphs2_) { // first filter out to common digraphs DigraphSequence digraphs1 = filter(digraphs1_, digraphs2_); DigraphSequence digraphs2 = filter(digraphs2_, digraphs1); // System.out.println("Common trigraphs:"); // System.out.println(trigraphs1); // System.out.println(trigraphs2); int distance = 0; int nCommonDigraphs = 0; for (int i = 0; i < digraphs1.size(); i++) { for (int j = 0; j < digraphs2.size(); j++) { Digraph d1 = (Digraph)digraphs1.get(i); Digraph d2 = (Digraph)digraphs2.get(j); if (d1.isSimilar(d2)) { nCommonDigraphs++; distance += Math.abs(i - j); break; } } } double normalizedDistance = (double)distance/maxDisorder(nCommonDigraphs); return normalizedDistance; } /** * Filters the input_ to retain only those elements that are also in the filter_. * Returns a new DigraphSequence of the filtered input, ordered in the same way. * @param input_ * @param filter_ * @return DigraphSequence of filtered input */ private DigraphSequence filter(DigraphSequence input_, DigraphSequence filter_) { Set filter = new HashSet(filter_); DigraphSequence filtered = new DigraphSequence(); for (Iterator i = input_.iterator(); i.hasNext();) { Digraph inputD = (Digraph)i.next(); for (Iterator j = filter.iterator(); j.hasNext();) { //System.out.println(j.next().getClass()); Digraph filterD = (Digraph)j.next(); if (inputD.isSimilar(filterD)) { filtered.add(inputD); filter.remove(filterD); break; } } } return filtered; } private int maxDisorder(int n_) { if (n_ % 2 == 0) { // even return n_ * n_ / 2; } return (n_ * n_ - 1) / 2; } public static void main(String[] args) { SimilarityExperiment exp = new SimilarityExperiment(); exp.computeDistanceBetweenSameUser(); exp.computeDistanceBetweenDifferentUsers(); } } PK 17K88 experiments/DigraphSequence.java/** * Created on Dec 5, 2004 * * TODO To change the template for this generated file go to * Window - Preferences - Java - Code Style - Code Templates */ package experiments; import java.util.ArrayList; import java.util.Collection; /** * @author Edmond Lau [edmond@mit.edu] * * TODO To change the template for this generated type comment go to * Window - Preferences - Java - Code Style - Code Templates */ public class DigraphSequence extends ArrayList { /** * @param arg0 */ public DigraphSequence(int arg0) { super(arg0); // TODO Auto-generated constructor stub } /** * */ public DigraphSequence() { super(); // TODO Auto-generated constructor stub } /** * @param arg0 */ public DigraphSequence(Collection arg0) { super(arg0); // TODO Auto-generated constructor stub } } PK 1sVw w experiments/DigraphWrapper.java/** * Created on Dec 5, 2004 */ package experiments; import keystats.*; import java.util.*; import java.awt.event.KeyEvent; /** * @author Edmond Lau [edmond@mit.edu] * * A DigraphWrapper is the glue between the KeyList object and the Digraph object. * Its basic functionality is to take a KeyList and transform it into a List of * Digraphs usable by the models. */ public class DigraphWrapper { private List _keyList; private DigraphSequence _digraphList; /** * Constructs a DigraphWrapper from the specified KeyList object. * @param list_ */ public DigraphWrapper(KeyList list_) { _keyList = list_.getData(); } /** * Converts a List of KeyLists to a List of DigraphLists * @param keyLists_ List[KeyList] * @return List[DigraphSequence] */ public static List keyListsToDigraphLists(List keyLists_) { List digraphLists = new ArrayList(); for (Iterator i = keyLists_.iterator(); i.hasNext();) { DigraphWrapper dw = new DigraphWrapper((KeyList)i.next()); digraphLists.add(dw.getDigraphList()); } return digraphLists; } /** * Returns a list of Digraphs that represent the KeyList that this is composed * of, in the same order as the KeyList. * @return List[Digraph] */ public DigraphSequence getDigraphList() { if (_digraphList != null) { return _digraphList; } _digraphList = new DigraphSequence(); // iterate over the keys and construct digraphs if (_keyList.size() < 2) { // insufficient to create one digraph return _digraphList; } Key k1 = (Key)_keyList.get(0); Key k2 = (Key)_keyList.get(1); Digraph digraph = constructDigraph(k1, k2); _digraphList.add(digraph); // initialize the iterator and skip over first two elements Iterator i = _keyList.iterator(); i.next(); i.next(); while (i.hasNext()) { k1 = k2; k2 = (Key)i.next(); digraph = constructDigraph(k1, k2); _digraphList.add(digraph); } return _digraphList; } /** * Constructs a Digraph from the two specified keys. The Strings used * in the Digraph are extracted from KeyEvent.getKeyText() operating on * Key k's k.getKeyCode(). * @param k1_ * @param k2_ * @return Digraph for the two keys. */ private Digraph constructDigraph(Key k1_, Key k2_) { // create a string array of the key representations String[] s = { KeyEvent.getKeyText(k1_.getKeyCode()), KeyEvent.getKeyText(k2_.getKeyCode())}; int metric = getMetric(k1_, k2_); return new Digraph(s, metric); } /** * Returns an integer metric characterizing the Digraph. For now, * it uses the difference b/w the release time of the second key * and the press time of the first key. * @param k1_ * @param k2_ * @return int metric. */ private int getMetric(Key k1_, Key k2_) { return (int)(k2_.getPressTime() - k1_.getReleaseTime()); } public static void main(String[] args) { // get a list of KeyLists List masterList = KeyDataUtilities.readFile("data/data0.txt"); for (Iterator i = masterList.iterator(); i.hasNext();) { KeyList list = (KeyList)i.next(); DigraphWrapper wrapper = new DigraphWrapper(list); System.out.println(wrapper.getDigraphList()); } } } PK p12eWexperiments/UserDatabase.java/** * Created on Dec 5, 2004 * * TODO To change the template for this generated file go to * Window - Preferences - Java - Code Style - Code Templates */ package experiments; import java.util.Map; import java.util.TreeMap; /** * @author Edmond Lau [edmond@mit.edu] * * TODO To change the template for this generated type comment go to * Window - Preferences - Java - Code Style - Code Templates */ public class UserDatabase { private static final TreeMap _userToFiles; private static String[] users = { "aceji", //"brianwu_dvorak", "brianwu_qwerty", "calvinon", "chenx05", "edmond", "haruka", "kirason", "neha_b", "nickchun", "qianwang", "shchang", "tylerc", "wayluu", "xialiu", //"xialiu_dvorak", "xyu" }; static { _userToFiles = new TreeMap(); for (int i = 0; i < users.length; i++) { _userToFiles.put(users[i], "data/"+users[i]+".txt"); } } /** * Returns a mapping from users to files, in alphabetical order. * @return */ public static TreeMap getUserToFileMap() { return _userToFiles; } public static void main(String[] args) { } } PK 1h'#experiments/KeyPressComparator.java/* * Created on Dec 6, 2004 * * TODO To change the template for this generated file go to * Window - Preferences - Java - Code Style - Code Templates */ package experiments; import java.util.Comparator; import keystats.Key; /** * @author Hottie * * TODO To change the template for this generated type comment go to * Window - Preferences - Java - Code Style - Code Templates */ public class KeyPressComparator implements Comparator{ /** * */ public KeyPressComparator() { super(); } public int compare(Object arg0, Object arg1) { Key t0 = (Key)arg0; Key t1 = (Key)arg1; // first order by the metrics long diff = t0.timePressed - t1.timePressed; return (int) diff; } } PK d1&D experiments/Digraph.java/** * Created on Dec 5, 2004 */ package experiments; /** * A Digraph is an immutable class representing a sequence of two * keystrokes and some timing metric, i.e. latency, to characterize timing * information of the keystrokes. * * Digraphs implement reference equality but can compared to be similar * if they share common keystrokes using the isSimilar() method. * * @author Edmond Lau [edmond@mit.edu] */ public class Digraph { String[] _keystrokes; /* 2 keystrokes */ int _metric; /** * Constructs a Trigraph out of the specified keystrokes and the metric. * @param keystrokes_ * @param latency_ */ public Digraph(String[] keystrokes_, int metric_) { if (keystrokes_.length != 2) { throw new IllegalArgumentException("Digraph constructor takes 3 keystrokes"); } _keystrokes = new String[2]; for (int i = 0; i < keystrokes_.length; i++) { _keystrokes[i] = keystrokes_[i]; } _metric = metric_; } /** * Gets the keystroke at the specified index. * @param index_ * @return the String representation of the keystroke at the specified index. */ public String getKeystroke(int index_) { if (index_ < 0 || index_ > 1) { throw new IllegalArgumentException("Invalid index: " + index_); } return _keystrokes[index_]; } /** * Gets the Digraph metric. * @return int representing metric. */ public int getMetric() { return _metric; } /** * Two Trigraphs are similar if their keystrokes are equal. */ public boolean isSimilar(Digraph digraph_) { return (_keystrokes[0].equals(digraph_._keystrokes[0]) && _keystrokes[1].equals(digraph_._keystrokes[1])); } /** * Two Trigraphs are equal if their keystrokes are equal. */ // public boolean equals(Object o) { // if (!(o instanceof Trigraph)) { // return false; // } // Trigraph trigraph = (Trigraph)o; // // return (_k // _keystrokes[0].equals(trigraph._keystrokes[0]) && // _keystrokes[1].equals(trigraph._keystrokes[1]) && // _keystrokes[2].equals(trigraph._keystrokes[2])); // } /** * Returns the hashcode. */ // public int hashCode() { // return _keystrokes[0].hashCode() + _keystrokes[1].hashCode() + _keystrokes[2].hashCode(); // } /** * Returns a String representation of the Digraph. */ public String toString() { String s = "(<" + _keystrokes[0] + "," + _keystrokes[1] + ">, " + _metric + ")"; return s; } public static void main(String[] args) { String s = "A quick brown fox jumps over the lazy dog."; System.out.println(s.length()); } } PK 1f"experiments/DigraphComparator.java/** * Created on Dec 5, 2004 */ package experiments; import java.util.*; /** * A DigraphComparator orders Digraph first by metric, then by * alphabetical order. Be careful because this ordering is inconsistent * with equals. * * @author Edmond Lau [edmond@mit.edu] */ public class DigraphComparator implements Comparator { /* (non-Javadoc) * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) */ public int compare(Object arg0, Object arg1) { Digraph t0 = (Digraph)arg0; Digraph t1 = (Digraph)arg1; // first order by the metrics int diff = t0.getMetric() - t1.getMetric(); if (diff != 0) { return diff; } // if metrics are equal, order by alphabetical order diff = t0.getKeystroke(0).compareTo(t1.getKeystroke(0)); if (diff != 0) { return diff; } diff = t0.getKeystroke(1).compareTo(t1.getKeystroke(1)); return diff; } public static void main(String[] args) { String[] am = {"a", "m"}; String[] me = {"m", "e"}; Digraph[] digraphs = { new Digraph(am, 10), new Digraph(me, 20), new Digraph(me, 10)}; List list = Arrays.asList(digraphs); Collections.sort(list, new DigraphComparator()); System.out.println(list); } } PK h1p_y keystats/XYUdef.javapackage keystats; import java.awt.Color; import java.awt.Font; import java.awt.Image; import java.net.URL; import java.sql.Date; import java.text.SimpleDateFormat; import javax.swing.ImageIcon; /** * @author xyu * * bunch of constants that I use */ public class XYUdef { public static final int MAX_MENU_BUTTON_WIDTH = 35; // icons // font defaults public static final Font COMMENT_VERDANA = new Font("Verdana", Font.PLAIN, 10); public static final Font COMMENT_ITALICS = new Font("Verdana", Font.ITALIC, 10); public static final Font VERDANA_10 = new Font("Verdana", Font.PLAIN, 10); public static final Font VERDANA_10_BOLD = new Font("Verdana", Font.BOLD, 10); // color defaults public static final Color COLOR_NO_GRADE_LABEL = Color.RED; public static final Color MENU_BAR_COLOR = Color.WHITE; public static final Color COLOR_CLEAR = new Color(0,0,0,0.0f); public static final Color COMMENT_SELECTED_COLOR = Color.YELLOW; public static final Color COMMENT_UNSELECT_COLOR = Color.LIGHT_GRAY; public static final Color BG_PROFILE_BOX = new Color(219,235,255); // borders public static final Color BORDER = Color.BLACK; public static final Color BORDER_BLUE = new Color(110, 205, 235); public static final Color BORDER_GRAY = new Color(100, 120, 135); public static final Color BG_STUDENT_PERF = Color.WHITE; // Table color public static final Color TBL_BASE_COLOR = Color.WHITE; public static final Color TBL_ALT_COLOR = new Color(230, 238, 249); public static final Color TBL_SELECT_COLOR = new Color(90, 150, 235); // Graph colors public static final Color COLOR_BARCHART_CLASS_AVE = new Color(150, 175, 200); public static final Color COLOR_BARCHART_STUDENT = Color.RED; public static final Color COLOR_HISTOGRAM_CLASS_AVE = Color.BLUE; public static final Color COLOR_HISTOGRAM_STUDENT = Color.RED; public static final Color COLOR_HISTOGRAM_BAR = new Color(150, 175, 200); public static final Color COLOR_HISTOGRAM_GRIDLINES = Color.BLACK; public static String dateWordStr(Date date) { SimpleDateFormat f = new SimpleDateFormat("MMM-d-yy"); return f.format(date); } public static String getDateString(Date date, boolean time) { // 11/31/04 SimpleDateFormat f; if (time) { f = new SimpleDateFormat("MM" + '/' + "d" + '/' + "yy" + " h:mm a"); } else { f = new SimpleDateFormat("MM" + '/' + "d" + '/' + "yy"); } return f.format(date); } public static String lastModDateTime(Date date) { // 11/31/04 12:08PM SimpleDateFormat f = new SimpleDateFormat("MM" + '/' + "d" + '/' + "yy" + " h:mm a"); return f.format(date); } } PK 18keystats/KeyUI.javapackage keystats; import javax.swing.*; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import java.awt.*; import java.awt.event.*; import java.net.*; import java.io.*; import java.util.*; import java.util.List; // we don't want java.awt.List import info.clearthought.layout.*; import keystats.*; /** * @author xyu * * TODO To change the template for this generated type comment go to * Window - Preferences - Java - Code Style - Code Templates */ public class KeyUI extends JFrame{ //determines whether you get the regular sentence //or the shift-key enhanced sentence public static final boolean shift_listen = true; private static String text; private JTextField nameBox; private JTextArea textBox; private Container contentPane; private JLabel textLabel, trialLabel, targetText; private KeyList curKeyList; private LinkedList masterList; private int trials; private boolean resetTextBox; public KeyUI(String inputText) { super(); // table dimensions double border = 10; double P = TableLayout.PREFERRED; double size[][] = { {border, TableLayout.PREFERRED, TableLayout.FILL, border}, // columns {border, TableLayout.PREFERRED, TableLayout.PREFERRED, TableLayout.FILL, TableLayout.PREFERRED, TableLayout.PREFERRED, TableLayout.PREFERRED, P, P, P} }; // rows TableLayout tableUI = new TableLayout(size); setDefaultCloseOperation(EXIT_ON_CLOSE); tableUI.setHGap(4); tableUI.setVGap(5); // initialize lists // masterList = list of KeyLists // KeyList = list of key data masterList = new LinkedList(); curKeyList = new KeyList(); trials = 1; resetTextBox = true; // content pane... contentPane = this.getContentPane(); contentPane.setLayout(tableUI); // clear button: clears text fields and resets data structures for new user JButton clearButton = new JButton("New User"); clearButton.setToolTipText("Starts Recording data for new user"); clearButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent arg0) { textBox.setText(""); // reset text fields nameBox.setText(""); masterList.clear(); // clear data lists curKeyList = new KeyList(); trials=1; trialLabel.setText("Trial #: " + trials); resetTextBox = true; }}); // textLabels JLabel nameLabel = new JLabel("Name:"); nameBox = new JTextField(10); JLabel textLabel = new JLabel("Type: "); targetText = new JLabel(); if (inputText==null) { targetText.setText("A quick brown fox jumps over the lazy dog."); } else { targetText.setText(inputText); } text = targetText.getText(); trialLabel = new JLabel("Trial #: " + trials); //------- textBox: user types here textBox = new JTextArea(7,8); textBox.setAutoscrolls(true); textBox.setLineWrap(true); JScrollPane scroll = new JScrollPane(textBox); textBox.addKeyListener(new KeyListener(){ public void keyTyped(KeyEvent arg0) { // nada } // record key data; we keep backspace, shift // we do NOT record tabbing public void keyPressed(KeyEvent e) { int kc = e.getKeyCode(); // don't create new line when pressing enter if (kc == KeyEvent.VK_ENTER ) { if(textBox.getText().equals(text)) { newTrial(); e.consume(); } else { textBox.setText(textBox.getText() + "\nWrong sentence typed: please throw out this trial."); } } else if (kc != KeyEvent.VK_TAB) { curKeyList.insertKey(KeyList.KEY_PRESS, e.getKeyCode(), e.getKeyChar(), e.getWhen(), e.getKeyLocation()); System.out.println("PRESS: (" + kc + ", " + e.getKeyChar() + ", " + e.getWhen() + ")"); if (resetTextBox) { resetTextBox = false; trialLabel.setText("Trial #: " + trials + " ( . . . )"); } } } public void keyReleased(KeyEvent e) { int kc = e.getKeyCode(); // ignore tab releases if (kc == KeyEvent.VK_TAB) { e.consume(); return; } if (kc != KeyEvent.VK_ENTER) { curKeyList.insertKey(KeyList.KEY_RELEASE, kc, e.getKeyChar(), e.getWhen(), e.getKeyLocation()); System.out.println("RELEASE: (" + e.getKeyCode() + ", " + e.getKeyChar() + ", " + e.getWhen() + ")"); } }}); // Button for saving data to a file JButton done = new JButton("Save Data ... "); done.setToolTipText("Write data to file"); done.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent arg0) { JFileChooser fc = new JFileChooser(); int result = fc.showSaveDialog(null); if (result == JFileChooser.APPROVE_OPTION) { File f = fc.getSelectedFile (); /*if (f.exists ()) { int response = JOptionPane.showConfirmDialog (null, "Overwrite existing file?","Confirm Overwrite", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); if (response == JOptionPane.CANCEL_OPTION) return false; */ KeyDataUtilities.writeFile(masterList,f,nameBox.getText(),targetText.getText()); } }}); JButton graph = new JButton("show Graph"); graph.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent arg0) { GraphingUtil.getCategoryTrendChart(masterList); }}); JButton indis = new JButton("show indis. keys"); indis.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent arg0) { GraphingUtil.getCategoryTrendChart2(masterList, "Testing"); }}); JButton clearRecent = new JButton("Throw out this trial"); clearRecent.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent arg0) { curKeyList = new KeyList(); textBox.setText(""); textBox.requestFocus(); }}); contentPane.add(nameLabel, "1, 1"); contentPane.add(nameBox, "2, 1"); contentPane.add(textLabel, "1, 2"); contentPane.add(targetText, "2, 2"); contentPane.add(scroll, "2, 3"); contentPane.add(trialLabel, "2, 4"); contentPane.add(clearRecent, "2, 5"); contentPane.add(clearButton, "2, 6"); // clear data contentPane.add(graph, "2, 7"); contentPane.add(done, "2, 8"); // save data contentPane.add(indis, "2, 9"); // graph w/ indistinguished keys } private void newTrial() { trials++; trialLabel.setText("Trial #: " + trials + " (Trial #" + (trials - 1) + " sent)"); textBox.setText(""); resetTextBox = true; masterList.add(curKeyList); curKeyList = new KeyList(); System.out.println("TOTAL SIZE OF MASTER LIST: " + masterList.size()); } public static void main(String[] args) { final String input = (args.length > 0) ? new String(args[0]) : null; SwingUtilities.invokeLater(new Runnable() { public void run () { // Make and display the WordFinder window. KeyUI blah = null; if(!shift_listen) blah = new KeyUI(input); else blah = new KeyUI("Another Quick Brown Fox Jumps Over The Lazy Dog Yet Round Cats Eat Plain Goldfish Heartily In Maine Not Kansas Under Some Vain Zealous Xena Warrior."); blah.pack(); blah.show(); } }); } } PK 1}Wkeystats/KeyDataUtilities.javapackage keystats; import java.io.*; import java.util.*; import java.util.Date; /** * @author xyu * * TODO To change the template for this generated type comment go to * Window - Preferences - Java - Code Style - Code Templates */ public class KeyDataUtilities { public static boolean shift_key_on = false; public KeyDataUtilities() { super(); } private static String getDate() { return new Date(System.currentTimeMillis()).toLocaleString(); } /** * @param masterList = LinkedList of KeyLists * @param f = file to be written to (accessed/specified via KeyUI GUI) * @param username = username entered in KeyUI GUI * @param targetText = test sentence that generated data * @requires masterList != null * @effect creates file f and outputs keystroke data to it */ public static boolean writeFile(LinkedList masterList, File f, String username, String testSentence) { try { PrintWriter output = new PrintWriter(new BufferedWriter(new FileWriter(f))); if(KeyUI.shift_listen) output.println("#+ Input formatted for Shift Key Listening"); output.println("# User Name: " + username); output.println("# " + getDate()); if(KeyUI.shift_listen) output.println("# A Quick Brown Fox Jumps Over The Lazy Dog Yet Round Cats Eat Plain Goldfish Heartily In Maine Not Kansas Under Some Vain Zealous Xena Warrior."); else output.println("# Test Sentence = " +'\"' + testSentence + '\"'); output.println("# Total Data Sets: " + masterList.size()); output.println("# 32 = space\n# 8 = delete\n# 16 = shift"); output.println("# DATA FORMAT:[ KEYCODE, CHARACTER, PRESS-TIME, RELEASE-TIME, KEY-LOCATION]\n"); for(int c=0; c 5 && curKeyList != null) { //System.out.println(blah); keyData = blah.split(" "); //System.out.println(keyData.length); //for (int i = 0 ; i < keyData.length; i++) System.out.println(keyData[i]); // 'space' is a special case if(shift_key_on) { if(Integer.parseInt(keyData[0]) == 32) { curKey = new Key(Integer.parseInt(keyData[0]), ' ', Long.parseLong(keyData[3]), Long.parseLong(keyData[4]), Integer.parseInt(keyData[5])); } else { curKey = new Key(Integer.parseInt(keyData[0]), keyData[1].charAt(0), Long.parseLong(keyData[2]), Long.parseLong(keyData[3]), Integer.parseInt(keyData[4])); } }else { if(Integer.parseInt(keyData[0]) == 32) { curKey = new Key(Integer.parseInt(keyData[0]), ' ', Long.parseLong(keyData[3]), Long.parseLong(keyData[4])); } else { curKey = new Key(Integer.parseInt(keyData[0]), keyData[1].charAt(0), Long.parseLong(keyData[2]), Long.parseLong(keyData[3])); } } curKeyList.insertKey(curKey); } } } catch (IOException e){ System.out.println(e.getMessage()); return null; } return masterList; } //DOESN'T WORK // returns a List of complete sentence without deletes //or characters that were deleted. Does NOT remove delete //keys from this List. public static List removeDeletes(List old){ List cleanList = new LinkedList(); Key curKey = null; for (int i = 0; i 0){ KeyList dList = k.removeDeletes(); //System.out.println("dList: " + dList); Key curKey = new Key(); OrderedKey tempKey = new OrderedKey(curKey); //add first key orderedList.add(new OrderedKey((Key)dList.completeData.get(0))); // temp variables that holds the position of a key press or release int pressPlace = orderedList.size()*2+1; int releasePlace = orderedList.size()*2 + 2; //loop through rest of key's for (int i = 1; i 0) Collections.sort(completeData, new KeyPressComparator()); } public void removeDeletesForReal() { if (completeData.isEmpty()) return; // sort completeData by press time sortByPressTime(); for (int c = 0; c < completeData.size(); c++) { Key currentKey = (Key) completeData.get(c); // if currentKey is 'delete', remove previous key if (currentKey.charCode == 8) { System.out.println("backspace at i=" + c); System.out.println("old size: " + completeData.size()); completeData.remove(c-1); // remove previous key completeData.remove(c-1); // remove current key System.out.println("new size: " + completeData.size()); c = c - 2; // step back to key before current key System.out.println("new i=" + c); } // so we can step forward again on ++ if (c > completeData.size() - 2) { System.out.println("expect list index out of bounds for size=" + completeData.size()); break; } } } public void insertKey(Key k){ completeData.add(k); } public LinkedList getTrigraph(){ int charOne = 0; int charTwo = 2; Key k1; Key k2; KeyPair keyPair; LinkedList trigraph = new LinkedList(); while (charTwo < completeData.size()){ k1 = (Key) completeData.get(charOne++); k2 = (Key) completeData.get(charTwo++); keyPair = new KeyPair(k1, k2); trigraph.add(keyPair); } return trigraph; } public LinkedList getData(){ return completeData; } /* public Iterator getBigraph(){ return new LinkedList().iterator(); } */ public Key removeLastKey(){ if (completeData.isEmpty()) return null; return (Key) completeData.removeLast(); } public String toString() { String ret = ""; for(int c=0; c 0) ? new String(args[0]) : null; SwingUtilities.invokeLater(new Runnable() { public void run () { // Make and display the WordFinder window. KeyUI blah = new KeyUI(input); blah.pack(); blah.show(); } }); } } PK j~1{  models/NameValuePair.java/** * Created on Nov 29, 2004 * * TODO To change the template for this generated file go to * Window - Preferences - Java - Code Style - Code Templates */ package models; /** * @author Edmond Lau [edmond@mit.edu] * * TODO To change the template for this generated type comment go to * Window - Preferences - Java - Code Style - Code Templates */ public class NameValuePair { public String name; public double value; public NameValuePair(String name_, double value_) { name = name_; value = value_; } } PK '~1models/TrigraphList.java/* * Created on Nov 29, 2004 * * TODO To change the template for this generated file go to * Window - Preferences - Java - Code Style - Code Templates */ package models; import java.util.ArrayList; import java.util.Collection; /** * @author Hottie * * TODO To change the template for this generated type comment go to * Window - Preferences - Java - Code Style - Code Templates */ public class TrigraphList extends ArrayList { /** * */ public TrigraphList() { super(); // TODO Auto-generated constructor stub } /** * @param arg0 */ public TrigraphList(int arg0) { super(arg0); // TODO Auto-generated constructor stub } /** * @param arg0 */ public TrigraphList(Collection arg0) { super(arg0); // TODO Auto-generated constructor stub } } PK j~1;6<models/KeystrokeModel.java/** * Created on Nov 26, 2004 */ package models; import java.util.*; /** * A KeystrokeModel represents a model of a particular user's keystrokes. * The keystroke model is constructed by feeding it sequences of trigraphs * representing user input and then using the sequences to build the model. * A keystroke model may have certain parameters or thresholds set, and can * then be used to authenticate a user based on some input sequence of trigraphs. * * @author Edmond Lau [edmond@mit.edu] */ public interface KeystrokeModel { /** * Returns the name of the user described by the model. * @return String representing username. */ public String getUser(); /** * Adds a trigraph sequence to the sequence used to describe the user. * @param trigraphs sequence to add to the model */ public void addTrigraphSequence(TrigraphList trigraphs); /** * Builds the model based on all trigraph sequences added so far. * This method should only be called after all trigraph sequences have * been added. */ public void buildModel(); /** * Returns true if the user's input trigraphs match the stored model. * @param trigraphs user input sequence * @return true if input matches model; false otherwise. */ public boolean authenticate(TrigraphList trigraphs); /** * Returns a skeleton model of the same type with the same parameters but * no Trigraphs for the specified user * @return Keystroke skeleton model. */ public KeystrokeModel copyModelSkeleton(String user_); } PK w1??models/ExperimentFramework.java/** * Created on Nov 28, 2004 */ package models; import java.util.*; //import java.util.Map.*; import keystats.KeyDataUtilities; import keystats.KeyList; /** * @author Edmond Lau [edmond@mit.edu] * * Experiments: * False Acceptance Rate: * For each parameter setting (threshold for DisorderModel and percentage and std. dev. for StatisticsModel) * For each user, * Build a model from the user's inputs and test on all other users. * * False Rejection Rate: * For each parameter setting, * For each model-size, * For each user, * Build model from all possible models of model-size and cross-validate on other input */ public class ExperimentFramework { private static final int SAMPLES_PER_USER = 10; private static final String INPUT = "models/control.txt"; private static final Map _userToFiles; private static final double HOLDOFF_PERCENTAGE = 0.2; // fraction of samples to hold off for testing in cross-validation private static String[] users = { "aceji", "brianwu_dvorak", // "brianwu_qwerty", "calvinon", "chenx05", "edmond", "haruka", "kirason", "neha_b", "nickchun", "qianwang", "shchang", "tylerc", "wayluu", // "xialiu", "xialiu_dvorak", "xyu" }; static { _userToFiles = new TreeMap(); for (int i = 0; i < users.length; i++) { _userToFiles.put(users[i], "data/"+users[i]+".txt"); } //_userToFiles.put("aceji", "data/data0.txt"); //_userToFiles.put("Ji Zhang", "data/data1.txt"); } // initialized to [.05 to 0.7] private static final double[] DISORDER_THRESHOLDS; static { DISORDER_THRESHOLDS = new double[25]; for (int i = 0; i < DISORDER_THRESHOLDS.length; i++) { DISORDER_THRESHOLDS[i] = 0.6 + (i+1) * 0.01; } } private static final double[] STATISTIC_STD_DEVS ={ 1.0, 1.5, 2.0, 2.5 }; private static final double[] STATISTIC_SIMILAR_PERCENTS = { 0.5, .55, 0.6, .65, 0.7, .75, 0.8, .85, 0.9, .95,1.0}; private static final int FAR = 0; private static final int FRR = 1; public void evaluateStatisticsModel(int type) { int counter = 0; if (type == FAR) { System.out.println("--- Evaluating FAR for Statistics Model ---"); } else { System.out.println("--- Evaluating FRR for Statistics Model ---"); } List[] indexedRates = new List[STATISTIC_STD_DEVS.length * STATISTIC_SIMILAR_PERCENTS.length]; StatisticsModel model = new StatisticsModel("stats_skeleton"); loadControlForStatisticsModel(model, INPUT); for (int i = 0; i < STATISTIC_STD_DEVS.length; i++) { model.setDeviation(STATISTIC_STD_DEVS[i]); for (int j = 0; j < STATISTIC_SIMILAR_PERCENTS.length; j++) { System.out.println("--- Statistics Standard Deviation = " + STATISTIC_STD_DEVS[i] + "\n" + "Statistics Similar Percent = " + STATISTIC_SIMILAR_PERCENTS[j] + " ---"); model.setPercent(STATISTIC_SIMILAR_PERCENTS[j]); List rates; if (type == FAR) { rates = evaluateFAROnAllUsers(model); } else { rates = evaluateFRROnAllUsers(model); } indexedRates[counter++] = rates; for (Iterator k = rates.iterator(); k.hasNext();) { NameValuePair pair = (NameValuePair) k.next(); System.out.println(pair.name + ": " + pair.value); } } } printMATLABReadableScriptForStatisticsModel(indexedRates); } public void evaluateDisorderModel(int type) { if (type == FAR) { System.out.println("--- Evaluating FAR for Disorder Model ---"); } else { System.out.println("--- Evaluating FRR for Disorder Model ---"); } List[] indexedRates = new List[DISORDER_THRESHOLDS.length]; DisorderModel model = new DisorderModel("skeleton"); for (int i = 0; i < DISORDER_THRESHOLDS.length; i++) { System.out.println("--- Disorder Threshold = " + DISORDER_THRESHOLDS[i] + " ---"); model.setThreshold(DISORDER_THRESHOLDS[i]); List rates; if (type == FAR) { rates = evaluateFAROnAllUsers(model); } else { rates = evaluateFRROnAllUsers(model); } indexedRates[i] = rates; for (Iterator j = rates.iterator(); j.hasNext();) { NameValuePair pair = (NameValuePair)j.next(); System.out.println(pair.name + ": " + pair.value); } } printMATLABReadableScriptForDisorderModel(indexedRates); } private void printMATLABReadableScriptForStatisticsModel(List[] rates) { System.out.println("--- Begin MATLAB Readable Script Output for Statistics ---"); String standard_dev = ""; for (int i = 0; i < STATISTIC_STD_DEVS.length; i++) { standard_dev += " " + STATISTIC_STD_DEVS[i]; } System.out.println("standard_dev = [" + standard_dev + " ];"); String percent_similar = ""; for (int i = 0; i < STATISTIC_SIMILAR_PERCENTS.length; i++) { percent_similar += " " + STATISTIC_SIMILAR_PERCENTS[i]; } System.out.println("percent_similar = [" + percent_similar + " ];"); String[] userArray = new String[_userToFiles.size()]; int index = 0; String users = ""; for (Iterator i = _userToFiles.keySet().iterator(); i.hasNext();) { String user = (String)i.next(); users += " '" + user + "'"; userArray[index++] = user; } System.out.println(users); for (int i = 0; i < userArray.length; i++) { String results = ""; for (int j = 0; j < rates.length; j++) { List FARList = rates[j]; NameValuePair pair = (NameValuePair)FARList.get(i); results += " " + pair.value; } //System.out.println(userArray[i] + " = [" + results + " ];"); System.out.println(results); } System.out.println("--- End MATLAB Readable Script Output for Statistics ---"); } private void printMATLABReadableScriptForDisorderModel(List[] rates) { System.out.println("--- Begin MATLAB Readable Script Output ---"); String disorder_thresholds = ""; for (int i = 0; i < DISORDER_THRESHOLDS.length; i++) { disorder_thresholds += " " + DISORDER_THRESHOLDS[i]; } System.out.println("disorder_thresholds = [" + disorder_thresholds + " ];"); String[] userArray = new String[_userToFiles.size()]; int index = 0; for (Iterator i = _userToFiles.keySet().iterator(); i.hasNext();) { String user = (String)i.next(); userArray[index++] = user; } for (int i = 0; i < userArray.length; i++) { String results = ""; for (int j = 0; j < rates.length; j++) { List FARList = rates[j]; NameValuePair pair = (NameValuePair)FARList.get(i); results += " " + pair.value; } System.out.println(userArray[i] + " = [" + results + " ];"); } String users = ""; for (int i = 0; i < userArray.length; i++) { users += userArray[i] + "; "; } System.out.println("users = [" + users + " ]; "); System.out.println("--- End MATLAB Readable Script Output ---"); } /** * Returns a List of all False Acceptance Rates for the model_ on all users, * ordered by the ordering of _userToFiles, i.e. alphabetically * @param model_ KeystrokeModel, parameters set */ public List evaluateFAROnAllUsers(KeystrokeModel model_) { List FARs = new ArrayList(); Set users = _userToFiles.keySet(); // iterate over each user and evaluate the FAR for (Iterator i = users.iterator(); i.hasNext();) { String user = (String)i.next(); double FAR = evaluateFAROnUser(model_.copyModelSkeleton(user), user); FARs.add(new NameValuePair(user, FAR)); } return FARs; } /** * Returns the False Acceptance Rate of the model_ trained on user_'s input and * tested against all inputs from all other users * @param model_ KeystrokeModel, parameters set * @param user_ user to test * @return FAR */ private double evaluateFAROnUser(KeystrokeModel model_, String user_) { if (!_userToFiles.containsKey(user_)) { throw new RuntimeException(user_ + "'s data file not found"); } // build the List of trigraph lists for the user List userTrigraphLists = getTrigraphListsForUser(user_); // List[List[Trigraphs]] // build the List of trigraph lists for all adversaries List adversaryLists = new ArrayList(); Set users = _userToFiles.keySet(); for (Iterator i = users.iterator(); i.hasNext();) { String adversary = (String)i.next(); if (!adversary.equals(user_)) { //TODO adversaryLists.addAll(getTrigraphListsForUser(adversary)); } } // test the model return buildModelAndComputeFAR(model_, userTrigraphLists, adversaryLists); } /** * Returns the False Acceptance Rate of a model_ trained on the specified userInput_ * and tested on the advesaryInput_. * @param model_ KeystrokeModel, parameters set but uninitialized * @param userInput_ List[TrigraphList] -- the training data * @param adversaryInput_ List[TrigraphList] -- the validation data * @return */ private double buildModelAndComputeFAR(KeystrokeModel model_, List userInput_, List adversaryInput_) { // add the trigraphs to the model for (Iterator i = userInput_.iterator(); i.hasNext();) { model_.addTrigraphSequence((TrigraphList)i.next()); } model_.buildModel(); return computeFAR(model_, adversaryInput_); } /** * Returns the False Acceptance Rate for model_ on the provided input from * an adversary. * @param model_ KeystrokeModel, already initialized. * @param adversaryInput_ List[TrigraphList] * @return False Acceptance Rate */ private double computeFAR(KeystrokeModel model_, List adversaryInput_) { return computeAcceptanceRate(model_, adversaryInput_); } /** * Returns a List of all False Rejection Rates for the model_ on all users, * ordered by the ordering of _userToFiles, i.e. alphabetically. The FRRs * are tabulated using cross-validation over all possible ways of holding off * HOLDOFF_PERCENTAGE of the data. * @param model_ KeystrokeModel, parameters set */ public List evaluateFRROnAllUsers(KeystrokeModel model_) { List FRRs = new ArrayList(); Set users = _userToFiles.keySet(); // iterate over each user and evaluate the FRR for (Iterator i = users.iterator(); i.hasNext();) { String user = (String)i.next(); double FRR = evaluateFRROnUser(model_.copyModelSkeleton(user), user); FRRs.add(new NameValuePair(user, FRR)); } return FRRs; } /** * Returns the False Rejection Rate of the model_ trained on 1-HOLDOFF_PERCENTAGE * of the user_'s data and validated on the remaining ones. * @param model_ KeystrokeModel, parameters set * @param user_ user to test * @return FRR */ public double evaluateFRROnUser(KeystrokeModel model_, String user_) { if (!_userToFiles.containsKey(user_)) { throw new RuntimeException(user_ + "'s data file not found"); } // get the user's trigraphs List userTrigraphLists = getTrigraphListsForUser(user_); // how many samples to use to create the model? // the remaining will be used to validate int modelSize = (int)(userTrigraphLists.size() * (1 - HOLDOFF_PERCENTAGE)); return crossValidateFRR(model_, userTrigraphLists, modelSize); } /** * Returns the model's FRR using cross-validation. * * Generates all possible models using modelSize_ number of userInput_ samples, and * then evaluates the FRR of the model using the remaining samples. FRR returned is * the average FRR over all models of modelSize_. * @param model_ KeystrokeModel_, parameters set, not initialized */ private double crossValidateFRR(KeystrokeModel model_, List userInput_, int modelSize_) { // model size must be between 1 and userInput_.size() - 1 if (modelSize_ < 1 || modelSize_ > userInput_.size() - 1) { throw new IllegalArgumentException("Model size must be at least 1 and must allow for at least 1 test sample"); } int nSamples = userInput_.size(); if (nSamples == 0 || nSamples > 31) { throw new IllegalArgumentException("Either 0 or more than 31 user input strings"); } double totalFRR = 0; long nExperiments = nChooseM(nSamples, modelSize_); //System.out.println(nExperiments); // to iterate over all possible subsets with modelSize_ elements, use bitstring int nSubsets = 1 << nSamples; for (int i = 0; i < nSubsets; i++) { // if matching number of ones in bitstring if (checkNumberOfOnesInBitstring(i, modelSize_)) { // filter out the userInput_ list List filtered = filter(userInput_, i); List remaining = new ArrayList(userInput_); remaining.removeAll(filtered); KeystrokeModel model = model_.copyModelSkeleton(model_.getUser()); double FRR = buildModelAndComputeFRR(model, filtered, remaining); totalFRR += FRR; } } double averageFRR = totalFRR / nExperiments; return averageFRR; } /** * Returns the FRR for a model_ trained on modelUserInput_ and tested on otherUserInput_ * @param model_ KeystrokeModel, parameters set * @param modelUserInput_ List[TrigraphList] -- training data * @param otherUserInput_ List[TrigraphList] -- testing data * @return FRR for model_ */ private double buildModelAndComputeFRR(KeystrokeModel model_, List modelUserInput_, List otherUserInput_) { // add the trigraphs to the model for (Iterator i = modelUserInput_.iterator(); i.hasNext();) { model_.addTrigraphSequence((TrigraphList)i.next()); } model_.buildModel(); return computeFRR(model_, otherUserInput_); } /** * Returns the False Rejection Rate for model_ on the provided input * from a user. * @param model_ KeystrokeModel, already initialized. * @param validInput_ List[TrigraphList] * @return False Rejection Rate. */ private double computeFRR(KeystrokeModel model_, List validInput_) { return 1.0 - computeAcceptanceRate(model_, validInput_); } /** * Returns the acceptance rate of model_ on input_. * @param model_ KeystrokeModel, already initialized * @param input_ List[TrigraphList] * @return acceptance rate */ private double computeAcceptanceRate(KeystrokeModel model_, List input_) { int total = input_.size(); int nPassed = 0; // iterate over each trigraph sequence and test it for (Iterator i = input_.iterator(); i.hasNext();) { TrigraphList trigraphList = (TrigraphList)i.next(); if (model_.authenticate(trigraphList)) { nPassed++; } } return (double)nPassed/total; } private List getTrigraphListsForUser(String user_) { // build the List of trigraph lists for the user String userFile = (String)_userToFiles.get(user_); List userKeyLists = KeyDataUtilities.readFile(userFile); List userTrigraphLists = TrigraphWrapper.keyListsToTrigraphLists(userKeyLists); //require the same number of samples per user if(userTrigraphLists.size() < SAMPLES_PER_USER) { throw new RuntimeException("Insufficient number of samples for " + user_); } List list = new ArrayList(); for (int i = 0; i < SAMPLES_PER_USER; i++) { list.add((TrigraphList)userTrigraphLists.get(i)); } return list; } private boolean checkNumberOfOnesInBitstring(int n_, int guess_) { int nOnes = 0; while (n_ > 0) { if (n_ % 2 == 1) { nOnes++; } n_ /= 2; } return nOnes == guess_; } private List filter(List source_, int bitstring_) { List filtered = new ArrayList(); int index = source_.size() - 1; while (bitstring_ > 0) { if (bitstring_ %2 == 1) { filtered.add(source_.get(index)); } index--; bitstring_ /= 2; } return filtered; } private long nChooseM(long n_, long m_) { if (n_ < m_) { throw new IllegalArgumentException("m is greater than n"); } long numerator = 1; for (long i = n_; i > m_; i--) { numerator *= i; } // factorial(n_)/((factorial(m_) * factorial (n_-m_))); return numerator / factorial(n_-m_); } private long factorial(long n_) { long result = 1; for (long i = 1; i <= n_; i++) { result *= i; } return result; } public void loadControlForStatisticsModel(StatisticsModel model_, String file_) { List controlKeyLists = KeyDataUtilities.readFile(file_); List controlTrigraphLists = TrigraphWrapper.keyListsToTrigraphLists(controlKeyLists); model_.setControl((TrigraphList)controlTrigraphLists.get(0)); } public static void main(String[] args) { ExperimentFramework framework = new ExperimentFramework(); //framework.evaluateDisorderModel(FRR); //framework.evaluateDisorderModel(FAR); //framework.evaluateStatisticsModel(FRR); framework.evaluateStatisticsModel(FAR); } } PK |1mb models/Trigraph.java/** * Created on Nov 26, 2004 */ package models; /** * A Trigraph is an immutable class representing a sequence of three * keystrokes and some timing metric, i.e. latency, to characterize timing * information of the keystrokes. * * Trigraphs implement reference equality but can compared to be similar * if they share common keystrokes using the isSimilar() method. * * @author Edmond Lau [edmond@mit.edu] */ public class Trigraph { String[] _keystrokes; /* 3 keystrokes */ int _metric; /** * Constructs a Trigraph out of the specified keystrokes and the metric. * @param keystrokes_ * @param latency_ */ public Trigraph(String[] keystrokes_, int metric_) { if (keystrokes_.length != 3) { throw new IllegalArgumentException("Trigraph constructor takes 3 keystrokes"); } _keystrokes = new String[3]; for (int i = 0; i < keystrokes_.length; i++) { _keystrokes[i] = keystrokes_[i]; } _metric = metric_; } /** * Gets the keystroke at the specified index. * @param index_ * @return the String representation of the keystroke at the specified index. */ public String getKeystroke(int index_) { if (index_ < 0 || index_ > 2) { throw new IllegalArgumentException("Invalid index: " + index_); } return _keystrokes[index_]; } /** * Gets the Trigraph metric. * @return int representing metric. */ public int getMetric() { return _metric; } /** * Two Trigraphs are similar if their keystrokes are equal. */ public boolean isSimilar(Trigraph trigraph_) { return (_keystrokes[0].equals(trigraph_._keystrokes[0]) && _keystrokes[1].equals(trigraph_._keystrokes[1]) && _keystrokes[2].equals(trigraph_._keystrokes[2])); } /** * Two Trigraphs are equal if their keystrokes are equal. */ // public boolean equals(Object o) { // if (!(o instanceof Trigraph)) { // return false; // } // Trigraph trigraph = (Trigraph)o; // // return (_k // _keystrokes[0].equals(trigraph._keystrokes[0]) && // _keystrokes[1].equals(trigraph._keystrokes[1]) && // _keystrokes[2].equals(trigraph._keystrokes[2])); // } /** * Returns the hashcode. */ // public int hashCode() { // return _keystrokes[0].hashCode() + _keystrokes[1].hashCode() + _keystrokes[2].hashCode(); // } /** * Returns a String representation of the Trigraph. */ public String toString() { String s = "(<" + _keystrokes[0] + "," + _keystrokes[1] + "," + _keystrokes[2] + ">, " + _metric + ")"; return s; } public static void main(String[] args) { } } PK az1Zhmodels/TrigraphComparator.java/** * Created on Nov 26, 2004 */ package models; import java.util.Comparator; /** * A TrigraphComparator orders Trigraph first by metric, then by * alphabetical order. Be careful because this ordering is inconsistent * with equals. * * @author Edmond Lau [edmond@mit.edu] */ public class TrigraphComparator implements Comparator { /* (non-Javadoc) * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) */ public int compare(Object arg0, Object arg1) { Trigraph t0 = (Trigraph)arg0; Trigraph t1 = (Trigraph)arg1; // first order by the metrics int diff = t0.getMetric() - t1.getMetric(); if (diff != 0) { return diff; } // if metrics are equal, order by alphabetical order diff = t0.getKeystroke(0).compareTo(t1.getKeystroke(0)); if (diff != 0) { return diff; } diff = t0.getKeystroke(1).compareTo(t1.getKeystroke(1)); if (diff != 0) { return diff; } diff = t0.getKeystroke(2).compareTo(t1.getKeystroke(2)); return diff; } public static void main(String[] args) { String[] ame = {"a", "m", "e"}; String[] mer = {"m", "e", "r"}; Trigraph t1 = new Trigraph(ame, 10); Trigraph t2 = new Trigraph(mer, 20); Trigraph t3 = new Trigraph(mer, 10); } } PK j~16*models/DisorderModel.java/** * Created on Nov 26, 2004 */ package models; import java.util.*; /** * The DisorderModel implements the keystroke model described by in a paper * entitled "User Authentication through Keystroke Dynamics" by * Bergadano, Gunetti, and Picardi. * * The model uses a similarity metric based on the disorder between relative * orderings of trigraph sequences. More details can be found in sections 2 * and 3 of the paper. * * One design issue is what happens if a trigraph sequence contains similar * Trigraphs, i.e. Trigraphs with the same keystrokes. In this case, for * disorder calculations between two trigraph sequences, we use the first N * of these trigraphs in each sorted sequence, where N is the minimum number * of appearances of the Trigraph in each sequence. This seems reasonable * assuming that the test text does not contain duplicate trigraphs, in which * case duplicate trigraphs would only arise based on typing errors. * * @author Edmond Lau [edmond@mit.edu] */ public class DisorderModel implements KeystrokeModel { private String _user; private double _threshold; private List _model; /* List[TrigraphList] */ private Comparator _trigraphComparator; private boolean _isModelBuilt; public DisorderModel(String user_) { _user = user_; _model = new ArrayList(); _threshold = 0.5; _trigraphComparator = new TrigraphComparator(); _isModelBuilt = false; } /* (non-Javadoc) * @see models.KeystrokeModel#getUser() */ public String getUser() { return _user; } /* (non-Javadoc) * @see models.KeystrokeModel#addTrigraphSequence(TrigraphList) */ public void addTrigraphSequence(TrigraphList trigraphs_) { if (_isModelBuilt) { throw new RuntimeException("Cannot add trigraphs to already built model."); } // sort the trigraph list, then tack it onto the model List sortedTrigraphs = new TrigraphList(trigraphs_); Collections.sort(sortedTrigraphs, _trigraphComparator); _model.add(sortedTrigraphs); } /* (non-Javadoc) * @see models.KeystrokeModel#buildModel() */ public void buildModel() { _isModelBuilt = true; if (_model.size() == 0) { throw new RuntimeException("Model contains no trigraph sequences."); } } /* (non-Javadoc) * @see models.KeystrokeModel#authenticate(java.util.List) */ public boolean authenticate(TrigraphList trigraphs_) { if (!_isModelBuilt) { throw new RuntimeException("Model cannot authenticate until it has been built"); } return (meanDistance(trigraphs_) <= _threshold); } /* (non-Javadoc) * @see models.KeystrokeModel#copyModelSkeleton() */ public KeystrokeModel copyModelSkeleton(String user_) { DisorderModel copy = new DisorderModel(user_); copy.setThreshold(_threshold); return copy; } public void setThreshold(double threshold_) { if (threshold_ < 0 || threshold_ > 1) { throw new IllegalArgumentException("Disorder threshold must be between 0 and 1, inclusive."); } _threshold = threshold_; } private double meanDistance(TrigraphList input_) { double total = 0; for (Iterator i = _model.iterator(); i.hasNext();) { TrigraphList trigraphs = (TrigraphList)i.next(); total += normalizedDistance(trigraphs, input_); } return total / _model.size(); } /** * Computes the normalized distance between two sequences of trigraphs. * The distance is only tabulated based on common trigraphs between the two sequences. * @param trigraphs1_ * @param trigraphs2_ * @return double between 0 and 1, inclusive, representing normalized distance. */ private double normalizedDistance(TrigraphList trigraphs1_, TrigraphList trigraphs2_) { // first filter out to common trigraphs TrigraphList trigraphs1 = filter(trigraphs1_, trigraphs2_); TrigraphList trigraphs2 = filter(trigraphs2_, trigraphs1); // System.out.println("Common trigraphs:"); // System.out.println(trigraphs1); // System.out.println(trigraphs2); int distance = 0; int nCommonTrigraphs = 0; for (int i = 0; i < trigraphs1.size(); i++) { for (int j = 0; j < trigraphs2.size(); j++) { Trigraph t1 = (Trigraph)trigraphs1.get(i); Trigraph t2 = (Trigraph)trigraphs2.get(j); if (t1.isSimilar(t2)) { nCommonTrigraphs++; distance += Math.abs(i - j); break; } } } double normalizedDistance = (double)distance/maxDisorder(nCommonTrigraphs); return normalizedDistance; } /** * Filters the input_ to retain only those elements that are also in the filter_. * Returns a new TrigraphList of the filtered input, ordered in the same way. * @param input_ * @param filter_ * @return TrigraphList of filtered input */ private TrigraphList filter(TrigraphList input_, TrigraphList filter_) { Set filter = new HashSet(filter_); TrigraphList filtered = new TrigraphList(); for (Iterator i = input_.iterator(); i.hasNext();) { Trigraph inputT = (Trigraph)i.next(); for (Iterator j = filter.iterator(); j.hasNext();) { //System.out.println(j.next().getClass()); Trigraph filterT = (Trigraph)j.next(); if (inputT.isSimilar(filterT)) { filtered.add(inputT); filter.remove(filterT); break; } } } return filtered; } private int maxDisorder(int n_) { if (n_ % 2 == 0) { // even return n_ * n_ / 2; } return (n_ * n_ - 1) / 2; } public String toString() { StringBuffer s = new StringBuffer("Disorder model for " + _user + ":\n"); for (Iterator i = _model.iterator(); i.hasNext();) { s.append(i.next()); s.append("\n"); } return s.toString(); } private TrigraphList getTrigraphSequence(int index) { return (TrigraphList)_model.get(index); } public static void main(String[] args) { String[] ame = {"a", "m", "e"}, mer = {"m", "e", "r"}, eri = {"e", "r", "i"}, ric = {"r", "i", "c"}, ica = {"i", "c", "a"}, dum = {"d", "u", "m"}, but = {"b", "u", "t"}; Trigraph[] s1 = { new Trigraph(ame, 277), new Trigraph(mer, 255), new Trigraph(eri, 297), new Trigraph(ric, 326), new Trigraph(ica, 235), new Trigraph(but, 235)}; Trigraph[] s2 = { new Trigraph(ame, 298), new Trigraph(mer, 215), new Trigraph(eri, 315), new Trigraph(ric, 306), new Trigraph(ica, 258), new Trigraph(dum, 258)}; DisorderModel model = new DisorderModel("edmond"); model.addTrigraphSequence(new TrigraphList(Arrays.asList(s1))); model.addTrigraphSequence(new TrigraphList(Arrays.asList(s2))); model.buildModel(); System.out.println(model); System.out.println("---- DISTANCE TEST -----"); TrigraphList tSeq1 = model.getTrigraphSequence(0); TrigraphList tSeq2 = model.getTrigraphSequence(1); System.out.println("tSeq1: " + tSeq1); System.out.println("tSeq2: " + tSeq2); double distance = model.normalizedDistance(tSeq1, tSeq2); System.out.println("Normalized distance = " + distance); } } PK j~1FO> > models/TrigraphWrapper.java/** * Created on Nov 27, 2004 */ package models; import keystats.*; import java.util.*; import java.awt.event.KeyEvent; /** * @author Edmond Lau [edmond@mit.edu] * * A TrigraphWrapper is the glue between the KeyList object and the Trigraph object. * Its basic functionality is to take a KeyList and transform it into a List of * Trigraphs usable by the models. */ public class TrigraphWrapper { private List _keyList; private TrigraphList _trigraphList; /** * Constructs a TrigraphWrapper from the specified KeyList object. * @param list_ */ public TrigraphWrapper(KeyList list_) { _keyList = list_.getData(); } /** * Converts a List of KeyLists to a List of TrigraphLists * @param keyLists_ List[KeyList] * @return List[TrigraphList] */ public static List keyListsToTrigraphLists(List keyLists_) { List trigraphLists = new ArrayList(); for (Iterator i = keyLists_.iterator(); i.hasNext();) { TrigraphWrapper tw = new TrigraphWrapper((KeyList)i.next()); trigraphLists.add(tw.getTrigraphList()); } return trigraphLists; } /** * Returns a list of Trigraphs that represent the KeyList that this is composed * of, in the same order as the KeyList. * @return List[Trigraph] */ public TrigraphList getTrigraphList() { if (_trigraphList != null) { return _trigraphList; } _trigraphList = new TrigraphList(); // iterate over the keys and construct trigraphs if (_keyList.size() < 3) { // insufficient to create one trigraph return _trigraphList; } Key k1 = (Key)_keyList.get(0); Key k2 = (Key)_keyList.get(1); Key k3 = (Key)_keyList.get(2); Trigraph trigraph = constructTrigraph(k1, k2, k3); _trigraphList.add(trigraph); // initialize the iterator and skip over first three elements Iterator i = _keyList.iterator(); i.next(); i.next(); i.next(); while (i.hasNext()) { k1 = k2; k2 = k3; k3 = (Key)i.next(); trigraph = constructTrigraph(k1, k2, k3); _trigraphList.add(trigraph); } return _trigraphList; } /** * Constructs a Trigraph from the three specified keys. The Strings used * in the Trigraph are extracted from KeyEvent.getKeyText() operating on * Key k's k.getKeyCode(). * @param k1_ * @param k2_ * @param k3_ * @return Trigraph for the three keys. */ private Trigraph constructTrigraph(Key k1_, Key k2_, Key k3_) { // create a string array of the key representations String[] s = { KeyEvent.getKeyText(k1_.getKeyCode()), KeyEvent.getKeyText(k2_.getKeyCode()), KeyEvent.getKeyText(k3_.getKeyCode()) }; int metric = getMetric(k1_, k2_, k3_); return new Trigraph(s, metric); } /** * Returns an integer metric characterizing the Trigraph. For now, * it uses the difference b/w the release time of the third key * and the press time of the first key. * @param k1_ * @param k2_ * @param k3_ * @return int metric. */ private int getMetric(Key k1_, Key k2_, Key k3_) { return (int)(k3_.getReleaseTime() - k1_.getPressTime()); } public static void main(String[] args) { // get a list of KeyLists List masterList = KeyDataUtilities.readFile("data/data0.txt"); for (Iterator i = masterList.iterator(); i.hasNext();) { KeyList list = (KeyList)i.next(); TrigraphWrapper wrapper = new TrigraphWrapper(list); System.out.println(wrapper.getTrigraphList()); } } } PK 䑅1models/StatisticsModel.javapackage models; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; /* * Model based on statistics of the latencies of the trigraphs. * Users can set the percentage matching and standard deviation * threshhold parameters to vary the authentication process. * */ public class StatisticsModel implements KeystrokeModel { boolean model_built = false; String _user; //name of user List _model; //List[TrigraphList] double dev_thresh; //threshhold of standard dev (number of standard devs accetpable) double percent_similar; //threshhold of percentage matching double[][] stats; //stats of each trigraph (mean and standard dev) TrigraphList control; //list of trigraphs that should be in the model String input; //input string that breaks into trigraphs public StatisticsModel(String user_) { _user = user_; _model = new ArrayList(); dev_thresh = 1; //default value percent_similar = .8; //default value } //input the sentence that the trigraphs will be made from // public void inputSentence(String sentence) { // input = sentence; // control = makeTrigraphSequence(input); // } //make the input into a list of trigraphs // private static TrigraphList makeTrigraphSequence(String input) { // int length = input.length(); // TrigraphList model = new TrigraphList(); // for(int i = 0; i < length - 2; i++) { // String[] tri = new String[3]; // int j = i; // tri[0] = input.substring(j,j+1); // j++; // tri[1] = input.substring(j,j+1); // j++; // tri[2] = input.substring(j,j+1); // // Trigraph trigraph = new Trigraph(tri, 0); // model.add(trigraph); // } // return model; // } //return name of user public String getUser() { return _user; } public void setControl(TrigraphList control_) { control = control_; } //add a sample list of trigraphs (will be filtered against the control list) public void addTrigraphSequence(TrigraphList trigraphs_) { if (model_built) throw new RuntimeException("Model has been built: can not add more Trigraphs"); TrigraphList filtered = filter(trigraphs_, control); _model.add(filtered); } //calculate the stats public void buildModel() { if (_model.size() == 0) { throw new RuntimeException("Model contains no trigraph sequences."); } stats = new double[control.size()][2]; //calc stats for(int i = 0; i < control.size(); i++) { //for each trigraph Iterator it = _model.iterator(); int counter = 0; double sum = 0; while(it.hasNext()) { //sum up all samples of the trigraph's latency TrigraphList list = (TrigraphList)it.next(); if (list.get(i) != null) { sum = sum + ((Trigraph)list.get(i))._metric; counter++; } } //mean of the latencies double mean = sum / counter; stats[i][0] = mean; it = _model.iterator(); double sum2 = 0; while(it.hasNext()) { //sum up all samples of the trigraph's deviation TrigraphList list = (TrigraphList)it.next(); if(list.get(i) != null) { double diff = (((Trigraph)list.get(i))._metric - mean); sum2 = sum2 + diff * diff; } } double inter = sum2 /counter; double dev = Math.sqrt(inter); //standard deviation per trigraph stats[i][1] = dev; // System.out.println("sum2: " + sum2); // System.out.println("counter: " + counter); // System.out.println("mean: " + mean); // System.out.println("dev: " + dev); } model_built = true; } //authenticate the user based on a sequence of trigraphs public boolean authenticate(TrigraphList trigraphs_) { if (!model_built) throw new RuntimeException("Model has not been built: can not authenticate"); //calc mean and standard dev int correct = 0; int incorrect = 0; //filter input first TrigraphList filtered = filter(trigraphs_, control); //find the number of similar and dissimilar for(int i = 0; i < stats.length; i++){ //dev_thresh determines how lenient to be classified as similar double max = stats[i][0] + dev_thresh * stats[i][1]; double min = stats[i][0] - dev_thresh * stats[i][1]; if(filtered.get(i) != null) { double num = ((Trigraph)filtered.get(i))._metric; if(num >= min && num <= max) correct++; else incorrect++; } } //TODO: Delete key messes everything up!!! double percent = (correct / (double)(correct+incorrect)); // System.out.println("correct: " + correct); // System.out.println("incorrect: " + incorrect); // System.out.println("percent: " + percent*100); return percent > percent_similar; } /* * (non-Javadoc) * @see models.KeystrokeModel#copyModelSkeleton() */ public KeystrokeModel copyModelSkeleton(String user_) { StatisticsModel copy = new StatisticsModel(user_); copy.control = control; copy.setPercent(percent_similar); copy.setDeviation(dev_thresh); return copy; } //set the percent similar threshhold (0-100) public void setPercent(double percent_correct) { if (percent_correct < 0 || percent_correct > 100) { throw new IllegalArgumentException("Percent threshold must be between 0 and 100, inclusive."); } percent_similar = percent_correct; } //set the standard deviation threshhold (> 0) public void setDeviation(double deviation) { if (deviation < 0) { throw new IllegalArgumentException("Deviation threshold must be nonnegative."); } dev_thresh = deviation; } /** * Filters the input_ to retain only those elements that are also in the filter_. * Returns a new List of the filtered input, ordered in the same way. * @param input_ * @param filter_ * @return List of filtered input */ private TrigraphList filter(TrigraphList input_, TrigraphList filter_) { TrigraphList sorted = new TrigraphList(); for(int i = 0; i < filter_.size(); i++) { Trigraph t = (Trigraph) filter_.get(i); int index = findIndex(input_, t); if(index != -1) { sorted.add(i,input_.get(index)); } else sorted.add(null); } return sorted; } private int findIndex(List list, Trigraph t) { int counter = 0; for(Iterator i = list.iterator(); i.hasNext();) { if(t.isSimilar((Trigraph)i.next())) return counter; else counter++; } return -1; } public String toString() { StringBuffer s = new StringBuffer("Statistics model for " + _user + ":\n"); for (Iterator i = _model.iterator(); i.hasNext();) { s.append(i.next()); s.append("\n"); } return s.toString(); } public static void main(String[] args) { // StatisticsModel model = new StatisticsModel("chenchen"); // model.inputSentence("ame"); // String[] ame = {"a", "m", "e"}; // String[] dme = {"d", "m", "e"}; // Trigraph[] s1 = { new Trigraph(ame, 5) }; // Trigraph[] s2 = { new Trigraph(ame, 3) }; // Trigraph[] s3 = { new Trigraph(ame, 4) }; // Trigraph[] s4 = { new Trigraph(ame, 4) }; // Trigraph[] s5 = { new Trigraph(ame, 3) }; // Trigraph[] s6 = { new Trigraph(ame, 4) }; // Trigraph[] s7 = { new Trigraph(ame, 5), new Trigraph(dme, 5) }; //make sure it gets filtered // // model.addTrigraphSequence(new TrigraphList(Arrays.asList(s1))); // model.addTrigraphSequence(new TrigraphList(Arrays.asList(s2))); // model.addTrigraphSequence(new TrigraphList(Arrays.asList(s3))); // model.addTrigraphSequence(new TrigraphList(Arrays.asList(s4))); // model.addTrigraphSequence(new TrigraphList(Arrays.asList(s5))); // model.addTrigraphSequence(new TrigraphList(Arrays.asList(s6))); // model.addTrigraphSequence(new TrigraphList(Arrays.asList(s7))); // model.buildModel(); // System.out.println(model); // System.out.println("Average: " + model.stats[0][0]); // System.out.println("Standard Dev: " + model.stats[0][1]); // System.out.println("Number of samples: " + model._model.size()); // System.out.println("Number of trigraphs per sample: " + model.stats.length); // System.out.println("Number of entries per stat entry: " + model.stats[0].length); // // Trigraph[] s10 = { new Trigraph(ame, 5) }; // System.out.println(model.authenticate(new TrigraphList(Arrays.asList(s10)))); } } PK }1BAy &models/ShiftExperimentalFramework.javapackage models; import java.awt.event.KeyEvent; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; import keystats.Key; import keystats.KeyDataUtilities; import keystats.KeyList; import experiments.KeyPressComparator; public class ShiftExperimentalFramework { private static final Map _userToFiles; private static String[] letters = {"A", "Q", "B", "F", "J", "O", "T", "L", "D", "Y", "R", "C", "E", "P", "G", "H", "I", "M", "N", "K", "U", "S", "V", "Z", "X", "W"}; private static String[] users = {"lahuang","sana","rusmin", "mohammed", "lcgibson", "evhan55", "aek", "sprite","ichthyos", "qliu", "chenx05", "edmond", "calvinon"}; static { _userToFiles = new TreeMap(); for (int i = 0; i < users.length; i++) { _userToFiles.put(users[i], "shift_data/shift_" + users[i] + ".txt"); } } public ShiftExperimentalFramework() { super(); } public void evaluateShiftOnAllUsers() { //set of users Set users = _userToFiles.keySet(); //iterate through users for (Iterator i = users.iterator(); i.hasNext();) { String user = (String) i.next(); //find the shifts of each user //List[Pair[]] List l = findShift(user); printPerUser(l, user); } } private void printPerUser(List l, String user) { // print out the information user String sum = "A Q B F J O T L D Y R C E P G H I M N K U S V Z X W"; String sum2 = ""; for (Iterator j = l.iterator(); j.hasNext();) { sum2 = sum2 + user; List list = (List) j.next(); for (Iterator k = list.iterator(); k.hasNext();) { Pair y = (Pair) k.next(); if(y.keyPos != -1) sum2 = sum2 + " " + y.keyPos; else sum2 = sum2 + " "; } sum2 = sum2 + "\n"; } System.out.println(user + " " + sum); System.out.println(sum2 + "\n"); } public List findShift(String user_) { if (!_userToFiles.containsKey(user_)) { throw new RuntimeException(user_ + "'s data file not found"); } List result = new ArrayList(); String userFile = (String) _userToFiles.get(user_); List userKeyLists = KeyDataUtilities.readFile(userFile); Iterator i = userKeyLists.iterator(); while (i.hasNext()) { List runningList = new ArrayList(); List kx = ((KeyList) i.next()).completeData; Collections.sort(kx, new KeyPressComparator()); List k = KeyDataUtilities.removeDeletes(kx); int shift = 0; Key a = null; Key b = null; for (Iterator j = k.iterator(); j.hasNext();) { a = (Key) j.next(); // System.out.println(a); if (a.keyLocation == KeyEvent.KEY_LOCATION_RIGHT || a.keyLocation == KeyEvent.KEY_LOCATION_LEFT) { shift = a.keyLocation; } if (Character.isUpperCase(a.keyChar)) { Pair p = new Pair(a.keyChar, shift-2); if(!contains(runningList, p)) { runningList.add(p); } } } if(runningList.size() == 26) result.add(runningList); } return result; } private boolean contains(List l, Pair p) { for(Iterator i = l.iterator(); i.hasNext();) { Pair j = (Pair) i.next(); if(p.keyChar == j.keyChar && p.keyPos == j.keyPos) return true; } return false; } public static void main(String[] args) { ShiftExperimentalFramework f = new ShiftExperimentalFramework(); f.evaluateShiftOnAllUsers(); } static class Pair { char keyChar; int keyPos; Pair(char k, int i) { keyChar = k; keyPos = i; } } } PK 1aF  models/Control.txt# User Name: Chen Xiao # Nov 30, 2004 1:24:56 PM # Test Sentence = "A quick brown fox jumps over the lazy dog." # Total Data Sets: 10 # 32 = space # 8 = delete # 16 = shift # DATA FORMAT:[ KEYCODE, CHARACTER, PRESS-TIME, RELEASE-TIME ] #------------------------ DATA SET: 0 ------------------------ 16 ? 59763036 59763207 65 A 59763197 59763282 32 59763276 59763359 81 q 59763428 59763509 85 u 59763691 59763754 73 i 59763961 59764018 67 c 59764101 59764201 75 k 59764215 59764391 32 59764331 59764461 66 b 59764971 59765049 82 r 59765072 59765156 79 o 59765180 59765241 87 w 59765306 59765390 78 n 59765387 59765501 32 59765479 59765578 70 f 59765578 59765641 79 o 59765668 59765725 88 x 59765817 59765870 32 59765933 59765992 74 j 59766088 59766131 85 u 59766223 59766281 77 m 59766403 59766480 80 p 59766582 59766630 83 s 59766700 59766782 32 59766792 59766852 79 o 59766950 59767022 86 v 59767084 59767170 69 e 59767280 59767415 82 r 59767385 59767450 32 59767443 59767503 72 h 59767623 59767680 84 t 59767570 59767716 69 e 59767727 59767824 32 59767774 59767851 76 l 59767907 59767960 65 a 59768022 59768110 90 z 59768260 59768329 89 y 59768489 59768629 32 59768610 59768729 68 d 59768781 59768861 79 o 59768861 59768930 71 g 59768991 59769071 46 . 59769109 59769173PK 1}d .DS_StoreBud1ysisfwi0analysisfwi0blobicnvanalysisfwswlongdatafwi0blobicnvdatafwswlongwriteupfwi0blobicnvwriteupfwswlong  @ @ @ @ EDSDB ` @ @ @PK 72~GK} .classpath PK z1Ipp.project Keystroke org.eclipse.jdt.core.javabuilder org.eclipse.jdt.core.javanature PK 1wNzz4/Keystroke/analysis/Disorder Average FAR and FRR.pngXX B EMFzflAT 0MATLAB Figure  kk kk `` 14I 0@P`p 0@P`pp`P@0 p`P@0 0 4Rp"Helvetica| 2 pM|NQ|Hm| oh-  dv |h- w M|p||w+ww1$M`-|p|dv% % ( Rp"Helvetica| 2 M|NQ|Hm|!? h-!m|!dv h- w M|p||w+ww.HM`-|p|dv% % ( Rp"Helvetica| 2 M|NQ|Hm|!? h-!m|!dv h- w M|p||w+ww1&M`-|p|dv% % % % % % % % % % % % % % % % % % % % % % % % % % % % % K@0 0 4K@0 % '% +A% % % K@0 % '% V,o0<dd++% % _888% % W0o0<dd++d% % ( ( % % d% % _888% % 6% % % % d% % % % 6d+d+% % % % % d% % % % 6dd% % % % [% %    T`e?xOVAA[LT0.6% % % % % % 6% % % % % %    Td?OVAALT0.65% % Q% % % % 6QQ% % % % H% %    T`n?OVAAHLT0.7% % % % % % 6% % % % % %    Td? OVAALT0.75% % ?% % % % 6??% % % % 6% %    T`w?OVAA6LT0.8% % % % % % 6% % % % % %    Td?OVAALT0.85% % % d% % % % 6ii% % % % Y% %    TTc3jCVAAYLP0% % d% % % % 6ii% % % % N% %    T`WjVAANLT0.1% % d% % % % 6ii% % % % N% %    T`WjVAANLT0.2% % dt% % % % 6itit% % % % Ny% %    T`WjVAANlLT0.3+% % dE% % % % 6iEiE% % % % NJ% %    T`WajqVAAN=LT0.4-% % d% % % % 6ii% % % % N% %    T`W-j=VAANLT0.5% % d% % % % 6ii% % % % N% %    T`WjVAANLT0.6% % d% % % % 6ii% % % % N% %    T`WjVAANLT0.7% % d% % % % 6ii% % % % N% %    T`WjVAANLT0.8% % dZ% % % % 6iZiZ% % % % N_% %    T`W[jkVAANRLT0.9% % d+% % % % 6i+i+% % % % Y0% %    TTc'j7VAAY#LP1K@0 o0=o0=( _888% % W3;{ ":QiwC(?WhoRD2.% % K@0 o0=o0=% % W02{+.16@S _"h:qQi9\w(?Wo% % K@0 o0=o0=% % W3;{ ":QiwC(?WhoRD2.% % K@0 % % y% % % % 6}}% % % % }% % % % 6yy% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6  % % % %  % % % % 6% % % %  % % % % 6$$% % % % $% % % % 6  % % % % 8% % % % 6<<% % % % <% % % % 688% % % % O% % % % 6SS% % % % S% % % % 6OO% % % % g% % % % 6kk% % % % k% % % % 6gg% % % % u% % % % 6yy% % % % u% % % % 6yy% % % % A% % % % 6EE% % % % A% % % % 6EE% % % %  % % % % 6% % % %  % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % &% % % % 6**% % % % *% % % % 6&&% % % % =~% % % % 6AA% % % % A~% % % % 6==% % % % Uf% % % % 6YjYj% % % % Yf% % % % 6UjUj% % % % mP% % % % 6qTqT% % % % qP% % % % 6mTmT% % % % B% % % % 6FF% % % % B% % % % 6FF% % % % 0% % % % 644% % % % 0% % % % 644% % % % ,% % % % 600% % % % ,% % % % 600% % K@0 o0=o0=K@0 o0=o0=% % W02{+.16@S _"h:qQi9\w(?Wo% % K@0 % % *w'/% % % % **2% % % % *-5% % % % *2:% % % % *<D% % % % *OW% % % % *[c% % % % *d&l% % % % *6m>u% % % % *M}U% % % % *em% % % % *}% % % % *% % % % *!% % % % *5=% % % % *X`% % % % *s{% % % % * % % % % *$,% % % % *;C% % % % *S[% % % % *ks% % % % *% % % % *% % % % *% % K@0 o0=o0=K@0 o0=o0=% % W3;{ ":QiwC(?WhoRD2.% % K@0 % % y% % % % 6}}% % % % }% % % % 6yy% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6  % % % %  % % % % 6% % % %  % % % % 6$$% % % % $% % % % 6  % % % % 8% % % % 6<<% % % % <% % % % 688% % % % O% % % % 6SS% % % % S% % % % 6OO% % % % g% % % % 6kk% % % % k% % % % 6gg% % % % u% % % % 6yy% % % % u% % % % 6yy% % % % A% % % % 6EE% % % % A% % % % 6EE% % % %  % % % % 6% % % %  % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % &% % % % 6**% % % % *% % % % 6&&% % % % =~% % % % 6AA% % % % A~% % % % 6==% % % % Uf% % % % 6YjYj% % % % Yf% % % % 6UjUj% % % % mP% % % % 6qTqT% % % % qP% % % % 6mTmT% % % % B% % % % 6FF% % % % B% % % % 6FF% % % % 0% % % % 644% % % % 0% % % % 644% % % % ,% % % % 600% % % % ,% % % % 600% % K@0 o0=o0=K@0 o0=o0=% % W02{+.16@S _"h:qQi9\w(?Wo% % K@0 % % *w'/% % % % **2% % % % *-5% % % % *2:% % % % *<D% % % % *OW% % % % *[c% % % % *d&l% % % % *6m>u% % % % *M}U% % % % *em% % % % *}% % % % *% % % % *!% % % % *5=% % % % *X`% % % % *s{% % % % * % % % % *$,% % % % *;C% % % % *S[% % % % *ks% % % % *% % % % *% % % % *% % K@0 o0=o0=% % % K@0 % ( % % % % !% % %    T,7A&VAA%LAverage FAR and FRR of Disorder Model    % % % K@0 % % % % % ~"% % %    TdRbVAA~LTRate % % % K@0 % % % % % DM% % %   % Rp"Helvetica 2 M|NQ|Hm|!? h-!m|!dv h- w M|p||w+ww1&M`-|p|dvdv%  T=NsVAA7MLpDisorder Threshold % ( K@0 K@0 A 0@P`p 0@P`pp`P@0 p`P@0 PK 1RDD$/Keystroke/analysis/Disorder FAR.pngXX B EMFDzlAT 0MATLAB Figure  kk kk `` 14I 0@P`p 0@P`pp`P@0 p`P@0 0 4Rp"Helvetica| 2 pM|(6 NQ|Hm|06  oh-  dv |h- w M06 |p||w+ww_006 M`-|p|dv% % ( Rp"Helvetica| 2 06 06 M|(6 NQ|Hm|06 !? (6 h-!m|!dv h- w M06 |p||w+ww9106 M`-|p|dv% % ( Rp"Helvetica| 2 06 06 M|(6 NQ|Hm|06 !? (6 h-!m|!dv h- w M06 |p||w+ww_006 M`-|p|dv% % % % % % % % % % % % % % % % % % % % % % % % % % % % % K@0 0 4K@0 % '% +A% % % K@0 % '% V,o0<dd++% % _888% % W0o0<dd++d% % ( ( % % d+% % _888% % 6++% % % % d% % % % 6% % % % % % % % 6++% % % % d% % % % 6d+d+% % % % d% % % % 6% % % % d% % % % 6d+d+% % % % % d% % % % 6dd% % % % d+% % % % 6d0d0% % % % [% %    T`e?xOVAA[LT0.6% % % % % % 6% % % % +% % % % 600% % % % % %    Td?OVAALT0.65% % Q% % % % 6QQ% % % % Q+% % % % 6Q0Q0% % % % H% %    T`n?OVAAHLT0.7% % % % % % 6% % % % +% % % % 600% % % % % %    Td? OVAALT0.75% % ?% % % % 6??% % % % ?+% % % % 6?0?0% % % % 6% %    T`w?OVAA6LT0.8% % % % % % 6% % % % +% % % % 600% % % % % %    Td?OVAALT0.85% % % d% % % % 6ii% % % % % % % % 6% % % % Y% %    TTc3jCVAAYLP0% % d% % % % 6ii% % % % % % % % 6% % % % N% %    T`WjVAANLT0.1% % d% % % % 6ii% % % % % % % % 6% % % % N% %    T`WjVAANLT0.2% % dt% % % % 6itit% % % % t% % % % 6tt% % % % Ny% %    T`WjVAANlLT0.3% % dE% % % % 6iEiE% % % % E% % % % 6EE% % % % NJ% %    T`WajqVAAN=LT0.4% % d% % % % 6ii% % % % % % % % 6% % % % N% %    T`W-j=VAANLT0.5% % d% % % % 6ii% % % % % % % % 6% % % % N% %    T`WjVAANLT0.6% % d% % % % 6ii% % % % % % % % 6% % % % N% %    T`WjVAANLT0.7% % d% % % % 6ii% % % % % % % % 6% % % % N% %    T`WjVAANLT0.8% % dZ% % % % 6iZiZ% % % % Z% % % % 6ZZ% % % % N_% %    T`W[jkVAANRLT0.9% % d+% % % % 6i+i+% % % % +% % % % 6++% % % % Y0% %    TTc'j7VAAY#LP1% % d+% % % % 6++% % % % d% % % % 6% % % % % % % % 6++% % % % d% % % % 6d+d+% % K@0 o0=o0=( _888% % W3;{ ":QiwC(?WhoRD2.% % K@0 % % y% % % % 6}}% % % % }% % % % 6yy% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6  % % % %  % % % % 6% % % %  % % % % 6$$% % % % $% % % % 6  % % % % 8% % % % 6<<% % % % <% % % % 688% % % % O% % % % 6SS% % % % S% % % % 6OO% % % % g% % % % 6kk% % % % k% % % % 6gg% % % % u% % % % 6yy% % % % u% % % % 6yy% % % % A% % % % 6EE% % % % A% % % % 6EE% % % %  % % % % 6% % % %  % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % &% % % % 6**% % % % *% % % % 6&&% % % % =~% % % % 6AA% % % % A~% % % % 6==% % % % Uf% % % % 6YjYj% % % % Yf% % % % 6UjUj% % % % mP% % % % 6qTqT% % % % qP% % % % 6mTmT% % % % B% % % % 6FF% % % % B% % % % 6FF% % % % 0% % % % 644% % % % 0% % % % 644% % % % ,% % % % 600% % % % ,% % % % 600% % K@0 o0=o0=K@0 o0=o0=% % W0<{ ":QiSzTH(<?3W3o--++% % K@0 o0=o0=( _888% % W0<{ ":Qi|\_B6--(+?+W+o++++% % K@0 o0=o0=( _888% % W5<{ ":Qi(?WoB30% % K@0 o0=o0=( _888% % W0<{ "W:HQ6i63-+++++(+?+W+o++++% % K@0 o0=o0=( _888% % W0<{ ":QinE?3-(-?-W-o---+% % K@0 o0=o0=( _888% % W0<{ ":QinZK(<?-W-o--++% % K@0 o0=o0=( _888???% % W0<{ ":QiV}(b?HW?o630+% % K@0 o0=o0=( _888% % W0<{ ":QiGbQ<60(0?+W+o++++% % K@0 o0=o0=( _888% % W0<{ ":QiTH?3000(-?+W+o++++% % K@0 o0=o0=( _888% % W0<{ ":QihE0+(+?+W+o++++% % K@0 o0=o0=( _888% % W0<{ ":Qi|tH6+++(+?+W+o++++% % K@0 o0=o0=( _888% % W0<{ ":QiTK?(<?6W0o00++% % K@0 o0=o0=( _888% % W0<{ ":QibNN?3(3?-W+o++++% % K@0 o0=o0=( _888???% % WF<{ ":Qi(?WoZE?% % K@0 o0=o0=( _888% % W08{ "k:NQHi663---++(+?+W+o++++% % K@0 o0=o0=( _888% % WM<{ ":Qi(?WoyzE% % K@0 o0=o0=( _888% % W2<{ ":Qi(?W\o900-% % K@0 o0=o0=( _888% % W3;{ ":QiwC(?WhoRD2.% % K@0 % % y% % % % 6}}% % % % }% % % % 6yy% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6  % % % %  % % % % 6% % % %  % % % % 6$$% % % % $% % % % 6  % % % % 8% % % % 6<<% % % % <% % % % 688% % % % O% % % % 6SS% % % % S% % % % 6OO% % % % g% % % % 6kk% % % % k% % % % 6gg% % % % u% % % % 6yy% % % % u% % % % 6yy% % % % A% % % % 6EE% % % % A% % % % 6EE% % % %  % % % % 6% % % %  % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % &% % % % 6**% % % % *% % % % 6&&% % % % =~% % % % 6AA% % % % A~% % % % 6==% % % % Uf% % % % 6YjYj% % % % Yf% % % % 6UjUj% % % % mP% % % % 6qTqT% % % % qP% % % % 6mTmT% % % % B% % % % 6FF% % % % B% % % % 6FF% % % % 0% % % % 644% % % % 0% % % % 644% % % % ,% % % % 600% % % % ,% % % % 600% % K@0 o0=o0=K@0 o0=o0=% % W0<{ ":QiSzTH(<?3W3o--++% % K@0 o0=o0=( _888% % W0<{ ":Qi|\_B6--(+?+W+o++++% % K@0 o0=o0=( _888% % W5<{ ":Qi(?WoB30% % K@0 o0=o0=( _888% % W0<{ "W:HQ6i63-+++++(+?+W+o++++% % K@0 o0=o0=( _888% % W0<{ ":QinE?3-(-?-W-o---+% % K@0 o0=o0=( _888% % W0<{ ":QinZK(<?-W-o--++% % K@0 o0=o0=( _888???% % W0<{ ":QiV}(b?HW?o630+% % K@0 o0=o0=( _888% % W0<{ ":QiGbQ<60(0?+W+o++++% % K@0 o0=o0=( _888% % W0<{ ":QiTH?3000(-?+W+o++++% % K@0 o0=o0=( _888% % W0<{ ":QihE0+(+?+W+o++++% % K@0 o0=o0=( _888% % W0<{ ":Qi|tH6+++(+?+W+o++++% % K@0 o0=o0=( _888% % W0<{ ":QiTK?(<?6W0o00++% % K@0 o0=o0=( _888% % W0<{ ":QibNN?3(3?-W+o++++% % K@0 o0=o0=( _888???% % WF<{ ":Qi(?WoZE?% % K@0 o0=o0=( _888% % W08{ "k:NQHi663---++(+?+W+o++++% % K@0 o0=o0=( _888% % WM<{ ":Qi(?WoyzE% % K@0 o0=o0=( _888% % W2<{ ":Qi(?W\o900-% % K@0 o0=o0=( _888% % W3;{ ":QiwC(?WhoRD2.% % K@0 % % y% % % % 6}}% % % % }% % % % 6yy% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6  % % % %  % % % % 6% % % %  % % % % 6$$% % % % $% % % % 6  % % % % 8% % % % 6<<% % % % <% % % % 688% % % % O% % % % 6SS% % % % S% % % % 6OO% % % % g% % % % 6kk% % % % k% % % % 6gg% % % % u% % % % 6yy% % % % u% % % % 6yy% % % % A% % % % 6EE% % % % A% % % % 6EE% % % %  % % % % 6% % % %  % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % &% % % % 6**% % % % *% % % % 6&&% % % % =~% % % % 6AA% % % % A~% % % % 6==% % % % Uf% % % % 6YjYj% % % % Yf% % % % 6UjUj% % % % mP% % % % 6qTqT% % % % qP% % % % 6mTmT% % % % B% % % % 6FF% % % % B% % % % 6FF% % % % 0% % % % 644% % % % 0% % % % 644% % % % ,% % % % 600% % % % ,% % % % 600% % K@0 o0=o0=K@0 o0=o0=% % W0<{ ":QiSzTH(<?3W3o--++% % K@0 o0=o0=( _888% % W0<{ ":Qi|\_B6--(+?+W+o++++% % K@0 o0=o0=( _888% % W5<{ ":Qi(?WoB30% % K@0 o0=o0=( _888% % W0<{ "W:HQ6i63-+++++(+?+W+o++++% % K@0 o0=o0=( _888% % W0<{ ":QinE?3-(-?-W-o---+% % K@0 o0=o0=( _888% % W0<{ ":QinZK(<?-W-o--++% % K@0 o0=o0=( _888???% % W0<{ ":QiV}(b?HW?o630+% % K@0 o0=o0=( _888% % W0<{ ":QiGbQ<60(0?+W+o++++% % K@0 o0=o0=( _888% % W0<{ ":QiTH?3000(-?+W+o++++% % K@0 o0=o0=( _888% % W0<{ ":QihE0+(+?+W+o++++% % K@0 o0=o0=( _888% % W0<{ ":Qi|tH6+++(+?+W+o++++% % K@0 o0=o0=( _888% % W0<{ ":QiTK?(<?6W0o00++% % K@0 o0=o0=( _888% % W0<{ ":QibNN?3(3?-W+o++++% % K@0 o0=o0=( _888???% % WF<{ ":Qi(?WoZE?% % K@0 o0=o0=( _888% % W08{ "k:NQHi663---++(+?+W+o++++% % K@0 o0=o0=( _888% % WM<{ ":Qi(?WoyzE% % K@0 o0=o0=( _888% % W2<{ ":Qi(?W\o900-% % K@0 o0=o0=( _888% % W3;{ ":QiwC(?WhoRD2.% % K@0 % % y% % % % 6}}% % % % }% % % % 6yy% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6  % % % %  % % % % 6% % % %  % % % % 6$$% % % % $% % % % 6  % % % % 8% % % % 6<<% % % % <% % % % 688% % % % O% % % % 6SS% % % % S% % % % 6OO% % % % g% % % % 6kk% % % % k% % % % 6gg% % % % u% % % % 6yy% % % % u% % % % 6yy% % % % A% % % % 6EE% % % % A% % % % 6EE% % % %  % % % % 6% % % %  % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % &% % % % 6**% % % % *% % % % 6&&% % % % =~% % % % 6AA% % % % A~% % % % 6==% % % % Uf% % % % 6YjYj% % % % Yf% % % % 6UjUj% % % % mP% % % % 6qTqT% % % % qP% % % % 6mTmT% % % % B% % % % 6FF% % % % B% % % % 6FF% % % % 0% % % % 644% % % % 0% % % % 644% % % % ,% % % % 600% % % % ,% % % % 600% % K@0 o0=o0=K@0 o0=o0=% % W0<{ ":QiSzTH(<?3W3o--++% % K@0 o0=o0=( _888% % W0<{ ":Qi|\_B6--(+?+W+o++++% % K@0 o0=o0=( _888% % W5<{ ":Qi(?WoB30% % K@0 o0=o0=( _888% % W0<{ "W:HQ6i63-+++++(+?+W+o++++% % K@0 o0=o0=( _888% % W0<{ ":QinE?3-(-?-W-o---+% % K@0 o0=o0=( _888% % W0<{ ":QinZK(<?-W-o--++% % K@0 o0=o0=( _888???% % W0<{ ":QiV}(b?HW?o630+% % K@0 o0=o0=( _888% % W0<{ ":QiGbQ<60(0?+W+o++++% % K@0 o0=o0=( _888% % W0<{ ":QiTH?3000(-?+W+o++++% % K@0 o0=o0=( _888% % W0<{ ":QihE0+(+?+W+o++++% % K@0 o0=o0=( _888% % W0<{ ":Qi|tH6+++(+?+W+o++++% % K@0 o0=o0=( _888% % W0<{ ":QiTK?(<?6W0o00++% % K@0 o0=o0=( _888% % W0<{ ":QibNN?3(3?-W+o++++% % K@0 o0=o0=( _888???% % WF<{ ":Qi(?WoZE?% % K@0 o0=o0=( _888% % W08{ "k:NQHi663---++(+?+W+o++++% % K@0 o0=o0=( _888% % WM<{ ":Qi(?WoyzE% % K@0 o0=o0=( _888% % W2<{ ":Qi(?W\o900-% % K@0 o0=o0=( _888% % W3;{ ":QiwC(?WhoRD2.% % K@0 % % y% % % % 6}}% % % % }% % % % 6yy% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6  % % % %  % % % % 6% % % %  % % % % 6$$% % % % $% % % % 6  % % % % 8% % % % 6<<% % % % <% % % % 688% % % % O% % % % 6SS% % % % S% % % % 6OO% % % % g% % % % 6kk% % % % k% % % % 6gg% % % % u% % % % 6yy% % % % u% % % % 6yy% % % % A% % % % 6EE% % % % A% % % % 6EE% % % %  % % % % 6% % % %  % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % &% % % % 6**% % % % *% % % % 6&&% % % % =~% % % % 6AA% % % % A~% % % % 6==% % % % Uf% % % % 6YjYj% % % % Yf% % % % 6UjUj% % % % mP% % % % 6qTqT% % % % qP% % % % 6mTmT% % % % B% % % % 6FF% % % % B% % % % 6FF% % % % 0% % % % 644% % % % 0% % % % 644% % % % ,% % % % 600% % % % ,% % % % 600% % K@0 o0=o0=% % % K@0 % ( % % % % K!% % %    Tq&VAAKLxFAR of Disorder Model   % % % K@0 % % % % % H"% % %    TnRbVAAHLxFalse Acceptance Rate % % % K@0 % % % % % DM% % %   % Rp"Helvetica 2 06 06 M|(6 NQ|Hm|06 !? (6 h-!m|!dv h- w M06 |p||w+ww_006 M`-|p|dvdv%  T=NsVAA7MLpDisorder Threshold % ( K@0 o0=o0=_888% % W0<{ ":QiSzTH(<?3W3o--++% % K@0 o0=o0=( _888% % W0<{ ":Qi|\_B6--(+?+W+o++++% % K@0 o0=o0=( _888% % W5<{ ":Qi(?WoB30% % K@0 o0=o0=( _888% % W0<{ "W:HQ6i63-+++++(+?+W+o++++% % K@0 o0=o0=( _888% % W0<{ ":QinE?3-(-?-W-o---+% % K@0 o0=o0=( _888% % W0<{ ":QinZK(<?-W-o--++% % K@0 o0=o0=( _888???% % W0<{ ":QiV}(b?HW?o630+% % K@0 o0=o0=( _888% % W0<{ ":QiGbQ<60(0?+W+o++++% % K@0 o0=o0=( _888% % W0<{ ":QiTH?3000(-?+W+o++++% % K@0 o0=o0=( _888% % W0<{ ":QihE0+(+?+W+o++++% % K@0 o0=o0=( _888% % W0<{ ":Qi|tH6+++(+?+W+o++++% % K@0 o0=o0=( _888% % W0<{ ":QiTK?(<?6W0o00++% % K@0 o0=o0=( _888% % W0<{ ":QibNN?3(3?-W+o++++% % K@0 o0=o0=( _888???% % WF<{ ":Qi(?WoZE?% % K@0 o0=o0=( _888% % W08{ "k:NQHi663---++(+?+W+o++++% % K@0 o0=o0=( _888% % WM<{ ":Qi(?WoyzE% % K@0 o0=o0=( _888% % W2<{ ":Qi(?W\o900-% % K@0 o0=o0=( _888% % W3;{ ":QiwC(?WhoRD2.% % K@0 % % y% % % % 6}}% % % % }% % % % 6yy% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6  % % % %  % % % % 6% % % %  % % % % 6$$% % % % $% % % % 6  % % % % 8% % % % 6<<% % % % <% % % % 688% % % % O% % % % 6SS% % % % S% % % % 6OO% % % % g% % % % 6kk% % % % k% % % % 6gg% % % % u% % % % 6yy% % % % u% % % % 6yy% % % % A% % % % 6EE% % % % A% % % % 6EE% % % %  % % % % 6% % % %  % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % &% % % % 6**% % % % *% % % % 6&&% % % % =~% % % % 6AA% % % % A~% % % % 6==% % % % Uf% % % % 6YjYj% % % % Yf% % % % 6UjUj% % % % mP% % % % 6qTqT% % % % qP% % % % 6mTmT% % % % B% % % % 6FF% % % % B% % % % 6FF% % % % 0% % % % 644% % % % 0% % % % 644% % % % ,% % % % 600% % % % ,% % % % 600% % K@0 o0=o0=K@0 o0=o0=% % W0<{ ":QiSzTH(<?3W3o--++% % K@0 o0=o0=( _888% % W0<{ ":Qi|\_B6--(+?+W+o++++% % K@0 o0=o0=( _888% % W5<{ ":Qi(?WoB30% % K@0 o0=o0=( _888% % W0<{ "W:HQ6i63-+++++(+?+W+o++++% % K@0 o0=o0=( _888% % W0<{ ":QinE?3-(-?-W-o---+% % K@0 o0=o0=( _888% % W0<{ ":QinZK(<?-W-o--++% % K@0 o0=o0=( _888???% % W0<{ ":QiV}(b?HW?o630+% % K@0 o0=o0=( _888% % W0<{ ":QiGbQ<60(0?+W+o++++% % K@0 o0=o0=( _888% % W0<{ ":QiTH?3000(-?+W+o++++% % K@0 o0=o0=( _888% % W0<{ ":QihE0+(+?+W+o++++% % K@0 o0=o0=( _888% % W0<{ ":Qi|tH6+++(+?+W+o++++% % K@0 o0=o0=( _888% % W0<{ ":QiTK?(<?6W0o00++% % K@0 o0=o0=( _888% % W0<{ ":QibNN?3(3?-W+o++++% % K@0 o0=o0=( _888???% % WF<{ ":Qi(?WoZE?% % K@0 o0=o0=( _888% % W08{ "k:NQHi663---++(+?+W+o++++% % K@0 o0=o0=( _888% % WM<{ ":Qi(?WoyzE% % K@0 o0=o0=( _888% % W2<{ ":Qi(?W\o900-% % K@0 o0=o0=( _888% % W3;{ ":QiwC(?WhoRD2.% % K@0 % % y% % % % 6}}% % % % }% % % % 6yy% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6  % % % %  % % % % 6% % % %  % % % % 6$$% % % % $% % % % 6  % % % % 8% % % % 6<<% % % % <% % % % 688% % % % O% % % % 6SS% % % % S% % % % 6OO% % % % g% % % % 6kk% % % % k% % % % 6gg% % % % u% % % % 6yy% % % % u% % % % 6yy% % % % A% % % % 6EE% % % % A% % % % 6EE% % % %  % % % % 6% % % %  % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % % % % % 6% % % % &% % % % 6**% % % % *% % % % 6&&% % % % =~% % % % 6AA% % % % A~% % % % 6==% % % % Uf% % % % 6YjYj% % % % Yf% % % % 6UjUj% % % % mP% % % % 6qTqT% % % % qP% % % % 6mTmT% % % % B% % % % 6FF% % % % B% % % % 6FF% % % % 0% % % % 644% % % % 0% % % % 644% % % % ,% % % % 600% % % % ,% % % % 600% % K@0 o0=o0=K@0 K@0 A 0@P`p 0@P`pp`P@0 p`P@0 PK 1Ωcc$/Keystroke/analysis/Disorder FRR.pngPNG  IHDR>_ pHYsgRtIME  Y"tEXtCreation Time02-Dec-2004 23:09:02O!e$tEXtSoftwareMATLAB, The Mathworks, Inc.R IDATx]v:.PqZS-Kefd 9Pvju:%tJ @)S!@BN :%tJ @)S!@BN :%tJ @)S!@BN :%tJ @)S!@BN :@QmM?מo =ȭ;T,5?㏮m>r;v$Uy6he)fp^֟W[*l5>E[ю*R! 鋏?l*#Y3ӯ]u%_j:Y8}g(L(^3E>5Ghg+Y>r(Om.Qowwǣ}4{徭G~\_㑗@a!@f&f ǟ?6cAy?*ի+7J|{^fͲ g!# oÐ~egF&sviޥ7baNͅXXB( ]y) GJkYLxj[sڠj%cջ Z}u<߿o2a>Of;gc& *Ҽ \H =@!(\$GY8lRc }=Z^[>:#%OdBj! =5 RXk5QcAHgApAD&4W9SL75ޯ<:/ ii#5( I0O  L}qi1f|a}}6)/KX$>6#ǠH ]F_S~ڌ ~ݏ‘xg ͕ ݟɄ@l!狐 #z 50~~5: Bcui&4DL84Rf׊yT_^m=YH8軿#@H6gy:(*CO+ULȳwG 4EBH8w3O{QX9"݃J +\(T&lp̸WKg清s[qiq8=PEf΄ ! e<w6>=bfN)my{YP<Kc=5OH_c͜S9baqP#>;E: sfĹ^|$@v#zt́ :NG%򱰱qDq[LK 0Mw[dMZߡZ?HA3%rș  \!̄CU?)nC3Kisr$y:Y:B5P һѦRj[{+k3K&d^7_EBO Ƚf[o3aj;2azF{h{9'g)*r&ZIG }i5w{2S*,Ν~l;lZ*P_;{ó"bB@ $8}11>zBoM)*|Lu>}ט }8>n3S+)}~uu},<Bئ۩lrܹOK/mHgA^P$T%EػBgwx; "vi|pyoءٳ_ǯ!HHBJHNa=#)D y*zY:sݞhڧN5oPd]!N=  >͢n~ʳ [3^yzXI2JP&f4*Ǻ KdPs Ǵf(T8qXOLMN3JoG(v"Z4h`@Hh2aRi8S|GkW5lB.x2eĿG:;t0Q__߃$['| 9kZB0獲鼽}ca50{g&4JB(L $0, `F.HkXCH`Z7~هR__?]I'a4^J$T}tYjlr)+Ұ&*G!i8ڀɥ0[~ S:@]nGAIuτ1+Xa3a9>90l?gAZ]8Z5^n-*ݾOǀn? 넊43xحqZo5Uq1r Ʉޝ5t)V3]_s*Hؾ a(^n*fZ6G"!OfO9wm3  @j4~%yD907)t/SP?<~v'S<{xz_[~GPDk};|D7xG(arj_Vq4yw1$\я,sҬM͸ >y7("IK(`;Yg"!\G LcS\a[3NX8y7TeiE:%fwD4*sS3Gy6IuޕGZeQe˙^*+3Z]Fd DSJI A9$}iSӒb!Y$NɄ<I/qoc8|y0JW?ÇOHNA#rf98p§xK_&x&t߼l,]R-P0\#G88 sx̄fc,\[P%/ T$@XT$ /_Bsbs^4 $}Y>'ʟRyMwHNj H ,uЭdPey{"D:yݏat -#* $Vemۆ&U&F?Q$ mN$J&[FW q*SՖ0*DD 53~cyuc.˥  6:@1!&^dĎSO% 3pp /rL8="TcOቬ߀RB|`6S^gܾ{Z}YHu;R$4# V? )W#f;SnJjS"uBHȥ7~m'³V䢀C+ τQ0|*H^{xT 6\ iLh`ǯj[a;;5:BΠTwՔy[O()2 ;j@\ &n! 9kpaʎ߬@!OB:مgp^e?z@ {Iy% -#lB- -Bp'+c e(|ϦJV!^$$c0uu8 Y+x/F@HGgwRz [CxxG@!qZSIA0PCj8g(l"EBN~MO+̏B&RkpaS2N?)p."4JMOBZuQ0!4і[3@BzBw>+QN;#i#P'8 B LX2jh</,!@>5h"3a i҉36=vOEžgHמ@h@̄nLT*|_nuM>Pkr(Oo":ᯀEBx4ەkL9vSkk.t@ŻR_gi汫tGS/E oکETfLTcixNWP)vEBx>(]*kAMvD-# A %q2a))3ldB:'tgGQ1"!m̈́f >P$"uǤ>%* qOG+EB`(8EB8ݑRpx ȄI Lt S!|`\rp{ʄf#VQ$ Fߕ o_?~܇`}>90kTǝwe!%ҼRׯ_:I0ܦR}}nFO9BK3aEB:_Ʉ@\@$`%i軖V"! @(rםfYkyLA`B|(̈́ h%T8c M " (uQRLy!!BapzKGHH{?_\vx6|}݇;ʄajVaiOqne{W'U/UTZ4 ̐M˙ }T;1}M~s鲟S|u0l cӒ i@T/҆=\\Hu3aVZS83$a1M l&|ݿ~~> y'm i@]Fo:Θ8J:uJ@W]d{0}[߻)/+M O|@^ X؋pEBʘ~8äFd‘ BhA)Mylu]T i@X(m3'Wpa IDAT;w6nV6 qTEB6vJ|ZpάQ"eх0{3CtFN  Yg}Dz@݆NVSMe %BinsYWo&Ǥ>"P$$&*0 fȄ]OyFHM  !rEBN.:RӴ{r# G{Tuqx"1kBFiiϖ4h9."!o߬)>uk]+1 P:HJSmPprm4 @˄;~5skZ/i@%*j2[FJ L%ĺDa":63|!6Uh2!EB1<. B_(锽%#A 8a BB,m& H!ޅS$©6U @ @ uIc.4ۆ{WN%@T|2:7G&bᓐ56@=Jx{%+8'.km*=!{KԠιGKYfR@R$EwaH8RB3x%s"˝8WP N$B8҆bc0*BIX3 df~ G (|y >pM]N{ę# il*{X"PkH0NϔslzZլхN~EBHetEZBՀ:Ўk˙}։WQZ ZI8@E[D¢"^IOu?{(1i@Տ~f:l4 GK{f\gH8fW Qehpsgo]U֗g{z@X\A A'kq!a!O 6Ltpr+?(g6h]?}ݿmNԕla> 7G(E wtK }&Y !"  |I E s+EC'c3@׮HȉB*y0H5Wz#4kAMNlo* T@XFH/2& H)ZA"Б.l4 P@@iG[gӳedH)BB]#z!iՉ|LD'V- BwIjq!WVDS^ '-4GF#W3!%a+ۄB =@@-Ks EB%D736!S$dVe ed'kYFĹf聺B" 50aVZ5뵊ShPֵ!|&L&BnW,#Խ[+ 5IxbqWJ ocZ Դs <B0aE Xb[ E&!i2ktHc*{8TfqWJ Z̈I ލN TP$5v<#B @W:hrF VHh|Q B ;6eta!S$\ HJ FXFȐyrF':nyo'и#%@I'S@DH7h@@4 ЎsGaNL.8gu. f@WŘLa!@SD:.?tG7h@@ugJ4I |vۨ7Ff?g=Q0k0q9E!QMEMX '};}:4FY % o)-xUn}eZH9a;M׎Հ6Pe#qF(B@daMer9q6[ȱ2B1*?H.B-v meE@jOƬ"ac;XO `jyu0GJt ,qjC \_%t%HD ES5{+4  ͎F iۉFw+sd+ֈ3+aa9G{  (Hs)0:1DH ]FtWS{˲g'(f KmnMsoxU>Kҳ'v]FRiK@c&|*d˛._ MX)w?'e}"o4A \c1j)9kЏ.i\x%B,#|R&ݹۅ!Yݾ}#HЕT ,e."~v[Tt}~6@]"@|іsQv^W ~um<>a❺G+_FcG][__H 4s'gR@?N|<뚭 ~P=XG;49 ЂȱI@BrȘL͂2^\<q}ehvK&yU T#S%=`ޅH@L*MA #4/2;Sy (}JKd*$-r)u4+@d)J_F* &:eaZM F%gO@3: !22f! ;, Gq+fVQRV珰@B;v`a'}j2&A3Y@.jvjuZH:A*j s4s(ݡg 7;T|5C0!*i@@,n_K '&KPe!.y hFiLY4CeFeh@i!AVr/3ްLBc!M>m'`dn 4H 'Ќevh_3cHG>w=[?iH{Nk?[QƦ2z47tD>6/+W-\x6A2V/m:Ǐ~& J$4o@[B`'Bk ?~i8@bʸzaEMwJ=,#dp8YԾ23,'OE |6T (W mL\/pWRBۍtDe4{#>oTxp-3cƩ٪K%^\LZf+ '5 }ۨRlU %j |kx+! C:y~iĜ= M:Hga_[δ@8ovv nfQf0'rAhOѮi~0[ =v2cаat s\B9vґ>u V+a4 IE ̻zu.#057!@XI[.ht펳 SNf+ >=oO?`4ŴQaog@a[c$N,]>ҧ/*%5 JzuO%a P߾οCT@XS[S} >DmF{ǏǼ_u 7}A[; y'48Gu|y'BйMl0aHA ZљM8@.kuDL!4N&vs"IWBztVFpWË́65a?l@dzl`>vG 7) ޫ{p%ݞ^blE/I.oX)R6G 'JXF6p}p;}dGޝ$8}"Y'.5}S&k@ӊAKHhQS{2 BSi^j'v]3 |+2pB# 2a- o6@Cg#·~_[o?E3?ć B.+@L`H.Vτ6:K0pɻw.C28Yae%$L4BiI}e&Zc}XO laQ NegU/j})zG&\@-/5e.A&y<=n>^Ⱦ{F@ d>T&>]+n ń [h*9YKqF.4}L=!&{|"œ'q%q_^2%[ߠ 2€*m4 P@daBh8G+G:c؏5 2  5d[mJ4ƾ2Wy}4Оv5ZZRSD<f(+C.lWbnruyCR0z7 2-#lr=&d .YxN ;ؼ9Wc2OUKf6tȾ2tkQ(Ҫ5U?@E#AS\Ln2@IgO&{~ݾ}1)VH ` ~DeBN2l̄3_xW^@1 >~_&ens26Xl 2wfw @^0NWl 7C *6f}||_KA Yտml3es?_M+5$.yy̻fQ'O#| +#(1Bl"~ J/ tnb?(X梷p*\+,#d$rQҏאcႅLqRTj x>iwy$+=(IAbF_0\LSIpR_d'~dBXkh9*p^>q}]fp1 WSVȾ2t+r1_F.Tԝ! >~SIDNl2ž?$9xC \$6A i.6l%! n @?E,ovV~3kO0$Iw3]`A lVeBhfNʃyE(`2MF*ePFy 0 I4W|#hLY'6[ЉՏ@챵-2rd{&ә.Q / .v Pq{0j,8 e_8^hI%I >rwTIXLhQY%c2|F(K ©H/ }b'@O_>7>sʋPPj@DyuZ_m9]!@*o[w|4Ճb$:t*SL~yP=I/A,(XF7d#(k P@WfL-K)I {J`VNkoLy!}e'?$<+.1˹Vm"yj#Sv0B'Ywj@F4LS{!MRE w$Cl4JR62|H,oXF!R'&7H\L `6*NĢ rHD J'p9qWoNJ!|?V'=AֵF I"gi !{(qeðzNsr/|p1,B8A̤^,a33B6h/`@B&ˈ *U"GWvptsq}`+m51XFXX-|Z cMФ?-FMJ4q. &KW4_I;l%=SB63 D&x1 .;IL?B4g}զ(r+l!ps`*;&({ 5|i@}e/ δ#lx0M۲:9@.Tԝ<>RC8ξ2d -Ou*BPK}56޲)fw߇֤jm\y&,#,c?~% T$W귟_cQ@j Ntui営@ $!"/#짮+B\v2ӤqSsun}˕ KOuvk@:!4#8HW1fYFBs&J6h`8rӰzP>2B])Gq;gE7i&uT'gJ-7U|ZwmߠR(xf6j0xbUs@.G~Awp Dw`$5,r Z3+Js߇?LB S"~TV ZSj߸RS྾2R {$5j=) YXFaQEr:}鬠@!gg:Pc~޸w{CōdV l4 xD  'VBf,dBZKMҞܚ2!-j),#,)G(N/EA`?yWO POTsxkb$Ѥ5Nd&+& LowܷWs364\6 ̪20\u&0iiFd v FR IDAT0%;dea0Em߿}8.xu@F˙^z+TjQ^9ALW̅N~E”VnE3aF3agQ]pN~EB*6]Tl6 !pkA,#̥X7|`3yw 5a*"9leV 9l42hdBrRYG ,j*>JsjR*Sl1S+aiOoMgDW^Ẅu=-g*еw ,TVcRA Ϳ}+;cO[,C-@n4iFcZ~_>u%YRX uhOKB!F\.i|"ײ(19[g)R @| ү7-5h@bn iAy#l=J,#BJPbzkNߔLLJk:D&[7kaܒx Eg J-N`pBr[ &n['^5B HCSh@i/!GB`emmm=Je_ KBiehW@D1wS} HÃMV4@ Jn#~HJ2Ȅԡ1G ݦN\D OaQT$|SfkQJx!AgNFaa\\G OgN Y i.ByABJ kz̈́ Uk|F@ᱣ~Ya8}6cL@\:@ sih*bEI/ ֣%"SWuΦ1>ړtk@9&Cp4 \3k42¢ok NW&>05i`: ε/ ]yݾ}ɋTiﺯYYW0fݶd>6߾b>crULHxu*F߇B4Ax b.#$68O&ggk-# N ,g+c4Ho"!nJ%-=Y 2'DZ'5 7MzJzO{(Mۖq& .8y3WKX aiOO1kY[e0m1-fadax$I1j u-UN@B'`qܨA30<{Db|T?B.!q5 O:Z?>6$|!'L \j6>=~ #ŘΦm<Nk ]{rvk_B 4Fy'Wūr5:f_?Yvvd+Nh2X erX @z&,c^Y͖\%2F @t2{dPDwyE  Pӊqי'N? T!@ uaYgZȄ9xZ$ 5ʲԡ)Ie:'x2?[@ t#H k p-F"7Sb<$@2EDaF7'7G r0k:kJU%zɬߌ@ S~g7# F:7sVw"0c% @fҌRU"! }eFb!$ДEB)]Swv U *8X$>~INT'иhEz^;O/Y9 p@PTq'M4T&cAlzϱOPe! w%f)jPX}e"e8UH({a<qיǛ\MBh־X'^N oB$З uHG,QHgpX^O( J!ۻYvnIdd&gI>k4-F?>~%N꘱UXRѣ;Cߥ 7 @u5)`)̲#1# H|3mw@4ea3aA\ڭ.ě>-Ydeu PloykpMlK]<ZښO豉k} ?R$<(u?Gwpv vO PSnds&loqOHhvsz J k1JzbhnGY,@}aHXY]7 @#TTحzа묕$"Lj1E깽U*3 B}nFqy9JqĬaZc'C a(*@• !7 AڲuXYS*\P7z_.R#x%vpG W yW֝~̶6BQ80hYh*%gaPWU4Sf3"Хc,3H4aZ<q2aOG `߿X ҭ.yԢTH;B ,) xpShCRaYI V׾ 8uT*u&#5f͝ G Ϻz$ TH-a q_UH[&l^ztQ*l#397׭EBٝ\T*D0ku^*<0KZ H 3kK-DAʬ*[Ru:ybBMfRҹM4c0TmglWjXXp)&7V/c K;ah?nHSz7vb>^^CrLJH8,r EH ߼[@*t*Q8,*?}z!2EBjJ&MH07g۾M9Np>*y48G>(m MD;)vB&<ٟ75BqThivAD[92ᛣ4$Q@XT$ /4RDaw;ΎhLw5G&6g(NIa[KUhY_#d,6IZua˛.ok]'rQR*ܞ{(~L{@]HvHX>ZY"mY3qk{@/f*Y2$md·NPd=8a5r*#(jgYid"!$0k4X®.2Nj@]C."@M3LʕLK̄OHJ}*Dޞ6Iј[ttzJ6A"fǯihG2B;7KpzQ"jx"n]z瑍oz9nsi)!ԷanHQ%>JA!УhzuJP&(K1V3a`܀!f&}4WfO  ds;!Yf6){1}"B_u<Ü[K]$NɄeKo@q[l#k@tM&$ zILrDL}@;z3nf :}41I zB(6~LxJ v UHo!U3aT@C42RfMh$׬A:2`oB1ì5zE:74 ;!'P&߇M@0 jI 7^\L8j 7}ؖdts)s>wt3a΄!5BDBHc05ZH8΄W4Ej!_SފP'<|&JPnw]D d??E!Q&dI&J41 ~!72\2pHtPN"!T,n%܊ ^}sNO xw}|QX"=q2a>IB~ Sk;pHX8D HHu7L:qAL*^(R6dBx0[oń2a^2"5 G ,q#}.dEULpC\x" oe/Е @M ,5:(^h5@;YԪk]Zdd EʄSmЪŒB% YhSl6äy_<2a"!ת gZU@M2pFҕC4{u&\#u&T$lҘP*B 5FXkWNVe:bB \S*B +C*Zc(\]X,&.τyc!W Acy]uTp #N&LZ*T$VL{'fFd .EXLHFJa ЬNՏLǓfB.aR0&`-12pkA%Y&[τJrJr }q%a:{Ʉbe G3!J2/3aB sLvV-^\ Iw /d^f>,I2ݼpm~ g~枤Ƭu]j̄ r~]qưO0rBX3Tx# +V8:Z[*r# 0[&d7 \jV$$6JARu!UPJzWP!@&mX.*D'brs܁fO_G>!瀺f7 n63L|ހt;(RT=_s,_a 6H1 ag8 3/y)>: mi7it,sG"EFgzI^DCB(JBOz]Uxu&^UX-?*ܾp dA,,/^LxɡA!0݇dB:OzjWr]hyJZ+-zveA,,/v{}8̧^nW P$$RaL8\o^>|[*>m2 T=ßՃ$ P"!aIzlP&s'Η U{2o,$2B׃݆$B!] SRxxz&VyD ċVGBxɡA!#YG|8?}5¿k2 Gba H YOk9@sbWi%NtbrLwc>Ήmj*ba 2ܬQݽA:m ﴚ t-= ?fSZKR3ްX*h*^.Rs pwO6MwMf/(-C%+:LSp9ZB'NjϥS߳^}z(^+Lz}DCk{ipic=RKPkL8 k!Z _ϥ³߳w0H&w +V & FeD~G 2ajH)QkvXmɻ\a*+zL ҏjib_9b8T-#z .S *(Z=Wۤsz&l[*ba/jg^RdB_ʩ&vUˠzNj9=T+ ?[W1GL/h`^@HW|{Z8T-:n*]-# '2g I,~:-,qQ2Vöʄo`'A r2G?!@P!@P0=q'Y{yq?&Նm9h!q7g̒P?,eIImض0᠅ -`w`,72N~Na2\`* z򭸟N1%eIڰmA [C (BBBBBBBBBB<{4봚1KsZKaq!7CqaIż]!j%]/ۆ!< 8Bv=0J_bL%y_\%zsK׻z/l$?N&Po~-Y+mJW*fl=Ol̇9`Ж!DK*~IDATGɤS)~|^c5HJ&2YMppE>?JϦW>L\5O#X݄ OT\<+kVZLD\Ud'w-Ӟ}lZX)~$%4ɌiL}*_>r@!m|Ld&3?YqTn-O,Y@@.y -o|4WB NSxu_ sT*bPG,o8@@3[dDӰ?p*%/ [1ɑtv39Z;Q*}]s-G R>RoTT˧|Squ@W:4~|zJ^_WVgcun{Wk \jSu B\C Pt DBt ?}AIENDB`PK 1?!/Keystroke/analysis/DisorderFAR.m% Disorder FRR disorder_thresholds = [ 0.61 0.62 0.63 0.64 0.65 0.6599999999999999 0.6699999999999999 0.6799999999999999 0.69 0.7 0.71 0.72 0.73 0.74 0.75 0.76 0.77 0.78 0.79 0.8 0.8099999999999999 0.82 0.83 0.84 0.85 ]; aceji = [ 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9777777777777777 0.8777777777777778 0.6111111111111112 0.3 0.08888888888888889 0.022222222222222223 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ]; brianwu_dvorak = [ 1.0 1.0 0.9888888888888889 0.9777777777777777 0.9333333333333333 0.9222222222222223 0.9111111111111111 0.9 0.8777777777777778 0.8333333333333334 0.7555555555555555 0.6555555555555556 0.5555555555555556 0.35555555555555557 0.23333333333333334 0.08888888888888889 0.03333333333333333 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ]; brianwu_qwerty = [ 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9444444444444444 0.8 0.6 0.4666666666666667 0.3111111111111111 0.15555555555555556 0.05555555555555555 ]; calvinon = [ 0.9777777777777777 0.9111111111111111 0.8333333333333334 0.7444444444444445 0.5444444444444444 0.25555555555555554 0.1 0.011111111111111112 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ]; chenx05 = [ 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.8222222222222222 0.34444444444444444 0.044444444444444446 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ]; edmond = [ 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9222222222222223 0.8111111111111111 0.4777777777777778 0.18888888888888888 0.044444444444444446 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ]; haruka = [ 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9666666666666667 0.8333333333333334 0.6111111111111112 0.2777777777777778 0.1 0.022222222222222223 0.0 0.0 0.0 0.0 0.0 ]; kirason = [ 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9888888888888889 0.9555555555555556 0.8444444444444444 0.6 0.4666666666666667 0.14444444444444443 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ]; neha_b = [ 1.0 1.0 1.0 1.0 1.0 1.0 0.9888888888888889 0.9333333333333333 0.7 0.37777777777777777 0.2111111111111111 0.12222222222222222 0.08888888888888889 0.03333333333333333 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ]; nickchun = [ 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9888888888888889 0.9555555555555556 0.8333333333333334 0.6666666666666666 0.45555555555555555 0.23333333333333334 0.05555555555555555 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ]; qianwang = [ 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9777777777777777 0.8777777777777778 0.5222222222222223 0.16666666666666666 0.03333333333333333 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ]; shchang = [ 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.8555555555555555 0.6 0.37777777777777777 0.17777777777777778 0.08888888888888889 0.022222222222222223 0.011111111111111112 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ]; tylerc = [ 1.0 1.0 1.0 1.0 1.0 1.0 0.9777777777777777 0.9555555555555556 0.9222222222222223 0.8333333333333334 0.6555555555555556 0.4777777777777778 0.28888888888888886 0.13333333333333333 0.03333333333333333 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ]; wayluu = [ 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9 0.7222222222222222 0.5222222222222223 0.2777777777777778 0.05555555555555555 ]; xialiu = [ 1.0 0.9777777777777777 0.9444444444444444 0.8666666666666667 0.7333333333333333 0.35555555555555557 0.13333333333333333 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ]; xialiu_dvorak = [ 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9333333333333333 0.8444444444444444 0.7777777777777778 0.6555555555555556 0.43333333333333335 0.18888888888888888 ]; xyu = [ 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9222222222222223 0.2111111111111111 0.1 0.1 0.1 0.03333333333333333 0.0 0.0 ]; users = [aceji; brianwu_dvorak; brianwu_qwerty; calvinon; chenx05; edmond; haruka; kirason; neha_b; nickchun; qianwang; shchang; tylerc; wayluu; xialiu; xialiu_dvorak; xyu; ] figure(1) avgFRR = mean(users) hold on plot(disorder_thresholds, users) plot(disorder_thresholds, avgFRR, 'o-') title('FRR of Disorder Model') xlabel('False Rejection Rate') ylabel('Disorder Threshold') hold off % DISORDER FAR disorder_thresholds = [ 0.61 0.62 0.63 0.64 0.65 0.6599999999999999 0.6699999999999999 0.6799999999999999 0.69 0.7 0.71 0.72 0.73 0.74 0.75 0.76 0.77 0.78 0.79 0.8 0.8099999999999999 0.82 0.83 0.84 0.85 ]; aceji = [ 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0125 0.0125 0.03125 0.09375 0.275 0.36875 0.83125 0.9125 0.9375 0.9625 0.98125 0.98125 0.99375 0.99375 1.0 1.0 ]; brianwu_dvorak = [ 0.0 0.0 0.0 0.0 0.0 0.0 0.00625 0.00625 0.01875 0.08125 0.125 0.28125 0.35 0.8875 0.95 0.975 0.99375 0.99375 1.0 1.0 1.0 1.0 1.0 1.0 1.0 ]; brianwu_qwerty = [ 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0375 0.05625 0.1125 0.64375 0.8125 0.95 0.98125 0.9875 ]; calvinon = [ 0.0 0.00625 0.0125 0.1 0.23125 0.7 0.8125 0.90625 0.9375 0.975 0.975 0.98125 0.99375 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 ]; chenx05 = [ 0.0 0.0 0.0 0.0 0.0 0.00625 0.00625 0.00625 0.0125 0.0375 0.1 0.18125 0.7625 0.85625 0.94375 0.95625 0.98125 0.99375 0.99375 0.99375 0.99375 0.99375 0.99375 0.99375 1.0 ]; edmond = [ 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.00625 0.0125 0.05 0.06875 0.09375 0.15625 0.3125 0.9 0.93125 0.9625 0.99375 0.99375 0.99375 0.99375 1.0 1.0 ]; haruka = [ 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.00625 0.00625 0.00625 0.0125 0.0125 0.05625 0.225 0.3625 0.825 0.88125 0.9375 0.95625 0.975 0.98125 0.9875 1.0 ]; kirason = [ 0.0 0.0 0.0 0.0 0.0 0.0 0.00625 0.0125 0.0375 0.14375 0.26875 0.39375 0.8125 0.88125 0.91875 0.9625 0.975 0.9875 0.9875 1.0 1.0 1.0 1.0 1.0 1.0 ]; neha_b = [ 0.0 0.0 0.0 0.0 0.0375 0.05 0.0625 0.1 0.15625 0.70625 0.76875 0.9125 0.9375 0.95625 0.98125 0.9875 0.9875 0.9875 0.99375 1.0 1.0 1.0 1.0 1.0 1.0 ]; nickchun = [ 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0375 0.05 0.05625 0.0875 0.1125 0.70625 0.86875 0.94375 0.9875 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 ]; qianwang = [ 0.0 0.0 0.0 0.0 0.0 0.0 0.00625 0.00625 0.05625 0.10625 0.28125 0.725 0.84375 0.9375 0.975 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 ]; shchang = [ 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.00625 0.04375 0.04375 0.05625 0.0625 0.15 0.275 0.775 0.9125 0.93125 0.95625 0.9625 0.975 0.9875 0.9875 0.9875 1.0 1.0 ]; tylerc = [ 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.00625 0.05625 0.0625 0.19375 0.275 0.7375 0.88125 0.925 0.925 0.95625 0.98125 0.98125 0.99375 1.0 1.0 1.0 1.0 1.0 ]; wayluu = [ 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.00625 0.00625 0.00625 0.05625 0.0875 0.23125 0.75 0.9 0.94375 0.95625 ]; xialiu = [ 0.00625 0.00625 0.0875 0.15 0.26875 0.79375 0.81875 0.8625 0.925 0.9375 0.975 0.975 0.98125 0.99375 0.99375 0.99375 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 ]; xialiu_dvorak = [ 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.00625 0.0125 0.0125 0.0625 0.08125 0.1125 0.2875 0.83125 0.94375 ]; xyu = [ 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.01875 0.075 0.13125 0.19375 0.71875 0.76875 0.89375 0.96875 0.9875 0.9875 0.99375 ]; users = [aceji; brianwu_dvorak; brianwu_qwerty; calvinon; chenx05; edmond; haruka; kirason; neha_b; nickchun; qianwang; shchang; tylerc; wayluu; xialiu; xialiu_dvorak; xyu; ]; figure(2) avgFAR = mean(users) hold on plot(disorder_thresholds, users) plot(disorder_thresholds, avgFAR, 'x-') title('FAR of Disorder Model') xlabel('False Acceptance Rate') ylabel('Disorder Threshold') hold off figure(3) hold on plot(disorder_thresholds, avgFAR, 'x-') plot(disorder_thresholds, avgFRR, 'o-') title('Average FAR and FRR of Disorder Model') xlabel('Rate') ylabel('Disorder Threshold') hold off PK W1 LjLj"/Keystroke/analysis/avg_far_matrix 8.2000000e+01 9.7000000e+01 1.1600000e+02 1.0100000e+02 1.1500000e+02 3.2000000e+01 1.0200000e+02 1.1100000e+02 1.1400000e+02 3.2000000e+01 8.3000000e+01 1.1600000e+02 1.0000000e+02 4.6000000e+01 3.2000000e+01 6.8000000e+01 1.0100000e+02 1.1800000e+02 4.6000000e+01 3.2000000e+01 1.1100000e+02 1.0200000e+02 3.2000000e+01 5.0000000e+01 4.6000000e+01 5.3000000e+01 2.0428571e-01 9.4761905e-02 3.4761905e-02 1.2857143e-02 5.2380952e-03 9.5238095e-04 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 6.1238095e-01 4.9714286e-01 3.3238095e-01 1.9714286e-01 1.0190476e-01 4.0952381e-02 1.1904762e-02 4.2857143e-03 0.0000000e+00 0.0000000e+00 0.0000000e+00 8.0809524e-01 7.3761905e-01 6.3619048e-01 5.0714286e-01 3.7190476e-01 2.2095238e-01 1.0857143e-01 3.8095238e-02 8.5714286e-03 9.5238095e-04 0.0000000e+00 8.6809524e-01 8.2904762e-01 7.7476190e-01 7.0809524e-01 6.2190476e-01 4.7095238e-01 2.8523810e-01 1.4476190e-01 4.9047619e-02 6.1904762e-03 0.0000000e+00 2.0428571e-01 9.4761905e-02 3.4761905e-02 1.2857143e-02 5.2380952e-03 9.5238095e-04 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 6.1238095e-01 4.9714286e-01 3.3238095e-01 1.9714286e-01 1.0190476e-01 4.0952381e-02 1.1904762e-02 4.2857143e-03 0.0000000e+00 0.0000000e+00 0.0000000e+00 8.0809524e-01 7.3761905e-01 6.3619048e-01 5.0714286e-01 3.7190476e-01 2.2095238e-01 1.0857143e-01 3.8095238e-02 8.5714286e-03 9.5238095e-04 0.0000000e+00 8.6809524e-01 8.2904762e-01 7.7476190e-01 7.0809524e-01 6.2190476e-01 4.7095238e-01 2.8523810e-01 1.4476190e-01 4.9047619e-02 6.1904762e-03 0.0000000e+00 7.8518519e-02 1.7259259e-01 3.0666667e-01 4.4814815e-01 6.0592593e-01 7.7407407e-01 8.8296296e-01 9.5555556e-01 9.9111111e-01 1.0000000e+00 1.0000000e+00 7.4074074e-04 3.7037037e-03 2.8148148e-02 6.1481481e-02 1.2370370e-01 2.6000000e-01 4.6370370e-01 6.6666667e-01 8.4074074e-01 9.5259259e-01 1.0000000e+00 0.0000000e+00 0.0000000e+00 2.2222222e-03 9.6296296e-03 2.5925926e-02 5.7777778e-02 1.6370370e-01 3.3629630e-01 5.7851852e-01 8.8592593e-01 1.0000000e+00 0.0000000e+00 0.0000000e+00 7.4074074e-04 6.6666667e-03 1.0370370e-02 2.1481481e-02 6.4444444e-02 1.5111111e-01 3.5037037e-01 7.4518519e-01 1.0000000e+00 7.8518519e-02 1.7259259e-01 3.0666667e-01 4.4814815e-01 6.0592593e-01 7.7407407e-01 8.8296296e-01 9.5555556e-01 9.9111111e-01 1.0000000e+00 1.0000000e+00 7.4074074e-04 3.7037037e-03 2.8148148e-02 6.1481481e-02 1.2370370e-01 2.6000000e-01 4.6370370e-01 6.6666667e-01 8.4074074e-01 9.5259259e-01 1.0000000e+00 0.0000000e+00 0.0000000e+00 2.2222222e-03 9.6296296e-03 2.5925926e-02 5.7777778e-02 1.6370370e-01 3.3629630e-01 5.7851852e-01 8.8592593e-01 1.0000000e+00 0.0000000e+00 0.0000000e+00 7.4074074e-04 6.6666667e-03 1.0370370e-02 2.1481481e-02 6.4444444e-02 1.5111111e-01 3.5037037e-01 7.4518519e-01 1.0000000e+00 4.4000000e+01 7.0000000e+01 8.2000000e+01 8.2000000e+01 3.2000000e+01 9.7000000e+01 1.1000000e+02 1.0000000e+02 3.2000000e+01 7.0000000e+01 6.5000000e+01 8.2000000e+01 3.2000000e+01 1.0200000e+02 1.1100000e+02 1.1400000e+02 3.2000000e+01 8.3000000e+01 1.1600000e+02 9.7000000e+01 1.1000000e+02 1.0000000e+02 9.7000000e+01 1.1400000e+02 1.0000000e+02 3.2000000e+01 6.8000000e+01 1.0100000e+02 1.1800000e+02 1.0500000e+02 9.7000000e+01 1.1600000e+02 1.0500000e+02 1.1100000e+02 1.1000000e+02 3.2000000e+01 1.1100000e+02 1.0200000e+02 3.2000000e+01 5.0000000e+01 4.6000000e+01 5.3000000e+01 3.2000000e+01 9.7000000e+01 1.1600000e+02 3.2000000e+01 8.6000000e+01 9.7000000e+01 1.1400000e+02 1.0500000e+02 1.1100000e+02 1.1700000e+02 1.1500000e+02 3.2000000e+01 8.4000000e+01 1.0400000e+02 1.1400000e+02 1.0100000e+02 1.0400000e+02 1.1100000e+02 1.0800000e+02 1.0000000e+02 1.1500000e+02 4.0000000e+00 3.4000000e+01 2.0714286e-01 7.8571429e-02 1.4285714e-02 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 6.3571429e-01 4.8571429e-01 2.7857143e-01 1.0000000e-01 5.0000000e-02 7.1428571e-03 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 8.7142857e-01 7.8571429e-01 6.4285714e-01 4.0714286e-01 2.6428571e-01 1.0714286e-01 2.1428571e-02 7.1428571e-03 0.0000000e+00 0.0000000e+00 0.0000000e+00 9.5000000e-01 9.2857143e-01 8.0000000e-01 7.2142857e-01 5.2142857e-01 3.5000000e-01 1.7142857e-01 5.0000000e-02 7.1428571e-03 0.0000000e+00 0.0000000e+00 4.1428571e-01 1.9285714e-01 4.2857143e-02 7.1428571e-03 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 9.6428571e-01 8.5000000e-01 6.0000000e-01 3.8571429e-01 1.7857143e-01 3.5714286e-02 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 9.9285714e-01 9.7857143e-01 9.4285714e-01 7.9285714e-01 6.6428571e-01 4.1428571e-01 1.4285714e-01 4.2857143e-02 0.0000000e+00 0.0000000e+00 0.0000000e+00 1.0000000e+00 1.0000000e+00 9.9285714e-01 9.6428571e-01 9.4285714e-01 7.7142857e-01 5.1428571e-01 2.1428571e-01 5.0000000e-02 7.1428571e-03 0.0000000e+00 2.0000000e-01 1.0000000e-01 4.2857143e-02 1.4285714e-02 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 4.6428571e-01 3.9285714e-01 2.6428571e-01 1.9285714e-01 1.2142857e-01 5.0000000e-02 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 7.0000000e-01 5.4285714e-01 4.3571429e-01 3.4285714e-01 2.6428571e-01 1.5714286e-01 7.1428571e-02 2.8571429e-02 0.0000000e+00 0.0000000e+00 0.0000000e+00 8.4285714e-01 7.6428571e-01 6.0000000e-01 4.5714286e-01 3.7857143e-01 2.6428571e-01 1.4285714e-01 6.4285714e-02 3.5714286e-02 0.0000000e+00 0.0000000e+00 1.1428571e-01 4.2857143e-02 7.1428571e-03 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 6.0714286e-01 4.2142857e-01 2.3571429e-01 1.2142857e-01 2.8571429e-02 1.4285714e-02 7.1428571e-03 7.1428571e-03 0.0000000e+00 0.0000000e+00 0.0000000e+00 8.8571429e-01 8.0714286e-01 6.1428571e-01 4.4285714e-01 2.9285714e-01 1.4285714e-01 6.4285714e-02 1.4285714e-02 0.0000000e+00 0.0000000e+00 0.0000000e+00 9.7142857e-01 9.1428571e-01 8.5000000e-01 7.7857143e-01 6.3571429e-01 4.4285714e-01 1.6428571e-01 7.1428571e-02 7.1428571e-03 0.0000000e+00 0.0000000e+00 2.6428571e-01 1.3571429e-01 7.8571429e-02 3.5714286e-02 2.1428571e-02 7.1428571e-03 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 8.4285714e-01 6.4285714e-01 4.4285714e-01 2.7857143e-01 1.1428571e-01 6.4285714e-02 2.1428571e-02 2.1428571e-02 0.0000000e+00 0.0000000e+00 0.0000000e+00 1.0000000e+00 9.5714286e-01 8.9285714e-01 7.5000000e-01 5.5000000e-01 3.3571429e-01 1.5000000e-01 7.1428571e-02 2.1428571e-02 0.0000000e+00 0.0000000e+00 1.0000000e+00 1.0000000e+00 9.7142857e-01 9.5000000e-01 8.7857143e-01 7.6428571e-01 4.8571429e-01 2.5714286e-01 6.4285714e-02 7.1428571e-03 0.0000000e+00 1.3571429e-01 5.0000000e-02 1.4285714e-02 7.1428571e-03 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 6.2142857e-01 4.8571429e-01 3.2857143e-01 2.0714286e-01 9.2857143e-02 2.8571429e-02 7.1428571e-03 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 9.4285714e-01 8.4285714e-01 6.9285714e-01 5.7857143e-01 3.7142857e-01 2.4285714e-01 1.5714286e-01 5.7142857e-02 7.1428571e-03 0.0000000e+00 0.0000000e+00 9.9285714e-01 9.7142857e-01 9.2142857e-01 8.2142857e-01 7.2857143e-01 5.1428571e-01 3.2142857e-01 1.6428571e-01 6.4285714e-02 0.0000000e+00 0.0000000e+00 1.4285714e-02 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 1.9285714e-01 1.2857143e-01 5.7142857e-02 7.1428571e-03 7.1428571e-03 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 4.1428571e-01 3.4285714e-01 2.2142857e-01 1.5714286e-01 1.0000000e-01 2.1428571e-02 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 6.0000000e-01 4.8571429e-01 3.8571429e-01 2.9285714e-01 2.3571429e-01 1.4285714e-01 5.0000000e-02 7.1428571e-03 0.0000000e+00 0.0000000e+00 0.0000000e+00 1.8571429e-01 1.2857143e-01 2.8571429e-02 2.1428571e-02 7.1428571e-03 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 6.2857143e-01 5.5000000e-01 4.0000000e-01 2.7142857e-01 2.0714286e-01 1.0714286e-01 2.1428571e-02 7.1428571e-03 0.0000000e+00 0.0000000e+00 0.0000000e+00 9.8571429e-01 9.2857143e-01 8.1428571e-01 6.7857143e-01 5.2857143e-01 3.8571429e-01 2.6428571e-01 1.0000000e-01 2.8571429e-02 7.1428571e-03 0.0000000e+00 1.0000000e+00 1.0000000e+00 9.9285714e-01 9.6428571e-01 9.0000000e-01 7.2142857e-01 4.8571429e-01 3.2857143e-01 1.5714286e-01 2.1428571e-02 0.0000000e+00 6.1428571e-01 3.5714286e-01 1.9285714e-01 9.2857143e-02 4.2857143e-02 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 9.6428571e-01 8.7857143e-01 7.5714286e-01 5.4285714e-01 3.9285714e-01 2.3571429e-01 1.0714286e-01 2.8571429e-02 0.0000000e+00 0.0000000e+00 0.0000000e+00 1.0000000e+00 9.9285714e-01 9.5000000e-01 8.9285714e-01 7.9285714e-01 6.0714286e-01 4.2142857e-01 1.8571429e-01 6.4285714e-02 7.1428571e-03 0.0000000e+00 1.0000000e+00 1.0000000e+00 9.9285714e-01 9.8571429e-01 9.5000000e-01 8.9285714e-01 7.2857143e-01 4.5714286e-01 2.3571429e-01 5.7142857e-02 0.0000000e+00 7.1428571e-02 7.1428571e-03 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 5.7142857e-01 4.6428571e-01 2.9285714e-01 1.8571429e-01 6.4285714e-02 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 9.7857143e-01 8.2857143e-01 6.8571429e-01 5.2142857e-01 3.7142857e-01 2.2142857e-01 8.5714286e-02 1.4285714e-02 0.0000000e+00 0.0000000e+00 0.0000000e+00 1.0000000e+00 9.9285714e-01 9.5714286e-01 9.0000000e-01 8.3571429e-01 6.4285714e-01 3.8571429e-01 2.1428571e-01 6.4285714e-02 0.0000000e+00 0.0000000e+00 2.5000000e-01 1.0000000e-01 2.8571429e-02 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 8.3571429e-01 6.7857143e-01 4.3571429e-01 1.5000000e-01 5.0000000e-02 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 9.7857143e-01 9.2142857e-01 8.0714286e-01 6.4285714e-01 4.0000000e-01 1.5000000e-01 2.8571429e-02 1.4285714e-02 0.0000000e+00 0.0000000e+00 0.0000000e+00 9.9285714e-01 9.6428571e-01 9.1428571e-01 8.2857143e-01 7.1428571e-01 4.3571429e-01 1.5714286e-01 2.8571429e-02 1.4285714e-02 0.0000000e+00 0.0000000e+00 1.1428571e-01 4.2857143e-02 7.1428571e-03 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 6.8571429e-01 5.3571429e-01 2.4285714e-01 1.0714286e-01 5.0000000e-02 1.4285714e-02 7.1428571e-03 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 8.9285714e-01 8.3571429e-01 7.3571429e-01 5.1428571e-01 3.5000000e-01 1.7142857e-01 7.1428571e-02 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 9.4285714e-01 8.8571429e-01 8.5714286e-01 7.9285714e-01 6.6428571e-01 4.5000000e-01 2.5000000e-01 8.5714286e-02 7.1428571e-03 0.0000000e+00 0.0000000e+00 4.2857143e-02 7.1428571e-03 7.1428571e-03 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 2.4285714e-01 1.4285714e-01 3.5714286e-02 1.4285714e-02 7.1428571e-03 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 3.5714286e-01 2.8571429e-01 2.0000000e-01 1.0000000e-01 2.8571429e-02 7.1428571e-03 7.1428571e-03 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 4.5714286e-01 3.8571429e-01 3.2857143e-01 2.3571429e-01 1.6428571e-01 3.5714286e-02 7.1428571e-03 7.1428571e-03 0.0000000e+00 0.0000000e+00 0.0000000e+00 4.3571429e-01 1.7857143e-01 5.7142857e-02 1.4285714e-02 7.1428571e-03 7.1428571e-03 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 9.0714286e-01 7.9285714e-01 6.1428571e-01 3.9285714e-01 1.6428571e-01 5.7142857e-02 7.1428571e-03 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 9.5000000e-01 9.1428571e-01 8.5000000e-01 7.8571429e-01 6.0000000e-01 3.5000000e-01 1.4285714e-01 3.5714286e-02 7.1428571e-03 0.0000000e+00 0.0000000e+00 9.8571429e-01 9.5000000e-01 9.2142857e-01 8.6428571e-01 7.5714286e-01 6.3571429e-01 4.1428571e-01 2.2142857e-01 2.8571429e-02 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 2.1428571e-02 7.1428571e-03 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 1.7142857e-01 1.0000000e-01 5.7142857e-02 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 2.8571429e-01 1.9285714e-01 1.3571429e-01 6.4285714e-02 2.1428571e-02 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 1.0000000e-01 2.1111111e-01 3.4444444e-01 4.0000000e-01 4.7777778e-01 7.5555556e-01 9.3333333e-01 1.0000000e+00 1.0000000e+00 1.0000000e+00 1.0000000e+00 0.0000000e+00 0.0000000e+00 2.2222222e-02 5.5555556e-02 7.7777778e-02 2.1111111e-01 4.1111111e-01 7.5555556e-01 9.8888889e-01 1.0000000e+00 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 1.1111111e-02 1.1111111e-02 7.7777778e-02 3.5555556e-01 6.6666667e-01 9.4444444e-01 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 2.2222222e-02 6.6666667e-02 3.6666667e-01 7.4444444e-01 1.0000000e+00 5.5555556e-02 1.2222222e-01 2.4444444e-01 4.0000000e-01 5.2222222e-01 6.3333333e-01 8.2222222e-01 9.3333333e-01 9.6666667e-01 1.0000000e+00 1.0000000e+00 0.0000000e+00 2.2222222e-02 1.0000000e-01 1.0000000e-01 1.7777778e-01 2.2222222e-01 3.7777778e-01 5.2222222e-01 7.7777778e-01 8.7777778e-01 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 3.3333333e-02 7.7777778e-02 1.1111111e-01 1.5555556e-01 3.2222222e-01 6.1111111e-01 8.2222222e-01 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 3.3333333e-02 1.0000000e-01 1.1111111e-01 1.2222222e-01 4.2222222e-01 7.4444444e-01 1.0000000e+00 0.0000000e+00 7.7777778e-02 2.8888889e-01 5.6666667e-01 7.4444444e-01 9.2222222e-01 1.0000000e+00 1.0000000e+00 1.0000000e+00 1.0000000e+00 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 1.1111111e-02 1.6666667e-01 6.2222222e-01 9.3333333e-01 1.0000000e+00 1.0000000e+00 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 6.6666667e-02 3.0000000e-01 7.4444444e-01 1.0000000e+00 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 3.3333333e-02 2.8888889e-01 8.2222222e-01 1.0000000e+00 6.6666667e-02 1.8888889e-01 2.2222222e-01 3.1111111e-01 3.6666667e-01 5.4444444e-01 6.7777778e-01 8.6666667e-01 9.7777778e-01 1.0000000e+00 1.0000000e+00 0.0000000e+00 0.0000000e+00 3.3333333e-02 8.8888889e-02 1.7777778e-01 2.5555556e-01 3.2222222e-01 3.7777778e-01 6.6666667e-01 9.3333333e-01 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 1.1111111e-02 7.7777778e-02 2.2222222e-01 3.2222222e-01 4.3333333e-01 7.7777778e-01 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 2.2222222e-02 6.6666667e-02 2.3333333e-01 4.1111111e-01 6.8888889e-01 1.0000000e+00 6.6666667e-02 1.3333333e-01 2.5555556e-01 4.6666667e-01 7.5555556e-01 8.6666667e-01 9.1111111e-01 9.5555556e-01 1.0000000e+00 1.0000000e+00 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 7.7777778e-02 2.3333333e-01 3.5555556e-01 4.8888889e-01 8.2222222e-01 9.0000000e-01 9.2222222e-01 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 3.3333333e-02 4.4444444e-02 1.7777778e-01 3.8888889e-01 5.7777778e-01 9.0000000e-01 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 1.1111111e-02 1.1111111e-02 6.6666667e-02 1.3333333e-01 2.7777778e-01 7.6666667e-01 1.0000000e+00 1.0000000e-01 1.6666667e-01 2.3333333e-01 3.8888889e-01 5.2222222e-01 7.6666667e-01 8.5555556e-01 9.1111111e-01 9.7777778e-01 1.0000000e+00 1.0000000e+00 0.0000000e+00 0.0000000e+00 3.3333333e-02 4.4444444e-02 1.4444444e-01 2.6666667e-01 4.4444444e-01 6.7777778e-01 8.5555556e-01 1.0000000e+00 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 2.2222222e-02 1.6666667e-01 3.8888889e-01 6.5555556e-01 1.0000000e+00 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 2.2222222e-02 2.3333333e-01 4.6666667e-01 7.7777778e-01 1.0000000e+00 7.7777778e-02 1.7777778e-01 4.3333333e-01 5.4444444e-01 6.0000000e-01 6.1111111e-01 7.0000000e-01 8.8888889e-01 9.8888889e-01 1.0000000e+00 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 4.4444444e-02 1.1111111e-01 3.2222222e-01 5.0000000e-01 6.0000000e-01 6.5555556e-01 7.8888889e-01 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 1.1111111e-02 1.2222222e-01 2.7777778e-01 4.3333333e-01 5.2222222e-01 7.0000000e-01 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 3.3333333e-02 2.0000000e-01 2.6666667e-01 4.8888889e-01 5.6666667e-01 1.0000000e+00 1.3333333e-01 3.1111111e-01 3.8888889e-01 4.4444444e-01 5.8888889e-01 7.6666667e-01 9.1111111e-01 9.7777778e-01 1.0000000e+00 1.0000000e+00 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 7.7777778e-02 1.7777778e-01 3.6666667e-01 5.7777778e-01 7.4444444e-01 8.2222222e-01 9.6666667e-01 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 3.3333333e-02 1.6666667e-01 3.1111111e-01 5.4444444e-01 8.4444444e-01 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 3.3333333e-02 2.2222222e-01 3.4444444e-01 6.6666667e-01 1.0000000e+00 0.0000000e+00 2.2222222e-02 1.3333333e-01 2.7777778e-01 6.3333333e-01 8.6666667e-01 9.0000000e-01 1.0000000e+00 1.0000000e+00 1.0000000e+00 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 1.1111111e-02 2.2222222e-01 4.8888889e-01 6.8888889e-01 8.8888889e-01 1.0000000e+00 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 1.1111111e-02 1.5555556e-01 3.0000000e-01 5.5555556e-01 9.7777778e-01 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 1.1111111e-02 8.8888889e-02 3.7777778e-01 9.3333333e-01 1.0000000e+00 2.2222222e-02 1.5555556e-01 3.2222222e-01 4.2222222e-01 4.8888889e-01 7.4444444e-01 9.2222222e-01 9.8888889e-01 1.0000000e+00 1.0000000e+00 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 3.3333333e-02 1.1111111e-01 2.7777778e-01 3.1111111e-01 4.6666667e-01 8.2222222e-01 1.0000000e+00 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 3.3333333e-02 2.2222222e-01 2.5555556e-01 4.5555556e-01 9.3333333e-01 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 4.4444444e-02 2.8888889e-01 8.3333333e-01 1.0000000e+00 2.0000000e-01 2.0000000e-01 2.3333333e-01 3.4444444e-01 4.2222222e-01 5.8888889e-01 7.4444444e-01 8.1111111e-01 9.5555556e-01 1.0000000e+00 1.0000000e+00 0.0000000e+00 1.1111111e-02 3.3333333e-02 1.2222222e-01 2.1111111e-01 2.5555556e-01 4.4444444e-01 4.8888889e-01 6.4444444e-01 8.0000000e-01 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 1.1111111e-02 1.4444444e-01 1.5555556e-01 2.7777778e-01 4.2222222e-01 4.6666667e-01 7.4444444e-01 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 1.1111111e-02 5.5555556e-02 2.1111111e-01 4.0000000e-01 4.3333333e-01 6.2222222e-01 1.0000000e+00 2.4444444e-01 3.1111111e-01 3.8888889e-01 4.4444444e-01 6.7777778e-01 8.5555556e-01 1.0000000e+00 1.0000000e+00 1.0000000e+00 1.0000000e+00 1.0000000e+00 1.1111111e-02 2.2222222e-02 1.0000000e-01 1.3333333e-01 2.0000000e-01 2.6666667e-01 4.4444444e-01 6.3333333e-01 8.8888889e-01 1.0000000e+00 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 1.3333333e-01 2.1111111e-01 3.3333333e-01 5.4444444e-01 8.7777778e-01 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 1.2222222e-01 2.6666667e-01 3.5555556e-01 6.5555556e-01 1.0000000e+00 8.8888889e-02 3.3333333e-01 5.8888889e-01 7.3333333e-01 9.1111111e-01 9.8888889e-01 1.0000000e+00 1.0000000e+00 1.0000000e+00 1.0000000e+00 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 2.2222222e-02 5.5555556e-02 2.4444444e-01 6.0000000e-01 7.6666667e-01 8.8888889e-01 1.0000000e+00 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 1.1111111e-02 6.6666667e-02 3.2222222e-01 6.2222222e-01 8.5555556e-01 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 2.2222222e-02 2.6666667e-01 8.2222222e-01 1.0000000e+00 0.0000000e+00 0.0000000e+00 1.2222222e-01 2.7777778e-01 5.4444444e-01 7.5555556e-01 8.6666667e-01 1.0000000e+00 1.0000000e+00 1.0000000e+00 1.0000000e+00 0.0000000e+00 0.0000000e+00 1.0000000e-01 1.0000000e-01 1.0000000e-01 1.5555556e-01 2.5555556e-01 5.3333333e-01 8.1111111e-01 1.0000000e+00 1.0000000e+00 0.0000000e+00 0.0000000e+00 3.3333333e-02 1.0000000e-01 1.0000000e-01 1.0000000e-01 1.0000000e-01 2.0000000e-01 4.8888889e-01 9.3333333e-01 1.0000000e+00 0.0000000e+00 0.0000000e+00 1.1111111e-02 1.0000000e-01 1.0000000e-01 1.0000000e-01 1.0000000e-01 1.3333333e-01 2.6666667e-01 9.0000000e-01 1.0000000e+00 2.2222222e-02 1.7777778e-01 4.0000000e-01 7.0000000e-01 8.3333333e-01 9.4444444e-01 1.0000000e+00 1.0000000e+00 1.0000000e+00 1.0000000e+00 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 2.2222222e-02 5.5555556e-02 3.1111111e-01 6.6666667e-01 9.8888889e-01 1.0000000e+00 1.0000000e+00 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 1.1111111e-01 3.8888889e-01 7.8888889e-01 9.7777778e-01 1.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 2.0000000e-01 6.3333333e-01 1.0000000e+00 5.0000000e-01 5.5000000e-01 6.0000000e-01 6.5000000e-01 7.0000000e-01 7.5000000e-01 8.0000000e-01 8.5000000e-01 9.0000000e-01 9.5000000e-01 1.0000000e+00 PK 1R