Git Product home page Git Product logo

launchmenu's Introduction

Logo

Goal

LaunchMenu is an free, open source, cross-platform utility application which brings utilities (applets) to your fingertips. It intends to increase your productivity through it's keyboard-centric design, meanwhile also being extremely customisable with advanced theming and applet settings. The application is styled similar to that of Spotlight for Mac, however it allows for 3rd party applets to be built and installed, further increasing your productivity in any aspect of life.

LaunchMenu runs in the background, and launches when the user presses the "open LaunchMenu" hotkey (โŒ˜ + space/โŠž + space by default).

introduction.mp4

Contact us if you want to contribute to the project.

For an extensive list of features please see the LaunchMenu website. For an extensive list of built-in applets see the applets section of the website.

3rd party Applets / LaunchMenu API

LaunchMenu offers a free and flexible API, which allows 3rd party developers to extend the application's functionality to any experience they desire. The API primarily targets extensibility via TypeScript and React.

export const info = {
    name: "HelloWorld",
    description: "A minimal example applet",
    version: "0.0.0",
    icon: <img width={30} src={Path.join(__dirname, "..", "images", "icon.png")} />,
};

export const settings = createSettings({
    version: "0.0.0",
    settings: () =>
        createSettingsFolder({
            ...info,
            children: {
                username: createStringSetting({name: "Username", init: "Bob"}),
            },
        }),
});

const items = [
    createStandardMenuItem({
        name: "Hello world",
        onExecute: ({context}) =>
            alert(`Hello ${context.settings.get(settings).username.get()}!`),
    }),
];

export default declare({
    info,
    settings,
    search: async (query, hook) => ({children: searchAction.get(items)}),
});

For more information about development of applets in LaunchMenu please see the LaunchMenu development website.

Contribution

As mentioned several times already, LaunchMenu is fully open-source! We welcome any contributions to the project, especially third party applets. In case you want to contribute to our official repository, we do recommend discussing your ideas with us first. This prevents you from investing a lot of time into something that doesn't line up with our long term vision. That said, we're open to most ideas, and welcome all discussions! So don't hesitate to join the community, both as developer or as user, at one of the following links:

Community links

Project structure

This repository is a mono-repo and contains several packages. The packages directory has the following structure:

  • applets
    • Notes applet
    • Dictionary applet
    • etc.
  • core
  • core-applets
    • settings manager
    • applet manager
    • etc.
  • dev-tools
    • build-tools
    • hmr
  • launcher

The applets directory is rather self-explanatory: it contains all official utility applets. The core-applets directory may be a bit more confusing. This too contains applets for LaunchMenu, but so called 'core-applets'. These are applets that wouldn't be useful as standalone programs, but are useful within LaunchMenu. For instance having a stand-alone 'settings' program wouldn't be useful (settings for what??) while having a stand-alone 'dictionary' program is still useful.

The launcher directory contains the launcher package. This is something that takes care of LaunchMenu (LM) installation and launching (similar to e.g. the MineCraft launcher). In the future auto-update code will also be added to this, to take care of updating LaunchMenu when new release come out.

The dev-tools directory contains any code that's useful during development. The build-tools package provides a command-line utility and can be used for building LM during development. The hmr can be used within code to allow for Hot Module Reloading.

Finally we have the most important package of them all: core. This contains the main structure of LaunchMenu and utilities that can be used by applets. In the future we may want to split-off these utilities a bit further in separate dedicated packages, but for now they are all part of core.

Development

To install all dependencies, simply run yarn in the root of the repository. This will install all dependencies, link the packages, and perform an initial build of all packages.

When you're working on either the core of LM or an applet, run yarn dev within packages/core. This will start the core of LM, launching the program.

Then in the case of working on an applet, simply run yarn dev again, but now within the directory of the applet you're working on. HMR will automatically take care of reloading your applet in the running LM instance when any changes occur. Do notice however that you may need to exit and open any menus of your applet again to see the changes.

launchmenu's People

Contributors

bramhoven avatar dependabot[bot] avatar sancarn avatar tarvk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

