Return statistics and collated events for keyboard events.

def stats_keyboard(events, table):
    """Return statistics and collated events for keyboard events."""
    if len(events) < 2: return [], []
    deltas, prev_dt = [], None
    sessions, session = [], None
    UNBROKEN_DELTA = datetime.timedelta(seconds=conf.KeyboardSessionMaxDelta)
    blank = collections.defaultdict(lambda: collections.defaultdict(int))
    collated = [blank.copy()] # [{dt, keys: {key: count}}]
    for e in events:
        if prev_dt:
            if (prev_dt.second != e["dt"].second
            or prev_dt.minute != e["dt"].minute or prev_dt.hour != e["dt"].hour):
                collated.append(blank.copy())
            delta = e["dt"] - prev_dt
            deltas.append(delta)
            if delta > UNBROKEN_DELTA:
                session = None
            else:
                if not session:
                    session = []
                    sessions.append(session)
                session.append(delta)
        collated[-1]["dt"] = e["dt"]
        collated[-1]["keys"][e["realkey"]] += 1
        prev_dt = e["dt"]
    longest_session = max(sessions + [[datetime.timedelta()]], key=lambda x: sum(x, datetime.timedelta()))
    stats = [
        ("Average interval between combos",
         sum(deltas, datetime.timedelta()) / len(deltas)),
    ] if "combos" == table else [
        ("Keys per hour",
         int(3600 * len(events) / timedelta_seconds(events[-1]["dt"] - events[0]["dt"]))),
        ("Average interval between keys",
         sum(deltas, datetime.timedelta()) / len(deltas)),
        ("Typing sessions (key interval < %ss)" % UNBROKEN_DELTA.seconds,
         len(sessions)),
        ("Average keys in session",
         sum(len(x) + 1 for x in sessions) / len(sessions)),
        ("Average session duration", sum((sum(x, datetime.timedelta())
         for x in sessions), datetime.timedelta()) / len(sessions)),
        ("Longest session duration",
         sum(longest_session, datetime.timedelta())),
        ("Keys in longest session",
         len(longest_session) + 1),
        ("Most keys in session",
         max(len(x) + 1 for x in sessions)),
    ]
    return stats, collated