launchmenu's Issues

Create fuzzy search action handler

Look for a nice TS fuzzy search library and either replace the current search by a fuzzy search handler, or add the fuzzy search handler

  • Add priority channels for better priority management

Create an undo/redo facility

  • Create a command interface and standard class
  • Create a facility for tracking, executing and undoing
  • Create compound and other utility commands
  • Integrate with context menu and executeAction

Hooked action binding lists

  • Allow for menu item action bindings to be retrieved with a hook.
  • Allow passing of hooks to action getters
  • Update action usages that use actions for state to specify hooks:
    • Context menu item retrieval
    • Category retrieval
    • Search action retrieval (Maybe ignore this because of performance concerns)

Context-menu improvements

Currently the context menu just shows items in a semi-arbitrary order (based on order bindings of items are defined).
It would preferable to change this to a prioritized menu and have bindings for the context-menu contain a tag that includes a priority as well.

  • Make context menu prioritized
  • Allow for multiple menu items per action
  • Open context menu on right click
  • Order categories based on how many items are in the category
  • Allow general context menu items to be passed in the IOContext
  • Make selection only trigger if no other keys were pressed (so you can still type capitals)

Increase SearchExecuter parallelism

Currently the search executer only handles 1 item at a time. This is problematic if a search requires some async behavior s;uch as getting data from a server. Code should be adapted to continue onto the next item already when this is the case.

I believe this should be doable without many changes.
Unit tests should be updated to properly test this parallelism.

Maximum category size prioritized menu

The user should be able to specify how many results to show per applet.
So to permit this, a maximum category size option should be introduced for prioritized menus, as well as some way of showing that there are more items, but those are hidden (possibly even make it possible to expand/collapse these).

An other interesting addition would be to add controls for the main search menu to 'tab' between different categories.

Improve theme

  • Add font styles to the theme and box component
  • Change spacing to be name based (to decrease confusion)
  • Remove fluent-ui library

Create search field

A search field that automatically creates and opens a menu with the search reults

SearchCache issue

Currently the search cache uses a queue to determine what item to remove from the cache.
However, when we have a cache hit, that item should actually be added to the end of the queue again (and removed from the current position).
Now if you have a cache of size 3, you would get the following result:

1. A   - Miss
2. B   - Miss
3. A   - Hit
4. C   - Miss
5. A   - Hit
6. D   - Miss
7. A   - Miss

Where as really 7 should be a hit, since every second lookup included it. So the queue should really track how long ago an item was looked up, rather than how long ago it was added.

Relevant line: https://github.com/LaunchMenu/LaunchMenu/blob/master/packages/core/src/utils/search/SearchCache.ts#L50
Fix would probably involve creating a map to store the queue items, and turn the queue in a doubly linked list such that a item can be removed (and inserted at the back) when requested.

Improved Global Keyboard Shortcut listeners

Improved listeners using IOHook so can listen to meta key and others.

  • Create and implement global key listeners in node-global-key-listener. Progress see here
  • Implement a wrapper in LM around node-global-key-listener.
  • Create a settings type for global listeners
    • Make the settings store the keycodes, and display character names obtained from the browser
    • Add a function to this setting type to register a listener for it

Dialogs

Add a layer type that can be used for simple dialogs, such confirmation prompts.
Also create simple confirmation execute handler using this UI

Improve settings

  • Make settings track what files changed, and auto save on changes
  • Add some more basic settings:
    • Window position
    • Max category size
  • Fix Session auto closing and window closing with appropriate settings

FileSystem search applet

The ability to search the file system for files in LM.

Requirements

  • Choose BFS (bredth first search) or DFS (depth first search)
  • Ability to cancel out whole trees of directories given a condition
  • Regex searching via file name
  • Regex searching via file contents searching (this might be a seperate applet plugin?)
  • Ideally Dynamic (updates as files change in background)
  • A plugin system.
  • File class to be extendable and matchable to multiple files simultaneously or folders of files. E.G. The following is a shape file, but comprises of 2 seperate files a .shp and a .dbf. Would want to be able to move them together, instead of individually etc. Would want to have them appear as 1 file (via a plugin) instead of 2 files.
    some/file.shp
    some/file.dbf
    
  • To be able to match a folder structure as a single File also e.g. a sewer asset survey:
    someID
    |- someID.docx
    |- someID-in.jpg
    |- someID-out.jpg
    |- someID-chamber.jpg
    |- telemetry
    |  |- dropTests.pdf
    |  |- scada
    ...
    
  • A simple run command for launching applications run:notepad.

Roadmap

Just a high level roadmap currently

  • Design and implement VFS model for efficient searching.
  • Design and implement query object for search criteria
  • Design and implement query search syntax to convert to query object

Final touches

  • Make LM contain a 'dev' parameter that can be controlled independent of environment variables
  • Make repo generate the settings file that contains all module paths on installation
  • Make all modules have appropriate icons
  • Fix opening transition of application layout (to improve session switching)
  • Improve context menu and path styling
  • Make default content, or remove default content
  • Create a help menu
  • Publish all the latest modules
  • Delete trash
  • Update the installer to include all the latest modules

View stack improvements

  • make animations configurable per pushed item
  • make view stack view hide if null is pushed to the stack
  • create and use LFC to be a FC without children

Create base LM application structure

  • Create dummy keyboard handler that catches all events
  • Create an overall UI using the stacks that applets can live in
  • Make the UI open and closable from keyboard
  • Add multi-instance support for multitasking within LM

Global hotkeys

Currently we have an issue installing global hotkeys in LaunchMenu.

Option 1: Do nothing

Currently we used Electron's global hotkey libraries but these are very limited as they use more restricted hotkey binding systems.

Option 2: Use IOHook

Problems: IOHook only supports a set of node and electron versions. Building is a bit of a nightmare.

Option 3: Use native implementation

Windows implementation

This implementation is described here. I've included some pseudocode below.

const WH_GETMESSAGE = 3
function Register(){
   this.hook = SetWindowHookEx(WH_GETMESSAGE, pointerTo(MyMsgProc), 0, 0)
}
function Unregister(){
  if(!UnhookWindowsHookEx(this.hook)){
    throw "Cannot unhook"
  }
}
function MyMsgProc(code, wParam, lParam){
  if(code == WM_KEYDOWN){
    //Detect keycode in wParam
    
    //Propogation
    if(!stopPropogation){
      CallNextHookEx(this.hook, code, wParam, lParam)
    }
  } else {
    CallNextHookEx(this.hook, code, wParam, lParam)
  }
}

Mac implementation

The following is the implementation for Macs written in swift.

var gMyHotKeyID = EventHotKeyID()
gMyHotKeyID.signature = OSType("swat".fourCharCodeValue)
gMyHotKeyID.id = UInt32(keyCode)

var eventType = EventTypeSpec()
eventType.eventClass = OSType(kEventClassKeyboard)
eventType.eventKind = OSType(kEventHotKeyPressed)

// Install handler.
InstallEventHandler(GetApplicationEventTarget(), {(nextHanlder, theEvent, userData) -> OSStatus in
    var hkCom = EventHotKeyID()
    GetEventParameter(theEvent, EventParamName(kEventParamDirectObject), EventParamType(typeEventHotKeyID), nil, sizeof(EventHotKeyID), nil, &hkCom)

    // Check that hkCom in indeed your hotkey ID and handle it.
}, 1, &eventType, nil, nil)

// Register hotkey.
let status = RegisterEventHotKey(UInt32(keyCode), UInt32(modifierKeys), gMyHotKeyID, GetApplicationEventTarget(), 0, &hotKeyRef)

Option 4: Use Node FFI

The above could be implemented in Node-FFI. This could mean that we have a bit of a build nightmare though...

Create input fields

  • Create field data structure
  • Create field input handler
  • Create field views

Notes improvements

Improved markdown rendering

Markdown renderer support

  • Tables
  • checkbox items

Markdown Text-editor behaviour

  • When caret is on a bullet / checkbox and a new line is inserted it would be nice to add a bullet/checkbox on the new line.
  • Match indenting of previous line on new line insertion
  • Ability to paste pictures into text editor might be nice (save file somewhere in file system), ensure file is cleaned up on delete.

And potentially some other things. It would be nice to support most features including advanced ones like this.

Can we use MDX with some special set components?

Additional notes features:

  • Setting for where to place caret on opening a note. I.E. At the beginning or end of the note.

Create applet boilerplate

Create some applet repository to contain some boilerplate currently required to create an applet for LM.

SearchMenu

Create a search menu that performs a search action on a set of given items and displays the ranked results

Mac OS Support

This is a megathread to attempt to get full support of LM features on Mac OS.

Following are some OS specific issues we've identified already:

  • Certificate issue on http requests. Perhaps using node-XMLHttpRequest and node-fetch.
  • Weird border at the top of the window; remove custom shadow and transparency
  • Icon size in tray is huge - resize to 16x16 image required
  • Glitchy window moving
  • Meta not releasing key ({Meta down}{a down}{a up}{meta up} not picked up but {Meta down}{a down}{meta up}{a up} is)
  • Exit the main process on window close
  • Detect terminal exit to force close window
  • When focussing outside of LM, when it had focus, it regrabs focus somehow.
  • Auto-paste doesn't work (might be related to focus issue)
  • Alt is used for character modifiers too; use keypress events for character inputs?
  • Auto-open on restart isn't implemented. link
  • Meta should be included in special modifier list
  • Change default bindings for mac (cmd+a, cmd+c, etc.)

Create onMenuChange action

Create an action that can be used to track what menus an item is a part of

onMenuChange(menu: IMenu, event: "added" | "removed"): void;

Update menu, prioritized menu and ordered list to accommodate for this event callback

Create settings system

  • Create settings items
  • Create settings data storage
  • Create settings management UI
  • Create settings context system

Add notification system

Add some UI system that can be used for showing notifications, which don't interrupt the user.

This should be some kind of overlay, separate window, or dedicated area that expands.
More thought must be put into this idea before implementation.

Fix found bugs

  • Fix pattern bug; type 'define nl: stuff'
  • Fix visual items glitch while typing
  • Fix LM build tools dependency
  • Fix tiny window showing when closing LM
  • Add LM window icon
  • Credit wikitionary at the bottom of definition content
  • In the installer add some text to show how to open LM
  • create singlePromptExecuteHandler
  • rename some execute handlers to prompt execute handler

Create window manager applet

Create an applet to handle window concerns:

  • Opening/closing of LM
  • Positioning and sizing of LM
  • Automatic startup of LM

Combined inputs

Currently situation:

  • Select 4 items, 2 with a input execute handler, and 2 with a select execute handler
  • Execute the items
  • Go through 4 different UIs to update the values of each item of the selection

Goal:

  • Select 4 items, 2 with a input execute handler, and 2 with a select execute handler
  • Execute the items
  • Go through 2 different UIs to update the values only for every type of input

So basically, there should be a way of creating something like a combinedExecuteHandler (action) given a execute handler and a configuration for it (input validity checker etc). Then this combined execute handler represents the input for a certain item type, such that when multiple of these items are selected, one UI is able to update them all at once.
This behavior should probably be optional though, so it would make sense for this combinedExecuteHandler to create 2 context items; 1 for updating each item individually and 1 for updating them all at once (combined) Maybe even with a setting for which behavior should be the default execute behavior.

Multiple minor improvements

  • Make context menu closing more dynamic
  • Make contexts properly closable using shortcuts and UI
  • Add a system to keep track of paths to keep track where in the application you are

Update model-react

Add all local changes to the real model-react instance.
Also update all documentation for it.
Also add try catch clauses to invocation of listeners, such that listener errors don't prevent other listeners from getting called

Keyboard listener updates

  • Make keyboard events class based
  • Add 'current selection' data to keyboard events
  • Create an 'onSelect' action handler that can be used to execute item actions on keyboard inputs (making the context menu items accessible through shortcuts)
  • Make IKeyEventListener callback be asynchronous for more flexibility

Mocking framework?

Might be useful for actions and handlers.... But not sure how needed it is.

Similar App Plugin Compatibility - Cerebro

Cerebro is an application similar to LaunchMenu but has a significantly simplified plugin system. There are however 200 or so existing cerebro plugins. It would be really cool if we could build a simple applet which allows the installation of Cerebro-style plugins into the LaunchMenu environment with minimal effort.

Some applet examples:

See src/index.js for code

The basic layout of a cerebro plugin is as follows.

module.exports = {
  fn: ({{term: string, display: function, update: function, actions: object }}) => {...},
  name: 'Hash input...',
  keyword: 'hash'
}

fn appears to be ran whenever anything is typed into the searchbar. term itself is the string containing the searched query. display function is passed an object which contains information about a menu item to display. update is used for updating the UI, including auto-completion of search term in query bar(I doubt this makes sense for launchmenu) but also the getPreview() method returns a react element to preview in the contents pane.

The menu item would generally follow this structure.

Generally speaking I'm going to guess that this would be very simple to add into LaunchMenu, at least in a basic form, and would at least make the application quite usable soon after initial release

It's likely that not all functionality will be easily mirror-able, however this might be a great way of re-using existing works.

Create mnemonics system

  • Create mnemonics context to track enabled/disabled states and forward the key events when enabled
  • Create mnemonic hook to trigger an action when a certain mnemonic is triggered
  • Create mnemonic component to trigger an action and highlight text when mnemonics are activated

Ability to prioritise menu items based on previously active application

Ability to prioritise menu items based on previously active application

It would be useful to be able to filter/prioritise LaunchMenu actions based on the previous opened application.

For instance if you're video editing you might have built a set of scripts to help you video edit faster. You might want to be able to prioritize your scripts instead of other items that may match your search term.

Function to export active window metadata

Windows

//Todo

Mac

let run = require("@jxa/run").run;
async function getActiveApp(){
  return await run(function(data){
    var proc = Application("System Events").processes().filter(e=>e.frontmost())[0]
    var wnd = proc.windows()[0];
    return {
      process: {
        name: proc.name(),
        id: proc.id()
      },
      window: {
        id: null,
        name: wnd.name(),
        pos: wnd.position(),
        size: wnd.size(),
        class: wnd.class(),
        desc: wnd.description(),
        role: wnd.role(),
        roleDesc: wnd.roleDescription()
      }
    }
  });
}

Linux

//Todo

Create applet/plugin system

  • Discuss and plan the structure for the applet system
  • Implement structure (sub tasks to be added after planning)

Handle user feedback

I had Selulance test some of the application, here is some feedback to cover:

  • Fix keyboard to work with other layouts than just standard qwerty
  • Navigation is quite difficult with normal keyboard layout, esc is hard to reach, and enter also isn't amazing (with right hand at arrow keys)
    • could possibly default to ctrl+left for escape and ctrl+right for enter
  • Help menu should really mention the escape key, since it's quite important for navigation
  • User should be able to specify how many results to show per applet
    • > perhaps a key to tab to the next applet in the result field if you are not interested in the results of the applet that appeared on the top
  • Add ctrl+left/right to jump whole words at once (and possibly double click word to select it, triple click to select all)
  • Add a shortcut for clearing the LM session (go to home page)
  • It wasn't obvious that any menu could be searched, so it might be wise to add blinking cursor by default (despite me hating it)
  • Selulance was annoyed by not being able to easily move the window. I personally think it's not important at all since usually it won't be moved often, and typing s:pos is quite simple, but it's something to consider.
  • Add tray actions: shutdown LM, enable/disable automatic startup, about LM

Text selection

Currently all text in LM is selectable with the mouse. This by itself isn't awful, but it is a little unusual.
We however also prevent all key events, and right click events. So you can select text, but you can't even copy it, making it rather useless.

I think it would be best to disable text selection by default, but allow it in the content section (possibly definable with a flag when you create your content). Then allow for right click on the content section and allow for ctrl+c.

Action generalization

Make the actions system more general, by allowing them to return inputs for multiple super-actions (parent actions):

  • Actions should indicate what actions they are handlers for (their parent actions, if any)
  • Actions should return a list where each element is either a binding for an action they indicated to be a handler for, or any other non binding result

Then in order to execute an action X, one would:
1- Retrieve all action bindings from the items (or any other thing that has an actionBindings property)
2- Group all action bindings by their actions
3- Recursively include all parent actions in the grouped collections
4- Take out an actions that don't contain X as an ancestor (step 3 and 4 might be combinable for efficiency)
5- Create a partial (or full) ordering of these collections, such that parents always come after their children
6- In sequence of the ordering, execute each action's core reducer on the input bindings, and add any resulting bindings to the binding's action's collection
7- Return the result of X's core reducer of step 6

Also while refactoring actions;

  • Think about dropping the 'tags' from action bindings
  • Think about handling the new more complex case of deciding what actions should be visible in the context menu,, when the action is a handler for another action (could be a handler for multiple actions!)
  • Try to make sure that ordering of input action bindings is retained in the output, even when going through multiple handlers

`OSPasteHandler` Upgrades

OSPasteHandler Upgrades

Current issues

  • Not all applications paste with ctrl+v.
  • Not all applications have a keyboard shortcut at all for pasting e.g. Specialist business software InfoWorks ICM has several Paste commands found in the "File menu" but no specific keybinds to execute them.
  • Linux is currently unsupported

Resolutions

  • Paste via Keyboard Shorcut
    • Build sendKeys(keys) script for Windows
    • Build sendKeys(keys) script for Mac OS X
    • Build sendKeys(keys) script for Linux
    • Ensure different keyboard shorcuts can be used for different applications (settings)
  • Paste via clicking menu items
    • Build execMenuItem(path) script for Windows
      • Via SendMessage()
      • Via SendMessage(WM_PASTE)
      • Via MSAA
    • Build execMenuItem(path) script for Mac OS X
      • Via JXA System Events UI Element tree
    • Build execMenuItem(path) script for Linux
    • Ensure different paths can be used for different applications (settings)

Increase action flexibility

Currently an action can specify multiple parents, but bindings have no way of choosing what parent they are for.
Therefor if an action decides to have multiple parents, all bindings will become bindings for all those parents too.
We can improve this by allowing bindings to specify 'targets'. This will specify what actions the binding should directly or indirectly be used for.

We can then also increase flexibility even more by allowing actions to specify children, instead of only parents. Currently actions always specify their parents, such that new handlers can always be created without the parents having to know of their existence. But it would also be useful to allow for the opposite; Have a new action be able to use an already existing action as a handler.
This way you can reuse all possible action handlers of an already existing action.
An action binding couldn't usually be traced back to the source ancestor action this way however (since some action doesn't know about one of its parents, its parent only know about it), but this is where the targets come in. When using this child behavior, the binding would have to specify the target in addition in order to allow for the action to be used in the actrion tree creation.

All of this has to be thought trough a little better, but will allow for an even greater amount of flexibility in the action system.

Notes applet

Create a notes applet with the following features:

  • Notes have titles and content
    • Both title and content should be searchable
    • Notes should have a file type (syntax highlighting)
      • Notes should have a 'rich content' option which performs rich rendering when not editing for:
        • text
        • html
        • markdown
    • Should have copy and paste handlers to copy and paste the content even when not editing it
  • There should be user definable note categories
    • Categories should be colorable
    • Categories should be able to have their own search pattern
    • Categories should have defaults for file type and rich content, which can optionally be overridden by notes
  • Notes should by default save in a folder in the installation directory
    • Both the default and per note, the file location should be changeable
  • In some advanced usage item, there should be a way to directly alter the notes data file

Settings:

  • default note storage location
  • default note type
  • default rich content enabled- [x] default category color
  • default note color
  • default font size
  • default search note content
  • fullscreen note editing
  • Show category inline
  • LM level 'advanced usage' option to show advanced items such as something to alter the notes data file

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.